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. |