diff options
Diffstat (limited to 'newlib/libc/stdlib')
-rw-r--r-- | newlib/libc/stdlib/Makefile.am | 11 | ||||
-rw-r--r-- | newlib/libc/stdlib/Makefile.in | 57 | ||||
-rw-r--r-- | newlib/libc/stdlib/stdlib.tex | 16 | ||||
-rw-r--r-- | newlib/libc/stdlib/strtoll.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdlib/strtoull.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdlib/wcstol.c | 226 | ||||
-rw-r--r-- | newlib/libc/stdlib/wcstoll.c | 138 | ||||
-rw-r--r-- | newlib/libc/stdlib/wcstoll_r.c | 140 | ||||
-rw-r--r-- | newlib/libc/stdlib/wcstoul.c | 206 | ||||
-rw-r--r-- | newlib/libc/stdlib/wcstoull.c | 139 | ||||
-rw-r--r-- | newlib/libc/stdlib/wcstoull_r.c | 120 |
11 files changed, 1052 insertions, 5 deletions
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am index 0874729c5..ce3bcbca4 100644 --- a/newlib/libc/stdlib/Makefile.am +++ b/newlib/libc/stdlib/Makefile.am @@ -50,6 +50,8 @@ GENERAL_SOURCES = \ strtod.c \ strtol.c \ strtoul.c \ + wcstol.c \ + wcstoul.c \ wcstombs.c \ wcstombs_r.c \ wctomb.c \ @@ -76,6 +78,10 @@ EXTENDED_SOURCES = \ strtoll_r.c \ strtoull.c \ strtoull_r.c \ + wcstoll.c \ + wcstoll_r.c \ + wcstoull.c \ + wcstoull_r.c \ atoll.c \ llabs.c \ lldiv.c @@ -231,7 +237,12 @@ CHEWOUT_FILES= \ strtoll.def \ strtoul.def \ strtoull.def \ + wcstol.def \ + wcstoll.def \ + wcstoul.def \ + wcstoull.def \ system.def \ + wcstol.def \ wcstombs.def \ wctomb.def diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in index dcf8ec8d3..6c28791a7 100644 --- a/newlib/libc/stdlib/Makefile.in +++ b/newlib/libc/stdlib/Makefile.in @@ -86,7 +86,8 @@ am__objects_1 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \ lib_a-mstats.$(OBJEXT) lib_a-rand.$(OBJEXT) \ lib_a-rand_r.$(OBJEXT) lib_a-realloc.$(OBJEXT) \ lib_a-strtod.$(OBJEXT) lib_a-strtol.$(OBJEXT) \ - lib_a-strtoul.$(OBJEXT) lib_a-wcstombs.$(OBJEXT) \ + lib_a-strtoul.$(OBJEXT) lib_a-wcstol.$(OBJEXT) \ + lib_a-wcstoul.$(OBJEXT) lib_a-wcstombs.$(OBJEXT) \ lib_a-wcstombs_r.$(OBJEXT) lib_a-wctomb.$(OBJEXT) \ lib_a-wctomb_r.$(OBJEXT) am__objects_2 = lib_a-cxa_atexit.$(OBJEXT) \ @@ -100,6 +101,8 @@ am__objects_2 = lib_a-cxa_atexit.$(OBJEXT) \ lib_a-srand48.$(OBJEXT) lib_a-strtoll.$(OBJEXT) \ lib_a-strtoll_r.$(OBJEXT) lib_a-strtoull.$(OBJEXT) \ lib_a-strtoull_r.$(OBJEXT) lib_a-atoll.$(OBJEXT) \ + lib_a-wcstoll.$(OBJEXT) lib_a-wcstoll_r.$(OBJEXT) \ + lib_a-wcstoull.$(OBJEXT) lib_a-wcstoull_r.$(OBJEXT) \ lib_a-llabs.$(OBJEXT) lib_a-lldiv.$(OBJEXT) am__objects_3 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \ lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \ @@ -131,12 +134,14 @@ am__objects_7 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \ ldiv.lo ldtoa.lo malloc.lo mblen.lo mblen_r.lo mbstowcs.lo \ mbstowcs_r.lo mbtowc.lo mbtowc_r.lo mlock.lo mprec.lo \ mstats.lo rand.lo rand_r.lo realloc.lo strtod.lo strtol.lo \ - strtoul.lo wcstombs.lo wcstombs_r.lo wctomb.lo wctomb_r.lo + strtoul.lo wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo \ + wctomb.lo wctomb_r.lo am__objects_8 = cxa_atexit.lo cxa_finalize.lo drand48.lo ecvtbuf.lo \ efgcvt.lo erand48.lo jrand48.lo lcong48.lo lrand48.lo \ mrand48.lo msize.lo mtrim.lo nrand48.lo rand48.lo seed48.lo \ srand48.lo strtoll.lo strtoll_r.lo strtoull.lo strtoull_r.lo \ - atoll.lo llabs.lo lldiv.lo + wcstoll.lo wcstoll_r.lo wcstoull.o wcstoull_r.lo atoll.lo \ + llabs.lo lldiv.lo am__objects_9 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \ malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsrtowcs.lo \ on_exit.lo valloc.lo wcrtomb.lo wcsrtombs.lo wctob.lo @@ -374,6 +379,8 @@ GENERAL_SOURCES = \ strtod.c \ strtol.c \ strtoul.c \ + wcstol.c \ + wcstoul.c \ wcstombs.c \ wcstombs_r.c \ wctomb.c \ @@ -400,6 +407,10 @@ EXTENDED_SOURCES = \ strtoll_r.c \ strtoull.c \ strtoull_r.c \ + wcstoll.c \ + wcstoll_r.c \ + wcstoull.c \ + wcstoull_r.c \ atoll.c \ llabs.c \ lldiv.c @@ -503,6 +514,10 @@ CHEWOUT_FILES = \ strtoul.def \ strtoull.def \ system.def \ + wcstol.def \ + wcstoll.def \ + wcstoul.def \ + wcstoull.def \ wcstombs.def \ wctomb.def @@ -847,6 +862,18 @@ lib_a-strtoul.o: strtoul.c lib_a-strtoul.obj: strtoul.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtoul.obj `if test -f 'strtoul.c'; then $(CYGPATH_W) 'strtoul.c'; else $(CYGPATH_W) '$(srcdir)/strtoul.c'; fi` +lib_a-wcstol.o: wcstol.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstol.o `test -f 'wcstol.c' || echo '$(srcdir)/'`wcstol.c + +lib_a-wcstol.obj: wcstol.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstol.obj `if test -f 'wcstol.c'; then $(CYGPATH_W) 'wcstol.c'; else $(CYGPATH_W) '$(srcdir)/wcstol.c'; fi` + +lib_a-wcstoul.o: wcstoul.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoul.o `test -f 'wcstoul.c' || echo '$(srcdir)/'`wcstoul.c + +lib_a-wcstoul.obj: wcstoul.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoul.obj `if test -f 'wcstoul.c'; then $(CYGPATH_W) 'wcstoul.c'; else $(CYGPATH_W) '$(srcdir)/wcstoul.c'; fi` + lib_a-wcstombs.o: wcstombs.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstombs.o `test -f 'wcstombs.c' || echo '$(srcdir)/'`wcstombs.c @@ -991,6 +1018,30 @@ lib_a-strtoull_r.o: strtoull_r.c lib_a-strtoull_r.obj: strtoull_r.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtoull_r.obj `if test -f 'strtoull_r.c'; then $(CYGPATH_W) 'strtoull_r.c'; else $(CYGPATH_W) '$(srcdir)/strtoull_r.c'; fi` +lib_a-wcstoll.o: wcstoll.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoll.o `test -f 'wcstoll.c' || echo '$(srcdir)/'`wcstoll.c + +lib_a-wcstoll.obj: wcstoll.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoll.obj `if test -f 'wcstoll.c'; then $(CYGPATH_W) 'wcstoll.c'; else $(CYGPATH_W) '$(srcdir)/wcstoll.c'; fi` + +lib_a-wcstoll_r.o: wcstoll_r.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoll_r.o `test -f 'wcstoll_r.c' || echo '$(srcdir)/'`wcstoll_r.c + +lib_a-wcstoll_r.obj: wcstoll_r.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoll_r.obj `if test -f 'wcstoll_r.c'; then $(CYGPATH_W) 'wcstoll_r.c'; else $(CYGPATH_W) '$(srcdir)/wcstoll_r.c'; fi` + +lib_a-wcstoull.o: wcstoull.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoull.o `test -f 'wcstoull.c' || echo '$(srcdir)/'`wcstoull.c + +lib_a-wcstoull.obj: wcstoull.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoull.obj `if test -f 'wcstoull.c'; then $(CYGPATH_W) 'wcstoull.c'; else $(CYGPATH_W) '$(srcdir)/wcstoull.c'; fi` + +lib_a-wcstoull_r.o: wcstoull_r.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoull_r.o `test -f 'wcstoull_r.c' || echo '$(srcdir)/'`wcstoull_r.c + +lib_a-wcstoull_r.obj: wcstoull_r.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstoull_r.obj `if test -f 'wcstoull_r.c'; then $(CYGPATH_W) 'wcstoull_r.c'; else $(CYGPATH_W) '$(srcdir)/wcstoull_r.c'; fi` + lib_a-atoll.o: atoll.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-atoll.o `test -f 'atoll.c' || echo '$(srcdir)/'`atoll.c diff --git a/newlib/libc/stdlib/stdlib.tex b/newlib/libc/stdlib/stdlib.tex index 9d19b71a8..acb4894a5 100644 --- a/newlib/libc/stdlib/stdlib.tex +++ b/newlib/libc/stdlib/stdlib.tex @@ -40,6 +40,10 @@ The corresponding declarations are in the header file @file{stdlib.h}. * strtoll:: String to long long * strtoul:: String to unsigned long * strtoull:: String to unsigned long long +* wcstol:: Wide string to long +* wcstoll:: Wide string to long long +* wcstoul:: Wide string to unsigned long +* wcstoull:: Wide string to unsigned long long * system:: Execute command string * wcstombs:: Minimal wide string to multibyte string converter * wctomb:: Minimal wide character to multibyte converter @@ -148,6 +152,18 @@ The corresponding declarations are in the header file @file{stdlib.h}. @include stdlib/strtoull.def @page +@include stdlib/wcstol.def + +@page +@include stdlib/wcstoll.def + +@page +@include stdlib/wcstoul.def + +@page +@include stdlib/wcstoull.def + +@page @include stdlib/system.def @page diff --git a/newlib/libc/stdlib/strtoll.c b/newlib/libc/stdlib/strtoll.c index 3ee9e7592..47558a8fd 100644 --- a/newlib/libc/stdlib/strtoll.c +++ b/newlib/libc/stdlib/strtoll.c @@ -78,7 +78,7 @@ made, 0 is returned. the converted value is too large, and sets <<errno>> to <<ERANGE>>. PORTABILITY -<<strtoll>> is nonstandard. +<<strtoll>> is ANSI. No supporting OS subroutines are required. */ diff --git a/newlib/libc/stdlib/strtoull.c b/newlib/libc/stdlib/strtoull.c index f7ab963a0..ec168b7f9 100644 --- a/newlib/libc/stdlib/strtoull.c +++ b/newlib/libc/stdlib/strtoull.c @@ -80,7 +80,7 @@ made, <<0>> is returned. value is too large, and sets <<errno>> to <<ERANGE>>. PORTABILITY -<<strtoull>> is nonstandard. +<<strtoull>> is ANSI. <<strtoull>> requires no supporting OS subroutines. */ diff --git a/newlib/libc/stdlib/wcstol.c b/newlib/libc/stdlib/wcstol.c new file mode 100644 index 000000000..e23254dc2 --- /dev/null +++ b/newlib/libc/stdlib/wcstol.c @@ -0,0 +1,226 @@ +/* +FUNCTION + <<wcstol>>---wide string to long + +INDEX + wcstol +INDEX + _wcstol_r + +ANSI_SYNOPSIS + #include <wchar.h> + long wcstol(const wchar_t *<[s]>, wchar_t **<[ptr]>,int <[base]>); + + long _wcstol_r(void *<[reent]>, + const wchar_t *<[s]>, wchar_t **<[ptr]>,int <[base]>); + +TRAD_SYNOPSIS + #include <stdlib.h> + long wcstol (<[s]>, <[ptr]>, <[base]>) + wchar_t *<[s]>; + wchar_t **<[ptr]>; + int <[base]>; + + long _wcstol_r (<[reent]>, <[s]>, <[ptr]>, <[base]>) + struct _reent *<[reent]>; + wchar_t *<[s]>; + wchar_t **<[ptr]>; + int <[base]>; + +DESCRIPTION +The function <<wcstol>> converts the wide string <<*<[s]>>> to +a <<long>>. First, it breaks down the string into three parts: +leading whitespace, which is ignored; a subject string consisting +of characters resembling an integer in the radix specified by <[base]>; +and a trailing portion consisting of zero or more unparseable characters, +and always including the terminating null character. Then, it attempts +to convert the subject string into a <<long>> and returns the +result. + +If the value of <[base]> is 0, the subject string is expected to look +like a normal C integer constant: an optional sign, a possible `<<0x>>' +indicating a hexadecimal base, and a number. If <[base]> is between +2 and 36, the expected form of the subject is a sequence of letters +and digits representing an integer in the radix specified by <[base]>, +with an optional plus or minus sign. The letters <<a>>--<<z>> (or, +equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35; +only letters whose ascribed values are less than <[base]> are +permitted. If <[base]> is 16, a leading <<0x>> is permitted. + +The subject sequence is the longest initial sequence of the input +string that has the expected form, starting with the first +non-whitespace character. If the string is empty or consists entirely +of whitespace, or if the first non-whitespace character is not a +permissible letter or digit, the subject string is empty. + +If the subject string is acceptable, and the value of <[base]> is zero, +<<wcstol>> attempts to determine the radix from the input string. A +string with a leading <<0x>> is treated as a hexadecimal value; a string with +a leading 0 and no <<x>> is treated as octal; all other strings are +treated as decimal. If <[base]> is between 2 and 36, it is used as the +conversion radix, as described above. If the subject string begins with +a minus sign, the value is negated. Finally, a pointer to the first +character past the converted subject string is stored in <[ptr]>, if +<[ptr]> is not <<NULL>>. + +If the subject string is empty (or not in acceptable form), no conversion +is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is +not <<NULL>>). + +The alternate function <<_wcstol_r>> is a reentrant version. The +extra argument <[reent]> is a pointer to a reentrancy structure. + +RETURNS +<<wcstol>> returns the converted value, if any. If no conversion was +made, 0 is returned. + +<<wcstol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of +the converted value is too large, and sets <<errno>> to <<ERANGE>>. + +PORTABILITY +<<wcstol>> is ANSI. + +No supporting OS subroutines are required. +*/ + +/*- + * Copyright (c) 1990 The 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. + */ + + +#include <_ansi.h> +#include <limits.h> +#include <wctype.h> +#include <errno.h> +#include <wchar.h> +#include <reent.h> + +/* + * Convert a wide string to a long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long +_DEFUN (_wcstol_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 acc; + register int c; + register unsigned long cutoff; + register int neg = 0, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + 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; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; + cutlim = cutoff % (unsigned long)base; + cutoff /= (unsigned 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 = neg ? LONG_MIN : LONG_MAX; + rptr->_errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (wchar_t *) (any ? s - 1 : nptr); + return (acc); +} + +#ifndef _REENT_ONLY + +long +_DEFUN (wcstol, (s, ptr, base), + _CONST wchar_t *s _AND + wchar_t **ptr _AND + int base) +{ + return _wcstol_r (_REENT, s, ptr, base); +} + +#endif diff --git a/newlib/libc/stdlib/wcstoll.c b/newlib/libc/stdlib/wcstoll.c new file mode 100644 index 000000000..75eda9f6c --- /dev/null +++ b/newlib/libc/stdlib/wcstoll.c @@ -0,0 +1,138 @@ +/* +FUNCTION + <<wcstoll>>---wide string to long long + +INDEX + wcstoll +INDEX + _wcstoll_r + +ANSI_SYNOPSIS + #include <wchar.h> + long long wcstoll(const wchar_t *<[s]>, wchar_t **<[ptr]>,int <[base]>); + + long long _wcstoll_r(void *<[reent]>, + const wchar_t *<[s]>, wchar_t **<[ptr]>,int <[base]>); + +TRAD_SYNOPSIS + #include <stdlib.h> + long long wcstoll (<[s]>, <[ptr]>, <[base]>) + const wchar_t *<[s]>; + wchar_t **<[ptr]>; + int <[base]>; + + long long _wcstoll_r (<[reent]>, <[s]>, <[ptr]>, <[base]>) + wchar_t *<[reent]>; + const wchar_t *<[s]>; + wchar_t **<[ptr]>; + int <[base]>; + +DESCRIPTION +The function <<wcstoll>> converts the wide string <<*<[s]>>> to +a <<long long>>. First, it breaks down the string into three parts: +leading whitespace, which is ignored; a subject string consisting +of characters resembling an integer in the radix specified by <[base]>; +and a trailing portion consisting of zero or more unparseable characters, +and always including the terminating null character. Then, it attempts +to convert the subject string into a <<long long>> and returns the +result. + +If the value of <[base]> is 0, the subject string is expected to look +like a normal C integer constant: an optional sign, a possible `<<0x>>' +indicating a hexadecimal base, and a number. If <[base]> is between +2 and 36, the expected form of the subject is a sequence of letters +and digits representing an integer in the radix specified by <[base]>, +with an optional plus or minus sign. The letters <<a>>--<<z>> (or, +equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35; +only letters whose ascribed values are less than <[base]> are +permitted. If <[base]> is 16, a leading <<0x>> is permitted. + +The subject sequence is the longest initial sequence of the input +string that has the expected form, starting with the first +non-whitespace character. If the string is empty or consists entirely +of whitespace, or if the first non-whitespace character is not a +permissible letter or digit, the subject string is empty. + +If the subject string is acceptable, and the value of <[base]> is zero, +<<wcstoll>> attempts to determine the radix from the input string. A +string with a leading <<0x>> is treated as a hexadecimal value; a string with +a leading 0 and no <<x>> is treated as octal; all other strings are +treated as decimal. If <[base]> is between 2 and 36, it is used as the +conversion radix, as described above. If the subject string begins with +a minus sign, the value is negated. Finally, a pointer to the first +character past the converted subject string is stored in <[ptr]>, if +<[ptr]> is not <<NULL>>. + +If the subject string is empty (or not in acceptable form), no conversion +is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is +not <<NULL>>). + +The alternate function <<_wcstoll_r>> is a reentrant version. The +extra argument <[reent]> is a pointer to a reentrancy structure. + +RETURNS +<<wcstoll>> returns the converted value, if any. If no conversion was +made, 0 is returned. + +<<wcstoll>> returns <<LONG_LONG_MAX>> or <<LONG_LONG_MIN>> if the magnitude of +the converted value is too large, and sets <<errno>> to <<ERANGE>>. + +PORTABILITY +<<wcstoll>> is ANSI. + +No supporting OS subroutines are required. +*/ + +/*- + * Copyright (c) 1990 The 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. + */ + + +#include <_ansi.h> +#include <limits.h> +#include <wctype.h> +#include <errno.h> +#include <wchar.h> +#include <reent.h> + +#ifndef _REENT_ONLY + +long long +_DEFUN (wcstoll, (s, ptr, base), + _CONST wchar_t *s _AND + wchar_t **ptr _AND + int base) +{ + return _wcstoll_r (_REENT, s, ptr, base); +} + +#endif diff --git a/newlib/libc/stdlib/wcstoll_r.c b/newlib/libc/stdlib/wcstoll_r.c new file mode 100644 index 000000000..d6baacaf5 --- /dev/null +++ b/newlib/libc/stdlib/wcstoll_r.c @@ -0,0 +1,140 @@ +/* + This code is based on strtoul.c which has the following copyright. + It is used to convert a wide string into a signed long long. + + long long _wcstoll_r (struct _reent *rptr, const wchar_t *s, + wchar_t **ptr, int base); +*/ + +/*- + * Copyright (c) 1990 The 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 <wctype.h> +#include <errno.h> +#include <wchar.h> +#include <reent.h> + +/* + * Convert a wide string to a long long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long long +_DEFUN (_wcstoll_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; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + 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; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(unsigned long long)LONG_LONG_MIN : LONG_LONG_MAX; + cutlim = cutoff % (unsigned long long)base; + cutoff /= (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 = neg ? LONG_LONG_MIN : LONG_LONG_MAX; + rptr->_errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (wchar_t *) (any ? s - 1 : nptr); + return (acc); +} + +#endif /* __GNUC__ */ diff --git a/newlib/libc/stdlib/wcstoul.c b/newlib/libc/stdlib/wcstoul.c new file mode 100644 index 000000000..0a06e861c --- /dev/null +++ b/newlib/libc/stdlib/wcstoul.c @@ -0,0 +1,206 @@ +/* +FUNCTION + <<wcstoul>>---wide string to unsigned long + +INDEX + wcstoul +INDEX + _wcstoul_r + +ANSI_SYNOPSIS + #include <wchar.h> + unsigned long wcstoul(const wchar_t *<[s]>, wchar_t **<[ptr]>, + int <[base]>); + + unsigned long _wcstoul_r(void *<[reent]>, const wchar_t *<[s]>, + wchar_t **<[ptr]>, int <[base]>); + +TRAD_SYNOPSIS + #include <stdlib.h> + unsigned long wcstoul(<[s]>, <[ptr]>, <[base]>) + wchar_t *<[s]>; + wchar_t **<[ptr]>; + int <[base]>; + + unsigned long _wcstoul_r(<[reent]>, <[s]>, <[ptr]>, <[base]>) + wchar_t *<[reent]>; + wchar_t *<[s]>; + wchar_t **<[ptr]>; + int <[base]>; + +DESCRIPTION +The function <<wcstoul>> converts the wide string <<*<[s]>>> to +an <<unsigned long>>. First, it breaks down the string into three parts: +leading whitespace, which is ignored; a subject string consisting +of the digits meaningful in the radix specified by <[base]> +(for example, <<0>> through <<7>> if the value of <[base]> is 8); +and a trailing portion consisting of one or more unparseable characters, +which always includes the terminating null character. Then, it attempts +to convert the subject string into an unsigned long integer, and returns the +result. + +If the value of <[base]> is zero, the subject string is expected to look +like a normal C integer constant (save that no optional sign is permitted): +a possible <<0x>> indicating hexadecimal radix, and a number. +If <[base]> is between 2 and 36, the expected form of the subject is a +sequence of digits (which may include letters, depending on the +base) representing an integer in the radix specified by <[base]>. +The letters <<a>>--<<z>> (or <<A>>--<<Z>>) are used as digits valued from +10 to 35. If <[base]> is 16, a leading <<0x>> is permitted. + +The subject sequence is the longest initial sequence of the input +string that has the expected form, starting with the first +non-whitespace character. If the string is empty or consists entirely +of whitespace, or if the first non-whitespace character is not a +permissible digit, the subject string is empty. + +If the subject string is acceptable, and the value of <[base]> is zero, +<<wcstoul>> attempts to determine the radix from the input string. A +string with a leading <<0x>> is treated as a hexadecimal value; a string with +a leading <<0>> and no <<x>> is treated as octal; all other strings are +treated as decimal. If <[base]> is between 2 and 36, it is used as the +conversion radix, as described above. Finally, a pointer to the first +character past the converted subject string is stored in <[ptr]>, if +<[ptr]> is not <<NULL>>. + +If the subject string is empty (that is, if <<*>><[s]> does not start +with a substring in acceptable form), no conversion +is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is +not <<NULL>>). + +The alternate function <<_wcstoul_r>> is a reentrant version. The +extra argument <[reent]> is a pointer to a reentrancy structure. + + +RETURNS +<<wcstoul>> returns the converted value, if any. If no conversion was +made, <<0>> is returned. + +<<wcstoul>> returns <<ULONG_MAX>> if the magnitude of the converted +value is too large, and sets <<errno>> to <<ERANGE>>. + +PORTABILITY +<<wcstoul>> is ANSI. + +<<wcstoul>> requires no supporting OS subroutines. +*/ + +/* + * 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. + */ + +#include <_ansi.h> +#include <limits.h> +#include <wctype.h> +#include <errno.h> +#include <stdlib.h> +#include <reent.h> + +/* + * Convert a wide string to an unsigned long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long +_DEFUN (_wcstoul_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 acc; + register int c; + register unsigned long cutoff; + register int neg = 0, any, cutlim; + + /* + * 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)ULONG_MAX / (unsigned long)base; + cutlim = (unsigned long)ULONG_MAX % (unsigned 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 = ULONG_MAX; + rptr->_errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (wchar_t *) (any ? s - 1 : nptr); + return (acc); +} + +#ifndef _REENT_ONLY + +unsigned long +_DEFUN (wcstoul, (s, ptr, base), + _CONST wchar_t *s _AND + wchar_t **ptr _AND + int base) +{ + return _wcstoul_r (_REENT, s, ptr, base); +} + +#endif diff --git a/newlib/libc/stdlib/wcstoull.c b/newlib/libc/stdlib/wcstoull.c new file mode 100644 index 000000000..861009b04 --- /dev/null +++ b/newlib/libc/stdlib/wcstoull.c @@ -0,0 +1,139 @@ +/* +FUNCTION + <<wcstoull>>---wide string to unsigned long long + +INDEX + wcstoull +INDEX + _wcstoull_r + +ANSI_SYNOPSIS + #include <wchar.h> + unsigned long long wcstoull(const wchar_t *<[s]>, wchar_t **<[ptr]>, + int <[base]>); + + unsigned long long _wcstoull_r(void *<[reent]>, const wchar_t *<[s]>, + wchar_t **<[ptr]>, int <[base]>); + +TRAD_SYNOPSIS + #include <stdlib.h> + unsigned long long wcstoull(<[s]>, <[ptr]>, <[base]>) + wchar_t *<[s]>; + wchar_t **<[ptr]>; + int <[base]>; + + unsigned long long _wcstoull_r(<[reent]>, <[s]>, <[ptr]>, <[base]>) + wchar_t *<[reent]>; + wchar_t *<[s]>; + wchar_t **<[ptr]>; + int <[base]>; + +DESCRIPTION +The function <<wcstoull>> converts the wide string <<*<[s]>>> to +an <<unsigned long long>>. First, it breaks down the string into three parts: +leading whitespace, which is ignored; a subject string consisting +of the digits meaningful in the radix specified by <[base]> +(for example, <<0>> through <<7>> if the value of <[base]> is 8); +and a trailing portion consisting of one or more unparseable characters, +which always includes the terminating null character. Then, it attempts +to convert the subject string into an unsigned long long integer, and returns the +result. + +If the value of <[base]> is zero, the subject string is expected to look +like a normal C integer constant (save that no optional sign is permitted): +a possible <<0x>> indicating hexadecimal radix, and a number. +If <[base]> is between 2 and 36, the expected form of the subject is a +sequence of digits (which may include letters, depending on the +base) representing an integer in the radix specified by <[base]>. +The letters <<a>>--<<z>> (or <<A>>--<<Z>>) are used as digits valued from +10 to 35. If <[base]> is 16, a leading <<0x>> is permitted. + +The subject sequence is the longest initial sequence of the input +string that has the expected form, starting with the first +non-whitespace character. If the string is empty or consists entirely +of whitespace, or if the first non-whitespace character is not a +permissible digit, the subject string is empty. + +If the subject string is acceptable, and the value of <[base]> is zero, +<<wcstoull>> attempts to determine the radix from the input string. A +string with a leading <<0x>> is treated as a hexadecimal value; a string with +a leading <<0>> and no <<x>> is treated as octal; all other strings are +treated as decimal. If <[base]> is between 2 and 36, it is used as the +conversion radix, as described above. Finally, a pointer to the first +character past the converted subject string is stored in <[ptr]>, if +<[ptr]> is not <<NULL>>. + +If the subject string is empty (that is, if <<*>><[s]> does not start +with a substring in acceptable form), no conversion +is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is +not <<NULL>>). + +The alternate function <<_wcstoull_r>> is a reentrant version. The +extra argument <[reent]> is a pointer to a reentrancy structure. + + +RETURNS +<<wcstoull>> returns the converted value, if any. If no conversion was +made, <<0>> is returned. + +<<wcstoull>> returns <<ULONG_LONG_MAX>> if the magnitude of the converted +value is too large, and sets <<errno>> to <<ERANGE>>. + +PORTABILITY +<<wcstoull>> is ANSI. + +<<wcstoull>> requires no supporting OS subroutines. +*/ + +/* + * 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. + */ + +#include <_ansi.h> +#include <limits.h> +#include <wctype.h> +#include <errno.h> +#include <stdlib.h> +#include <reent.h> + +#ifndef _REENT_ONLY + +unsigned long long +_DEFUN (wcstoull, (s, ptr, base), + _CONST wchar_t *s _AND + wchar_t **ptr _AND + int base) +{ + return _wcstoull_r (_REENT, s, ptr, base); +} + +#endif diff --git a/newlib/libc/stdlib/wcstoull_r.c b/newlib/libc/stdlib/wcstoull_r.c new file mode 100644 index 000000000..81dd320d1 --- /dev/null +++ b/newlib/libc/stdlib/wcstoull_r.c @@ -0,0 +1,120 @@ +/* + 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 <wctype.h> +#include <errno.h> +#include <stdlib.h> +#include <reent.h> + +/* + * 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; + + /* + * 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)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 (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 = ULONG_LONG_MAX; + rptr->_errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (wchar_t *) (any ? s - 1 : nptr); + return (acc); +} + +#endif /* __GNUC__ */ |