PR rtl-optimization/82913
[official-gcc.git] / gcc / ada / libgnat / a-tigeau.adb
blob34dac8bf5e7b16e49c4f7d9db89cd9b63c04eaa5
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- A D A . T E X T _ I O . G E N E R I C _ A U X --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2017, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
21 -- --
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/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
32 with Interfaces.C_Streams; use Interfaces.C_Streams;
33 with System.File_IO;
34 with System.File_Control_Block;
36 package body Ada.Text_IO.Generic_Aux is
38 package FIO renames System.File_IO;
39 package FCB renames System.File_Control_Block;
40 subtype AP is FCB.AFCB_Ptr;
42 ------------------------
43 -- Check_End_Of_Field --
44 ------------------------
46 procedure Check_End_Of_Field
47 (Buf : String;
48 Stop : Integer;
49 Ptr : Integer;
50 Width : Field)
52 begin
53 if Ptr > Stop then
54 return;
56 elsif Width = 0 then
57 raise Data_Error;
59 else
60 for J in Ptr .. Stop loop
61 if not Is_Blank (Buf (J)) then
62 raise Data_Error;
63 end if;
64 end loop;
65 end if;
66 end Check_End_Of_Field;
68 -----------------------
69 -- Check_On_One_Line --
70 -----------------------
72 procedure Check_On_One_Line
73 (File : File_Type;
74 Length : Integer)
76 begin
77 FIO.Check_Write_Status (AP (File));
79 if File.Line_Length /= 0 then
80 if Count (Length) > File.Line_Length then
81 raise Layout_Error;
82 elsif File.Col + Count (Length) > File.Line_Length + 1 then
83 New_Line (File);
84 end if;
85 end if;
86 end Check_On_One_Line;
88 ----------
89 -- Getc --
90 ----------
92 function Getc (File : File_Type) return int is
93 ch : int;
95 begin
96 ch := fgetc (File.Stream);
98 if ch = EOF and then ferror (File.Stream) /= 0 then
99 raise Device_Error;
100 else
101 return ch;
102 end if;
103 end Getc;
105 --------------
106 -- Is_Blank --
107 --------------
109 function Is_Blank (C : Character) return Boolean is
110 begin
111 return C = ' ' or else C = ASCII.HT;
112 end Is_Blank;
114 ----------
115 -- Load --
116 ----------
118 procedure Load
119 (File : File_Type;
120 Buf : out String;
121 Ptr : in out Integer;
122 Char : Character;
123 Loaded : out Boolean)
125 ch : int;
127 begin
128 ch := Getc (File);
130 if ch = Character'Pos (Char) then
131 Store_Char (File, ch, Buf, Ptr);
132 Loaded := True;
133 else
134 Ungetc (ch, File);
135 Loaded := False;
136 end if;
137 end Load;
139 procedure Load
140 (File : File_Type;
141 Buf : out String;
142 Ptr : in out Integer;
143 Char : Character)
145 ch : int;
147 begin
148 ch := Getc (File);
150 if ch = Character'Pos (Char) then
151 Store_Char (File, ch, Buf, Ptr);
152 else
153 Ungetc (ch, File);
154 end if;
155 end Load;
157 procedure Load
158 (File : File_Type;
159 Buf : out String;
160 Ptr : in out Integer;
161 Char1 : Character;
162 Char2 : Character;
163 Loaded : out Boolean)
165 ch : int;
167 begin
168 ch := Getc (File);
170 if ch = Character'Pos (Char1) or else ch = Character'Pos (Char2) then
171 Store_Char (File, ch, Buf, Ptr);
172 Loaded := True;
173 else
174 Ungetc (ch, File);
175 Loaded := False;
176 end if;
177 end Load;
179 procedure Load
180 (File : File_Type;
181 Buf : out String;
182 Ptr : in out Integer;
183 Char1 : Character;
184 Char2 : Character)
186 ch : int;
188 begin
189 ch := Getc (File);
191 if ch = Character'Pos (Char1) or else ch = Character'Pos (Char2) then
192 Store_Char (File, ch, Buf, Ptr);
193 else
194 Ungetc (ch, File);
195 end if;
196 end Load;
198 -----------------
199 -- Load_Digits --
200 -----------------
202 procedure Load_Digits
203 (File : File_Type;
204 Buf : out String;
205 Ptr : in out Integer;
206 Loaded : out Boolean)
208 ch : int;
209 After_Digit : Boolean;
211 begin
212 ch := Getc (File);
214 if ch not in Character'Pos ('0') .. Character'Pos ('9') then
215 Loaded := False;
217 else
218 Loaded := True;
219 After_Digit := True;
221 loop
222 Store_Char (File, ch, Buf, Ptr);
223 ch := Getc (File);
225 if ch in Character'Pos ('0') .. Character'Pos ('9') then
226 After_Digit := True;
228 elsif ch = Character'Pos ('_') and then After_Digit then
229 After_Digit := False;
231 else
232 exit;
233 end if;
234 end loop;
235 end if;
237 Ungetc (ch, File);
238 end Load_Digits;
240 procedure Load_Digits
241 (File : File_Type;
242 Buf : out String;
243 Ptr : in out Integer)
245 ch : int;
246 After_Digit : Boolean;
248 begin
249 ch := Getc (File);
251 if ch in Character'Pos ('0') .. Character'Pos ('9') then
252 After_Digit := True;
254 loop
255 Store_Char (File, ch, Buf, Ptr);
256 ch := Getc (File);
258 if ch in Character'Pos ('0') .. Character'Pos ('9') then
259 After_Digit := True;
261 elsif ch = Character'Pos ('_') and then After_Digit then
262 After_Digit := False;
264 else
265 exit;
266 end if;
267 end loop;
268 end if;
270 Ungetc (ch, File);
271 end Load_Digits;
273 --------------------------
274 -- Load_Extended_Digits --
275 --------------------------
277 procedure Load_Extended_Digits
278 (File : File_Type;
279 Buf : out String;
280 Ptr : in out Integer;
281 Loaded : out Boolean)
283 ch : int;
284 After_Digit : Boolean := False;
286 begin
287 Loaded := False;
289 loop
290 ch := Getc (File);
292 if ch in Character'Pos ('0') .. Character'Pos ('9')
293 or else
294 ch in Character'Pos ('a') .. Character'Pos ('f')
295 or else
296 ch in Character'Pos ('A') .. Character'Pos ('F')
297 then
298 After_Digit := True;
300 elsif ch = Character'Pos ('_') and then After_Digit then
301 After_Digit := False;
303 else
304 exit;
305 end if;
307 Store_Char (File, ch, Buf, Ptr);
308 Loaded := True;
309 end loop;
311 Ungetc (ch, File);
312 end Load_Extended_Digits;
314 procedure Load_Extended_Digits
315 (File : File_Type;
316 Buf : out String;
317 Ptr : in out Integer)
319 Junk : Boolean;
320 pragma Unreferenced (Junk);
321 begin
322 Load_Extended_Digits (File, Buf, Ptr, Junk);
323 end Load_Extended_Digits;
325 ---------------
326 -- Load_Skip --
327 ---------------
329 procedure Load_Skip (File : File_Type) is
330 C : Character;
332 begin
333 FIO.Check_Read_Status (AP (File));
335 -- Loop till we find a non-blank character (note that as usual in
336 -- Text_IO, blank includes horizontal tab). Note that Get deals with
337 -- the Before_LM and Before_LM_PM flags appropriately.
339 loop
340 Get (File, C);
341 exit when not Is_Blank (C);
342 end loop;
344 Ungetc (Character'Pos (C), File);
345 File.Col := File.Col - 1;
346 end Load_Skip;
348 ----------------
349 -- Load_Width --
350 ----------------
352 procedure Load_Width
353 (File : File_Type;
354 Width : Field;
355 Buf : out String;
356 Ptr : in out Integer)
358 ch : int;
360 begin
361 FIO.Check_Read_Status (AP (File));
363 -- If we are immediately before a line mark, then we have no characters.
364 -- This is always a data error, so we may as well raise it right away.
366 if File.Before_LM then
367 raise Data_Error;
369 else
370 for J in 1 .. Width loop
371 ch := Getc (File);
373 if ch = EOF then
374 return;
376 elsif ch = LM then
377 Ungetc (ch, File);
378 return;
380 else
381 Store_Char (File, ch, Buf, Ptr);
382 end if;
383 end loop;
384 end if;
385 end Load_Width;
387 -----------
388 -- Nextc --
389 -----------
391 function Nextc (File : File_Type) return int is
392 ch : int;
394 begin
395 ch := fgetc (File.Stream);
397 if ch = EOF then
398 if ferror (File.Stream) /= 0 then
399 raise Device_Error;
400 else
401 return EOF;
402 end if;
404 else
405 Ungetc (ch, File);
406 return ch;
407 end if;
408 end Nextc;
410 --------------
411 -- Put_Item --
412 --------------
414 procedure Put_Item (File : File_Type; Str : String) is
415 begin
416 Check_On_One_Line (File, Str'Length);
417 Put (File, Str);
418 end Put_Item;
420 ----------------
421 -- Store_Char --
422 ----------------
424 procedure Store_Char
425 (File : File_Type;
426 ch : int;
427 Buf : in out String;
428 Ptr : in out Integer)
430 begin
431 File.Col := File.Col + 1;
433 if Ptr < Buf'Last then
434 Ptr := Ptr + 1;
435 end if;
437 Buf (Ptr) := Character'Val (ch);
438 end Store_Char;
440 -----------------
441 -- String_Skip --
442 -----------------
444 procedure String_Skip (Str : String; Ptr : out Integer) is
445 begin
446 -- Routines calling String_Skip malfunction if Str'Last = Positive'Last.
447 -- It's too much trouble to make this silly case work, so we just raise
448 -- Program_Error with an appropriate message. We raise Program_Error
449 -- rather than Constraint_Error because we don't want this case to be
450 -- converted to Data_Error.
452 if Str'Last = Positive'Last then
453 raise Program_Error with
454 "string upper bound is Positive'Last, not supported";
455 end if;
457 -- Normal case where Str'Last < Positive'Last
459 Ptr := Str'First;
461 loop
462 if Ptr > Str'Last then
463 raise End_Error;
465 elsif not Is_Blank (Str (Ptr)) then
466 return;
468 else
469 Ptr := Ptr + 1;
470 end if;
471 end loop;
472 end String_Skip;
474 ------------
475 -- Ungetc --
476 ------------
478 procedure Ungetc (ch : int; File : File_Type) is
479 begin
480 if ch /= EOF then
481 if ungetc (ch, File.Stream) = EOF then
482 raise Device_Error;
483 end if;
484 end if;
485 end Ungetc;
487 end Ada.Text_IO.Generic_Aux;