[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);