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-2020, 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_Wide_Maps; use Ada.Strings.Wide_Wide_Maps;
33 with Ada.Strings.Wide_Wide_Search;
35 package body Ada.Strings.Wide_Wide_Fixed is
37 ------------------------
38 -- Search Subprograms --
39 ------------------------
42 (Source : Wide_Wide_String;
43 Pattern : Wide_Wide_String;
44 Going : Direction := Forward;
45 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
46 Wide_Wide_Maps.Identity)
48 renames Ada.Strings.Wide_Wide_Search.Index;
51 (Source : Wide_Wide_String;
52 Pattern : Wide_Wide_String;
53 Going : Direction := Forward;
54 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping_Function)
56 renames Ada.Strings.Wide_Wide_Search.Index;
59 (Source : Wide_Wide_String;
60 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
61 Test : Membership := Inside;
62 Going : Direction := Forward) return Natural
63 renames Ada.Strings.Wide_Wide_Search.Index;
66 (Source : Wide_Wide_String;
67 Pattern : Wide_Wide_String;
69 Going : Direction := Forward;
70 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
71 Wide_Wide_Maps.Identity)
73 renames Ada.Strings.Wide_Wide_Search.Index;
76 (Source : Wide_Wide_String;
77 Pattern : Wide_Wide_String;
79 Going : Direction := Forward;
80 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping_Function)
82 renames Ada.Strings.Wide_Wide_Search.Index;
85 (Source : Wide_Wide_String;
86 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
88 Test : Membership := Inside;
89 Going : Direction := Forward) return Natural
90 renames Ada.Strings.Wide_Wide_Search.Index;
92 function Index_Non_Blank
93 (Source : Wide_Wide_String;
94 Going : Direction := Forward) return Natural
95 renames Ada.Strings.Wide_Wide_Search.Index_Non_Blank;
97 function Index_Non_Blank
98 (Source : Wide_Wide_String;
100 Going : Direction := Forward) return Natural
101 renames Ada.Strings.Wide_Wide_Search.Index_Non_Blank;
104 (Source : Wide_Wide_String;
105 Pattern : Wide_Wide_String;
106 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
107 Wide_Wide_Maps.Identity)
109 renames Ada.Strings.Wide_Wide_Search.Count;
112 (Source : Wide_Wide_String;
113 Pattern : Wide_Wide_String;
114 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping_Function)
116 renames Ada.Strings.Wide_Wide_Search.Count;
119 (Source : Wide_Wide_String;
120 Set : Wide_Wide_Maps.Wide_Wide_Character_Set) return Natural
121 renames Ada.Strings.Wide_Wide_Search.Count;
124 (Source : Wide_Wide_String;
125 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
128 First : out Positive;
130 renames Ada.Strings.Wide_Wide_Search.Find_Token;
133 (Source : Wide_Wide_String;
134 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
136 First : out Positive;
138 renames Ada.Strings.Wide_Wide_Search.Find_Token;
146 Right : Wide_Wide_Character) return Wide_Wide_String
148 Result : Wide_Wide_String (1 .. Left);
151 for J in Result'Range loop
160 Right : Wide_Wide_String) return Wide_Wide_String
162 Result : Wide_Wide_String (1 .. Left * Right'Length);
166 for J in 1 .. Left loop
167 Result (Ptr .. Ptr + Right'Length - 1) := Right;
168 Ptr := Ptr + Right'Length;
179 (Source : Wide_Wide_String;
181 Through : Natural) return Wide_Wide_String
184 if From not in Source'Range
185 or else Through > Source'Last
189 elsif From > Through then
194 Len : constant Integer := Source'Length - (Through - From + 1);
195 Result : constant Wide_Wide_String
196 (Source'First .. Source'First + Len - 1) :=
197 Source (Source'First .. From - 1) &
198 Source (Through + 1 .. Source'Last);
206 (Source : in out Wide_Wide_String;
209 Justify : Alignment := Left;
210 Pad : Wide_Wide_Character := Wide_Wide_Space)
213 Move (Source => Delete (Source, From, Through),
224 (Source : Wide_Wide_String;
226 Pad : Wide_Wide_Character := Wide_Wide_Space) return Wide_Wide_String
228 Result : Wide_Wide_String (1 .. Count);
231 if Count <= Source'Length then
232 Result := Source (Source'First .. Source'First + Count - 1);
235 Result (1 .. Source'Length) := Source;
237 for J in Source'Length + 1 .. Count loop
246 (Source : in out Wide_Wide_String;
248 Justify : Alignment := Left;
249 Pad : Wide_Wide_Character := Ada.Strings.Wide_Wide_Space)
252 Move (Source => Head (Source, Count, Pad),
264 (Source : Wide_Wide_String;
266 New_Item : Wide_Wide_String) return Wide_Wide_String
268 Result : Wide_Wide_String (1 .. Source'Length + New_Item'Length);
271 if Before < Source'First or else Before > Source'Last + 1 then
275 Result := Source (Source'First .. Before - 1) & New_Item &
276 Source (Before .. Source'Last);
281 (Source : in out Wide_Wide_String;
283 New_Item : Wide_Wide_String;
284 Drop : Truncation := Error)
287 Move (Source => Insert (Source, Before, New_Item),
297 (Source : Wide_Wide_String;
298 Target : out Wide_Wide_String;
299 Drop : Truncation := Error;
300 Justify : Alignment := Left;
301 Pad : Wide_Wide_Character := Wide_Wide_Space)
303 Sfirst : constant Integer := Source'First;
304 Slast : constant Integer := Source'Last;
305 Slength : constant Integer := Source'Length;
307 Tfirst : constant Integer := Target'First;
308 Tlast : constant Integer := Target'Last;
309 Tlength : constant Integer := Target'Length;
311 function Is_Padding (Item : Wide_Wide_String) return Boolean;
312 -- Determinbe if all characters in Item are pad characters
314 function Is_Padding (Item : Wide_Wide_String) return Boolean is
316 for J in Item'Range loop
317 if Item (J) /= Pad then
325 -- Start of processing for Move
328 if Slength = Tlength then
331 elsif Slength > Tlength then
334 Target := Source (Slast - Tlength + 1 .. Slast);
337 Target := Source (Sfirst .. Sfirst + Tlength - 1);
342 if Is_Padding (Source (Sfirst + Tlength .. Slast)) then
344 Source (Sfirst .. Sfirst + Target'Length - 1);
350 if Is_Padding (Source (Sfirst .. Slast - Tlength)) then
351 Target := Source (Slast - Tlength + 1 .. Slast);
362 -- Source'Length < Target'Length
367 Target (Tfirst .. Tfirst + Slength - 1) := Source;
369 for J in Tfirst + Slength .. Tlast loop
374 for J in Tfirst .. Tlast - Slength loop
378 Target (Tlast - Slength + 1 .. Tlast) := Source;
382 Front_Pad : constant Integer := (Tlength - Slength) / 2;
383 Tfirst_Fpad : constant Integer := Tfirst + Front_Pad;
386 for J in Tfirst .. Tfirst_Fpad - 1 loop
390 Target (Tfirst_Fpad .. Tfirst_Fpad + Slength - 1) := Source;
392 for J in Tfirst_Fpad + Slength .. Tlast loop
405 (Source : Wide_Wide_String;
407 New_Item : Wide_Wide_String) return Wide_Wide_String
410 if Position not in Source'First .. Source'Last + 1 then
414 Result_Length : constant Natural :=
417 Position - Source'First + New_Item'Length);
419 Result : Wide_Wide_String (1 .. Result_Length);
422 Result := Source (Source'First .. Position - 1) & New_Item &
423 Source (Position + New_Item'Length .. Source'Last);
430 (Source : in out Wide_Wide_String;
432 New_Item : Wide_Wide_String;
433 Drop : Truncation := Right)
436 Move (Source => Overwrite (Source, Position, New_Item),
445 function Replace_Slice
446 (Source : Wide_Wide_String;
449 By : Wide_Wide_String) return Wide_Wide_String
452 if Low > Source'Last + 1 or else High < Source'First - 1 then
458 Front_Len : constant Integer :=
459 Integer'Max (0, Low - Source'First);
460 -- Length of prefix of Source copied to result
462 Back_Len : constant Integer :=
463 Integer'Max (0, Source'Last - High);
464 -- Length of suffix of Source copied to result
466 Result_Length : constant Integer :=
467 Front_Len + By'Length + Back_Len;
470 Result : Wide_Wide_String (1 .. Result_Length);
473 Result (1 .. Front_Len) := Source (Source'First .. Low - 1);
474 Result (Front_Len + 1 .. Front_Len + By'Length) := By;
475 Result (Front_Len + By'Length + 1 .. Result'Length) :=
476 Source (High + 1 .. Source'Last);
481 return Insert (Source, Before => Low, New_Item => By);
485 procedure Replace_Slice
486 (Source : in out Wide_Wide_String;
489 By : Wide_Wide_String;
490 Drop : Truncation := Error;
491 Justify : Alignment := Left;
492 Pad : Wide_Wide_Character := Wide_Wide_Space)
495 Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
503 (Source : Wide_Wide_String;
505 Pad : Wide_Wide_Character := Wide_Wide_Space) return Wide_Wide_String
507 Result : Wide_Wide_String (1 .. Count);
510 if Count < Source'Length then
511 Result := Source (Source'Last - Count + 1 .. Source'Last);
516 for J in 1 .. Count - Source'Length loop
520 Result (Count - Source'Length + 1 .. Count) := Source;
527 (Source : in out Wide_Wide_String;
529 Justify : Alignment := Left;
530 Pad : Wide_Wide_Character := Ada.Strings.Wide_Wide_Space)
533 Move (Source => Tail (Source, Count, Pad),
545 (Source : Wide_Wide_String;
546 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping)
547 return Wide_Wide_String
549 Result : Wide_Wide_String (1 .. Source'Length);
552 for J in Source'Range loop
553 Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
560 (Source : in out Wide_Wide_String;
561 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping)
564 for J in Source'Range loop
565 Source (J) := Value (Mapping, Source (J));
570 (Source : Wide_Wide_String;
571 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping_Function)
572 return Wide_Wide_String
574 Result : Wide_Wide_String (1 .. Source'Length);
577 for J in Source'Range loop
578 Result (J - (Source'First - 1)) := Mapping (Source (J));
585 (Source : in out Wide_Wide_String;
586 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping_Function)
589 for J in Source'Range loop
590 Source (J) := Mapping (Source (J));
599 (Source : Wide_Wide_String;
600 Side : Trim_End) return Wide_Wide_String
602 Low : Natural := Source'First;
603 High : Natural := Source'Last;
606 if Side = Left or else Side = Both then
607 while Low <= High and then Source (Low) = Wide_Wide_Space loop
612 if Side = Right or else Side = Both then
613 while High >= Low and then Source (High) = Wide_Wide_Space loop
623 -- At least one non-blank
627 Result : constant Wide_Wide_String (1 .. High - Low + 1) :=
628 Source (Low .. High);
637 (Source : in out Wide_Wide_String;
639 Justify : Alignment := Left;
640 Pad : Wide_Wide_Character := Wide_Wide_Space)
643 Move (Source => Trim (Source, Side),
650 (Source : Wide_Wide_String;
651 Left : Wide_Wide_Maps.Wide_Wide_Character_Set;
652 Right : Wide_Wide_Maps.Wide_Wide_Character_Set) return Wide_Wide_String
654 Low : Natural := Source'First;
655 High : Natural := Source'Last;
658 while Low <= High and then Is_In (Source (Low), Left) loop
662 while High >= Low and then Is_In (Source (High), Right) loop
666 -- Case where source comprises only characters in the sets
672 subtype WS is Wide_Wide_String (1 .. High - Low + 1);
675 return WS (Source (Low .. High));
681 (Source : in out Wide_Wide_String;
682 Left : Wide_Wide_Maps.Wide_Wide_Character_Set;
683 Right : Wide_Wide_Maps.Wide_Wide_Character_Set;
684 Justify : Alignment := Strings.Left;
685 Pad : Wide_Wide_Character := Wide_Wide_Space)
688 Move (Source => Trim (Source, Left, Right),
694 end Ada.Strings.Wide_Wide_Fixed;