OSDN Git Service

* Make-lang.in (gnat_ug_unx.info): Add dependency on stmp-docobjdir.
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-strunb.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT RUNTIME COMPONENTS                          --
4 --                                                                          --
5 --                A D A . S T R I N G S . U N B O U N D E D                 --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2001 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.Fixed;
35 with Ada.Strings.Search;
36 with Ada.Unchecked_Deallocation;
37
38 package body Ada.Strings.Unbounded is
39
40    use Ada.Finalization;
41
42    ---------
43    -- "&" --
44    ---------
45
46    function "&" (Left, Right : Unbounded_String) return Unbounded_String is
47       L_Length : constant Integer := Left.Reference.all'Length;
48       R_Length : constant Integer := Right.Reference.all'Length;
49       Length   : constant Integer :=  L_Length + R_Length;
50       Result   : Unbounded_String;
51
52    begin
53       Result.Reference := new String (1 .. Length);
54       Result.Reference.all (1 .. L_Length)          := Left.Reference.all;
55       Result.Reference.all (L_Length + 1 .. Length) := Right.Reference.all;
56       return Result;
57    end "&";
58
59    function "&"
60      (Left  : Unbounded_String;
61       Right : String)
62       return  Unbounded_String
63    is
64       L_Length : constant Integer := Left.Reference.all'Length;
65       Length   : constant Integer := L_Length +  Right'Length;
66       Result   : Unbounded_String;
67
68    begin
69       Result.Reference := new String (1 .. Length);
70       Result.Reference.all (1 .. L_Length)          := Left.Reference.all;
71       Result.Reference.all (L_Length + 1 .. Length) := Right;
72       return Result;
73    end "&";
74
75    function "&"
76      (Left  : String;
77       Right : Unbounded_String)
78       return  Unbounded_String
79    is
80       R_Length : constant Integer := Right.Reference.all'Length;
81       Length   : constant Integer := Left'Length + R_Length;
82       Result   : Unbounded_String;
83
84    begin
85       Result.Reference := new String (1 .. Length);
86       Result.Reference.all (1 .. Left'Length)          := Left;
87       Result.Reference.all (Left'Length + 1 .. Length) := Right.Reference.all;
88       return Result;
89    end "&";
90
91    function "&"
92      (Left  : Unbounded_String;
93       Right : Character)
94       return  Unbounded_String
95    is
96       Length : constant Integer := Left.Reference.all'Length + 1;
97       Result : Unbounded_String;
98
99    begin
100       Result.Reference := new String (1 .. Length);
101       Result.Reference.all (1 .. Length - 1) := Left.Reference.all;
102       Result.Reference.all (Length)          := Right;
103       return Result;
104    end "&";
105
106    function "&"
107      (Left  : Character;
108       Right : Unbounded_String)
109       return  Unbounded_String
110    is
111       Length : constant Integer := Right.Reference.all'Length + 1;
112       Result : Unbounded_String;
113
114    begin
115       Result.Reference := new String (1 .. Length);
116       Result.Reference.all (1)           := Left;
117       Result.Reference.all (2 .. Length) := Right.Reference.all;
118       return Result;
119    end "&";
120
121    ---------
122    -- "*" --
123    ---------
124
125    function "*"
126      (Left  : Natural;
127       Right : Character)
128       return  Unbounded_String
129    is
130       Result : Unbounded_String;
131
132    begin
133       Result.Reference := new String (1 .. Left);
134       for J in Result.Reference'Range loop
135          Result.Reference (J) := Right;
136       end loop;
137
138       return Result;
139    end "*";
140
141    function "*"
142      (Left  : Natural;
143       Right : String)
144      return   Unbounded_String
145    is
146       Len    : constant Integer := Right'Length;
147       Result : Unbounded_String;
148
149    begin
150       Result.Reference := new String (1 .. Left * Len);
151       for J in 1 .. Left loop
152          Result.Reference.all (Len * J - Len + 1 .. Len * J) := Right;
153       end loop;
154
155       return Result;
156    end "*";
157
158    function "*"
159      (Left  : Natural;
160       Right : Unbounded_String)
161       return  Unbounded_String
162    is
163       Len    : constant Integer := Right.Reference.all'Length;
164       Result : Unbounded_String;
165
166    begin
167       Result.Reference := new String (1 .. Left * Len);
168       for I in 1 .. Left loop
169          Result.Reference.all (Len * I - Len + 1 .. Len * I) :=
170            Right.Reference.all;
171       end loop;
172
173       return Result;
174    end "*";
175
176    ---------
177    -- "<" --
178    ---------
179
180    function "<" (Left, Right : in Unbounded_String) return Boolean is
181    begin
182       return Left.Reference.all < Right.Reference.all;
183    end "<";
184
185    function "<"
186      (Left  : in Unbounded_String;
187       Right : in String)
188       return  Boolean
189    is
190    begin
191       return Left.Reference.all < Right;
192    end "<";
193
194    function "<"
195      (Left  : in String;
196       Right : in Unbounded_String)
197       return  Boolean
198    is
199    begin
200       return Left < Right.Reference.all;
201    end "<";
202
203    ----------
204    -- "<=" --
205    ----------
206
207    function "<=" (Left, Right : in Unbounded_String) return Boolean is
208    begin
209       return Left.Reference.all <= Right.Reference.all;
210    end "<=";
211
212    function "<="
213      (Left  : in Unbounded_String;
214       Right : in String)
215       return  Boolean
216    is
217    begin
218       return Left.Reference.all <= Right;
219    end "<=";
220
221    function "<="
222      (Left  : in String;
223       Right : in Unbounded_String)
224       return  Boolean
225    is
226    begin
227       return Left <= Right.Reference.all;
228    end "<=";
229
230    ---------
231    -- "=" --
232    ---------
233
234    function "=" (Left, Right : in Unbounded_String) return Boolean is
235    begin
236       return Left.Reference.all = Right.Reference.all;
237    end "=";
238
239    function "="
240      (Left  : in Unbounded_String;
241       Right : in String)
242       return  Boolean
243    is
244    begin
245       return Left.Reference.all = Right;
246    end "=";
247
248    function "="
249      (Left  : in String;
250       Right : in Unbounded_String)
251       return  Boolean
252    is
253    begin
254       return Left = Right.Reference.all;
255    end "=";
256
257    ---------
258    -- ">" --
259    ---------
260
261    function ">"  (Left, Right : in Unbounded_String) return Boolean is
262    begin
263       return Left.Reference.all > Right.Reference.all;
264    end ">";
265
266    function ">"
267      (Left  : in Unbounded_String;
268       Right : in String)
269       return  Boolean
270    is
271    begin
272       return Left.Reference.all > Right;
273    end ">";
274
275    function ">"
276      (Left  : in String;
277       Right : in Unbounded_String)
278       return  Boolean
279    is
280    begin
281       return Left > Right.Reference.all;
282    end ">";
283
284    ----------
285    -- ">=" --
286    ----------
287
288    function ">=" (Left, Right : in Unbounded_String) return Boolean is
289    begin
290       return Left.Reference.all >= Right.Reference.all;
291    end ">=";
292
293    function ">="
294      (Left  : in Unbounded_String;
295       Right : in String)
296       return  Boolean
297    is
298    begin
299       return Left.Reference.all >= Right;
300    end ">=";
301
302    function ">="
303      (Left  : in String;
304       Right : in Unbounded_String)
305       return  Boolean
306    is
307    begin
308       return Left >= Right.Reference.all;
309    end ">=";
310
311    ------------
312    -- Adjust --
313    ------------
314
315    procedure Adjust (Object : in out Unbounded_String) is
316    begin
317       --  Copy string, except we do not copy the statically allocated null
318       --  string, since it can never be deallocated.
319
320       if Object.Reference /= Null_String'Access then
321          Object.Reference := new String'(Object.Reference.all);
322       end if;
323    end Adjust;
324
325    ------------
326    -- Append --
327    ------------
328
329    procedure Append
330      (Source   : in out Unbounded_String;
331       New_Item : in Unbounded_String)
332    is
333       S_Length : constant Integer := Source.Reference.all'Length;
334       Length   : constant Integer := S_Length + New_Item.Reference.all'Length;
335       Tmp      : String_Access;
336
337    begin
338       Tmp := new String (1 .. Length);
339       Tmp (1 .. S_Length) := Source.Reference.all;
340       Tmp (S_Length + 1 .. Length) := New_Item.Reference.all;
341       Free (Source.Reference);
342       Source.Reference := Tmp;
343    end Append;
344
345    procedure Append
346      (Source   : in out Unbounded_String;
347       New_Item : in String)
348    is
349       S_Length : constant Integer := Source.Reference.all'Length;
350       Length   : constant Integer := S_Length + New_Item'Length;
351       Tmp      : String_Access;
352
353    begin
354       Tmp := new String (1 .. Length);
355       Tmp (1 .. S_Length) := Source.Reference.all;
356       Tmp (S_Length + 1 .. Length) := New_Item;
357       Free (Source.Reference);
358       Source.Reference := Tmp;
359    end Append;
360
361    procedure Append
362      (Source   : in out Unbounded_String;
363       New_Item : in Character)
364    is
365       S_Length : constant Integer := Source.Reference.all'Length;
366       Length   : constant Integer := S_Length + 1;
367       Tmp      : String_Access;
368
369    begin
370       Tmp := new String (1 .. Length);
371       Tmp (1 .. S_Length) := Source.Reference.all;
372       Tmp (S_Length + 1) := New_Item;
373       Free (Source.Reference);
374       Source.Reference := Tmp;
375    end Append;
376
377    -----------
378    -- Count --
379    -----------
380
381    function Count
382      (Source   : Unbounded_String;
383       Pattern  : String;
384       Mapping  : Maps.Character_Mapping := Maps.Identity)
385       return     Natural
386    is
387    begin
388       return Search.Count (Source.Reference.all, Pattern, Mapping);
389    end Count;
390
391    function Count
392      (Source   : in Unbounded_String;
393       Pattern  : in String;
394       Mapping  : in Maps.Character_Mapping_Function)
395       return     Natural
396    is
397    begin
398       return Search.Count (Source.Reference.all, Pattern, Mapping);
399    end Count;
400
401    function Count
402      (Source   : Unbounded_String;
403       Set      : Maps.Character_Set)
404       return     Natural
405    is
406    begin
407       return Search.Count (Source.Reference.all, Set);
408    end Count;
409
410    ------------
411    -- Delete --
412    ------------
413
414    function Delete
415      (Source  : Unbounded_String;
416       From    : Positive;
417       Through : Natural)
418       return    Unbounded_String
419    is
420    begin
421       return
422         To_Unbounded_String
423           (Fixed.Delete (Source.Reference.all, From, Through));
424    end Delete;
425
426    procedure Delete
427      (Source  : in out Unbounded_String;
428       From    : in Positive;
429       Through : in Natural)
430    is
431       Old : String_Access := Source.Reference;
432
433    begin
434       Source.Reference :=
435         new String' (Fixed.Delete (Old.all, From, Through));
436       Free (Old);
437    end Delete;
438
439    -------------
440    -- Element --
441    -------------
442
443    function Element
444      (Source : Unbounded_String;
445       Index  : Positive)
446       return   Character
447    is
448    begin
449       if Index <= Source.Reference.all'Last then
450          return Source.Reference.all (Index);
451       else
452          raise Strings.Index_Error;
453       end if;
454    end Element;
455
456    --------------
457    -- Finalize --
458    --------------
459
460    procedure Finalize (Object : in out Unbounded_String) is
461       procedure Deallocate is
462          new Ada.Unchecked_Deallocation (String, String_Access);
463
464    begin
465       --  Note: Don't try to free statically allocated null string
466
467       if Object.Reference /= Null_String'Access then
468          Deallocate (Object.Reference);
469          Object.Reference := Null_Unbounded_String.Reference;
470       end if;
471    end Finalize;
472
473    ----------------
474    -- Find_Token --
475    ----------------
476
477    procedure Find_Token
478      (Source : Unbounded_String;
479       Set    : Maps.Character_Set;
480       Test   : Strings.Membership;
481       First  : out Positive;
482       Last   : out Natural)
483    is
484    begin
485       Search.Find_Token (Source.Reference.all, Set, Test, First, Last);
486    end Find_Token;
487
488    ----------
489    -- Free --
490    ----------
491
492    procedure Free (X : in out String_Access) is
493       procedure Deallocate is
494          new Ada.Unchecked_Deallocation (String, String_Access);
495
496    begin
497       --  Note: Don't try to free statically allocated null string
498
499       if X /= Null_Unbounded_String.Reference then
500          Deallocate (X);
501       end if;
502    end Free;
503
504    ----------
505    -- Head --
506    ----------
507
508    function Head
509      (Source : Unbounded_String;
510       Count  : Natural;
511       Pad    : Character := Space)
512       return   Unbounded_String
513    is
514    begin
515       return
516         To_Unbounded_String (Fixed.Head (Source.Reference.all, Count, Pad));
517    end Head;
518
519    procedure Head
520      (Source : in out Unbounded_String;
521       Count  : in Natural;
522       Pad    : in Character := Space)
523    is
524       Old : String_Access := Source.Reference;
525
526    begin
527       Source.Reference := new String'(Fixed.Head (Old.all, Count, Pad));
528       Free (Old);
529    end Head;
530
531    -----------
532    -- Index --
533    -----------
534
535    function Index
536      (Source   : Unbounded_String;
537       Pattern  : String;
538       Going    : Strings.Direction := Strings.Forward;
539       Mapping  : Maps.Character_Mapping := Maps.Identity)
540       return     Natural
541    is
542    begin
543       return Search.Index (Source.Reference.all, Pattern, Going, Mapping);
544    end Index;
545
546    function Index
547      (Source   : in Unbounded_String;
548       Pattern  : in String;
549       Going    : in Direction := Forward;
550       Mapping  : in Maps.Character_Mapping_Function)
551       return Natural
552    is
553    begin
554       return Search.Index (Source.Reference.all, Pattern, Going, Mapping);
555    end Index;
556
557    function Index
558      (Source : Unbounded_String;
559       Set    : Maps.Character_Set;
560       Test   : Strings.Membership := Strings.Inside;
561       Going  : Strings.Direction  := Strings.Forward)
562       return   Natural
563    is
564    begin
565       return Search.Index (Source.Reference.all, Set, Test, Going);
566    end Index;
567
568    function Index_Non_Blank
569      (Source : Unbounded_String;
570       Going  : Strings.Direction := Strings.Forward)
571       return   Natural
572    is
573    begin
574       return Search.Index_Non_Blank (Source.Reference.all, Going);
575    end Index_Non_Blank;
576
577    ----------------
578    -- Initialize --
579    ----------------
580
581    procedure Initialize (Object : in out Unbounded_String) is
582    begin
583       Object.Reference := Null_Unbounded_String.Reference;
584    end Initialize;
585
586    ------------
587    -- Insert --
588    ------------
589
590    function Insert
591      (Source   : Unbounded_String;
592       Before   : Positive;
593       New_Item : String)
594       return     Unbounded_String
595    is
596    begin
597       return
598         To_Unbounded_String
599           (Fixed.Insert (Source.Reference.all, Before, New_Item));
600    end Insert;
601
602    procedure Insert
603      (Source   : in out Unbounded_String;
604       Before   : in Positive;
605       New_Item : in String)
606    is
607       Old : String_Access := Source.Reference;
608
609    begin
610       Source.Reference :=
611         new String' (Fixed.Insert (Source.Reference.all, Before, New_Item));
612       Free (Old);
613    end Insert;
614
615    ------------
616    -- Length --
617    ------------
618
619    function Length (Source : Unbounded_String) return Natural is
620    begin
621       return Source.Reference.all'Length;
622    end Length;
623
624    ---------------
625    -- Overwrite --
626    ---------------
627
628    function Overwrite
629      (Source    : Unbounded_String;
630       Position  : Positive;
631       New_Item  : String)
632       return      Unbounded_String is
633
634    begin
635       return To_Unbounded_String
636         (Fixed.Overwrite (Source.Reference.all, Position, New_Item));
637    end Overwrite;
638
639    procedure Overwrite
640      (Source    : in out Unbounded_String;
641       Position  : in Positive;
642       New_Item  : in String)
643    is
644       NL : constant Integer := New_Item'Length;
645
646    begin
647       if Position <= Source.Reference'Length - NL + 1 then
648          Source.Reference (Position .. Position + NL - 1) := New_Item;
649
650       else
651          declare
652             Old : String_Access := Source.Reference;
653
654          begin
655             Source.Reference := new
656               String'(Fixed.Overwrite (Old.all, Position, New_Item));
657             Free (Old);
658          end;
659       end if;
660    end Overwrite;
661
662    ---------------------
663    -- Replace_Element --
664    ---------------------
665
666    procedure Replace_Element
667      (Source : in out Unbounded_String;
668       Index  : Positive;
669       By     : Character)
670    is
671    begin
672       if Index <= Source.Reference.all'Last then
673          Source.Reference.all (Index) := By;
674       else
675          raise Strings.Index_Error;
676       end if;
677    end Replace_Element;
678
679    -------------------
680    -- Replace_Slice --
681    -------------------
682
683    function Replace_Slice
684      (Source   : Unbounded_String;
685       Low      : Positive;
686       High     : Natural;
687       By       : String)
688       return     Unbounded_String
689    is
690    begin
691       return
692         To_Unbounded_String
693           (Fixed.Replace_Slice (Source.Reference.all, Low, High, By));
694    end Replace_Slice;
695
696    procedure Replace_Slice
697      (Source   : in out Unbounded_String;
698       Low      : in Positive;
699       High     : in Natural;
700       By       : in String)
701    is
702       Old : String_Access := Source.Reference;
703
704    begin
705       Source.Reference :=
706         new String'(Fixed.Replace_Slice (Old.all, Low, High, By));
707       Free (Old);
708    end Replace_Slice;
709
710    -----------
711    -- Slice --
712    -----------
713
714    function Slice
715      (Source : Unbounded_String;
716       Low    : Positive;
717       High   : Natural)
718       return   String
719    is
720       Length : constant Natural := Source.Reference'Length;
721
722    begin
723       --  Note: test of High > Length is in accordance with AI95-00128
724
725       if Low > Length + 1 or else High > Length then
726          raise Index_Error;
727       else
728          return Source.Reference.all (Low .. High);
729       end if;
730    end Slice;
731
732    ----------
733    -- Tail --
734    ----------
735
736    function Tail
737      (Source : Unbounded_String;
738       Count  : Natural;
739       Pad    : Character := Space)
740       return   Unbounded_String is
741
742    begin
743       return
744         To_Unbounded_String (Fixed.Tail (Source.Reference.all, Count, Pad));
745    end Tail;
746
747    procedure Tail
748      (Source : in out Unbounded_String;
749       Count  : in Natural;
750       Pad    : in Character := Space)
751    is
752       Old : String_Access := Source.Reference;
753
754    begin
755       Source.Reference := new String'(Fixed.Tail (Old.all, Count, Pad));
756       Free (Old);
757    end Tail;
758
759    ---------------
760    -- To_String --
761    ---------------
762
763    function To_String (Source : Unbounded_String) return String is
764    begin
765       return Source.Reference.all;
766    end To_String;
767
768    -------------------------
769    -- To_Unbounded_String --
770    -------------------------
771
772    function To_Unbounded_String (Source : String) return Unbounded_String is
773       Result : Unbounded_String;
774
775    begin
776       Result.Reference := new String (1 .. Source'Length);
777       Result.Reference.all := Source;
778       return Result;
779    end To_Unbounded_String;
780
781    function To_Unbounded_String
782      (Length : in Natural)
783       return   Unbounded_String
784    is
785       Result : Unbounded_String;
786
787    begin
788       Result.Reference := new String (1 .. Length);
789       return Result;
790    end To_Unbounded_String;
791
792    ---------------
793    -- Translate --
794    ---------------
795
796    function Translate
797      (Source  : Unbounded_String;
798       Mapping : Maps.Character_Mapping)
799       return    Unbounded_String
800    is
801    begin
802       return
803         To_Unbounded_String (Fixed.Translate (Source.Reference.all, Mapping));
804    end Translate;
805
806    procedure Translate
807      (Source  : in out Unbounded_String;
808       Mapping : Maps.Character_Mapping)
809    is
810    begin
811       Fixed.Translate (Source.Reference.all, Mapping);
812    end Translate;
813
814    function Translate
815      (Source  : in Unbounded_String;
816       Mapping : in Maps.Character_Mapping_Function)
817       return    Unbounded_String
818    is
819    begin
820       return
821         To_Unbounded_String (Fixed.Translate (Source.Reference.all, Mapping));
822    end Translate;
823
824    procedure Translate
825      (Source  : in out Unbounded_String;
826       Mapping : in Maps.Character_Mapping_Function)
827    is
828    begin
829       Fixed.Translate (Source.Reference.all, Mapping);
830    end Translate;
831
832    ----------
833    -- Trim --
834    ----------
835
836    function Trim
837      (Source : in Unbounded_String;
838       Side   : in Trim_End)
839       return   Unbounded_String
840    is
841    begin
842       return To_Unbounded_String (Fixed.Trim (Source.Reference.all, Side));
843    end Trim;
844
845    procedure Trim
846      (Source : in out Unbounded_String;
847       Side   : in Trim_End)
848    is
849       Old : String_Access := Source.Reference;
850
851    begin
852       Source.Reference := new String'(Fixed.Trim (Old.all, Side));
853       Free (Old);
854    end Trim;
855
856    function Trim
857      (Source : in Unbounded_String;
858       Left   : in Maps.Character_Set;
859       Right  : in Maps.Character_Set)
860       return   Unbounded_String
861    is
862    begin
863       return
864         To_Unbounded_String (Fixed.Trim (Source.Reference.all, Left, Right));
865    end Trim;
866
867    procedure Trim
868      (Source : in out Unbounded_String;
869       Left   : in Maps.Character_Set;
870       Right  : in Maps.Character_Set)
871    is
872       Old : String_Access := Source.Reference;
873
874    begin
875       Source.Reference := new String'(Fixed.Trim (Old.all, Left, Right));
876       Free (Old);
877    end Trim;
878
879 end Ada.Strings.Unbounded;