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-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, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, 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 : Wide_String;
45 Pattern : Wide_String;
46 Going : Direction := Forward;
47 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
49 renames Ada.Strings.Wide_Search.Index;
52 (Source : Wide_String;
53 Pattern : Wide_String;
54 Going : Direction := Forward;
55 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
56 renames Ada.Strings.Wide_Search.Index;
59 (Source : Wide_String;
60 Set : Wide_Maps.Wide_Character_Set;
61 Test : Membership := Inside;
62 Going : Direction := Forward) return Natural
63 renames Ada.Strings.Wide_Search.Index;
66 (Source : Wide_String;
67 Pattern : Wide_String;
69 Going : Direction := Forward;
70 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
72 renames Ada.Strings.Wide_Search.Index;
75 (Source : Wide_String;
76 Pattern : Wide_String;
78 Going : Direction := Forward;
79 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
80 renames Ada.Strings.Wide_Search.Index;
83 (Source : Wide_String;
84 Set : Wide_Maps.Wide_Character_Set;
86 Test : Membership := Inside;
87 Going : Direction := Forward) return Natural
88 renames Ada.Strings.Wide_Search.Index;
90 function Index_Non_Blank
91 (Source : Wide_String;
92 Going : Direction := Forward) return Natural
93 renames Ada.Strings.Wide_Search.Index_Non_Blank;
95 function Index_Non_Blank
96 (Source : Wide_String;
98 Going : Direction := Forward) return Natural
99 renames Ada.Strings.Wide_Search.Index_Non_Blank;
102 (Source : Wide_String;
103 Pattern : Wide_String;
104 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
106 renames Ada.Strings.Wide_Search.Count;
109 (Source : Wide_String;
110 Pattern : Wide_String;
111 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
112 renames Ada.Strings.Wide_Search.Count;
115 (Source : Wide_String;
116 Set : Wide_Maps.Wide_Character_Set) return Natural
117 renames Ada.Strings.Wide_Search.Count;
120 (Source : Wide_String;
121 Set : Wide_Maps.Wide_Character_Set;
123 First : out Positive;
125 renames Ada.Strings.Wide_Search.Find_Token;
133 Right : Wide_Character) return Wide_String
135 Result : Wide_String (1 .. Left);
138 for J in Result'Range loop
147 Right : Wide_String) return Wide_String
149 Result : Wide_String (1 .. Left * Right'Length);
153 for J in 1 .. Left loop
154 Result (Ptr .. Ptr + Right'Length - 1) := Right;
155 Ptr := Ptr + Right'Length;
166 (Source : Wide_String;
168 Through : Natural) return Wide_String
171 if From not in Source'Range
172 or else Through > Source'Last
176 elsif From > Through then
181 Len : constant Integer := Source'Length - (Through - From + 1);
183 Wide_String (Source'First .. Source'First + Len - 1) :=
184 Source (Source'First .. From - 1) &
185 Source (Through + 1 .. Source'Last);
193 (Source : in out Wide_String;
196 Justify : Alignment := Left;
197 Pad : Wide_Character := Wide_Space)
200 Move (Source => Delete (Source, From, Through),
211 (Source : Wide_String;
213 Pad : Wide_Character := Wide_Space) return Wide_String
215 Result : Wide_String (1 .. Count);
218 if Count <= Source'Length then
219 Result := Source (Source'First .. Source'First + Count - 1);
222 Result (1 .. Source'Length) := Source;
224 for J in Source'Length + 1 .. Count loop
233 (Source : in out Wide_String;
235 Justify : Alignment := Left;
236 Pad : Wide_Character := Ada.Strings.Wide_Space)
239 Move (Source => Head (Source, Count, Pad),
251 (Source : Wide_String;
253 New_Item : Wide_String) return Wide_String
255 Result : Wide_String (1 .. Source'Length + New_Item'Length);
258 if Before < Source'First or else Before > Source'Last + 1 then
262 Result := Source (Source'First .. Before - 1) & New_Item &
263 Source (Before .. Source'Last);
268 (Source : in out Wide_String;
270 New_Item : Wide_String;
271 Drop : Truncation := Error)
274 Move (Source => Insert (Source, Before, New_Item),
284 (Source : Wide_String;
285 Target : out Wide_String;
286 Drop : Truncation := Error;
287 Justify : Alignment := Left;
288 Pad : Wide_Character := Wide_Space)
290 Sfirst : constant Integer := Source'First;
291 Slast : constant Integer := Source'Last;
292 Slength : constant Integer := Source'Length;
294 Tfirst : constant Integer := Target'First;
295 Tlast : constant Integer := Target'Last;
296 Tlength : constant Integer := Target'Length;
298 function Is_Padding (Item : Wide_String) return Boolean;
299 -- Determinbe if all characters in Item are pad characters
301 function Is_Padding (Item : Wide_String) return Boolean is
303 for J in Item'Range loop
304 if Item (J) /= Pad then
312 -- Start of processing for Move
315 if Slength = Tlength then
318 elsif Slength > Tlength then
322 Target := Source (Slast - Tlength + 1 .. Slast);
325 Target := Source (Sfirst .. Sfirst + Tlength - 1);
330 if Is_Padding (Source (Sfirst + Tlength .. Slast)) then
332 Source (Sfirst .. Sfirst + Target'Length - 1);
338 if Is_Padding (Source (Sfirst .. Slast - Tlength)) then
339 Target := Source (Slast - Tlength + 1 .. Slast);
350 -- Source'Length < Target'Length
355 Target (Tfirst .. Tfirst + Slength - 1) := Source;
357 for J in Tfirst + Slength .. Tlast loop
362 for J in Tfirst .. Tlast - Slength loop
366 Target (Tlast - Slength + 1 .. Tlast) := Source;
370 Front_Pad : constant Integer := (Tlength - Slength) / 2;
371 Tfirst_Fpad : constant Integer := Tfirst + Front_Pad;
374 for J in Tfirst .. Tfirst_Fpad - 1 loop
378 Target (Tfirst_Fpad .. Tfirst_Fpad + Slength - 1) := Source;
380 for J in Tfirst_Fpad + Slength .. Tlast loop
393 (Source : Wide_String;
395 New_Item : Wide_String) return Wide_String
398 if Position not in Source'First .. Source'Last + 1 then
402 Result_Length : constant Natural :=
405 Position - Source'First + New_Item'Length);
407 Result : Wide_String (1 .. Result_Length);
410 Result := Source (Source'First .. Position - 1) & New_Item &
411 Source (Position + New_Item'Length .. Source'Last);
418 (Source : in out Wide_String;
420 New_Item : Wide_String;
421 Drop : Truncation := Right)
424 Move (Source => Overwrite (Source, Position, New_Item),
433 function Replace_Slice
434 (Source : Wide_String;
437 By : Wide_String) return Wide_String
439 Result_Length : Natural;
442 if Low > Source'Last + 1 or else High < Source'First - 1 then
446 Source'Length - Natural'Max (High - Low + 1, 0) + By'Length;
449 Result : Wide_String (1 .. Result_Length);
454 Source (Source'First .. Low - 1) & By &
455 Source (High + 1 .. Source'Last);
457 Result := Source (Source'First .. Low - 1) & By &
458 Source (Low .. Source'Last);
466 procedure Replace_Slice
467 (Source : in out Wide_String;
471 Drop : Truncation := Error;
472 Justify : Alignment := Left;
473 Pad : Wide_Character := Wide_Space)
476 Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
484 (Source : Wide_String;
486 Pad : Wide_Character := Wide_Space) return Wide_String
488 Result : Wide_String (1 .. Count);
491 if Count < Source'Length then
492 Result := Source (Source'Last - Count + 1 .. Source'Last);
497 for J in 1 .. Count - Source'Length loop
501 Result (Count - Source'Length + 1 .. Count) := Source;
508 (Source : in out Wide_String;
510 Justify : Alignment := Left;
511 Pad : Wide_Character := Ada.Strings.Wide_Space)
514 Move (Source => Tail (Source, Count, Pad),
526 (Source : Wide_String;
527 Mapping : Wide_Maps.Wide_Character_Mapping) return Wide_String
529 Result : Wide_String (1 .. Source'Length);
532 for J in Source'Range loop
533 Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
540 (Source : in out Wide_String;
541 Mapping : Wide_Maps.Wide_Character_Mapping)
544 for J in Source'Range loop
545 Source (J) := Value (Mapping, Source (J));
550 (Source : Wide_String;
551 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Wide_String
553 Result : Wide_String (1 .. Source'Length);
556 for J in Source'Range loop
557 Result (J - (Source'First - 1)) := Mapping (Source (J));
564 (Source : in out Wide_String;
565 Mapping : Wide_Maps.Wide_Character_Mapping_Function)
568 for J in Source'Range loop
569 Source (J) := Mapping (Source (J));
578 (Source : Wide_String;
579 Side : Trim_End) return Wide_String
581 Low : Natural := Source'First;
582 High : Natural := Source'Last;
585 if Side = Left or else Side = Both then
586 while Low <= High and then Source (Low) = Wide_Space loop
591 if Side = Right or else Side = Both then
592 while High >= Low and then Source (High) = Wide_Space loop
602 -- At least one non-blank
606 Result : constant Wide_String (1 .. High - Low + 1) :=
607 Source (Low .. High);
616 (Source : in out Wide_String;
618 Justify : Alignment := Left;
619 Pad : Wide_Character := Wide_Space)
622 Move (Source => Trim (Source, Side),
629 (Source : Wide_String;
630 Left : Wide_Maps.Wide_Character_Set;
631 Right : Wide_Maps.Wide_Character_Set) return Wide_String
633 Low : Natural := Source'First;
634 High : Natural := Source'Last;
637 while Low <= High and then Is_In (Source (Low), Left) loop
641 while High >= Low and then Is_In (Source (High), Right) loop
645 -- Case where source comprises only characters in the sets
651 subtype WS is Wide_String (1 .. High - Low + 1);
654 return WS (Source (Low .. High));
660 (Source : in out Wide_String;
661 Left : Wide_Maps.Wide_Character_Set;
662 Right : Wide_Maps.Wide_Character_Set;
663 Justify : Alignment := Strings.Left;
664 Pad : Wide_Character := Wide_Space)
667 Move (Source => Trim (Source, Left, Right),
673 end Ada.Strings.Wide_Fixed;