0,0 → 1,130 |
/* |
This code is based on wcstoul.c which has the following copyright. |
It is used to convert a wide string into an unsigned long long. |
|
unsigned long long _wcstoull_r (struct _reent *rptr, const wchar_t *s, |
wchar_t **ptr, int base); |
|
*/ |
|
/* |
* Copyright (c) 1990 Regents of the University of California. |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
|
#ifdef __GNUC__ |
|
#define _GNU_SOURCE |
#include <_ansi.h> |
#include <limits.h> |
#include <wchar.h> |
#include <wctype.h> |
#include <errno.h> |
#include <reent.h> |
|
/* Make up for older non-compliant limits.h. (This is a C99/POSIX function, |
* and both require ULLONG_MAX in limits.h.) */ |
#if !defined(ULLONG_MAX) |
# define ULLONG_MAX ULONG_LONG_MAX |
#endif |
|
/* |
* Convert a wide 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 (_wcstoull_r, (rptr, nptr, endptr, base), |
struct _reent *rptr _AND |
_CONST wchar_t *nptr _AND |
wchar_t **endptr _AND |
int base) |
{ |
register const wchar_t *s = nptr; |
register unsigned long long acc; |
register int c; |
register unsigned long long cutoff; |
register int neg = 0, any, cutlim; |
|
if(base < 0 || base == 1 || base > 36) { |
rptr->_errno = EINVAL; |
return(0ULL); |
} |
/* |
* See strtol for comments as to the logic used. |
*/ |
do { |
c = *s++; |
} while (iswspace(c)); |
if (c == L'-') { |
neg = 1; |
c = *s++; |
} else if (c == L'+') |
c = *s++; |
if ((base == 0 || base == 16) && |
c == L'0' && (*s == L'x' || *s == L'X')) { |
c = s[1]; |
s += 2; |
base = 16; |
} |
if (base == 0) |
base = c == L'0' ? 8 : 10; |
cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base; |
cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base; |
for (acc = 0, any = 0;; c = *s++) { |
if (iswdigit(c)) |
c -= L'0'; |
else if (iswalpha(c)) |
c -= iswupper(c) ? L'A' - 10 : L'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 = ULLONG_MAX; |
rptr->_errno = ERANGE; |
} else if (neg) |
acc = -acc; |
if (endptr != 0) |
*endptr = (wchar_t *) (any ? s - 1 : nptr); |
return (acc); |
} |
|
#endif /* __GNUC__ */ |