PR sanitizer/80403
[official-gcc.git] / gcc / ada / a-strsup.adb
blob50df7dd48b4831cf9f8234919b1e6b7e84ad8190
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- A D A . S T R I N G S . S U P E R B O U N D E D --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2003-2015, 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 Ada.Strings.Maps; use Ada.Strings.Maps;
33 with Ada.Strings.Search;
35 package body Ada.Strings.Superbounded is
37 ------------
38 -- Concat --
39 ------------
41 function Concat
42 (Left : Super_String;
43 Right : Super_String) return Super_String
45 begin
46 return Result : Super_String (Left.Max_Length) do
47 declare
48 Llen : constant Natural := Left.Current_Length;
49 Rlen : constant Natural := Right.Current_Length;
50 Nlen : constant Natural := Llen + Rlen;
51 begin
52 if Nlen > Left.Max_Length then
53 raise Ada.Strings.Length_Error;
54 end if;
56 Result.Current_Length := Nlen;
57 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
58 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
59 end;
60 end return;
61 end Concat;
63 function Concat
64 (Left : Super_String;
65 Right : String) return Super_String
67 begin
68 return Result : Super_String (Left.Max_Length) do
69 declare
70 Llen : constant Natural := Left.Current_Length;
71 Nlen : constant Natural := Llen + Right'Length;
72 begin
73 if Nlen > Left.Max_Length then
74 raise Ada.Strings.Length_Error;
75 end if;
77 Result.Current_Length := Nlen;
78 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
79 Result.Data (Llen + 1 .. Nlen) := Right;
80 end;
81 end return;
82 end Concat;
84 function Concat
85 (Left : String;
86 Right : Super_String) return Super_String
89 begin
90 return Result : Super_String (Right.Max_Length) do
91 declare
92 Llen : constant Natural := Left'Length;
93 Rlen : constant Natural := Right.Current_Length;
94 Nlen : constant Natural := Llen + Rlen;
95 begin
96 if Nlen > Right.Max_Length then
97 raise Ada.Strings.Length_Error;
98 end if;
100 Result.Current_Length := Nlen;
101 Result.Data (1 .. Llen) := Left;
102 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
103 end;
104 end return;
105 end Concat;
107 function Concat
108 (Left : Super_String;
109 Right : Character) return Super_String
111 begin
112 return Result : Super_String (Left.Max_Length) do
113 declare
114 Llen : constant Natural := Left.Current_Length;
115 begin
116 if Llen = Left.Max_Length then
117 raise Ada.Strings.Length_Error;
118 end if;
120 Result.Current_Length := Llen + 1;
121 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
122 Result.Data (Result.Current_Length) := Right;
123 end;
124 end return;
125 end Concat;
127 function Concat
128 (Left : Character;
129 Right : Super_String) return Super_String
131 begin
132 return Result : Super_String (Right.Max_Length) do
133 declare
134 Rlen : constant Natural := Right.Current_Length;
135 begin
136 if Rlen = Right.Max_Length then
137 raise Ada.Strings.Length_Error;
138 end if;
140 Result.Current_Length := Rlen + 1;
141 Result.Data (1) := Left;
142 Result.Data (2 .. Result.Current_Length) :=
143 Right.Data (1 .. Rlen);
144 end;
145 end return;
146 end Concat;
148 -----------
149 -- Equal --
150 -----------
152 function "="
153 (Left : Super_String;
154 Right : Super_String) return Boolean
156 begin
157 return Left.Current_Length = Right.Current_Length
158 and then Left.Data (1 .. Left.Current_Length) =
159 Right.Data (1 .. Right.Current_Length);
160 end "=";
162 function Equal
163 (Left : Super_String;
164 Right : String) return Boolean
166 begin
167 return Left.Current_Length = Right'Length
168 and then Left.Data (1 .. Left.Current_Length) = Right;
169 end Equal;
171 function Equal
172 (Left : String;
173 Right : Super_String) return Boolean
175 begin
176 return Left'Length = Right.Current_Length
177 and then Left = Right.Data (1 .. Right.Current_Length);
178 end Equal;
180 -------------
181 -- Greater --
182 -------------
184 function Greater
185 (Left : Super_String;
186 Right : Super_String) return Boolean
188 begin
189 return Left.Data (1 .. Left.Current_Length) >
190 Right.Data (1 .. Right.Current_Length);
191 end Greater;
193 function Greater
194 (Left : Super_String;
195 Right : String) return Boolean
197 begin
198 return Left.Data (1 .. Left.Current_Length) > Right;
199 end Greater;
201 function Greater
202 (Left : String;
203 Right : Super_String) return Boolean
205 begin
206 return Left > Right.Data (1 .. Right.Current_Length);
207 end Greater;
209 ----------------------
210 -- Greater_Or_Equal --
211 ----------------------
213 function Greater_Or_Equal
214 (Left : Super_String;
215 Right : Super_String) return Boolean
217 begin
218 return Left.Data (1 .. Left.Current_Length) >=
219 Right.Data (1 .. Right.Current_Length);
220 end Greater_Or_Equal;
222 function Greater_Or_Equal
223 (Left : Super_String;
224 Right : String) return Boolean
226 begin
227 return Left.Data (1 .. Left.Current_Length) >= Right;
228 end Greater_Or_Equal;
230 function Greater_Or_Equal
231 (Left : String;
232 Right : Super_String) return Boolean
234 begin
235 return Left >= Right.Data (1 .. Right.Current_Length);
236 end Greater_Or_Equal;
238 ----------
239 -- Less --
240 ----------
242 function Less
243 (Left : Super_String;
244 Right : Super_String) return Boolean
246 begin
247 return Left.Data (1 .. Left.Current_Length) <
248 Right.Data (1 .. Right.Current_Length);
249 end Less;
251 function Less
252 (Left : Super_String;
253 Right : String) return Boolean
255 begin
256 return Left.Data (1 .. Left.Current_Length) < Right;
257 end Less;
259 function Less
260 (Left : String;
261 Right : Super_String) return Boolean
263 begin
264 return Left < Right.Data (1 .. Right.Current_Length);
265 end Less;
267 -------------------
268 -- Less_Or_Equal --
269 -------------------
271 function Less_Or_Equal
272 (Left : Super_String;
273 Right : Super_String) return Boolean
275 begin
276 return Left.Data (1 .. Left.Current_Length) <=
277 Right.Data (1 .. Right.Current_Length);
278 end Less_Or_Equal;
280 function Less_Or_Equal
281 (Left : Super_String;
282 Right : String) return Boolean
284 begin
285 return Left.Data (1 .. Left.Current_Length) <= Right;
286 end Less_Or_Equal;
288 function Less_Or_Equal
289 (Left : String;
290 Right : Super_String) return Boolean
292 begin
293 return Left <= Right.Data (1 .. Right.Current_Length);
294 end Less_Or_Equal;
296 ----------------------
297 -- Set_Super_String --
298 ----------------------
300 procedure Set_Super_String
301 (Target : out Super_String;
302 Source : String;
303 Drop : Truncation := Error)
305 Slen : constant Natural := Source'Length;
306 Max_Length : constant Positive := Target.Max_Length;
308 begin
309 if Slen <= Max_Length then
310 Target.Current_Length := Slen;
311 Target.Data (1 .. Slen) := Source;
313 else
314 case Drop is
315 when Strings.Right =>
316 Target.Current_Length := Max_Length;
317 Target.Data (1 .. Max_Length) :=
318 Source (Source'First .. Source'First - 1 + Max_Length);
320 when Strings.Left =>
321 Target.Current_Length := Max_Length;
322 Target.Data (1 .. Max_Length) :=
323 Source (Source'Last - (Max_Length - 1) .. Source'Last);
325 when Strings.Error =>
326 raise Ada.Strings.Length_Error;
327 end case;
328 end if;
329 end Set_Super_String;
331 ------------------
332 -- Super_Append --
333 ------------------
335 -- Case of Super_String and Super_String
337 function Super_Append
338 (Left : Super_String;
339 Right : Super_String;
340 Drop : Truncation := Error) return Super_String
342 Max_Length : constant Positive := Left.Max_Length;
343 Result : Super_String (Max_Length);
344 Llen : constant Natural := Left.Current_Length;
345 Rlen : constant Natural := Right.Current_Length;
346 Nlen : constant Natural := Llen + Rlen;
348 begin
349 if Nlen <= Max_Length then
350 Result.Current_Length := Nlen;
351 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
352 Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
354 else
355 Result.Current_Length := Max_Length;
357 case Drop is
358 when Strings.Right =>
359 if Llen >= Max_Length then -- only case is Llen = Max_Length
360 Result.Data := Left.Data;
362 else
363 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
364 Result.Data (Llen + 1 .. Max_Length) :=
365 Right.Data (1 .. Max_Length - Llen);
366 end if;
368 when Strings.Left =>
369 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
370 Result.Data := Right.Data;
372 else
373 Result.Data (1 .. Max_Length - Rlen) :=
374 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
375 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
376 Right.Data (1 .. Rlen);
377 end if;
379 when Strings.Error =>
380 raise Ada.Strings.Length_Error;
381 end case;
382 end if;
384 return Result;
385 end Super_Append;
387 procedure Super_Append
388 (Source : in out Super_String;
389 New_Item : Super_String;
390 Drop : Truncation := Error)
392 Max_Length : constant Positive := Source.Max_Length;
393 Llen : constant Natural := Source.Current_Length;
394 Rlen : constant Natural := New_Item.Current_Length;
395 Nlen : constant Natural := Llen + Rlen;
397 begin
398 if Nlen <= Max_Length then
399 Source.Current_Length := Nlen;
400 Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
402 else
403 Source.Current_Length := Max_Length;
405 case Drop is
406 when Strings.Right =>
407 if Llen < Max_Length then
408 Source.Data (Llen + 1 .. Max_Length) :=
409 New_Item.Data (1 .. Max_Length - Llen);
410 end if;
412 when Strings.Left =>
413 if Rlen >= Max_Length then -- only case is Rlen = Max_Length
414 Source.Data := New_Item.Data;
416 else
417 Source.Data (1 .. Max_Length - Rlen) :=
418 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
419 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
420 New_Item.Data (1 .. Rlen);
421 end if;
423 when Strings.Error =>
424 raise Ada.Strings.Length_Error;
425 end case;
426 end if;
428 end Super_Append;
430 -- Case of Super_String and String
432 function Super_Append
433 (Left : Super_String;
434 Right : String;
435 Drop : Strings.Truncation := Strings.Error) return Super_String
437 Max_Length : constant Positive := Left.Max_Length;
438 Result : Super_String (Max_Length);
439 Llen : constant Natural := Left.Current_Length;
440 Rlen : constant Natural := Right'Length;
441 Nlen : constant Natural := Llen + Rlen;
443 begin
444 if Nlen <= Max_Length then
445 Result.Current_Length := Nlen;
446 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
447 Result.Data (Llen + 1 .. Nlen) := Right;
449 else
450 Result.Current_Length := Max_Length;
452 case Drop is
453 when Strings.Right =>
454 if Llen >= Max_Length then -- only case is Llen = Max_Length
455 Result.Data := Left.Data;
457 else
458 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
459 Result.Data (Llen + 1 .. Max_Length) :=
460 Right (Right'First .. Right'First - 1 +
461 Max_Length - Llen);
463 end if;
465 when Strings.Left =>
466 if Rlen >= Max_Length then
467 Result.Data (1 .. Max_Length) :=
468 Right (Right'Last - (Max_Length - 1) .. Right'Last);
470 else
471 Result.Data (1 .. Max_Length - Rlen) :=
472 Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
473 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
474 Right;
475 end if;
477 when Strings.Error =>
478 raise Ada.Strings.Length_Error;
479 end case;
480 end if;
482 return Result;
483 end Super_Append;
485 procedure Super_Append
486 (Source : in out Super_String;
487 New_Item : String;
488 Drop : Truncation := Error)
490 Max_Length : constant Positive := Source.Max_Length;
491 Llen : constant Natural := Source.Current_Length;
492 Rlen : constant Natural := New_Item'Length;
493 Nlen : constant Natural := Llen + Rlen;
495 begin
496 if Nlen <= Max_Length then
497 Source.Current_Length := Nlen;
498 Source.Data (Llen + 1 .. Nlen) := New_Item;
500 else
501 Source.Current_Length := Max_Length;
503 case Drop is
504 when Strings.Right =>
505 if Llen < Max_Length then
506 Source.Data (Llen + 1 .. Max_Length) :=
507 New_Item (New_Item'First ..
508 New_Item'First - 1 + Max_Length - Llen);
509 end if;
511 when Strings.Left =>
512 if Rlen >= Max_Length then
513 Source.Data (1 .. Max_Length) :=
514 New_Item (New_Item'Last - (Max_Length - 1) ..
515 New_Item'Last);
517 else
518 Source.Data (1 .. Max_Length - Rlen) :=
519 Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
520 Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
521 New_Item;
522 end if;
524 when Strings.Error =>
525 raise Ada.Strings.Length_Error;
526 end case;
527 end if;
529 end Super_Append;
531 -- Case of String and Super_String
533 function Super_Append
534 (Left : String;
535 Right : Super_String;
536 Drop : Strings.Truncation := Strings.Error) return Super_String
538 Max_Length : constant Positive := Right.Max_Length;
539 Result : Super_String (Max_Length);
540 Llen : constant Natural := Left'Length;
541 Rlen : constant Natural := Right.Current_Length;
542 Nlen : constant Natural := Llen + Rlen;
544 begin
545 if Nlen <= Max_Length then
546 Result.Current_Length := Nlen;
547 Result.Data (1 .. Llen) := Left;
548 Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
550 else
551 Result.Current_Length := Max_Length;
553 case Drop is
554 when Strings.Right =>
555 if Llen >= Max_Length then
556 Result.Data (1 .. Max_Length) :=
557 Left (Left'First .. Left'First + (Max_Length - 1));
559 else
560 Result.Data (1 .. Llen) := Left;
561 Result.Data (Llen + 1 .. Max_Length) :=
562 Right.Data (1 .. Max_Length - Llen);
563 end if;
565 when Strings.Left =>
566 if Rlen >= Max_Length then
567 Result.Data (1 .. Max_Length) :=
568 Right.Data (Rlen - (Max_Length - 1) .. Rlen);
570 else
571 Result.Data (1 .. Max_Length - Rlen) :=
572 Left (Left'Last - (Max_Length - Rlen - 1) .. Left'Last);
573 Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
574 Right.Data (1 .. Rlen);
575 end if;
577 when Strings.Error =>
578 raise Ada.Strings.Length_Error;
579 end case;
580 end if;
582 return Result;
583 end Super_Append;
585 -- Case of Super_String and Character
587 function Super_Append
588 (Left : Super_String;
589 Right : Character;
590 Drop : Strings.Truncation := Strings.Error) return Super_String
592 Max_Length : constant Positive := Left.Max_Length;
593 Result : Super_String (Max_Length);
594 Llen : constant Natural := Left.Current_Length;
596 begin
597 if Llen < Max_Length then
598 Result.Current_Length := Llen + 1;
599 Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
600 Result.Data (Llen + 1) := Right;
601 return Result;
603 else
604 case Drop is
605 when Strings.Right =>
606 return Left;
608 when Strings.Left =>
609 Result.Current_Length := Max_Length;
610 Result.Data (1 .. Max_Length - 1) :=
611 Left.Data (2 .. Max_Length);
612 Result.Data (Max_Length) := Right;
613 return Result;
615 when Strings.Error =>
616 raise Ada.Strings.Length_Error;
617 end case;
618 end if;
619 end Super_Append;
621 procedure Super_Append
622 (Source : in out Super_String;
623 New_Item : Character;
624 Drop : Truncation := Error)
626 Max_Length : constant Positive := Source.Max_Length;
627 Llen : constant Natural := Source.Current_Length;
629 begin
630 if Llen < Max_Length then
631 Source.Current_Length := Llen + 1;
632 Source.Data (Llen + 1) := New_Item;
634 else
635 Source.Current_Length := Max_Length;
637 case Drop is
638 when Strings.Right =>
639 null;
641 when Strings.Left =>
642 Source.Data (1 .. Max_Length - 1) :=
643 Source.Data (2 .. Max_Length);
644 Source.Data (Max_Length) := New_Item;
646 when Strings.Error =>
647 raise Ada.Strings.Length_Error;
648 end case;
649 end if;
651 end Super_Append;
653 -- Case of Character and Super_String
655 function Super_Append
656 (Left : Character;
657 Right : Super_String;
658 Drop : Strings.Truncation := Strings.Error) return Super_String
660 Max_Length : constant Positive := Right.Max_Length;
661 Result : Super_String (Max_Length);
662 Rlen : constant Natural := Right.Current_Length;
664 begin
665 if Rlen < Max_Length then
666 Result.Current_Length := Rlen + 1;
667 Result.Data (1) := Left;
668 Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
669 return Result;
671 else
672 case Drop is
673 when Strings.Right =>
674 Result.Current_Length := Max_Length;
675 Result.Data (1) := Left;
676 Result.Data (2 .. Max_Length) :=
677 Right.Data (1 .. Max_Length - 1);
678 return Result;
680 when Strings.Left =>
681 return Right;
683 when Strings.Error =>
684 raise Ada.Strings.Length_Error;
685 end case;
686 end if;
687 end Super_Append;
689 -----------------
690 -- Super_Count --
691 -----------------
693 function Super_Count
694 (Source : Super_String;
695 Pattern : String;
696 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
698 begin
699 return
700 Search.Count
701 (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
702 end Super_Count;
704 function Super_Count
705 (Source : Super_String;
706 Pattern : String;
707 Mapping : Maps.Character_Mapping_Function) return Natural
709 begin
710 return
711 Search.Count
712 (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
713 end Super_Count;
715 function Super_Count
716 (Source : Super_String;
717 Set : Maps.Character_Set) return Natural
719 begin
720 return Search.Count (Source.Data (1 .. Source.Current_Length), Set);
721 end Super_Count;
723 ------------------
724 -- Super_Delete --
725 ------------------
727 function Super_Delete
728 (Source : Super_String;
729 From : Positive;
730 Through : Natural) return Super_String
732 Result : Super_String (Source.Max_Length);
733 Slen : constant Natural := Source.Current_Length;
734 Num_Delete : constant Integer := Through - From + 1;
736 begin
737 if Num_Delete <= 0 then
738 return Source;
740 elsif From > Slen + 1 then
741 raise Ada.Strings.Index_Error;
743 elsif Through >= Slen then
744 Result.Current_Length := From - 1;
745 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
746 return Result;
748 else
749 Result.Current_Length := Slen - Num_Delete;
750 Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
751 Result.Data (From .. Result.Current_Length) :=
752 Source.Data (Through + 1 .. Slen);
753 return Result;
754 end if;
755 end Super_Delete;
757 procedure Super_Delete
758 (Source : in out Super_String;
759 From : Positive;
760 Through : Natural)
762 Slen : constant Natural := Source.Current_Length;
763 Num_Delete : constant Integer := Through - From + 1;
765 begin
766 if Num_Delete <= 0 then
767 return;
769 elsif From > Slen + 1 then
770 raise Ada.Strings.Index_Error;
772 elsif Through >= Slen then
773 Source.Current_Length := From - 1;
775 else
776 Source.Current_Length := Slen - Num_Delete;
777 Source.Data (From .. Source.Current_Length) :=
778 Source.Data (Through + 1 .. Slen);
779 end if;
780 end Super_Delete;
782 -------------------
783 -- Super_Element --
784 -------------------
786 function Super_Element
787 (Source : Super_String;
788 Index : Positive) return Character
790 begin
791 if Index <= Source.Current_Length then
792 return Source.Data (Index);
793 else
794 raise Strings.Index_Error;
795 end if;
796 end Super_Element;
798 ----------------------
799 -- Super_Find_Token --
800 ----------------------
802 procedure Super_Find_Token
803 (Source : Super_String;
804 Set : Maps.Character_Set;
805 From : Positive;
806 Test : Strings.Membership;
807 First : out Positive;
808 Last : out Natural)
810 begin
811 Search.Find_Token
812 (Source.Data (From .. Source.Current_Length), Set, Test, First, Last);
813 end Super_Find_Token;
815 procedure Super_Find_Token
816 (Source : Super_String;
817 Set : Maps.Character_Set;
818 Test : Strings.Membership;
819 First : out Positive;
820 Last : out Natural)
822 begin
823 Search.Find_Token
824 (Source.Data (1 .. Source.Current_Length), Set, Test, First, Last);
825 end Super_Find_Token;
827 ----------------
828 -- Super_Head --
829 ----------------
831 function Super_Head
832 (Source : Super_String;
833 Count : Natural;
834 Pad : Character := Space;
835 Drop : Strings.Truncation := Strings.Error) return Super_String
837 Max_Length : constant Positive := Source.Max_Length;
838 Result : Super_String (Max_Length);
839 Slen : constant Natural := Source.Current_Length;
840 Npad : constant Integer := Count - Slen;
842 begin
843 if Npad <= 0 then
844 Result.Current_Length := Count;
845 Result.Data (1 .. Count) := Source.Data (1 .. Count);
847 elsif Count <= Max_Length then
848 Result.Current_Length := Count;
849 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
850 Result.Data (Slen + 1 .. Count) := (others => Pad);
852 else
853 Result.Current_Length := Max_Length;
855 case Drop is
856 when Strings.Right =>
857 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
858 Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
860 when Strings.Left =>
861 if Npad >= Max_Length then
862 Result.Data := (others => Pad);
864 else
865 Result.Data (1 .. Max_Length - Npad) :=
866 Source.Data (Count - Max_Length + 1 .. Slen);
867 Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
868 (others => Pad);
869 end if;
871 when Strings.Error =>
872 raise Ada.Strings.Length_Error;
873 end case;
874 end if;
876 return Result;
877 end Super_Head;
879 procedure Super_Head
880 (Source : in out Super_String;
881 Count : Natural;
882 Pad : Character := Space;
883 Drop : Truncation := Error)
885 Max_Length : constant Positive := Source.Max_Length;
886 Slen : constant Natural := Source.Current_Length;
887 Npad : constant Integer := Count - Slen;
888 Temp : String (1 .. Max_Length);
890 begin
891 if Npad <= 0 then
892 Source.Current_Length := Count;
894 elsif Count <= Max_Length then
895 Source.Current_Length := Count;
896 Source.Data (Slen + 1 .. Count) := (others => Pad);
898 else
899 Source.Current_Length := Max_Length;
901 case Drop is
902 when Strings.Right =>
903 Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
905 when Strings.Left =>
906 if Npad > Max_Length then
907 Source.Data := (others => Pad);
909 else
910 Temp := Source.Data;
911 Source.Data (1 .. Max_Length - Npad) :=
912 Temp (Count - Max_Length + 1 .. Slen);
914 for J in Max_Length - Npad + 1 .. Max_Length loop
915 Source.Data (J) := Pad;
916 end loop;
917 end if;
919 when Strings.Error =>
920 raise Ada.Strings.Length_Error;
921 end case;
922 end if;
923 end Super_Head;
925 -----------------
926 -- Super_Index --
927 -----------------
929 function Super_Index
930 (Source : Super_String;
931 Pattern : String;
932 Going : Strings.Direction := Strings.Forward;
933 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
935 begin
936 return Search.Index
937 (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
938 end Super_Index;
940 function Super_Index
941 (Source : Super_String;
942 Pattern : String;
943 Going : Direction := Forward;
944 Mapping : Maps.Character_Mapping_Function) return Natural
946 begin
947 return Search.Index
948 (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
949 end Super_Index;
951 function Super_Index
952 (Source : Super_String;
953 Set : Maps.Character_Set;
954 Test : Strings.Membership := Strings.Inside;
955 Going : Strings.Direction := Strings.Forward) return Natural
957 begin
958 return Search.Index
959 (Source.Data (1 .. Source.Current_Length), Set, Test, Going);
960 end Super_Index;
962 function Super_Index
963 (Source : Super_String;
964 Pattern : String;
965 From : Positive;
966 Going : Direction := Forward;
967 Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
969 begin
970 return Search.Index
971 (Source.Data (1 .. Source.Current_Length),
972 Pattern, From, Going, Mapping);
973 end Super_Index;
975 function Super_Index
976 (Source : Super_String;
977 Pattern : String;
978 From : Positive;
979 Going : Direction := Forward;
980 Mapping : Maps.Character_Mapping_Function) return Natural
982 begin
983 return Search.Index
984 (Source.Data (1 .. Source.Current_Length),
985 Pattern, From, Going, Mapping);
986 end Super_Index;
988 function Super_Index
989 (Source : Super_String;
990 Set : Maps.Character_Set;
991 From : Positive;
992 Test : Membership := Inside;
993 Going : Direction := Forward) return Natural
995 begin
996 return Search.Index
997 (Source.Data (1 .. Source.Current_Length), Set, From, Test, Going);
998 end Super_Index;
1000 ---------------------------
1001 -- Super_Index_Non_Blank --
1002 ---------------------------
1004 function Super_Index_Non_Blank
1005 (Source : Super_String;
1006 Going : Strings.Direction := Strings.Forward) return Natural
1008 begin
1009 return
1010 Search.Index_Non_Blank
1011 (Source.Data (1 .. Source.Current_Length), Going);
1012 end Super_Index_Non_Blank;
1014 function Super_Index_Non_Blank
1015 (Source : Super_String;
1016 From : Positive;
1017 Going : Direction := Forward) return Natural
1019 begin
1020 return
1021 Search.Index_Non_Blank
1022 (Source.Data (1 .. Source.Current_Length), From, Going);
1023 end Super_Index_Non_Blank;
1025 ------------------
1026 -- Super_Insert --
1027 ------------------
1029 function Super_Insert
1030 (Source : Super_String;
1031 Before : Positive;
1032 New_Item : String;
1033 Drop : Strings.Truncation := Strings.Error) return Super_String
1035 Max_Length : constant Positive := Source.Max_Length;
1036 Result : Super_String (Max_Length);
1037 Slen : constant Natural := Source.Current_Length;
1038 Nlen : constant Natural := New_Item'Length;
1039 Tlen : constant Natural := Slen + Nlen;
1040 Blen : constant Natural := Before - 1;
1041 Alen : constant Integer := Slen - Blen;
1042 Droplen : constant Integer := Tlen - Max_Length;
1044 -- Tlen is the length of the total string before possible truncation.
1045 -- Blen, Alen are the lengths of the before and after pieces of the
1046 -- source string.
1048 begin
1049 if Alen < 0 then
1050 raise Ada.Strings.Index_Error;
1052 elsif Droplen <= 0 then
1053 Result.Current_Length := Tlen;
1054 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1055 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1056 Result.Data (Before + Nlen .. Tlen) :=
1057 Source.Data (Before .. Slen);
1059 else
1060 Result.Current_Length := Max_Length;
1062 case Drop is
1063 when Strings.Right =>
1064 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1066 if Droplen > Alen then
1067 Result.Data (Before .. Max_Length) :=
1068 New_Item (New_Item'First
1069 .. New_Item'First + Max_Length - Before);
1070 else
1071 Result.Data (Before .. Before + Nlen - 1) := New_Item;
1072 Result.Data (Before + Nlen .. Max_Length) :=
1073 Source.Data (Before .. Slen - Droplen);
1074 end if;
1076 when Strings.Left =>
1077 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1078 Source.Data (Before .. Slen);
1080 if Droplen >= Blen then
1081 Result.Data (1 .. Max_Length - Alen) :=
1082 New_Item (New_Item'Last - (Max_Length - Alen) + 1
1083 .. New_Item'Last);
1084 else
1085 Result.Data
1086 (Blen - Droplen + 1 .. Max_Length - Alen) :=
1087 New_Item;
1088 Result.Data (1 .. Blen - Droplen) :=
1089 Source.Data (Droplen + 1 .. Blen);
1090 end if;
1092 when Strings.Error =>
1093 raise Ada.Strings.Length_Error;
1094 end case;
1095 end if;
1097 return Result;
1098 end Super_Insert;
1100 procedure Super_Insert
1101 (Source : in out Super_String;
1102 Before : Positive;
1103 New_Item : String;
1104 Drop : Strings.Truncation := Strings.Error)
1106 begin
1107 -- We do a double copy here because this is one of the situations
1108 -- in which we move data to the right, and at least at the moment,
1109 -- GNAT is not handling such cases correctly ???
1111 Source := Super_Insert (Source, Before, New_Item, Drop);
1112 end Super_Insert;
1114 ------------------
1115 -- Super_Length --
1116 ------------------
1118 function Super_Length (Source : Super_String) return Natural is
1119 begin
1120 return Source.Current_Length;
1121 end Super_Length;
1123 ---------------------
1124 -- Super_Overwrite --
1125 ---------------------
1127 function Super_Overwrite
1128 (Source : Super_String;
1129 Position : Positive;
1130 New_Item : String;
1131 Drop : Strings.Truncation := Strings.Error) return Super_String
1133 Max_Length : constant Positive := Source.Max_Length;
1134 Result : Super_String (Max_Length);
1135 Endpos : constant Natural := Position + New_Item'Length - 1;
1136 Slen : constant Natural := Source.Current_Length;
1137 Droplen : Natural;
1139 begin
1140 if Position > Slen + 1 then
1141 raise Ada.Strings.Index_Error;
1143 elsif New_Item'Length = 0 then
1144 return Source;
1146 elsif Endpos <= Slen then
1147 Result.Current_Length := Source.Current_Length;
1148 Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
1149 Result.Data (Position .. Endpos) := New_Item;
1150 return Result;
1152 elsif Endpos <= Max_Length then
1153 Result.Current_Length := Endpos;
1154 Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
1155 Result.Data (Position .. Endpos) := New_Item;
1156 return Result;
1158 else
1159 Result.Current_Length := Max_Length;
1160 Droplen := Endpos - Max_Length;
1162 case Drop is
1163 when Strings.Right =>
1164 Result.Data (1 .. Position - 1) :=
1165 Source.Data (1 .. Position - 1);
1167 Result.Data (Position .. Max_Length) :=
1168 New_Item (New_Item'First .. New_Item'Last - Droplen);
1169 return Result;
1171 when Strings.Left =>
1172 if New_Item'Length >= Max_Length then
1173 Result.Data (1 .. Max_Length) :=
1174 New_Item (New_Item'Last - Max_Length + 1 ..
1175 New_Item'Last);
1176 return Result;
1178 else
1179 Result.Data (1 .. Max_Length - New_Item'Length) :=
1180 Source.Data (Droplen + 1 .. Position - 1);
1181 Result.Data
1182 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1183 New_Item;
1184 return Result;
1185 end if;
1187 when Strings.Error =>
1188 raise Ada.Strings.Length_Error;
1189 end case;
1190 end if;
1191 end Super_Overwrite;
1193 procedure Super_Overwrite
1194 (Source : in out Super_String;
1195 Position : Positive;
1196 New_Item : String;
1197 Drop : Strings.Truncation := Strings.Error)
1199 Max_Length : constant Positive := Source.Max_Length;
1200 Endpos : constant Positive := Position + New_Item'Length - 1;
1201 Slen : constant Natural := Source.Current_Length;
1202 Droplen : Natural;
1204 begin
1205 if Position > Slen + 1 then
1206 raise Ada.Strings.Index_Error;
1208 elsif Endpos <= Slen then
1209 Source.Data (Position .. Endpos) := New_Item;
1211 elsif Endpos <= Max_Length then
1212 Source.Data (Position .. Endpos) := New_Item;
1213 Source.Current_Length := Endpos;
1215 else
1216 Source.Current_Length := Max_Length;
1217 Droplen := Endpos - Max_Length;
1219 case Drop is
1220 when Strings.Right =>
1221 Source.Data (Position .. Max_Length) :=
1222 New_Item (New_Item'First .. New_Item'Last - Droplen);
1224 when Strings.Left =>
1225 if New_Item'Length > Max_Length then
1226 Source.Data (1 .. Max_Length) :=
1227 New_Item (New_Item'Last - Max_Length + 1 ..
1228 New_Item'Last);
1230 else
1231 Source.Data (1 .. Max_Length - New_Item'Length) :=
1232 Source.Data (Droplen + 1 .. Position - 1);
1234 Source.Data
1235 (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1236 New_Item;
1237 end if;
1239 when Strings.Error =>
1240 raise Ada.Strings.Length_Error;
1241 end case;
1242 end if;
1243 end Super_Overwrite;
1245 ---------------------------
1246 -- Super_Replace_Element --
1247 ---------------------------
1249 procedure Super_Replace_Element
1250 (Source : in out Super_String;
1251 Index : Positive;
1252 By : Character)
1254 begin
1255 if Index <= Source.Current_Length then
1256 Source.Data (Index) := By;
1257 else
1258 raise Ada.Strings.Index_Error;
1259 end if;
1260 end Super_Replace_Element;
1262 -------------------------
1263 -- Super_Replace_Slice --
1264 -------------------------
1266 function Super_Replace_Slice
1267 (Source : Super_String;
1268 Low : Positive;
1269 High : Natural;
1270 By : String;
1271 Drop : Strings.Truncation := Strings.Error) return Super_String
1273 Max_Length : constant Positive := Source.Max_Length;
1274 Slen : constant Natural := Source.Current_Length;
1276 begin
1277 if Low > Slen + 1 then
1278 raise Strings.Index_Error;
1280 elsif High < Low then
1281 return Super_Insert (Source, Low, By, Drop);
1283 else
1284 declare
1285 Blen : constant Natural := Natural'Max (0, Low - 1);
1286 Alen : constant Natural := Natural'Max (0, Slen - High);
1287 Tlen : constant Natural := Blen + By'Length + Alen;
1288 Droplen : constant Integer := Tlen - Max_Length;
1289 Result : Super_String (Max_Length);
1291 -- Tlen is the total length of the result string before any
1292 -- truncation. Blen and Alen are the lengths of the pieces
1293 -- of the original string that end up in the result string
1294 -- before and after the replaced slice.
1296 begin
1297 if Droplen <= 0 then
1298 Result.Current_Length := Tlen;
1299 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1300 Result.Data (Low .. Low + By'Length - 1) := By;
1301 Result.Data (Low + By'Length .. Tlen) :=
1302 Source.Data (High + 1 .. Slen);
1304 else
1305 Result.Current_Length := Max_Length;
1307 case Drop is
1308 when Strings.Right =>
1309 Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1311 if Droplen > Alen then
1312 Result.Data (Low .. Max_Length) :=
1313 By (By'First .. By'First + Max_Length - Low);
1314 else
1315 Result.Data (Low .. Low + By'Length - 1) := By;
1316 Result.Data (Low + By'Length .. Max_Length) :=
1317 Source.Data (High + 1 .. Slen - Droplen);
1318 end if;
1320 when Strings.Left =>
1321 Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1322 Source.Data (High + 1 .. Slen);
1324 if Droplen >= Blen then
1325 Result.Data (1 .. Max_Length - Alen) :=
1326 By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
1327 else
1328 Result.Data
1329 (Blen - Droplen + 1 .. Max_Length - Alen) := By;
1330 Result.Data (1 .. Blen - Droplen) :=
1331 Source.Data (Droplen + 1 .. Blen);
1332 end if;
1334 when Strings.Error =>
1335 raise Ada.Strings.Length_Error;
1336 end case;
1337 end if;
1339 return Result;
1340 end;
1341 end if;
1342 end Super_Replace_Slice;
1344 procedure Super_Replace_Slice
1345 (Source : in out Super_String;
1346 Low : Positive;
1347 High : Natural;
1348 By : String;
1349 Drop : Strings.Truncation := Strings.Error)
1351 begin
1352 -- We do a double copy here because this is one of the situations
1353 -- in which we move data to the right, and at least at the moment,
1354 -- GNAT is not handling such cases correctly ???
1356 Source := Super_Replace_Slice (Source, Low, High, By, Drop);
1357 end Super_Replace_Slice;
1359 ---------------------
1360 -- Super_Replicate --
1361 ---------------------
1363 function Super_Replicate
1364 (Count : Natural;
1365 Item : Character;
1366 Drop : Truncation := Error;
1367 Max_Length : Positive) return Super_String
1369 Result : Super_String (Max_Length);
1371 begin
1372 if Count <= Max_Length then
1373 Result.Current_Length := Count;
1375 elsif Drop = Strings.Error then
1376 raise Ada.Strings.Length_Error;
1378 else
1379 Result.Current_Length := Max_Length;
1380 end if;
1382 Result.Data (1 .. Result.Current_Length) := (others => Item);
1383 return Result;
1384 end Super_Replicate;
1386 function Super_Replicate
1387 (Count : Natural;
1388 Item : String;
1389 Drop : Truncation := Error;
1390 Max_Length : Positive) return Super_String
1392 Length : constant Integer := Count * Item'Length;
1393 Result : Super_String (Max_Length);
1394 Indx : Positive;
1396 begin
1397 if Length <= Max_Length then
1398 Result.Current_Length := Length;
1400 if Length > 0 then
1401 Indx := 1;
1403 for J in 1 .. Count loop
1404 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1405 Indx := Indx + Item'Length;
1406 end loop;
1407 end if;
1409 else
1410 Result.Current_Length := Max_Length;
1412 case Drop is
1413 when Strings.Right =>
1414 Indx := 1;
1416 while Indx + Item'Length <= Max_Length + 1 loop
1417 Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1418 Indx := Indx + Item'Length;
1419 end loop;
1421 Result.Data (Indx .. Max_Length) :=
1422 Item (Item'First .. Item'First + Max_Length - Indx);
1424 when Strings.Left =>
1425 Indx := Max_Length;
1427 while Indx - Item'Length >= 1 loop
1428 Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
1429 Indx := Indx - Item'Length;
1430 end loop;
1432 Result.Data (1 .. Indx) :=
1433 Item (Item'Last - Indx + 1 .. Item'Last);
1435 when Strings.Error =>
1436 raise Ada.Strings.Length_Error;
1437 end case;
1438 end if;
1440 return Result;
1441 end Super_Replicate;
1443 function Super_Replicate
1444 (Count : Natural;
1445 Item : Super_String;
1446 Drop : Strings.Truncation := Strings.Error) return Super_String
1448 begin
1449 return
1450 Super_Replicate
1451 (Count,
1452 Item.Data (1 .. Item.Current_Length),
1453 Drop,
1454 Item.Max_Length);
1455 end Super_Replicate;
1457 -----------------
1458 -- Super_Slice --
1459 -----------------
1461 function Super_Slice
1462 (Source : Super_String;
1463 Low : Positive;
1464 High : Natural) return String
1466 begin
1467 -- Note: test of High > Length is in accordance with AI95-00128
1469 return R : String (Low .. High) do
1470 if Low > Source.Current_Length + 1
1471 or else High > Source.Current_Length
1472 then
1473 raise Index_Error;
1474 end if;
1476 -- Note: in this case, superflat bounds are not a problem, we just
1477 -- get the null string in accordance with normal Ada slice rules.
1479 R := Source.Data (Low .. High);
1480 end return;
1481 end Super_Slice;
1483 function Super_Slice
1484 (Source : Super_String;
1485 Low : Positive;
1486 High : Natural) return Super_String
1488 begin
1489 return Result : Super_String (Source.Max_Length) do
1490 if Low > Source.Current_Length + 1
1491 or else High > Source.Current_Length
1492 then
1493 raise Index_Error;
1494 end if;
1496 -- Note: the Max operation here deals with the superflat case
1498 Result.Current_Length := Integer'Max (0, High - Low + 1);
1499 Result.Data (1 .. Result.Current_Length) := Source.Data (Low .. High);
1500 end return;
1501 end Super_Slice;
1503 procedure Super_Slice
1504 (Source : Super_String;
1505 Target : out Super_String;
1506 Low : Positive;
1507 High : Natural)
1509 begin
1510 if Low > Source.Current_Length + 1
1511 or else High > Source.Current_Length
1512 then
1513 raise Index_Error;
1514 end if;
1516 -- Note: the Max operation here deals with the superflat case
1518 Target.Current_Length := Integer'Max (0, High - Low + 1);
1519 Target.Data (1 .. Target.Current_Length) := Source.Data (Low .. High);
1520 end Super_Slice;
1522 ----------------
1523 -- Super_Tail --
1524 ----------------
1526 function Super_Tail
1527 (Source : Super_String;
1528 Count : Natural;
1529 Pad : Character := Space;
1530 Drop : Strings.Truncation := Strings.Error) return Super_String
1532 Max_Length : constant Positive := Source.Max_Length;
1533 Result : Super_String (Max_Length);
1534 Slen : constant Natural := Source.Current_Length;
1535 Npad : constant Integer := Count - Slen;
1537 begin
1538 if Npad <= 0 then
1539 Result.Current_Length := Count;
1540 Result.Data (1 .. Count) :=
1541 Source.Data (Slen - (Count - 1) .. Slen);
1543 elsif Count <= Max_Length then
1544 Result.Current_Length := Count;
1545 Result.Data (1 .. Npad) := (others => Pad);
1546 Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
1548 else
1549 Result.Current_Length := Max_Length;
1551 case Drop is
1552 when Strings.Right =>
1553 if Npad >= Max_Length then
1554 Result.Data := (others => Pad);
1556 else
1557 Result.Data (1 .. Npad) := (others => Pad);
1558 Result.Data (Npad + 1 .. Max_Length) :=
1559 Source.Data (1 .. Max_Length - Npad);
1560 end if;
1562 when Strings.Left =>
1563 Result.Data (1 .. Max_Length - Slen) := (others => Pad);
1564 Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
1565 Source.Data (1 .. Slen);
1567 when Strings.Error =>
1568 raise Ada.Strings.Length_Error;
1569 end case;
1570 end if;
1572 return Result;
1573 end Super_Tail;
1575 procedure Super_Tail
1576 (Source : in out Super_String;
1577 Count : Natural;
1578 Pad : Character := Space;
1579 Drop : Truncation := Error)
1581 Max_Length : constant Positive := Source.Max_Length;
1582 Slen : constant Natural := Source.Current_Length;
1583 Npad : constant Integer := Count - Slen;
1585 Temp : constant String (1 .. Max_Length) := Source.Data;
1587 begin
1588 if Npad <= 0 then
1589 Source.Current_Length := Count;
1590 Source.Data (1 .. Count) :=
1591 Temp (Slen - (Count - 1) .. Slen);
1593 elsif Count <= Max_Length then
1594 Source.Current_Length := Count;
1595 Source.Data (1 .. Npad) := (others => Pad);
1596 Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
1598 else
1599 Source.Current_Length := Max_Length;
1601 case Drop is
1602 when Strings.Right =>
1603 if Npad >= Max_Length then
1604 Source.Data := (others => Pad);
1606 else
1607 Source.Data (1 .. Npad) := (others => Pad);
1608 Source.Data (Npad + 1 .. Max_Length) :=
1609 Temp (1 .. Max_Length - Npad);
1610 end if;
1612 when Strings.Left =>
1613 for J in 1 .. Max_Length - Slen loop
1614 Source.Data (J) := Pad;
1615 end loop;
1617 Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
1618 Temp (1 .. Slen);
1620 when Strings.Error =>
1621 raise Ada.Strings.Length_Error;
1622 end case;
1623 end if;
1624 end Super_Tail;
1626 ---------------------
1627 -- Super_To_String --
1628 ---------------------
1630 function Super_To_String (Source : Super_String) return String is
1631 begin
1632 return R : String (1 .. Source.Current_Length) do
1633 R := Source.Data (1 .. Source.Current_Length);
1634 end return;
1635 end Super_To_String;
1637 ---------------------
1638 -- Super_Translate --
1639 ---------------------
1641 function Super_Translate
1642 (Source : Super_String;
1643 Mapping : Maps.Character_Mapping) return Super_String
1645 Result : Super_String (Source.Max_Length);
1647 begin
1648 Result.Current_Length := Source.Current_Length;
1650 for J in 1 .. Source.Current_Length loop
1651 Result.Data (J) := Value (Mapping, Source.Data (J));
1652 end loop;
1654 return Result;
1655 end Super_Translate;
1657 procedure Super_Translate
1658 (Source : in out Super_String;
1659 Mapping : Maps.Character_Mapping)
1661 begin
1662 for J in 1 .. Source.Current_Length loop
1663 Source.Data (J) := Value (Mapping, Source.Data (J));
1664 end loop;
1665 end Super_Translate;
1667 function Super_Translate
1668 (Source : Super_String;
1669 Mapping : Maps.Character_Mapping_Function) return Super_String
1671 Result : Super_String (Source.Max_Length);
1673 begin
1674 Result.Current_Length := Source.Current_Length;
1676 for J in 1 .. Source.Current_Length loop
1677 Result.Data (J) := Mapping.all (Source.Data (J));
1678 end loop;
1680 return Result;
1681 end Super_Translate;
1683 procedure Super_Translate
1684 (Source : in out Super_String;
1685 Mapping : Maps.Character_Mapping_Function)
1687 begin
1688 for J in 1 .. Source.Current_Length loop
1689 Source.Data (J) := Mapping.all (Source.Data (J));
1690 end loop;
1691 end Super_Translate;
1693 ----------------
1694 -- Super_Trim --
1695 ----------------
1697 function Super_Trim
1698 (Source : Super_String;
1699 Side : Trim_End) return Super_String
1701 Result : Super_String (Source.Max_Length);
1702 Last : Natural := Source.Current_Length;
1703 First : Positive := 1;
1705 begin
1706 if Side = Left or else Side = Both then
1707 while First <= Last and then Source.Data (First) = ' ' loop
1708 First := First + 1;
1709 end loop;
1710 end if;
1712 if Side = Right or else Side = Both then
1713 while Last >= First and then Source.Data (Last) = ' ' loop
1714 Last := Last - 1;
1715 end loop;
1716 end if;
1718 Result.Current_Length := Last - First + 1;
1719 Result.Data (1 .. Result.Current_Length) := Source.Data (First .. Last);
1720 return Result;
1721 end Super_Trim;
1723 procedure Super_Trim
1724 (Source : in out Super_String;
1725 Side : Trim_End)
1727 Max_Length : constant Positive := Source.Max_Length;
1728 Last : Natural := Source.Current_Length;
1729 First : Positive := 1;
1730 Temp : String (1 .. Max_Length);
1732 begin
1733 Temp (1 .. Last) := Source.Data (1 .. Last);
1735 if Side = Left or else Side = Both then
1736 while First <= Last and then Temp (First) = ' ' loop
1737 First := First + 1;
1738 end loop;
1739 end if;
1741 if Side = Right or else Side = Both then
1742 while Last >= First and then Temp (Last) = ' ' loop
1743 Last := Last - 1;
1744 end loop;
1745 end if;
1747 Source.Current_Length := Last - First + 1;
1748 Source.Data (1 .. Source.Current_Length) := Temp (First .. Last);
1749 end Super_Trim;
1751 function Super_Trim
1752 (Source : Super_String;
1753 Left : Maps.Character_Set;
1754 Right : Maps.Character_Set) return Super_String
1756 Result : Super_String (Source.Max_Length);
1758 begin
1759 for First in 1 .. Source.Current_Length loop
1760 if not Is_In (Source.Data (First), Left) then
1761 for Last in reverse First .. Source.Current_Length loop
1762 if not Is_In (Source.Data (Last), Right) then
1763 Result.Current_Length := Last - First + 1;
1764 Result.Data (1 .. Result.Current_Length) :=
1765 Source.Data (First .. Last);
1766 return Result;
1767 end if;
1768 end loop;
1769 end if;
1770 end loop;
1772 Result.Current_Length := 0;
1773 return Result;
1774 end Super_Trim;
1776 procedure Super_Trim
1777 (Source : in out Super_String;
1778 Left : Maps.Character_Set;
1779 Right : Maps.Character_Set)
1781 begin
1782 for First in 1 .. Source.Current_Length loop
1783 if not Is_In (Source.Data (First), Left) then
1784 for Last in reverse First .. Source.Current_Length loop
1785 if not Is_In (Source.Data (Last), Right) then
1786 if First = 1 then
1787 Source.Current_Length := Last;
1788 return;
1789 else
1790 Source.Current_Length := Last - First + 1;
1791 Source.Data (1 .. Source.Current_Length) :=
1792 Source.Data (First .. Last);
1793 return;
1794 end if;
1795 end if;
1796 end loop;
1798 Source.Current_Length := 0;
1799 return;
1800 end if;
1801 end loop;
1803 Source.Current_Length := 0;
1804 end Super_Trim;
1806 -----------
1807 -- Times --
1808 -----------
1810 function Times
1811 (Left : Natural;
1812 Right : Character;
1813 Max_Length : Positive) return Super_String
1815 Result : Super_String (Max_Length);
1817 begin
1818 if Left > Max_Length then
1819 raise Ada.Strings.Length_Error;
1821 else
1822 Result.Current_Length := Left;
1824 for J in 1 .. Left loop
1825 Result.Data (J) := Right;
1826 end loop;
1827 end if;
1829 return Result;
1830 end Times;
1832 function Times
1833 (Left : Natural;
1834 Right : String;
1835 Max_Length : Positive) return Super_String
1837 Result : Super_String (Max_Length);
1838 Pos : Positive := 1;
1839 Rlen : constant Natural := Right'Length;
1840 Nlen : constant Natural := Left * Rlen;
1842 begin
1843 if Nlen > Max_Length then
1844 raise Ada.Strings.Length_Error;
1846 else
1847 Result.Current_Length := Nlen;
1849 if Nlen > 0 then
1850 for J in 1 .. Left loop
1851 Result.Data (Pos .. Pos + Rlen - 1) := Right;
1852 Pos := Pos + Rlen;
1853 end loop;
1854 end if;
1855 end if;
1857 return Result;
1858 end Times;
1860 function Times
1861 (Left : Natural;
1862 Right : Super_String) return Super_String
1864 Result : Super_String (Right.Max_Length);
1865 Pos : Positive := 1;
1866 Rlen : constant Natural := Right.Current_Length;
1867 Nlen : constant Natural := Left * Rlen;
1869 begin
1870 if Nlen > Right.Max_Length then
1871 raise Ada.Strings.Length_Error;
1873 else
1874 Result.Current_Length := Nlen;
1876 if Nlen > 0 then
1877 for J in 1 .. Left loop
1878 Result.Data (Pos .. Pos + Rlen - 1) :=
1879 Right.Data (1 .. Rlen);
1880 Pos := Pos + Rlen;
1881 end loop;
1882 end if;
1883 end if;
1885 return Result;
1886 end Times;
1888 ---------------------
1889 -- To_Super_String --
1890 ---------------------
1892 function To_Super_String
1893 (Source : String;
1894 Max_Length : Natural;
1895 Drop : Truncation := Error) return Super_String
1897 Result : Super_String (Max_Length);
1898 Slen : constant Natural := Source'Length;
1900 begin
1901 if Slen <= Max_Length then
1902 Result.Current_Length := Slen;
1903 Result.Data (1 .. Slen) := Source;
1905 else
1906 case Drop is
1907 when Strings.Right =>
1908 Result.Current_Length := Max_Length;
1909 Result.Data (1 .. Max_Length) :=
1910 Source (Source'First .. Source'First - 1 + Max_Length);
1912 when Strings.Left =>
1913 Result.Current_Length := Max_Length;
1914 Result.Data (1 .. Max_Length) :=
1915 Source (Source'Last - (Max_Length - 1) .. Source'Last);
1917 when Strings.Error =>
1918 raise Ada.Strings.Length_Error;
1919 end case;
1920 end if;
1922 return Result;
1923 end To_Super_String;
1925 end Ada.Strings.Superbounded;