comparison gcc/ada/libgnat/a-ztgeau.adb @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- A D A . W I D E _ W I D E _ 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 ------------------------------------------------------------------------------
31
32 with Interfaces.C_Streams; use Interfaces.C_Streams;
33 with System.File_IO;
34 with System.File_Control_Block;
35
36 package body Ada.Wide_Wide_Text_IO.Generic_Aux is
37
38 package FIO renames System.File_IO;
39 package FCB renames System.File_Control_Block;
40 subtype AP is FCB.AFCB_Ptr;
41
42 ------------------------
43 -- Check_End_Of_Field --
44 ------------------------
45
46 procedure Check_End_Of_Field
47 (Buf : String;
48 Stop : Integer;
49 Ptr : Integer;
50 Width : Field)
51 is
52 begin
53 if Ptr > Stop then
54 return;
55
56 elsif Width = 0 then
57 raise Data_Error;
58
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;
67
68 -----------------------
69 -- Check_On_One_Line --
70 -----------------------
71
72 procedure Check_On_One_Line
73 (File : File_Type;
74 Length : Integer)
75 is
76 begin
77 FIO.Check_Write_Status (AP (File));
78
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;
87
88 --------------
89 -- Is_Blank --
90 --------------
91
92 function Is_Blank (C : Character) return Boolean is
93 begin
94 return C = ' ' or else C = ASCII.HT;
95 end Is_Blank;
96
97 ----------
98 -- Load --
99 ----------
100
101 procedure Load
102 (File : File_Type;
103 Buf : out String;
104 Ptr : in out Integer;
105 Char : Character;
106 Loaded : out Boolean)
107 is
108 ch : int;
109
110 begin
111 if File.Before_Wide_Wide_Character then
112 Loaded := False;
113 return;
114
115 else
116 ch := Getc (File);
117
118 if ch = Character'Pos (Char) then
119 Store_Char (File, ch, Buf, Ptr);
120 Loaded := True;
121 else
122 Ungetc (ch, File);
123 Loaded := False;
124 end if;
125 end if;
126 end Load;
127
128 procedure Load
129 (File : File_Type;
130 Buf : out String;
131 Ptr : in out Integer;
132 Char : Character)
133 is
134 ch : int;
135
136 begin
137 if File.Before_Wide_Wide_Character then
138 null;
139
140 else
141 ch := Getc (File);
142
143 if ch = Character'Pos (Char) then
144 Store_Char (File, ch, Buf, Ptr);
145 else
146 Ungetc (ch, File);
147 end if;
148 end if;
149 end Load;
150
151 procedure Load
152 (File : File_Type;
153 Buf : out String;
154 Ptr : in out Integer;
155 Char1 : Character;
156 Char2 : Character;
157 Loaded : out Boolean)
158 is
159 ch : int;
160
161 begin
162 if File.Before_Wide_Wide_Character then
163 Loaded := False;
164 return;
165
166 else
167 ch := Getc (File);
168
169 if ch = Character'Pos (Char1)
170 or else ch = Character'Pos (Char2)
171 then
172 Store_Char (File, ch, Buf, Ptr);
173 Loaded := True;
174 else
175 Ungetc (ch, File);
176 Loaded := False;
177 end if;
178 end if;
179 end Load;
180
181 procedure Load
182 (File : File_Type;
183 Buf : out String;
184 Ptr : in out Integer;
185 Char1 : Character;
186 Char2 : Character)
187 is
188 ch : int;
189
190 begin
191 if File.Before_Wide_Wide_Character then
192 null;
193
194 else
195 ch := Getc (File);
196
197 if ch = Character'Pos (Char1)
198 or else ch = Character'Pos (Char2)
199 then
200 Store_Char (File, ch, Buf, Ptr);
201 else
202 Ungetc (ch, File);
203 end if;
204 end if;
205 end Load;
206
207 -----------------
208 -- Load_Digits --
209 -----------------
210
211 procedure Load_Digits
212 (File : File_Type;
213 Buf : out String;
214 Ptr : in out Integer;
215 Loaded : out Boolean)
216 is
217 ch : int;
218 After_Digit : Boolean;
219
220 begin
221 if File.Before_Wide_Wide_Character then
222 Loaded := False;
223 return;
224
225 else
226 ch := Getc (File);
227
228 if ch not in Character'Pos ('0') .. Character'Pos ('9') then
229 Loaded := False;
230
231 else
232 Loaded := True;
233 After_Digit := True;
234
235 loop
236 Store_Char (File, ch, Buf, Ptr);
237 ch := Getc (File);
238
239 if ch in Character'Pos ('0') .. Character'Pos ('9') then
240 After_Digit := True;
241
242 elsif ch = Character'Pos ('_') and then After_Digit then
243 After_Digit := False;
244
245 else
246 exit;
247 end if;
248 end loop;
249 end if;
250
251 Ungetc (ch, File);
252 end if;
253 end Load_Digits;
254
255 procedure Load_Digits
256 (File : File_Type;
257 Buf : out String;
258 Ptr : in out Integer)
259 is
260 ch : int;
261 After_Digit : Boolean;
262
263 begin
264 if File.Before_Wide_Wide_Character then
265 return;
266
267 else
268 ch := Getc (File);
269
270 if ch in Character'Pos ('0') .. Character'Pos ('9') then
271 After_Digit := True;
272
273 loop
274 Store_Char (File, ch, Buf, Ptr);
275 ch := Getc (File);
276
277 if ch in Character'Pos ('0') .. Character'Pos ('9') then
278 After_Digit := True;
279
280 elsif ch = Character'Pos ('_') and then After_Digit then
281 After_Digit := False;
282
283 else
284 exit;
285 end if;
286 end loop;
287 end if;
288
289 Ungetc (ch, File);
290 end if;
291 end Load_Digits;
292
293 --------------------------
294 -- Load_Extended_Digits --
295 --------------------------
296
297 procedure Load_Extended_Digits
298 (File : File_Type;
299 Buf : out String;
300 Ptr : in out Integer;
301 Loaded : out Boolean)
302 is
303 ch : int;
304 After_Digit : Boolean := False;
305
306 begin
307 if File.Before_Wide_Wide_Character then
308 Loaded := False;
309 return;
310
311 else
312 Loaded := False;
313
314 loop
315 ch := Getc (File);
316
317 if ch in Character'Pos ('0') .. Character'Pos ('9')
318 or else
319 ch in Character'Pos ('a') .. Character'Pos ('f')
320 or else
321 ch in Character'Pos ('A') .. Character'Pos ('F')
322 then
323 After_Digit := True;
324
325 elsif ch = Character'Pos ('_') and then After_Digit then
326 After_Digit := False;
327
328 else
329 exit;
330 end if;
331
332 Store_Char (File, ch, Buf, Ptr);
333 Loaded := True;
334 end loop;
335
336 Ungetc (ch, File);
337 end if;
338 end Load_Extended_Digits;
339
340 procedure Load_Extended_Digits
341 (File : File_Type;
342 Buf : out String;
343 Ptr : in out Integer)
344 is
345 Junk : Boolean;
346 pragma Unreferenced (Junk);
347 begin
348 Load_Extended_Digits (File, Buf, Ptr, Junk);
349 end Load_Extended_Digits;
350
351 ---------------
352 -- Load_Skip --
353 ---------------
354
355 procedure Load_Skip (File : File_Type) is
356 C : Character;
357
358 begin
359 FIO.Check_Read_Status (AP (File));
360
361 -- We need to explicitly test for the case of being before a wide
362 -- character (greater than 16#7F#). Since no such character can
363 -- ever legitimately be a valid numeric character, we can
364 -- immediately signal Data_Error.
365
366 if File.Before_Wide_Wide_Character then
367 raise Data_Error;
368 end if;
369
370 -- Otherwise loop till we find a non-blank character (note that as
371 -- usual in Wide_Wide_Text_IO, blank includes horizontal tab). Note that
372 -- Get_Character deals with Before_LM/Before_LM_PM flags appropriately.
373
374 loop
375 Get_Character (File, C);
376 exit when not Is_Blank (C);
377 end loop;
378
379 Ungetc (Character'Pos (C), File);
380 File.Col := File.Col - 1;
381 end Load_Skip;
382
383 ----------------
384 -- Load_Width --
385 ----------------
386
387 procedure Load_Width
388 (File : File_Type;
389 Width : Field;
390 Buf : out String;
391 Ptr : in out Integer)
392 is
393 ch : int;
394 WC : Wide_Wide_Character;
395
396 Bad_Wide_Wide_C : Boolean := False;
397 -- Set True if one of the characters read is not in range of type
398 -- Character. This is always a Data_Error, but we do not signal it
399 -- right away, since we have to read the full number of characters.
400
401 begin
402 FIO.Check_Read_Status (AP (File));
403
404 -- If we are immediately before a line mark, then we have no characters.
405 -- This is always a data error, so we may as well raise it right away.
406
407 if File.Before_LM then
408 raise Data_Error;
409
410 else
411 for J in 1 .. Width loop
412 if File.Before_Wide_Wide_Character then
413 Bad_Wide_Wide_C := True;
414 Store_Char (File, 0, Buf, Ptr);
415 File.Before_Wide_Wide_Character := False;
416
417 else
418 ch := Getc (File);
419
420 if ch = EOF then
421 exit;
422
423 elsif ch = LM then
424 Ungetc (ch, File);
425 exit;
426
427 else
428 WC := Get_Wide_Wide_Char (Character'Val (ch), File);
429 ch := Wide_Wide_Character'Pos (WC);
430
431 if ch > 255 then
432 Bad_Wide_Wide_C := True;
433 ch := 0;
434 end if;
435
436 Store_Char (File, ch, Buf, Ptr);
437 end if;
438 end if;
439 end loop;
440
441 if Bad_Wide_Wide_C then
442 raise Data_Error;
443 end if;
444 end if;
445 end Load_Width;
446
447 --------------
448 -- Put_Item --
449 --------------
450
451 procedure Put_Item (File : File_Type; Str : String) is
452 begin
453 Check_On_One_Line (File, Str'Length);
454
455 for J in Str'Range loop
456 Put (File, Wide_Wide_Character'Val (Character'Pos (Str (J))));
457 end loop;
458 end Put_Item;
459
460 ----------------
461 -- Store_Char --
462 ----------------
463
464 procedure Store_Char
465 (File : File_Type;
466 ch : Integer;
467 Buf : out String;
468 Ptr : in out Integer)
469 is
470 begin
471 File.Col := File.Col + 1;
472
473 if Ptr = Buf'Last then
474 raise Data_Error;
475 else
476 Ptr := Ptr + 1;
477 Buf (Ptr) := Character'Val (ch);
478 end if;
479 end Store_Char;
480
481 -----------------
482 -- String_Skip --
483 -----------------
484
485 procedure String_Skip (Str : String; Ptr : out Integer) is
486 begin
487 -- Routines calling String_Skip malfunction if Str'Last = Positive'Last.
488 -- It's too much trouble to make this silly case work, so we just raise
489 -- Program_Error with an appropriate message. We raise Program_Error
490 -- rather than Constraint_Error because we don't want this case to be
491 -- converted to Data_Error.
492
493 if Str'Last = Positive'Last then
494 raise Program_Error with
495 "string upper bound is Positive'Last, not supported";
496 end if;
497
498 -- Normal case where Str'Last < Positive'Last
499
500 Ptr := Str'First;
501
502 loop
503 if Ptr > Str'Last then
504 raise End_Error;
505
506 elsif not Is_Blank (Str (Ptr)) then
507 return;
508
509 else
510 Ptr := Ptr + 1;
511 end if;
512 end loop;
513 end String_Skip;
514
515 ------------
516 -- Ungetc --
517 ------------
518
519 procedure Ungetc (ch : int; File : File_Type) is
520 begin
521 if ch /= EOF then
522 if ungetc (ch, File.Stream) = EOF then
523 raise Device_Error;
524 end if;
525 end if;
526 end Ungetc;
527
528 end Ada.Wide_Wide_Text_IO.Generic_Aux;