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