1 % (c) 2009-2024 Lehrstuhl fuer Softwaretechnik und Programmiersprachen,
2 % Heinrich Heine Universitaet Duesseldorf
3 % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html)
4
5
6 :- module(tools_positions,
7 [is_position/1,
8 is_valid_position/1,
9 get_position_filenumber/2,
10 update_position_filenumber/4,
11 get_position_row_cols/5,
12 row_col_to_position/3,
13 add_col_offset_to_position/3,
14 add_line_col_offset_to_position/4
15 ]).
16
17 :- use_module(module_information).
18
19 :- module_info(group,infrastructure).
20 :- module_info(description,'A few utilities on raw positions as provided by the B Parser.').
21
22 is_position(none).
23 is_position(pos(_,_,_,_,_,_)). % old pos/6 format with unused ID
24 is_position(p5(_,_,_,_,_)). % new format without ID
25 is_position(p4(_,_,_,_)). % new format without ID and for end line = start line
26 is_position(p3(_,_,_)). % new format without ID and for file number 1 and with end line = start line
27 is_position(rodinpos(_Model,_Name,_Internal)). % created by Event-B export
28 is_position(rodinpos(_,_)). % old style positions, e.g., for test 362
29 is_position(pos_context(_,_,_)). % created by combine_pos; not generated by B parser
30
31 % same but with more stringent checks
32 is_valid_position(none).
33 is_valid_position(pos(Id,F,SL,SC,EL,EC)) :-
34 number(Id),atomic(F),number(SL),number(SC),number(EL),number(EC).
35 is_valid_position(p5(F,SL,SC,EL,EC)) :-
36 atomic(F),number(SL),number(SC),number(EL),number(EC).
37 is_valid_position(p4(File,SL,SC,EC)) :-
38 atomic(File),number(SL),number(SC),number(EC).
39 is_valid_position(p3(SL,SC,EC)) :-
40 number(SL),number(SC),number(EC).
41 is_valid_position(pos_context(P1,_Ctxt,P2)) :-
42 is_valid_position(P1), is_valid_position(P2).
43
44 get_position_filenumber(pos(_,FN,_Srow,_Scol,_Erow,_Ecol),FN).
45 get_position_filenumber(p5(FN,_Srow,_Scol,_Erow,_Ecol),FN).
46 get_position_filenumber(p4(FN,_Srow,_Scol,_Ecol),FN).
47 get_position_filenumber(p3(_Srow,_Scol,_Ecol),1).
48
49 % change filenumber of main file 1 to a new nr
50 % fails if no update needs to be done
51 update_position_filenumber(pos(A,OldFN,Srow,Scol,Erow,Ecol),OldFN,
52 pos(A,NewFN,Srow,Scol,Erow,Ecol),NewFN).
53 update_position_filenumber(p5(OldFN,Srow,Scol,Erow,Ecol),OldFN,
54 p5(NewFN,Srow,Scol,Erow,Ecol),NewFN).
55 update_position_filenumber(p4(OldFN,Srow,Scol,Ecol),OldFN,
56 p4(NewFN,Srow,Scol,Ecol),NewFN).
57 update_position_filenumber(p3(Srow,Scol,Ecol),1,
58 p4(NewFN,Srow,Scol,Ecol),NewFN).
59
60 % get start and end row/column information:
61 get_position_row_cols(pos(_,_FN,Srow,Scol,Erow,Ecol),Srow,Scol,Erow,Ecol).
62 get_position_row_cols(p5(_FN,Srow,Scol,Erow,Ecol),Srow,Scol,Erow,Ecol).
63 get_position_row_cols(p4(_FN,Srow,Scol,Ecol),Srow,Scol,Srow,Ecol).
64 get_position_row_cols(p3(Srow,Scol,Ecol),Srow,Scol,Srow,Ecol).
65
66 % construct position in main file (number 1)
67 row_col_to_position(Row,Col,p3(Row,Col,Col)).
68
69 % add column offset to position:
70 add_col_offset_to_position(Span,0,R) :- !, R=Span.
71 add_col_offset_to_position(p3(Line,Scol,Ecol),Offset,p3(Line,S2,E2)) :- !,
72 S2 is Scol+Offset, E2 is Ecol+Offset.
73 add_col_offset_to_position(p4(File,Line,Scol,Ecol),Offset,p4(File,Line,S2,E2)) :- !,
74 S2 is Scol+Offset, E2 is Ecol+Offset.
75 add_col_offset_to_position(p5(FN,Srow,Scol,Srow,Ecol),Offset,p4(FN,Srow,S2,E2)) :- !,
76 S2 is Scol+Offset, E2 is Ecol+Offset.
77 add_col_offset_to_position(p5(FN,Srow,Scol,Erow,Ecol),Offset,p5(FN,Srow,S2,Erow,Ecol)) :- !,
78 S2 is Scol+Offset.
79 add_col_offset_to_position(pos(BC,FN,Srow,Scol,Srow,Ecol),Offset,pos(BC,FN,Srow,S2,Srow,E2)) :- !,
80 S2 is Scol+Offset, E2 is Ecol+Offset.
81 add_col_offset_to_position(pos(BC,FN,Srow,Scol,Erow,Ecol),Offset,pos(BC,FN,Srow,S2,Erow,Ecol)) :- !,
82 S2 is Scol+Offset.
83 add_col_offset_to_position(pos_context(Span,C,S2),Offset,pos_context(Res,C,S2)) :- !,
84 add_col_offset_to_position(Span,Offset,Res).
85 add_col_offset_to_position(Span,_,Res) :- is_position(Span),!,Res=Span.
86 add_col_offset_to_position(Span,Offset,Span) :- write(cannot_add_offset_to_unknown_span(Offset,Span)),nl.
87
88
89 % add line and column offset to position:
90 add_line_col_offset_to_position(Span,0,C,R) :- !, add_col_offset_to_position(Span,C,R).
91 add_line_col_offset_to_position(p3(Line,Scol,Ecol),LineOffset,ColOffset,p3(L2,S2,E2)) :- !,
92 L2 is Line+LineOffset, S2 is ColOffset+1, % column numbers start at 1
93 E2 is Ecol-Scol+ColOffset.
94 add_line_col_offset_to_position(p4(File,Line,Scol,Ecol),LineOffset,ColOffset,p4(File,L2,S2,E2)) :- !,
95 L2 is Line+LineOffset, S2 is ColOffset+1, E2 is Ecol-Scol+ColOffset+1.
96 add_line_col_offset_to_position(p5(FN,Srow,Scol,Srow,Ecol),LineOffset,ColOffset,p4(FN,L2,S2,E2)) :- !,
97 L2 is Srow+LineOffset, S2 is ColOffset+1, E2 is Ecol-Scol+ColOffset+1.
98 add_line_col_offset_to_position(p5(FN,Srow,_Scol,Erow,Ecol),LineOffset,ColOffset,p5(FN,SL2,S2,EL2,Ecol)) :- !,
99 SL2 is Srow+LineOffset, EL2 is Erow+LineOffset, S2 is ColOffset+1.
100 add_line_col_offset_to_position(pos(BC,FN,Srow,Scol,Srow,Ecol),LineOffset,ColOffset,pos(BC,FN,L2,S2,L2,E2)) :- !,
101 L2 is Srow+LineOffset, S2 is ColOffset+1, E2 is Ecol-Scol+ColOffset+1.
102 add_line_col_offset_to_position(pos(BC,FN,Srow,_Scol,Erow,Ecol),LineOffset,ColOffset,pos(BC,FN,SL2,S2,EL2,Ecol)) :- !,
103 SL2 is Srow+LineOffset, EL2 is Erow+LineOffset, S2 is ColOffset+1.
104 add_line_col_offset_to_position(pos_context(Span,C,S2),LineOffset,ColOffset,pos_context(Res,C,S2)) :- !,
105 add_line_col_offset_to_position(Span,LineOffset,ColOffset,Res).
106 add_line_col_offset_to_position(Span,_,_,Res) :- is_position(Span),!,Res=Span.
107 add_line_col_offset_to_position(Span,LineOffset,ColOffset,Span) :-
108 write(cannot_add_offset_to_unknown_span(LineOffset,ColOffset,Span)),nl.