aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/a-strsea.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2009-06-24 12:11:52 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2009-06-24 12:11:52 +0200
commite1f3cb584d01e98206cea8feeb094ca025534ff7 (patch)
tree93566d15728270f04bb11663b8d930f136b389a4 /gcc/ada/a-strsea.adb
parentc928785785d29202b33a7738adecff9a09c93738 (diff)
downloadgcc-e1f3cb584d01e98206cea8feeb094ca025534ff7.zip
gcc-e1f3cb584d01e98206cea8feeb094ca025534ff7.tar.gz
gcc-e1f3cb584d01e98206cea8feeb094ca025534ff7.tar.bz2
[multiple changes]
2009-06-24 Robert Dewar <dewar@adacore.com> * prj-nmsc.adb, prj-nmsc.ads, prj-proc.adb, prj.adb: Minor reformatting * a-strsea.adb (Count): Avoid local copy on stack, speed up unmapped case. (Index): Ditto. 2009-06-24 Ed Schonberg <schonberg@adacore.com> * sem_ch4.adb (Analyze_One_Call): Check that at least one actual is present when checking whether a call may be interpreted as an indexing of the result of a call. * exp_ch9.adb (Expand_N_Subprogram_Declaration): Place the generated body for a null procedure on the freeze actions for the procedure, so that it will be analyzed at the proper place without premature freezing of actuals. * sem_ch3.adb (Check_Completion): Code cleanup. Do not diagnose a null procedure without a body, if previous errors have disabled expansion. 2009-06-24 Doug Rupp <rupp@adacore.com> * init.c [VMS] Resignal C$_SIGKILL 2009-06-24 Ed Falis <falis@adacore.com> * s-vxwext.adb, s-vxwext-kernel.adb: Add s-vxwext body for VxWorks 5 Define ERROR in body for VxWorks 6 kernel 2009-06-24 Pascal Obry <obry@adacore.com> * g-socket.adb, g-socket.ads: Fix possible unexpected constraint error in [Send/Receive]_Socket. From-SVN: r148905
Diffstat (limited to 'gcc/ada/a-strsea.adb')
-rw-r--r--gcc/ada/a-strsea.adb269
1 files changed, 178 insertions, 91 deletions
diff --git a/gcc/ada/a-strsea.adb b/gcc/ada/a-strsea.adb
index b613895..1994745 100644
--- a/gcc/ada/a-strsea.adb
+++ b/gcc/ada/a-strsea.adb
@@ -36,6 +36,7 @@
-- is specialized (rather than using the general Index routine).
with Ada.Strings.Maps; use Ada.Strings.Maps;
+with System; use System;
package body Ada.Strings.Search is
@@ -77,33 +78,58 @@ package body Ada.Strings.Search is
Pattern : String;
Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
is
- N : Natural;
- J : Natural;
-
- Mapped_Source : String (Source'Range);
+ PL1 : constant Integer := Pattern'Length - 1;
+ Num : Natural;
+ Ind : Natural;
+ Cur : Natural;
begin
- for J in Source'Range loop
- Mapped_Source (J) := Value (Mapping, Source (J));
- end loop;
-
if Pattern = "" then
raise Pattern_Error;
end if;
- N := 0;
- J := Source'First;
+ Num := 0;
+ Ind := Source'First;
- while J <= Source'Last - (Pattern'Length - 1) loop
- if Mapped_Source (J .. J + (Pattern'Length - 1)) = Pattern then
- N := N + 1;
- J := J + Pattern'Length;
- else
- J := J + 1;
- end if;
- end loop;
+ -- Unmapped case
- return N;
+ if Mapping'Address = Maps.Identity'Address then
+ Ind := Source'First;
+ while Ind <= Source'Length - PL1 loop
+ if Pattern = Source (Ind .. Ind + PL1) then
+ Num := Num + 1;
+ Ind := Ind + Pattern'Length;
+ else
+ Ind := Ind + 1;
+ end if;
+ end loop;
+
+ -- Mapped case
+
+ else
+ Ind := Source'First;
+ while Ind <= Source'Length - PL1 loop
+ Cur := Ind;
+ for K in Pattern'Range loop
+ if Pattern (K) /= Value (Mapping, Source (Cur)) then
+ Ind := Ind + 1;
+ goto Cont;
+ else
+ Cur := Cur + 1;
+ end if;
+ end loop;
+
+ Num := Num + 1;
+ Ind := Ind + Pattern'Length;
+
+ <<Cont>>
+ null;
+ end loop;
+ end if;
+
+ -- Return result
+
+ return Num;
end Count;
function Count
@@ -111,41 +137,43 @@ package body Ada.Strings.Search is
Pattern : String;
Mapping : Maps.Character_Mapping_Function) return Natural
is
- Mapped_Source : String (Source'Range);
- N : Natural;
- J : Natural;
+ PL1 : constant Integer := Pattern'Length - 1;
+ Num : Natural;
+ Ind : Natural;
+ Cur : Natural;
begin
if Pattern = "" then
raise Pattern_Error;
end if;
- -- We make sure Access_Check is unsuppressed so that the Mapping.all
- -- call will generate a friendly Constraint_Error if the value for
- -- Mapping is uninitialized (and hence null).
+ -- Check for null pointer in case checks are off
- declare
- pragma Unsuppress (Access_Check);
+ if Mapping = null then
+ raise Constraint_Error;
+ end if;
- begin
- for J in Source'Range loop
- Mapped_Source (J) := Mapping.all (Source (J));
+ Num := 0;
+ Ind := Source'First;
+ while Ind <= Source'Last - PL1 loop
+ Cur := Ind;
+ for K in Pattern'Range loop
+ if Pattern (K) /= Mapping (Source (Cur)) then
+ Ind := Ind + 1;
+ goto Cont;
+ else
+ Cur := Cur + 1;
+ end if;
end loop;
- end;
- N := 0;
- J := Source'First;
+ Num := Num + 1;
+ Ind := Ind + Pattern'Length;
- while J <= Source'Last - (Pattern'Length - 1) loop
- if Mapped_Source (J .. J + (Pattern'Length - 1)) = Pattern then
- N := N + 1;
- J := J + Pattern'Length;
- else
- J := J + 1;
- end if;
+ <<Cont>>
+ null;
end loop;
- return N;
+ return Num;
end Count;
function Count
@@ -187,8 +215,8 @@ package body Ada.Strings.Search is
end if;
end loop;
- -- Here if J indexes 1st char of token, and all chars
- -- after J are in the token
+ -- Here if J indexes first char of token, and all chars after J
+ -- are in the token.
Last := Source'Last;
return;
@@ -211,43 +239,88 @@ package body Ada.Strings.Search is
Going : Direction := Forward;
Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
is
- Cur_Index : Natural;
- Mapped_Source : String (Source'Range);
+ PL1 : constant Integer := Pattern'Length - 1;
+ Ind : Natural;
+ Cur : Natural;
begin
if Pattern = "" then
raise Pattern_Error;
end if;
- for J in Source'Range loop
- Mapped_Source (J) := Value (Mapping, Source (J));
- end loop;
-
-- Forwards case
if Going = Forward then
- for J in 1 .. Source'Length - Pattern'Length + 1 loop
- Cur_Index := Source'First + J - 1;
+ Ind := Source'First;
- if Pattern = Mapped_Source
- (Cur_Index .. Cur_Index + Pattern'Length - 1)
- then
- return Cur_Index;
- end if;
- end loop;
+ -- Unmapped forward case
+
+ if Mapping'Address = Maps.Identity'Address then
+ for J in 1 .. Source'Length - PL1 loop
+ if Pattern = Source (Ind .. Ind + PL1) then
+ return Ind;
+ else
+ Ind := Ind + 1;
+ end if;
+ end loop;
+
+ -- Mapped forward case
+
+ else
+ for J in 1 .. Source'Length - PL1 loop
+ Cur := Ind;
+
+ for K in Pattern'Range loop
+ if Pattern (K) /= Value (Mapping, Source (Cur)) then
+ goto Cont1;
+ else
+ Cur := Cur + 1;
+ end if;
+ end loop;
+
+ return Ind;
+
+ <<Cont1>>
+ Ind := Ind + 1;
+ end loop;
+ end if;
-- Backwards case
else
- for J in reverse 1 .. Source'Length - Pattern'Length + 1 loop
- Cur_Index := Source'First + J - 1;
+ -- Unmapped backward case
- if Pattern = Mapped_Source
- (Cur_Index .. Cur_Index + Pattern'Length - 1)
- then
- return Cur_Index;
- end if;
- end loop;
+ Ind := Source'Last - PL1;
+
+ if Mapping'Address = Maps.Identity'Address then
+ for J in reverse 1 .. Source'Length - PL1 loop
+ if Pattern = Source (Ind .. Ind + PL1) then
+ return Ind;
+ else
+ Ind := Ind - 1;
+ end if;
+ end loop;
+
+ -- Mapped backward case
+
+ else
+ for J in reverse 1 .. Source'Length - PL1 loop
+ Cur := Ind;
+
+ for K in Pattern'Range loop
+ if Pattern (K) /= Value (Mapping, Source (Cur)) then
+ goto Cont2;
+ else
+ Cur := Cur + 1;
+ end if;
+ end loop;
+
+ return Ind;
+
+ <<Cont2>>
+ Ind := Ind - 1;
+ end loop;
+ end if;
end if;
-- Fall through if no match found. Note that the loops are skipped
@@ -262,53 +335,67 @@ package body Ada.Strings.Search is
Going : Direction := Forward;
Mapping : Maps.Character_Mapping_Function) return Natural
is
- Mapped_Source : String (Source'Range);
- Cur_Index : Natural;
+ PL1 : constant Integer := Pattern'Length - 1;
+ Ind : Natural;
+ Cur : Natural;
begin
if Pattern = "" then
raise Pattern_Error;
end if;
- -- We make sure Access_Check is unsuppressed so that the Mapping.all
- -- call will generate a friendly Constraint_Error if the value for
- -- Mapping is uninitialized (and hence null).
+ -- Check for null pointer in case checks are off
- declare
- pragma Unsuppress (Access_Check);
- begin
- for J in Source'Range loop
- Mapped_Source (J) := Mapping.all (Source (J));
- end loop;
- end;
+ if Mapping = null then
+ raise Constraint_Error;
+ end if;
-- Forwards case
if Going = Forward then
- for J in 1 .. Source'Length - Pattern'Length + 1 loop
- Cur_Index := Source'First + J - 1;
+ Ind := Source'First;
+ for J in 1 .. Source'Length - PL1 loop
+ Cur := Ind;
+
+ for K in Pattern'Range loop
+ if Pattern (K) /= Mapping.all (Source (Cur)) then
+ goto Cont1;
+ else
+ Cur := Cur + 1;
+ end if;
+ end loop;
- if Pattern = Mapped_Source
- (Cur_Index .. Cur_Index + Pattern'Length - 1)
- then
- return Cur_Index;
- end if;
+ return Ind;
+
+ <<Cont1>>
+ Ind := Ind + 1;
end loop;
-- Backwards case
else
- for J in reverse 1 .. Source'Length - Pattern'Length + 1 loop
- Cur_Index := Source'First + J - 1;
+ Ind := Source'Last - PL1;
+ for J in reverse 1 .. Source'Length - PL1 loop
+ Cur := Ind;
+
+ for K in Pattern'Range loop
+ if Pattern (K) /= Mapping.all (Source (Cur)) then
+ goto Cont2;
+ else
+ Cur := Cur + 1;
+ end if;
+ end loop;
- if Pattern = Mapped_Source
- (Cur_Index .. Cur_Index + Pattern'Length - 1)
- then
- return Cur_Index;
- end if;
+ return Ind;
+
+ <<Cont2>>
+ Ind := Ind - 1;
end loop;
end if;
+ -- Fall through if no match found. Note that the loops are skipped
+ -- completely in the case of the pattern being longer than the source.
+
return 0;
end Index;