Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.   This code is based on wcstoul.c which has the following copyright.
  3.   It is used to convert a wide string into an unsigned long long.
  4.  
  5.   unsigned long long _wcstoull_r (struct _reent *rptr, const wchar_t *s,
  6.                                   wchar_t **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 <wchar.h>
  49. #include <wctype.h>
  50. #include <errno.h>
  51. #include <reent.h>
  52.  
  53. /* Make up for older non-compliant limits.h.  (This is a C99/POSIX function,
  54.  * and both require ULLONG_MAX in limits.h.)  */
  55. #if !defined(ULLONG_MAX)
  56. # define ULLONG_MAX     ULONG_LONG_MAX
  57. #endif
  58.  
  59. /*
  60.  * Convert a wide string to an unsigned long long integer.
  61.  *
  62.  * Ignores `locale' stuff.  Assumes that the upper and lower case
  63.  * alphabets and digits are each contiguous.
  64.  */
  65. unsigned long long
  66. _DEFUN (_wcstoull_r, (rptr, nptr, endptr, base),
  67.         struct _reent *rptr _AND
  68.         _CONST wchar_t *nptr _AND
  69.         wchar_t **endptr _AND
  70.         int base)
  71. {
  72.         register const wchar_t *s = nptr;
  73.         register unsigned long long acc;
  74.         register int c;
  75.         register unsigned long long cutoff;
  76.         register int neg = 0, any, cutlim;
  77.  
  78.         if(base < 0  ||  base == 1  ||  base > 36)  {
  79.                 rptr->_errno = EINVAL;
  80.                 return(0ULL);
  81.         }
  82.         /*
  83.          * See strtol for comments as to the logic used.
  84.          */
  85.         do {
  86.                 c = *s++;
  87.         } while (iswspace(c));
  88.         if (c == L'-') {
  89.                 neg = 1;
  90.                 c = *s++;
  91.         } else if (c == L'+')
  92.                 c = *s++;
  93.         if ((base == 0 || base == 16) &&
  94.             c == L'0' && (*s == L'x' || *s == L'X')) {
  95.                 c = s[1];
  96.                 s += 2;
  97.                 base = 16;
  98.         }
  99.         if (base == 0)
  100.                 base = c == L'0' ? 8 : 10;
  101.         cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base;
  102.         cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base;
  103.         for (acc = 0, any = 0;; c = *s++) {
  104.                 if (iswdigit(c))
  105.                         c -= L'0';
  106.                 else if (iswalpha(c))
  107.                         c -= iswupper(c) ? L'A' - 10 : L'a' - 10;
  108.                 else
  109.                         break;
  110.                 if (c >= base)
  111.                         break;
  112.                if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
  113.                         any = -1;
  114.                 else {
  115.                         any = 1;
  116.                         acc *= base;
  117.                         acc += c;
  118.                 }
  119.         }
  120.         if (any < 0) {
  121.                 acc = ULLONG_MAX;
  122.                 rptr->_errno = ERANGE;
  123.         } else if (neg)
  124.                 acc = -acc;
  125.         if (endptr != 0)
  126.                 *endptr = (wchar_t *) (any ? s - 1 : nptr);
  127.         return (acc);
  128. }
  129.  
  130. #endif /* __GNUC__ */
  131.