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