2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / ada / a-stwifi.adb
blob100fb8019e650c47e86a5b701a0dcc8adab91378
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUNTIME 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-2002 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 2, 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. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
28 -- --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 with Ada.Strings.Wide_Maps; use Ada.Strings.Wide_Maps;
35 with Ada.Strings.Wide_Search;
37 package body Ada.Strings.Wide_Fixed is
39 ------------------------
40 -- Search Subprograms --
41 ------------------------
43 function Index
44 (Source : in Wide_String;
45 Pattern : in Wide_String;
46 Going : in Direction := Forward;
47 Mapping : in Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
48 return Natural
49 renames Ada.Strings.Wide_Search.Index;
51 function Index
52 (Source : in Wide_String;
53 Pattern : in Wide_String;
54 Going : in Direction := Forward;
55 Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
56 return Natural
57 renames Ada.Strings.Wide_Search.Index;
59 function Index
60 (Source : in Wide_String;
61 Set : in Wide_Maps.Wide_Character_Set;
62 Test : in Membership := Inside;
63 Going : in Direction := Forward)
64 return Natural
65 renames Ada.Strings.Wide_Search.Index;
67 function Index_Non_Blank
68 (Source : in Wide_String;
69 Going : in Direction := Forward)
70 return Natural
71 renames Ada.Strings.Wide_Search.Index_Non_Blank;
73 function Count
74 (Source : in Wide_String;
75 Pattern : in Wide_String;
76 Mapping : in Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
77 return Natural
78 renames Ada.Strings.Wide_Search.Count;
80 function Count
81 (Source : in Wide_String;
82 Pattern : in Wide_String;
83 Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
84 return Natural
85 renames Ada.Strings.Wide_Search.Count;
87 function Count
88 (Source : in Wide_String;
89 Set : in Wide_Maps.Wide_Character_Set)
90 return Natural
91 renames Ada.Strings.Wide_Search.Count;
93 procedure Find_Token
94 (Source : in Wide_String;
95 Set : in Wide_Maps.Wide_Character_Set;
96 Test : in Membership;
97 First : out Positive;
98 Last : out Natural)
99 renames Ada.Strings.Wide_Search.Find_Token;
101 ---------
102 -- "*" --
103 ---------
105 function "*"
106 (Left : in Natural;
107 Right : in Wide_Character)
108 return Wide_String
110 Result : Wide_String (1 .. Left);
112 begin
113 for J in Result'Range loop
114 Result (J) := Right;
115 end loop;
117 return Result;
118 end "*";
120 function "*"
121 (Left : in Natural;
122 Right : in Wide_String)
123 return Wide_String
125 Result : Wide_String (1 .. Left * Right'Length);
126 Ptr : Integer := 1;
128 begin
129 for J in 1 .. Left loop
130 Result (Ptr .. Ptr + Right'Length - 1) := Right;
131 Ptr := Ptr + Right'Length;
132 end loop;
134 return Result;
135 end "*";
137 ------------
138 -- Delete --
139 ------------
141 function Delete
142 (Source : in Wide_String;
143 From : in Positive;
144 Through : in Natural)
145 return Wide_String
147 begin
148 if From not in Source'Range
149 or else Through > Source'Last
150 then
151 raise Index_Error;
153 elsif From > Through then
154 return Source;
156 else
157 declare
158 Len : constant Integer := Source'Length - (Through - From + 1);
159 Result : constant
160 Wide_String (Source'First .. Source'First + Len - 1) :=
161 Source (Source'First .. From - 1) &
162 Source (Through + 1 .. Source'Last);
163 begin
164 return Result;
165 end;
166 end if;
167 end Delete;
169 procedure Delete
170 (Source : in out Wide_String;
171 From : in Positive;
172 Through : in Natural;
173 Justify : in Alignment := Left;
174 Pad : in Wide_Character := Wide_Space)
176 begin
177 Move (Source => Delete (Source, From, Through),
178 Target => Source,
179 Justify => Justify,
180 Pad => Pad);
181 end Delete;
183 ----------
184 -- Head --
185 ----------
187 function Head
188 (Source : in Wide_String;
189 Count : in Natural;
190 Pad : in Wide_Character := Wide_Space)
191 return Wide_String
193 Result : Wide_String (1 .. Count);
195 begin
196 if Count <= Source'Length then
197 Result := Source (Source'First .. Source'First + Count - 1);
199 else
200 Result (1 .. Source'Length) := Source;
202 for J in Source'Length + 1 .. Count loop
203 Result (J) := Pad;
204 end loop;
205 end if;
207 return Result;
208 end Head;
210 procedure Head
211 (Source : in out Wide_String;
212 Count : in Natural;
213 Justify : in Alignment := Left;
214 Pad : in Wide_Character := Ada.Strings.Wide_Space)
216 begin
217 Move (Source => Head (Source, Count, Pad),
218 Target => Source,
219 Drop => Error,
220 Justify => Justify,
221 Pad => Pad);
222 end Head;
224 ------------
225 -- Insert --
226 ------------
228 function Insert
229 (Source : in Wide_String;
230 Before : in Positive;
231 New_Item : in Wide_String)
232 return Wide_String
234 Result : Wide_String (1 .. Source'Length + New_Item'Length);
236 begin
237 if Before < Source'First or else Before > Source'Last + 1 then
238 raise Index_Error;
239 end if;
241 Result := Source (Source'First .. Before - 1) & New_Item &
242 Source (Before .. Source'Last);
243 return Result;
244 end Insert;
246 procedure Insert
247 (Source : in out Wide_String;
248 Before : in Positive;
249 New_Item : in Wide_String;
250 Drop : in Truncation := Error)
252 begin
253 Move (Source => Insert (Source, Before, New_Item),
254 Target => Source,
255 Drop => Drop);
256 end Insert;
258 ----------
259 -- Move --
260 ----------
262 procedure Move
263 (Source : in Wide_String;
264 Target : out Wide_String;
265 Drop : in Truncation := Error;
266 Justify : in Alignment := Left;
267 Pad : in Wide_Character := Wide_Space)
269 Sfirst : constant Integer := Source'First;
270 Slast : constant Integer := Source'Last;
271 Slength : constant Integer := Source'Length;
273 Tfirst : constant Integer := Target'First;
274 Tlast : constant Integer := Target'Last;
275 Tlength : constant Integer := Target'Length;
277 function Is_Padding (Item : Wide_String) return Boolean;
278 -- Determinbe if all characters in Item are pad characters
280 function Is_Padding (Item : Wide_String) return Boolean is
281 begin
282 for J in Item'Range loop
283 if Item (J) /= Pad then
284 return False;
285 end if;
286 end loop;
288 return True;
289 end Is_Padding;
291 -- Start of processing for Move
293 begin
294 if Slength = Tlength then
295 Target := Source;
297 elsif Slength > Tlength then
299 case Drop is
300 when Left =>
301 Target := Source (Slast - Tlength + 1 .. Slast);
303 when Right =>
304 Target := Source (Sfirst .. Sfirst + Tlength - 1);
306 when Error =>
307 case Justify is
308 when Left =>
309 if Is_Padding (Source (Sfirst + Tlength .. Slast)) then
310 Target :=
311 Source (Sfirst .. Sfirst + Target'Length - 1);
312 else
313 raise Length_Error;
314 end if;
316 when Right =>
317 if Is_Padding (Source (Sfirst .. Slast - Tlength)) then
318 Target := Source (Slast - Tlength + 1 .. Slast);
319 else
320 raise Length_Error;
321 end if;
323 when Center =>
324 raise Length_Error;
325 end case;
327 end case;
329 -- Source'Length < Target'Length
331 else
332 case Justify is
333 when Left =>
334 Target (Tfirst .. Tfirst + Slength - 1) := Source;
336 for J in Tfirst + Slength .. Tlast loop
337 Target (J) := Pad;
338 end loop;
340 when Right =>
341 for J in Tfirst .. Tlast - Slength loop
342 Target (J) := Pad;
343 end loop;
345 Target (Tlast - Slength + 1 .. Tlast) := Source;
347 when Center =>
348 declare
349 Front_Pad : constant Integer := (Tlength - Slength) / 2;
350 Tfirst_Fpad : constant Integer := Tfirst + Front_Pad;
352 begin
353 for J in Tfirst .. Tfirst_Fpad - 1 loop
354 Target (J) := Pad;
355 end loop;
357 Target (Tfirst_Fpad .. Tfirst_Fpad + Slength - 1) := Source;
359 for J in Tfirst_Fpad + Slength .. Tlast loop
360 Target (J) := Pad;
361 end loop;
362 end;
363 end case;
364 end if;
365 end Move;
367 ---------------
368 -- Overwrite --
369 ---------------
371 function Overwrite
372 (Source : in Wide_String;
373 Position : in Positive;
374 New_Item : in Wide_String)
375 return Wide_String
377 begin
378 if Position not in Source'First .. Source'Last + 1 then
379 raise Index_Error;
380 else
381 declare
382 Result_Length : constant Natural :=
383 Natural'Max
384 (Source'Length,
385 Position - Source'First + New_Item'Length);
387 Result : Wide_String (1 .. Result_Length);
389 begin
390 Result := Source (Source'First .. Position - 1) & New_Item &
391 Source (Position + New_Item'Length .. Source'Last);
392 return Result;
393 end;
394 end if;
395 end Overwrite;
397 procedure Overwrite
398 (Source : in out Wide_String;
399 Position : in Positive;
400 New_Item : in Wide_String;
401 Drop : in Truncation := Right)
403 begin
404 Move (Source => Overwrite (Source, Position, New_Item),
405 Target => Source,
406 Drop => Drop);
407 end Overwrite;
409 -------------------
410 -- Replace_Slice --
411 -------------------
413 function Replace_Slice
414 (Source : in Wide_String;
415 Low : in Positive;
416 High : in Natural;
417 By : in Wide_String)
418 return Wide_String
420 Result_Length : Natural;
422 begin
423 if Low > Source'Last + 1 or else High < Source'First - 1 then
424 raise Index_Error;
425 else
426 Result_Length :=
427 Source'Length - Natural'Max (High - Low + 1, 0) + By'Length;
429 declare
430 Result : Wide_String (1 .. Result_Length);
432 begin
433 if High >= Low then
434 Result :=
435 Source (Source'First .. Low - 1) & By &
436 Source (High + 1 .. Source'Last);
437 else
438 Result := Source (Source'First .. Low - 1) & By &
439 Source (Low .. Source'Last);
440 end if;
442 return Result;
443 end;
444 end if;
445 end Replace_Slice;
447 procedure Replace_Slice
448 (Source : in out Wide_String;
449 Low : in Positive;
450 High : in Natural;
451 By : in Wide_String;
452 Drop : in Truncation := Error;
453 Justify : in Alignment := Left;
454 Pad : in Wide_Character := Wide_Space)
456 begin
457 Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
458 end Replace_Slice;
460 ----------
461 -- Tail --
462 ----------
464 function Tail
465 (Source : in Wide_String;
466 Count : in Natural;
467 Pad : in Wide_Character := Wide_Space)
468 return Wide_String
470 Result : Wide_String (1 .. Count);
472 begin
473 if Count < Source'Length then
474 Result := Source (Source'Last - Count + 1 .. Source'Last);
476 -- Pad on left
478 else
479 for J in 1 .. Count - Source'Length loop
480 Result (J) := Pad;
481 end loop;
483 Result (Count - Source'Length + 1 .. Count) := Source;
484 end if;
486 return Result;
487 end Tail;
489 procedure Tail
490 (Source : in out Wide_String;
491 Count : in Natural;
492 Justify : in Alignment := Left;
493 Pad : in Wide_Character := Ada.Strings.Wide_Space)
495 begin
496 Move (Source => Tail (Source, Count, Pad),
497 Target => Source,
498 Drop => Error,
499 Justify => Justify,
500 Pad => Pad);
501 end Tail;
503 ---------------
504 -- Translate --
505 ---------------
507 function Translate
508 (Source : in Wide_String;
509 Mapping : in Wide_Maps.Wide_Character_Mapping)
510 return Wide_String
512 Result : Wide_String (1 .. Source'Length);
514 begin
515 for J in Source'Range loop
516 Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
517 end loop;
519 return Result;
520 end Translate;
522 procedure Translate
523 (Source : in out Wide_String;
524 Mapping : in Wide_Maps.Wide_Character_Mapping)
526 begin
527 for J in Source'Range loop
528 Source (J) := Value (Mapping, Source (J));
529 end loop;
530 end Translate;
532 function Translate
533 (Source : in Wide_String;
534 Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
535 return Wide_String
537 Result : Wide_String (1 .. Source'Length);
539 begin
540 for J in Source'Range loop
541 Result (J - (Source'First - 1)) := Mapping (Source (J));
542 end loop;
544 return Result;
545 end Translate;
547 procedure Translate
548 (Source : in out Wide_String;
549 Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
551 begin
552 for J in Source'Range loop
553 Source (J) := Mapping (Source (J));
554 end loop;
555 end Translate;
557 ----------
558 -- Trim --
559 ----------
561 function Trim
562 (Source : in Wide_String;
563 Side : in Trim_End)
564 return Wide_String
566 Low : Natural := Source'First;
567 High : Natural := Source'Last;
569 begin
570 if Side = Left or else Side = Both then
571 while Low <= High and then Source (Low) = Wide_Space loop
572 Low := Low + 1;
573 end loop;
574 end if;
576 if Side = Right or else Side = Both then
577 while High >= Low and then Source (High) = Wide_Space loop
578 High := High - 1;
579 end loop;
580 end if;
582 -- All blanks case
584 if Low > High then
585 return "";
587 -- At least one non-blank
589 else
590 declare
591 Result : constant Wide_String (1 .. High - Low + 1) :=
592 Source (Low .. High);
594 begin
595 return Result;
596 end;
597 end if;
598 end Trim;
600 procedure Trim
601 (Source : in out Wide_String;
602 Side : in Trim_End;
603 Justify : in Alignment := Left;
604 Pad : in Wide_Character := Wide_Space)
606 begin
607 Move (Source => Trim (Source, Side),
608 Target => Source,
609 Justify => Justify,
610 Pad => Pad);
611 end Trim;
613 function Trim
614 (Source : in Wide_String;
615 Left : in Wide_Maps.Wide_Character_Set;
616 Right : in Wide_Maps.Wide_Character_Set)
617 return Wide_String
619 Low : Natural := Source'First;
620 High : Natural := Source'Last;
622 begin
623 while Low <= High and then Is_In (Source (Low), Left) loop
624 Low := Low + 1;
625 end loop;
627 while High >= Low and then Is_In (Source (High), Right) loop
628 High := High - 1;
629 end loop;
631 -- Case where source comprises only characters in the sets
633 if Low > High then
634 return "";
635 else
636 declare
637 subtype WS is Wide_String (1 .. High - Low + 1);
639 begin
640 return WS (Source (Low .. High));
641 end;
642 end if;
643 end Trim;
645 procedure Trim
646 (Source : in out Wide_String;
647 Left : in Wide_Maps.Wide_Character_Set;
648 Right : in Wide_Maps.Wide_Character_Set;
649 Justify : in Alignment := Strings.Left;
650 Pad : in Wide_Character := Wide_Space)
652 begin
653 Move (Source => Trim (Source, Left, Right),
654 Target => Source,
655 Justify => Justify,
656 Pad => Pad);
657 end Trim;
659 end Ada.Strings.Wide_Fixed;