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-2010, 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 :=
462 Integer'Max (0, Source'Last - High);
463 -- Length of suffix of Source copied to result
465 Result_Length : constant Integer :=
466 Front_Len + By'Length + Back_Len;
469 Result : Wide_String (1 .. Result_Length);
472 Result (1 .. Front_Len) := Source (Source'First .. Low - 1);
473 Result (Front_Len + 1 .. Front_Len + By'Length) := By;
474 Result (Front_Len + By'Length + 1 .. Result'Length) :=
475 Source (High + 1 .. Source'Last);
480 return Insert (Source, Before => Low, New_Item => By);
484 procedure Replace_Slice
485 (Source : in out Wide_String;
489 Drop : Truncation := Error;
490 Justify : Alignment := Left;
491 Pad : Wide_Character := Wide_Space)
494 Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
502 (Source : Wide_String;
504 Pad : Wide_Character := Wide_Space) return Wide_String
506 Result : Wide_String (1 .. Count);
509 if Count < Source'Length then
510 Result := Source (Source'Last - Count + 1 .. Source'Last);
515 for J in 1 .. Count - Source'Length loop
519 Result (Count - Source'Length + 1 .. Count) := Source;
526 (Source : in out Wide_String;
528 Justify : Alignment := Left;
529 Pad : Wide_Character := Ada.Strings.Wide_Space)
532 Move (Source => Tail (Source, Count, Pad),
544 (Source : Wide_String;
545 Mapping : Wide_Maps.Wide_Character_Mapping) return Wide_String
547 Result : Wide_String (1 .. Source'Length);
550 for J in Source'Range loop
551 Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
558 (Source : in out Wide_String;
559 Mapping : Wide_Maps.Wide_Character_Mapping)
562 for J in Source'Range loop
563 Source (J) := Value (Mapping, Source (J));
568 (Source : Wide_String;
569 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Wide_String
571 Result : Wide_String (1 .. Source'Length);
574 for J in Source'Range loop
575 Result (J - (Source'First - 1)) := Mapping (Source (J));
582 (Source : in out Wide_String;
583 Mapping : Wide_Maps.Wide_Character_Mapping_Function)
586 for J in Source'Range loop
587 Source (J) := Mapping (Source (J));
596 (Source : Wide_String;
597 Side : Trim_End) return Wide_String
599 Low : Natural := Source'First;
600 High : Natural := Source'Last;
603 if Side = Left or else Side = Both then
604 while Low <= High and then Source (Low) = Wide_Space loop
609 if Side = Right or else Side = Both then
610 while High >= Low and then Source (High) = Wide_Space loop
620 -- At least one non-blank
624 Result : constant Wide_String (1 .. High - Low + 1) :=
625 Source (Low .. High);
634 (Source : in out Wide_String;
636 Justify : Alignment := Left;
637 Pad : Wide_Character := Wide_Space)
640 Move (Source => Trim (Source, Side),
647 (Source : Wide_String;
648 Left : Wide_Maps.Wide_Character_Set;
649 Right : Wide_Maps.Wide_Character_Set) return Wide_String
651 Low : Natural := Source'First;
652 High : Natural := Source'Last;
655 while Low <= High and then Is_In (Source (Low), Left) loop
659 while High >= Low and then Is_In (Source (High), Right) loop
663 -- Case where source comprises only characters in the sets
669 subtype WS is Wide_String (1 .. High - Low + 1);
672 return WS (Source (Low .. High));
678 (Source : in out Wide_String;
679 Left : Wide_Maps.Wide_Character_Set;
680 Right : Wide_Maps.Wide_Character_Set;
681 Justify : Alignment := Strings.Left;
682 Pad : Wide_Character := Wide_Space)
685 Move (Source => Trim (Source, Left, Right),
691 end Ada.Strings.Wide_Fixed;