poke-devel
[Top][All Lists]
Advanced

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

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


From: Arsen Arsenović
Subject: [PATCH v2 2/4] std.pk: Refactor atoi into strtoi
Date: Sun, 29 Jan 2023 21:04:36 +0100

* 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 0606f136..b1997f17 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);
-- 
2.39.1




reply via email to

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