[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
- [PATCH v2 0/4] Implement version tools (was: add pk_vercmp), Arsen Arsenović, 2023/01/29
- [PATCH v2 2/4] std.pk: Refactor atoi into strtoi,
Arsen Arsenović <=
- [PATCH v2 1/4] std.pk: Implement strrchr, Arsen Arsenović, 2023/01/29
- [PATCH v2 4/4] std.pk: Implement pk_version_parse, pk_vercmp, Arsen Arsenović, 2023/01/29
- [PATCH v2 3/4] std.pk: Implement strtok, Arsen Arsenović, 2023/01/29
- Re: [PATCH v2 0/4] Implement version tools, Jose E. Marchesi, 2023/01/29