comparison gcc/ada/libgnat/g-spitbo.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 LIBRARY COMPONENTS --
4 -- --
5 -- G N A T . S P I T B O L --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1998-2017, AdaCore --
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 Ada.Strings; use Ada.Strings;
33 with Ada.Strings.Unbounded.Aux; use Ada.Strings.Unbounded.Aux;
34
35 with GNAT.Debug_Utilities; use GNAT.Debug_Utilities;
36 with GNAT.IO; use GNAT.IO;
37
38 with System.String_Hash;
39
40 with Ada.Unchecked_Deallocation;
41
42 package body GNAT.Spitbol is
43
44 ---------
45 -- "&" --
46 ---------
47
48 function "&" (Num : Integer; Str : String) return String is
49 begin
50 return S (Num) & Str;
51 end "&";
52
53 function "&" (Str : String; Num : Integer) return String is
54 begin
55 return Str & S (Num);
56 end "&";
57
58 function "&" (Num : Integer; Str : VString) return VString is
59 begin
60 return S (Num) & Str;
61 end "&";
62
63 function "&" (Str : VString; Num : Integer) return VString is
64 begin
65 return Str & S (Num);
66 end "&";
67
68 ----------
69 -- Char --
70 ----------
71
72 function Char (Num : Natural) return Character is
73 begin
74 return Character'Val (Num);
75 end Char;
76
77 ----------
78 -- Lpad --
79 ----------
80
81 function Lpad
82 (Str : VString;
83 Len : Natural;
84 Pad : Character := ' ') return VString
85 is
86 begin
87 if Length (Str) >= Len then
88 return Str;
89 else
90 return Tail (Str, Len, Pad);
91 end if;
92 end Lpad;
93
94 function Lpad
95 (Str : String;
96 Len : Natural;
97 Pad : Character := ' ') return VString
98 is
99 begin
100 if Str'Length >= Len then
101 return V (Str);
102
103 else
104 declare
105 R : String (1 .. Len);
106
107 begin
108 for J in 1 .. Len - Str'Length loop
109 R (J) := Pad;
110 end loop;
111
112 R (Len - Str'Length + 1 .. Len) := Str;
113 return V (R);
114 end;
115 end if;
116 end Lpad;
117
118 procedure Lpad
119 (Str : in out VString;
120 Len : Natural;
121 Pad : Character := ' ')
122 is
123 begin
124 if Length (Str) >= Len then
125 return;
126 else
127 Tail (Str, Len, Pad);
128 end if;
129 end Lpad;
130
131 -------
132 -- N --
133 -------
134
135 function N (Str : VString) return Integer is
136 S : Big_String_Access;
137 L : Natural;
138 begin
139 Get_String (Str, S, L);
140 return Integer'Value (S (1 .. L));
141 end N;
142
143 --------------------
144 -- Reverse_String --
145 --------------------
146
147 function Reverse_String (Str : VString) return VString is
148 S : Big_String_Access;
149 L : Natural;
150
151 begin
152 Get_String (Str, S, L);
153
154 declare
155 Result : String (1 .. L);
156
157 begin
158 for J in 1 .. L loop
159 Result (J) := S (L + 1 - J);
160 end loop;
161
162 return V (Result);
163 end;
164 end Reverse_String;
165
166 function Reverse_String (Str : String) return VString is
167 Result : String (1 .. Str'Length);
168
169 begin
170 for J in 1 .. Str'Length loop
171 Result (J) := Str (Str'Last + 1 - J);
172 end loop;
173
174 return V (Result);
175 end Reverse_String;
176
177 procedure Reverse_String (Str : in out VString) is
178 S : Big_String_Access;
179 L : Natural;
180
181 begin
182 Get_String (Str, S, L);
183
184 declare
185 Result : String (1 .. L);
186
187 begin
188 for J in 1 .. L loop
189 Result (J) := S (L + 1 - J);
190 end loop;
191
192 Set_Unbounded_String (Str, Result);
193 end;
194 end Reverse_String;
195
196 ----------
197 -- Rpad --
198 ----------
199
200 function Rpad
201 (Str : VString;
202 Len : Natural;
203 Pad : Character := ' ') return VString
204 is
205 begin
206 if Length (Str) >= Len then
207 return Str;
208 else
209 return Head (Str, Len, Pad);
210 end if;
211 end Rpad;
212
213 function Rpad
214 (Str : String;
215 Len : Natural;
216 Pad : Character := ' ') return VString
217 is
218 begin
219 if Str'Length >= Len then
220 return V (Str);
221
222 else
223 declare
224 R : String (1 .. Len);
225
226 begin
227 for J in Str'Length + 1 .. Len loop
228 R (J) := Pad;
229 end loop;
230
231 R (1 .. Str'Length) := Str;
232 return V (R);
233 end;
234 end if;
235 end Rpad;
236
237 procedure Rpad
238 (Str : in out VString;
239 Len : Natural;
240 Pad : Character := ' ')
241 is
242 begin
243 if Length (Str) >= Len then
244 return;
245
246 else
247 Head (Str, Len, Pad);
248 end if;
249 end Rpad;
250
251 -------
252 -- S --
253 -------
254
255 function S (Num : Integer) return String is
256 Buf : String (1 .. 30);
257 Ptr : Natural := Buf'Last + 1;
258 Val : Natural := abs (Num);
259
260 begin
261 loop
262 Ptr := Ptr - 1;
263 Buf (Ptr) := Character'Val (Val mod 10 + Character'Pos ('0'));
264 Val := Val / 10;
265 exit when Val = 0;
266 end loop;
267
268 if Num < 0 then
269 Ptr := Ptr - 1;
270 Buf (Ptr) := '-';
271 end if;
272
273 return Buf (Ptr .. Buf'Last);
274 end S;
275
276 ------------
277 -- Substr --
278 ------------
279
280 function Substr
281 (Str : VString;
282 Start : Positive;
283 Len : Natural) return VString
284 is
285 S : Big_String_Access;
286 L : Natural;
287
288 begin
289 Get_String (Str, S, L);
290
291 if Start > L then
292 raise Index_Error;
293 elsif Start + Len - 1 > L then
294 raise Length_Error;
295 else
296 return V (S (Start .. Start + Len - 1));
297 end if;
298 end Substr;
299
300 function Substr
301 (Str : String;
302 Start : Positive;
303 Len : Natural) return VString
304 is
305 begin
306 if Start > Str'Length then
307 raise Index_Error;
308 elsif Start + Len - 1 > Str'Length then
309 raise Length_Error;
310 else
311 return
312 V (Str (Str'First + Start - 1 .. Str'First + Start + Len - 2));
313 end if;
314 end Substr;
315
316 -----------
317 -- Table --
318 -----------
319
320 package body Table is
321
322 procedure Free is new
323 Ada.Unchecked_Deallocation (Hash_Element, Hash_Element_Ptr);
324
325 -----------------------
326 -- Local Subprograms --
327 -----------------------
328
329 function Hash is new System.String_Hash.Hash
330 (Character, String, Unsigned_32);
331
332 ------------
333 -- Adjust --
334 ------------
335
336 overriding procedure Adjust (Object : in out Table) is
337 Ptr1 : Hash_Element_Ptr;
338 Ptr2 : Hash_Element_Ptr;
339
340 begin
341 for J in Object.Elmts'Range loop
342 Ptr1 := Object.Elmts (J)'Unrestricted_Access;
343
344 if Ptr1.Name /= null then
345 loop
346 Ptr1.Name := new String'(Ptr1.Name.all);
347 exit when Ptr1.Next = null;
348 Ptr2 := Ptr1.Next;
349 Ptr1.Next := new Hash_Element'(Ptr2.all);
350 Ptr1 := Ptr1.Next;
351 end loop;
352 end if;
353 end loop;
354 end Adjust;
355
356 -----------
357 -- Clear --
358 -----------
359
360 procedure Clear (T : in out Table) is
361 Ptr1 : Hash_Element_Ptr;
362 Ptr2 : Hash_Element_Ptr;
363
364 begin
365 for J in T.Elmts'Range loop
366 if T.Elmts (J).Name /= null then
367 Free (T.Elmts (J).Name);
368 T.Elmts (J).Value := Null_Value;
369
370 Ptr1 := T.Elmts (J).Next;
371 T.Elmts (J).Next := null;
372
373 while Ptr1 /= null loop
374 Ptr2 := Ptr1.Next;
375 Free (Ptr1.Name);
376 Free (Ptr1);
377 Ptr1 := Ptr2;
378 end loop;
379 end if;
380 end loop;
381 end Clear;
382
383 ----------------------
384 -- Convert_To_Array --
385 ----------------------
386
387 function Convert_To_Array (T : Table) return Table_Array is
388 Num_Elmts : Natural := 0;
389 Elmt : Hash_Element_Ptr;
390
391 begin
392 for J in T.Elmts'Range loop
393 Elmt := T.Elmts (J)'Unrestricted_Access;
394
395 if Elmt.Name /= null then
396 loop
397 Num_Elmts := Num_Elmts + 1;
398 Elmt := Elmt.Next;
399 exit when Elmt = null;
400 end loop;
401 end if;
402 end loop;
403
404 declare
405 TA : Table_Array (1 .. Num_Elmts);
406 P : Natural := 1;
407
408 begin
409 for J in T.Elmts'Range loop
410 Elmt := T.Elmts (J)'Unrestricted_Access;
411
412 if Elmt.Name /= null then
413 loop
414 Set_Unbounded_String (TA (P).Name, Elmt.Name.all);
415 TA (P).Value := Elmt.Value;
416 P := P + 1;
417 Elmt := Elmt.Next;
418 exit when Elmt = null;
419 end loop;
420 end if;
421 end loop;
422
423 return TA;
424 end;
425 end Convert_To_Array;
426
427 ----------
428 -- Copy --
429 ----------
430
431 procedure Copy (From : Table; To : in out Table) is
432 Elmt : Hash_Element_Ptr;
433
434 begin
435 Clear (To);
436
437 for J in From.Elmts'Range loop
438 Elmt := From.Elmts (J)'Unrestricted_Access;
439 if Elmt.Name /= null then
440 loop
441 Set (To, Elmt.Name.all, Elmt.Value);
442 Elmt := Elmt.Next;
443 exit when Elmt = null;
444 end loop;
445 end if;
446 end loop;
447 end Copy;
448
449 ------------
450 -- Delete --
451 ------------
452
453 procedure Delete (T : in out Table; Name : Character) is
454 begin
455 Delete (T, String'(1 => Name));
456 end Delete;
457
458 procedure Delete (T : in out Table; Name : VString) is
459 S : Big_String_Access;
460 L : Natural;
461 begin
462 Get_String (Name, S, L);
463 Delete (T, S (1 .. L));
464 end Delete;
465
466 procedure Delete (T : in out Table; Name : String) is
467 Slot : constant Unsigned_32 := Hash (Name) mod T.N + 1;
468 Elmt : Hash_Element_Ptr := T.Elmts (Slot)'Unrestricted_Access;
469 Next : Hash_Element_Ptr;
470
471 begin
472 if Elmt.Name = null then
473 null;
474
475 elsif Elmt.Name.all = Name then
476 Free (Elmt.Name);
477
478 if Elmt.Next = null then
479 Elmt.Value := Null_Value;
480 return;
481
482 else
483 Next := Elmt.Next;
484 Elmt.Name := Next.Name;
485 Elmt.Value := Next.Value;
486 Elmt.Next := Next.Next;
487 Free (Next);
488 return;
489 end if;
490
491 else
492 loop
493 Next := Elmt.Next;
494
495 if Next = null then
496 return;
497
498 elsif Next.Name.all = Name then
499 Free (Next.Name);
500 Elmt.Next := Next.Next;
501 Free (Next);
502 return;
503
504 else
505 Elmt := Next;
506 end if;
507 end loop;
508 end if;
509 end Delete;
510
511 ----------
512 -- Dump --
513 ----------
514
515 procedure Dump (T : Table; Str : String := "Table") is
516 Num_Elmts : Natural := 0;
517 Elmt : Hash_Element_Ptr;
518
519 begin
520 for J in T.Elmts'Range loop
521 Elmt := T.Elmts (J)'Unrestricted_Access;
522
523 if Elmt.Name /= null then
524 loop
525 Num_Elmts := Num_Elmts + 1;
526 Put_Line
527 (Str & '<' & Image (Elmt.Name.all) & "> = " &
528 Img (Elmt.Value));
529 Elmt := Elmt.Next;
530 exit when Elmt = null;
531 end loop;
532 end if;
533 end loop;
534
535 if Num_Elmts = 0 then
536 Put_Line (Str & " is empty");
537 end if;
538 end Dump;
539
540 procedure Dump (T : Table_Array; Str : String := "Table_Array") is
541 begin
542 if T'Length = 0 then
543 Put_Line (Str & " is empty");
544
545 else
546 for J in T'Range loop
547 Put_Line
548 (Str & '(' & Image (To_String (T (J).Name)) & ") = " &
549 Img (T (J).Value));
550 end loop;
551 end if;
552 end Dump;
553
554 --------------
555 -- Finalize --
556 --------------
557
558 overriding procedure Finalize (Object : in out Table) is
559 Ptr1 : Hash_Element_Ptr;
560 Ptr2 : Hash_Element_Ptr;
561
562 begin
563 for J in Object.Elmts'Range loop
564 Ptr1 := Object.Elmts (J).Next;
565 Free (Object.Elmts (J).Name);
566 while Ptr1 /= null loop
567 Ptr2 := Ptr1.Next;
568 Free (Ptr1.Name);
569 Free (Ptr1);
570 Ptr1 := Ptr2;
571 end loop;
572 end loop;
573 end Finalize;
574
575 ---------
576 -- Get --
577 ---------
578
579 function Get (T : Table; Name : Character) return Value_Type is
580 begin
581 return Get (T, String'(1 => Name));
582 end Get;
583
584 function Get (T : Table; Name : VString) return Value_Type is
585 S : Big_String_Access;
586 L : Natural;
587 begin
588 Get_String (Name, S, L);
589 return Get (T, S (1 .. L));
590 end Get;
591
592 function Get (T : Table; Name : String) return Value_Type is
593 Slot : constant Unsigned_32 := Hash (Name) mod T.N + 1;
594 Elmt : Hash_Element_Ptr := T.Elmts (Slot)'Unrestricted_Access;
595
596 begin
597 if Elmt.Name = null then
598 return Null_Value;
599
600 else
601 loop
602 if Name = Elmt.Name.all then
603 return Elmt.Value;
604
605 else
606 Elmt := Elmt.Next;
607
608 if Elmt = null then
609 return Null_Value;
610 end if;
611 end if;
612 end loop;
613 end if;
614 end Get;
615
616 -------------
617 -- Present --
618 -------------
619
620 function Present (T : Table; Name : Character) return Boolean is
621 begin
622 return Present (T, String'(1 => Name));
623 end Present;
624
625 function Present (T : Table; Name : VString) return Boolean is
626 S : Big_String_Access;
627 L : Natural;
628 begin
629 Get_String (Name, S, L);
630 return Present (T, S (1 .. L));
631 end Present;
632
633 function Present (T : Table; Name : String) return Boolean is
634 Slot : constant Unsigned_32 := Hash (Name) mod T.N + 1;
635 Elmt : Hash_Element_Ptr := T.Elmts (Slot)'Unrestricted_Access;
636
637 begin
638 if Elmt.Name = null then
639 return False;
640
641 else
642 loop
643 if Name = Elmt.Name.all then
644 return True;
645
646 else
647 Elmt := Elmt.Next;
648
649 if Elmt = null then
650 return False;
651 end if;
652 end if;
653 end loop;
654 end if;
655 end Present;
656
657 ---------
658 -- Set --
659 ---------
660
661 procedure Set (T : in out Table; Name : VString; Value : Value_Type) is
662 S : Big_String_Access;
663 L : Natural;
664 begin
665 Get_String (Name, S, L);
666 Set (T, S (1 .. L), Value);
667 end Set;
668
669 procedure Set (T : in out Table; Name : Character; Value : Value_Type) is
670 begin
671 Set (T, String'(1 => Name), Value);
672 end Set;
673
674 procedure Set
675 (T : in out Table;
676 Name : String;
677 Value : Value_Type)
678 is
679 begin
680 if Value = Null_Value then
681 Delete (T, Name);
682
683 else
684 declare
685 Slot : constant Unsigned_32 := Hash (Name) mod T.N + 1;
686 Elmt : Hash_Element_Ptr := T.Elmts (Slot)'Unrestricted_Access;
687
688 subtype String1 is String (1 .. Name'Length);
689
690 begin
691 if Elmt.Name = null then
692 Elmt.Name := new String'(String1 (Name));
693 Elmt.Value := Value;
694 return;
695
696 else
697 loop
698 if Name = Elmt.Name.all then
699 Elmt.Value := Value;
700 return;
701
702 elsif Elmt.Next = null then
703 Elmt.Next := new Hash_Element'(
704 Name => new String'(String1 (Name)),
705 Value => Value,
706 Next => null);
707 return;
708
709 else
710 Elmt := Elmt.Next;
711 end if;
712 end loop;
713 end if;
714 end;
715 end if;
716 end Set;
717 end Table;
718
719 ----------
720 -- Trim --
721 ----------
722
723 function Trim (Str : VString) return VString is
724 begin
725 return Trim (Str, Right);
726 end Trim;
727
728 function Trim (Str : String) return VString is
729 begin
730 for J in reverse Str'Range loop
731 if Str (J) /= ' ' then
732 return V (Str (Str'First .. J));
733 end if;
734 end loop;
735
736 return Nul;
737 end Trim;
738
739 procedure Trim (Str : in out VString) is
740 begin
741 Trim (Str, Right);
742 end Trim;
743
744 -------
745 -- V --
746 -------
747
748 function V (Num : Integer) return VString is
749 Buf : String (1 .. 30);
750 Ptr : Natural := Buf'Last + 1;
751 Val : Natural := abs (Num);
752
753 begin
754 loop
755 Ptr := Ptr - 1;
756 Buf (Ptr) := Character'Val (Val mod 10 + Character'Pos ('0'));
757 Val := Val / 10;
758 exit when Val = 0;
759 end loop;
760
761 if Num < 0 then
762 Ptr := Ptr - 1;
763 Buf (Ptr) := '-';
764 end if;
765
766 return V (Buf (Ptr .. Buf'Last));
767 end V;
768
769 end GNAT.Spitbol;