Subversion Repositories Kolibri OS

Rev

Rev 4874 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.   This code is based on strtoul.c which has the following copyright.
  3.   It is used to convert a string into an unsigned long long.
  4.  
  5.   long long _strtoull_r (struct _reent *rptr, const char *s,
  6.                         char **ptr, int base);
  7.  
  8. */
  9.  
  10. /*
  11.  * Copyright (c) 1990 Regents of the University of California.
  12.  * All rights reserved.
  13.  *
  14.  * Redistribution and use in source and binary forms, with or without
  15.  * modification, are permitted provided that the following conditions
  16.  * are met:
  17.  * 1. Redistributions of source code must retain the above copyright
  18.  *    notice, this list of conditions and the following disclaimer.
  19.  * 2. Redistributions in binary form must reproduce the above copyright
  20.  *    notice, this list of conditions and the following disclaimer in the
  21.  *    documentation and/or other materials provided with the distribution.
  22.  * 3. All advertising materials mentioning features or use of this software
  23.  *    must display the following acknowledgement:
  24.  *      This product includes software developed by the University of
  25.  *      California, Berkeley and its contributors.
  26.  * 4. Neither the name of the University nor the names of its contributors
  27.  *    may be used to endorse or promote products derived from this software
  28.  *    without specific prior written permission.
  29.  *
  30.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  31.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  34.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  38.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  39.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  40.  * SUCH DAMAGE.
  41.  */
  42.  
  43. #ifdef __GNUC__
  44.  
  45. #define _GNU_SOURCE
  46. #include <_ansi.h>
  47. #include <limits.h>
  48. #include <ctype.h>
  49. #include <errno.h>
  50. #include <stdlib.h>
  51. #include <reent.h>
  52.  
  53. /*
  54.  * Convert a string to an unsigned long long integer.
  55.  *
  56.  * Ignores `locale' stuff.  Assumes that the upper and lower case
  57.  * alphabets and digits are each contiguous.
  58.  */
  59. unsigned long long
  60. _DEFUN (_strtoull_r, (rptr, nptr, endptr, base),
  61.         struct _reent *rptr _AND
  62.         _CONST char *__restrict nptr _AND
  63.         char **__restrict endptr _AND
  64.         int base)
  65. {
  66.         register const unsigned char *s = (const unsigned char *)nptr;
  67.         register unsigned long long acc;
  68.         register int c;
  69.         register unsigned long long cutoff;
  70.         register int neg = 0, any, cutlim;
  71.  
  72.         /*
  73.          * See strtol for comments as to the logic used.
  74.          */
  75.         do {
  76.                 c = *s++;
  77.         } while (isspace(c));
  78.         if (c == '-') {
  79.                 neg = 1;
  80.                 c = *s++;
  81.         } else if (c == '+')
  82.                 c = *s++;
  83.         if ((base == 0 || base == 16) &&
  84.             c == '0' && (*s == 'x' || *s == 'X')) {
  85.                 c = s[1];
  86.                 s += 2;
  87.                 base = 16;
  88.         }
  89.         if (base == 0)
  90.                 base = c == '0' ? 8 : 10;
  91.         cutoff = (unsigned long long)ULONG_LONG_MAX / (unsigned long long)base;
  92.         cutlim = (unsigned long long)ULONG_LONG_MAX % (unsigned long long)base;
  93.         for (acc = 0, any = 0;; c = *s++) {
  94.                 if (isdigit(c))
  95.                         c -= '0';
  96.                 else if (isalpha(c))
  97.                         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
  98.                 else
  99.                         break;
  100.                 if (c >= base)
  101.                         break;
  102.                if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
  103.                         any = -1;
  104.                 else {
  105.                         any = 1;
  106.                         acc *= base;
  107.                         acc += c;
  108.                 }
  109.         }
  110.         if (any < 0) {
  111.                 acc = ULONG_LONG_MAX;
  112.                 rptr->_errno = ERANGE;
  113.         } else if (neg)
  114.                 acc = -acc;
  115.         if (endptr != 0)
  116.                 *endptr = (char *) (any ? (char *)s - 1 : nptr);
  117.         return (acc);
  118. }
  119.  
  120. #endif /* __GNUC__ */
  121.