1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME 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-2009, 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 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. --
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. --
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/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 with Ada
.Strings
.Wide_Maps
; use Ada
.Strings
.Wide_Maps
;
33 with Ada
.Strings
.Wide_Search
;
35 package body Ada
.Strings
.Wide_Fixed
is
37 ------------------------
38 -- Search Subprograms --
39 ------------------------
42 (Source
: Wide_String;
43 Pattern
: Wide_String;
44 Going
: Direction
:= Forward
;
45 Mapping
: Wide_Maps
.Wide_Character_Mapping
:= Wide_Maps
.Identity
)
47 renames Ada
.Strings
.Wide_Search
.Index
;
50 (Source
: Wide_String;
51 Pattern
: Wide_String;
52 Going
: Direction
:= Forward
;
53 Mapping
: Wide_Maps
.Wide_Character_Mapping_Function
) return Natural
54 renames Ada
.Strings
.Wide_Search
.Index
;
57 (Source
: Wide_String;
58 Set
: Wide_Maps
.Wide_Character_Set
;
59 Test
: Membership
:= Inside
;
60 Going
: Direction
:= Forward
) return Natural
61 renames Ada
.Strings
.Wide_Search
.Index
;
64 (Source
: Wide_String;
65 Pattern
: Wide_String;
67 Going
: Direction
:= Forward
;
68 Mapping
: Wide_Maps
.Wide_Character_Mapping
:= Wide_Maps
.Identity
)
70 renames Ada
.Strings
.Wide_Search
.Index
;
73 (Source
: Wide_String;
74 Pattern
: Wide_String;
76 Going
: Direction
:= Forward
;
77 Mapping
: Wide_Maps
.Wide_Character_Mapping_Function
) return Natural
78 renames Ada
.Strings
.Wide_Search
.Index
;
81 (Source
: Wide_String;
82 Set
: Wide_Maps
.Wide_Character_Set
;
84 Test
: Membership
:= Inside
;
85 Going
: Direction
:= Forward
) return Natural
86 renames Ada
.Strings
.Wide_Search
.Index
;
88 function Index_Non_Blank
89 (Source
: Wide_String;
90 Going
: Direction
:= Forward
) return Natural
91 renames Ada
.Strings
.Wide_Search
.Index_Non_Blank
;
93 function Index_Non_Blank
94 (Source
: Wide_String;
96 Going
: Direction
:= Forward
) return Natural
97 renames Ada
.Strings
.Wide_Search
.Index_Non_Blank
;
100 (Source
: Wide_String;
101 Pattern
: Wide_String;
102 Mapping
: Wide_Maps
.Wide_Character_Mapping
:= Wide_Maps
.Identity
)
104 renames Ada
.Strings
.Wide_Search
.Count
;
107 (Source
: Wide_String;
108 Pattern
: Wide_String;
109 Mapping
: Wide_Maps
.Wide_Character_Mapping_Function
) return Natural
110 renames Ada
.Strings
.Wide_Search
.Count
;
113 (Source
: Wide_String;
114 Set
: Wide_Maps
.Wide_Character_Set
) return Natural
115 renames Ada
.Strings
.Wide_Search
.Count
;
118 (Source
: Wide_String;
119 Set
: Wide_Maps
.Wide_Character_Set
;
121 First
: out Positive;
123 renames Ada
.Strings
.Wide_Search
.Find_Token
;
131 Right
: Wide_Character) return Wide_String
133 Result
: Wide_String (1 .. Left
);
136 for J
in Result
'Range loop
145 Right
: Wide_String) return Wide_String
147 Result
: Wide_String (1 .. Left
* Right
'Length);
151 for J
in 1 .. Left
loop
152 Result
(Ptr
.. Ptr
+ Right
'Length - 1) := Right
;
153 Ptr
:= Ptr
+ Right
'Length;
164 (Source
: Wide_String;
166 Through
: Natural) return Wide_String
169 if From
not in Source
'Range
170 or else Through
> Source
'Last
174 elsif From
> Through
then
179 Len
: constant Integer := Source
'Length - (Through
- From
+ 1);
181 Wide_String (Source
'First .. Source
'First + Len
- 1) :=
182 Source
(Source
'First .. From
- 1) &
183 Source
(Through
+ 1 .. Source
'Last);
191 (Source
: in out Wide_String;
194 Justify
: Alignment
:= Left
;
195 Pad
: Wide_Character := Wide_Space
)
198 Move
(Source
=> Delete
(Source
, From
, Through
),
209 (Source
: Wide_String;
211 Pad
: Wide_Character := Wide_Space
) return Wide_String
213 Result
: Wide_String (1 .. Count
);
216 if Count
<= Source
'Length then
217 Result
:= Source
(Source
'First .. Source
'First + Count
- 1);
220 Result
(1 .. Source
'Length) := Source
;
222 for J
in Source
'Length + 1 .. Count
loop
231 (Source
: in out Wide_String;
233 Justify
: Alignment
:= Left
;
234 Pad
: Wide_Character := Ada
.Strings
.Wide_Space
)
237 Move
(Source
=> Head
(Source
, Count
, Pad
),
249 (Source
: Wide_String;
251 New_Item
: Wide_String) return Wide_String
253 Result
: Wide_String (1 .. Source
'Length + New_Item
'Length);
256 if Before
< Source
'First or else Before
> Source
'Last + 1 then
260 Result
:= Source
(Source
'First .. Before
- 1) & New_Item
&
261 Source
(Before
.. Source
'Last);
266 (Source
: in out Wide_String;
268 New_Item
: Wide_String;
269 Drop
: Truncation
:= Error
)
272 Move
(Source
=> Insert
(Source
, Before
, New_Item
),
282 (Source
: Wide_String;
283 Target
: out Wide_String;
284 Drop
: Truncation
:= Error
;
285 Justify
: Alignment
:= Left
;
286 Pad
: Wide_Character := Wide_Space
)
288 Sfirst
: constant Integer := Source
'First;
289 Slast
: constant Integer := Source
'Last;
290 Slength
: constant Integer := Source
'Length;
292 Tfirst
: constant Integer := Target
'First;
293 Tlast
: constant Integer := Target
'Last;
294 Tlength
: constant Integer := Target
'Length;
296 function Is_Padding
(Item
: Wide_String) return Boolean;
297 -- Determine if all characters in Item are pad characters
303 function Is_Padding
(Item
: Wide_String) return Boolean is
305 for J
in Item
'Range loop
306 if Item
(J
) /= Pad
then
314 -- Start of processing for Move
317 if Slength
= Tlength
then
320 elsif Slength
> Tlength
then
324 Target
:= Source
(Slast
- Tlength
+ 1 .. Slast
);
327 Target
:= Source
(Sfirst
.. Sfirst
+ Tlength
- 1);
332 if Is_Padding
(Source
(Sfirst
+ Tlength
.. Slast
)) then
334 Source
(Sfirst
.. Sfirst
+ Target
'Length - 1);
340 if Is_Padding
(Source
(Sfirst
.. Slast
- Tlength
)) then
341 Target
:= Source
(Slast
- Tlength
+ 1 .. Slast
);
352 -- Source'Length < Target'Length
357 Target
(Tfirst
.. Tfirst
+ Slength
- 1) := Source
;
359 for J
in Tfirst
+ Slength
.. Tlast
loop
364 for J
in Tfirst
.. Tlast
- Slength
loop
368 Target
(Tlast
- Slength
+ 1 .. Tlast
) := Source
;
372 Front_Pad
: constant Integer := (Tlength
- Slength
) / 2;
373 Tfirst_Fpad
: constant Integer := Tfirst
+ Front_Pad
;
376 for J
in Tfirst
.. Tfirst_Fpad
- 1 loop
380 Target
(Tfirst_Fpad
.. Tfirst_Fpad
+ Slength
- 1) := Source
;
382 for J
in Tfirst_Fpad
+ Slength
.. Tlast
loop
395 (Source
: Wide_String;
397 New_Item
: Wide_String) return Wide_String
400 if Position
not in Source
'First .. Source
'Last + 1 then
404 Result_Length
: constant Natural :=
407 Position
- Source
'First + New_Item
'Length);
409 Result
: Wide_String (1 .. Result_Length
);
412 Result
:= Source
(Source
'First .. Position
- 1) & New_Item
&
413 Source
(Position
+ New_Item
'Length .. Source
'Last);
420 (Source
: in out Wide_String;
422 New_Item
: Wide_String;
423 Drop
: Truncation
:= Right
)
426 Move
(Source
=> Overwrite
(Source
, Position
, New_Item
),
435 function Replace_Slice
436 (Source
: Wide_String;
439 By
: Wide_String) return Wide_String
441 Result_Length
: Natural;
444 if Low
> Source
'Last + 1 or else High
< Source
'First - 1 then
448 Source
'Length - Natural'Max (High
- Low
+ 1, 0) + By
'Length;
451 Result
: Wide_String (1 .. Result_Length
);
456 Source
(Source
'First .. Low
- 1) & By
&
457 Source
(High
+ 1 .. Source
'Last);
459 Result
:= Source
(Source
'First .. Low
- 1) & By
&
460 Source
(Low
.. Source
'Last);
468 procedure Replace_Slice
469 (Source
: in out Wide_String;
473 Drop
: Truncation
:= Error
;
474 Justify
: Alignment
:= Left
;
475 Pad
: Wide_Character := Wide_Space
)
478 Move
(Replace_Slice
(Source
, Low
, High
, By
), Source
, Drop
, Justify
, Pad
);
486 (Source
: Wide_String;
488 Pad
: Wide_Character := Wide_Space
) return Wide_String
490 Result
: Wide_String (1 .. Count
);
493 if Count
< Source
'Length then
494 Result
:= Source
(Source
'Last - Count
+ 1 .. Source
'Last);
499 for J
in 1 .. Count
- Source
'Length loop
503 Result
(Count
- Source
'Length + 1 .. Count
) := Source
;
510 (Source
: in out Wide_String;
512 Justify
: Alignment
:= Left
;
513 Pad
: Wide_Character := Ada
.Strings
.Wide_Space
)
516 Move
(Source
=> Tail
(Source
, Count
, Pad
),
528 (Source
: Wide_String;
529 Mapping
: Wide_Maps
.Wide_Character_Mapping
) return Wide_String
531 Result
: Wide_String (1 .. Source
'Length);
534 for J
in Source
'Range loop
535 Result
(J
- (Source
'First - 1)) := Value
(Mapping
, Source
(J
));
542 (Source
: in out Wide_String;
543 Mapping
: Wide_Maps
.Wide_Character_Mapping
)
546 for J
in Source
'Range loop
547 Source
(J
) := Value
(Mapping
, Source
(J
));
552 (Source
: Wide_String;
553 Mapping
: Wide_Maps
.Wide_Character_Mapping_Function
) return Wide_String
555 Result
: Wide_String (1 .. Source
'Length);
558 for J
in Source
'Range loop
559 Result
(J
- (Source
'First - 1)) := Mapping
(Source
(J
));
566 (Source
: in out Wide_String;
567 Mapping
: Wide_Maps
.Wide_Character_Mapping_Function
)
570 for J
in Source
'Range loop
571 Source
(J
) := Mapping
(Source
(J
));
580 (Source
: Wide_String;
581 Side
: Trim_End
) return Wide_String
583 Low
: Natural := Source
'First;
584 High
: Natural := Source
'Last;
587 if Side
= Left
or else Side
= Both
then
588 while Low
<= High
and then Source
(Low
) = Wide_Space
loop
593 if Side
= Right
or else Side
= Both
then
594 while High
>= Low
and then Source
(High
) = Wide_Space
loop
604 -- At least one non-blank
608 Result
: constant Wide_String (1 .. High
- Low
+ 1) :=
609 Source
(Low
.. High
);
618 (Source
: in out Wide_String;
620 Justify
: Alignment
:= Left
;
621 Pad
: Wide_Character := Wide_Space
)
624 Move
(Source
=> Trim
(Source
, Side
),
631 (Source
: Wide_String;
632 Left
: Wide_Maps
.Wide_Character_Set
;
633 Right
: Wide_Maps
.Wide_Character_Set
) return Wide_String
635 Low
: Natural := Source
'First;
636 High
: Natural := Source
'Last;
639 while Low
<= High
and then Is_In
(Source
(Low
), Left
) loop
643 while High
>= Low
and then Is_In
(Source
(High
), Right
) loop
647 -- Case where source comprises only characters in the sets
653 subtype WS
is Wide_String (1 .. High
- Low
+ 1);
656 return WS
(Source
(Low
.. High
));
662 (Source
: in out Wide_String;
663 Left
: Wide_Maps
.Wide_Character_Set
;
664 Right
: Wide_Maps
.Wide_Character_Set
;
665 Justify
: Alignment
:= Strings
.Left
;
666 Pad
: Wide_Character := Wide_Space
)
669 Move
(Source
=> Trim
(Source
, Left
, Right
),
675 end Ada
.Strings
.Wide_Fixed
;