1 ------------------------------------------------------------------------------
3 -- GNAT RUNTIME COMPONENTS --
5 -- A D A . S T R I N G S . W I D E _ F I X E D --
9 -- Copyright (C) 1992-2005 Free Software Foundation, Inc. --
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. --
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. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 with Ada
.Strings
.Wide_Wide_Maps
; use Ada
.Strings
.Wide_Wide_Maps
;
35 with Ada
.Strings
.Wide_Wide_Search
;
37 package body Ada
.Strings
.Wide_Wide_Fixed
is
39 ------------------------
40 -- Search Subprograms --
41 ------------------------
44 (Source
: Wide_Wide_String
;
45 Pattern
: Wide_Wide_String
;
46 Going
: Direction
:= Forward
;
47 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
48 Wide_Wide_Maps
.Identity
)
50 renames Ada
.Strings
.Wide_Wide_Search
.Index
;
53 (Source
: Wide_Wide_String
;
54 Pattern
: Wide_Wide_String
;
55 Going
: Direction
:= Forward
;
56 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
58 renames Ada
.Strings
.Wide_Wide_Search
.Index
;
61 (Source
: Wide_Wide_String
;
62 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
63 Test
: Membership
:= Inside
;
64 Going
: Direction
:= Forward
) return Natural
65 renames Ada
.Strings
.Wide_Wide_Search
.Index
;
68 (Source
: Wide_Wide_String
;
69 Pattern
: Wide_Wide_String
;
71 Going
: Direction
:= Forward
;
72 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
73 Wide_Wide_Maps
.Identity
)
75 renames Ada
.Strings
.Wide_Wide_Search
.Index
;
78 (Source
: Wide_Wide_String
;
79 Pattern
: Wide_Wide_String
;
81 Going
: Direction
:= Forward
;
82 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
84 renames Ada
.Strings
.Wide_Wide_Search
.Index
;
87 (Source
: Wide_Wide_String
;
88 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
90 Test
: Membership
:= Inside
;
91 Going
: Direction
:= Forward
) return Natural
92 renames Ada
.Strings
.Wide_Wide_Search
.Index
;
94 function Index_Non_Blank
95 (Source
: Wide_Wide_String
;
96 Going
: Direction
:= Forward
) return Natural
97 renames Ada
.Strings
.Wide_Wide_Search
.Index_Non_Blank
;
99 function Index_Non_Blank
100 (Source
: Wide_Wide_String
;
102 Going
: Direction
:= Forward
) return Natural
103 renames Ada
.Strings
.Wide_Wide_Search
.Index_Non_Blank
;
106 (Source
: Wide_Wide_String
;
107 Pattern
: Wide_Wide_String
;
108 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
109 Wide_Wide_Maps
.Identity
)
111 renames Ada
.Strings
.Wide_Wide_Search
.Count
;
114 (Source
: Wide_Wide_String
;
115 Pattern
: Wide_Wide_String
;
116 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
118 renames Ada
.Strings
.Wide_Wide_Search
.Count
;
121 (Source
: Wide_Wide_String
;
122 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
) return Natural
123 renames Ada
.Strings
.Wide_Wide_Search
.Count
;
126 (Source
: Wide_Wide_String
;
127 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
129 First
: out Positive;
131 renames Ada
.Strings
.Wide_Wide_Search
.Find_Token
;
139 Right
: Wide_Wide_Character
) return Wide_Wide_String
141 Result
: Wide_Wide_String
(1 .. Left
);
144 for J
in Result
'Range loop
153 Right
: Wide_Wide_String
) return Wide_Wide_String
155 Result
: Wide_Wide_String
(1 .. Left
* Right
'Length);
159 for J
in 1 .. Left
loop
160 Result
(Ptr
.. Ptr
+ Right
'Length - 1) := Right
;
161 Ptr
:= Ptr
+ Right
'Length;
172 (Source
: Wide_Wide_String
;
174 Through
: Natural) return Wide_Wide_String
177 if From
not in Source
'Range
178 or else Through
> Source
'Last
182 elsif From
> Through
then
187 Len
: constant Integer := Source
'Length - (Through
- From
+ 1);
188 Result
: constant Wide_Wide_String
189 (Source
'First .. Source
'First + Len
- 1) :=
190 Source
(Source
'First .. From
- 1) &
191 Source
(Through
+ 1 .. Source
'Last);
199 (Source
: in out Wide_Wide_String
;
202 Justify
: Alignment
:= Left
;
203 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
206 Move
(Source
=> Delete
(Source
, From
, Through
),
217 (Source
: Wide_Wide_String
;
219 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
) return Wide_Wide_String
221 Result
: Wide_Wide_String
(1 .. Count
);
224 if Count
<= Source
'Length then
225 Result
:= Source
(Source
'First .. Source
'First + Count
- 1);
228 Result
(1 .. Source
'Length) := Source
;
230 for J
in Source
'Length + 1 .. Count
loop
239 (Source
: in out Wide_Wide_String
;
241 Justify
: Alignment
:= Left
;
242 Pad
: Wide_Wide_Character
:= Ada
.Strings
.Wide_Wide_Space
)
245 Move
(Source
=> Head
(Source
, Count
, Pad
),
257 (Source
: Wide_Wide_String
;
259 New_Item
: Wide_Wide_String
) return Wide_Wide_String
261 Result
: Wide_Wide_String
(1 .. Source
'Length + New_Item
'Length);
264 if Before
< Source
'First or else Before
> Source
'Last + 1 then
268 Result
:= Source
(Source
'First .. Before
- 1) & New_Item
&
269 Source
(Before
.. Source
'Last);
274 (Source
: in out Wide_Wide_String
;
276 New_Item
: Wide_Wide_String
;
277 Drop
: Truncation
:= Error
)
280 Move
(Source
=> Insert
(Source
, Before
, New_Item
),
290 (Source
: Wide_Wide_String
;
291 Target
: out Wide_Wide_String
;
292 Drop
: Truncation
:= Error
;
293 Justify
: Alignment
:= Left
;
294 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
296 Sfirst
: constant Integer := Source
'First;
297 Slast
: constant Integer := Source
'Last;
298 Slength
: constant Integer := Source
'Length;
300 Tfirst
: constant Integer := Target
'First;
301 Tlast
: constant Integer := Target
'Last;
302 Tlength
: constant Integer := Target
'Length;
304 function Is_Padding
(Item
: Wide_Wide_String
) return Boolean;
305 -- Determinbe if all characters in Item are pad characters
307 function Is_Padding
(Item
: Wide_Wide_String
) return Boolean is
309 for J
in Item
'Range loop
310 if Item
(J
) /= Pad
then
318 -- Start of processing for Move
321 if Slength
= Tlength
then
324 elsif Slength
> Tlength
then
328 Target
:= Source
(Slast
- Tlength
+ 1 .. Slast
);
331 Target
:= Source
(Sfirst
.. Sfirst
+ Tlength
- 1);
336 if Is_Padding
(Source
(Sfirst
+ Tlength
.. Slast
)) then
338 Source
(Sfirst
.. Sfirst
+ Target
'Length - 1);
344 if Is_Padding
(Source
(Sfirst
.. Slast
- Tlength
)) then
345 Target
:= Source
(Slast
- Tlength
+ 1 .. Slast
);
356 -- Source'Length < Target'Length
361 Target
(Tfirst
.. Tfirst
+ Slength
- 1) := Source
;
363 for J
in Tfirst
+ Slength
.. Tlast
loop
368 for J
in Tfirst
.. Tlast
- Slength
loop
372 Target
(Tlast
- Slength
+ 1 .. Tlast
) := Source
;
376 Front_Pad
: constant Integer := (Tlength
- Slength
) / 2;
377 Tfirst_Fpad
: constant Integer := Tfirst
+ Front_Pad
;
380 for J
in Tfirst
.. Tfirst_Fpad
- 1 loop
384 Target
(Tfirst_Fpad
.. Tfirst_Fpad
+ Slength
- 1) := Source
;
386 for J
in Tfirst_Fpad
+ Slength
.. Tlast
loop
399 (Source
: Wide_Wide_String
;
401 New_Item
: Wide_Wide_String
) return Wide_Wide_String
404 if Position
not in Source
'First .. Source
'Last + 1 then
408 Result_Length
: constant Natural :=
411 Position
- Source
'First + New_Item
'Length);
413 Result
: Wide_Wide_String
(1 .. Result_Length
);
416 Result
:= Source
(Source
'First .. Position
- 1) & New_Item
&
417 Source
(Position
+ New_Item
'Length .. Source
'Last);
424 (Source
: in out Wide_Wide_String
;
426 New_Item
: Wide_Wide_String
;
427 Drop
: Truncation
:= Right
)
430 Move
(Source
=> Overwrite
(Source
, Position
, New_Item
),
439 function Replace_Slice
440 (Source
: Wide_Wide_String
;
443 By
: Wide_Wide_String
) return Wide_Wide_String
445 Result_Length
: Natural;
448 if Low
> Source
'Last + 1 or else High
< Source
'First - 1 then
452 Source
'Length - Natural'Max (High
- Low
+ 1, 0) + By
'Length;
455 Result
: Wide_Wide_String
(1 .. Result_Length
);
460 Source
(Source
'First .. Low
- 1) & By
&
461 Source
(High
+ 1 .. Source
'Last);
463 Result
:= Source
(Source
'First .. Low
- 1) & By
&
464 Source
(Low
.. Source
'Last);
472 procedure Replace_Slice
473 (Source
: in out Wide_Wide_String
;
476 By
: Wide_Wide_String
;
477 Drop
: Truncation
:= Error
;
478 Justify
: Alignment
:= Left
;
479 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
482 Move
(Replace_Slice
(Source
, Low
, High
, By
), Source
, Drop
, Justify
, Pad
);
490 (Source
: Wide_Wide_String
;
492 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
) return Wide_Wide_String
494 Result
: Wide_Wide_String
(1 .. Count
);
497 if Count
< Source
'Length then
498 Result
:= Source
(Source
'Last - Count
+ 1 .. Source
'Last);
503 for J
in 1 .. Count
- Source
'Length loop
507 Result
(Count
- Source
'Length + 1 .. Count
) := Source
;
514 (Source
: in out Wide_Wide_String
;
516 Justify
: Alignment
:= Left
;
517 Pad
: Wide_Wide_Character
:= Ada
.Strings
.Wide_Wide_Space
)
520 Move
(Source
=> Tail
(Source
, Count
, Pad
),
532 (Source
: Wide_Wide_String
;
533 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
)
534 return Wide_Wide_String
536 Result
: Wide_Wide_String
(1 .. Source
'Length);
539 for J
in Source
'Range loop
540 Result
(J
- (Source
'First - 1)) := Value
(Mapping
, Source
(J
));
547 (Source
: in out Wide_Wide_String
;
548 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
)
551 for J
in Source
'Range loop
552 Source
(J
) := Value
(Mapping
, Source
(J
));
557 (Source
: Wide_Wide_String
;
558 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
559 return Wide_Wide_String
561 Result
: Wide_Wide_String
(1 .. Source
'Length);
564 for J
in Source
'Range loop
565 Result
(J
- (Source
'First - 1)) := Mapping
(Source
(J
));
572 (Source
: in out Wide_Wide_String
;
573 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
576 for J
in Source
'Range loop
577 Source
(J
) := Mapping
(Source
(J
));
586 (Source
: Wide_Wide_String
;
587 Side
: Trim_End
) return Wide_Wide_String
589 Low
: Natural := Source
'First;
590 High
: Natural := Source
'Last;
593 if Side
= Left
or else Side
= Both
then
594 while Low
<= High
and then Source
(Low
) = Wide_Wide_Space
loop
599 if Side
= Right
or else Side
= Both
then
600 while High
>= Low
and then Source
(High
) = Wide_Wide_Space
loop
610 -- At least one non-blank
614 Result
: constant Wide_Wide_String
(1 .. High
- Low
+ 1) :=
615 Source
(Low
.. High
);
624 (Source
: in out Wide_Wide_String
;
626 Justify
: Alignment
:= Left
;
627 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
630 Move
(Source
=> Trim
(Source
, Side
),
637 (Source
: Wide_Wide_String
;
638 Left
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
639 Right
: Wide_Wide_Maps
.Wide_Wide_Character_Set
) return Wide_Wide_String
641 Low
: Natural := Source
'First;
642 High
: Natural := Source
'Last;
645 while Low
<= High
and then Is_In
(Source
(Low
), Left
) loop
649 while High
>= Low
and then Is_In
(Source
(High
), Right
) loop
653 -- Case where source comprises only characters in the sets
659 subtype WS
is Wide_Wide_String
(1 .. High
- Low
+ 1);
662 return WS
(Source
(Low
.. High
));
668 (Source
: in out Wide_Wide_String
;
669 Left
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
670 Right
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
671 Justify
: Alignment
:= Strings
.Left
;
672 Pad
: Wide_Wide_Character
:= Wide_Wide_Space
)
675 Move
(Source
=> Trim
(Source
, Left
, Right
),
681 end Ada
.Strings
.Wide_Wide_Fixed
;