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;