diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2009-06-24 12:11:52 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2009-06-24 12:11:52 +0200 |
commit | e1f3cb584d01e98206cea8feeb094ca025534ff7 (patch) | |
tree | 93566d15728270f04bb11663b8d930f136b389a4 /gcc/ada/a-strsea.adb | |
parent | c928785785d29202b33a7738adecff9a09c93738 (diff) | |
download | gcc-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.adb | 269 |
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; |