Re: [kvm-unit-tests PATCH v2 1/3] lib/string: Add stroull and strtoll

Andrew Jones
2021-10-13T16:44:11Z

On Mon, Sep 27, 2021 at 03:30:26PM +0000, ahmeddan@amazon.com wrote:
> From: Daniele Ahmed <ahmeddan@amazon.com>
>
> Add the two functions strtoull and strtoll.
> This is in preparation for an update
> in x86/msr.c to write 64b values
> that are given as inputs as strings by
> a user.
>
> Signed-off-by: Daniele Ahmed <ahmeddan@amazon.com>
> ---
> lib/stdlib.h | 2 ++
> lib/string.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 76 insertions(+)
>
> diff --git a/lib/stdlib.h b/lib/stdlib.h
> index 33c00e8..48e10f0 100644
> --- a/lib/stdlib.h
> +++ b/lib/stdlib.h
> @@ -9,5 +9,7 @@
>
> long int strtol(const char *nptr, char **endptr, int base);
> unsigned long int strtoul(const char *nptr, char **endptr, int base);
> +long long int strtoll(const char *nptr, char **endptr, int base);
> +unsigned long long strtoull(const char *nptr, char **endptr, int base);
>
> #endif /* _STDLIB_H_ */
> diff --git a/lib/string.c b/lib/string.c
> index ffc7c7e..dacd927 100644
> --- a/lib/string.c
> +++ b/lib/string.c
> @@ -242,6 +242,80 @@ unsigned long int strtoul(const char *nptr, char **endptr, int base)
> return __strtol(nptr, endptr, base, false);
> }
>
> +static unsigned long long __strtoll(const char *nptr, char **endptr,
> + int base, bool is_signed) {
> + unsigned long long acc = 0;
> + const char *s = nptr;
> + int neg, c;
> +
> + assert(base == 0 || (base >= 2 && base <= 36));
> +
> + while (isspace(*s))
> + s++;
> +
> + if (*s == '-') {
> + neg = 1;
> + s++;
> + } else {
> + neg = 0;
> + if (*s == '+')
> + s++;
> + }
> +
> + if (base == 0 || base == 16) {
> + if (*s == '0') {
> + s++;
> + if (*s == 'x' || *s == 'X') {
> + s++;
> + base = 16;
> + } else if (base == 0)
> + base = 8;
> + } else if (base == 0)
> + base = 10;
> + }
> +
> + while (*s) {
> + if (*s >= '0' && *s < '0' + base && *s <= '9')
> + c = *s - '0';
> + else if (*s >= 'a' && *s < 'a' + base - 10)
> + c = *s - 'a' + 10;
> + else if (*s >= 'A' && *s < 'A' + base - 10)
> + c = *s - 'A' + 10;
> + else
> + break;
> +
> + if (is_signed) {
> + long long sacc = (long long)acc;
> + assert(!check_mul_overflow(sacc, base));
> + assert(!check_add_overflow(sacc * base, c));
> + } else {
> + assert(!check_mul_overflow(acc, base));
> + assert(!check_add_overflow(acc * base, c));
> + }
> +
> + acc = acc * base + c;
> + s++;
> + }
> +
> + if (neg)
> + acc = -acc;
> +
> + if (endptr)
> + *endptr = (char *)s;
> +
> + return acc;
> +}
> +
> +long long int strtoll(const char *nptr, char **endptr, int base)
> +{
> + return __strtoll(nptr, endptr, base, true);
> +}
> +
> +unsigned long long int strtoull(const char *nptr, char **endptr, int base)
> +{
> + return __strtoll(nptr, endptr, base, false);
> +}
> +
> long atol(const char *ptr)
> {
> return strtol(ptr, NULL, 10);
> --
> 2.32.0
>
>

Hi Daniele,

I just sent an alternative to this patch which doesn't requiring
duplicating as much code.

Thanks,
drew

>
>
> Amazon Development Center Germany GmbH
> Krausenstr. 38
> 10117 Berlin
> Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
> Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
> Sitz: Berlin
> Ust-ID: DE 289 237 879
>
>
>