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-2012, 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
;
122 First
: out Positive;
124 renames Ada
.Strings
.Wide_Search
.Find_Token
;
127 (Source
: Wide_String;
128 Set
: Wide_Maps
.Wide_Character_Set
;
130 First
: out Positive;
132 renames Ada
.Strings
.Wide_Search
.Find_Token
;
140 Right
: Wide_Character) return Wide_String
142 Result
: Wide_String (1 .. Left
);
145 for J
in Result
'Range loop
154 Right
: Wide_String) return Wide_String
156 Result
: Wide_String (1 .. Left
* Right
'Length);
160 for J
in 1 .. Left
loop
161 Result
(Ptr
.. Ptr
+ Right
'Length - 1) := Right
;
162 Ptr
:= Ptr
+ Right
'Length;
173 (Source
: Wide_String;
175 Through
: Natural) return Wide_String
178 if From
not in Source
'Range
179 or else Through
> Source
'Last
183 elsif From
> Through
then
188 Len
: constant Integer := Source
'Length - (Through
- From
+ 1);
190 Wide_String (Source
'First .. Source
'First + Len
- 1) :=
191 Source
(Source
'First .. From
- 1) &
192 Source
(Through
+ 1 .. Source
'Last);
200 (Source
: in out Wide_String;
203 Justify
: Alignment
:= Left
;
204 Pad
: Wide_Character := Wide_Space
)
207 Move
(Source
=> Delete
(Source
, From
, Through
),
218 (Source
: Wide_String;
220 Pad
: Wide_Character := Wide_Space
) return Wide_String
222 Result
: Wide_String (1 .. Count
);
225 if Count
<= Source
'Length then
226 Result
:= Source
(Source
'First .. Source
'First + Count
- 1);
229 Result
(1 .. Source
'Length) := Source
;
231 for J
in Source
'Length + 1 .. Count
loop
240 (Source
: in out Wide_String;
242 Justify
: Alignment
:= Left
;
243 Pad
: Wide_Character := Ada
.Strings
.Wide_Space
)
246 Move
(Source
=> Head
(Source
, Count
, Pad
),
258 (Source
: Wide_String;
260 New_Item
: Wide_String) return Wide_String
262 Result
: Wide_String (1 .. Source
'Length + New_Item
'Length);
265 if Before
< Source
'First or else Before
> Source
'Last + 1 then
269 Result
:= Source
(Source
'First .. Before
- 1) & New_Item
&
270 Source
(Before
.. Source
'Last);
275 (Source
: in out Wide_String;
277 New_Item
: Wide_String;
278 Drop
: Truncation
:= Error
)
281 Move
(Source
=> Insert
(Source
, Before
, New_Item
),
291 (Source
: Wide_String;
292 Target
: out Wide_String;
293 Drop
: Truncation
:= Error
;
294 Justify
: Alignment
:= Left
;
295 Pad
: Wide_Character := Wide_Space
)
297 Sfirst
: constant Integer := Source
'First;
298 Slast
: constant Integer := Source
'Last;
299 Slength
: constant Integer := Source
'Length;
301 Tfirst
: constant Integer := Target
'First;
302 Tlast
: constant Integer := Target
'Last;
303 Tlength
: constant Integer := Target
'Length;
305 function Is_Padding
(Item
: Wide_String) return Boolean;
306 -- Determine if all characters in Item are pad characters
312 function Is_Padding
(Item
: Wide_String) return Boolean is
314 for J
in Item
'Range loop
315 if Item
(J
) /= Pad
then
323 -- Start of processing for Move
326 if Slength
= Tlength
then
329 elsif Slength
> Tlength
then
333 Target
:= Source
(Slast
- Tlength
+ 1 .. Slast
);
336 Target
:= Source
(Sfirst
.. Sfirst
+ Tlength
- 1);
341 if Is_Padding
(Source
(Sfirst
+ Tlength
.. Slast
)) then
343 Source
(Sfirst
.. Sfirst
+ Target
'Length - 1);
349 if Is_Padding
(Source
(Sfirst
.. Slast
- Tlength
)) then
350 Target
:= Source
(Slast
- Tlength
+ 1 .. Slast
);
361 -- Source'Length < Target'Length
366 Target
(Tfirst
.. Tfirst
+ Slength
- 1) := Source
;
368 for J
in Tfirst
+ Slength
.. Tlast
loop
373 for J
in Tfirst
.. Tlast
- Slength
loop
377 Target
(Tlast
- Slength
+ 1 .. Tlast
) := Source
;
381 Front_Pad
: constant Integer := (Tlength
- Slength
) / 2;
382 Tfirst_Fpad
: constant Integer := Tfirst
+ Front_Pad
;
385 for J
in Tfirst
.. Tfirst_Fpad
- 1 loop
389 Target
(Tfirst_Fpad
.. Tfirst_Fpad
+ Slength
- 1) := Source
;
391 for J
in Tfirst_Fpad
+ Slength
.. Tlast
loop
404 (Source
: Wide_String;
406 New_Item
: Wide_String) return Wide_String
409 if Position
not in Source
'First .. Source
'Last + 1 then
413 Result_Length
: constant Natural :=
416 Position
- Source
'First + New_Item
'Length);
418 Result
: Wide_String (1 .. Result_Length
);
421 Result
:= Source
(Source
'First .. Position
- 1) & New_Item
&
422 Source
(Position
+ New_Item
'Length .. Source
'Last);
429 (Source
: in out Wide_String;
431 New_Item
: Wide_String;
432 Drop
: Truncation
:= Right
)
435 Move
(Source
=> Overwrite
(Source
, Position
, New_Item
),
444 function Replace_Slice
445 (Source
: Wide_String;
448 By
: Wide_String) return Wide_String
451 if Low
> Source
'Last + 1 or else High
< Source
'First - 1 then
457 Front_Len
: constant Integer :=
458 Integer'Max (0, Low
- Source
'First);
459 -- Length of prefix of Source copied to result
461 Back_Len
: constant Integer := Integer'Max (0, Source
'Last - High
);
462 -- Length of suffix of Source copied to result
464 Result_Length
: constant Integer :=
465 Front_Len
+ By
'Length + Back_Len
;
468 Result
: Wide_String (1 .. Result_Length
);
471 Result
(1 .. Front_Len
) := Source
(Source
'First .. Low
- 1);
472 Result
(Front_Len
+ 1 .. Front_Len
+ By
'Length) := By
;
473 Result
(Front_Len
+ By
'Length + 1 .. Result
'Length) :=
474 Source
(High
+ 1 .. Source
'Last);
479 return Insert
(Source
, Before
=> Low
, New_Item
=> By
);
483 procedure Replace_Slice
484 (Source
: in out Wide_String;
488 Drop
: Truncation
:= Error
;
489 Justify
: Alignment
:= Left
;
490 Pad
: Wide_Character := Wide_Space
)
493 Move
(Replace_Slice
(Source
, Low
, High
, By
), Source
, Drop
, Justify
, Pad
);
501 (Source
: Wide_String;
503 Pad
: Wide_Character := Wide_Space
) return Wide_String
505 Result
: Wide_String (1 .. Count
);
508 if Count
< Source
'Length then
509 Result
:= Source
(Source
'Last - Count
+ 1 .. Source
'Last);
514 for J
in 1 .. Count
- Source
'Length loop
518 Result
(Count
- Source
'Length + 1 .. Count
) := Source
;
525 (Source
: in out Wide_String;
527 Justify
: Alignment
:= Left
;
528 Pad
: Wide_Character := Ada
.Strings
.Wide_Space
)
531 Move
(Source
=> Tail
(Source
, Count
, Pad
),
543 (Source
: Wide_String;
544 Mapping
: Wide_Maps
.Wide_Character_Mapping
) return Wide_String
546 Result
: Wide_String (1 .. Source
'Length);
549 for J
in Source
'Range loop
550 Result
(J
- (Source
'First - 1)) := Value
(Mapping
, Source
(J
));
557 (Source
: in out Wide_String;
558 Mapping
: Wide_Maps
.Wide_Character_Mapping
)
561 for J
in Source
'Range loop
562 Source
(J
) := Value
(Mapping
, Source
(J
));
567 (Source
: Wide_String;
568 Mapping
: Wide_Maps
.Wide_Character_Mapping_Function
) return Wide_String
570 Result
: Wide_String (1 .. Source
'Length);
573 for J
in Source
'Range loop
574 Result
(J
- (Source
'First - 1)) := Mapping
(Source
(J
));
581 (Source
: in out Wide_String;
582 Mapping
: Wide_Maps
.Wide_Character_Mapping_Function
)
585 for J
in Source
'Range loop
586 Source
(J
) := Mapping
(Source
(J
));
595 (Source
: Wide_String;
596 Side
: Trim_End
) return Wide_String
598 Low
: Natural := Source
'First;
599 High
: Natural := Source
'Last;
602 if Side
= Left
or else Side
= Both
then
603 while Low
<= High
and then Source
(Low
) = Wide_Space
loop
608 if Side
= Right
or else Side
= Both
then
609 while High
>= Low
and then Source
(High
) = Wide_Space
loop
619 -- At least one non-blank
623 Result
: constant Wide_String (1 .. High
- Low
+ 1) :=
624 Source
(Low
.. High
);
633 (Source
: in out Wide_String;
635 Justify
: Alignment
:= Left
;
636 Pad
: Wide_Character := Wide_Space
)
639 Move
(Source
=> Trim
(Source
, Side
),
646 (Source
: Wide_String;
647 Left
: Wide_Maps
.Wide_Character_Set
;
648 Right
: Wide_Maps
.Wide_Character_Set
) return Wide_String
650 Low
: Natural := Source
'First;
651 High
: Natural := Source
'Last;
654 while Low
<= High
and then Is_In
(Source
(Low
), Left
) loop
658 while High
>= Low
and then Is_In
(Source
(High
), Right
) loop
662 -- Case where source comprises only characters in the sets
668 subtype WS
is Wide_String (1 .. High
- Low
+ 1);
671 return WS
(Source
(Low
.. High
));
677 (Source
: in out Wide_String;
678 Left
: Wide_Maps
.Wide_Character_Set
;
679 Right
: Wide_Maps
.Wide_Character_Set
;
680 Justify
: Alignment
:= Strings
.Left
;
681 Pad
: Wide_Character := Wide_Space
)
684 Move
(Source
=> Trim
(Source
, Left
, Right
),
690 end Ada
.Strings
.Wide_Fixed
;