This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [RFA] Add new function strtoull()


"John R. Moore" wrote:
> 
> For 64-bit architectures, gdbtk needs a function exactly
> like strtoul(), but that extends "unsigned long" to
> be "unsigned long long". I'm proposing strtoull to be added
> to newlib/libc/stdlib/strtoul.c since it mimics strtoul.
> 
> The following code has been tested using gcc-2.97 on linux-2.4.2 kernel:
> 
> 2001-04-19  John R. Moore  <jmoore@redhat.com>
> 
>         * newlib/libc/stdlib/strtoul.c: Added new strtoull() and
>         _strtoull_r.
> 

Thanks John.  I am going to make a change though.  The code should sit
in its own file to prevent excessive code bloat to an application that
needs strtoul.

-- Jeff J.

> Index: newlib/libc/stdlib/strtoul.c
> ===================================================================
> RCS file: /cvs/cvsfiles/devo/newlib/libc/stdlib/strtoul.c,v
> retrieving revision 1.13
> diff -p -u -r1.13 strtoul.c
> --- newlib/libc/stdlib/strtoul.c        2000/04/17 17:11:23     1.13
> +++ newlib/libc/stdlib/strtoul.c        2001/04/19 18:49:43
> @@ -204,3 +204,83 @@ _DEFUN (strtoul, (s, ptr, base),
>  }
> 
>  #endif
> +
> +/*
> + * Convert a string to an unsigned long long integer.
> + *
> + * Ignores `locale' stuff.  Assumes that the upper and lower case
> + * alphabets and digits are each contiguous.
> + */
> +unsigned long long
> +_DEFUN (_strtoull_r, (rptr, nptr, endptr, base),
> +       struct _reent *rptr _AND
> +       _CONST char *nptr _AND
> +       char **endptr _AND
> +       int base)
> +{
> +       register const char *s = nptr;
> +       register unsigned long long acc;
> +       register int c;
> +       register unsigned long long cutoff;
> +       register int neg = 0, any, cutlim;
> +
> +       /*
> +        * See strtol for comments as to the logic used.
> +        */
> +       do {
> +               c = *s++;
> +       } while (isspace(c));
> +       if (c == '-') {
> +               neg = 1;
> +               c = *s++;
> +       } else if (c == '+')
> +               c = *s++;
> +       if ((base == 0 || base == 16) &&
> +           c == '0' && (*s == 'x' || *s == 'X')) {
> +               c = s[1];
> +               s += 2;
> +               base = 16;
> +       }
> +       if (base == 0)
> +               base = c == '0' ? 8 : 10;
> +       cutoff = (unsigned long long)ULONG_LONG_MAX / (unsigned long long)base;
> +       cutlim = (unsigned long long)ULONG_LONG_MAX % (unsigned long long)base;
> +       for (acc = 0, any = 0;; c = *s++) {
> +               if (isdigit(c))
> +                       c -= '0';
> +               else if (isalpha(c))
> +                       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
> +               else
> +                       break;
> +               if (c >= base)
> +                       break;
> +               if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
> +                       any = -1;
> +               else {
> +                       any = 1;
> +                       acc *= base;
> +                       acc += c;
> +               }
> +       }
> +       if (any < 0) {
> +               acc = ULONG_LONG_MAX;
> +               rptr->_errno = ERANGE;
> +       } else if (neg)
> +               acc = -acc;
> +       if (endptr != 0)
> +               *endptr = (char *) (any ? s - 1 : nptr);
> +       return (acc);
> +}
> +
> +#ifndef _REENT_ONLY
> +
> +unsigned long long
> +_DEFUN (strtoull, (s, ptr, base),
> +       _CONST char *s _AND
> +       char **ptr _AND
> +       int base)
> +{
> +       return _strtoull_r (_REENT, s, ptr, base);
> +}
> +
> +#endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]