gcc:
[official-gcc.git] / gcc / ada / a-stzsea.adb
blob2e29415e0c18199ec2f09299948b01f49ed1e945
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- A D A . S T R I N G S . W I D E _ W I D E _ S E A R C H --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2005, 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, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, 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_Wide_Maps; use Ada.Strings.Wide_Wide_Maps;
36 package body Ada.Strings.Wide_Wide_Search is
38 -----------------------
39 -- Local Subprograms --
40 -----------------------
42 function Belongs
43 (Element : Wide_Wide_Character;
44 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
45 Test : Membership) return Boolean;
46 pragma Inline (Belongs);
47 -- Determines if the given element is in (Test = Inside) or not in
48 -- (Test = Outside) the given character set.
50 -------------
51 -- Belongs --
52 -------------
54 function Belongs
55 (Element : Wide_Wide_Character;
56 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
57 Test : Membership) return Boolean
59 begin
60 if Test = Inside then
61 return Is_In (Element, Set);
62 else
63 return not Is_In (Element, Set);
64 end if;
65 end Belongs;
67 -----------
68 -- Count --
69 -----------
71 function Count
72 (Source : Wide_Wide_String;
73 Pattern : Wide_Wide_String;
74 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
75 Wide_Wide_Maps.Identity)
76 return Natural
78 N : Natural;
79 J : Natural;
81 begin
82 if Pattern = "" then
83 raise Pattern_Error;
84 end if;
86 -- Handle the case of non-identity mappings by creating a mapped
87 -- string and making a recursive call using the identity mapping
88 -- on this mapped string.
90 if Mapping /= Wide_Wide_Maps.Identity then
91 declare
92 Mapped_Source : Wide_Wide_String (Source'Range);
94 begin
95 for J in Source'Range loop
96 Mapped_Source (J) := Value (Mapping, Source (J));
97 end loop;
99 return Count (Mapped_Source, Pattern);
100 end;
101 end if;
103 N := 0;
104 J := Source'First;
106 while J <= Source'Last - (Pattern'Length - 1) loop
107 if Source (J .. J + (Pattern'Length - 1)) = Pattern then
108 N := N + 1;
109 J := J + Pattern'Length;
110 else
111 J := J + 1;
112 end if;
113 end loop;
115 return N;
116 end Count;
118 function Count
119 (Source : Wide_Wide_String;
120 Pattern : Wide_Wide_String;
121 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping_Function)
122 return Natural
124 Mapped_Source : Wide_Wide_String (Source'Range);
126 begin
127 for J in Source'Range loop
128 Mapped_Source (J) := Mapping (Source (J));
129 end loop;
131 return Count (Mapped_Source, Pattern);
132 end Count;
134 function Count
135 (Source : Wide_Wide_String;
136 Set : Wide_Wide_Maps.Wide_Wide_Character_Set) return Natural
138 N : Natural := 0;
140 begin
141 for J in Source'Range loop
142 if Is_In (Source (J), Set) then
143 N := N + 1;
144 end if;
145 end loop;
147 return N;
148 end Count;
150 ----------------
151 -- Find_Token --
152 ----------------
154 procedure Find_Token
155 (Source : Wide_Wide_String;
156 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
157 Test : Membership;
158 First : out Positive;
159 Last : out Natural)
161 begin
162 for J in Source'Range loop
163 if Belongs (Source (J), Set, Test) then
164 First := J;
166 for K in J + 1 .. Source'Last loop
167 if not Belongs (Source (K), Set, Test) then
168 Last := K - 1;
169 return;
170 end if;
171 end loop;
173 -- Here if J indexes 1st char of token, and all chars
174 -- after J are in the token
176 Last := Source'Last;
177 return;
178 end if;
179 end loop;
181 -- Here if no token found
183 First := Source'First;
184 Last := 0;
185 end Find_Token;
187 -----------
188 -- Index --
189 -----------
191 function Index
192 (Source : Wide_Wide_String;
193 Pattern : Wide_Wide_String;
194 Going : Direction := Forward;
195 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
196 Wide_Wide_Maps.Identity)
197 return Natural
199 begin
200 if Pattern = "" then
201 raise Pattern_Error;
202 end if;
204 -- Handle the case of non-identity mappings by creating a mapped
205 -- string and making a recursive call using the identity mapping
206 -- on this mapped string.
208 if Mapping /= Identity then
209 declare
210 Mapped_Source : Wide_Wide_String (Source'Range);
212 begin
213 for J in Source'Range loop
214 Mapped_Source (J) := Value (Mapping, Source (J));
215 end loop;
217 return Index (Mapped_Source, Pattern, Going);
218 end;
219 end if;
221 if Going = Forward then
222 for J in Source'First .. Source'Last - Pattern'Length + 1 loop
223 if Pattern = Source (J .. J + Pattern'Length - 1) then
224 return J;
225 end if;
226 end loop;
228 else -- Going = Backward
229 for J in reverse Source'First .. Source'Last - Pattern'Length + 1 loop
230 if Pattern = Source (J .. J + Pattern'Length - 1) then
231 return J;
232 end if;
233 end loop;
234 end if;
236 -- Fall through if no match found. Note that the loops are skipped
237 -- completely in the case of the pattern being longer than the source.
239 return 0;
240 end Index;
242 function Index
243 (Source : Wide_Wide_String;
244 Pattern : Wide_Wide_String;
245 Going : Direction := Forward;
246 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping_Function)
247 return Natural
249 Mapped_Source : Wide_Wide_String (Source'Range);
251 begin
252 for J in Source'Range loop
253 Mapped_Source (J) := Mapping (Source (J));
254 end loop;
256 return Index (Mapped_Source, Pattern, Going);
257 end Index;
259 function Index
260 (Source : Wide_Wide_String;
261 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
262 Test : Membership := Inside;
263 Going : Direction := Forward) return Natural
265 begin
266 if Going = Forward then
267 for J in Source'Range loop
268 if Belongs (Source (J), Set, Test) then
269 return J;
270 end if;
271 end loop;
273 else -- Going = Backward
274 for J in reverse Source'Range loop
275 if Belongs (Source (J), Set, Test) then
276 return J;
277 end if;
278 end loop;
279 end if;
281 -- Fall through if no match
283 return 0;
284 end Index;
286 function Index
287 (Source : Wide_Wide_String;
288 Pattern : Wide_Wide_String;
289 From : Positive;
290 Going : Direction := Forward;
291 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
292 Wide_Wide_Maps.Identity)
293 return Natural
295 begin
296 if Going = Forward then
297 if From < Source'First then
298 raise Index_Error;
299 end if;
301 return
302 Index (Source (From .. Source'Last), Pattern, Forward, Mapping);
304 else
305 if From > Source'Last then
306 raise Index_Error;
307 end if;
309 return
310 Index (Source (Source'First .. From), Pattern, Backward, Mapping);
311 end if;
312 end Index;
314 function Index
315 (Source : Wide_Wide_String;
316 Pattern : Wide_Wide_String;
317 From : Positive;
318 Going : Direction := Forward;
319 Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping_Function)
320 return Natural
322 begin
323 if Going = Forward then
324 if From < Source'First then
325 raise Index_Error;
326 end if;
328 return Index
329 (Source (From .. Source'Last), Pattern, Forward, Mapping);
331 else
332 if From > Source'Last then
333 raise Index_Error;
334 end if;
336 return Index
337 (Source (Source'First .. From), Pattern, Backward, Mapping);
338 end if;
339 end Index;
341 function Index
342 (Source : Wide_Wide_String;
343 Set : Wide_Wide_Maps.Wide_Wide_Character_Set;
344 From : Positive;
345 Test : Membership := Inside;
346 Going : Direction := Forward) return Natural
348 begin
349 if Going = Forward then
350 if From < Source'First then
351 raise Index_Error;
352 end if;
354 return
355 Index (Source (From .. Source'Last), Set, Test, Forward);
357 else
358 if From > Source'Last then
359 raise Index_Error;
360 end if;
362 return
363 Index (Source (Source'First .. From), Set, Test, Backward);
364 end if;
365 end Index;
367 ---------------------
368 -- Index_Non_Blank --
369 ---------------------
371 function Index_Non_Blank
372 (Source : Wide_Wide_String;
373 Going : Direction := Forward) return Natural
375 begin
376 if Going = Forward then
377 for J in Source'Range loop
378 if Source (J) /= Wide_Wide_Space then
379 return J;
380 end if;
381 end loop;
383 else -- Going = Backward
384 for J in reverse Source'Range loop
385 if Source (J) /= Wide_Wide_Space then
386 return J;
387 end if;
388 end loop;
389 end if;
391 -- Fall through if no match
393 return 0;
394 end Index_Non_Blank;
396 function Index_Non_Blank
397 (Source : Wide_Wide_String;
398 From : Positive;
399 Going : Direction := Forward) return Natural
401 begin
402 if Going = Forward then
403 if From < Source'First then
404 raise Index_Error;
405 end if;
407 return
408 Index_Non_Blank (Source (From .. Source'Last), Forward);
410 else
411 if From > Source'Last then
412 raise Index_Error;
413 end if;
415 return
416 Index_Non_Blank (Source (Source'First .. From), Backward);
417 end if;
418 end Index_Non_Blank;
420 end Ada.Strings.Wide_Wide_Search;