cutils: Add qemu_strto*l() wrappers
cover cutils: Add qemu_strto*l() wrappers
From: "Carlos L. Torres" <[email protected]>
Introduce qemu_ wrappers for strtol/strtoul/strtoll/strtoull C functions, ensure that errno is checked, and if NULL is passed as the endptr argument, then whole string has to be a valid number on the given base, otherwise return appropriate error.
Different from the C strto*l() functions, these wrappers return through the 'result' out parameter.
Include unit-tests for each wrapper function.
Carlos L. Torres (4):
cutils: Add qemu_strtol() wrapper
cutils: Add qemu_strtoul() wrapper
cutils: Add qemu_strtoll() wrapper
cutils: Add qemu_strtoull() wrapper
include/qemu-common.h | 8 + tests/test-cutils.c | 1172 +++++++++++++++++++++++++++++++++++++++++++++++++ util/cutils.c | 131 ++++++ 3 files changed, 1311 insertions(+)
Signature · 1 line
1.9.1
PATCH 1/4 cutils: Add qemu_strtol() wrapper
From: "Carlos L. Torres" <[email protected]>
Add wrapper for strtol() function. Include unit tests.
--- include/qemu-common.h | 2 + tests/test-cutils.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/cutils.c | 58 ++++++++++ 3 files changed, 352 insertions(+)
include/qemu-common.h +2 -0
@@ -161,6 +161,8 @@ int qemu_fls(int i);int qemu_fdatasync (int fd);int fcntl_setfl (int fd,int flag);int qemu_parse_fd (const char *param); +int qemu_strtol (const char *nptr,const char **endptr,int base, +long *result);int parse_uint (const char *s,unsigned long long *value,char **endptr,int base);
tests/test-cutils.c +292 -0
303 lines not on this page · raw message
util/cutils.c +58 -0
64 lines not on this page · raw message
Signature · 1 line
1.9.1
Re: [Qemu-devel] [PATCH 1/4] cutils: Add qemu_strtol() wrapper
Quoted 5 lines · Carlos L. Torres
From: "Carlos L. Torres" <[email protected]>
Add wrapper for
strtol()function. Include unit tests.Signed-off-by Carlos L. Torres <[email protected]>
Very thorough work, just a couple comments below.
Quoted 57 lines
--- include/qemu-common.h | 2 + tests/test-cutils.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/cutils.c | 58 ++++++++++ 3 files changed, 352 insertions(+)include/qemu-common.h +2
-0@@ -161,6 +161,8 @@ int qemu_fls(int i);int qemu_fdatasync (int fd);int fcntl_setfl (int fd,int flag);int qemu_parse_fd (const char *param); +int qemu_strtol (const char *nptr,const char **endptr,int base, +long *result);int parse_uint (const char *s,unsigned long long *value,char **endptr,int base);tests/test-cutils.c +30
-0@@ -226,6 +226,269 @@ static void test_parse_uint_full_correct(void) g_assert_cmpint(i, ==, 123); } +static void test_qemu_strtol_correct (void ) +{ +const char *str ="12345 foo" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 12345); +g_assert (endptr == str +5 ); +} + +static void test_qemu_strtol_null (void ) +{ +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (NULL , &endptr,0 , &res); + + g_assert_cmpint(err, ==, -EINVAL); +g_assert (endptr ==NULL ); +} + +static void test_qemu_strtol_empty (void ) +{
tests/test-cutils.c static void test_parse_uint_full_correct(void) · line 268
Quoted 10 lines
tests/test-cutils.c +10
-0+const char *str ="" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0);
Please assert that endptr == str.
Quoted 46 lines
tests/test-cutils.c +46
-0+} + +static void test_qemu_strtol_whitespace (void ) +{ +const char *str =" \t " ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0); +g_assert (endptr == str); +} + +static void test_qemu_strtol_invalid (void ) +{ +const char *str =" xxxx \t abc" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0); +g_assert (endptr == str); +} + +static void test_qemu_strtol_trailing (void ) +{ +const char *str ="123xxx" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 123); +g_assert (endptr == str +3 ); +}
tests/test-cutils.c static void test_parse_uint_full_correct(void) · line 324
Quoted 10 lines
tests/test-cutils.c +10
-0+ +static void test_qemu_strtol_octal (void ) +{ +const char *str ="0123" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,8 , &res);
Add a testcase for str = "0123" and base = 0?
Quoted 225 lines
tests/test-cutils.c +196
-0+ + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0123); +g_assert (endptr == str +strlen (str)); +} + +static void test_qemu_strtol_decimal (void ) +{ +const char *str ="0123" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,10 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 123); +g_assert (endptr == str +strlen (str)); +} + +static void test_qemu_strtol_hex (void ) +{ +const char *str ="0123" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,16 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0x123); +g_assert (endptr == str +strlen (str)); +} + +static void test_qemu_strtol_max (void ) +{ +const char *str =g_strdup_printf ("%ld" ,LONG_MAX ); +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, LONG_MAX); +g_assert (endptr == str +strlen (str)); +} + +static void test_qemu_strtol_overflow (void ) +{ +const char *str ="99999999999999999999999999999999999999999999" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpint(res, ==, LONG_MAX); +g_assert (endptr == str +strlen (str)); +} + +static void test_qemu_strtol_underflow (void ) +{ +const char *str ="-99999999999999999999999999999999999999999999" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpint(res, ==, LONG_MIN); +g_assert (endptr == str +strlen (str)); +} + +static void test_qemu_strtol_negative (void ) +{ +const char *str =" \t -321" ; +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (str, &endptr,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, -321); +g_assert (endptr == str +strlen (str)); +} + +static void test_qemu_strtol_full_correct (void ) +{ +const char *str ="123" ; +long res =999 ; +int err; + + err =qemu_strtol (str,NULL ,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 123); +} + +static void test_qemu_strtol_full_null (void ) +{ +char f ='X' ; +const char *endptr = &f; +long res =999 ; +int err; + + err =qemu_strtol (NULL , &endptr,0 , &res); + + g_assert_cmpint(err, ==, -EINVAL); +g_assert (endptr ==NULL ); +} + +static void test_qemu_strtol_full_empty (void ) +{ +const char *str ="" ; +long res =999L ; +int err; + + err =qemu_strtol (str,NULL ,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0); +} + +static void test_qemu_strtol_full_negative (void ) +{ +const char *str =" \t -321" ; +long res =999 ; +int err; + + err =qemu_strtol (str,NULL ,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, -321); +} + +static void test_qemu_strtol_full_trailing (void ) +{ +const char *str ="123xxx" ; +long res; +int err; + + err =qemu_strtol (str,NULL ,0 , &res); + + g_assert_cmpint(err, ==, -EINVAL); +} + +static void test_qemu_strtol_full_max (void ) +{ +const char *str =g_strdup_printf ("%ld" ,LONG_MAX ); +long res; +int err; + + err =qemu_strtol (str,NULL ,0 , &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, LONG_MAX); +}int main (int argc,char **argv) {g_test_init (&argc, &argv,NULL );@@ -247,5 +510,34 @@ int main(int argc, char **argv)g_test_add_func ("/cutils/parse_uint_full/correct" , test_parse_uint_full_correct); +/* qemu_strtol() tests */ +g_test_add_func ("/cutils/qemu_strtol/correct" , test_qemu_strtol_correct); +g_test_add_func ("/cutils/qemu_strtol/null" , test_qemu_strtol_null); +g_test_add_func ("/cutils/qemu_strtol/empty" , test_qemu_strtol_empty); +g_test_add_func ("/cutils/qemu_strtol/whitespace" , + test_qemu_strtol_whitespace); +g_test_add_func ("/cutils/qemu_strtol/invalid" , test_qemu_strtol_invalid); +g_test_add_func ("/cutils/qemu_strtol/trailing" , test_qemu_strtol_trailing); +g_test_add_func ("/cutils/qemu_strtol/octal" , test_qemu_strtol_octal); +g_test_add_func ("/cutils/qemu_strtol/decimal" , test_qemu_strtol_decimal); +g_test_add_func ("/cutils/qemu_strtol/hex" , test_qemu_strtol_hex); +g_test_add_func ("/cutils/qemu_strtol/max" , test_qemu_strtol_max); +g_test_add_func ("/cutils/qemu_strtol/overflow" , test_qemu_strtol_overflow); +g_test_add_func ("/cutils/qemu_strtol/underflow" , + test_qemu_strtol_underflow); +g_test_add_func ("/cutils/qemu_strtol/negative" , test_qemu_strtol_negative); +g_test_add_func ("/cutils/qemu_strtol_full/correct" , + test_qemu_strtol_full_correct); +g_test_add_func ("/cutils/qemu_strtol_full/null" , + test_qemu_strtol_full_null); +g_test_add_func ("/cutils/qemu_strtol_full/empty" , + test_qemu_strtol_full_empty); +g_test_add_func ("/cutils/qemu_strtol_full/negative" , + test_qemu_strtol_full_negative); +g_test_add_func ("/cutils/qemu_strtol_full/trailing" , + test_qemu_strtol_full_trailing); +g_test_add_func ("/cutils/qemu_strtol_full/max" , + test_qemu_strtol_full_max); +return g_test_run (); }util/cutils.c +12
-0@@ -359,6 +359,64 @@ int64_t strtosz(const char *nptr, char **end) }/** +* Helper function for qemu_strto*l() functions. +*/ +static int check_strtox_error (const char **next,char *endptr, +int err) +{ +if (!next && *endptr) { +return -EINVAL ; + } +if (next) { + *next = endptr; + } +return -err;
util/cutils.c int64_t strtosz(const char *nptr, char **end) · line 383
Quoted 10 lines
util/cutils.c +10
-0+} + +/** +* QEMU wrappers for strtol(), strtoll(), strtoul(), strotull() C functions. +* +* Convert ASCII string @nptr to a long integer value +* from the given @base. Parameters @nptr, @endptr, @base +* follows same semantics as strtol() C function. +* +* Different from strtol() function, if @endptr is not NULL, this
"Unlike the strtol() function," ...
util/cutils.c int64_t strtosz(const char *nptr, char **end) · line 392
Quoted 9 lines
util/cutils.c +9
-0+* function will return -EINVAL whenever it cannot fully convert +* the string in @nptr with given @base to a long. This function returns +* the result of the conversion only through the @result parameter. +* +* If NULL is passed in @endptr, then the whole string in @ntpr +* is a number otherwise it returns -EINVAL. +* +* RETURN VALUE +* Different from strtol() function, this wrapper returns either
Same here.
Quoted 31 lines
util/cutils.c +27
-0+* -EINVAL or the errno set by strtol() function (e.g -ERANGE). +* If the conversion overflows, -ERANGE is returned, and @result +* is set to the max value of the desired type +* (e.g. LONG_MAX, LLONG_MAX, ULONG_MAX, ULLONG_MAX). If the case +* of underflow, -ERANGE is returned, and @result is set to the min +* value of the desired type. For strtol(), strtoll(), @result is set to +* LONG_MIN, LLONG_MIN, respectively, and for strtoul(), strtoull() it +* is set to 0. +*/ +int qemu_strtol (const char *nptr,const char **endptr,int base, +long *result) +{ +char *p; +int err =0 ; +if (!nptr) { +if (endptr) { + *endptr = nptr; + } + err = -EINVAL ; + }else { + errno =0 ; + *result =strtol (nptr, &p, base); + err =check_strtox_error (endptr, p, errno); + } +return err; +} +/** * parse_uint: * * @s: String to parse
PATCH 2/4 cutils: Add qemu_strtoul() wrapper
In reply to Carlos L. TorresFrom: "Carlos L. Torres" <[email protected]>
Add wrapper for strtoul() function. Include unit tests.
--- include/qemu-common.h | 2 + tests/test-cutils.c | 291 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/cutils.c | 27 +++++ 3 files changed, 320 insertions(+)
include/qemu-common.h +2 -0
@@ -163,6 +163,8 @@ int fcntl_setfl(int fd, int flag);int qemu_parse_fd (const char *param);int qemu_strtol (const char *nptr,const char **endptr,int base,long *result); +int qemu_strtoul (const char *nptr,const char **endptr,int base, +unsigned long *result);int parse_uint (const char *s,unsigned long long *value,char **endptr,int base);
tests/test-cutils.c +291 -0
302 lines not on this page · raw message
util/cutils.c +27 -0
@@ -416,6 +416,33 @@ int qemu_strtol(const char *nptr, const char **endptr, int base, }return err; } + +/** +* Converts ASCII string to an unsigned long integer. +* +* If string contains a negative number, value will be converted to +* the unsigned representation of the signed value. +* +* See qemu_strtol() documentation for more info. +*/ +int qemu_strtoul (const char *nptr,const char **endptr,int base, +unsigned long *result) +{ +char *p; +int err =0 ; +if (!nptr) { +if (endptr) { + *endptr = nptr; + } + err = -EINVAL ; + }else { + errno =0 ; + *result =strtoul (nptr, &p, base); + err =check_strtox_error (endptr, p, errno); + } +return err; +} +/** * parse_uint: *
Signature · 1 line
1.9.1
Re: [Qemu-devel] [PATCH 2/4] cutils: Add qemu_strtoul() wrapper
util/cutils.c int qemu_strtol(const char *nptr, const char **endptr, int base, · line 424
Quoted 6 lines · Carlos L. Torres
util/cutils.c +6
-0+ +/** +* Converts ASCII string to an unsigned long integer. +* +* If string contains a negative number, value will be converted to +* the unsigned representation of the signed value.
Please document overflow here, as it is slightly different between strtol and strtoul.
Paolo
Quoted 2 lines
+ * See
qemu_strtol()documentation for more info.
+ */
PATCH 3/4 cutils: Add qemu_strtoll() wrapper
In reply to Carlos L. TorresFrom: "Carlos L. Torres" <[email protected]>
Add wrapper for strtoll() function. Include unit tests.
--- include/qemu-common.h | 2 + tests/test-cutils.c | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/cutils.c | 23 ++++ 3 files changed, 318 insertions(+)
include/qemu-common.h +2 -0
@@ -165,6 +165,8 @@ int qemu_strtol(const char *nptr, const char **endptr, int base, long *result);int qemu_strtoul (const char *nptr,const char **endptr,int base,unsigned long *result); +int qemu_strtoll (const char *nptr,const char **endptr,int base, +long long *result);int parse_uint (const char *s,unsigned long long *value,char **endptr,int base);
tests/test-cutils.c +293 -0
304 lines not on this page · raw message
util/cutils.c +23 -0
@@ -444,6 +444,29 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base, }/** +* Converts ASCII string to a long long integer. +* +* See qemu_strtol() documentation for more info. +*/ +int qemu_strtoll (const char *nptr,const char **endptr,int base, +long long *result) +{ +char *p; +int err =0 ; +if (!nptr) { +if (endptr) { + *endptr = nptr; + } + err = -EINVAL ; + }else { + errno =0 ; + *result =strtoll (nptr, &p, base); + err =check_strtox_error (endptr, p, errno); + } +return err; +} + +/** * parse_uint: * * @s: String to parse
Signature · 1 line
1.9.1
PATCH 4/4 cutils: Add qemu_strtoull() wrapper
In reply to Carlos L. TorresFrom: "Carlos L. Torres" <[email protected]>
Add wrapper for strtoull() function. Include unit tests.
--- include/qemu-common.h | 2 + tests/test-cutils.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/cutils.c | 23 ++++ 3 files changed, 321 insertions(+)
include/qemu-common.h +2 -0
@@ -167,6 +167,8 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base, unsigned long *result);int qemu_strtoll (const char *nptr,const char **endptr,int base,long long *result); +int qemu_strtoull (const char *nptr,const char **endptr,int base, +unsigned long long *result);int parse_uint (const char *s,unsigned long long *value,char **endptr,int base);
tests/test-cutils.c +296 -0
307 lines not on this page · raw message
util/cutils.c +23 -0
@@ -467,6 +467,29 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base, }/** +* Converts ASCII string to an unsigned long long integer. +* +* See qemu_strtol() documentation for more info. +*/ +int qemu_strtoull (const char *nptr,const char **endptr,int base, +unsigned long long *result) +{ +char *p; +int err =0 ; +if (!nptr) { +if (endptr) { + *endptr = nptr; + } + err = -EINVAL ; + }else { + errno =0 ; + *result =strtoull (nptr, &p, base); + err =check_strtox_error (endptr, p, errno); + } +return err; +} + +/** * parse_uint: * * @s: String to parse
Signature · 1 line
1.9.1
Quoted 22 lines · Carlos L. Torres
From: "Carlos L. Torres" <[email protected]>
Introduce
qemu_wrappers for strtol/strtoul/strtoll/strtoull C functions, ensure that errno is checked, and if NULL is passed as the endptr argument, then whole string has to be a valid number on the given base, otherwise return appropriate error.Different from the C strto*l() functions, these wrappers return through the 'result' out parameter.
Include unit-tests for each wrapper function.
Signed-off-by Carlos L. Torres <[email protected]>Carlos L. Torres (4):
cutils: Addqemu_strtol()wrapper
cutils: Addqemu_strtoul()wrapper
cutils: Addqemu_strtoll()wrapper
cutils: Addqemu_strtoull()wrapper
Quoted 5 lines
include/qemu-common.h | 8 + tests/test-cutils.c | 1172 +++++++++++++++++++++++++++++++++++++++++++++++++ util/cutils.c | 131 ++++++ 3 files changed, 1311 insertions(+)
This looks pretty much okay. Of course, you would include at least one conversion from strto* to qemu_strto* (not necessarily one per function, though one signed case and one unsigned case would be great).
Paolo