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-2002 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_Maps
; use Ada
.Strings
.Wide_Maps
;
35 with Ada
.Strings
.Wide_Search
;
37 package body Ada
.Strings
.Wide_Fixed
is
39 ------------------------
40 -- Search Subprograms --
41 ------------------------
44 (Source
: in Wide_String;
45 Pattern
: in Wide_String;
46 Going
: in Direction
:= Forward
;
47 Mapping
: in Wide_Maps
.Wide_Character_Mapping
:= Wide_Maps
.Identity
)
49 renames Ada
.Strings
.Wide_Search
.Index
;
52 (Source
: in Wide_String;
53 Pattern
: in Wide_String;
54 Going
: in Direction
:= Forward
;
55 Mapping
: in Wide_Maps
.Wide_Character_Mapping_Function
)
57 renames Ada
.Strings
.Wide_Search
.Index
;
60 (Source
: in Wide_String;
61 Set
: in Wide_Maps
.Wide_Character_Set
;
62 Test
: in Membership
:= Inside
;
63 Going
: in Direction
:= Forward
)
65 renames Ada
.Strings
.Wide_Search
.Index
;
67 function Index_Non_Blank
68 (Source
: in Wide_String;
69 Going
: in Direction
:= Forward
)
71 renames Ada
.Strings
.Wide_Search
.Index_Non_Blank
;
74 (Source
: in Wide_String;
75 Pattern
: in Wide_String;
76 Mapping
: in Wide_Maps
.Wide_Character_Mapping
:= Wide_Maps
.Identity
)
78 renames Ada
.Strings
.Wide_Search
.Count
;
81 (Source
: in Wide_String;
82 Pattern
: in Wide_String;
83 Mapping
: in Wide_Maps
.Wide_Character_Mapping_Function
)
85 renames Ada
.Strings
.Wide_Search
.Count
;
88 (Source
: in Wide_String;
89 Set
: in Wide_Maps
.Wide_Character_Set
)
91 renames Ada
.Strings
.Wide_Search
.Count
;
94 (Source
: in Wide_String;
95 Set
: in Wide_Maps
.Wide_Character_Set
;
99 renames Ada
.Strings
.Wide_Search
.Find_Token
;
107 Right
: in Wide_Character)
110 Result
: Wide_String (1 .. Left
);
113 for J
in Result
'Range loop
122 Right
: in Wide_String)
125 Result
: Wide_String (1 .. Left
* Right
'Length);
129 for J
in 1 .. Left
loop
130 Result
(Ptr
.. Ptr
+ Right
'Length - 1) := Right
;
131 Ptr
:= Ptr
+ Right
'Length;
142 (Source
: in Wide_String;
144 Through
: in Natural)
148 if From
not in Source
'Range
149 or else Through
> Source
'Last
153 elsif From
> Through
then
158 Len
: constant Integer := Source
'Length - (Through
- From
+ 1);
160 Wide_String (Source
'First .. Source
'First + Len
- 1) :=
161 Source
(Source
'First .. From
- 1) &
162 Source
(Through
+ 1 .. Source
'Last);
170 (Source
: in out Wide_String;
172 Through
: in Natural;
173 Justify
: in Alignment
:= Left
;
174 Pad
: in Wide_Character := Wide_Space
)
177 Move
(Source
=> Delete
(Source
, From
, Through
),
188 (Source
: in Wide_String;
190 Pad
: in Wide_Character := Wide_Space
)
193 Result
: Wide_String (1 .. Count
);
196 if Count
<= Source
'Length then
197 Result
:= Source
(Source
'First .. Source
'First + Count
- 1);
200 Result
(1 .. Source
'Length) := Source
;
202 for J
in Source
'Length + 1 .. Count
loop
211 (Source
: in out Wide_String;
213 Justify
: in Alignment
:= Left
;
214 Pad
: in Wide_Character := Ada
.Strings
.Wide_Space
)
217 Move
(Source
=> Head
(Source
, Count
, Pad
),
229 (Source
: in Wide_String;
230 Before
: in Positive;
231 New_Item
: in Wide_String)
234 Result
: Wide_String (1 .. Source
'Length + New_Item
'Length);
237 if Before
< Source
'First or else Before
> Source
'Last + 1 then
241 Result
:= Source
(Source
'First .. Before
- 1) & New_Item
&
242 Source
(Before
.. Source
'Last);
247 (Source
: in out Wide_String;
248 Before
: in Positive;
249 New_Item
: in Wide_String;
250 Drop
: in Truncation
:= Error
)
253 Move
(Source
=> Insert
(Source
, Before
, New_Item
),
263 (Source
: in Wide_String;
264 Target
: out Wide_String;
265 Drop
: in Truncation
:= Error
;
266 Justify
: in Alignment
:= Left
;
267 Pad
: in Wide_Character := Wide_Space
)
269 Sfirst
: constant Integer := Source
'First;
270 Slast
: constant Integer := Source
'Last;
271 Slength
: constant Integer := Source
'Length;
273 Tfirst
: constant Integer := Target
'First;
274 Tlast
: constant Integer := Target
'Last;
275 Tlength
: constant Integer := Target
'Length;
277 function Is_Padding
(Item
: Wide_String) return Boolean;
278 -- Determinbe if all characters in Item are pad characters
280 function Is_Padding
(Item
: Wide_String) return Boolean is
282 for J
in Item
'Range loop
283 if Item
(J
) /= Pad
then
291 -- Start of processing for Move
294 if Slength
= Tlength
then
297 elsif Slength
> Tlength
then
301 Target
:= Source
(Slast
- Tlength
+ 1 .. Slast
);
304 Target
:= Source
(Sfirst
.. Sfirst
+ Tlength
- 1);
309 if Is_Padding
(Source
(Sfirst
+ Tlength
.. Slast
)) then
311 Source
(Sfirst
.. Sfirst
+ Target
'Length - 1);
317 if Is_Padding
(Source
(Sfirst
.. Slast
- Tlength
)) then
318 Target
:= Source
(Slast
- Tlength
+ 1 .. Slast
);
329 -- Source'Length < Target'Length
334 Target
(Tfirst
.. Tfirst
+ Slength
- 1) := Source
;
336 for J
in Tfirst
+ Slength
.. Tlast
loop
341 for J
in Tfirst
.. Tlast
- Slength
loop
345 Target
(Tlast
- Slength
+ 1 .. Tlast
) := Source
;
349 Front_Pad
: constant Integer := (Tlength
- Slength
) / 2;
350 Tfirst_Fpad
: constant Integer := Tfirst
+ Front_Pad
;
353 for J
in Tfirst
.. Tfirst_Fpad
- 1 loop
357 Target
(Tfirst_Fpad
.. Tfirst_Fpad
+ Slength
- 1) := Source
;
359 for J
in Tfirst_Fpad
+ Slength
.. Tlast
loop
372 (Source
: in Wide_String;
373 Position
: in Positive;
374 New_Item
: in Wide_String)
378 if Position
not in Source
'First .. Source
'Last + 1 then
382 Result_Length
: constant Natural :=
385 Position
- Source
'First + New_Item
'Length);
387 Result
: Wide_String (1 .. Result_Length
);
390 Result
:= Source
(Source
'First .. Position
- 1) & New_Item
&
391 Source
(Position
+ New_Item
'Length .. Source
'Last);
398 (Source
: in out Wide_String;
399 Position
: in Positive;
400 New_Item
: in Wide_String;
401 Drop
: in Truncation
:= Right
)
404 Move
(Source
=> Overwrite
(Source
, Position
, New_Item
),
413 function Replace_Slice
414 (Source
: in Wide_String;
420 Result_Length
: Natural;
423 if Low
> Source
'Last + 1 or else High
< Source
'First - 1 then
427 Source
'Length - Natural'Max (High
- Low
+ 1, 0) + By
'Length;
430 Result
: Wide_String (1 .. Result_Length
);
435 Source
(Source
'First .. Low
- 1) & By
&
436 Source
(High
+ 1 .. Source
'Last);
438 Result
:= Source
(Source
'First .. Low
- 1) & By
&
439 Source
(Low
.. Source
'Last);
447 procedure Replace_Slice
448 (Source
: in out Wide_String;
452 Drop
: in Truncation
:= Error
;
453 Justify
: in Alignment
:= Left
;
454 Pad
: in Wide_Character := Wide_Space
)
457 Move
(Replace_Slice
(Source
, Low
, High
, By
), Source
, Drop
, Justify
, Pad
);
465 (Source
: in Wide_String;
467 Pad
: in Wide_Character := Wide_Space
)
470 Result
: Wide_String (1 .. Count
);
473 if Count
< Source
'Length then
474 Result
:= Source
(Source
'Last - Count
+ 1 .. Source
'Last);
479 for J
in 1 .. Count
- Source
'Length loop
483 Result
(Count
- Source
'Length + 1 .. Count
) := Source
;
490 (Source
: in out Wide_String;
492 Justify
: in Alignment
:= Left
;
493 Pad
: in Wide_Character := Ada
.Strings
.Wide_Space
)
496 Move
(Source
=> Tail
(Source
, Count
, Pad
),
508 (Source
: in Wide_String;
509 Mapping
: in Wide_Maps
.Wide_Character_Mapping
)
512 Result
: Wide_String (1 .. Source
'Length);
515 for J
in Source
'Range loop
516 Result
(J
- (Source
'First - 1)) := Value
(Mapping
, Source
(J
));
523 (Source
: in out Wide_String;
524 Mapping
: in Wide_Maps
.Wide_Character_Mapping
)
527 for J
in Source
'Range loop
528 Source
(J
) := Value
(Mapping
, Source
(J
));
533 (Source
: in Wide_String;
534 Mapping
: in Wide_Maps
.Wide_Character_Mapping_Function
)
537 Result
: Wide_String (1 .. Source
'Length);
540 for J
in Source
'Range loop
541 Result
(J
- (Source
'First - 1)) := Mapping
(Source
(J
));
548 (Source
: in out Wide_String;
549 Mapping
: in Wide_Maps
.Wide_Character_Mapping_Function
)
552 for J
in Source
'Range loop
553 Source
(J
) := Mapping
(Source
(J
));
562 (Source
: in Wide_String;
566 Low
: Natural := Source
'First;
567 High
: Natural := Source
'Last;
570 if Side
= Left
or else Side
= Both
then
571 while Low
<= High
and then Source
(Low
) = Wide_Space
loop
576 if Side
= Right
or else Side
= Both
then
577 while High
>= Low
and then Source
(High
) = Wide_Space
loop
587 -- At least one non-blank
591 Result
: constant Wide_String (1 .. High
- Low
+ 1) :=
592 Source
(Low
.. High
);
601 (Source
: in out Wide_String;
603 Justify
: in Alignment
:= Left
;
604 Pad
: in Wide_Character := Wide_Space
)
607 Move
(Source
=> Trim
(Source
, Side
),
614 (Source
: in Wide_String;
615 Left
: in Wide_Maps
.Wide_Character_Set
;
616 Right
: in Wide_Maps
.Wide_Character_Set
)
619 Low
: Natural := Source
'First;
620 High
: Natural := Source
'Last;
623 while Low
<= High
and then Is_In
(Source
(Low
), Left
) loop
627 while High
>= Low
and then Is_In
(Source
(High
), Right
) loop
631 -- Case where source comprises only characters in the sets
637 subtype WS
is Wide_String (1 .. High
- Low
+ 1);
640 return WS
(Source
(Low
.. High
));
646 (Source
: in out Wide_String;
647 Left
: in Wide_Maps
.Wide_Character_Set
;
648 Right
: in Wide_Maps
.Wide_Character_Set
;
649 Justify
: in Alignment
:= Strings
.Left
;
650 Pad
: in Wide_Character := Wide_Space
)
653 Move
(Source
=> Trim
(Source
, Left
, Right
),
659 end Ada
.Strings
.Wide_Fixed
;