1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
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 --
9 -- Copyright (C) 1992-2005, Free Software Foundation, Inc. --
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. --
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. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
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 -----------------------
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.
55 (Element
: Wide_Wide_Character
;
56 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
57 Test
: Membership
) return Boolean
61 return Is_In
(Element
, Set
);
63 return not Is_In
(Element
, Set
);
72 (Source
: Wide_Wide_String
;
73 Pattern
: Wide_Wide_String
;
74 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
75 Wide_Wide_Maps
.Identity
)
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
92 Mapped_Source
: Wide_Wide_String
(Source
'Range);
95 for J
in Source
'Range loop
96 Mapped_Source
(J
) := Value
(Mapping
, Source
(J
));
99 return Count
(Mapped_Source
, Pattern
);
106 while J
<= Source
'Last - (Pattern
'Length - 1) loop
107 if Source
(J
.. J
+ (Pattern
'Length - 1)) = Pattern
then
109 J
:= J
+ Pattern
'Length;
119 (Source
: Wide_Wide_String
;
120 Pattern
: Wide_Wide_String
;
121 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
124 Mapped_Source
: Wide_Wide_String
(Source
'Range);
127 for J
in Source
'Range loop
128 Mapped_Source
(J
) := Mapping
(Source
(J
));
131 return Count
(Mapped_Source
, Pattern
);
135 (Source
: Wide_Wide_String
;
136 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
) return Natural
141 for J
in Source
'Range loop
142 if Is_In
(Source
(J
), Set
) then
155 (Source
: Wide_Wide_String
;
156 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
158 First
: out Positive;
162 for J
in Source
'Range loop
163 if Belongs
(Source
(J
), Set
, Test
) then
166 for K
in J
+ 1 .. Source
'Last loop
167 if not Belongs
(Source
(K
), Set
, Test
) then
173 -- Here if J indexes 1st char of token, and all chars
174 -- after J are in the token
181 -- Here if no token found
183 First
:= Source
'First;
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
)
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
210 Mapped_Source
: Wide_Wide_String
(Source
'Range);
213 for J
in Source
'Range loop
214 Mapped_Source
(J
) := Value
(Mapping
, Source
(J
));
217 return Index
(Mapped_Source
, Pattern
, Going
);
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
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
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.
243 (Source
: Wide_Wide_String
;
244 Pattern
: Wide_Wide_String
;
245 Going
: Direction
:= Forward
;
246 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
249 Mapped_Source
: Wide_Wide_String
(Source
'Range);
252 for J
in Source
'Range loop
253 Mapped_Source
(J
) := Mapping
(Source
(J
));
256 return Index
(Mapped_Source
, Pattern
, Going
);
260 (Source
: Wide_Wide_String
;
261 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
262 Test
: Membership
:= Inside
;
263 Going
: Direction
:= Forward
) return Natural
266 if Going
= Forward
then
267 for J
in Source
'Range loop
268 if Belongs
(Source
(J
), Set
, Test
) then
273 else -- Going = Backward
274 for J
in reverse Source
'Range loop
275 if Belongs
(Source
(J
), Set
, Test
) then
281 -- Fall through if no match
287 (Source
: Wide_Wide_String
;
288 Pattern
: Wide_Wide_String
;
290 Going
: Direction
:= Forward
;
291 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping
:=
292 Wide_Wide_Maps
.Identity
)
296 if Going
= Forward
then
297 if From
< Source
'First then
302 Index
(Source
(From
.. Source
'Last), Pattern
, Forward
, Mapping
);
305 if From
> Source
'Last then
310 Index
(Source
(Source
'First .. From
), Pattern
, Backward
, Mapping
);
315 (Source
: Wide_Wide_String
;
316 Pattern
: Wide_Wide_String
;
318 Going
: Direction
:= Forward
;
319 Mapping
: Wide_Wide_Maps
.Wide_Wide_Character_Mapping_Function
)
323 if Going
= Forward
then
324 if From
< Source
'First then
329 (Source
(From
.. Source
'Last), Pattern
, Forward
, Mapping
);
332 if From
> Source
'Last then
337 (Source
(Source
'First .. From
), Pattern
, Backward
, Mapping
);
342 (Source
: Wide_Wide_String
;
343 Set
: Wide_Wide_Maps
.Wide_Wide_Character_Set
;
345 Test
: Membership
:= Inside
;
346 Going
: Direction
:= Forward
) return Natural
349 if Going
= Forward
then
350 if From
< Source
'First then
355 Index
(Source
(From
.. Source
'Last), Set
, Test
, Forward
);
358 if From
> Source
'Last then
363 Index
(Source
(Source
'First .. From
), Set
, Test
, Backward
);
367 ---------------------
368 -- Index_Non_Blank --
369 ---------------------
371 function Index_Non_Blank
372 (Source
: Wide_Wide_String
;
373 Going
: Direction
:= Forward
) return Natural
376 if Going
= Forward
then
377 for J
in Source
'Range loop
378 if Source
(J
) /= Wide_Wide_Space
then
383 else -- Going = Backward
384 for J
in reverse Source
'Range loop
385 if Source
(J
) /= Wide_Wide_Space
then
391 -- Fall through if no match
396 function Index_Non_Blank
397 (Source
: Wide_Wide_String
;
399 Going
: Direction
:= Forward
) return Natural
402 if Going
= Forward
then
403 if From
< Source
'First then
408 Index_Non_Blank
(Source
(From
.. Source
'Last), Forward
);
411 if From
> Source
'Last then
416 Index_Non_Blank
(Source
(Source
'First .. From
), Backward
);
420 end Ada
.Strings
.Wide_Wide_Search
;