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-2009, 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;
121 First : out Positive;
123 renames Ada.Strings.Wide_Search.Find_Token;
131 Right : Wide_Character) return Wide_String
133 Result : Wide_String (1 .. Left);
136 for J in Result'Range loop
145 Right : Wide_String) return Wide_String
147 Result : Wide_String (1 .. Left * Right'Length);
151 for J in 1 .. Left loop
152 Result (Ptr .. Ptr + Right'Length - 1) := Right;
153 Ptr := Ptr + Right'Length;
164 (Source : Wide_String;
166 Through : Natural) return Wide_String
169 if From not in Source'Range
170 or else Through > Source'Last
174 elsif From > Through then
179 Len : constant Integer := Source'Length - (Through - From + 1);
181 Wide_String (Source'First .. Source'First + Len - 1) :=
182 Source (Source'First .. From - 1) &
183 Source (Through + 1 .. Source'Last);
191 (Source : in out Wide_String;
194 Justify : Alignment := Left;
195 Pad : Wide_Character := Wide_Space)
198 Move (Source => Delete (Source, From, Through),
209 (Source : Wide_String;
211 Pad : Wide_Character := Wide_Space) return Wide_String
213 Result : Wide_String (1 .. Count);
216 if Count <= Source'Length then
217 Result := Source (Source'First .. Source'First + Count - 1);
220 Result (1 .. Source'Length) := Source;
222 for J in Source'Length + 1 .. Count loop
231 (Source : in out Wide_String;
233 Justify : Alignment := Left;
234 Pad : Wide_Character := Ada.Strings.Wide_Space)
237 Move (Source => Head (Source, Count, Pad),
249 (Source : Wide_String;
251 New_Item : Wide_String) return Wide_String
253 Result : Wide_String (1 .. Source'Length + New_Item'Length);
256 if Before < Source'First or else Before > Source'Last + 1 then
260 Result := Source (Source'First .. Before - 1) & New_Item &
261 Source (Before .. Source'Last);
266 (Source : in out Wide_String;
268 New_Item : Wide_String;
269 Drop : Truncation := Error)
272 Move (Source => Insert (Source, Before, New_Item),
282 (Source : Wide_String;
283 Target : out Wide_String;
284 Drop : Truncation := Error;
285 Justify : Alignment := Left;
286 Pad : Wide_Character := Wide_Space)
288 Sfirst : constant Integer := Source'First;
289 Slast : constant Integer := Source'Last;
290 Slength : constant Integer := Source'Length;
292 Tfirst : constant Integer := Target'First;
293 Tlast : constant Integer := Target'Last;
294 Tlength : constant Integer := Target'Length;
296 function Is_Padding (Item : Wide_String) return Boolean;
297 -- Determine if all characters in Item are pad characters
303 function Is_Padding (Item : Wide_String) return Boolean is
305 for J in Item'Range loop
306 if Item (J) /= Pad then
314 -- Start of processing for Move
317 if Slength = Tlength then
320 elsif Slength > Tlength then
324 Target := Source (Slast - Tlength + 1 .. Slast);
327 Target := Source (Sfirst .. Sfirst + Tlength - 1);
332 if Is_Padding (Source (Sfirst + Tlength .. Slast)) then
334 Source (Sfirst .. Sfirst + Target'Length - 1);
340 if Is_Padding (Source (Sfirst .. Slast - Tlength)) then
341 Target := Source (Slast - Tlength + 1 .. Slast);
352 -- Source'Length < Target'Length
357 Target (Tfirst .. Tfirst + Slength - 1) := Source;
359 for J in Tfirst + Slength .. Tlast loop
364 for J in Tfirst .. Tlast - Slength loop
368 Target (Tlast - Slength + 1 .. Tlast) := Source;
372 Front_Pad : constant Integer := (Tlength - Slength) / 2;
373 Tfirst_Fpad : constant Integer := Tfirst + Front_Pad;
376 for J in Tfirst .. Tfirst_Fpad - 1 loop
380 Target (Tfirst_Fpad .. Tfirst_Fpad + Slength - 1) := Source;
382 for J in Tfirst_Fpad + Slength .. Tlast loop
395 (Source : Wide_String;
397 New_Item : Wide_String) return Wide_String
400 if Position not in Source'First .. Source'Last + 1 then
404 Result_Length : constant Natural :=
407 Position - Source'First + New_Item'Length);
409 Result : Wide_String (1 .. Result_Length);
412 Result := Source (Source'First .. Position - 1) & New_Item &
413 Source (Position + New_Item'Length .. Source'Last);
420 (Source : in out Wide_String;
422 New_Item : Wide_String;
423 Drop : Truncation := Right)
426 Move (Source => Overwrite (Source, Position, New_Item),
435 function Replace_Slice
436 (Source : Wide_String;
439 By : Wide_String) return Wide_String
441 Result_Length : Natural;
444 if Low > Source'Last + 1 or else High < Source'First - 1 then
448 Source'Length - Natural'Max (High - Low + 1, 0) + By'Length;
451 Result : Wide_String (1 .. Result_Length);
456 Source (Source'First .. Low - 1) & By &
457 Source (High + 1 .. Source'Last);
459 Result := Source (Source'First .. Low - 1) & By &
460 Source (Low .. Source'Last);
468 procedure Replace_Slice
469 (Source : in out Wide_String;
473 Drop : Truncation := Error;
474 Justify : Alignment := Left;
475 Pad : Wide_Character := Wide_Space)
478 Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
486 (Source : Wide_String;
488 Pad : Wide_Character := Wide_Space) return Wide_String
490 Result : Wide_String (1 .. Count);
493 if Count < Source'Length then
494 Result := Source (Source'Last - Count + 1 .. Source'Last);
499 for J in 1 .. Count - Source'Length loop
503 Result (Count - Source'Length + 1 .. Count) := Source;
510 (Source : in out Wide_String;
512 Justify : Alignment := Left;
513 Pad : Wide_Character := Ada.Strings.Wide_Space)
516 Move (Source => Tail (Source, Count, Pad),
528 (Source : Wide_String;
529 Mapping : Wide_Maps.Wide_Character_Mapping) return Wide_String
531 Result : Wide_String (1 .. Source'Length);
534 for J in Source'Range loop
535 Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
542 (Source : in out Wide_String;
543 Mapping : Wide_Maps.Wide_Character_Mapping)
546 for J in Source'Range loop
547 Source (J) := Value (Mapping, Source (J));
552 (Source : Wide_String;
553 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Wide_String
555 Result : Wide_String (1 .. Source'Length);
558 for J in Source'Range loop
559 Result (J - (Source'First - 1)) := Mapping (Source (J));
566 (Source : in out Wide_String;
567 Mapping : Wide_Maps.Wide_Character_Mapping_Function)
570 for J in Source'Range loop
571 Source (J) := Mapping (Source (J));
580 (Source : Wide_String;
581 Side : Trim_End) return Wide_String
583 Low : Natural := Source'First;
584 High : Natural := Source'Last;
587 if Side = Left or else Side = Both then
588 while Low <= High and then Source (Low) = Wide_Space loop
593 if Side = Right or else Side = Both then
594 while High >= Low and then Source (High) = Wide_Space loop
604 -- At least one non-blank
608 Result : constant Wide_String (1 .. High - Low + 1) :=
609 Source (Low .. High);
618 (Source : in out Wide_String;
620 Justify : Alignment := Left;
621 Pad : Wide_Character := Wide_Space)
624 Move (Source => Trim (Source, Side),
631 (Source : Wide_String;
632 Left : Wide_Maps.Wide_Character_Set;
633 Right : Wide_Maps.Wide_Character_Set) return Wide_String
635 Low : Natural := Source'First;
636 High : Natural := Source'Last;
639 while Low <= High and then Is_In (Source (Low), Left) loop
643 while High >= Low and then Is_In (Source (High), Right) loop
647 -- Case where source comprises only characters in the sets
653 subtype WS is Wide_String (1 .. High - Low + 1);
656 return WS (Source (Low .. High));
662 (Source : in out Wide_String;
663 Left : Wide_Maps.Wide_Character_Set;
664 Right : Wide_Maps.Wide_Character_Set;
665 Justify : Alignment := Strings.Left;
666 Pad : Wide_Character := Wide_Space)
669 Move (Source => Trim (Source, Left, Right),
675 end Ada.Strings.Wide_Fixed;