[patch] Add wcstol, wcstoul, wcstoll, wcstoull

Jeff Johnston jjohnstn@redhat.com
Fri Jul 6 20:07:00 GMT 2007


Please go ahead.

-- Jeff J.

Corinna Vinschen wrote:
> This adds the missing wide char to integer conversion functions.  I
> created them from their single-byte character counterparts.  I also
> tried to convert strtod to wcstod, but stopped midway since that would
> have also required to create wide char functions of the helper routines
> in mprec.h and gdtoa-gethex.c.
>
> I also changed the man page entries in strtoll.c and strtoull.c.  The
> still claimed that these functions are non-standard, which isn't correct
> anymore.  All of these functions, including the wcstoxxx functions are
> POSIX standard functions referrencing the ISO C standard.
>
>
> Ok to apply?
>
>
> Corinna
>
>
> 	* libc/include/wchar.h: Declare wcstol, wcstoll, wcstoul,
> 	wcstoull, _wcstol_r, _wcstoll_r, _wcstoul_r and _wcstoull_r.
> 	* libc/stdlib/Makefile.am (GENERAL_SOURCES): Add wcstol.c and wcstoul.c.
> 	(EXTENDED_SOURCES): Add wcstoll.c, wcstoll_r.c, wcstoull.c and
> 	wcstoull_r.c.
> 	(CHEWOUT_FILES): Add .def files accordingly.
> 	* libc/stdlib/Makefile.in: Regenerate.
> 	* libc/stdlib/stdlib.tex: Add documentation links for above functions.
> 	* libc/stdlib/strtoll.c: Fix portability note.
> 	* libc/stdlib/strtoull.c: Ditto.
> 	* libc/stdlib/wcstol.c: New file.
> 	* libc/stdlib/wcstoll.c: New file.
> 	* libc/stdlib/wcstoll_r.c: New file.
> 	* libc/stdlib/wcstoul.c: New file.
> 	* libc/stdlib/wcstoull.c: New file.
> 	* libc/stdlib/wcstoull_r.c: New file.
>
>
> Index: libc/include/wchar.h
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/include/wchar.h,v
> retrieving revision 1.14
> diff -u -p -r1.14 wchar.h
> --- libc/include/wchar.h	4 Jul 2007 16:18:33 -0000	1.14
> +++ libc/include/wchar.h	4 Jul 2007 17:55:59 -0000
> @@ -79,6 +79,15 @@ wchar_t	*_EXFUN(wmemcpy, (wchar_t * , co
>  wchar_t	*_EXFUN(wmemmove, (wchar_t *, const wchar_t *, size_t));
>  wchar_t	*_EXFUN(wmemset, (wchar_t *, wchar_t, size_t));
>  
> +long    _EXFUN(wcstol, (const wchar_t *, wchar_t **, int));
> +long long _EXFUN(wcstoll, (const wchar_t *, wchar_t **, int));
> +unsigned long _EXFUN(wcstoul, (const wchar_t *, wchar_t **, int));
> +unsigned long long _EXFUN(wcstoull, (const wchar_t *, wchar_t **, int));
> +long    _EXFUN(_wcstol_r, (struct _reent *, const wchar_t *, wchar_t **, int));
> +long long _EXFUN(_wcstoll_r, (struct _reent *, const wchar_t *, wchar_t **, int));
> +unsigned long _EXFUN(_wcstoul_r, (struct _reent *, const wchar_t *, wchar_t **, int));
> +unsigned long long _EXFUN(_wcstoull_r, (struct _reent *, const wchar_t *, wchar_t **, int));
> +
>  _END_STD_C
>  
>  #endif /* _WCHAR_H_ */
> Index: libc/stdlib/Makefile.am
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/Makefile.am,v
> retrieving revision 1.23
> diff -u -p -r1.23 Makefile.am
> --- libc/stdlib/Makefile.am	22 Jun 2006 17:59:52 -0000	1.23
> +++ libc/stdlib/Makefile.am	4 Jul 2007 17:55:59 -0000
> @@ -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	
>  
> Index: libc/stdlib/Makefile.in
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/Makefile.in,v
> retrieving revision 1.33
> diff -u -p -r1.33 Makefile.in
> --- libc/stdlib/Makefile.in	24 May 2007 17:33:36 -0000	1.33
> +++ libc/stdlib/Makefile.in	4 Jul 2007 17:55:59 -0000
> @@ -86,7 +86,8 @@ am__objects_1 = lib_a-__adjust.$(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.$(OBJEX
>  	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 
>  	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
>  
> Index: libc/stdlib/stdlib.tex
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/stdlib.tex,v
> retrieving revision 1.6
> diff -u -p -r1.6 stdlib.tex
> --- libc/stdlib/stdlib.tex	16 Sep 2004 21:14:45 -0000	1.6
> +++ libc/stdlib/stdlib.tex	4 Jul 2007 17:56:00 -0000
> @@ -40,6 +40,10 @@ The corresponding declarations are in th
>  * 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 th
>  @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
> Index: libc/stdlib/strtoll.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/strtoll.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 strtoll.c
> --- libc/stdlib/strtoll.c	30 Apr 2002 18:23:38 -0000	1.2
> +++ libc/stdlib/strtoll.c	4 Jul 2007 17:56:00 -0000
> @@ -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.
>  */
> Index: libc/stdlib/strtoull.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/strtoull.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 strtoull.c
> --- libc/stdlib/strtoull.c	1 Oct 2001 18:05:10 -0000	1.1
> +++ libc/stdlib/strtoull.c	4 Jul 2007 17:56:00 -0000
> @@ -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.
>  */
> Index: libc/stdlib/wcstol.c
> ===================================================================
> RCS file: libc/stdlib/wcstol.c
> diff -N libc/stdlib/wcstol.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ libc/stdlib/wcstol.c	4 Jul 2007 17:56:00 -0000
> @@ -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
> Index: libc/stdlib/wcstoll.c
> ===================================================================
> RCS file: libc/stdlib/wcstoll.c
> diff -N libc/stdlib/wcstoll.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ libc/stdlib/wcstoll.c	4 Jul 2007 17:56:00 -0000
> @@ -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
> Index: libc/stdlib/wcstoll_r.c
> ===================================================================
> RCS file: libc/stdlib/wcstoll_r.c
> diff -N libc/stdlib/wcstoll_r.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ libc/stdlib/wcstoll_r.c	4 Jul 2007 17:56:00 -0000
> @@ -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__ */
> Index: libc/stdlib/wcstoul.c
> ===================================================================
> RCS file: libc/stdlib/wcstoul.c
> diff -N libc/stdlib/wcstoul.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ libc/stdlib/wcstoul.c	4 Jul 2007 17:56:00 -0000
> @@ -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
> Index: libc/stdlib/wcstoull.c
> ===================================================================
> RCS file: libc/stdlib/wcstoull.c
> diff -N libc/stdlib/wcstoull.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ libc/stdlib/wcstoull.c	4 Jul 2007 17:56:00 -0000
> @@ -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
> Index: libc/stdlib/wcstoull_r.c
> ===================================================================
> RCS file: libc/stdlib/wcstoull_r.c
> diff -N libc/stdlib/wcstoull_r.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ libc/stdlib/wcstoull_r.c	4 Jul 2007 17:56:00 -0000
> @@ -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__ */
>
>   



More information about the Newlib mailing list