OSDN Git Service

2004-05-17 Steve Kargl <kargls@comcast.net>
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-strsup.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT RUNTIME 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 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 2,  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.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, USA.                                                      --
21 --                                                                          --
22 -- As a special exception,  if other files  instantiate  generics from this --
23 -- unit, or you link  this unit with other files  to produce an executable, --
24 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
25 -- covered  by the  GNU  General  Public  License.  This exception does not --
26 -- however invalidate  any other reasons why  the executable file  might be --
27 -- covered by the  GNU Public License.                                      --
28 --                                                                          --
29 -- GNAT was originally developed  by the GNAT team at  New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
31 --                                                                          --
32 ------------------------------------------------------------------------------
33
34 with Ada.Strings.Maps;   use Ada.Strings.Maps;
35 with Ada.Strings.Search;
36
37 package body Ada.Strings.Superbounded is
38
39    ------------
40    -- Concat --
41    ------------
42
43    function Concat
44      (Left  : Super_String;
45       Right : Super_String)
46       return  Super_String
47    is
48       Result : Super_String (Left.Max_Length);
49       Llen   : constant Natural := Left.Current_Length;
50       Rlen   : constant Natural := Right.Current_Length;
51       Nlen   : constant Natural := Llen + Rlen;
52
53    begin
54       if Nlen > Left.Max_Length then
55          raise Ada.Strings.Length_Error;
56       else
57          Result.Current_Length := Nlen;
58          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
59          Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
60       end if;
61
62       return Result;
63    end Concat;
64
65    function Concat
66      (Left  : Super_String;
67       Right : String)
68       return  Super_String
69    is
70       Result : Super_String (Left.Max_Length);
71       Llen   : constant Natural := Left.Current_Length;
72
73       Nlen   : constant Natural := Llen + Right'Length;
74
75    begin
76       if Nlen > Left.Max_Length then
77          raise Ada.Strings.Length_Error;
78       else
79          Result.Current_Length := Nlen;
80          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
81          Result.Data (Llen + 1 .. Nlen) := Right;
82       end if;
83       return Result;
84    end Concat;
85
86    function Concat
87      (Left  : String;
88       Right : Super_String)
89       return  Super_String
90    is
91       Result : Super_String (Right.Max_Length);
92       Llen   : constant Natural := Left'Length;
93       Rlen   : constant Natural := Right.Current_Length;
94       Nlen   : constant Natural := Llen + Rlen;
95
96    begin
97       if Nlen > Right.Max_Length then
98          raise Ada.Strings.Length_Error;
99       else
100          Result.Current_Length := Nlen;
101          Result.Data (1 .. Llen) := Left;
102          Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
103       end if;
104
105       return Result;
106    end Concat;
107
108    function Concat
109      (Left  : Super_String;
110       Right : Character)
111       return  Super_String
112    is
113       Result : Super_String (Left.Max_Length);
114       Llen   : constant Natural := Left.Current_Length;
115
116    begin
117       if Llen = Left.Max_Length then
118          raise Ada.Strings.Length_Error;
119       else
120          Result.Current_Length := Llen + 1;
121          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
122          Result.Data (Result.Current_Length) := Right;
123       end if;
124
125       return Result;
126    end Concat;
127
128    function Concat
129      (Left  : Character;
130       Right : Super_String)
131       return  Super_String
132    is
133       Result : Super_String (Right.Max_Length);
134       Rlen   : constant Natural := Right.Current_Length;
135
136    begin
137       if Rlen = Right.Max_Length then
138          raise Ada.Strings.Length_Error;
139       else
140          Result.Current_Length := Rlen + 1;
141          Result.Data (1) := Left;
142          Result.Data (2 .. Result.Current_Length) := Right.Data (1 .. Rlen);
143       end if;
144
145       return Result;
146    end Concat;
147
148    -----------
149    -- Equal --
150    -----------
151
152    function "=" (Left, Right : Super_String) return Boolean is
153    begin
154       return Left.Current_Length = Right.Current_Length
155         and then Left.Data (1 .. Left.Current_Length) =
156                    Right.Data (1 .. Right.Current_Length);
157    end "=";
158
159    function Equal (Left : Super_String; Right : String)
160                    return Boolean is
161    begin
162       return Left.Current_Length = Right'Length
163         and then Left.Data (1 .. Left.Current_Length) = Right;
164    end Equal;
165
166    function Equal (Left : String; Right : Super_String)
167                    return Boolean is
168    begin
169       return Left'Length = Right.Current_Length
170         and then Left = Right.Data (1 .. Right.Current_Length);
171    end Equal;
172
173    -------------
174    -- Greater --
175    -------------
176
177    function Greater (Left, Right : Super_String) return Boolean is
178    begin
179       return Left.Data (1 .. Left.Current_Length) >
180                Right.Data (1 .. Right.Current_Length);
181    end Greater;
182
183    function Greater
184      (Left  : Super_String;
185       Right : String)
186       return  Boolean
187    is
188    begin
189       return Left.Data (1 .. Left.Current_Length) > Right;
190    end Greater;
191
192    function Greater
193      (Left  : String;
194       Right : Super_String)
195       return  Boolean
196    is
197    begin
198       return Left > Right.Data (1 .. Right.Current_Length);
199    end Greater;
200
201    ----------------------
202    -- Greater_Or_Equal --
203    ----------------------
204
205    function Greater_Or_Equal (Left, Right : Super_String) return Boolean is
206    begin
207       return Left.Data (1 .. Left.Current_Length) >=
208                Right.Data (1 .. Right.Current_Length);
209    end Greater_Or_Equal;
210
211    function Greater_Or_Equal
212      (Left  : Super_String;
213       Right : String)
214       return  Boolean
215    is
216    begin
217       return Left.Data (1 .. Left.Current_Length) >= Right;
218    end Greater_Or_Equal;
219
220    function Greater_Or_Equal
221      (Left  : String;
222       Right : Super_String)
223       return  Boolean
224    is
225    begin
226       return Left >= Right.Data (1 .. Right.Current_Length);
227    end Greater_Or_Equal;
228
229    ----------
230    -- Less --
231    ----------
232
233    function Less (Left, Right : Super_String) return Boolean is
234    begin
235       return Left.Data (1 .. Left.Current_Length) <
236                Right.Data (1 .. Right.Current_Length);
237    end Less;
238
239    function Less
240      (Left  : Super_String;
241       Right : String)
242       return  Boolean
243    is
244    begin
245       return Left.Data (1 .. Left.Current_Length) < Right;
246    end Less;
247
248    function Less
249      (Left  : String;
250       Right : Super_String)
251       return  Boolean
252    is
253    begin
254       return Left < Right.Data (1 .. Right.Current_Length);
255    end Less;
256
257    -------------------
258    -- Less_Or_Equal --
259    -------------------
260
261    function Less_Or_Equal (Left, Right : Super_String) return Boolean is
262    begin
263       return Left.Data (1 .. Left.Current_Length) <=
264                Right.Data (1 .. Right.Current_Length);
265    end Less_Or_Equal;
266
267    function Less_Or_Equal
268      (Left  : Super_String;
269       Right : String)
270       return  Boolean
271    is
272    begin
273       return Left.Data (1 .. Left.Current_Length) <= Right;
274    end Less_Or_Equal;
275
276    function Less_Or_Equal
277      (Left  : String;
278       Right : Super_String)
279       return  Boolean
280    is
281    begin
282       return Left <= Right.Data (1 .. Right.Current_Length);
283    end Less_Or_Equal;
284
285    ------------------
286    -- Super_Append --
287    ------------------
288
289    --  Case of Super_String and Super_String
290
291    function Super_Append
292      (Left, Right : Super_String;
293       Drop        : Strings.Truncation  := Strings.Error)
294       return        Super_String
295    is
296       Max_Length : constant Positive := Left.Max_Length;
297       Result : Super_String (Max_Length);
298       Llen   : constant Natural := Left.Current_Length;
299       Rlen   : constant Natural := Right.Current_Length;
300       Nlen   : constant Natural := Llen + Rlen;
301
302    begin
303       if Nlen <= Max_Length then
304          Result.Current_Length := Nlen;
305          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
306          Result.Data (Llen + 1 .. Nlen) := Right.Data (1 .. Rlen);
307
308       else
309          Result.Current_Length := Max_Length;
310
311          case Drop is
312             when Strings.Right =>
313                if Llen >= Max_Length then -- only case is Llen = Max_Length
314                   Result.Data := Left.Data;
315
316                else
317                   Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
318                   Result.Data (Llen + 1 .. Max_Length) :=
319                     Right.Data (1 .. Max_Length - Llen);
320                end if;
321
322             when Strings.Left =>
323                if Rlen >= Max_Length then -- only case is Rlen = Max_Length
324                   Result.Data := Right.Data;
325
326                else
327                   Result.Data (1 .. Max_Length - Rlen) :=
328                     Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
329                   Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
330                     Right.Data (1 .. Rlen);
331                end if;
332
333             when Strings.Error =>
334                raise Ada.Strings.Length_Error;
335          end case;
336       end if;
337
338       return Result;
339    end Super_Append;
340
341    procedure Super_Append
342      (Source   : in out Super_String;
343       New_Item : Super_String;
344       Drop     : Truncation  := Error)
345    is
346       Max_Length : constant Positive := Source.Max_Length;
347       Llen       : constant Natural := Source.Current_Length;
348       Rlen       : constant Natural := New_Item.Current_Length;
349       Nlen       : constant Natural := Llen + Rlen;
350
351    begin
352       if Nlen <= Max_Length then
353          Source.Current_Length := Nlen;
354          Source.Data (Llen + 1 .. Nlen) := New_Item.Data (1 .. Rlen);
355
356       else
357          Source.Current_Length := Max_Length;
358
359          case Drop is
360             when Strings.Right =>
361                if Llen < Max_Length then
362                   Source.Data (Llen + 1 .. Max_Length) :=
363                     New_Item.Data (1 .. Max_Length - Llen);
364                end if;
365
366             when Strings.Left =>
367                if Rlen >= Max_Length then -- only case is Rlen = Max_Length
368                   Source.Data := New_Item.Data;
369
370                else
371                   Source.Data (1 .. Max_Length - Rlen) :=
372                     Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
373                   Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
374                     New_Item.Data (1 .. Rlen);
375                end if;
376
377             when Strings.Error =>
378                raise Ada.Strings.Length_Error;
379          end case;
380       end if;
381
382    end Super_Append;
383
384    --  Case of Super_String and String
385
386    function Super_Append
387      (Left  : Super_String;
388       Right : String;
389       Drop  : Strings.Truncation := Strings.Error)
390       return  Super_String
391    is
392       Max_Length : constant Positive := Left.Max_Length;
393       Result : Super_String (Max_Length);
394       Llen   : constant Natural := Left.Current_Length;
395       Rlen   : constant Natural := Right'Length;
396       Nlen   : constant Natural := Llen + Rlen;
397
398    begin
399       if Nlen <= Max_Length then
400          Result.Current_Length := Nlen;
401          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
402          Result.Data (Llen + 1 .. Nlen) := Right;
403
404       else
405          Result.Current_Length := Max_Length;
406
407          case Drop is
408             when Strings.Right =>
409                if Llen >= Max_Length then -- only case is Llen = Max_Length
410                   Result.Data := Left.Data;
411
412                else
413                   Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
414                   Result.Data (Llen + 1 .. Max_Length) :=
415                     Right (Right'First .. Right'First - 1 +
416                              Max_Length - Llen);
417
418                end if;
419
420             when Strings.Left =>
421                if Rlen >= Max_Length then
422                   Result.Data (1 .. Max_Length) :=
423                     Right (Right'Last - (Max_Length - 1) .. Right'Last);
424
425                else
426                   Result.Data (1 .. Max_Length - Rlen) :=
427                     Left.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
428                   Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
429                     Right;
430                end if;
431
432             when Strings.Error =>
433                raise Ada.Strings.Length_Error;
434          end case;
435       end if;
436
437       return Result;
438    end Super_Append;
439
440    procedure Super_Append
441      (Source   : in out Super_String;
442       New_Item : String;
443       Drop     : Truncation  := Error)
444    is
445       Max_Length : constant Positive := Source.Max_Length;
446       Llen   : constant Natural := Source.Current_Length;
447       Rlen   : constant Natural := New_Item'Length;
448       Nlen   : constant Natural := Llen + Rlen;
449
450    begin
451       if Nlen <= Max_Length then
452          Source.Current_Length := Nlen;
453          Source.Data (Llen + 1 .. Nlen) := New_Item;
454
455       else
456          Source.Current_Length := Max_Length;
457
458          case Drop is
459             when Strings.Right =>
460                if Llen < Max_Length then
461                   Source.Data (Llen + 1 .. Max_Length) :=
462                     New_Item (New_Item'First ..
463                                 New_Item'First - 1 + Max_Length - Llen);
464                end if;
465
466             when Strings.Left =>
467                if Rlen >= Max_Length then
468                   Source.Data (1 .. Max_Length) :=
469                     New_Item (New_Item'Last - (Max_Length - 1) ..
470                                 New_Item'Last);
471
472                else
473                   Source.Data (1 .. Max_Length - Rlen) :=
474                     Source.Data (Llen - (Max_Length - Rlen - 1) .. Llen);
475                   Source.Data (Max_Length - Rlen + 1 .. Max_Length) :=
476                     New_Item;
477                end if;
478
479             when Strings.Error =>
480                raise Ada.Strings.Length_Error;
481          end case;
482       end if;
483
484    end Super_Append;
485
486    --  Case of String and Super_String
487
488    function Super_Append
489      (Left  : String;
490       Right : Super_String;
491       Drop  : Strings.Truncation := Strings.Error)
492       return  Super_String
493    is
494       Max_Length : constant Positive := Right.Max_Length;
495       Result     : Super_String (Max_Length);
496       Llen       : constant Natural := Left'Length;
497       Rlen       : constant Natural := Right.Current_Length;
498       Nlen       : constant Natural := Llen + Rlen;
499
500    begin
501       if Nlen <= Max_Length then
502          Result.Current_Length := Nlen;
503          Result.Data (1 .. Llen) := Left;
504          Result.Data (Llen + 1 .. Llen + Rlen) := Right.Data (1 .. Rlen);
505
506       else
507          Result.Current_Length := Max_Length;
508
509          case Drop is
510             when Strings.Right =>
511                if Llen >= Max_Length then
512                   Result.Data (1 .. Max_Length) :=
513                     Left (Left'First .. Left'First + (Max_Length - 1));
514
515                else
516                   Result.Data (1 .. Llen) := Left;
517                   Result.Data (Llen + 1 .. Max_Length) :=
518                     Right.Data (1 .. Max_Length - Llen);
519                end if;
520
521             when Strings.Left =>
522                if Rlen >= Max_Length then
523                   Result.Data (1 .. Max_Length) :=
524                     Right.Data (Rlen - (Max_Length - 1) .. Rlen);
525
526                else
527                   Result.Data (1 .. Max_Length - Rlen) :=
528                     Left (Left'Last - (Max_Length - Rlen - 1) .. Left'Last);
529                   Result.Data (Max_Length - Rlen + 1 .. Max_Length) :=
530                     Right.Data (1 .. Rlen);
531                end if;
532
533             when Strings.Error =>
534                raise Ada.Strings.Length_Error;
535          end case;
536       end if;
537
538       return Result;
539    end Super_Append;
540
541    --  Case of Super_String and Character
542
543    function Super_Append
544      (Left  : Super_String;
545       Right : Character;
546       Drop  : Strings.Truncation := Strings.Error)
547       return  Super_String
548    is
549       Max_Length : constant Positive := Left.Max_Length;
550       Result     : Super_String (Max_Length);
551       Llen       : constant Natural := Left.Current_Length;
552
553    begin
554       if Llen  < Max_Length then
555          Result.Current_Length := Llen + 1;
556          Result.Data (1 .. Llen) := Left.Data (1 .. Llen);
557          Result.Data (Llen + 1) := Right;
558          return Result;
559
560       else
561          case Drop is
562             when Strings.Right =>
563                return Left;
564
565             when Strings.Left =>
566                Result.Current_Length := Max_Length;
567                Result.Data (1 .. Max_Length - 1) :=
568                  Left.Data (2 .. Max_Length);
569                Result.Data (Max_Length) := Right;
570                return Result;
571
572             when Strings.Error =>
573                raise Ada.Strings.Length_Error;
574          end case;
575       end if;
576    end Super_Append;
577
578    procedure Super_Append
579      (Source   : in out Super_String;
580       New_Item : Character;
581       Drop     : Truncation  := Error)
582    is
583       Max_Length : constant Positive := Source.Max_Length;
584       Llen       : constant Natural  := Source.Current_Length;
585
586    begin
587       if Llen  < Max_Length then
588          Source.Current_Length := Llen + 1;
589          Source.Data (Llen + 1) := New_Item;
590
591       else
592          Source.Current_Length := Max_Length;
593
594          case Drop is
595             when Strings.Right =>
596                null;
597
598             when Strings.Left =>
599                Source.Data (1 .. Max_Length - 1) :=
600                  Source.Data (2 .. Max_Length);
601                Source.Data (Max_Length) := New_Item;
602
603             when Strings.Error =>
604                raise Ada.Strings.Length_Error;
605          end case;
606       end if;
607
608    end Super_Append;
609
610    --  Case of Character and Super_String
611
612    function Super_Append
613      (Left  : Character;
614       Right : Super_String;
615       Drop  : Strings.Truncation := Strings.Error)
616       return  Super_String
617    is
618       Max_Length : constant Positive := Right.Max_Length;
619       Result : Super_String (Max_Length);
620       Rlen   : constant Natural := Right.Current_Length;
621
622    begin
623       if Rlen < Max_Length then
624          Result.Current_Length := Rlen + 1;
625          Result.Data (1) := Left;
626          Result.Data (2 .. Rlen + 1) := Right.Data (1 .. Rlen);
627          return Result;
628
629       else
630          case Drop is
631             when Strings.Right =>
632                Result.Current_Length := Max_Length;
633                Result.Data (1) := Left;
634                Result.Data (2 .. Max_Length) :=
635                  Right.Data (1 .. Max_Length - 1);
636                return Result;
637
638             when Strings.Left =>
639                return Right;
640
641             when Strings.Error =>
642                raise Ada.Strings.Length_Error;
643          end case;
644       end if;
645    end Super_Append;
646
647    -----------------
648    -- Super_Count --
649    -----------------
650
651    function Super_Count
652      (Source   : Super_String;
653       Pattern  : String;
654       Mapping  : Maps.Character_Mapping := Maps.Identity)
655       return     Natural
656    is
657    begin
658       return
659         Search.Count
660           (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
661    end Super_Count;
662
663    function Super_Count
664      (Source   : Super_String;
665       Pattern  : String;
666       Mapping  : Maps.Character_Mapping_Function)
667       return     Natural
668    is
669    begin
670       return
671         Search.Count
672           (Source.Data (1 .. Source.Current_Length), Pattern, Mapping);
673    end Super_Count;
674
675    function Super_Count
676      (Source : Super_String;
677       Set    : Maps.Character_Set)
678       return   Natural
679    is
680    begin
681       return Search.Count (Source.Data (1 .. Source.Current_Length), Set);
682    end Super_Count;
683
684    ------------------
685    -- Super_Delete --
686    ------------------
687
688    function Super_Delete
689      (Source  : Super_String;
690       From    : Positive;
691       Through : Natural)
692       return    Super_String
693    is
694       Result     : Super_String (Source.Max_Length);
695       Slen       : constant Natural := Source.Current_Length;
696       Num_Delete : constant Integer := Through - From + 1;
697
698    begin
699       if Num_Delete <= 0 then
700          return Source;
701
702       elsif From > Slen + 1 then
703          raise Ada.Strings.Index_Error;
704
705       elsif Through >= Slen then
706          Result.Current_Length := From - 1;
707          Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
708          return Result;
709
710       else
711          Result.Current_Length := Slen - Num_Delete;
712          Result.Data (1 .. From - 1) := Source.Data (1 .. From - 1);
713          Result.Data (From .. Result.Current_Length) :=
714            Source.Data (Through + 1 .. Slen);
715          return Result;
716       end if;
717    end Super_Delete;
718
719    procedure Super_Delete
720      (Source  : in out Super_String;
721       From    : Positive;
722       Through : Natural)
723    is
724       Slen       : constant Natural := Source.Current_Length;
725       Num_Delete : constant Integer := Through - From + 1;
726
727    begin
728       if Num_Delete <= 0 then
729          return;
730
731       elsif From > Slen + 1 then
732          raise Ada.Strings.Index_Error;
733
734       elsif Through >= Slen then
735          Source.Current_Length := From - 1;
736
737       else
738          Source.Current_Length := Slen - Num_Delete;
739          Source.Data (From .. Source.Current_Length) :=
740            Source.Data (Through + 1 .. Slen);
741       end if;
742    end Super_Delete;
743
744    -------------------
745    -- Super_Element --
746    -------------------
747
748    function Super_Element
749      (Source : Super_String;
750       Index  : Positive)
751       return   Character
752    is
753    begin
754       if Index in 1 .. Source.Current_Length then
755          return Source.Data (Index);
756       else
757          raise Strings.Index_Error;
758       end if;
759    end Super_Element;
760
761    ----------------------
762    -- Super_Find_Token --
763    ----------------------
764
765    procedure Super_Find_Token
766      (Source : Super_String;
767       Set    : Maps.Character_Set;
768       Test   : Strings.Membership;
769       First  : out Positive;
770       Last   : out Natural)
771    is
772    begin
773       Search.Find_Token
774         (Source.Data (1 .. Source.Current_Length), Set, Test, First, Last);
775    end Super_Find_Token;
776
777    ----------------
778    -- Super_Head --
779    ----------------
780
781    function Super_Head
782      (Source : Super_String;
783       Count  : Natural;
784       Pad    : Character := Space;
785       Drop   : Strings.Truncation := Strings.Error)
786       return   Super_String
787    is
788       Max_Length : constant Positive := Source.Max_Length;
789       Result     : Super_String (Max_Length);
790       Slen       : constant Natural := Source.Current_Length;
791       Npad       : constant Integer := Count - Slen;
792
793    begin
794       if Npad <= 0 then
795          Result.Current_Length := Count;
796          Result.Data (1 .. Count) := Source.Data (1 .. Count);
797
798       elsif Count <= Max_Length then
799          Result.Current_Length := Count;
800          Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
801          Result.Data (Slen + 1 .. Count) := (others => Pad);
802
803       else
804          Result.Current_Length := Max_Length;
805
806          case Drop is
807             when Strings.Right =>
808                Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
809                Result.Data (Slen + 1 .. Max_Length) := (others => Pad);
810
811             when Strings.Left =>
812                if Npad >= Max_Length then
813                   Result.Data := (others => Pad);
814
815                else
816                   Result.Data (1 .. Max_Length - Npad) :=
817                     Source.Data (Count - Max_Length + 1 .. Slen);
818                   Result.Data (Max_Length - Npad + 1 .. Max_Length) :=
819                     (others => Pad);
820                end if;
821
822             when Strings.Error =>
823                raise Ada.Strings.Length_Error;
824          end case;
825       end if;
826
827       return Result;
828    end Super_Head;
829
830    procedure Super_Head
831      (Source : in out Super_String;
832       Count  : Natural;
833       Pad    : Character  := Space;
834       Drop   : Truncation := Error)
835    is
836       Max_Length : constant Positive := Source.Max_Length;
837       Slen       : constant Natural  := Source.Current_Length;
838       Npad       : constant Integer  := Count - Slen;
839       Temp       : String (1 .. Max_Length);
840
841    begin
842       if Npad <= 0 then
843          Source.Current_Length := Count;
844
845       elsif Count <= Max_Length then
846          Source.Current_Length := Count;
847          Source.Data (Slen + 1 .. Count) := (others => Pad);
848
849       else
850          Source.Current_Length := Max_Length;
851
852          case Drop is
853             when Strings.Right =>
854                Source.Data (Slen + 1 .. Max_Length) := (others => Pad);
855
856             when Strings.Left =>
857                if Npad > Max_Length then
858                   Source.Data := (others => Pad);
859
860                else
861                   Temp := Source.Data;
862                   Source.Data (1 .. Max_Length - Npad) :=
863                     Temp (Count - Max_Length + 1 .. Slen);
864
865                   for J in Max_Length - Npad + 1 .. Max_Length loop
866                      Source.Data (J) := Pad;
867                   end loop;
868                end if;
869
870             when Strings.Error =>
871                raise Ada.Strings.Length_Error;
872          end case;
873       end if;
874    end Super_Head;
875
876    -----------------
877    -- Super_Index --
878    -----------------
879
880    function Super_Index
881      (Source   : Super_String;
882       Pattern  : String;
883       Going    : Strings.Direction := Strings.Forward;
884       Mapping  : Maps.Character_Mapping := Maps.Identity)
885       return     Natural
886    is
887    begin
888       return Search.Index
889         (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
890    end Super_Index;
891
892    function Super_Index
893      (Source   : Super_String;
894       Pattern  : String;
895       Going    : Direction := Forward;
896       Mapping  : Maps.Character_Mapping_Function)
897       return     Natural
898    is
899    begin
900       return Search.Index
901         (Source.Data (1 .. Source.Current_Length), Pattern, Going, Mapping);
902    end Super_Index;
903
904    function Super_Index
905      (Source : Super_String;
906       Set    : Maps.Character_Set;
907       Test   : Strings.Membership := Strings.Inside;
908       Going  : Strings.Direction  := Strings.Forward)
909       return   Natural
910    is
911    begin
912       return Search.Index
913         (Source.Data (1 .. Source.Current_Length), Set, Test, Going);
914    end Super_Index;
915
916    ---------------------------
917    -- Super_Index_Non_Blank --
918    ---------------------------
919
920    function Super_Index_Non_Blank
921      (Source : Super_String;
922       Going  : Strings.Direction := Strings.Forward)
923       return   Natural
924    is
925    begin
926       return
927         Search.Index_Non_Blank
928           (Source.Data (1 .. Source.Current_Length), Going);
929    end Super_Index_Non_Blank;
930
931    ------------------
932    -- Super_Insert --
933    ------------------
934
935    function Super_Insert
936      (Source   : Super_String;
937       Before   : Positive;
938       New_Item : String;
939       Drop     : Strings.Truncation := Strings.Error)
940       return     Super_String
941    is
942       Max_Length : constant Positive := Source.Max_Length;
943       Result     : Super_String (Max_Length);
944       Slen       : constant Natural := Source.Current_Length;
945       Nlen       : constant Natural := New_Item'Length;
946       Tlen       : constant Natural := Slen + Nlen;
947       Blen       : constant Natural := Before - 1;
948       Alen       : constant Integer := Slen - Blen;
949       Droplen    : constant Integer := Tlen - Max_Length;
950
951       --  Tlen is the length of the total string before possible truncation.
952       --  Blen, Alen are the lengths of the before and after pieces of the
953       --  source string.
954
955    begin
956       if Alen < 0 then
957          raise Ada.Strings.Index_Error;
958
959       elsif Droplen <= 0 then
960          Result.Current_Length := Tlen;
961          Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
962          Result.Data (Before .. Before + Nlen - 1) := New_Item;
963          Result.Data (Before + Nlen .. Tlen) :=
964            Source.Data (Before .. Slen);
965
966       else
967          Result.Current_Length := Max_Length;
968
969          case Drop is
970             when Strings.Right =>
971                Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
972
973                if Droplen > Alen then
974                   Result.Data (Before .. Max_Length) :=
975                     New_Item (New_Item'First
976                                 .. New_Item'First + Max_Length - Before);
977                else
978                   Result.Data (Before .. Before + Nlen - 1) := New_Item;
979                   Result.Data (Before + Nlen .. Max_Length) :=
980                     Source.Data (Before .. Slen - Droplen);
981                end if;
982
983             when Strings.Left =>
984                Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
985                  Source.Data (Before .. Slen);
986
987                if Droplen >= Blen then
988                   Result.Data (1 .. Max_Length - Alen) :=
989                     New_Item (New_Item'Last - (Max_Length - Alen) + 1
990                                 .. New_Item'Last);
991                else
992                   Result.Data
993                     (Blen - Droplen + 1 .. Max_Length - Alen) :=
994                     New_Item;
995                   Result.Data (1 .. Blen - Droplen) :=
996                     Source.Data (Droplen + 1 .. Blen);
997                end if;
998
999             when Strings.Error =>
1000                raise Ada.Strings.Length_Error;
1001          end case;
1002       end if;
1003
1004       return Result;
1005    end Super_Insert;
1006
1007    procedure Super_Insert
1008      (Source   : in out Super_String;
1009       Before   : Positive;
1010       New_Item : String;
1011       Drop     : Strings.Truncation := Strings.Error)
1012    is
1013    begin
1014       --  We do a double copy here because this is one of the situations
1015       --  in which we move data to the right, and at least at the moment,
1016       --  GNAT is not handling such cases correctly ???
1017
1018       Source := Super_Insert (Source, Before, New_Item, Drop);
1019    end Super_Insert;
1020
1021    ------------------
1022    -- Super_Length --
1023    ------------------
1024
1025    function Super_Length (Source : Super_String) return Natural is
1026    begin
1027       return Source.Current_Length;
1028    end Super_Length;
1029
1030    ---------------------
1031    -- Super_Overwrite --
1032    ---------------------
1033
1034    function Super_Overwrite
1035      (Source    : Super_String;
1036       Position  : Positive;
1037       New_Item  : String;
1038       Drop      : Strings.Truncation := Strings.Error)
1039       return      Super_String
1040    is
1041       Max_Length : constant Positive := Source.Max_Length;
1042       Result     : Super_String (Max_Length);
1043       Endpos     : constant Natural  := Position + New_Item'Length - 1;
1044       Slen       : constant Natural  := Source.Current_Length;
1045       Droplen    : Natural;
1046
1047    begin
1048       if Position > Slen + 1 then
1049          raise Ada.Strings.Index_Error;
1050
1051       elsif New_Item'Length = 0 then
1052          return Source;
1053
1054       elsif Endpos <= Slen then
1055          Result.Current_Length := Source.Current_Length;
1056          Result.Data (1 .. Slen) := Source.Data (1 .. Slen);
1057          Result.Data (Position .. Endpos) := New_Item;
1058          return Result;
1059
1060       elsif Endpos <= Max_Length then
1061          Result.Current_Length := Endpos;
1062          Result.Data (1 .. Position - 1) := Source.Data (1 .. Position - 1);
1063          Result.Data (Position .. Endpos) := New_Item;
1064          return Result;
1065
1066       else
1067          Result.Current_Length := Max_Length;
1068          Droplen := Endpos - Max_Length;
1069
1070          case Drop is
1071             when Strings.Right =>
1072                Result.Data (1 .. Position - 1) :=
1073                  Source.Data (1 .. Position - 1);
1074
1075                Result.Data (Position .. Max_Length) :=
1076                  New_Item (New_Item'First .. New_Item'Last - Droplen);
1077                return Result;
1078
1079             when Strings.Left =>
1080                if New_Item'Length >= Max_Length then
1081                   Result.Data (1 .. Max_Length) :=
1082                     New_Item (New_Item'Last - Max_Length + 1 ..
1083                                 New_Item'Last);
1084                   return Result;
1085
1086                else
1087                   Result.Data (1 .. Max_Length - New_Item'Length) :=
1088                     Source.Data (Droplen + 1 .. Position - 1);
1089                   Result.Data
1090                     (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1091                     New_Item;
1092                   return Result;
1093                end if;
1094
1095             when Strings.Error =>
1096                raise Ada.Strings.Length_Error;
1097          end case;
1098       end if;
1099    end Super_Overwrite;
1100
1101    procedure Super_Overwrite
1102      (Source    : in out Super_String;
1103       Position  : Positive;
1104       New_Item  : String;
1105       Drop      : Strings.Truncation := Strings.Error)
1106    is
1107       Max_Length : constant Positive := Source.Max_Length;
1108       Endpos     : constant Positive := Position + New_Item'Length - 1;
1109       Slen       : constant Natural  := Source.Current_Length;
1110       Droplen    : Natural;
1111
1112    begin
1113       if Position > Slen + 1 then
1114          raise Ada.Strings.Index_Error;
1115
1116       elsif Endpos <= Slen then
1117          Source.Data (Position .. Endpos) := New_Item;
1118
1119       elsif Endpos <= Max_Length then
1120          Source.Data (Position .. Endpos) := New_Item;
1121          Source.Current_Length := Endpos;
1122
1123       else
1124          Source.Current_Length := Max_Length;
1125          Droplen := Endpos - Max_Length;
1126
1127          case Drop is
1128             when Strings.Right =>
1129                Source.Data (Position .. Max_Length) :=
1130                  New_Item (New_Item'First .. New_Item'Last - Droplen);
1131
1132             when Strings.Left =>
1133                if New_Item'Length > Max_Length then
1134                   Source.Data (1 .. Max_Length) :=
1135                     New_Item (New_Item'Last - Max_Length + 1 ..
1136                                 New_Item'Last);
1137
1138                else
1139                   Source.Data (1 .. Max_Length - New_Item'Length) :=
1140                     Source.Data (Droplen + 1 .. Position - 1);
1141
1142                   Source.Data
1143                     (Max_Length - New_Item'Length + 1 .. Max_Length) :=
1144                     New_Item;
1145                end if;
1146
1147             when Strings.Error =>
1148                raise Ada.Strings.Length_Error;
1149          end case;
1150       end if;
1151    end Super_Overwrite;
1152
1153    ---------------------------
1154    -- Super_Replace_Element --
1155    ---------------------------
1156
1157    procedure Super_Replace_Element
1158      (Source : in out Super_String;
1159       Index  : Positive;
1160       By     : Character)
1161    is
1162    begin
1163       if Index <= Source.Current_Length then
1164          Source.Data (Index) := By;
1165       else
1166          raise Ada.Strings.Index_Error;
1167       end if;
1168    end Super_Replace_Element;
1169
1170    -------------------------
1171    -- Super_Replace_Slice --
1172    -------------------------
1173
1174    function Super_Replace_Slice
1175      (Source   : Super_String;
1176       Low      : Positive;
1177       High     : Natural;
1178       By       : String;
1179       Drop     : Strings.Truncation := Strings.Error)
1180       return     Super_String
1181    is
1182       Max_Length : constant Positive := Source.Max_Length;
1183       Slen       : constant Natural  := Source.Current_Length;
1184
1185    begin
1186       if Low > Slen + 1 then
1187          raise Strings.Index_Error;
1188
1189       elsif High < Low then
1190          return Super_Insert (Source, Low, By, Drop);
1191
1192       else
1193          declare
1194             Blen    : constant Natural := Natural'Max (0, Low - 1);
1195             Alen    : constant Natural := Natural'Max (0, Slen - High);
1196             Tlen    : constant Natural := Blen + By'Length + Alen;
1197             Droplen : constant Integer := Tlen - Max_Length;
1198             Result  : Super_String (Max_Length);
1199
1200             --  Tlen is the total length of the result string before any
1201             --  truncation. Blen and Alen are the lengths of the pieces
1202             --  of the original string that end up in the result string
1203             --  before and after the replaced slice.
1204
1205          begin
1206             if Droplen <= 0 then
1207                Result.Current_Length := Tlen;
1208                Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1209                Result.Data (Low .. Low + By'Length - 1) := By;
1210                Result.Data (Low + By'Length .. Tlen) :=
1211                  Source.Data (High + 1 .. Slen);
1212
1213             else
1214                Result.Current_Length := Max_Length;
1215
1216                case Drop is
1217                   when Strings.Right =>
1218                      Result.Data (1 .. Blen) := Source.Data (1 .. Blen);
1219
1220                      if Droplen > Alen then
1221                         Result.Data (Low .. Max_Length) :=
1222                           By (By'First .. By'First + Max_Length - Low);
1223                      else
1224                         Result.Data (Low .. Low + By'Length - 1) := By;
1225                         Result.Data (Low + By'Length .. Max_Length) :=
1226                           Source.Data (High + 1 .. Slen - Droplen);
1227                      end if;
1228
1229                   when Strings.Left =>
1230                      Result.Data (Max_Length - (Alen - 1) .. Max_Length) :=
1231                        Source.Data (High + 1 .. Slen);
1232
1233                      if Droplen >= Blen then
1234                         Result.Data (1 .. Max_Length - Alen) :=
1235                           By (By'Last - (Max_Length - Alen) + 1 .. By'Last);
1236                      else
1237                         Result.Data
1238                           (Blen - Droplen + 1 .. Max_Length - Alen) := By;
1239                         Result.Data (1 .. Blen - Droplen) :=
1240                           Source.Data (Droplen + 1 .. Blen);
1241                      end if;
1242
1243                   when Strings.Error =>
1244                      raise Ada.Strings.Length_Error;
1245                end case;
1246             end if;
1247
1248             return Result;
1249          end;
1250       end if;
1251    end Super_Replace_Slice;
1252
1253    procedure Super_Replace_Slice
1254      (Source   : in out Super_String;
1255       Low      : Positive;
1256       High     : Natural;
1257       By       : String;
1258       Drop     : Strings.Truncation := Strings.Error)
1259    is
1260    begin
1261       --  We do a double copy here because this is one of the situations
1262       --  in which we move data to the right, and at least at the moment,
1263       --  GNAT is not handling such cases correctly ???
1264
1265       Source := Super_Replace_Slice (Source, Low, High, By, Drop);
1266    end Super_Replace_Slice;
1267
1268    ---------------------
1269    -- Super_Replicate --
1270    ---------------------
1271
1272    function Super_Replicate
1273      (Count      : Natural;
1274       Item       : Character;
1275       Drop       : Truncation := Error;
1276       Max_Length : Positive)
1277       return       Super_String
1278    is
1279       Result : Super_String (Max_Length);
1280
1281    begin
1282       if Count <= Max_Length then
1283          Result.Current_Length := Count;
1284
1285       elsif Drop = Strings.Error then
1286          raise Ada.Strings.Length_Error;
1287
1288       else
1289          Result.Current_Length := Max_Length;
1290       end if;
1291
1292       Result.Data (1 .. Result.Current_Length) := (others => Item);
1293       return Result;
1294    end Super_Replicate;
1295
1296    function Super_Replicate
1297      (Count      : Natural;
1298       Item       : String;
1299       Drop       : Truncation := Error;
1300       Max_Length : Positive)
1301       return       Super_String
1302    is
1303       Length : constant Integer := Count * Item'Length;
1304       Result : Super_String (Max_Length);
1305       Indx   : Positive;
1306
1307    begin
1308       if Length <= Max_Length then
1309          Result.Current_Length := Length;
1310
1311          if Length > 0 then
1312             Indx := 1;
1313
1314             for J in 1 .. Count loop
1315                Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1316                Indx := Indx + Item'Length;
1317             end loop;
1318          end if;
1319
1320       else
1321          Result.Current_Length := Max_Length;
1322
1323          case Drop is
1324             when Strings.Right =>
1325                Indx := 1;
1326
1327                while Indx + Item'Length <= Max_Length + 1 loop
1328                   Result.Data (Indx .. Indx + Item'Length - 1) := Item;
1329                   Indx := Indx + Item'Length;
1330                end loop;
1331
1332                Result.Data (Indx .. Max_Length) :=
1333                  Item (Item'First .. Item'First + Max_Length - Indx);
1334
1335             when Strings.Left =>
1336                Indx := Max_Length;
1337
1338                while Indx - Item'Length >= 1 loop
1339                   Result.Data (Indx - (Item'Length - 1) .. Indx) := Item;
1340                   Indx := Indx - Item'Length;
1341                end loop;
1342
1343                Result.Data (1 .. Indx) :=
1344                  Item (Item'Last - Indx + 1 .. Item'Last);
1345
1346             when Strings.Error =>
1347                raise Ada.Strings.Length_Error;
1348          end case;
1349       end if;
1350
1351       return Result;
1352    end Super_Replicate;
1353
1354    function Super_Replicate
1355      (Count : Natural;
1356       Item  : Super_String;
1357       Drop  : Strings.Truncation := Strings.Error)
1358       return  Super_String
1359    is
1360    begin
1361       return
1362         Super_Replicate
1363           (Count,
1364            Item.Data (1 .. Item.Current_Length),
1365            Drop,
1366            Item.Max_Length);
1367    end Super_Replicate;
1368
1369    -----------------
1370    -- Super_Slice --
1371    -----------------
1372
1373    function Super_Slice
1374      (Source : Super_String;
1375       Low    : Positive;
1376       High   : Natural)
1377       return   String
1378    is
1379    begin
1380       --  Note: test of High > Length is in accordance with AI95-00128
1381
1382       if Low > Source.Current_Length + 1
1383         or else High > Source.Current_Length
1384       then
1385          raise Index_Error;
1386       else
1387          return Source.Data (Low .. High);
1388       end if;
1389    end Super_Slice;
1390
1391    ----------------
1392    -- Super_Tail --
1393    ----------------
1394
1395    function Super_Tail
1396      (Source : Super_String;
1397       Count  : Natural;
1398       Pad    : Character := Space;
1399       Drop   : Strings.Truncation := Strings.Error)
1400       return   Super_String
1401    is
1402       Max_Length : constant Positive := Source.Max_Length;
1403       Result     : Super_String (Max_Length);
1404       Slen       : constant Natural := Source.Current_Length;
1405       Npad       : constant Integer := Count - Slen;
1406
1407    begin
1408       if Npad <= 0 then
1409          Result.Current_Length := Count;
1410          Result.Data (1 .. Count) :=
1411            Source.Data (Slen - (Count - 1) .. Slen);
1412
1413       elsif Count <= Max_Length then
1414          Result.Current_Length := Count;
1415          Result.Data (1 .. Npad) := (others => Pad);
1416          Result.Data (Npad + 1 .. Count) := Source.Data (1 .. Slen);
1417
1418       else
1419          Result.Current_Length := Max_Length;
1420
1421          case Drop is
1422             when Strings.Right =>
1423                if Npad >= Max_Length then
1424                   Result.Data := (others => Pad);
1425
1426                else
1427                   Result.Data (1 .. Npad) := (others => Pad);
1428                   Result.Data (Npad + 1 .. Max_Length) :=
1429                     Source.Data (1 .. Max_Length - Npad);
1430                end if;
1431
1432             when Strings.Left =>
1433                Result.Data (1 .. Max_Length - Slen) := (others => Pad);
1434                Result.Data (Max_Length - Slen + 1 .. Max_Length) :=
1435                  Source.Data (1 .. Slen);
1436
1437             when Strings.Error =>
1438                raise Ada.Strings.Length_Error;
1439          end case;
1440       end if;
1441
1442       return Result;
1443    end Super_Tail;
1444
1445    procedure Super_Tail
1446      (Source : in out Super_String;
1447       Count  : Natural;
1448       Pad    : Character  := Space;
1449       Drop   : Truncation := Error)
1450    is
1451       Max_Length : constant Positive := Source.Max_Length;
1452       Slen       : constant Natural  := Source.Current_Length;
1453       Npad       : constant Integer  := Count - Slen;
1454
1455       Temp : constant String (1 .. Max_Length) := Source.Data;
1456
1457    begin
1458       if Npad <= 0 then
1459          Source.Current_Length := Count;
1460          Source.Data (1 .. Count) :=
1461            Temp (Slen - (Count - 1) .. Slen);
1462
1463       elsif Count <= Max_Length then
1464          Source.Current_Length := Count;
1465          Source.Data (1 .. Npad) := (others => Pad);
1466          Source.Data (Npad + 1 .. Count) := Temp (1 .. Slen);
1467
1468       else
1469          Source.Current_Length := Max_Length;
1470
1471          case Drop is
1472             when Strings.Right =>
1473                if Npad >= Max_Length then
1474                   Source.Data := (others => Pad);
1475
1476                else
1477                   Source.Data (1 .. Npad) := (others => Pad);
1478                   Source.Data (Npad + 1 .. Max_Length) :=
1479                     Temp (1 .. Max_Length - Npad);
1480                end if;
1481
1482             when Strings.Left =>
1483                for J in 1 .. Max_Length - Slen loop
1484                   Source.Data (J) := Pad;
1485                end loop;
1486
1487                Source.Data (Max_Length - Slen + 1 .. Max_Length) :=
1488                  Temp (1 .. Slen);
1489
1490             when Strings.Error =>
1491                raise Ada.Strings.Length_Error;
1492          end case;
1493       end if;
1494    end Super_Tail;
1495
1496    ---------------------
1497    -- Super_To_String --
1498    ---------------------
1499
1500    function Super_To_String (Source : in Super_String) return String is
1501    begin
1502       return Source.Data (1 .. Source.Current_Length);
1503    end Super_To_String;
1504
1505    ---------------------
1506    -- Super_Translate --
1507    ---------------------
1508
1509    function Super_Translate
1510      (Source  : Super_String;
1511       Mapping : Maps.Character_Mapping)
1512       return    Super_String
1513    is
1514       Result : Super_String (Source.Max_Length);
1515
1516    begin
1517       Result.Current_Length := Source.Current_Length;
1518
1519       for J in 1 .. Source.Current_Length loop
1520          Result.Data (J) := Value (Mapping, Source.Data (J));
1521       end loop;
1522
1523       return Result;
1524    end Super_Translate;
1525
1526    procedure Super_Translate
1527      (Source  : in out Super_String;
1528       Mapping : Maps.Character_Mapping)
1529    is
1530    begin
1531       for J in 1 .. Source.Current_Length loop
1532          Source.Data (J) := Value (Mapping, Source.Data (J));
1533       end loop;
1534    end Super_Translate;
1535
1536    function Super_Translate
1537      (Source  : Super_String;
1538       Mapping : Maps.Character_Mapping_Function)
1539       return    Super_String
1540    is
1541       Result : Super_String (Source.Max_Length);
1542
1543    begin
1544       Result.Current_Length := Source.Current_Length;
1545
1546       for J in 1 .. Source.Current_Length loop
1547          Result.Data (J) := Mapping.all (Source.Data (J));
1548       end loop;
1549
1550       return Result;
1551    end Super_Translate;
1552
1553    procedure Super_Translate
1554      (Source  : in out Super_String;
1555       Mapping : Maps.Character_Mapping_Function)
1556    is
1557    begin
1558       for J in 1 .. Source.Current_Length loop
1559          Source.Data (J) := Mapping.all (Source.Data (J));
1560       end loop;
1561    end Super_Translate;
1562
1563    ----------------
1564    -- Super_Trim --
1565    ----------------
1566
1567    function Super_Trim (Source : Super_String; Side : Trim_End)
1568                         return   Super_String
1569    is
1570       Result : Super_String (Source.Max_Length);
1571       Last   : Natural := Source.Current_Length;
1572       First  : Positive := 1;
1573
1574    begin
1575       if Side = Left or else Side = Both then
1576          while First <= Last and then Source.Data (First) = ' ' loop
1577             First := First + 1;
1578          end loop;
1579       end if;
1580
1581       if Side = Right or else Side = Both then
1582          while Last >= First and then Source.Data (Last) = ' ' loop
1583             Last := Last - 1;
1584          end loop;
1585       end if;
1586
1587       Result.Current_Length := Last - First + 1;
1588       Result.Data (1 .. Result.Current_Length) := Source.Data (First .. Last);
1589       return Result;
1590    end Super_Trim;
1591
1592    procedure Super_Trim
1593      (Source : in out Super_String;
1594       Side   : Trim_End)
1595    is
1596       Max_Length : constant Positive := Source.Max_Length;
1597       Last       : Natural           := Source.Current_Length;
1598       First      : Positive          := 1;
1599       Temp       : String (1 .. Max_Length);
1600
1601    begin
1602       Temp (1 .. Last) := Source.Data (1 .. Last);
1603
1604       if Side = Left or else Side = Both then
1605          while First <= Last and then Temp (First) = ' ' loop
1606             First := First + 1;
1607          end loop;
1608       end if;
1609
1610       if Side = Right or else Side = Both then
1611          while Last >= First and then Temp (Last) = ' ' loop
1612             Last := Last - 1;
1613          end loop;
1614       end if;
1615
1616       Source.Data := (others => ASCII.NUL);
1617       Source.Current_Length := Last - First + 1;
1618       Source.Data (1 .. Source.Current_Length) := Temp (First .. Last);
1619    end Super_Trim;
1620
1621    function Super_Trim
1622      (Source : Super_String;
1623       Left   : Maps.Character_Set;
1624       Right  : Maps.Character_Set)
1625       return   Super_String
1626    is
1627       Result : Super_String (Source.Max_Length);
1628
1629    begin
1630       for First in 1 .. Source.Current_Length loop
1631          if not Is_In (Source.Data (First), Left) then
1632             for Last in reverse First .. Source.Current_Length loop
1633                if not Is_In (Source.Data (Last), Right) then
1634                   Result.Current_Length := Last - First + 1;
1635                   Result.Data (1 .. Result.Current_Length) :=
1636                     Source.Data (First .. Last);
1637                   return Result;
1638                end if;
1639             end loop;
1640          end if;
1641       end loop;
1642
1643       Result.Current_Length := 0;
1644       return Result;
1645    end Super_Trim;
1646
1647    procedure Super_Trim
1648      (Source : in out Super_String;
1649       Left   : Maps.Character_Set;
1650       Right  : Maps.Character_Set)
1651    is
1652    begin
1653       for First in 1 .. Source.Current_Length loop
1654          if not Is_In (Source.Data (First), Left) then
1655             for Last in reverse First .. Source.Current_Length loop
1656                if not Is_In (Source.Data (Last), Right) then
1657                   if First = 1 then
1658                      Source.Current_Length := Last;
1659                      return;
1660                   else
1661                      Source.Current_Length := Last - First + 1;
1662                      Source.Data (1 .. Source.Current_Length) :=
1663                        Source.Data (First .. Last);
1664
1665                      for J in Source.Current_Length + 1 ..
1666                                 Source.Max_Length
1667                      loop
1668                         Source.Data (J) := ASCII.NUL;
1669                      end loop;
1670
1671                      return;
1672                   end if;
1673                end if;
1674             end loop;
1675
1676             Source.Current_Length := 0;
1677             return;
1678          end if;
1679       end loop;
1680
1681       Source.Current_Length := 0;
1682    end Super_Trim;
1683
1684    -----------
1685    -- Times --
1686    -----------
1687
1688    function Times
1689      (Left       : Natural;
1690       Right      : Character;
1691       Max_Length : Positive)
1692       return  Super_String
1693    is
1694       Result : Super_String (Max_Length);
1695
1696    begin
1697       if Left > Max_Length then
1698          raise Ada.Strings.Length_Error;
1699
1700       else
1701          Result.Current_Length := Left;
1702
1703          for J in 1 .. Left loop
1704             Result.Data (J) := Right;
1705          end loop;
1706       end if;
1707
1708       return Result;
1709    end Times;
1710
1711    function Times
1712      (Left       : Natural;
1713       Right      : String;
1714       Max_Length : Positive)
1715       return  Super_String
1716    is
1717       Result : Super_String (Max_Length);
1718       Pos    : Positive         := 1;
1719       Rlen   : constant Natural := Right'Length;
1720       Nlen   : constant Natural := Left * Rlen;
1721
1722    begin
1723       if Nlen > Max_Length then
1724          raise Ada.Strings.Index_Error;
1725
1726       else
1727          Result.Current_Length := Nlen;
1728
1729          if Nlen > 0 then
1730             for J in 1 .. Left loop
1731                Result.Data (Pos .. Pos + Rlen - 1) := Right;
1732                Pos := Pos + Rlen;
1733             end loop;
1734          end if;
1735       end if;
1736
1737       return Result;
1738    end Times;
1739
1740    function Times
1741      (Left  : Natural;
1742       Right : Super_String)
1743       return  Super_String
1744    is
1745       Result : Super_String (Right.Max_Length);
1746       Pos    : Positive := 1;
1747       Rlen   : constant Natural := Right.Current_Length;
1748       Nlen   : constant Natural := Left * Rlen;
1749
1750    begin
1751       if Nlen > Right.Max_Length then
1752          raise Ada.Strings.Length_Error;
1753
1754       else
1755          Result.Current_Length := Nlen;
1756
1757          if Nlen > 0 then
1758             for J in 1 .. Left loop
1759                Result.Data (Pos .. Pos + Rlen - 1) :=
1760                  Right.Data (1 .. Rlen);
1761                Pos := Pos + Rlen;
1762             end loop;
1763          end if;
1764       end if;
1765
1766       return Result;
1767    end Times;
1768
1769    ---------------------
1770    -- To_Super_String --
1771    ---------------------
1772
1773    function To_Super_String
1774      (Source     : String;
1775       Max_Length : Natural;
1776       Drop       : Truncation := Error)
1777       return       Super_String
1778    is
1779       Result : Super_String (Max_Length);
1780       Slen   : constant Natural := Source'Length;
1781
1782    begin
1783       if Slen <= Max_Length then
1784          Result.Current_Length := Slen;
1785          Result.Data (1 .. Slen) := Source;
1786
1787       else
1788          case Drop is
1789             when Strings.Right =>
1790                Result.Current_Length := Max_Length;
1791                Result.Data (1 .. Max_Length) :=
1792                  Source (Source'First .. Source'First - 1 + Max_Length);
1793
1794             when Strings.Left =>
1795                Result.Current_Length := Max_Length;
1796                Result.Data (1 .. Max_Length) :=
1797                  Source (Source'Last - (Max_Length - 1) .. Source'Last);
1798
1799             when Strings.Error =>
1800                raise Ada.Strings.Length_Error;
1801          end case;
1802       end if;
1803
1804       return Result;
1805    end To_Super_String;
1806
1807 end Ada.Strings.Superbounded;