poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/4] std.pk: Refactor atoi into strtoi


From: Jose E. Marchesi
Subject: Re: [PATCH 2/4] std.pk: Refactor atoi into strtoi
Date: Sun, 29 Jan 2023 17:48:05 +0100
User-agent: Gnus/5.13 (Gnus v5.13)

Hi Arsen.

Thanks for the patch.
OK for master.

> * libpoke/std.pk (Strtoi_Result): New type.  Stores the result of
> a strtoi call.
> (strtoi): New function.  Parses a numeric prefix on a string and
> returns the result and the number of parsed characters.
> (atoi): Refactor to wrap strtoi.
> * testsuite/poke.std/std-test.pk: Add tests for strtoi
> offset-returning semantics.
> ---
>  ChangeLog                      | 13 ++++++++
>  doc/poke.texi                  | 54 +++++++++++++++++++++++++++++++---
>  libpoke/std.pk                 | 26 ++++++++++++++--
>  testsuite/poke.std/std-test.pk | 18 ++++++++++++
>  4 files changed, 104 insertions(+), 7 deletions(-)
>
> diff --git a/ChangeLog b/ChangeLog
> index 751eb110..7f90ba64 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,16 @@
> +2023-01-29  Arsen Arsenović  <arsen@aarsen.me>
> +
> +     std.pk: Refactor atoi into strtoi
> +     * libpoke/std.pk (Strtoi_Result): New type.  Stores the result of
> +     a strtoi call.
> +     (strtoi): New function.  Parses a numeric prefix on a string and
> +     returns the result and the number of parsed characters.
> +     (atoi): Refactor to wrap strtoi.
> +     * doc/poke.texi (strtoi): New node.
> +     (atoi): Refer to strtoi for a list of bases.
> +     * testsuite/poke.std/std-test.pk: Add tests for strtoi
> +     offset-returning semantics.
> +
>  2023-01-28  Arsen Arsenović  <arsen@aarsen.me>
>  
>       std.pk: Implement strrchr
> diff --git a/doc/poke.texi b/doc/poke.texi
> index f0cd3a7e..54a369c8 100644
> --- a/doc/poke.texi
> +++ b/doc/poke.texi
> @@ -15547,6 +15547,7 @@ useful conversions.
>  @menu
>  * catos::            converting characters arrays into string.
>  * stoca::            filling character arrays from strings.
> +* strtoi::           convert numeric prefix to integer.
>  * atoi::             converting strings to integers.
>  * ltos::             converting integers to strings.
>  @end menu
> @@ -15597,6 +15598,53 @@ It fills the given array @var{ca} with the contents 
> of the string
>  than the length of the array, the extra characters are set to the
>  @var{fill} character, which defaults to @code{\0}.
>  
> +@node strtoi
> +@subsection @code{strtoi}
> +@cindex @code{strtoi}
> +@cindex converting, strings to integers
> +The standard function @code{strtoi} provides the following interface:
> +
> +@example
> +type Strtoi_Result =
> +  struct
> +  @{
> +    uint<64> @var{off};
> +    int<64> @var{val};
> +  @};
> +
> +fun strtoi = (string @var{str}, int @var{base} = 10, ulong @var{start} = 0) 
> Stroi_Result: @{ @dots{} @}
> +@end example
> +
> +It parses a signed integral number in the given @var{base} in the
> +string @var{str} at position @var{start} and returns its value and its
> +length in the @var{val} and @var{off} fields of a new
> +@code{Strtoi_Result} instance.
> +
> +Specifying a @var{start} that is greater than or equal to the length
> +of the string causes a @code{E_out_of_bound} exception to be raised.
> +
> +@cindex base, argument in @command{strtoi}
> +The accepted values for @var{base} are @code{2}, @code{8}, @code{10}
> +(the default) and @code{16}.  If any other base is requested an
> +@code{E_inval} exception is raised.
> +
> +Note that this function parses an integer but permits more characters
> +to follow the given integer.  As an example, lets parse ``12foo'' in
> +base 16:
> +
> +@example
> +#!!# strtoi ("12foo", 16)
> +Strtoi_Result @{
> +  off=3UL,
> +  val=303L
> +@}
> +#!!# strtoi ("12foo", 16, 1)
> +Strtoi_Result @{
> +  off=3UL,
> +  val=47L
> +@}
> +@end example
> +
>  @node atoi
>  @subsection @code{atoi}
>  @cindex @code{atoi}
> @@ -15610,10 +15658,8 @@ fun atoi = (string @var{str}, int @var{base} = 10) 
> long: @{ @dots{} @}
>  It parses a signed integral number in the given @var{base} in the
>  string @var{str} and returns it as a signed 64-bit integer.
>  
> -@cindex base, argument in @command{atoi}
> -The accepted values for @var{base} are @code{2}, @code{8}, @code{10}
> -(the default) and @code{16}.  If any other base is requested an
> -@code{E_inval} exception is raised.
> +The accepted values for @var{base} are the same as for @samp{strtoi}.
> +@xref{strtoi} for a list of supported bases.
>  
>  Note that atoi allows for extra information to be stored in @var{str}
>  after the parsed integer.  Thus, this works:
> diff --git a/libpoke/std.pk b/libpoke/std.pk
> index 9d9972d3..a9ed3305 100644
> --- a/libpoke/std.pk
> +++ b/libpoke/std.pk
> @@ -72,10 +72,20 @@ fun stoca = (string s, uint<8>[] ca, uint<8> fill = 0) 
> void:
>        }
>    }
>  
> -fun atoi = (string s, int<32> b = 10) int<64>:
> +type Strtoi_Result =
> +  struct
> +  {
> +    uint<64> off;
> +    int<64> val;
> +  };
> +
> +fun strtoi = (string s, int<32> b = 10, uint<64> start = 0) Strtoi_Result:
>    {
>      var result = 0L;
>  
> +    if (start >= s'length)
> +      raise E_out_of_bounds;
> +
>      fun htoi = (uint<8> c) int<32>:
>        {
>          if (c >= '0' && c <= '9') return c - '0';
> @@ -112,17 +122,27 @@ fun atoi = (string s, int<32> b = 10) int<64>:
>      else
>        s = s[1:];
>  
> -    for (c in s)
> +    var i = start;
> +    for (; i < s'length; i++)
>      {
> +      var c = s[i];
>        if (!valid(c, b))
>          break;
>  
>        result = result * b + htoi (c);
>      }
>  
> -    return sign * result;
> +    return Strtoi_Result { val = sign * result, off = i };
>    }
>  
> +fun atoi = (string s, int<32> b = 10) int<64>:
> +{
> +  /* Match old behavior.  */
> +  if (s == "")
> +    return 0;
> +  return strtoi (s, b).val;
> +}
> +
>  fun ltos = (int<64> i, uint<32> base = 10) string:
>  {
>    var chars = "0123456789abcdef";
> diff --git a/testsuite/poke.std/std-test.pk b/testsuite/poke.std/std-test.pk
> index 58d042e2..924767f5 100644
> --- a/testsuite/poke.std/std-test.pk
> +++ b/testsuite/poke.std/std-test.pk
> @@ -364,6 +364,24 @@ var tests = [
>          assert (strrchr ("", 'x') == -1);
>        },
>    },
> +  PkTest {
> +    name = "strtoi",
> +    func = lambda (string name) void:
> +      {
> +        /* The atoi tests above already thoroughly test the parser.  This 
> test
> +           just tests that the extra semantics that atoi () removes are 
> proper.
> +       */
> +        var x = strtoi ("foo", 16);
> +        assert (x.off == 1);
> +        assert (x.val == 0xf);
> +        x = strtoi ("foo", 16, 1);
> +        assert (x.off == 1);
> +        assert (x.val == 0);
> +        x = strtoi ("1001", 10, 1);
> +        assert (x.off == 4);
> +        assert (x.val == 1);
> +      },
> +  },
>  ];
>  
>  exit (pktest_run (tests) ? 0 : 1);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]