2014-10-10 Robert Dewar <dewar@adacore.com>
[official-gcc.git] / gcc / ada / a-stwifi.adb
blobdfe961995da75316a581a5dc00e1856e6ed6c21a
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- A D A . S T R I N G S . W I D E _ F I X E D --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
10 -- --
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. --
17 -- --
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. --
21 -- --
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/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
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 ------------------------
41 function Index
42 (Source : Wide_String;
43 Pattern : Wide_String;
44 Going : Direction := Forward;
45 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
46 return Natural
47 renames Ada.Strings.Wide_Search.Index;
49 function 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;
56 function 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;
63 function Index
64 (Source : Wide_String;
65 Pattern : Wide_String;
66 From : Positive;
67 Going : Direction := Forward;
68 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
69 return Natural
70 renames Ada.Strings.Wide_Search.Index;
72 function Index
73 (Source : Wide_String;
74 Pattern : Wide_String;
75 From : Positive;
76 Going : Direction := Forward;
77 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
78 renames Ada.Strings.Wide_Search.Index;
80 function Index
81 (Source : Wide_String;
82 Set : Wide_Maps.Wide_Character_Set;
83 From : Positive;
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;
95 From : Positive;
96 Going : Direction := Forward) return Natural
97 renames Ada.Strings.Wide_Search.Index_Non_Blank;
99 function Count
100 (Source : Wide_String;
101 Pattern : Wide_String;
102 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
103 return Natural
104 renames Ada.Strings.Wide_Search.Count;
106 function 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;
112 function Count
113 (Source : Wide_String;
114 Set : Wide_Maps.Wide_Character_Set) return Natural
115 renames Ada.Strings.Wide_Search.Count;
117 procedure Find_Token
118 (Source : Wide_String;
119 Set : Wide_Maps.Wide_Character_Set;
120 From : Positive;
121 Test : Membership;
122 First : out Positive;
123 Last : out Natural)
124 renames Ada.Strings.Wide_Search.Find_Token;
126 procedure Find_Token
127 (Source : Wide_String;
128 Set : Wide_Maps.Wide_Character_Set;
129 Test : Membership;
130 First : out Positive;
131 Last : out Natural)
132 renames Ada.Strings.Wide_Search.Find_Token;
134 ---------
135 -- "*" --
136 ---------
138 function "*"
139 (Left : Natural;
140 Right : Wide_Character) return Wide_String
142 Result : Wide_String (1 .. Left);
144 begin
145 for J in Result'Range loop
146 Result (J) := Right;
147 end loop;
149 return Result;
150 end "*";
152 function "*"
153 (Left : Natural;
154 Right : Wide_String) return Wide_String
156 Result : Wide_String (1 .. Left * Right'Length);
157 Ptr : Integer := 1;
159 begin
160 for J in 1 .. Left loop
161 Result (Ptr .. Ptr + Right'Length - 1) := Right;
162 Ptr := Ptr + Right'Length;
163 end loop;
165 return Result;
166 end "*";
168 ------------
169 -- Delete --
170 ------------
172 function Delete
173 (Source : Wide_String;
174 From : Positive;
175 Through : Natural) return Wide_String
177 begin
178 if From not in Source'Range
179 or else Through > Source'Last
180 then
181 raise Index_Error;
183 elsif From > Through then
184 return Source;
186 else
187 declare
188 Len : constant Integer := Source'Length - (Through - From + 1);
189 Result : constant
190 Wide_String (Source'First .. Source'First + Len - 1) :=
191 Source (Source'First .. From - 1) &
192 Source (Through + 1 .. Source'Last);
193 begin
194 return Result;
195 end;
196 end if;
197 end Delete;
199 procedure Delete
200 (Source : in out Wide_String;
201 From : Positive;
202 Through : Natural;
203 Justify : Alignment := Left;
204 Pad : Wide_Character := Wide_Space)
206 begin
207 Move (Source => Delete (Source, From, Through),
208 Target => Source,
209 Justify => Justify,
210 Pad => Pad);
211 end Delete;
213 ----------
214 -- Head --
215 ----------
217 function Head
218 (Source : Wide_String;
219 Count : Natural;
220 Pad : Wide_Character := Wide_Space) return Wide_String
222 Result : Wide_String (1 .. Count);
224 begin
225 if Count <= Source'Length then
226 Result := Source (Source'First .. Source'First + Count - 1);
228 else
229 Result (1 .. Source'Length) := Source;
231 for J in Source'Length + 1 .. Count loop
232 Result (J) := Pad;
233 end loop;
234 end if;
236 return Result;
237 end Head;
239 procedure Head
240 (Source : in out Wide_String;
241 Count : Natural;
242 Justify : Alignment := Left;
243 Pad : Wide_Character := Ada.Strings.Wide_Space)
245 begin
246 Move (Source => Head (Source, Count, Pad),
247 Target => Source,
248 Drop => Error,
249 Justify => Justify,
250 Pad => Pad);
251 end Head;
253 ------------
254 -- Insert --
255 ------------
257 function Insert
258 (Source : Wide_String;
259 Before : Positive;
260 New_Item : Wide_String) return Wide_String
262 Result : Wide_String (1 .. Source'Length + New_Item'Length);
264 begin
265 if Before < Source'First or else Before > Source'Last + 1 then
266 raise Index_Error;
267 end if;
269 Result := Source (Source'First .. Before - 1) & New_Item &
270 Source (Before .. Source'Last);
271 return Result;
272 end Insert;
274 procedure Insert
275 (Source : in out Wide_String;
276 Before : Positive;
277 New_Item : Wide_String;
278 Drop : Truncation := Error)
280 begin
281 Move (Source => Insert (Source, Before, New_Item),
282 Target => Source,
283 Drop => Drop);
284 end Insert;
286 ----------
287 -- Move --
288 ----------
290 procedure Move
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
308 ----------------
309 -- Is_Padding --
310 ----------------
312 function Is_Padding (Item : Wide_String) return Boolean is
313 begin
314 for J in Item'Range loop
315 if Item (J) /= Pad then
316 return False;
317 end if;
318 end loop;
320 return True;
321 end Is_Padding;
323 -- Start of processing for Move
325 begin
326 if Slength = Tlength then
327 Target := Source;
329 elsif Slength > Tlength then
331 case Drop is
332 when Left =>
333 Target := Source (Slast - Tlength + 1 .. Slast);
335 when Right =>
336 Target := Source (Sfirst .. Sfirst + Tlength - 1);
338 when Error =>
339 case Justify is
340 when Left =>
341 if Is_Padding (Source (Sfirst + Tlength .. Slast)) then
342 Target :=
343 Source (Sfirst .. Sfirst + Target'Length - 1);
344 else
345 raise Length_Error;
346 end if;
348 when Right =>
349 if Is_Padding (Source (Sfirst .. Slast - Tlength)) then
350 Target := Source (Slast - Tlength + 1 .. Slast);
351 else
352 raise Length_Error;
353 end if;
355 when Center =>
356 raise Length_Error;
357 end case;
359 end case;
361 -- Source'Length < Target'Length
363 else
364 case Justify is
365 when Left =>
366 Target (Tfirst .. Tfirst + Slength - 1) := Source;
368 for J in Tfirst + Slength .. Tlast loop
369 Target (J) := Pad;
370 end loop;
372 when Right =>
373 for J in Tfirst .. Tlast - Slength loop
374 Target (J) := Pad;
375 end loop;
377 Target (Tlast - Slength + 1 .. Tlast) := Source;
379 when Center =>
380 declare
381 Front_Pad : constant Integer := (Tlength - Slength) / 2;
382 Tfirst_Fpad : constant Integer := Tfirst + Front_Pad;
384 begin
385 for J in Tfirst .. Tfirst_Fpad - 1 loop
386 Target (J) := Pad;
387 end loop;
389 Target (Tfirst_Fpad .. Tfirst_Fpad + Slength - 1) := Source;
391 for J in Tfirst_Fpad + Slength .. Tlast loop
392 Target (J) := Pad;
393 end loop;
394 end;
395 end case;
396 end if;
397 end Move;
399 ---------------
400 -- Overwrite --
401 ---------------
403 function Overwrite
404 (Source : Wide_String;
405 Position : Positive;
406 New_Item : Wide_String) return Wide_String
408 begin
409 if Position not in Source'First .. Source'Last + 1 then
410 raise Index_Error;
411 else
412 declare
413 Result_Length : constant Natural :=
414 Natural'Max
415 (Source'Length,
416 Position - Source'First + New_Item'Length);
418 Result : Wide_String (1 .. Result_Length);
420 begin
421 Result := Source (Source'First .. Position - 1) & New_Item &
422 Source (Position + New_Item'Length .. Source'Last);
423 return Result;
424 end;
425 end if;
426 end Overwrite;
428 procedure Overwrite
429 (Source : in out Wide_String;
430 Position : Positive;
431 New_Item : Wide_String;
432 Drop : Truncation := Right)
434 begin
435 Move (Source => Overwrite (Source, Position, New_Item),
436 Target => Source,
437 Drop => Drop);
438 end Overwrite;
440 -------------------
441 -- Replace_Slice --
442 -------------------
444 function Replace_Slice
445 (Source : Wide_String;
446 Low : Positive;
447 High : Natural;
448 By : Wide_String) return Wide_String
450 begin
451 if Low > Source'Last + 1 or else High < Source'First - 1 then
452 raise Index_Error;
453 end if;
455 if High >= Low then
456 declare
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 := Integer'Max (0, Source'Last - High);
462 -- Length of suffix of Source copied to result
464 Result_Length : constant Integer :=
465 Front_Len + By'Length + Back_Len;
466 -- Length of result
468 Result : Wide_String (1 .. Result_Length);
470 begin
471 Result (1 .. Front_Len) := Source (Source'First .. Low - 1);
472 Result (Front_Len + 1 .. Front_Len + By'Length) := By;
473 Result (Front_Len + By'Length + 1 .. Result'Length) :=
474 Source (High + 1 .. Source'Last);
475 return Result;
476 end;
478 else
479 return Insert (Source, Before => Low, New_Item => By);
480 end if;
481 end Replace_Slice;
483 procedure Replace_Slice
484 (Source : in out Wide_String;
485 Low : Positive;
486 High : Natural;
487 By : Wide_String;
488 Drop : Truncation := Error;
489 Justify : Alignment := Left;
490 Pad : Wide_Character := Wide_Space)
492 begin
493 Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
494 end Replace_Slice;
496 ----------
497 -- Tail --
498 ----------
500 function Tail
501 (Source : Wide_String;
502 Count : Natural;
503 Pad : Wide_Character := Wide_Space) return Wide_String
505 Result : Wide_String (1 .. Count);
507 begin
508 if Count < Source'Length then
509 Result := Source (Source'Last - Count + 1 .. Source'Last);
511 -- Pad on left
513 else
514 for J in 1 .. Count - Source'Length loop
515 Result (J) := Pad;
516 end loop;
518 Result (Count - Source'Length + 1 .. Count) := Source;
519 end if;
521 return Result;
522 end Tail;
524 procedure Tail
525 (Source : in out Wide_String;
526 Count : Natural;
527 Justify : Alignment := Left;
528 Pad : Wide_Character := Ada.Strings.Wide_Space)
530 begin
531 Move (Source => Tail (Source, Count, Pad),
532 Target => Source,
533 Drop => Error,
534 Justify => Justify,
535 Pad => Pad);
536 end Tail;
538 ---------------
539 -- Translate --
540 ---------------
542 function Translate
543 (Source : Wide_String;
544 Mapping : Wide_Maps.Wide_Character_Mapping) return Wide_String
546 Result : Wide_String (1 .. Source'Length);
548 begin
549 for J in Source'Range loop
550 Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
551 end loop;
553 return Result;
554 end Translate;
556 procedure Translate
557 (Source : in out Wide_String;
558 Mapping : Wide_Maps.Wide_Character_Mapping)
560 begin
561 for J in Source'Range loop
562 Source (J) := Value (Mapping, Source (J));
563 end loop;
564 end Translate;
566 function Translate
567 (Source : Wide_String;
568 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Wide_String
570 Result : Wide_String (1 .. Source'Length);
572 begin
573 for J in Source'Range loop
574 Result (J - (Source'First - 1)) := Mapping (Source (J));
575 end loop;
577 return Result;
578 end Translate;
580 procedure Translate
581 (Source : in out Wide_String;
582 Mapping : Wide_Maps.Wide_Character_Mapping_Function)
584 begin
585 for J in Source'Range loop
586 Source (J) := Mapping (Source (J));
587 end loop;
588 end Translate;
590 ----------
591 -- Trim --
592 ----------
594 function Trim
595 (Source : Wide_String;
596 Side : Trim_End) return Wide_String
598 Low : Natural := Source'First;
599 High : Natural := Source'Last;
601 begin
602 if Side = Left or else Side = Both then
603 while Low <= High and then Source (Low) = Wide_Space loop
604 Low := Low + 1;
605 end loop;
606 end if;
608 if Side = Right or else Side = Both then
609 while High >= Low and then Source (High) = Wide_Space loop
610 High := High - 1;
611 end loop;
612 end if;
614 -- All blanks case
616 if Low > High then
617 return "";
619 -- At least one non-blank
621 else
622 declare
623 Result : constant Wide_String (1 .. High - Low + 1) :=
624 Source (Low .. High);
626 begin
627 return Result;
628 end;
629 end if;
630 end Trim;
632 procedure Trim
633 (Source : in out Wide_String;
634 Side : Trim_End;
635 Justify : Alignment := Left;
636 Pad : Wide_Character := Wide_Space)
638 begin
639 Move (Source => Trim (Source, Side),
640 Target => Source,
641 Justify => Justify,
642 Pad => Pad);
643 end Trim;
645 function Trim
646 (Source : Wide_String;
647 Left : Wide_Maps.Wide_Character_Set;
648 Right : Wide_Maps.Wide_Character_Set) return Wide_String
650 Low : Natural := Source'First;
651 High : Natural := Source'Last;
653 begin
654 while Low <= High and then Is_In (Source (Low), Left) loop
655 Low := Low + 1;
656 end loop;
658 while High >= Low and then Is_In (Source (High), Right) loop
659 High := High - 1;
660 end loop;
662 -- Case where source comprises only characters in the sets
664 if Low > High then
665 return "";
666 else
667 declare
668 subtype WS is Wide_String (1 .. High - Low + 1);
670 begin
671 return WS (Source (Low .. High));
672 end;
673 end if;
674 end Trim;
676 procedure Trim
677 (Source : in out Wide_String;
678 Left : Wide_Maps.Wide_Character_Set;
679 Right : Wide_Maps.Wide_Character_Set;
680 Justify : Alignment := Strings.Left;
681 Pad : Wide_Character := Wide_Space)
683 begin
684 Move (Source => Trim (Source, Left, Right),
685 Target => Source,
686 Justify => Justify,
687 Pad => Pad);
688 end Trim;
690 end Ada.Strings.Wide_Fixed;