OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-dev/] [fsf-gcc-snapshot-1-mar-12/] [or1k-gcc/] [gcc/] [ada/] [a-strfix.adb] - Blame information for rev 706

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT RUN-TIME COMPONENTS                         --
4
--                                                                          --
5
--                    A D A . S T R I N G S . F I X E D                     --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
10
--                                                                          --
11
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12
-- terms of the  GNU General Public License as published  by the Free Soft- --
13
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
17
--                                                                          --
18
-- As a special exception under Section 7 of GPL version 3, you are granted --
19
-- additional permissions described in the GCC Runtime Library Exception,   --
20
-- version 3.1, as published by the Free Software Foundation.               --
21
--                                                                          --
22
-- You should have received a copy of the GNU General Public License and    --
23
-- a copy of the GCC Runtime Library Exception along with this program;     --
24
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25
-- <http://www.gnu.org/licenses/>.                                          --
26
--                                                                          --
27
-- GNAT was originally developed  by the GNAT team at  New York University. --
28
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
29
--                                                                          --
30
------------------------------------------------------------------------------
31
 
32
--  Note: This code is derived from the ADAR.CSH public domain Ada 83 versions
33
--  of the Appendix C string handling packages. One change is to avoid the use
34
--  of Is_In, so that we are not dependent on inlining. Note that the search
35
--  function implementations are to be found in the auxiliary package
36
--  Ada.Strings.Search. Also the Move procedure is directly incorporated (ADAR
37
--  used a subunit for this procedure). The number of errors having to do with
38
--  bounds of function return results were also fixed, and use of & removed for
39
--  efficiency reasons.
40
 
41
with Ada.Strings.Maps; use Ada.Strings.Maps;
42
with Ada.Strings.Search;
43
 
44
package body Ada.Strings.Fixed is
45
 
46
   ------------------------
47
   -- Search Subprograms --
48
   ------------------------
49
 
50
   function Index
51
     (Source  : String;
52
      Pattern : String;
53
      Going   : Direction := Forward;
54
      Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
55
   renames Ada.Strings.Search.Index;
56
 
57
   function Index
58
     (Source  : String;
59
      Pattern : String;
60
      Going   : Direction := Forward;
61
      Mapping : Maps.Character_Mapping_Function) return Natural
62
   renames Ada.Strings.Search.Index;
63
 
64
   function Index
65
     (Source : String;
66
      Set    : Maps.Character_Set;
67
      Test   : Membership := Inside;
68
      Going  : Direction  := Forward) return Natural
69
   renames Ada.Strings.Search.Index;
70
 
71
   function Index
72
     (Source  : String;
73
      Pattern : String;
74
      From    : Positive;
75
      Going   : Direction := Forward;
76
      Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
77
   renames Ada.Strings.Search.Index;
78
 
79
   function Index
80
     (Source  : String;
81
      Pattern : String;
82
      From    : Positive;
83
      Going   : Direction := Forward;
84
      Mapping : Maps.Character_Mapping_Function) return Natural
85
   renames Ada.Strings.Search.Index;
86
 
87
   function Index
88
     (Source  : String;
89
      Set     : Maps.Character_Set;
90
      From    : Positive;
91
      Test    : Membership := Inside;
92
      Going   : Direction := Forward) return Natural
93
   renames Ada.Strings.Search.Index;
94
 
95
   function Index_Non_Blank
96
     (Source : String;
97
      Going  : Direction := Forward) return Natural
98
   renames Ada.Strings.Search.Index_Non_Blank;
99
 
100
   function Index_Non_Blank
101
     (Source : String;
102
      From   : Positive;
103
      Going  : Direction := Forward) return Natural
104
   renames Ada.Strings.Search.Index_Non_Blank;
105
 
106
   function Count
107
     (Source  : String;
108
      Pattern : String;
109
      Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
110
   renames Ada.Strings.Search.Count;
111
 
112
   function Count
113
     (Source  : String;
114
      Pattern : String;
115
      Mapping : Maps.Character_Mapping_Function) return Natural
116
   renames Ada.Strings.Search.Count;
117
 
118
   function Count
119
     (Source : String;
120
      Set    : Maps.Character_Set) return Natural
121
   renames Ada.Strings.Search.Count;
122
 
123
   procedure Find_Token
124
     (Source : String;
125
      Set    : Maps.Character_Set;
126
      From   : Positive;
127
      Test   : Membership;
128
      First  : out Positive;
129
      Last   : out Natural)
130
   renames Ada.Strings.Search.Find_Token;
131
 
132
   procedure Find_Token
133
     (Source : String;
134
      Set    : Maps.Character_Set;
135
      Test   : Membership;
136
      First  : out Positive;
137
      Last   : out Natural)
138
   renames Ada.Strings.Search.Find_Token;
139
 
140
   ---------
141
   -- "*" --
142
   ---------
143
 
144
   function "*"
145
     (Left  : Natural;
146
      Right : Character) return String
147
   is
148
      Result : String (1 .. Left);
149
 
150
   begin
151
      for J in Result'Range loop
152
         Result (J) := Right;
153
      end loop;
154
 
155
      return Result;
156
   end "*";
157
 
158
   function "*"
159
     (Left  : Natural;
160
      Right : String) return String
161
   is
162
      Result : String (1 .. Left * Right'Length);
163
      Ptr    : Integer := 1;
164
 
165
   begin
166
      for J in 1 .. Left loop
167
         Result (Ptr .. Ptr + Right'Length - 1) := Right;
168
         Ptr := Ptr + Right'Length;
169
      end loop;
170
 
171
      return Result;
172
   end "*";
173
 
174
   ------------
175
   -- Delete --
176
   ------------
177
 
178
   function Delete
179
     (Source  : String;
180
      From    : Positive;
181
      Through : Natural) return String
182
   is
183
   begin
184
      if From > Through then
185
         declare
186
            subtype Result_Type is String (1 .. Source'Length);
187
 
188
         begin
189
            return Result_Type (Source);
190
         end;
191
 
192
      elsif From not in Source'Range
193
        or else Through > Source'Last
194
      then
195
         raise Index_Error;
196
 
197
      else
198
         declare
199
            Front  : constant Integer := From - Source'First;
200
            Result : String (1 .. Source'Length - (Through - From + 1));
201
 
202
         begin
203
            Result (1 .. Front) :=
204
              Source (Source'First .. From - 1);
205
            Result (Front + 1 .. Result'Last) :=
206
              Source (Through + 1 .. Source'Last);
207
 
208
            return Result;
209
         end;
210
      end if;
211
   end Delete;
212
 
213
   procedure Delete
214
     (Source  : in out String;
215
      From    : Positive;
216
      Through : Natural;
217
      Justify : Alignment := Left;
218
      Pad     : Character := Space)
219
   is
220
   begin
221
      Move (Source  => Delete (Source, From, Through),
222
            Target  => Source,
223
            Justify => Justify,
224
            Pad     => Pad);
225
   end Delete;
226
 
227
   ----------
228
   -- Head --
229
   ----------
230
 
231
   function Head
232
     (Source : String;
233
      Count  : Natural;
234
      Pad    : Character := Space) return String
235
   is
236
      subtype Result_Type is String (1 .. Count);
237
 
238
   begin
239
      if Count < Source'Length then
240
         return
241
           Result_Type (Source (Source'First .. Source'First + Count - 1));
242
 
243
      else
244
         declare
245
            Result : Result_Type;
246
 
247
         begin
248
            Result (1 .. Source'Length) := Source;
249
 
250
            for J in Source'Length + 1 .. Count loop
251
               Result (J) := Pad;
252
            end loop;
253
 
254
            return Result;
255
         end;
256
      end if;
257
   end Head;
258
 
259
   procedure Head
260
     (Source  : in out String;
261
      Count   : Natural;
262
      Justify : Alignment := Left;
263
      Pad     : Character := Space)
264
   is
265
   begin
266
      Move (Source  => Head (Source, Count, Pad),
267
            Target  => Source,
268
            Drop    => Error,
269
            Justify => Justify,
270
            Pad     => Pad);
271
   end Head;
272
 
273
   ------------
274
   -- Insert --
275
   ------------
276
 
277
   function Insert
278
     (Source   : String;
279
      Before   : Positive;
280
      New_Item : String) return String
281
   is
282
      Result : String (1 .. Source'Length + New_Item'Length);
283
      Front  : constant Integer := Before - Source'First;
284
 
285
   begin
286
      if Before not in Source'First .. Source'Last + 1 then
287
         raise Index_Error;
288
      end if;
289
 
290
      Result (1 .. Front) :=
291
        Source (Source'First .. Before - 1);
292
      Result (Front + 1 .. Front + New_Item'Length) :=
293
        New_Item;
294
      Result (Front + New_Item'Length + 1 .. Result'Last) :=
295
        Source (Before .. Source'Last);
296
 
297
      return Result;
298
   end Insert;
299
 
300
   procedure Insert
301
     (Source   : in out String;
302
      Before   : Positive;
303
      New_Item : String;
304
      Drop     : Truncation := Error)
305
   is
306
   begin
307
      Move (Source => Insert (Source, Before, New_Item),
308
            Target => Source,
309
            Drop   => Drop);
310
   end Insert;
311
 
312
   ----------
313
   -- Move --
314
   ----------
315
 
316
   procedure Move
317
     (Source  : String;
318
      Target  : out String;
319
      Drop    : Truncation := Error;
320
      Justify : Alignment  := Left;
321
      Pad     : Character  := Space)
322
   is
323
      Sfirst  : constant Integer := Source'First;
324
      Slast   : constant Integer := Source'Last;
325
      Slength : constant Integer := Source'Length;
326
 
327
      Tfirst  : constant Integer := Target'First;
328
      Tlast   : constant Integer := Target'Last;
329
      Tlength : constant Integer := Target'Length;
330
 
331
      function Is_Padding (Item : String) return Boolean;
332
      --  Check if Item is all Pad characters, return True if so, False if not
333
 
334
      function Is_Padding (Item : String) return Boolean is
335
      begin
336
         for J in Item'Range loop
337
            if Item (J) /= Pad then
338
               return False;
339
            end if;
340
         end loop;
341
 
342
         return True;
343
      end Is_Padding;
344
 
345
   --  Start of processing for Move
346
 
347
   begin
348
      if Slength = Tlength then
349
         Target := Source;
350
 
351
      elsif Slength > Tlength then
352
 
353
         case Drop is
354
            when Left =>
355
               Target := Source (Slast - Tlength + 1 .. Slast);
356
 
357
            when Right =>
358
               Target := Source (Sfirst .. Sfirst + Tlength - 1);
359
 
360
            when Error =>
361
               case Justify is
362
                  when Left =>
363
                     if Is_Padding (Source (Sfirst + Tlength .. Slast)) then
364
                        Target :=
365
                          Source (Sfirst .. Sfirst + Target'Length - 1);
366
                     else
367
                        raise Length_Error;
368
                     end if;
369
 
370
                  when Right =>
371
                     if Is_Padding (Source (Sfirst .. Slast - Tlength)) then
372
                        Target := Source (Slast - Tlength + 1 .. Slast);
373
                     else
374
                        raise Length_Error;
375
                     end if;
376
 
377
                  when Center =>
378
                     raise Length_Error;
379
               end case;
380
 
381
         end case;
382
 
383
      --  Source'Length < Target'Length
384
 
385
      else
386
         case Justify is
387
            when Left =>
388
               Target (Tfirst .. Tfirst + Slength - 1) := Source;
389
 
390
               for I in Tfirst + Slength .. Tlast loop
391
                  Target (I) := Pad;
392
               end loop;
393
 
394
            when Right =>
395
               for I in Tfirst .. Tlast - Slength loop
396
                  Target (I) := Pad;
397
               end loop;
398
 
399
               Target (Tlast - Slength + 1 .. Tlast) := Source;
400
 
401
            when Center =>
402
               declare
403
                  Front_Pad   : constant Integer := (Tlength - Slength) / 2;
404
                  Tfirst_Fpad : constant Integer := Tfirst + Front_Pad;
405
 
406
               begin
407
                  for I in Tfirst .. Tfirst_Fpad - 1 loop
408
                     Target (I) := Pad;
409
                  end loop;
410
 
411
                  Target (Tfirst_Fpad .. Tfirst_Fpad + Slength - 1) := Source;
412
 
413
                  for I in Tfirst_Fpad + Slength .. Tlast loop
414
                     Target (I) := Pad;
415
                  end loop;
416
               end;
417
         end case;
418
      end if;
419
   end Move;
420
 
421
   ---------------
422
   -- Overwrite --
423
   ---------------
424
 
425
   function Overwrite
426
     (Source   : String;
427
      Position : Positive;
428
      New_Item : String) return String
429
   is
430
   begin
431
      if Position not in Source'First .. Source'Last + 1 then
432
         raise Index_Error;
433
      end if;
434
 
435
      declare
436
         Result_Length : constant Natural :=
437
                           Integer'Max
438
                             (Source'Length,
439
                              Position - Source'First + New_Item'Length);
440
 
441
         Result : String (1 .. Result_Length);
442
         Front  : constant Integer := Position - Source'First;
443
 
444
      begin
445
         Result (1 .. Front) :=
446
           Source (Source'First .. Position - 1);
447
         Result (Front + 1 .. Front + New_Item'Length) :=
448
           New_Item;
449
         Result (Front + New_Item'Length + 1 .. Result'Length) :=
450
           Source (Position + New_Item'Length .. Source'Last);
451
         return Result;
452
      end;
453
   end Overwrite;
454
 
455
   procedure Overwrite
456
     (Source   : in out String;
457
      Position : Positive;
458
      New_Item : String;
459
      Drop     : Truncation := Right)
460
   is
461
   begin
462
      Move (Source => Overwrite (Source, Position, New_Item),
463
            Target => Source,
464
            Drop   => Drop);
465
   end Overwrite;
466
 
467
   -------------------
468
   -- Replace_Slice --
469
   -------------------
470
 
471
   function Replace_Slice
472
     (Source : String;
473
      Low    : Positive;
474
      High   : Natural;
475
      By     : String) return String
476
   is
477
   begin
478
      if Low > Source'Last + 1 or else High < Source'First - 1 then
479
         raise Index_Error;
480
      end if;
481
 
482
      if High >= Low then
483
         declare
484
            Front_Len : constant Integer :=
485
                          Integer'Max (0, Low - Source'First);
486
            --  Length of prefix of Source copied to result
487
 
488
            Back_Len : constant Integer :=
489
                         Integer'Max (0, Source'Last - High);
490
            --  Length of suffix of Source copied to result
491
 
492
            Result_Length : constant Integer :=
493
                              Front_Len + By'Length + Back_Len;
494
            --  Length of result
495
 
496
            Result : String (1 .. Result_Length);
497
 
498
         begin
499
            Result (1 .. Front_Len) := Source (Source'First .. Low - 1);
500
            Result (Front_Len + 1 .. Front_Len + By'Length) := By;
501
            Result (Front_Len + By'Length + 1 .. Result'Length) :=
502
              Source (High + 1 .. Source'Last);
503
            return Result;
504
         end;
505
 
506
      else
507
         return Insert (Source, Before => Low, New_Item => By);
508
      end if;
509
   end Replace_Slice;
510
 
511
   procedure Replace_Slice
512
     (Source   : in out String;
513
      Low      : Positive;
514
      High     : Natural;
515
      By       : String;
516
      Drop     : Truncation := Error;
517
      Justify  : Alignment  := Left;
518
      Pad      : Character  := Space)
519
   is
520
   begin
521
      Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
522
   end Replace_Slice;
523
 
524
   ----------
525
   -- Tail --
526
   ----------
527
 
528
   function Tail
529
     (Source : String;
530
      Count  : Natural;
531
      Pad    : Character := Space) return String
532
   is
533
      subtype Result_Type is String (1 .. Count);
534
 
535
   begin
536
      if Count < Source'Length then
537
         return Result_Type (Source (Source'Last - Count + 1 .. Source'Last));
538
 
539
      --  Pad on left
540
 
541
      else
542
         declare
543
            Result : Result_Type;
544
 
545
         begin
546
            for J in 1 .. Count - Source'Length loop
547
               Result (J) := Pad;
548
            end loop;
549
 
550
            Result (Count - Source'Length + 1 .. Count) := Source;
551
            return Result;
552
         end;
553
      end if;
554
   end Tail;
555
 
556
   procedure Tail
557
     (Source  : in out String;
558
      Count   : Natural;
559
      Justify : Alignment := Left;
560
      Pad     : Character := Space)
561
   is
562
   begin
563
      Move (Source  => Tail (Source, Count, Pad),
564
            Target  => Source,
565
            Drop    => Error,
566
            Justify => Justify,
567
            Pad     => Pad);
568
   end Tail;
569
 
570
   ---------------
571
   -- Translate --
572
   ---------------
573
 
574
   function Translate
575
     (Source  : String;
576
      Mapping : Maps.Character_Mapping) return String
577
   is
578
      Result : String (1 .. Source'Length);
579
 
580
   begin
581
      for J in Source'Range loop
582
         Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
583
      end loop;
584
 
585
      return Result;
586
   end Translate;
587
 
588
   procedure Translate
589
     (Source  : in out String;
590
      Mapping : Maps.Character_Mapping)
591
   is
592
   begin
593
      for J in Source'Range loop
594
         Source (J) := Value (Mapping, Source (J));
595
      end loop;
596
   end Translate;
597
 
598
   function Translate
599
     (Source  : String;
600
      Mapping : Maps.Character_Mapping_Function) return String
601
   is
602
      Result : String (1 .. Source'Length);
603
      pragma Unsuppress (Access_Check);
604
 
605
   begin
606
      for J in Source'Range loop
607
         Result (J - (Source'First - 1)) := Mapping.all (Source (J));
608
      end loop;
609
 
610
      return Result;
611
   end Translate;
612
 
613
   procedure Translate
614
     (Source  : in out String;
615
      Mapping : Maps.Character_Mapping_Function)
616
   is
617
      pragma Unsuppress (Access_Check);
618
   begin
619
      for J in Source'Range loop
620
         Source (J) := Mapping.all (Source (J));
621
      end loop;
622
   end Translate;
623
 
624
   ----------
625
   -- Trim --
626
   ----------
627
 
628
   function Trim
629
     (Source : String;
630
      Side   : Trim_End) return String
631
   is
632
      Low, High : Integer;
633
 
634
   begin
635
      Low := Index_Non_Blank (Source, Forward);
636
 
637
      --  All blanks case
638
 
639
      if Low = 0 then
640
         return "";
641
 
642
      --  At least one non-blank
643
 
644
      else
645
         High := Index_Non_Blank (Source, Backward);
646
 
647
         case Side is
648
            when Strings.Left =>
649
               declare
650
                  subtype Result_Type is String (1 .. Source'Last - Low + 1);
651
 
652
               begin
653
                  return Result_Type (Source (Low .. Source'Last));
654
               end;
655
 
656
            when Strings.Right =>
657
               declare
658
                  subtype Result_Type is String (1 .. High - Source'First + 1);
659
 
660
               begin
661
                  return Result_Type (Source (Source'First .. High));
662
               end;
663
 
664
            when Strings.Both =>
665
               declare
666
                  subtype Result_Type is String (1 .. High - Low + 1);
667
 
668
               begin
669
                  return Result_Type (Source (Low .. High));
670
               end;
671
         end case;
672
      end if;
673
   end Trim;
674
 
675
   procedure Trim
676
     (Source  : in out String;
677
      Side    : Trim_End;
678
      Justify : Alignment := Left;
679
      Pad     : Character := Space)
680
   is
681
   begin
682
      Move (Trim (Source, Side),
683
            Source,
684
            Justify => Justify,
685
            Pad => Pad);
686
   end Trim;
687
 
688
   function Trim
689
     (Source : String;
690
      Left   : Maps.Character_Set;
691
      Right  : Maps.Character_Set) return String
692
   is
693
      High, Low : Integer;
694
 
695
   begin
696
      Low := Index (Source, Set => Left, Test  => Outside, Going => Forward);
697
 
698
      --  Case where source comprises only characters in Left
699
 
700
      if Low = 0 then
701
         return "";
702
      end if;
703
 
704
      High :=
705
        Index (Source, Set => Right, Test  => Outside, Going => Backward);
706
 
707
      --  Case where source comprises only characters in Right
708
 
709
      if High = 0 then
710
         return "";
711
      end if;
712
 
713
      declare
714
         subtype Result_Type is String (1 .. High - Low + 1);
715
 
716
      begin
717
         return Result_Type (Source (Low .. High));
718
      end;
719
   end Trim;
720
 
721
   procedure Trim
722
     (Source  : in out String;
723
      Left    : Maps.Character_Set;
724
      Right   : Maps.Character_Set;
725
      Justify : Alignment := Strings.Left;
726
      Pad     : Character := Space)
727
   is
728
   begin
729
      Move (Source  => Trim (Source, Left, Right),
730
            Target  => Source,
731
            Justify => Justify,
732
            Pad     => Pad);
733
   end Trim;
734
 
735
end Ada.Strings.Fixed;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.