From: Liaiss Merzougue Date: Thu, 8 Oct 2020 15:26:11 +0000 (+0000) Subject: [Ada] Unrecursify Set_Digit/Set_Image_Unsigned procedure X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cf4737dcec18336b735a46d524bd8ef056e3d245;p=gcc.git [Ada] Unrecursify Set_Digit/Set_Image_Unsigned procedure gcc/ada/ * libgnat/s-imagei.adb (Set_Digits): Rewrite the procedure to remove recursion. (Image_Integer, Set_Image_Integer): Update assertions and remove redundant ones. * libgnat/s-imageu.adb (Set_Image_Unsigned): Rewrite the procedure to remove recursion. --- diff --git a/gcc/ada/libgnat/s-imagei.adb b/gcc/ada/libgnat/s-imagei.adb index c739dfb8af6..36c1f6fea9f 100644 --- a/gcc/ada/libgnat/s-imagei.adb +++ b/gcc/ada/libgnat/s-imagei.adb @@ -56,8 +56,11 @@ package body System.Image_I is if V >= 0 then S (1) := ' '; P := 1; + pragma Assert (P < S'Last); + else P := 0; + pragma Assert (P < S'Last - 1); end if; Set_Image_Integer (V, S, P); @@ -72,26 +75,31 @@ package body System.Image_I is S : in out String; P : in out Natural) is + Nb_Digits : Natural := 0; + Value : Non_Positive := T; begin - if T <= -10 then - Set_Digits (T / 10, S, P); - pragma Assert (P >= (S'First - 1) and P < S'Last and - P < Natural'Last); - -- No check is done since, as documented in the Set_Image_Integer - -- specification, the caller guarantees that S is long enough to - -- hold the result. - P := P + 1; - S (P) := Character'Val (48 - (T rem 10)); + pragma Assert (P >= S'First - 1 and P < S'Last); + -- No check is done since, as documented in the Set_Image_Integer + -- specification, the caller guarantees that S is long enough to + -- hold the result. - else - pragma Assert (P >= (S'First - 1) and P < S'Last and - P < Natural'Last); - -- No check is done since, as documented in the Set_Image_Integer - -- specification, the caller guarantees that S is long enough to - -- hold the result. - P := P + 1; - S (P) := Character'Val (48 - T); - end if; + -- First we compute the number of characters needed for representing + -- the number. + loop + Value := Value / 10; + Nb_Digits := Nb_Digits + 1; + exit when Value = 0; + end loop; + + Value := T; + + -- We now populate digits from the end of the string to the beginning + for J in reverse 1 .. Nb_Digits loop + S (P + J) := Character'Val (48 - (Value rem 10)); + Value := Value / 10; + end loop; + + P := P + Nb_Digits; end Set_Digits; ----------------------- @@ -108,8 +116,7 @@ package body System.Image_I is Set_Digits (-V, S, P); else - pragma Assert (P >= (S'First - 1) and P < S'Last and - P < Natural'Last); + pragma Assert (P >= S'First - 1 and P < S'Last); -- No check is done since, as documented in the specification, -- the caller guarantees that S is long enough to hold the result. P := P + 1; diff --git a/gcc/ada/libgnat/s-imageu.adb b/gcc/ada/libgnat/s-imageu.adb index c995d554d17..8ffb8f03603 100644 --- a/gcc/ada/libgnat/s-imageu.adb +++ b/gcc/ada/libgnat/s-imageu.adb @@ -56,24 +56,31 @@ package body System.Image_U is S : in out String; P : in out Natural) is + Nb_Digits : Natural := 0; + Value : Uns := V; begin - if V >= 10 then - Set_Image_Unsigned (V / 10, S, P); - pragma Assert (P >= (S'First - 1) and P < S'Last and - P < Natural'Last); - -- No check is done since, as documented in the specification, - -- the caller guarantees that S is long enough to hold the result. - P := P + 1; - S (P) := Character'Val (48 + (V rem 10)); + pragma Assert (P >= S'First - 1 and then P < S'Last and then + P < Natural'Last); + -- No check is done since, as documented in the specification, the + -- caller guarantees that S is long enough to hold the result. - else - pragma Assert (P >= (S'First - 1) and P < S'Last and - P < Natural'Last); - -- No check is done since, as documented in the specification, - -- the caller guarantees that S is long enough to hold the result. - P := P + 1; - S (P) := Character'Val (48 + V); - end if; + -- First we compute the number of characters needed for representing + -- the number. + loop + Value := Value / 10; + Nb_Digits := Nb_Digits + 1; + exit when Value = 0; + end loop; + + Value := V; + + -- We now populate digits from the end of the string to the beginning + for J in reverse 1 .. Nb_Digits loop + S (P + J) := Character'Val (48 + (Value rem 10)); + Value := Value / 10; + end loop; + + P := P + Nb_Digits; end Set_Image_Unsigned; end System.Image_U;