]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/a-stwifi.adb
Licensing changes to GPLv3 resp. GPLv3 with GCC Runtime Exception.
[thirdparty/gcc.git] / gcc / ada / a-stwifi.adb
CommitLineData
d23b8f57
RK
1------------------------------------------------------------------------------
2-- --
3084fecd 3-- GNAT RUN-TIME COMPONENTS --
d23b8f57
RK
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-- --
748086b7 9-- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
d23b8f57
RK
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- --
748086b7 13-- ware Foundation; either version 3, or (at your option) any later ver- --
d23b8f57
RK
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 --
748086b7
JJ
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/>. --
d23b8f57
RK
26-- --
27-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 28-- Extensive contributions were provided by Ada Core Technologies Inc. --
d23b8f57
RK
29-- --
30------------------------------------------------------------------------------
31
9de61fcb 32with Ada.Strings.Wide_Maps; use Ada.Strings.Wide_Maps;
d23b8f57
RK
33with Ada.Strings.Wide_Search;
34
35package body Ada.Strings.Wide_Fixed is
36
37 ------------------------
38 -- Search Subprograms --
39 ------------------------
40
41 function Index
4e45e7a9
RD
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
d23b8f57
RK
47 renames Ada.Strings.Wide_Search.Index;
48
49 function Index
4e45e7a9
RD
50 (Source : Wide_String;
51 Pattern : Wide_String;
52 Going : Direction := Forward;
53 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
d23b8f57
RK
54 renames Ada.Strings.Wide_Search.Index;
55
56 function Index
4e45e7a9
RD
57 (Source : Wide_String;
58 Set : Wide_Maps.Wide_Character_Set;
59 Test : Membership := Inside;
60 Going : Direction := Forward) return Natural
d23b8f57
RK
61 renames Ada.Strings.Wide_Search.Index;
62
4e45e7a9
RD
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;
71
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;
79
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;
87
88 function Index_Non_Blank
89 (Source : Wide_String;
90 Going : Direction := Forward) return Natural
91 renames Ada.Strings.Wide_Search.Index_Non_Blank;
92
d23b8f57 93 function Index_Non_Blank
4e45e7a9
RD
94 (Source : Wide_String;
95 From : Positive;
96 Going : Direction := Forward) return Natural
d23b8f57
RK
97 renames Ada.Strings.Wide_Search.Index_Non_Blank;
98
99 function Count
4e45e7a9
RD
100 (Source : Wide_String;
101 Pattern : Wide_String;
102 Mapping : Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
103 return Natural
d23b8f57
RK
104 renames Ada.Strings.Wide_Search.Count;
105
106 function Count
4e45e7a9
RD
107 (Source : Wide_String;
108 Pattern : Wide_String;
109 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Natural
d23b8f57
RK
110 renames Ada.Strings.Wide_Search.Count;
111
112 function Count
4e45e7a9
RD
113 (Source : Wide_String;
114 Set : Wide_Maps.Wide_Character_Set) return Natural
d23b8f57
RK
115 renames Ada.Strings.Wide_Search.Count;
116
117 procedure Find_Token
4e45e7a9
RD
118 (Source : Wide_String;
119 Set : Wide_Maps.Wide_Character_Set;
120 Test : Membership;
d23b8f57
RK
121 First : out Positive;
122 Last : out Natural)
123 renames Ada.Strings.Wide_Search.Find_Token;
124
125 ---------
126 -- "*" --
127 ---------
128
129 function "*"
4e45e7a9
RD
130 (Left : Natural;
131 Right : Wide_Character) return Wide_String
d23b8f57
RK
132 is
133 Result : Wide_String (1 .. Left);
134
135 begin
136 for J in Result'Range loop
137 Result (J) := Right;
138 end loop;
139
140 return Result;
141 end "*";
142
143 function "*"
4e45e7a9
RD
144 (Left : Natural;
145 Right : Wide_String) return Wide_String
d23b8f57
RK
146 is
147 Result : Wide_String (1 .. Left * Right'Length);
148 Ptr : Integer := 1;
149
150 begin
151 for J in 1 .. Left loop
152 Result (Ptr .. Ptr + Right'Length - 1) := Right;
153 Ptr := Ptr + Right'Length;
154 end loop;
155
156 return Result;
157 end "*";
158
159 ------------
160 -- Delete --
161 ------------
162
163 function Delete
4e45e7a9
RD
164 (Source : Wide_String;
165 From : Positive;
166 Through : Natural) return Wide_String
d23b8f57
RK
167 is
168 begin
169 if From not in Source'Range
170 or else Through > Source'Last
171 then
172 raise Index_Error;
173
174 elsif From > Through then
175 return Source;
176
177 else
178 declare
07fc65c4
GB
179 Len : constant Integer := Source'Length - (Through - From + 1);
180 Result : constant
181 Wide_String (Source'First .. Source'First + Len - 1) :=
182 Source (Source'First .. From - 1) &
183 Source (Through + 1 .. Source'Last);
d23b8f57
RK
184 begin
185 return Result;
186 end;
187 end if;
188 end Delete;
189
190 procedure Delete
191 (Source : in out Wide_String;
4e45e7a9
RD
192 From : Positive;
193 Through : Natural;
194 Justify : Alignment := Left;
195 Pad : Wide_Character := Wide_Space)
d23b8f57
RK
196 is
197 begin
198 Move (Source => Delete (Source, From, Through),
199 Target => Source,
200 Justify => Justify,
201 Pad => Pad);
202 end Delete;
203
204 ----------
205 -- Head --
206 ----------
207
208 function Head
4e45e7a9
RD
209 (Source : Wide_String;
210 Count : Natural;
211 Pad : Wide_Character := Wide_Space) return Wide_String
d23b8f57
RK
212 is
213 Result : Wide_String (1 .. Count);
214
215 begin
216 if Count <= Source'Length then
217 Result := Source (Source'First .. Source'First + Count - 1);
218
219 else
220 Result (1 .. Source'Length) := Source;
221
222 for J in Source'Length + 1 .. Count loop
223 Result (J) := Pad;
224 end loop;
225 end if;
226
227 return Result;
228 end Head;
229
230 procedure Head
231 (Source : in out Wide_String;
4e45e7a9
RD
232 Count : Natural;
233 Justify : Alignment := Left;
234 Pad : Wide_Character := Ada.Strings.Wide_Space)
d23b8f57
RK
235 is
236 begin
237 Move (Source => Head (Source, Count, Pad),
238 Target => Source,
239 Drop => Error,
240 Justify => Justify,
241 Pad => Pad);
242 end Head;
243
244 ------------
245 -- Insert --
246 ------------
247
248 function Insert
4e45e7a9
RD
249 (Source : Wide_String;
250 Before : Positive;
251 New_Item : Wide_String) return Wide_String
d23b8f57
RK
252 is
253 Result : Wide_String (1 .. Source'Length + New_Item'Length);
254
255 begin
256 if Before < Source'First or else Before > Source'Last + 1 then
257 raise Index_Error;
258 end if;
259
260 Result := Source (Source'First .. Before - 1) & New_Item &
261 Source (Before .. Source'Last);
262 return Result;
263 end Insert;
264
265 procedure Insert
266 (Source : in out Wide_String;
4e45e7a9
RD
267 Before : Positive;
268 New_Item : Wide_String;
269 Drop : Truncation := Error)
d23b8f57
RK
270 is
271 begin
272 Move (Source => Insert (Source, Before, New_Item),
273 Target => Source,
274 Drop => Drop);
275 end Insert;
276
277 ----------
278 -- Move --
279 ----------
280
281 procedure Move
4e45e7a9 282 (Source : Wide_String;
d23b8f57 283 Target : out Wide_String;
4e45e7a9
RD
284 Drop : Truncation := Error;
285 Justify : Alignment := Left;
286 Pad : Wide_Character := Wide_Space)
d23b8f57
RK
287 is
288 Sfirst : constant Integer := Source'First;
289 Slast : constant Integer := Source'Last;
290 Slength : constant Integer := Source'Length;
291
292 Tfirst : constant Integer := Target'First;
293 Tlast : constant Integer := Target'Last;
294 Tlength : constant Integer := Target'Length;
295
296 function Is_Padding (Item : Wide_String) return Boolean;
9de61fcb
RD
297 -- Determine if all characters in Item are pad characters
298
299 ----------------
300 -- Is_Padding --
301 ----------------
d23b8f57
RK
302
303 function Is_Padding (Item : Wide_String) return Boolean is
304 begin
305 for J in Item'Range loop
306 if Item (J) /= Pad then
307 return False;
308 end if;
309 end loop;
310
311 return True;
312 end Is_Padding;
313
314 -- Start of processing for Move
315
316 begin
317 if Slength = Tlength then
318 Target := Source;
319
320 elsif Slength > Tlength then
321
322 case Drop is
323 when Left =>
324 Target := Source (Slast - Tlength + 1 .. Slast);
325
326 when Right =>
327 Target := Source (Sfirst .. Sfirst + Tlength - 1);
328
329 when Error =>
330 case Justify is
331 when Left =>
332 if Is_Padding (Source (Sfirst + Tlength .. Slast)) then
333 Target :=
334 Source (Sfirst .. Sfirst + Target'Length - 1);
335 else
336 raise Length_Error;
337 end if;
338
339 when Right =>
340 if Is_Padding (Source (Sfirst .. Slast - Tlength)) then
341 Target := Source (Slast - Tlength + 1 .. Slast);
342 else
343 raise Length_Error;
344 end if;
345
346 when Center =>
347 raise Length_Error;
348 end case;
349
350 end case;
351
352 -- Source'Length < Target'Length
353
354 else
355 case Justify is
356 when Left =>
357 Target (Tfirst .. Tfirst + Slength - 1) := Source;
358
359 for J in Tfirst + Slength .. Tlast loop
360 Target (J) := Pad;
361 end loop;
362
363 when Right =>
364 for J in Tfirst .. Tlast - Slength loop
365 Target (J) := Pad;
366 end loop;
367
368 Target (Tlast - Slength + 1 .. Tlast) := Source;
369
370 when Center =>
371 declare
372 Front_Pad : constant Integer := (Tlength - Slength) / 2;
373 Tfirst_Fpad : constant Integer := Tfirst + Front_Pad;
374
375 begin
376 for J in Tfirst .. Tfirst_Fpad - 1 loop
377 Target (J) := Pad;
378 end loop;
379
380 Target (Tfirst_Fpad .. Tfirst_Fpad + Slength - 1) := Source;
381
382 for J in Tfirst_Fpad + Slength .. Tlast loop
383 Target (J) := Pad;
384 end loop;
385 end;
386 end case;
387 end if;
388 end Move;
389
390 ---------------
391 -- Overwrite --
392 ---------------
393
394 function Overwrite
4e45e7a9
RD
395 (Source : Wide_String;
396 Position : Positive;
397 New_Item : Wide_String) return Wide_String
d23b8f57
RK
398 is
399 begin
400 if Position not in Source'First .. Source'Last + 1 then
401 raise Index_Error;
402 else
403 declare
fbf5a39b 404 Result_Length : constant Natural :=
07fc65c4
GB
405 Natural'Max
406 (Source'Length,
407 Position - Source'First + New_Item'Length);
408
d23b8f57
RK
409 Result : Wide_String (1 .. Result_Length);
410
411 begin
412 Result := Source (Source'First .. Position - 1) & New_Item &
07fc65c4 413 Source (Position + New_Item'Length .. Source'Last);
d23b8f57
RK
414 return Result;
415 end;
416 end if;
417 end Overwrite;
418
419 procedure Overwrite
420 (Source : in out Wide_String;
4e45e7a9
RD
421 Position : Positive;
422 New_Item : Wide_String;
423 Drop : Truncation := Right)
d23b8f57
RK
424 is
425 begin
426 Move (Source => Overwrite (Source, Position, New_Item),
427 Target => Source,
428 Drop => Drop);
429 end Overwrite;
430
431 -------------------
432 -- Replace_Slice --
433 -------------------
434
435 function Replace_Slice
4e45e7a9
RD
436 (Source : Wide_String;
437 Low : Positive;
438 High : Natural;
439 By : Wide_String) return Wide_String
d23b8f57
RK
440 is
441 Result_Length : Natural;
442
443 begin
444 if Low > Source'Last + 1 or else High < Source'First - 1 then
445 raise Index_Error;
446 else
447 Result_Length :=
448 Source'Length - Natural'Max (High - Low + 1, 0) + By'Length;
449
450 declare
451 Result : Wide_String (1 .. Result_Length);
452
453 begin
454 if High >= Low then
455 Result :=
456 Source (Source'First .. Low - 1) & By &
457 Source (High + 1 .. Source'Last);
458 else
459 Result := Source (Source'First .. Low - 1) & By &
460 Source (Low .. Source'Last);
461 end if;
462
463 return Result;
464 end;
465 end if;
466 end Replace_Slice;
467
468 procedure Replace_Slice
469 (Source : in out Wide_String;
4e45e7a9
RD
470 Low : Positive;
471 High : Natural;
472 By : Wide_String;
473 Drop : Truncation := Error;
474 Justify : Alignment := Left;
475 Pad : Wide_Character := Wide_Space)
d23b8f57
RK
476 is
477 begin
478 Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
479 end Replace_Slice;
480
481 ----------
482 -- Tail --
483 ----------
484
485 function Tail
4e45e7a9
RD
486 (Source : Wide_String;
487 Count : Natural;
488 Pad : Wide_Character := Wide_Space) return Wide_String
d23b8f57
RK
489 is
490 Result : Wide_String (1 .. Count);
491
492 begin
493 if Count < Source'Length then
494 Result := Source (Source'Last - Count + 1 .. Source'Last);
495
496 -- Pad on left
497
498 else
499 for J in 1 .. Count - Source'Length loop
500 Result (J) := Pad;
501 end loop;
502
503 Result (Count - Source'Length + 1 .. Count) := Source;
504 end if;
505
506 return Result;
507 end Tail;
508
509 procedure Tail
510 (Source : in out Wide_String;
4e45e7a9
RD
511 Count : Natural;
512 Justify : Alignment := Left;
513 Pad : Wide_Character := Ada.Strings.Wide_Space)
d23b8f57
RK
514 is
515 begin
516 Move (Source => Tail (Source, Count, Pad),
517 Target => Source,
518 Drop => Error,
519 Justify => Justify,
520 Pad => Pad);
521 end Tail;
522
523 ---------------
524 -- Translate --
525 ---------------
526
527 function Translate
4e45e7a9
RD
528 (Source : Wide_String;
529 Mapping : Wide_Maps.Wide_Character_Mapping) return Wide_String
d23b8f57
RK
530 is
531 Result : Wide_String (1 .. Source'Length);
532
533 begin
534 for J in Source'Range loop
535 Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
536 end loop;
537
538 return Result;
539 end Translate;
540
541 procedure Translate
542 (Source : in out Wide_String;
4e45e7a9 543 Mapping : Wide_Maps.Wide_Character_Mapping)
d23b8f57
RK
544 is
545 begin
546 for J in Source'Range loop
547 Source (J) := Value (Mapping, Source (J));
548 end loop;
549 end Translate;
550
551 function Translate
4e45e7a9
RD
552 (Source : Wide_String;
553 Mapping : Wide_Maps.Wide_Character_Mapping_Function) return Wide_String
d23b8f57
RK
554 is
555 Result : Wide_String (1 .. Source'Length);
556
557 begin
558 for J in Source'Range loop
559 Result (J - (Source'First - 1)) := Mapping (Source (J));
560 end loop;
561
562 return Result;
563 end Translate;
564
565 procedure Translate
566 (Source : in out Wide_String;
4e45e7a9 567 Mapping : Wide_Maps.Wide_Character_Mapping_Function)
d23b8f57
RK
568 is
569 begin
570 for J in Source'Range loop
571 Source (J) := Mapping (Source (J));
572 end loop;
573 end Translate;
574
575 ----------
576 -- Trim --
577 ----------
578
579 function Trim
4e45e7a9
RD
580 (Source : Wide_String;
581 Side : Trim_End) return Wide_String
d23b8f57
RK
582 is
583 Low : Natural := Source'First;
584 High : Natural := Source'Last;
585
586 begin
587 if Side = Left or else Side = Both then
588 while Low <= High and then Source (Low) = Wide_Space loop
589 Low := Low + 1;
590 end loop;
591 end if;
592
593 if Side = Right or else Side = Both then
594 while High >= Low and then Source (High) = Wide_Space loop
595 High := High - 1;
596 end loop;
597 end if;
598
599 -- All blanks case
600
601 if Low > High then
602 return "";
603
604 -- At least one non-blank
605
606 else
607 declare
fbf5a39b
AC
608 Result : constant Wide_String (1 .. High - Low + 1) :=
609 Source (Low .. High);
d23b8f57
RK
610
611 begin
612 return Result;
613 end;
614 end if;
615 end Trim;
616
617 procedure Trim
618 (Source : in out Wide_String;
4e45e7a9
RD
619 Side : Trim_End;
620 Justify : Alignment := Left;
621 Pad : Wide_Character := Wide_Space)
d23b8f57
RK
622 is
623 begin
624 Move (Source => Trim (Source, Side),
625 Target => Source,
626 Justify => Justify,
627 Pad => Pad);
628 end Trim;
629
630 function Trim
4e45e7a9
RD
631 (Source : Wide_String;
632 Left : Wide_Maps.Wide_Character_Set;
633 Right : Wide_Maps.Wide_Character_Set) return Wide_String
d23b8f57
RK
634 is
635 Low : Natural := Source'First;
636 High : Natural := Source'Last;
637
638 begin
639 while Low <= High and then Is_In (Source (Low), Left) loop
640 Low := Low + 1;
641 end loop;
642
643 while High >= Low and then Is_In (Source (High), Right) loop
644 High := High - 1;
645 end loop;
646
647 -- Case where source comprises only characters in the sets
648
649 if Low > High then
650 return "";
651 else
652 declare
653 subtype WS is Wide_String (1 .. High - Low + 1);
654
655 begin
656 return WS (Source (Low .. High));
657 end;
658 end if;
659 end Trim;
660
661 procedure Trim
662 (Source : in out Wide_String;
4e45e7a9
RD
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)
d23b8f57
RK
667 is
668 begin
669 Move (Source => Trim (Source, Left, Right),
670 Target => Source,
671 Justify => Justify,
672 Pad => Pad);
673 end Trim;
674
675end Ada.Strings.Wide_Fixed;