xfail scan-tree-dump-not throw in g++.dg/pr99966.C on hppa*64*-*-*
[official-gcc.git] / gcc / m2 / gm2-libs / Scan.mod
blob7fa801ffaadfef8ef6b8e7df6db9174580602fba
1 (* Scan.mod Provides a primitive symbol fetching from input.
3 Copyright (C) 2001-2024 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. *)
27 IMPLEMENTATION MODULE Scan ;
30 IMPORT StdIO ;
32 FROM ASCII IMPORT nul, lf, cr, bs, del, bel ;
33 FROM StdIO IMPORT Write ;
34 FROM StrLib IMPORT StrEqual, StrLen, StrCopy ;
35 FROM NumberIO IMPORT WriteCard, CardToStr ;
36 FROM FIO IMPORT OpenToRead, IsNoError, Close, File, ReadChar ;
37 FROM StrIO IMPORT WriteLn, WriteString ;
38 FROM libc IMPORT exit ;
41 CONST
42 MaxLength = 255 ; (* Max Length of Source Line *)
44 VAR
45 FileName,
46 CurrentString : ARRAY [0..MaxLength] OF CHAR ;
47 CurrentLineNo : CARDINAL ;
48 CurrentCursorPos : CARDINAL ;
49 EOF : BOOLEAN ;
50 LengthOfCurSym : CARDINAL ;
51 f : File ;
52 Opened : BOOLEAN ;
53 HaltOnError : BOOLEAN ;
54 AllowComments : BOOLEAN ;
55 CommentLeader,
56 CommentTrailer : ARRAY [0..MaxLength] OF CHAR ;
57 TerminateOnEndOfLine: BOOLEAN ;
58 InString : BOOLEAN ;
61 PROCEDURE OpenSource (a: ARRAY OF CHAR) : BOOLEAN ;
62 BEGIN
63 StrCopy(a, FileName) ;
64 f := OpenToRead(a) ;
65 IF IsNoError(f)
66 THEN
67 StrCopy( '', CurrentString ) ;
68 LengthOfCurSym := 0 ;
69 CurrentCursorPos := 0 ;
70 EOF := FALSE ;
71 CurrentLineNo := 1 ;
72 Opened := TRUE
73 ELSE
74 Opened := FALSE
75 END ;
76 RETURN( Opened )
77 END OpenSource ;
80 PROCEDURE CloseSource ;
81 BEGIN
82 IF Opened
83 THEN
84 Close( f ) ;
85 Opened := FALSE
86 END
87 END CloseSource ;
91 IsStartOfComment - returns TRUE if we are looking at the start of a comment.
94 PROCEDURE IsStartOfComment () : BOOLEAN ;
95 VAR
96 i, h: CARDINAL ;
97 BEGIN
98 IF AllowComments
99 THEN
100 i := 0 ;
101 h := StrLen(CommentLeader) ;
102 WHILE (i<h) AND (CommentLeader[i]=CurrentString[CurrentCursorPos+i]) DO
103 INC(i)
104 END ;
105 RETURN( i=h )
106 ELSE
107 RETURN( FALSE )
109 END IsStartOfComment ;
113 IsEndOfComment - returns TRUE if we can see the end of comment string.
114 If TRUE is returned then we also have consumed the string.
117 PROCEDURE IsEndOfComment () : BOOLEAN ;
119 i, h: CARDINAL ;
120 BEGIN
121 IF AllowComments
122 THEN
123 IF TerminateOnEndOfLine AND (SymbolChar()=nul)
124 THEN
125 NextChar ;
126 RETURN( TRUE )
127 ELSE
128 i := 0 ;
129 h := StrLen(CommentTrailer) ;
130 WHILE (i<h) AND (CommentTrailer[i]=CurrentString[CurrentCursorPos+i]) DO
131 INC(i)
132 END ;
133 IF (i=h) AND (h#0)
134 THEN
135 (* seen tailer therefore eat it *)
136 INC(CurrentCursorPos, i) ;
137 RETURN( TRUE )
138 ELSE
139 RETURN( FALSE )
142 ELSE
143 RETURN( FALSE )
145 END IsEndOfComment ;
149 IsQuote - returns TRUE if the current character is a quote.
152 PROCEDURE IsQuote () : BOOLEAN ;
153 BEGIN
154 RETURN( SymbolChar()='"' )
155 END IsQuote ;
159 GetNextSymbol - returns the next symbol from the source file.
160 It ignores comments and treats strings differently
161 from normal symbols. Strings will return " string ".
164 PROCEDURE GetNextSymbol (VAR a: ARRAY OF CHAR) ;
166 index,
167 High : CARDINAL ;
168 BEGIN
169 index := 0 ;
170 High := HIGH( a ) ;
171 ChuckUpToSymbol ;
173 IF InString
174 THEN
175 IF (NOT EOF) AND (NOT IsStartOfComment()) AND (index<High) AND IsQuote()
176 THEN
177 (* found final quote *)
178 a[index] := SymbolChar() ;
179 NextChar ;
180 INC(index) ;
181 InString := FALSE ;
182 ELSE
183 (* copy literal into, a *)
184 WHILE (index<High) AND (NOT EOF) AND (SymbolChar()#nul) AND (NOT IsQuote()) DO
185 a[index] := SymbolChar() ;
186 NextChar ;
187 INC(index)
188 END ;
189 IF NOT IsQuote()
190 THEN
191 WriteError('unterminated string, strings must terminate before the end of a line')
192 END ;
194 ELSE
195 IF (NOT EOF) AND (NOT IsStartOfComment())
196 THEN
197 IF (index<High) AND IsQuote()
198 THEN
199 (* found string start *)
200 a[index] := SymbolChar() ;
201 NextChar ; (* skip quote *)
202 INC(index) ;
203 InString := TRUE ;
204 ELSE
205 (* normal symbol, not a comment and not a string *)
206 WHILE (index<High) AND (NOT NonSymbolChar()) AND (NOT IsStartOfComment()) DO
207 a[index] := SymbolChar() ;
208 NextChar ;
209 INC(index)
213 END ;
214 IF index<High
215 THEN
216 a[index] := nul
217 END ;
218 LengthOfCurSym := index
219 END GetNextSymbol ;
223 ChuckUpToSymbol - throws away white space and comments.
226 PROCEDURE ChuckUpToSymbol ;
227 BEGIN
228 REPEAT
229 IF (NOT EOF) AND IsStartOfComment()
230 THEN
231 NextChar ;
232 WHILE (NOT EOF) AND (NOT IsEndOfComment()) DO
233 NextChar
235 END ;
236 WHILE (NOT EOF) AND NonSymbolChar() DO
237 NextChar
239 UNTIL EOF OR (NOT IsStartOfComment())
240 END ChuckUpToSymbol ;
244 SymbolChar - returns a character from the CurrentString, if the end
245 of CurrentString is found then SymbolChar returns nul.
248 PROCEDURE SymbolChar () : CHAR ;
249 BEGIN
250 IF EOF
251 THEN
252 RETURN( nul )
253 ELSE
254 IF CurrentCursorPos<StrLen(CurrentString)
255 THEN
256 RETURN( CurrentString[CurrentCursorPos] )
257 ELSE
258 RETURN( nul )
261 END SymbolChar ;
264 (* NextChar advances the CurrentCursorPos along a line of the source, *)
265 (* resetting the CurrentCursorPos every time a newline is read. *)
267 PROCEDURE NextChar ;
268 BEGIN
269 IF NOT EOF
270 THEN
271 IF CurrentCursorPos<StrLen(CurrentString)
272 THEN
273 INC(CurrentCursorPos)
274 ELSE
275 ReadString(CurrentString) ;
276 (* WriteString( CurrentString ) ; WriteLn ; *)
277 INC(CurrentLineNo) ;
278 CurrentCursorPos := 0 ;
279 LengthOfCurSym := 0
282 END NextChar ;
285 PROCEDURE NonSymbolChar () : BOOLEAN ;
286 BEGIN
287 RETURN( CurrentString[CurrentCursorPos]<=' ' )
288 END NonSymbolChar ;
291 PROCEDURE WriteError (a: ARRAY OF CHAR) ;
293 i, j : CARDINAL ;
294 LineNo: ARRAY [0..20] OF CHAR ;
295 BEGIN
296 WriteString(FileName) ;
297 Write(':') ;
298 CardToStr(CurrentLineNo, 0, LineNo) ;
299 WriteString(LineNo) ;
300 Write(':') ;
301 WriteString( CurrentString ) ; WriteLn ;
302 WriteString(FileName) ;
303 Write(':') ;
304 WriteString(LineNo) ;
305 Write(':') ;
306 i := 0 ;
307 j := CurrentCursorPos-LengthOfCurSym ;
308 WHILE i<j DO
309 Write(' ') ;
310 INC( i )
311 END ;
312 FOR i := 1 TO LengthOfCurSym DO
313 Write('^')
314 END ;
315 WriteLn ;
316 WriteString(FileName) ;
317 Write(':') ;
318 WriteString(LineNo) ;
319 Write(':') ;
320 WriteString( a ) ; WriteLn ;
321 IF HaltOnError
322 THEN
323 exit(1)
325 END WriteError ;
328 PROCEDURE ReadString (VAR a: ARRAY OF CHAR) ;
331 high : CARDINAL ;
332 ch : CHAR ;
333 BEGIN
334 high := HIGH( a ) ;
335 n := 0 ;
336 REPEAT
337 Read( ch ) ;
338 IF (ch=del) OR (ch=bs)
339 THEN
340 IF n=0
341 THEN
342 Write( bel )
343 ELSE
344 Write( bs ) ;
345 Write(' ') ;
346 Write( bs ) ;
347 DEC( n )
349 ELSIF n <= high
350 THEN
351 IF (ch = cr) OR (cr = lf)
352 THEN
353 a[n] := nul
354 ELSE
355 (* Write( ch ) ;
356 *) a[n] := ch
357 END ;
358 INC( n )
359 ELSE
360 ch := cr (* exit gracefully *)
362 UNTIL ch = cr
363 END ReadString ;
366 PROCEDURE Read (VAR ch: CHAR) ;
367 BEGIN
368 IF Opened
369 THEN
370 ch := ReadChar(f) ;
371 EOF := NOT IsNoError(f)
372 ELSE
373 StdIO.Read( ch )
374 END ;
375 IF ch=lf THEN ch := cr END
376 END Read ;
380 TerminateOnError - exits with status 1 if we call WriteError.
383 PROCEDURE TerminateOnError ;
384 BEGIN
385 HaltOnError := TRUE
386 END TerminateOnError ;
390 DefineComments - defines the start of comments within the source
391 file.
393 The characters in Start define the comment start
394 and characters in End define the end.
395 The BOOLEAN eoln determine whether the comment
396 is terminated by end of line. If eoln is TRUE
397 then End is ignored.
400 PROCEDURE DefineComments (Start, End: ARRAY OF CHAR; eoln: BOOLEAN) ;
401 BEGIN
402 TerminateOnEndOfLine := eoln ;
403 StrCopy(Start, CommentLeader) ;
404 StrCopy(End, CommentTrailer) ;
405 AllowComments := StrLen(CommentLeader)>0
406 END DefineComments ;
409 BEGIN
410 InString := FALSE ;
411 AllowComments := FALSE ;
412 TerminateOnEndOfLine := FALSE ;
413 StrCopy('' , CurrentString) ;
414 LengthOfCurSym := 0 ;
415 CurrentCursorPos := 0 ;
416 EOF := FALSE ;
417 CurrentLineNo := 1 ;
418 Opened := FALSE ;
419 HaltOnError := FALSE
420 END Scan.