Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6606 → Rev 6607

/contrib/sdk/sources/newlib/libc/Makefile
165,6 → 165,8
atof.c \
atoi.c \
atol.c \
btowc.c \
calloc.c \
cxa_atexit.c \
cxa_finalize.c \
div.c \
180,18 → 182,28
getenv.c \
getenv_r.c \
itoa.c \
ldiv.c \
labs.c \
mprec.c \
ldtoa.c \
malloc.c \
mallocr.c \
mblen.c \
mblen_r.c \
mbrlen.c \
mbrtowc.c \
mbsinit.c \
mbsnrtowcs.c \
mbsrtowcs.c \
mbstowcs.c \
mbstowcs_r.c \
mbtowc.c \
mbtowc_r.c \
mbrtowc.c \
mlock.c \
calloc.c \
malloc.c \
mallocr.c \
mprec.c \
rand.c \
rand_r.c \
rand48.c \
random.c \
realloc.c \
seed48.c \
srand48.c \
208,6 → 220,20
system.c \
utoa.c \
wcrtomb.c \
wcsnrtombs.c \
wcsrtombs.c \
wcstod.c \
wcstol.c \
wcstold.c \
wcstoll.c \
wcstoll_r.c \
wcstombs.c \
wcstombs_r.c \
wcstoul.c \
wcstoull.c \
wcstoull_r.c \
wctob.c \
wctomb.c \
wctomb_r.c
 
 
322,6 → 348,10
fgetpos.c \
fgets.c \
fgets_u.c \
fgetwc.c \
fgetwc_u.c \
fgetws.c \
fgetws_u.c \
fileno.c \
fileno_u.c \
findfp.c \
338,6 → 368,9
fputs.c \
fputs_u.c \
fputwc.c \
fputwc_u.c \
fputws.c \
fputws_u.c \
fsetpos.c \
funopen.c \
fread.c \
352,8 → 385,10
fvwrite.c \
fwalk.c \
fwide.c \
fwprintf.c \
fwrite.c \
fwrite_u.c \
fwscanf.c \
getc.c \
getc_u.c \
getchar.c \
361,10 → 396,14
getdelim.c \
getline.c \
gets.c \
getw.c \
getwc.c \
getwc_u.c \
getwchar.c \
getwchar_u.c \
iprintf.c \
iscanf.c \
makebuf.c \
mbstowcs.c \
mktemp.c \
open_memstream.c \
perror.c \
374,6 → 413,11
putchar.c \
putchar_u.c \
puts.c \
putw.c \
putwc.c \
putwc_u.c \
putwchar.c \
putwchar_u.c \
refill.c \
remove.c \
rename.c \
393,9 → 437,12
sscanf.c \
stdio.c \
stdio_ext.c \
swprintf.c \
swscanf.c \
tmpfile.c \
tmpnam.c \
ungetc.c \
ungetwc.c \
vasiprintf.c \
vasniprintf.c \
vasnprintf.c \
402,6 → 449,7
vasprintf.c \
vdiprintf.c \
vdprintf.c \
vfwscanf.c \
viprintf.c \
viscanf.c \
vprintf.c \
412,8 → 460,14
vsniprintf.c \
vsnprintf.c \
vsscanf.c \
wsetup.c \
wbuf.c
vswprintf.c \
vswscanf.c \
vwprintf.c \
vwscanf.c \
wbuf.c \
wprintf.c \
wscanf.c \
wsetup.c
 
 
MATH_SRCS = e_acos.c e_acosh.c e_asin.c e_atan2.c e_atanh.c e_cosh.c e_exp.c e_fmod.c \
481,10 → 535,16
stdio/vfiprintf.o \
stdio/svfprintf.o \
stdio/svfiprintf.o \
stdio/svfiwprintf.o \
stdio/svfwprintf.o \
stdio/vfiwprintf.o \
stdio/vfwprintf.o \
stdio/vfscanf.o \
stdio/vfiscanf.o \
stdio/svscanf.o \
stdio/svfiscanf.o
stdio/svfiscanf.o \
stdio/svfiwscanf.o \
stdio/svfwscanf.o
 
ifeq ($(findstring static,$(MAKECMDGOALS)),static)
 
561,7 → 621,18
stdio/vfprintf.o: stdio/vfprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums stdio/vfprintf.c -o $@
 
stdio/svfiwprintf.o: stdio/vfwprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DINTEGER_ONLY -DSTRING_ONLY stdio/vfwprintf.c -o $@
 
stdio/svfwprintf.o: stdio/vfwprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DSTRING_ONLY stdio/vfwprintf.c -o $@
 
stdio/vfiwprintf.o: stdio/vfwprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums -DINTEGER_ONLY stdio/vfwprintf.c -o $@
 
stdio/vfwprintf.o: stdio/vfwprintf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -fshort-enums stdio/vfwprintf.c -o $@
stdio/svfiscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DINTEGER_ONLY -DSTRING_ONLY $(INCLUDES) stdio/vfscanf.c -o $@
 
574,11 → 645,18
stdio/vfiscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DINTEGER_ONLY $(INCLUDES) stdio/vfscanf.c -o $@
 
stdio/svfiwscanf.o: stdio/vfwscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DINTEGER_ONLY -DSTRING_ONLY $(INCLUDES) stdio/vfwscanf.c -o $@
 
stdio/svfwscanf.o: stdio/vfwscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DSTRING_ONLY $(INCLUDES) stdio/vfwscanf.c -o $@
 
stdio/vfiwscanf.o: stdio/vfwscanf.c
$(CC) $(CFLAGS) $(DEFINES) -DINTEGER_ONLY $(INCLUDES) stdio/vfwscanf.c -o $@
 
 
 
 
%.obj : %.asm Makefile
fasm $< $
 
/contrib/sdk/sources/newlib/libc/include/newlib.h
56,7 → 56,7
#define _ATEXIT_DYNAMIC_ALLOC 1
 
/* True if long double supported. */
//#define _HAVE_LONG_DOUBLE 1
#define _HAVE_LONG_DOUBLE 1
 
/* Define if compiler supports -fno-tree-loop-distribute-patterns. */
#define _HAVE_CC_INHIBIT_LOOP_TO_LIBCALL 1
/contrib/sdk/sources/newlib/libc/include/sys/unistd.h
20,7 → 20,7
int _EXFUN(access,(const char *__path, int __amode ));
unsigned _EXFUN(alarm, (unsigned __secs ));
int _EXFUN(chdir, (const char *__path ));
int _EXFUN(chmod, (const char *__path, mode_t __mode ));
//int _EXFUN(chmod, (const char *__path, mode_t __mode ));
#if !defined(__INSIDE_CYGWIN__)
int _EXFUN(chown, (const char *__path, uid_t __owner, gid_t __group ));
#endif
66,7 → 66,7
#if __BSD_VISIBLE || __XSI_VISIBLE >= 4
int _EXFUN(fchdir, (int __fildes));
#endif
int _EXFUN(fchmod, (int __fildes, mode_t __mode ));
//int _EXFUN(fchmod, (int __fildes, mode_t __mode ));
#if !defined(__INSIDE_CYGWIN__)
int _EXFUN(fchown, (int __fildes, uid_t __owner, gid_t __group ));
#endif
/contrib/sdk/sources/newlib/libc/stdio/fgetwc.c
0,0 → 1,243
/*-
* Copyright (c) 2002-2004 Tim J. Robbins.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
/*
FUNCTION
<<fgetwc>>, <<getwc>>, <<fgetwc_unlocked>>, <<getwc_unlocked>>---get a wide character from a file or stream
 
INDEX
fgetwc
INDEX
fgetwc_unlocked
INDEX
_fgetwc_r
INDEX
_fgetwc_unlocked_r
INDEX
getwc
INDEX
getwc_unlocked
INDEX
_getwc_r
INDEX
_getwc_unlocked_r
 
ANSI_SYNOPSIS
#include <stdio.h>
#include <wchar.h>
wint_t fgetwc(FILE *<[fp]>);
 
#define _GNU_SOURCE
#include <stdio.h>
#include <wchar.h>
wint_t fgetwc_unlocked(FILE *<[fp]>);
 
#include <stdio.h>
#include <wchar.h>
wint_t _fgetwc_r(struct _reent *<[ptr]>, FILE *<[fp]>);
 
#include <stdio.h>
#include <wchar.h>
wint_t _fgetwc_unlocked_r(struct _reent *<[ptr]>, FILE *<[fp]>);
 
#include <stdio.h>
#include <wchar.h>
wint_t getwc(FILE *<[fp]>);
 
#define _GNU_SOURCE
#include <stdio.h>
#include <wchar.h>
wint_t getwc_unlocked(FILE *<[fp]>);
 
#include <stdio.h>
#include <wchar.h>
wint_t _getwc_r(struct _reent *<[ptr]>, FILE *<[fp]>);
 
#include <stdio.h>
#include <wchar.h>
wint_t _getwc_unlocked_r(struct _reent *<[ptr]>, FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
#include <wchar.h>
wint_t fgetwc(<[fp]>)
FILE *<[fp]>;
 
#define _GNU_SOURCE
#include <stdio.h>
#include <wchar.h>
wint_t fgetwc_unlocked(<[fp]>)
FILE *<[fp]>;
 
#include <stdio.h>
#include <wchar.h>
wint_t _fgetwc_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
 
#include <stdio.h>
#include <wchar.h>
wint_t _fgetwc_unlocked_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
 
#include <stdio.h>
#include <wchar.h>
wint_t getwc(<[fp]>)
FILE *<[fp]>;
 
#define _GNU_SOURCE
#include <stdio.h>
#include <wchar.h>
wint_t getwc_unlocked(<[fp]>)
FILE *<[fp]>;
 
#include <stdio.h>
#include <wchar.h>
wint_t _getwc_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
 
#include <stdio.h>
#include <wchar.h>
wint_t _getwc_unlocked_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
 
DESCRIPTION
Use <<fgetwc>> to get the next wide character from the file or stream
identified by <[fp]>. As a side effect, <<fgetwc>> advances the file's
current position indicator.
 
<<fgetwc_unlocked>> is a non-thread-safe version of <<fgetwc>>.
<<fgetwc_unlocked>> may only safely be used within a scope
protected by flockfile() (or ftrylockfile()) and funlockfile(). This
function may safely be used in a multi-threaded program if and only
if they are called while the invoking thread owns the (FILE *)
object, as is the case after a successful call to the flockfile() or
ftrylockfile() functions. If threads are disabled, then
<<fgetwc_unlocked>> is equivalent to <<fgetwc>>.
 
The <<getwc>> and <<getwc_unlocked>> functions or macros functions identically
to <<fgetwc>> and <<fgetwc_unlocked>>. It may be implemented as a macro, and
may evaluate its argument more than once. There is no reason ever to use it.
 
<<_fgetwc_r>>, <<_getwc_r>>, <<_fgetwc_unlocked_r>>, and <<_getwc_unlocked_r>>
are simply reentrant versions of the above functions that are passed the
additional reentrant structure pointer argument: <[ptr]>.
 
RETURNS
The next wide character cast to <<wint_t>>, unless there is no more data,
or the host system reports a read error; in either of these situations,
<<fgetwc>> and <<getwc>> return <<WEOF>>.
 
You can distinguish the two situations that cause an <<EOF>> result by
using the <<ferror>> and <<feof>> functions.
 
PORTABILITY
<<fgetwc>> and <<getwc>> are required by C99 and POSIX.1-2001.
 
<<fgetwc_unlocked>> and <<getwc_unlocked>> are GNU extensions.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include "local.h"
 
wint_t
_DEFUN(__fgetwc, (ptr, fp),
struct _reent *ptr _AND
register FILE *fp)
{
wchar_t wc;
size_t nconv;
 
if (fp->_r <= 0 && __srefill_r (ptr, fp))
return (WEOF);
if (MB_CUR_MAX == 1)
{
/* Fast path for single-byte encodings. */
wc = *fp->_p++;
fp->_r--;
return (wc);
}
do
{
nconv = _mbrtowc_r (ptr, &wc, (char *) fp->_p, fp->_r, &fp->_mbstate);
if (nconv == (size_t)-1)
break;
else if (nconv == (size_t)-2)
continue;
else if (nconv == 0)
{
/*
* Assume that the only valid representation of
* the null wide character is a single null byte.
*/
fp->_p++;
fp->_r--;
return (L'\0');
}
else
{
fp->_p += nconv;
fp->_r -= nconv;
return (wc);
}
}
while (__srefill_r(ptr, fp) == 0);
fp->_flags |= __SERR;
errno = EILSEQ;
return (WEOF);
}
 
wint_t
_DEFUN(_fgetwc_r, (ptr, fp),
struct _reent *ptr _AND
register FILE *fp)
{
wint_t r;
 
_newlib_flockfile_start (fp);
ORIENT(fp, 1);
r = __fgetwc (ptr, fp);
_newlib_flockfile_end (fp);
return r;
}
 
wint_t
_DEFUN(fgetwc, (fp),
FILE *fp)
{
struct _reent *reent = _REENT;
 
CHECK_INIT(reent, fp);
return _fgetwc_r (reent, fp);
}
/contrib/sdk/sources/newlib/libc/stdio/fgetwc_u.c
0,0 → 1,49
/*
* Copyright (c) 2014 Red Hat, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <stdio.h>
#include <wchar.h>
#include "local.h"
 
wint_t
_DEFUN(_fgetwc_unlocked_r, (ptr, fp),
struct _reent *ptr _AND
register FILE *fp)
{
ORIENT(fp, 1);
return __fgetwc (ptr, fp);
}
 
wint_t
_DEFUN(fgetwc_unlocked, (fp),
FILE *fp)
{
struct _reent *reent = _REENT;
 
CHECK_INIT(reent, fp);
return _fgetwc_unlocked_r (reent, fp);
}
/contrib/sdk/sources/newlib/libc/stdio/fgetws.c
0,0 → 1,212
/*-
* Copyright (c) 2002-2004 Tim J. Robbins.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
/*
FUNCTION
<<fgetws>>, <<fgetws_unlocked>>---get wide character string from a file or stream
 
INDEX
fgetws
INDEX
fgetws_unlocked
INDEX
_fgetws_r
INDEX
_fgetws_unlocked_r
 
ANSI_SYNOPSIS
#include <wchar.h>
wchar_t *fgetws(wchar_t *__restrict <[ws]>, int <[n]>,
FILE *__restrict <[fp]>);
 
#define _GNU_SOURCE
#include <wchar.h>
wchar_t *fgetws_unlocked(wchar_t *__restrict <[ws]>, int <[n]>,
FILE *__restrict <[fp]>);
 
#include <wchar.h>
wchar_t *_fgetws_r(struct _reent *<[ptr]>, wchar_t *<[ws]>,
int <[n]>, FILE *<[fp]>);
 
#include <wchar.h>
wchar_t *_fgetws_unlocked_r(struct _reent *<[ptr]>, wchar_t *<[ws]>,
int <[n]>, FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <wchar.h>
wchar_t *fgetws(<[ws]>,<[n]>,<[fp]>)
wchar_t *__restrict <[ws]>;
int <[n]>;
FILE *__restrict <[fp]>;
 
#define _GNU_SOURCE
#include <wchar.h>
wchar_t *fgetws_unlocked(<[ws]>,<[n]>,<[fp]>)
wchar_t *__restrict <[ws]>;
int <[n]>;
FILE *__restrict <[fp]>;
 
#include <wchar.h>
wchar_t *_fgetws_r(<[ptr]>, <[ws]>,<[n]>,<[fp]>)
struct _reent *<[ptr]>;
wchar_t *<[ws]>;
int <[n]>;
FILE *<[fp]>;
 
#include <wchar.h>
wchar_t *_fgetws_unlocked_r(<[ptr]>, <[ws]>,<[n]>,<[fp]>)
struct _reent *<[ptr]>;
wchar_t *<[ws]>;
int <[n]>;
FILE *<[fp]>;
 
DESCRIPTION
Reads at most <[n-1]> wide characters from <[fp]> until a newline
is found. The wide characters including to the newline are stored
in <[ws]>. The buffer is terminated with a 0.
 
<<fgetws_unlocked>> is a non-thread-safe version of <<fgetws>>.
<<fgetws_unlocked>> may only safely be used within a scope
protected by flockfile() (or ftrylockfile()) and funlockfile(). This
function may safely be used in a multi-threaded program if and only
if they are called while the invoking thread owns the (FILE *)
object, as is the case after a successful call to the flockfile() or
ftrylockfile() functions. If threads are disabled, then
<<fgetws_unlocked>> is equivalent to <<fgetws>>.
 
The <<_fgetws_r>> and <<_fgetws_unlocked_r>> functions are simply reentrant
version of the above and are passed an additional reentrancy structure
pointer: <[ptr]>.
 
RETURNS
<<fgetws>> returns the buffer passed to it, with the data
filled in. If end of file occurs with some data already
accumulated, the data is returned with no other indication. If
no data are read, NULL is returned instead.
 
PORTABILITY
<<fgetws>> is required by C99 and POSIX.1-2001.
 
<<fgetws_unlocked>> is a GNU extension.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include "local.h"
 
#ifdef __IMPL_UNLOCKED__
#define _fgetws_r _fgetws_unlocked_r
#define fgetws fgetws_unlocked
#endif
 
wchar_t *
_DEFUN(_fgetws_r, (ptr, ws, n, fp),
struct _reent *ptr _AND
wchar_t * ws _AND
int n _AND
FILE * fp)
{
wchar_t *wsp;
size_t nconv;
const char *src;
unsigned char *nl;
 
_newlib_flockfile_start (fp);
ORIENT (fp, 1);
 
if (n <= 0)
{
errno = EINVAL;
goto error;
}
 
if (fp->_r <= 0 && __srefill_r (ptr, fp))
/* EOF */
goto error;
wsp = ws;
do
{
src = (char *) fp->_p;
nl = memchr (fp->_p, '\n', fp->_r);
nconv = _mbsnrtowcs_r (ptr, wsp, &src,
/* Read all bytes up to the next NL, or up to the
end of the buffer if there is no NL. */
nl != NULL ? (nl - fp->_p + 1) : fp->_r,
/* But never more than n - 1 wide chars. */
n - 1,
&fp->_mbstate);
if (nconv == (size_t) -1)
/* Conversion error */
goto error;
if (src == NULL)
{
/*
* We hit a null byte. Increment the character count,
* since mbsnrtowcs()'s return value doesn't include
* the terminating null, then resume conversion
* after the null.
*/
nconv++;
src = memchr (fp->_p, '\0', fp->_r);
src++;
}
fp->_r -= (unsigned char *) src - fp->_p;
fp->_p = (unsigned char *) src;
n -= nconv;
wsp += nconv;
}
while (wsp[-1] != L'\n' && n > 1 && (fp->_r > 0
|| __srefill_r (ptr, fp) == 0));
if (wsp == ws)
/* EOF */
goto error;
if (!mbsinit (&fp->_mbstate))
/* Incomplete character */
goto error;
*wsp++ = L'\0';
_newlib_flockfile_exit (fp);
return ws;
 
error:
_newlib_flockfile_end (fp);
return NULL;
}
 
wchar_t *
_DEFUN(fgetws, (ws, n, fp),
wchar_t *__restrict ws _AND
int n _AND
FILE *__restrict fp)
{
struct _reent *reent = _REENT;
 
CHECK_INIT (reent, fp);
return _fgetws_r (reent, ws, n, fp);
}
/contrib/sdk/sources/newlib/libc/stdio/fgetws_u.c
0,0 → 1,28
/*
* Copyright (c) 2014 Red Hat, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
#define __IMPL_UNLOCKED__
#include "fgetws.c"
/contrib/sdk/sources/newlib/libc/stdio/fputwc_u.c
0,0 → 1,51
/*
* Copyright (c) 2014 Red Hat, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <stdio.h>
#include <wchar.h>
#include "local.h"
 
wint_t
_DEFUN(_fputwc_unlocked_r, (ptr, wc, fp),
struct _reent *ptr _AND
wchar_t wc _AND
FILE *fp)
{
ORIENT(fp, 1);
return __fputwc(ptr, wc, fp);
}
 
wint_t
_DEFUN(fputwc_unlocked, (wc, fp),
wchar_t wc _AND
FILE *fp)
{
struct _reent *reent = _REENT;
 
CHECK_INIT(reent, fp);
return _fputwc_unlocked_r (reent, wc, fp);
}
/contrib/sdk/sources/newlib/libc/stdio/fputws.c
0,0 → 1,193
/*-
* Copyright (c) 2002-2004 Tim J. Robbins.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
/*
FUNCTION
<<fputws>>, <<fputws_unlocked>>---write a wide character string in a file or stream
 
INDEX
fputws
INDEX
fputws_unlocked
INDEX
_fputws_r
INDEX
_fputws_unlocked_r
 
ANSI_SYNOPSIS
#include <wchar.h>
int fputws(const wchar_t *__restrict <[ws]>, FILE *__restrict <[fp]>);
 
#define _GNU_SOURCE
#include <wchar.h>
int fputws_unlocked(const wchar_t *__restrict <[ws]>, FILE *__restrict <[fp]>);
 
#include <wchar.h>
int _fputws_r(struct _reent *<[ptr]>, const wchar_t *<[ws]>,
FILE *<[fp]>);
 
#include <wchar.h>
int _fputws_unlocked_r(struct _reent *<[ptr]>, const wchar_t *<[ws]>,
FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <wchar.h>
int fputws(<[ws]>, <[fp]>)
wchar_t *__restrict <[ws]>;
FILE *__restrict <[fp]>;
 
#define _GNU_SOURCE
#include <wchar.h>
int fputws_unlocked(<[ws]>, <[fp]>)
wchar_t *__restrict <[ws]>;
FILE *__restrict <[fp]>;
 
#include <wchar.h>
int _fputws_r(<[ptr]>, <[ws]>, <[fp]>)
struct _reent *<[ptr]>;
wchar_t *<[ws]>;
FILE *<[fp]>;
 
#include <wchar.h>
int _fputws_unlocked_r(<[ptr]>, <[ws]>, <[fp]>)
struct _reent *<[ptr]>;
wchar_t *<[ws]>;
FILE *<[fp]>;
 
DESCRIPTION
<<fputws>> writes the wide character string at <[ws]> (but without the
trailing null) to the file or stream identified by <[fp]>.
 
<<fputws_unlocked>> is a non-thread-safe version of <<fputws>>.
<<fputws_unlocked>> may only safely be used within a scope
protected by flockfile() (or ftrylockfile()) and funlockfile(). This
function may safely be used in a multi-threaded program if and only
if they are called while the invoking thread owns the (FILE *)
object, as is the case after a successful call to the flockfile() or
ftrylockfile() functions. If threads are disabled, then
<<fputws_unlocked>> is equivalent to <<fputws>>.
 
<<_fputws_r>> and <<_fputws_unlocked_r>> are simply reentrant versions of the
above that take an additional reentrant struct pointer argument: <[ptr]>.
 
RETURNS
If successful, the result is a non-negative integer; otherwise, the result
is <<-1>> to indicate an error.
 
PORTABILITY
<<fputws>> is required by C99 and POSIX.1-2001.
 
<<fputws_unlocked>> is a GNU extension.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <wchar.h>
#include "fvwrite.h"
#include "local.h"
 
#ifdef __IMPL_UNLOCKED__
#define _fputws_r _fputws_unlocked_r
#define fputws fputws_unlocked
#endif
 
int
_DEFUN(_fputws_r, (ptr, ws, fp),
struct _reent *ptr _AND
const wchar_t *ws _AND
FILE *fp)
{
size_t nbytes;
char buf[BUFSIZ];
#ifdef _FVWRITE_IN_STREAMIO
struct __suio uio;
struct __siov iov;
 
_newlib_flockfile_start (fp);
ORIENT (fp, 1);
if (cantwrite (ptr, fp) != 0)
goto error;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
iov.iov_base = buf;
do
{
nbytes = _wcsrtombs_r(ptr, buf, &ws, sizeof (buf), &fp->_mbstate);
if (nbytes == (size_t) -1)
goto error;
iov.iov_len = uio.uio_resid = nbytes;
if (__sfvwrite_r(ptr, fp, &uio) != 0)
goto error;
}
while (ws != NULL);
_newlib_flockfile_exit (fp);
return (0);
 
error:
_newlib_flockfile_end (fp);
return (-1);
#else
_newlib_flockfile_start (fp);
ORIENT (fp, 1);
if (cantwrite (ptr, fp) != 0)
goto error;
 
do
{
size_t i = 0;
nbytes = _wcsrtombs_r (ptr, buf, &ws, sizeof (buf), &fp->_mbstate);
if (nbytes == (size_t) -1)
goto error;
while (i < nbytes)
{
if (__sputc_r (ptr, buf[i], fp) == EOF)
goto error;
i++;
}
}
while (ws != NULL);
_newlib_flockfile_exit (fp);
return (0);
 
error:
_newlib_flockfile_end (fp);
return (-1);
#endif
}
 
int
_DEFUN(fputws, (ws, fp),
const wchar_t *__restrict ws _AND
FILE *__restrict fp)
{
struct _reent *reent = _REENT;
 
CHECK_INIT (reent, fp);
return _fputws_r (reent, ws, fp);
}
/contrib/sdk/sources/newlib/libc/stdio/fputws_u.c
0,0 → 1,28
/*
* Copyright (c) 2014 Red Hat, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
#define __IMPL_UNLOCKED__
#include "fputws.c"
/contrib/sdk/sources/newlib/libc/stdio/fwprintf.c
0,0 → 1,56
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* doc in swprintf.c */
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
 
int
_DEFUN(_fwprintf_r, (ptr, fp, fmt),
struct _reent *ptr _AND
FILE *fp _AND
const wchar_t *fmt _DOTS)
{
int ret;
va_list ap;
 
va_start (ap, fmt);
ret = _vfwprintf_r (ptr, fp, fmt, ap);
va_end (ap);
return ret;
}
 
#ifndef _REENT_ONLY
 
int
_DEFUN(fwprintf, (fp, fmt),
FILE *__restrict fp _AND
const wchar_t *__restrict fmt _DOTS)
{
int ret;
va_list ap;
 
va_start (ap, fmt);
ret = _vfwprintf_r (_REENT, fp, fmt, ap);
va_end (ap);
return ret;
}
 
#endif /* ! _REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdio/fwscanf.c
0,0 → 1,53
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Doc in swscanf.c */
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
#include "local.h"
 
#ifndef _REENT_ONLY
 
int
fwscanf (FILE *__restrict fp, _CONST wchar_t *__restrict fmt, ...)
{
int ret;
va_list ap;
 
va_start (ap, fmt);
ret = _vfwscanf_r (_REENT, fp, fmt, ap);
va_end (ap);
return ret;
}
 
#endif /* !_REENT_ONLY */
 
int
_fwscanf_r (struct _reent *ptr, FILE *fp, _CONST wchar_t *fmt, ...)
{
int ret;
va_list ap;
 
va_start (ap, fmt);
ret = _vfwscanf_r (ptr, fp, fmt, ap);
va_end (ap);
return (ret);
}
 
/contrib/sdk/sources/newlib/libc/stdio/getw.c
0,0 → 1,69
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<getw>>---read a word (int)
 
INDEX
getw
 
ANSI_SYNOPSIS
#include <stdio.h>
int getw(FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
int getw(<[fp]>)
FILE *<[fp]>;
 
DESCRIPTION
<<getw>> is a function, defined in <<stdio.h>>. You can use <<getw>>
to get the next word from the file or stream identified by <[fp]>. As
a side effect, <<getw>> advances the file's current position
indicator.
 
RETURNS
The next word (read as an <<int>>), unless there is no more
data or the host system reports a read error; in either of these
situations, <<getw>> returns <<EOF>>. Since <<EOF>> is a valid
<<int>>, you must use <<ferror>> or <<feof>> to distinguish these
situations.
 
PORTABILITY
<<getw>> is a remnant of K&R C; it is not part of any ISO C Standard.
<<fread>> should be used instead. In fact, this implementation of
<<getw>> is based upon <<fread>>.
 
Supporting OS subroutines required: <<fread>>. */
 
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
 
#include <_ansi.h>
#include <stdio.h>
 
int
_DEFUN(getw, (fp),
register FILE *fp)
{
int result;
if (fread ((char*)&result, sizeof (result), 1, fp) != 1)
return EOF;
return result;
}
/contrib/sdk/sources/newlib/libc/stdio/getwc.c
0,0 → 1,52
/*-
* Copyright (c) 2002 Tim J. Robbins.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <reent.h>
#include <stdio.h>
#include <wchar.h>
#include "local.h"
 
#undef getwc
 
wint_t
_DEFUN(_getwc_r, (ptr, fp),
struct _reent *ptr _AND
FILE *fp)
{
return _fgetwc_r (ptr, fp);
}
 
/*
* Synonym for fgetwc(). The only difference is that getwc(), if it is a
* macro, may evaluate `fp' more than once.
*/
wint_t
_DEFUN(getwc, (fp),
FILE *fp)
{
return fgetwc(fp);
}
/contrib/sdk/sources/newlib/libc/stdio/getwc_u.c
0,0 → 1,53
/*
* Copyright (c) 2014 Red Hat, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
#define _GNU_SOURCE
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include "local.h"
 
#undef getwc_unlocked
 
wint_t
_DEFUN(_getwc_unlocked_r, (ptr, fp),
struct _reent *ptr _AND
FILE *fp)
{
return _fgetwc_unlocked_r (ptr, fp);
}
 
/*
* Synonym for fgetwc_unlocked(). The only difference is that getwc(), if it is
* a macro, may evaluate `fp' more than once.
*/
wint_t
_DEFUN(getwc_unlocked, (fp),
FILE *fp)
{
return fgetwc_unlocked(fp);
}
/contrib/sdk/sources/newlib/libc/stdio/getwchar.c
0,0 → 1,126
/*-
* Copyright (c) 2002 Tim J. Robbins.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
/*
FUNCTION
<<getwchar>>, <<getwchar_unlocked>>---read a wide character from standard input
 
INDEX
getwchar
INDEX
getwchar_unlocked
INDEX
_getwchar_r
INDEX
_getwchar_unlocked_r
 
ANSI_SYNOPSIS
#include <wchar.h>
wint_t getwchar(void);
 
#define _GNU_SOURCE
#include <wchar.h>
wint_t getwchar_unlocked(void);
 
#include <wchar.h>
wint_t _getwchar_r(struct _reent *<[reent]>);
 
#include <wchar.h>
wint_t _getwchar_unlocked_r(struct _reent *<[reent]>);
 
TRAD_SYNOPSIS
#include <wchar.h>
wint_t getwchar();
 
#define _GNU_SOURCE
#include <wchar.h>
wint_t getwchar_unlocked();
 
#include <wchar.h>
wint_t _getwchar_r(<[reent]>)
char * <[reent]>;
 
#include <wchar.h>
wint_t _getwchar_unlocked_r(<[reent]>)
char * <[reent]>;
 
DESCRIPTION
<<getwchar>> function or macro is the wide character equivalent of
the <<getchar>> function. You can use <<getwchar>> to get the next
wide character from the standard input stream. As a side effect,
<<getwchar>> advances the standard input's current position indicator.
 
<<getwchar_unlocked>> is a non-thread-safe version of <<getwchar>>.
<<getwchar_unlocked>> may only safely be used within a scope
protected by flockfile() (or ftrylockfile()) and funlockfile(). This
function may safely be used in a multi-threaded program if and only
if they are called while the invoking thread owns the (FILE *)
object, as is the case after a successful call to the flockfile() or
ftrylockfile() functions. If threads are disabled, then
<<getwchar_unlocked>> is equivalent to <<getwchar>>.
 
The alternate functions <<_getwchar_r>> and <<_getwchar_unlocked_r>> are
reentrant versions of the above. The extra argument <[reent]> is a pointer to
a reentrancy structure.
 
RETURNS
The next wide character cast to <<wint_t>>, unless there is no more
data, or the host system reports a read error; in either of these
situations, <<getwchar>> returns <<WEOF>>.
 
You can distinguish the two situations that cause an <<WEOF>> result by
using `<<ferror(stdin)>>' and `<<feof(stdin)>>'.
 
PORTABILITY
<<getwchar>> is required by C99.
 
<<getwchar_unlocked>> is a GNU extension.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include "local.h"
 
#undef getwchar
 
wint_t
_DEFUN (_getwchar_r, (ptr),
struct _reent *ptr)
{
return _fgetwc_r (ptr, stdin);
}
 
/*
* Synonym for fgetwc(stdin).
*/
wint_t
_DEFUN_VOID (getwchar)
{
_REENT_SMALL_CHECK_INIT (_REENT);
return fgetwc (stdin);
}
/contrib/sdk/sources/newlib/libc/stdio/getwchar_u.c
0,0 → 1,51
/*
* Copyright (c) 2014 Red Hat, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
#define _GNU_SOURCE
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include "local.h"
 
#undef getwchar_unlocked
 
wint_t
_DEFUN (_getwchar_unlocked_r, (ptr),
struct _reent *ptr)
{
return _fgetwc_unlocked_r (ptr, stdin);
}
 
/*
* Synonym for fgetwc_unlocked(stdin).
*/
wint_t
_DEFUN_VOID (getwchar_unlocked)
{
_REENT_SMALL_CHECK_INIT (_REENT);
return fgetwc_unlocked (stdin);
}
/contrib/sdk/sources/newlib/libc/stdio/putw.c
0,0 → 1,65
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<putw>>---write a word (int)
 
INDEX
putw
 
ANSI_SYNOPSIS
#include <stdio.h>
int putw(int <[w]>, FILE *<[fp]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
int putw(<w>, <[fp]>)
int <w>;
FILE *<[fp]>;
 
DESCRIPTION
<<putw>> is a function, defined in <<stdio.h>>. You can use <<putw>>
to write a word to the file or stream identified by <[fp]>. As a side
effect, <<putw>> advances the file's current position indicator.
 
RETURNS
Zero on success, <<EOF>> on failure.
 
PORTABILITY
<<putw>> is a remnant of K&R C; it is not part of any ISO C Standard.
<<fwrite>> should be used instead. In fact, this implementation of
<<putw>> is based upon <<fwrite>>.
 
Supporting OS subroutines required: <<fwrite>>.
*/
 
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
 
#include <stdio.h>
 
int
_DEFUN(putw, (w, fp),
int w _AND
register FILE *fp)
{
if (fwrite ((_CONST char*)&w, sizeof (w), 1, fp) != 1)
return EOF;
return 0;
}
/contrib/sdk/sources/newlib/libc/stdio/putwc.c
0,0 → 1,53
/*-
* Copyright (c) 2002 Tim J. Robbins.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <reent.h>
#include <stdio.h>
#include <wchar.h>
#include "local.h"
 
#undef putwc
 
wint_t
_DEFUN(_putwc_r, (ptr, wc, fp),
struct _reent *ptr _AND
wchar_t wc _AND
FILE *fp)
{
return _fputwc_r (ptr, wc, fp);
}
/*
* Synonym for fputwc(). The only difference is that putwc(), if it is a
* macro, may evaluate `fp' more than once.
*/
wint_t
_DEFUN(putwc, (wc, fp),
wchar_t wc _AND
FILE *fp)
{
return fputwc (wc, fp);
}
/contrib/sdk/sources/newlib/libc/stdio/putwc_u.c
0,0 → 1,54
/*-
* Copyright (c) 2014 Red Hat, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
#define _GNU_SOURCE
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include "local.h"
 
#undef putwc_unlocked
 
wint_t
_DEFUN(_putwc_unlocked_r, (ptr, wc, fp),
struct _reent *ptr _AND
wchar_t wc _AND
FILE *fp)
{
return _fputwc_unlocked_r (ptr, wc, fp);
}
/*
* Synonym for fputwc_unlocked(). The only difference is that putwc_unlocked(),
* if it is a macro, may evaluate `fp' more than once.
*/
wint_t
_DEFUN(putwc_unlocked, (wc, fp),
wchar_t wc _AND
FILE *fp)
{
return fputwc_unlocked (wc, fp);
}
/contrib/sdk/sources/newlib/libc/stdio/putwchar.c
0,0 → 1,125
/*-
* Copyright (c) 2002 Tim J. Robbins.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
/*
FUNCTION
<<putwchar>>, <<putwchar_unlocked>>---write a wide character to standard output
 
INDEX
putwchar
INDEX
putwchar_unlocked
INDEX
_putwchar_r
INDEX
_putwchar_unlocked_r
 
ANSI_SYNOPSIS
#include <wchar.h>
wint_t putwchar(wchar_t <[wc]>);
 
#include <wchar.h>
wint_t putwchar_unlocked(wchar_t <[wc]>);
 
#include <wchar.h>
wint_t _putwchar_r(struct _reent *<[reent]>, wchar_t <[wc]>);
 
#include <wchar.h>
wint_t _putwchar_unlocked_r(struct _reent *<[reent]>, wchar_t <[wc]>);
 
TRAD_SYNOPSIS
#include <wchar.h>
wint_t putwchar(<[wc]>)
wchar_t <[wc]>;
 
#include <wchar.h>
wint_t putwchar_unlocked(<[wc]>)
wchar_t <[wc]>;
 
#include <wchar.h>
wint_t _putwchar_r(<[reent]>, <[wc]>)
struct _reent *<[reent]>;
wchar_t <[wc]>;
 
#include <wchar.h>
wint_t _putwchar_unlocked_r(<[reent]>, <[wc]>)
struct _reent *<[reent]>;
wchar_t <[wc]>;
 
DESCRIPTION
The <<putwchar>> function or macro is the wide-character equivalent of
the <<putchar>> function. It writes the wide character wc to stdout.
 
<<putwchar_unlocked>> is a non-thread-safe version of <<putwchar>>.
<<putwchar_unlocked>> may only safely be used within a scope
protected by flockfile() (or ftrylockfile()) and funlockfile(). This
function may safely be used in a multi-threaded program if and only
if they are called while the invoking thread owns the (FILE *)
object, as is the case after a successful call to the flockfile() or
ftrylockfile() functions. If threads are disabled, then
<<putwchar_unlocked>> is equivalent to <<putwchar>>.
 
The alternate functions <<_putwchar_r>> and <<_putwchar_unlocked_r>> are
reentrant versions of the above. The extra argument <[reent]> is a pointer
to a reentrancy structure.
 
RETURNS
If successful, <<putwchar>> returns its argument <[wc]>. If an error
intervenes, the result is <<EOF>>. You can use `<<ferror(stdin)>>' to
query for errors.
 
PORTABILITY
<<putwchar>> is required by C99.
 
<<putwchar_unlocked>> is a GNU extension.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include "local.h"
 
#undef putwchar
 
wint_t
_DEFUN(_putwchar_r, (ptr, wc),
struct _reent *ptr _AND
wchar_t wc)
{
return _fputwc_r (ptr, wc, stdout);
}
 
/*
* Synonym for fputwc(wc, stdout).
*/
wint_t
_DEFUN(putwchar, (wc),
wchar_t wc)
{
_REENT_SMALL_CHECK_INIT (_REENT);
return fputwc (wc, stdout);
}
/contrib/sdk/sources/newlib/libc/stdio/putwchar_u.c
0,0 → 1,53
/*
* Copyright (c) 2014 Red Hat, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
#define _GNU_SOURCE
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include "local.h"
 
#undef putwchar_unlocked
 
wint_t
_DEFUN(_putwchar_unlocked_r, (ptr, wc),
struct _reent *ptr _AND
wchar_t wc)
{
return _fputwc_unlocked_r (ptr, wc, stdout);
}
 
/*
* Synonym for fputwc_unlocked(wc, stdout).
*/
wint_t
_DEFUN(putwchar_unlocked, (wc),
wchar_t wc)
{
_REENT_SMALL_CHECK_INIT (_REENT);
return fputwc_unlocked (wc, stdout);
}
/contrib/sdk/sources/newlib/libc/stdio/swprintf.c
0,0 → 1,635
/*
* Copyright (c) 1990, 2007 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<swprintf>>, <<fwprintf>>, <<wprintf>>---wide character format output
 
INDEX
fwprintf
INDEX
_fwprintf_r
INDEX
wprintf
INDEX
_wprintf_r
INDEX
swprintf
INDEX
_swprintf_r
 
ANSI_SYNOPSIS
#include <wchar.h>
 
int wprintf(const wchar_t *<[format]>, ...);
int fwprintf(FILE *__restrict <[fd]>,
const wchar_t *__restrict <[format]>, ...);
int swprintf(wchar_t *__restrict <[str]>, size_t <[size]>,
const wchar_t *__restrict <[format]>, ...);
 
int _wprintf_r(struct _reent *<[ptr]>, const wchar_t *<[format]>, ...);
int _fwprintf_r(struct _reent *<[ptr]>, FILE *<[fd]>,
const wchar_t *<[format]>, ...);
int _swprintf_r(struct _reent *<[ptr]>, wchar_t *<[str]>,
size_t <[size]>, const wchar_t *<[format]>, ...);
 
DESCRIPTION
<<wprintf>> accepts a series of arguments, applies to each a
format specifier from <<*<[format]>>>, and writes the
formatted data to <<stdout>>, without a terminating NUL
wide character. The behavior of <<wprintf>> is undefined if there
are not enough arguments for the format or if any argument is not the
right type for the corresponding conversion specifier. <<wprintf>>
returns when it reaches the end of the format string. If there are
more arguments than the format requires, excess arguments are
ignored.
 
<<fwprintf>> is like <<wprintf>>, except that output is directed
to the stream <[fd]> rather than <<stdout>>.
 
<<swprintf>> is like <<wprintf>>, except that output is directed
to the buffer <[str]> with a terminating wide <<NUL>>, and the
resulting string length is limited to at most <[size]> wide characters,
including the terminating <<NUL>>. It is considered an error if the
output (including the terminating wide-<<NULL>>) does not fit into
<[size]> wide characters. (This error behavior is not the same as for
<<snprintf>>, which <<swprintf>> is otherwise completely analogous to.
While <<snprintf>> allows the needed size to be known simply by giving
<[size]>=0, <<swprintf>> does not, giving an error instead.)
 
For <<swprintf>> the behavior is undefined if the output
<<*<[str]>>> overlaps with one of the arguments. Behavior is also
undefined if the argument for <<%n>> within <<*<[format]>>>
overlaps another argument.
 
<[format]> is a pointer to a wide character string containing two
types of objects: ordinary characters (other than <<%>>),
which are copied unchanged to the output, and conversion
specifications, each of which is introduced by <<%>>. (To
include <<%>> in the output, use <<%%>> in the format string.)
A conversion specification has the following form:
 
. %[<[pos]>][<[flags]>][<[width]>][.<[prec]>][<[size]>]<[type]>
 
The fields of the conversion specification have the following
meanings:
 
O+
o <[pos]>
 
Conversions normally consume arguments in the order that they
are presented. However, it is possible to consume arguments
out of order, and reuse an argument for more than one
conversion specification (although the behavior is undefined
if the same argument is requested with different types), by
specifying <[pos]>, which is a decimal integer followed by
'$'. The integer must be between 1 and <NL_ARGMAX> from
limits.h, and if argument <<%n$>> is requested, all earlier
arguments must be requested somewhere within <[format]>. If
positional parameters are used, then all conversion
specifications except for <<%%>> must specify a position.
This positional parameters method is a POSIX extension to the C
standard definition for the functions.
 
o <[flags]>
 
<[flags]> is an optional sequence of characters which control
output justification, numeric signs, decimal points, trailing
zeros, and octal and hex prefixes. The flag characters are
minus (<<->>), plus (<<+>>), space ( ), zero (<<0>>), sharp
(<<#>>), and quote (<<'>>). They can appear in any
combination, although not all flags can be used for all
conversion specification types.
 
o+
o '
A POSIX extension to the C standard. However, this
implementation presently treats it as a no-op, which
is the default behavior for the C locale, anyway. (If
it did what it is supposed to, when <[type]> were <<i>>,
<<d>>, <<u>>, <<f>>, <<F>>, <<g>>, or <<G>>, the
integer portion of the conversion would be formatted
with thousands' grouping wide characters.)
 
o -
The result of the conversion is left
justified, and the right is padded with
blanks. If you do not use this flag, the
result is right justified, and padded on the
left.
 
o +
The result of a signed conversion (as
determined by <[type]> of <<d>>, <<i>>, <<a>>,
<<A>>, <<e>>, <<E>>, <<f>>, <<F>>, <<g>>, or
<<G>>) will always begin with a plus or minus
sign. (If you do not use this flag, positive
values do not begin with a plus sign.)
 
o " " (space)
If the first character of a signed conversion
specification is not a sign, or if a signed
conversion results in no characters, the
result will begin with a space. If the space
( ) flag and the plus (<<+>>) flag both
appear, the space flag is ignored.
 
o 0
If the <[type]> character is <<d>>, <<i>>,
<<o>>, <<u>>, <<x>>, <<X>>, <<a>>, <<A>>,
<<e>>, <<E>>, <<f>>, <<F>>, <<g>>, or <<G>>: leading
zeros are used to pad the field width
(following any indication of sign or base); no
spaces are used for padding. If the zero
(<<0>>) and minus (<<->>) flags both appear,
the zero (<<0>>) flag will be ignored. For
<<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>
conversions, if a precision <[prec]> is
specified, the zero (<<0>>) flag is ignored.
 
Note that <<0>> is interpreted as a flag, not
as the beginning of a field width.
 
o #
The result is to be converted to an
alternative form, according to the <[type]>
character.
o-
 
The alternative form output with the # flag depends on the <[type]>
character:
 
o+
o o
Increases precision to force the first
digit of the result to be a zero.
 
o x
A non-zero result will have a <<0x>>
prefix.
 
o X
A non-zero result will have a <<0X>>
prefix.
 
o a, A, e, E, f, or F
The result will always contain a
decimal point even if no digits follow
the point. (Normally, a decimal point
appears only if a digit follows it.)
Trailing zeros are removed.
 
o g or G
The result will always contain a
decimal point even if no digits follow
the point. Trailing zeros are not
removed.
 
o all others
Undefined.
 
o-
 
 
o <[width]>
 
<[width]> is an optional minimum field width. You can
either specify it directly as a decimal integer, or
indirectly by using instead an asterisk (<<*>>), in
which case an <<int>> argument is used as the field
width. If positional arguments are used, then the
width must also be specified positionally as <<*m$>>,
with m as a decimal integer. Negative field widths
are treated as specifying the minus (<<->>) flag for
left justfication, along with a positive field width.
The resulting format may be wider than the specified
width.
 
o <[prec]>
 
<[prec]> is an optional field; if present, it is
introduced with `<<.>>' (a period). You can specify
the precision either directly as a decimal integer or
indirectly by using an asterisk (<<*>>), in which case
an <<int>> argument is used as the precision. If
positional arguments are used, then the precision must
also be specified positionally as <<*m$>>, with m as a
decimal integer. Supplying a negative precision is
equivalent to omitting the precision. If only a
period is specified the precision is zero. The effect
depends on the conversion <[type]>.
 
o+
o d, i, o, u, x, or X
Minimum number of digits to appear. If no
precision is given, defaults to 1.
 
o a or A
Number of digits to appear after the decimal
point. If no precision is given, the
precision defaults to the minimum needed for
an exact representation.
 
o e, E, f or F
Number of digits to appear after the decimal
point. If no precision is given, the
precision defaults to 6.
 
o g or G
Maximum number of significant digits. A
precision of 0 is treated the same as a
precision of 1. If no precision is given, the
precision defaults to 6.
 
o s or S
Maximum number of characters to print from the
string. If no precision is given, the entire
string is printed.
 
o all others
undefined.
 
o-
 
o <[size]>
 
<[size]> is an optional modifier that changes the data
type that the corresponding argument has. Behavior is
unspecified if a size is given that does not match the
<[type]>.
 
o+
o hh
With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
<<X>>, specifies that the argument should be
converted to a <<signed char>> or <<unsigned
char>> before printing.
 
With <<n>>, specifies that the argument is a
pointer to a <<signed char>>.
 
o h
With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
<<X>>, specifies that the argument should be
converted to a <<short>> or <<unsigned short>>
before printing.
 
With <<n>>, specifies that the argument is a
pointer to a <<short>>.
 
o l
With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
<<X>>, specifies that the argument is a
<<long>> or <<unsigned long>>.
 
With <<c>>, specifies that the argument has
type <<wint_t>>.
 
With <<s>>, specifies that the argument is a
pointer to <<wchar_t>>.
 
With <<n>>, specifies that the argument is a
pointer to a <<long>>.
 
With <<a>>, <<A>>, <<e>>, <<E>>, <<f>>, <<F>>,
<<g>>, or <<G>>, has no effect (because of
vararg promotion rules, there is no need to
distinguish between <<float>> and <<double>>).
 
o ll
With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
<<X>>, specifies that the argument is a
<<long long>> or <<unsigned long long>>.
 
With <<n>>, specifies that the argument is a
pointer to a <<long long>>.
 
o j
With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
<<X>>, specifies that the argument is an
<<intmax_t>> or <<uintmax_t>>.
 
With <<n>>, specifies that the argument is a
pointer to an <<intmax_t>>.
 
o z
With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
<<X>>, specifies that the argument is a <<size_t>>.
 
With <<n>>, specifies that the argument is a
pointer to a <<size_t>>.
 
o t
With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
<<X>>, specifies that the argument is a
<<ptrdiff_t>>.
 
With <<n>>, specifies that the argument is a
pointer to a <<ptrdiff_t>>.
 
o L
With <<a>>, <<A>>, <<e>>, <<E>>, <<f>>, <<F>>,
<<g>>, or <<G>>, specifies that the argument
is a <<long double>>.
 
o-
 
o <[type]>
 
<[type]> specifies what kind of conversion <<wprintf>>
performs. Here is a table of these:
 
o+
o %
Prints the percent character (<<%>>).
 
o c
If no <<l>> qualifier is present, the int argument shall
be converted to a wide character as if by calling
the btowc() function and the resulting wide character
shall be written. Otherwise, the wint_t argument
shall be converted to wchar_t, and written.
 
o C
Short for <<%lc>>. A POSIX extension to the C standard.
 
o s
If no <<l>> qualifier is present, the application
shall ensure that the argument is a pointer to a
character array containing a character sequence
beginning in the initial shift state. Characters
from the array shall be converted as if by repeated
calls to the mbrtowc() function, with the conversion
state described by an mbstate_t object initialized to
zero before the first character is converted, and
written up to (but not including) the terminating
null wide character. If the precision is specified,
no more than that many wide characters shall be
written. If the precision is not specified, or is
greater than the size of the array, the application
shall ensure that the array contains a null wide
character.
 
If an <<l>> qualifier is present, the application
shall ensure that the argument is a pointer to an
array of type wchar_t. Wide characters from the array
shall be written up to (but not including) a
terminating null wide character. If no precision is
specified, or is greater than the size of the array,
the application shall ensure that the array contains
a null wide character. If a precision is specified,
no more than that many wide characters shall be
written.
 
o S
Short for <<%ls>>. A POSIX extension to the C standard.
 
o d or i
Prints a signed decimal integer; takes an
<<int>>. Leading zeros are inserted as
necessary to reach the precision. A value of 0 with
a precision of 0 produces an empty string.
 
o o
Prints an unsigned octal integer; takes an
<<unsigned>>. Leading zeros are inserted as
necessary to reach the precision. A value of 0 with
a precision of 0 produces an empty string.
 
o u
Prints an unsigned decimal integer; takes an
<<unsigned>>. Leading zeros are inserted as
necessary to reach the precision. A value of 0 with
a precision of 0 produces an empty string.
 
o x
Prints an unsigned hexadecimal integer (using
<<abcdef>> as digits beyond <<9>>); takes an
<<unsigned>>. Leading zeros are inserted as
necessary to reach the precision. A value of 0 with
a precision of 0 produces an empty string.
 
o X
Like <<x>>, but uses <<ABCDEF>> as digits
beyond <<9>>.
 
o f
Prints a signed value of the form
<<[-]9999.9999>>, with the precision
determining how many digits follow the decimal
point; takes a <<double>> (remember that
<<float>> promotes to <<double>> as a vararg).
The low order digit is rounded to even. If
the precision results in at most DECIMAL_DIG
digits, the result is rounded correctly; if
more than DECIMAL_DIG digits are printed, the
result is only guaranteed to round back to the
original value.
 
If the value is infinite, the result is
<<inf>>, and no zero padding is performed. If
the value is not a number, the result is
<<nan>>, and no zero padding is performed.
 
o F
Like <<f>>, but uses <<INF>> and <<NAN>> for
non-finite numbers.
 
o e
Prints a signed value of the form
<<[-]9.9999e[+|-]999>>; takes a <<double>>.
The digit before the decimal point is non-zero
if the value is non-zero. The precision
determines how many digits appear between
<<.>> and <<e>>, and the exponent always
contains at least two digits. The value zero
has an exponent of zero. If the value is not
finite, it is printed like <<f>>.
 
o E
Like <<e>>, but using <<E>> to introduce the
exponent, and like <<F>> for non-finite
values.
 
o g
Prints a signed value in either <<f>> or <<e>>
form, based on the given value and
precision---an exponent less than -4 or
greater than the precision selects the <<e>>
form. Trailing zeros and the decimal point
are printed only if necessary; takes a
<<double>>.
 
o G
Like <<g>>, except use <<F>> or <<E>> form.
 
o a
Prints a signed value of the form
<<[-]0x1.ffffp[+|-]9>>; takes a <<double>>.
The letters <<abcdef>> are used for digits
beyond <<9>>. The precision determines how
many digits appear after the decimal point.
The exponent contains at least one digit, and
is a decimal value representing the power of
2; a value of 0 has an exponent of 0.
Non-finite values are printed like <<f>>.
 
o A
Like <<a>>, except uses <<X>>, <<P>>, and
<<ABCDEF>> instead of lower case.
 
o n
Takes a pointer to <<int>>, and stores a count
of the number of bytes written so far. No
output is created.
 
o p
Takes a pointer to <<void>>, and prints it in
an implementation-defined format. This
implementation is similar to <<%#tx>>), except
that <<0x>> appears even for the NULL pointer.
 
o m
Prints the output of <<strerror(errno)>>; no
argument is required. A GNU extension.
 
o-
O-
 
<<_wprintf_r>>, <<_fwprintf_r>>, <<_swprintf_r>>, are simply
reentrant versions of the functions above.
 
RETURNS
On success, <<swprintf>> return the number of wide characters in
the output string, except the concluding <<NUL>> is not counted.
<<wprintf>> and <<fwprintf>> return the number of characters transmitted.
 
If an error occurs, the result of <<wprintf>>, <<fwprintf>>, and
<<swprintf>> is a negative value. For <<wprintf>> and <<fwprintf>>,
<<errno>> may be set according to <<fputwc>>. For <<swprintf>>, <<errno>>
may be set to EOVERFLOW if <[size]> is greater than INT_MAX / sizeof (wchar_t),
or when the output does not fit into <[size]> wide characters (including the
terminating wide <<NULL>>).
 
BUGS
The ``''' (quote) flag does not work when locale's thousands_sep is not empty.
 
PORTABILITY
POSIX-1.2008 with extensions; C99 (compliant except for POSIX extensions).
 
Depending on how newlib was configured, not all format specifiers are
supported.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
#include <limits.h>
#include <errno.h>
#include "local.h"
 
/* NOTE: _swprintf_r() should be identical to swprintf() except for the
* former having ptr as a parameter and the latter needing to declare it as
* a variable set to _REENT. */
 
int
_DEFUN(_swprintf_r, (ptr, str, size, fmt),
struct _reent *ptr _AND
wchar_t *str _AND
size_t size _AND
_CONST wchar_t *fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
 
if (size > INT_MAX / sizeof (wchar_t))
{
ptr->_errno = EOVERFLOW; /* POSIX extension */
return EOF;
}
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = (size > 0 ? (size - 1) * sizeof (wchar_t) : 0);
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfwprintf_r (ptr, &f, fmt, ap);
va_end (ap);
/* _svfwprintf_r() does not put in a terminating NUL, so add one if
* appropriate, which is whenever size is > 0. _svfwprintf_r() stops
* after n-1, so always just put at the end. */
if (size > 0) {
*(wchar_t *)f._p = L'\0'; /* terminate the string */
}
if(ret >= size) {
/* _svfwprintf_r() returns how many wide characters it would have printed
* if there were enough space. Return an error if too big to fit in str,
* unlike snprintf, which returns the size needed. */
ptr->_errno = EOVERFLOW; /* POSIX extension */
ret = -1;
}
return (ret);
}
 
#ifndef _REENT_ONLY
 
int
_DEFUN(swprintf, (str, size, fmt),
wchar_t *__restrict str _AND
size_t size _AND
_CONST wchar_t *__restrict fmt _DOTS)
{
int ret;
va_list ap;
FILE f;
struct _reent *ptr = _REENT;
 
if (size > INT_MAX / sizeof (wchar_t))
{
ptr->_errno = EOVERFLOW; /* POSIX extension */
return EOF;
}
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = (size > 0 ? (size - 1) * sizeof (wchar_t) : 0);
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = _svfwprintf_r (ptr, &f, fmt, ap);
va_end (ap);
/* _svfwprintf_r() does not put in a terminating NUL, so add one if
* appropriate, which is whenever size is > 0. _svfwprintf_r() stops
* after n-1, so always just put at the end. */
if (size > 0) {
*(wchar_t *)f._p = L'\0'; /* terminate the string */
}
if(ret >= size) {
/* _svfwprintf_r() returns how many wide characters it would have printed
* if there were enough space. Return an error if too big to fit in str,
* unlike snprintf, which returns the size needed. */
ptr->_errno = EOVERFLOW; /* POSIX extension */
ret = -1;
}
return (ret);
}
 
#endif
/contrib/sdk/sources/newlib/libc/stdio/swscanf.c
0,0 → 1,487
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<swscanf>>, <<fwscanf>>, <<wscanf>>---scan and format wide character input
 
INDEX
wscanf
INDEX
_wscanf_r
INDEX
fwscanf
INDEX
_fwscanf_r
INDEX
swscanf
INDEX
_swscanf_r
 
ANSI_SYNOPSIS
#include <stdio.h>
 
int wscanf(const wchar_t *__restrict <[format]>, ...);
int fwscanf(FILE *__restrict <[fd]>,
const wchar_t *__restrict <[format]>, ...);
int swscanf(const wchar_t *__restrict <[str]>,
const wchar_t *__restrict <[format]>, ...);
 
int _wscanf_r(struct _reent *<[ptr]>, const wchar_t *<[format]>, ...);
int _fwscanf_r(struct _reent *<[ptr]>, FILE *<[fd]>,
const wchar_t *<[format]>, ...);
int _swscanf_r(struct _reent *<[ptr]>, const wchar_t *<[str]>,
const wchar_t *<[format]>, ...);
 
 
TRAD_SYNOPSIS
#include <stdio.h>
 
int wscanf(<[format]> [, <[arg]>, ...])
wchar_t *__restrict <[format]>;
 
int fwscanf(<[fd]>, <[format]> [, <[arg]>, ...]);
FILE *<[fd]>;
wchar_t *<[format]>;
 
int swscanf(<[str]>, <[format]> [, <[arg]>, ...]);
wchar_t *__restrict <[str]>;
wchar_t *__restrict <[format]>;
 
int _wscanf_r(<[ptr]>, <[format]> [, <[arg]>, ...])
struct _reent *<[ptr]>;
wchar_t *<[format]>;
 
int _fwscanf_r(<[ptr]>, <[fd]>, <[format]> [, <[arg]>, ...]);
struct _reent *<[ptr]>;
FILE *<[fd]>;
wchar_t *<[format]>;
 
int _swscanf_r(<[ptr]>, <[str]>, <[format]> [, <[arg]>, ...]);
struct _reent *<[ptr]>;
wchar_t *<[str]>;
wchar_t *<[format]>;
 
 
DESCRIPTION
<<wscanf>> scans a series of input fields from standard input,
one wide character at a time. Each field is interpreted according to
a format specifier passed to <<wscanf>> in the format string at
<<*<[format]>>>. <<wscanf>> stores the interpreted input from
each field at the address passed to it as the corresponding argument
following <[format]>. You must supply the same number of
format specifiers and address arguments as there are input fields.
 
There must be sufficient address arguments for the given format
specifiers; if not the results are unpredictable and likely
disasterous. Excess address arguments are merely ignored.
 
<<wscanf>> often produces unexpected results if the input diverges from
an expected pattern. Since the combination of <<gets>> or <<fgets>>
followed by <<swscanf>> is safe and easy, that is the preferred way
to be certain that a program is synchronized with input at the end
of a line.
 
<<fwscanf>> and <<swscanf>> are identical to <<wscanf>>, other than the
source of input: <<fwscanf>> reads from a file, and <<swscanf>>
from a string.
 
The routines <<_wscanf_r>>, <<_fwscanf_r>>, and <<_swscanf_r>> are reentrant
versions of <<wscanf>>, <<fwscanf>>, and <<swscanf>> that take an additional
first argument pointing to a reentrancy structure.
 
The string at <<*<[format]>>> is a wide character sequence composed
of zero or more directives. Directives are composed of
one or more whitespace characters, non-whitespace characters,
and format specifications.
 
Whitespace characters are blank (<< >>), tab (<<\t>>), or
newline (<<\n>>).
When <<wscanf>> encounters a whitespace character in the format string
it will read (but not store) all consecutive whitespace characters
up to the next non-whitespace character in the input.
 
Non-whitespace characters are all other ASCII characters except the
percent sign (<<%>>). When <<wscanf>> encounters a non-whitespace
character in the format string it will read, but not store
a matching non-whitespace character.
 
Format specifications tell <<wscanf>> to read and convert characters
from the input field into specific types of values, and store then
in the locations specified by the address arguments.
 
Trailing whitespace is left unread unless explicitly
matched in the format string.
 
The format specifiers must begin with a percent sign (<<%>>)
and have the following form:
 
. %[*][<[width]>][<[size]>]<[type]>
 
Each format specification begins with the percent character (<<%>>).
The other fields are:
O+
o *
 
an optional marker; if present, it suppresses interpretation and
assignment of this input field.
 
o <[width]>
 
an optional maximum field width: a decimal integer,
which controls the maximum number of characters that
will be read before converting the current input field. If the
input field has fewer than <[width]> characters, <<wscanf>>
reads all the characters in the field, and then
proceeds with the next field and its format specification.
 
If a whitespace or a non-convertable wide character occurs
before <[width]> character are read, the characters up
to that character are read, converted, and stored.
Then <<wscanf>> proceeds to the next format specification.
 
o <[size]>
 
<<h>>, <<j>>, <<l>>, <<L>>, <<t>>, and <<z>> are optional size
characters which override the default way that <<wscanf>>
interprets the data type of the corresponding argument.
 
@multitable @columnfractions 0.18 0.30 0.52
@headitem
Modifier
@tab
Type(s)
@tab
@item
hh
@tab
d, i, o, u, x, n
@tab
convert input to char, store in char object
@item
h
@tab
d, i, o, u, x, n
@tab
convert input to short, store in short object
@item
h
@tab
e, f, c, s, p
@tab
no effect
@item
j
@tab
d, i, o, u, x, n
@tab
convert input to intmax_t, store in intmax_t object
@item
j
@tab
all others
@tab
no effect
@item
l
@tab
d, i, o, u, x, n
@tab
convert input to long, store in long object
@item
l
@tab
e, f, g
@tab
convert input to double, store in a double object
@item
l
@tab
c, s, [
@tab
the input is stored in a wchar_t object
@item
l
@tab
p
@tab
no effect
@item
ll
@tab
d, i, o, u, x, n
@tab
convert to long long, store in long long object
@item
L
@tab
d, i, o, u, x, n
@tab
convert to long long, store in long long object
@item
L
@tab
e, f, g, E, G
@tab
convert to long double, store in long double object
@item
L
@tab
all others
@tab
no effect
@item
t
@tab
d, i, o, u, x, n
@tab
convert input to ptrdiff_t, store in ptrdiff_t object
@item
t
@tab
all others
@tab
no effect
@item
z
@tab
d, i, o, u, x, n
@tab
convert input to size_t, store in size_t object
@item
z
@tab
all others
@tab
no effect
@end multitable
 
o <[type]>
 
A character to specify what kind of conversion
<<wscanf>> performs. Here is a table of the conversion
characters:
 
o+
o %
No conversion is done; the percent character (<<%>>) is stored.
 
o c
Scans one wide character. Corresponding <[arg]>: <<(char *arg)>>.
Otherwise, if an <<l>> specifier is present, the corresponding
<[arg]> is a <<(wchar_t *arg)>>.
 
o s
Reads a character string into the array supplied.
Corresponding <[arg]>: <<(char arg[])>>.
If an <<l>> specifier is present, the corresponding <[arg]> is a <<(wchar_t *arg)>>.
 
o [<[pattern]>]
Reads a non-empty character string into memory
starting at <[arg]>. This area must be large
enough to accept the sequence and a
terminating null character which will be added
automatically. (<[pattern]> is discussed in the paragraph following
this table). Corresponding <[arg]>: <<(char *arg)>>.
If an <<l>> specifier is present, the corresponding <[arg]> is
a <<(wchar_t *arg)>>.
 
o d
Reads a decimal integer into the corresponding <[arg]>: <<(int *arg)>>.
 
o o
Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>.
 
o u
Reads an unsigned decimal integer into the corresponding
<[arg]>: <<(unsigned int *arg)>>.
 
o x,X
Read a hexadecimal integer into the corresponding <[arg]>:
<<(int *arg)>>.
 
o e, f, g
Read a floating-point number into the corresponding <[arg]>:
<<(float *arg)>>.
 
o E, F, G
Read a floating-point number into the corresponding <[arg]>:
<<(double *arg)>>.
 
o i
Reads a decimal, octal or hexadecimal integer into the
corresponding <[arg]>: <<(int *arg)>>.
 
o n
Stores the number of characters read in the corresponding
<[arg]>: <<(int *arg)>>.
 
o p
Stores a scanned pointer. ANSI C leaves the details
to each implementation; this implementation treats
<<%p>> exactly the same as <<%U>>. Corresponding
<[arg]>: <<(void **arg)>>.
o-
 
A <[pattern]> of characters surrounded by square brackets can be used
instead of the <<s>> type character. <[pattern]> is a set of
characters which define a search set of possible characters making up
the <<wscanf>> input field. If the first character in the brackets is a
caret (<<^>>), the search set is inverted to include all ASCII characters
except those between the brackets. There is no range facility as is
defined in the corresponding non-wide character scanf functions.
Ranges are not part of the POSIX standard.
 
Here are some <[pattern]> examples:
o+
o %[abcd]
matches wide character strings containing only
<<a>>, <<b>>, <<c>>, and <<d>>.
 
o %[^abcd]
matches wide character strings containing any characters except
<<a>>, <<b>>, <<c>>, or <<d>>.
 
o %[A-DW-Z]
Note: No wide character ranges, so this expression matches wide
character strings containing <<A>>, <<->>, <<D>>, <<W>>, <<Z>>.
o-
 
Floating point numbers (for field types <<e>>, <<f>>, <<g>>, <<E>>,
<<F>>, <<G>>) must correspond to the following general form:
 
. [+/-] ddddd[.]ddd [E|e[+|-]ddd]
 
where objects inclosed in square brackets are optional, and <<ddd>>
represents decimal, octal, or hexadecimal digits.
O-
 
RETURNS
<<wscanf>> returns the number of input fields successfully
scanned, converted and stored; the return value does
not include scanned fields which were not stored.
 
If <<wscanf>> attempts to read at end-of-file, the return
value is <<EOF>>.
 
If no fields were stored, the return value is <<0>>.
 
<<wscanf>> might stop scanning a particular field before
reaching the normal field end character, or may
terminate entirely.
 
<<wscanf>> stops scanning and storing the current field
and moves to the next input field (if any)
in any of the following situations:
 
O+
o The assignment suppressing character (<<*>>) appears
after the <<%>> in the format specification; the current
input field is scanned but not stored.
 
o <[width]> characters have been read (<[width]> is a
width specification, a positive decimal integer).
 
o The next wide character read cannot be converted
under the the current format (for example,
if a <<Z>> is read when the format is decimal).
 
o The next wide character in the input field does not appear
in the search set (or does appear in the inverted search set).
O-
 
When <<wscanf>> stops scanning the current input field for one of
these reasons, the next character is considered unread and
used as the first character of the following input field, or the
first character in a subsequent read operation on the input.
 
<<wscanf>> will terminate under the following circumstances:
 
O+
o The next wide character in the input field conflicts
with a corresponding non-whitespace character in the
format string.
 
o The next wide character in the input field is <<WEOF>>.
 
o The format string has been exhausted.
O-
 
When the format string contains a wide character sequence that is
not part of a format specification, the same wide character
sequence must appear in the input; <<wscanf>> will
scan but not store the matched characters. If a
conflict occurs, the first conflicting wide character remains in the
input as if it had never been read.
 
PORTABILITY
<<wscanf>> is C99, POSIX-1.2008.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
#include "local.h"
 
#ifndef _REENT_ONLY
 
int
swscanf (_CONST wchar_t *__restrict str, _CONST wchar_t *__restrict fmt, ...)
{
int ret;
va_list ap;
FILE f;
 
f._flags = __SRD | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._r = wcslen (str) * sizeof (wchar_t);
f._read = __seofread;
f._ub._base = NULL;
f._lb._base = NULL;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = __ssvfwscanf_r (_REENT, &f, fmt, ap);
va_end (ap);
return ret;
}
 
#endif /* !_REENT_ONLY */
 
int
_swscanf_r (struct _reent *ptr, _CONST wchar_t *str, _CONST wchar_t *fmt, ...)
{
int ret;
va_list ap;
FILE f;
 
f._flags = __SRD | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._r = wcslen (str) * sizeof (wchar_t);
f._read = __seofread;
f._ub._base = NULL;
f._lb._base = NULL;
f._file = -1; /* No file. */
va_start (ap, fmt);
ret = __ssvfwscanf_r (ptr, &f, fmt, ap);
va_end (ap);
return ret;
}
/contrib/sdk/sources/newlib/libc/stdio/ungetwc.c
0,0 → 1,117
/*-
* Copyright (c) 2002-2004 Tim J. Robbins.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
 
/*
FUNCTION
<<ungetwc>>---push wide character data back into a stream
 
INDEX
ungetwc
INDEX
_ungetwc_r
 
ANSI_SYNOPSIS
#include <stdio.h>
#include <wchar.h>
wint_t ungetwc(wint_t <[wc]>, FILE *<[stream]>);
 
wint_t _ungetwc_r(struct _reent *<[reent]>, wint_t <[wc]>, FILE *<[stream]>);
 
DESCRIPTION
<<ungetwc>> is used to return wide characters back to <[stream]> to be
read again. If <[wc]> is WEOF, the stream is unchanged. Otherwise, the
wide character <[wc]> is put back on the stream, and subsequent reads will see
the wide chars pushed back in reverse order. Pushed wide chars are lost if the
stream is repositioned, such as by <<fseek>>, <<fsetpos>>, or
<<rewind>>.
 
The underlying file is not changed, but it is possible to push back
something different than what was originally read. Ungetting a
character will clear the end-of-stream marker, and decrement the file
position indicator. Pushing back beyond the beginning of a file gives
unspecified behavior.
 
The alternate function <<_ungetwc_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
 
RETURNS
The wide character pushed back, or <<WEOF>> on error.
 
PORTABILITY
C99
*/
 
#include <_ansi.h>
#include <reent.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include "local.h"
 
wint_t
_DEFUN(_ungetwc_r, (ptr, wc, fp),
struct _reent *ptr _AND
wint_t wc _AND
register FILE *fp)
{
char buf[MB_LEN_MAX];
size_t len;
 
_newlib_flockfile_start (fp);
ORIENT (fp, 1);
if (wc == WEOF)
wc = WEOF;
else if ((len = _wcrtomb_r(ptr, buf, wc, &fp->_mbstate)) == (size_t)-1)
{
fp->_flags |= __SERR;
wc = WEOF;
}
else
while (len-- != 0)
if (_ungetc_r(ptr, (unsigned char)buf[len], fp) == EOF)
{
wc = WEOF;
break;
}
_newlib_flockfile_end (fp);
return wc;
}
 
/*
* MT-safe version.
*/
wint_t
_DEFUN(ungetwc, (wint_t wc, FILE *fp),
wint_t wc _AND
FILE *fp)
{
struct _reent *reent = _REENT;
 
CHECK_INIT (reent, fp);
return _ungetwc_r (reent, wc, fp);
}
/contrib/sdk/sources/newlib/libc/stdio/vfwprintf.c
0,0 → 1,2019
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* 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.
* 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.
*/
 
/*
FUNCTION
<<vfwprintf>>, <<vwprintf>>, <<vswprintf>>---wide character format argument list
 
INDEX
vfwprintf
INDEX
_vfwprintf_r
INDEX
vwprintf
INDEX
_vwprintf_r
INDEX
vswprintf
INDEX
_vswprintf_r
 
ANSI_SYNOPSIS
#include <stdio.h>
#include <stdarg.h>
#include <wchar.h>
int vwprintf(const wchar_t *__restrict <[fmt]>, va_list <[list]>);
int vfwprintf(FILE *__restrict <[fp]>,
const wchar_t *__restrict <[fmt]>, va_list <[list]>);
int vswprintf(wchar_t * __restrict <[str]>, size_t <[size]>,
const wchar_t *__ restrict <[fmt]>, va_list <[list]>);
 
int _vwprintf_r(struct _reent *<[reent]>, const wchar_t *<[fmt]>,
va_list <[list]>);
int _vfwprintf_r(struct _reent *<[reent]>, FILE *<[fp]>,
const wchar_t *<[fmt]>, va_list <[list]>);
int _vswprintf_r(struct _reent *<[reent]>, wchar_t *<[str]>,
size_t <[size]>, const wchar_t *<[fmt]>, va_list <[list]>);
 
DESCRIPTION
<<vwprintf>>, <<vfwprintf>> and <<vswprintf>> are (respectively) variants
of <<wprintf>>, <<fwprintf>> and <<swprintf>>. They differ only in allowing
their caller to pass the variable argument list as a <<va_list>> object
(initialized by <<va_start>>) rather than directly accepting a variable
number of arguments. The caller is responsible for calling <<va_end>>.
 
<<_vwprintf_r>>, <<_vfwprintf_r>> and <<_vswprintf_r>> are reentrant
versions of the above.
 
RETURNS
The return values are consistent with the corresponding functions.
 
PORTABILITY
POSIX-1.2008 with extensions; C99 (compliant except for POSIX extensions).
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
 
SEEALSO
<<wprintf>>, <<fwprintf>> and <<swprintf>>.
*/
 
/*
* Actual wprintf innards.
*
* This code is large and complicated...
*/
#include <newlib.h>
 
#ifdef INTEGER_ONLY
# define VFWPRINTF vfiwprintf
# ifdef STRING_ONLY
# define _VFWPRINTF_R _svfiwprintf_r
# else
# define _VFWPRINTF_R _vfiwprintf_r
# endif
#else
# define VFWPRINTF vfwprintf
# ifdef STRING_ONLY
# define _VFWPRINTF_R _svfwprintf_r
# else
# define _VFWPRINTF_R _vfwprintf_r
# endif
# ifndef NO_FLOATING_POINT
# define FLOATING_POINT
# endif
#endif
 
#define _NO_POS_ARGS
#ifdef _WANT_IO_POS_ARGS
# undef _NO_POS_ARGS
#endif
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>
#include <wchar.h>
#include <sys/lock.h>
#include <stdarg.h>
#include "local.h"
#include "fvwrite.h"
#include "vfieeefp.h"
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
#include "../locale/lnumeric.h"
#endif
 
/* Currently a test is made to see if long double processing is warranted.
This could be changed in the future should the _ldtoa_r code be
preferred over _dtoa_r. */
#define _NO_LONGDBL
#if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
#undef _NO_LONGDBL
#endif
 
#define _NO_LONGLONG
#if defined _WANT_IO_LONG_LONG \
&& (defined __GNUC__ || __STDC_VERSION__ >= 199901L)
# undef _NO_LONGLONG
#endif
 
int _EXFUN(_VFWPRINTF_R, (struct _reent *, FILE *, _CONST wchar_t *, va_list));
/* Defined in vfprintf.c. */
#ifdef _FVWRITE_IN_STREAMIO
# ifdef STRING_ONLY
# define __SPRINT __ssprint_r
# else
# define __SPRINT __sprint_r
# endif
int _EXFUN(__SPRINT, (struct _reent *, FILE *, register struct __suio *));
#else
# ifdef STRING_ONLY
# define __SPRINT __ssputs_r
# else
# define __SPRINT __sfputs_r
# endif
int _EXFUN(__SPRINT, (struct _reent *, FILE *, _CONST char *, size_t));
#endif
#ifndef STRING_ONLY
#ifdef _UNBUF_STREAM_OPT
/*
* Helper function for `fprintf to unbuffered unix file': creates a
* temporary buffer. We only work on write-only files; this avoids
* worries about ungetc buffers and so forth.
*/
static int
_DEFUN(__sbwprintf, (rptr, fp, fmt, ap),
struct _reent *rptr _AND
register FILE *fp _AND
_CONST wchar_t *fmt _AND
va_list ap)
{
int ret;
FILE fake;
unsigned char buf[BUFSIZ];
 
/* copy the important variables */
fake._flags = fp->_flags & ~__SNBF;
fake._flags2 = fp->_flags2;
fake._file = fp->_file;
fake._cookie = fp->_cookie;
fake._write = fp->_write;
 
/* set up the buffer */
fake._bf._base = fake._p = buf;
fake._bf._size = fake._w = sizeof (buf);
fake._lbfsize = 0; /* not actually used, but Just In Case */
#ifndef __SINGLE_THREAD__
__lock_init_recursive (fake._lock);
#endif
 
/* do the work, then copy any error status */
ret = _VFWPRINTF_R (rptr, &fake, fmt, ap);
if (ret >= 0 && _fflush_r (rptr, &fake))
ret = EOF;
if (fake._flags & __SERR)
fp->_flags |= __SERR;
 
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fake._lock);
#endif
return (ret);
}
#endif /* _UNBUF_STREAM_OPT */
#endif /* !STRING_ONLY */
 
 
#if defined (FLOATING_POINT) || defined (_WANT_IO_C99_FORMATS)
# include <locale.h>
#endif
#ifdef FLOATING_POINT
# include <math.h>
 
/* For %La, an exponent of 15 bits occupies the exponent character, a
sign, and up to 5 digits. */
# define MAXEXPLEN 7
# define DEFPREC 6
 
# ifdef _NO_LONGDBL
 
extern char *_dtoa_r _PARAMS((struct _reent *, double, int,
int, int *, int *, char **));
 
# define _PRINTF_FLOAT_TYPE double
# define _DTOA_R _dtoa_r
# define FREXP frexp
 
# else /* !_NO_LONGDBL */
 
extern char *_ldtoa_r _PARAMS((struct _reent *, _LONG_DOUBLE, int,
int, int *, int *, char **));
 
extern int _EXFUN(_ldcheck,(_LONG_DOUBLE *));
 
# define _PRINTF_FLOAT_TYPE _LONG_DOUBLE
# define _DTOA_R _ldtoa_r
/* FIXME - frexpl is not yet supported; and cvt infloops if (double)f
converts a finite value into infinity. */
/* # define FREXP frexpl */
# define FREXP(f,e) ((_LONG_DOUBLE) frexp ((double)f, e))
# endif /* !_NO_LONGDBL */
 
static wchar_t *wcvt(struct _reent *, _PRINTF_FLOAT_TYPE, int, int, wchar_t *,
int *, int, int *, wchar_t *, int);
 
static int wexponent(wchar_t *, int, int);
 
#endif /* FLOATING_POINT */
 
/* BUF must be big enough for the maximum %#llo (assuming long long is
at most 64 bits, this would be 23 characters), the maximum
multibyte character %C, and the maximum default precision of %La
(assuming long double is at most 128 bits with 113 bits of
mantissa, this would be 29 characters). %e, %f, and %g use
reentrant storage shared with mprec. All other formats that use
buf get by with fewer characters. Making BUF slightly bigger
reduces the need for malloc in %.*a and %ls/%S, when large precision or
long strings are processed.
The bigger size of 100 bytes is used on systems which allow number
strings using the locale's grouping character. Since that's a multibyte
value, we should use a conservative value.
*/
#ifdef _WANT_IO_C99_FORMATS
#define BUF 100
#else
#define BUF 40
#endif
#if defined _MB_CAPABLE && MB_LEN_MAX > BUF
# undef BUF
# define BUF MB_LEN_MAX
#endif
 
#ifndef _NO_LONGLONG
# define quad_t long long
# define u_quad_t unsigned long long
#else
# define quad_t long
# define u_quad_t unsigned long
#endif
 
typedef quad_t * quad_ptr_t;
typedef _PTR void_ptr_t;
typedef char * char_ptr_t;
typedef wchar_t* wchar_ptr_t;
typedef long * long_ptr_t;
typedef int * int_ptr_t;
typedef short * short_ptr_t;
 
#ifndef _NO_POS_ARGS
# ifdef NL_ARGMAX
# define MAX_POS_ARGS NL_ARGMAX
# else
# define MAX_POS_ARGS 32
# endif
 
union arg_val
{
int val_int;
u_int val_u_int;
long val_long;
u_long val_u_long;
float val_float;
double val_double;
_LONG_DOUBLE val__LONG_DOUBLE;
int_ptr_t val_int_ptr_t;
short_ptr_t val_short_ptr_t;
long_ptr_t val_long_ptr_t;
char_ptr_t val_char_ptr_t;
wchar_ptr_t val_wchar_ptr_t;
quad_ptr_t val_quad_ptr_t;
void_ptr_t val_void_ptr_t;
quad_t val_quad_t;
u_quad_t val_u_quad_t;
wint_t val_wint_t;
};
 
static union arg_val *
_EXFUN(get_arg, (struct _reent *data, int n, wchar_t *fmt,
va_list *ap, int *numargs, union arg_val *args,
int *arg_type, wchar_t **last_fmt));
#endif /* !_NO_POS_ARGS */
 
/*
* Macros for converting digits to letters and vice versa
*/
#define to_digit(c) ((c) - L'0')
#define is_digit(c) ((unsigned)to_digit (c) <= 9)
#define to_char(n) ((n) + L'0')
 
/*
* Flags used during conversion.
*/
#define ALT 0x001 /* alternate form */
#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
#define LADJUST 0x004 /* left adjustment */
#define LONGDBL 0x008 /* long double */
#define LONGINT 0x010 /* long integer */
#ifndef _NO_LONGLONG
# define QUADINT 0x020 /* quad integer */
#else /* ifdef _NO_LONGLONG, make QUADINT equivalent to LONGINT, so
that %lld behaves the same as %ld, not as %d, as expected if:
sizeof (long long) = sizeof long > sizeof int */
# define QUADINT LONGINT
#endif
#define SHORTINT 0x040 /* short integer */
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
#define FPT 0x100 /* Floating point number */
#ifdef _WANT_IO_C99_FORMATS
# define CHARINT 0x200 /* char as integer */
#else /* define as 0, to make SARG and UARG occupy fewer instructions */
# define CHARINT 0
#endif
#ifdef _WANT_IO_C99_FORMATS
# define GROUPING 0x400 /* use grouping ("'" flag) */
#endif
 
#ifndef STRING_ONLY
int
_DEFUN(VFWPRINTF, (fp, fmt0, ap),
FILE *__restrict fp _AND
_CONST wchar_t *__restrict fmt0 _AND
va_list ap)
{
int result;
result = _VFWPRINTF_R (_REENT, fp, fmt0, ap);
return result;
}
#endif /* STRING_ONLY */
 
int
_DEFUN(_VFWPRINTF_R, (data, fp, fmt0, ap),
struct _reent *data _AND
FILE * fp _AND
_CONST wchar_t *fmt0 _AND
va_list ap)
{
register wchar_t *fmt; /* format string */
register wint_t ch; /* character from fmt */
register int n, m; /* handy integers (short term usage) */
register wchar_t *cp; /* handy char pointer (short term usage) */
register int flags; /* flags as above */
wchar_t *fmt_anchor; /* current format spec being processed */
#ifndef _NO_POS_ARGS
int N; /* arg number */
int arg_index; /* index into args processed directly */
int numargs; /* number of varargs read */
wchar_t *saved_fmt; /* saved fmt pointer */
union arg_val args[MAX_POS_ARGS];
int arg_type[MAX_POS_ARGS];
int is_pos_arg; /* is current format positional? */
int old_is_pos_arg; /* is current format positional? */
#endif
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format (%.3d), or -1 */
wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */
#ifdef _WANT_IO_C99_FORMATS
/* locale specific numeric grouping */
wchar_t thousands_sep = L'\0';
const char *grouping = NULL;
#endif
#if defined (_MB_CAPABLE) && !defined (__HAVE_LOCALE_INFO_EXTENDED__) \
&& (defined (FLOATING_POINT) || defined (_WANT_IO_C99_FORMATS))
mbstate_t state; /* mbtowc calls from library must not change state */
#endif
#ifdef FLOATING_POINT
wchar_t decimal_point;
wchar_t softsign; /* temporary negative sign for floats */
union { int i; _PRINTF_FLOAT_TYPE fp; } _double_ = {0};
# define _fpvalue (_double_.fp)
int expt; /* integer value of exponent */
int expsize = 0; /* character count for expstr */
wchar_t expstr[MAXEXPLEN]; /* buffer for exponent string */
int lead; /* sig figs before decimal or group sep */
#endif /* FLOATING_POINT */
#if defined (FLOATING_POINT) || defined (_WANT_IO_C99_FORMATS)
int ndig = 0; /* actual number of digits returned by cvt */
#endif
#if defined (FLOATING_POINT) && defined (_WANT_IO_C99_FORMATS)
int nseps; /* number of group separators with ' */
int nrepeats; /* number of repeats of the last group */
#endif
u_quad_t _uquad; /* integer arguments %[diouxX] */
enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
int dprec; /* a copy of prec if [diouxX], 0 otherwise */
int realsz; /* field size expanded by dprec */
int size = 0; /* size of converted field or string */
wchar_t *xdigs = NULL; /* digits for [xX] conversion */
#ifdef _FVWRITE_IN_STREAMIO
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
register struct __siov *iovp;/* for PRINT macro */
#endif
wchar_t buf[BUF]; /* space for %c, %ls/%S, %[diouxX], %[aA] */
wchar_t ox[2]; /* space for 0x hex-prefix */
wchar_t *malloc_buf = NULL;/* handy pointer for malloced buffers */
 
/*
* Choose PADSIZE to trade efficiency vs. size. If larger printf
* fields occur frequently, increase PADSIZE and make the initialisers
* below longer.
*/
#define PADSIZE 16 /* pad chunk size */
static _CONST wchar_t blanks[PADSIZE] =
{L' ',L' ',L' ',L' ',L' ',L' ',L' ',L' ',
L' ',L' ',L' ',L' ',L' ',L' ',L' ',L' '};
static _CONST wchar_t zeroes[PADSIZE] =
{L'0',L'0',L'0',L'0',L'0',L'0',L'0',L'0',
L'0',L'0',L'0',L'0',L'0',L'0',L'0',L'0'};
 
#ifdef FLOATING_POINT
#ifdef _MB_CAPABLE
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
decimal_point = *__get_current_numeric_locale ()->wdecimal_point;
#else
{
size_t nconv;
 
memset (&state, '\0', sizeof (state));
nconv = _mbrtowc_r (data, &decimal_point,
_localeconv_r (data)->decimal_point,
MB_CUR_MAX, &state);
if (nconv == (size_t) -1 || nconv == (size_t) -2)
decimal_point = L'.';
}
#endif
#else
decimal_point = (wchar_t) *_localeconv_r (data)->decimal_point;
#endif
#endif
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
#ifdef _FVWRITE_IN_STREAMIO
#define PRINT(ptr, len) { \
iovp->iov_base = (char *) (ptr); \
iovp->iov_len = (len) * sizeof (wchar_t); \
uio.uio_resid += (len) * sizeof (wchar_t); \
iovp++; \
if (++uio.uio_iovcnt >= NIOV) { \
if (__SPRINT(data, fp, &uio)) \
goto error; \
iovp = iov; \
} \
}
#define PAD(howmany, with) { \
if ((n = (howmany)) > 0) { \
while (n > PADSIZE) { \
PRINT (with, PADSIZE); \
n -= PADSIZE; \
} \
PRINT (with, n); \
} \
}
#define PRINTANDPAD(p, ep, len, with) { \
int n = (ep) - (p); \
if (n > (len)) \
n = (len); \
if (n > 0) \
PRINT((p), n); \
PAD((len) - (n > 0 ? n : 0), (with)); \
}
#define FLUSH() { \
if (uio.uio_resid && __SPRINT(data, fp, &uio)) \
goto error; \
uio.uio_iovcnt = 0; \
iovp = iov; \
}
#else
#define PRINT(ptr, len) { \
if (__SPRINT (data, fp, (_CONST char *)(ptr), (len) * sizeof (wchar_t)) == EOF) \
goto error; \
}
#define PAD(howmany, with) { \
if ((n = (howmany)) > 0) { \
while (n > PADSIZE) { \
PRINT (with, PADSIZE); \
n -= PADSIZE; \
} \
PRINT (with, n); \
} \
}
#define PRINTANDPAD(p, ep, len, with) { \
int n = (ep) - (p); \
if (n > (len)) \
n = (len); \
if (n > 0) \
PRINT((p), n); \
PAD((len) - (n > 0 ? n : 0), (with)); \
}
#define FLUSH()
#endif
 
/* Macros to support positional arguments */
#ifndef _NO_POS_ARGS
# define GET_ARG(n, ap, type) \
(is_pos_arg \
? (n < numargs \
? args[n].val_##type \
: get_arg (data, n, fmt_anchor, &ap, &numargs, args, \
arg_type, &saved_fmt)->val_##type) \
: (arg_index++ < numargs \
? args[n].val_##type \
: (numargs < MAX_POS_ARGS \
? args[numargs++].val_##type = va_arg (ap, type) \
: va_arg (ap, type))))
#else
# define GET_ARG(n, ap, type) (va_arg (ap, type))
#endif
 
/*
* To extend shorts properly, we need both signed and unsigned
* argument extraction methods.
*/
#ifndef _NO_LONGLONG
#define SARG() \
(flags&QUADINT ? GET_ARG (N, ap, quad_t) : \
flags&LONGINT ? GET_ARG (N, ap, long) : \
flags&SHORTINT ? (long)(short)GET_ARG (N, ap, int) : \
flags&CHARINT ? (long)(signed char)GET_ARG (N, ap, int) : \
(long)GET_ARG (N, ap, int))
#define UARG() \
(flags&QUADINT ? GET_ARG (N, ap, u_quad_t) : \
flags&LONGINT ? GET_ARG (N, ap, u_long) : \
flags&SHORTINT ? (u_long)(u_short)GET_ARG (N, ap, int) : \
flags&CHARINT ? (u_long)(unsigned char)GET_ARG (N, ap, int) : \
(u_long)GET_ARG (N, ap, u_int))
#else
#define SARG() \
(flags&LONGINT ? GET_ARG (N, ap, long) : \
flags&SHORTINT ? (long)(short)GET_ARG (N, ap, int) : \
flags&CHARINT ? (long)(signed char)GET_ARG (N, ap, int) : \
(long)GET_ARG (N, ap, int))
#define UARG() \
(flags&LONGINT ? GET_ARG (N, ap, u_long) : \
flags&SHORTINT ? (u_long)(u_short)GET_ARG (N, ap, int) : \
flags&CHARINT ? (u_long)(unsigned char)GET_ARG (N, ap, int) : \
(u_long)GET_ARG (N, ap, u_int))
#endif
 
#ifndef STRING_ONLY
/* Initialize std streams if not dealing with sprintf family. */
CHECK_INIT (data, fp);
_newlib_flockfile_start (fp);
 
ORIENT(fp, 1);
 
/* sorry, fwprintf(read_only_file, "") returns EOF, not 0 */
if (cantwrite (data, fp)) {
_newlib_flockfile_exit (fp);
return (EOF);
}
 
#ifdef _UNBUF_STREAM_OPT
/* optimise fwprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0) {
_newlib_flockfile_exit (fp);
return (__sbwprintf (data, fp, fmt0, ap));
}
#endif
#else /* STRING_ONLY */
/* Create initial buffer if we are called by asprintf family. */
if (fp->_flags & __SMBF && !fp->_bf._base)
{
fp->_bf._base = fp->_p = _malloc_r (data, 64);
if (!fp->_p)
{
data->_errno = ENOMEM;
return EOF;
}
fp->_bf._size = 64;
}
#endif /* STRING_ONLY */
 
fmt = (wchar_t *)fmt0;
#ifdef _FVWRITE_IN_STREAMIO
uio.uio_iov = iovp = iov;
uio.uio_resid = 0;
uio.uio_iovcnt = 0;
#endif
ret = 0;
#ifndef _NO_POS_ARGS
arg_index = 0;
saved_fmt = NULL;
arg_type[0] = -1;
numargs = 0;
is_pos_arg = 0;
#endif
 
/*
* Scan the format for conversions (`%' character).
*/
for (;;) {
cp = fmt;
while (*fmt != L'\0' && *fmt != L'%')
++fmt;
if ((m = fmt - cp) != 0) {
PRINT (cp, m);
ret += m;
}
if (*fmt == L'\0')
goto done;
fmt_anchor = fmt;
fmt++; /* skip over '%' */
 
flags = 0;
dprec = 0;
width = 0;
prec = -1;
sign = L'\0';
#ifdef FLOATING_POINT
lead = 0;
#ifdef _WANT_IO_C99_FORMATS
nseps = nrepeats = 0;
#endif
#endif
#ifndef _NO_POS_ARGS
N = arg_index;
is_pos_arg = 0;
#endif
 
rflag: ch = *fmt++;
reswitch: switch (ch) {
#ifdef _WANT_IO_C99_FORMATS
case L'\'':
#ifdef _MB_CAPABLE
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
thousands_sep = *__get_current_numeric_locale ()->wthousands_sep;
#else
{
size_t nconv;
 
memset (&state, '\0', sizeof (state));
nconv = _mbrtowc_r (data, &thousands_sep,
_localeconv_r (data)->thousands_sep,
MB_CUR_MAX, &state);
if (nconv == (size_t) -1 || nconv == (size_t) -2)
thousands_sep = L'\0';
}
#endif
#else
thousands_sep = (wchar_t) *_localeconv_r(data)->thousands_sep;
#endif
grouping = _localeconv_r (data)->grouping;
if (thousands_sep && grouping && *grouping)
flags |= GROUPING;
goto rflag;
#endif
case L' ':
/*
* ``If the space and + flags both appear, the space
* flag will be ignored.''
* -- ANSI X3J11
*/
if (!sign)
sign = L' ';
goto rflag;
case L'#':
flags |= ALT;
goto rflag;
case L'*':
#ifndef _NO_POS_ARGS
/* we must check for positional arg used for dynamic width */
n = N;
old_is_pos_arg = is_pos_arg;
is_pos_arg = 0;
if (is_digit (*fmt)) {
wchar_t *old_fmt = fmt;
 
n = 0;
ch = *fmt++;
do {
n = 10 * n + to_digit (ch);
ch = *fmt++;
} while (is_digit (ch));
 
if (ch == L'$') {
if (n <= MAX_POS_ARGS) {
n -= 1;
is_pos_arg = 1;
}
else
goto error;
}
else {
fmt = old_fmt;
goto rflag;
}
}
#endif /* !_NO_POS_ARGS */
 
/*
* ``A negative field width argument is taken as a
* - flag followed by a positive field width.''
* -- ANSI X3J11
* They don't exclude field widths read from args.
*/
width = GET_ARG (n, ap, int);
#ifndef _NO_POS_ARGS
is_pos_arg = old_is_pos_arg;
#endif
if (width >= 0)
goto rflag;
width = -width;
/* FALLTHROUGH */
case L'-':
flags |= LADJUST;
goto rflag;
case L'+':
sign = L'+';
goto rflag;
case L'.':
if ((ch = *fmt++) == L'*') {
#ifndef _NO_POS_ARGS
/* we must check for positional arg used for dynamic width */
n = N;
old_is_pos_arg = is_pos_arg;
is_pos_arg = 0;
if (is_digit (*fmt)) {
wchar_t *old_fmt = fmt;
 
n = 0;
ch = *fmt++;
do {
n = 10 * n + to_digit (ch);
ch = *fmt++;
} while (is_digit (ch));
 
if (ch == L'$') {
if (n <= MAX_POS_ARGS) {
n -= 1;
is_pos_arg = 1;
}
else
goto error;
}
else {
fmt = old_fmt;
goto rflag;
}
}
#endif /* !_NO_POS_ARGS */
prec = GET_ARG (n, ap, int);
#ifndef _NO_POS_ARGS
is_pos_arg = old_is_pos_arg;
#endif
if (prec < 0)
prec = -1;
goto rflag;
}
n = 0;
while (is_digit (ch)) {
n = 10 * n + to_digit (ch);
ch = *fmt++;
}
prec = n < 0 ? -1 : n;
goto reswitch;
case L'0':
/*
* ``Note that 0 is taken as a flag, not as the
* beginning of a field width.''
* -- ANSI X3J11
*/
flags |= ZEROPAD;
goto rflag;
case L'1': case L'2': case L'3': case L'4':
case L'5': case L'6': case L'7': case L'8': case L'9':
n = 0;
do {
n = 10 * n + to_digit (ch);
ch = *fmt++;
} while (is_digit (ch));
#ifndef _NO_POS_ARGS
if (ch == L'$') {
if (n <= MAX_POS_ARGS) {
N = n - 1;
is_pos_arg = 1;
goto rflag;
}
else
goto error;
}
#endif /* !_NO_POS_ARGS */
width = n;
goto reswitch;
#ifdef FLOATING_POINT
case L'L':
flags |= LONGDBL;
goto rflag;
#endif
case L'h':
#ifdef _WANT_IO_C99_FORMATS
if (*fmt == L'h') {
fmt++;
flags |= CHARINT;
} else
#endif
flags |= SHORTINT;
goto rflag;
case L'l':
#if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG
if (*fmt == L'l') {
fmt++;
flags |= QUADINT;
} else
#endif
flags |= LONGINT;
goto rflag;
case L'q': /* GNU extension */
flags |= QUADINT;
goto rflag;
#ifdef _WANT_IO_C99_FORMATS
case L'j':
if (sizeof (intmax_t) == sizeof (long))
flags |= LONGINT;
else
flags |= QUADINT;
goto rflag;
case L'z':
if (sizeof (size_t) < sizeof (int))
/* POSIX states size_t is 16 or more bits, as is short. */
flags |= SHORTINT;
else if (sizeof (size_t) == sizeof (int))
/* no flag needed */;
else if (sizeof (size_t) <= sizeof (long))
flags |= LONGINT;
else
/* POSIX states that at least one programming
environment must support size_t no wider than
long, but that means other environments can
have size_t as wide as long long. */
flags |= QUADINT;
goto rflag;
case L't':
if (sizeof (ptrdiff_t) < sizeof (int))
/* POSIX states ptrdiff_t is 16 or more bits, as
is short. */
flags |= SHORTINT;
else if (sizeof (ptrdiff_t) == sizeof (int))
/* no flag needed */;
else if (sizeof (ptrdiff_t) <= sizeof (long))
flags |= LONGINT;
else
/* POSIX states that at least one programming
environment must support ptrdiff_t no wider than
long, but that means other environments can
have ptrdiff_t as wide as long long. */
flags |= QUADINT;
goto rflag;
case L'C': /* POSIX extension */
#endif /* _WANT_IO_C99_FORMATS */
case L'c':
cp = buf;
if (ch == L'c' && !(flags & LONGINT)) {
wint_t wc = btowc ((int) GET_ARG (N, ap, int));
if (wc == WEOF) {
fp->_flags |= __SERR;
goto error;
}
cp[0] = (wchar_t) wc;
}
else
{
cp[0] = GET_ARG (N, ap, int);
}
cp[1] = L'\0';
size = 1;
sign = L'\0';
break;
case L'd':
case L'i':
_uquad = SARG ();
#ifndef _NO_LONGLONG
if ((quad_t)_uquad < 0)
#else
if ((long) _uquad < 0)
#endif
{
 
_uquad = -_uquad;
sign = L'-';
}
base = DEC;
goto number;
#ifdef FLOATING_POINT
# ifdef _WANT_IO_C99_FORMATS
case L'a':
case L'A':
case L'F':
# endif
case L'e':
case L'E':
case L'f':
case L'g':
case L'G':
# ifdef _NO_LONGDBL
if (flags & LONGDBL) {
_fpvalue = (double) GET_ARG (N, ap, _LONG_DOUBLE);
} else {
_fpvalue = GET_ARG (N, ap, double);
}
 
/* do this before tricky precision changes
 
If the output is infinite or NaN, leading
zeros are not permitted. Otherwise, scanf
could not read what printf wrote.
*/
if (isinf (_fpvalue)) {
if (_fpvalue < 0)
sign = '-';
if (ch <= L'G') /* 'A', 'E', 'F', or 'G' */
cp = L"INF";
else
cp = L"inf";
size = 3;
flags &= ~ZEROPAD;
break;
}
if (isnan (_fpvalue)) {
if (ch <= L'G') /* 'A', 'E', 'F', or 'G' */
cp = L"NAN";
else
cp = L"nan";
size = 3;
flags &= ~ZEROPAD;
break;
}
 
# else /* !_NO_LONGDBL */
 
if (flags & LONGDBL) {
_fpvalue = GET_ARG (N, ap, _LONG_DOUBLE);
} else {
_fpvalue = (_LONG_DOUBLE)GET_ARG (N, ap, double);
}
 
/* do this before tricky precision changes */
expt = _ldcheck (&_fpvalue);
if (expt == 2) {
if (_fpvalue < 0)
sign = L'-';
if (ch <= L'G') /* 'A', 'E', 'F', or 'G' */
cp = L"INF";
else
cp = L"inf";
size = 3;
flags &= ~ZEROPAD;
break;
}
if (expt == 1) {
if (ch <= L'G') /* 'A', 'E', 'F', or 'G' */
cp = L"NAN";
else
cp = L"nan";
size = 3;
flags &= ~ZEROPAD;
break;
}
# endif /* !_NO_LONGDBL */
 
cp = buf;
# ifdef _WANT_IO_C99_FORMATS
if (ch == L'a' || ch == L'A') {
ox[0] = L'0';
ox[1] = ch == L'a' ? L'x' : L'X';
flags |= HEXPREFIX;
if (prec >= BUF)
{
if ((malloc_buf =
(wchar_t *)_malloc_r (data, (prec + 1) * sizeof (wchar_t)))
== NULL)
{
fp->_flags |= __SERR;
goto error;
}
cp = malloc_buf;
}
} else
# endif /* _WANT_IO_C99_FORMATS */
if (prec == -1) {
prec = DEFPREC;
} else if ((ch == L'g' || ch == L'G') && prec == 0) {
prec = 1;
}
 
flags |= FPT;
 
cp = wcvt (data, _fpvalue, prec, flags, &softsign,
&expt, ch, &ndig, cp, BUF);
 
/* If buf is not large enough for the converted wchar_t
sequence, call wcvt again with a malloced new buffer.
This should happen fairly rarely.
*/
if (cp == buf && ndig > BUF && malloc_buf == NULL) {
if ((malloc_buf =
(wchar_t *)_malloc_r (data, ndig * sizeof (wchar_t)))
== NULL)
{
fp->_flags |= __SERR;
goto error;
}
cp = wcvt (data, _fpvalue, prec, flags, &softsign,
&expt, ch, &ndig, malloc_buf, ndig);
}
 
if (ch == L'g' || ch == L'G') {
if (expt <= -4 || expt > prec)
ch -= 2; /* 'e' or 'E' */
else
ch = L'g';
}
# ifdef _WANT_IO_C99_FORMATS
else if (ch == L'F')
ch = L'f';
# endif
if (ch <= L'e') { /* 'a', 'A', 'e', or 'E' fmt */
--expt;
expsize = wexponent (expstr, expt, ch);
size = expsize + ndig;
if (ndig > 1 || flags & ALT)
++size;
# ifdef _WANT_IO_C99_FORMATS
flags &= ~GROUPING;
# endif
} else {
if (ch == L'f') { /* f fmt */
if (expt > 0) {
size = expt;
if (prec || flags & ALT)
size += prec + 1;
} else /* "0.X" */
size = (prec || flags & ALT)
? prec + 2
: 1;
} else if (expt >= ndig) { /* fixed g fmt */
size = expt;
if (flags & ALT)
++size;
} else
size = ndig + (expt > 0 ?
1 : 2 - expt);
# ifdef _WANT_IO_C99_FORMATS
if ((flags & GROUPING) && expt > 0) {
/* space for thousands' grouping */
nseps = nrepeats = 0;
lead = expt;
while (*grouping != CHAR_MAX) {
if (lead <= *grouping)
break;
lead -= *grouping;
if (grouping[1]) {
nseps++;
grouping++;
} else
nrepeats++;
}
size += nseps + nrepeats;
} else
# endif
lead = expt;
}
if (softsign)
sign = L'-';
break;
#endif /* FLOATING_POINT */
#ifdef _GLIBC_EXTENSION
case L'm': /* GNU extension */
{
int dummy;
cp = (wchar_t *) _strerror_r (data, data->_errno, 1, &dummy);
}
flags &= ~LONGINT;
goto string;
#endif
case L'n':
#ifndef _NO_LONGLONG
if (flags & QUADINT)
*GET_ARG (N, ap, quad_ptr_t) = ret;
else
#endif
if (flags & LONGINT)
*GET_ARG (N, ap, long_ptr_t) = ret;
else if (flags & SHORTINT)
*GET_ARG (N, ap, short_ptr_t) = ret;
#ifdef _WANT_IO_C99_FORMATS
else if (flags & CHARINT)
*GET_ARG (N, ap, char_ptr_t) = ret;
#endif
else
*GET_ARG (N, ap, int_ptr_t) = ret;
continue; /* no output */
case L'o':
_uquad = UARG ();
base = OCT;
#ifdef _WANT_IO_C99_FORMATS
flags &= ~GROUPING;
#endif
goto nosign;
case L'p':
/*
* ``The argument shall be a pointer to void. The
* value of the pointer is converted to a sequence
* of printable characters, in an implementation-
* defined manner.''
* -- ANSI X3J11
*/
/* NOSTRICT */
_uquad = (uintptr_t) GET_ARG (N, ap, void_ptr_t);
base = HEX;
xdigs = L"0123456789abcdef";
flags |= HEXPREFIX;
ox[0] = L'0';
ox[1] = ch = L'x';
goto nosign;
case L's':
#ifdef _WANT_IO_C99_FORMATS
case L'S': /* POSIX extension */
#endif
cp = GET_ARG (N, ap, wchar_ptr_t);
#ifdef _GLIBC_EXTENSION
string:
#endif
sign = '\0';
#ifndef __OPTIMIZE_SIZE__
/* Behavior is undefined if the user passed a
NULL string when precision is not 0.
However, if we are not optimizing for size,
we might as well mirror glibc behavior. */
if (cp == NULL) {
cp = L"(null)";
size = ((unsigned) prec > 6U) ? 6 : prec;
}
else
#endif /* __OPTIMIZE_SIZE__ */
#ifdef _MB_CAPABLE
if (ch != L'S' && !(flags & LONGINT)) {
char *arg = (char *) cp;
size_t insize = 0, nchars = 0, nconv = 0;
mbstate_t ps;
wchar_t *p;
 
if (prec >= 0) {
char *p = arg;
memset ((_PTR)&ps, '\0', sizeof (mbstate_t));
while (nchars < (size_t)prec) {
nconv = mbrlen (p, MB_CUR_MAX, &ps);
if (nconv == 0 || nconv == (size_t)-1 ||
nconv == (size_t)-2)
break;
p += nconv;
++nchars;
insize += nconv;
}
if (nconv == (size_t) -1 || nconv == (size_t) -2) {
fp->_flags |= __SERR;
goto error;
}
} else
insize = strlen(arg);
if (insize >= BUF) {
if ((malloc_buf = (wchar_t *) _malloc_r (data, (insize + 1) * sizeof (wchar_t)))
== NULL) {
fp->_flags |= __SERR;
goto error;
}
cp = malloc_buf;
} else
cp = buf;
memset ((_PTR)&ps, '\0', sizeof (mbstate_t));
p = cp;
while (insize != 0) {
nconv = _mbrtowc_r (data, p, arg, insize, &ps);
if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
break;
++p;
arg += nconv;
insize -= nconv;
}
if (nconv == (size_t) -1 || nconv == (size_t) -2) {
fp->_flags |= __SERR;
goto error;
}
*p = L'\0';
size = p - cp;
}
#else
if (ch != L'S' && !(flags & LONGINT)) {
char *arg = (char *) cp;
size_t insize = 0;
 
if (prec >= 0) {
char *p = memchr (arg, '\0', prec);
insize = p ? p - arg : prec;
} else
insize = strlen (arg);
if (insize >= BUF) {
if ((malloc_buf = (wchar_t *) _malloc_r (data, (insize + 1) * sizeof (wchar_t)))
== NULL) {
fp->_flags |= __SERR;
goto error;
}
cp = malloc_buf;
} else
cp = buf;
for (size = 0; size < insize; ++size)
cp[size] = arg[size];
cp[size] = L'\0';
}
#endif /* _MB_CAPABLE */
else if (prec >= 0) {
/*
* can't use wcslen; can only look for the
* NUL in the first `prec' characters, and
* strlen () will go further.
*/
wchar_t *p = wmemchr (cp, L'\0', prec);
 
if (p != NULL) {
size = p - cp;
if (size > prec)
size = prec;
} else
size = prec;
} else
size = wcslen (cp);
 
break;
case L'u':
_uquad = UARG ();
base = DEC;
goto nosign;
case L'X':
xdigs = L"0123456789ABCDEF";
goto hex;
case L'x':
xdigs = L"0123456789abcdef";
hex: _uquad = UARG ();
base = HEX;
/* leading 0x/X only if non-zero */
if (flags & ALT && _uquad != 0) {
ox[0] = L'0';
ox[1] = ch;
flags |= HEXPREFIX;
}
 
#ifdef _WANT_IO_C99_FORMATS
flags &= ~GROUPING;
#endif
/* unsigned conversions */
nosign: sign = L'\0';
/*
* ``... diouXx conversions ... if a precision is
* specified, the 0 flag will be ignored.''
* -- ANSI X3J11
*/
number: if ((dprec = prec) >= 0)
flags &= ~ZEROPAD;
 
/*
* ``The result of converting a zero value with an
* explicit precision of zero is no characters.''
* -- ANSI X3J11
*/
cp = buf + BUF;
if (_uquad != 0 || prec != 0) {
/*
* Unsigned mod is hard, and unsigned mod
* by a constant is easier than that by
* a variable; hence this switch.
*/
switch (base) {
case OCT:
do {
*--cp = to_char (_uquad & 7);
_uquad >>= 3;
} while (_uquad);
/* handle octal leading 0 */
if (flags & ALT && *cp != L'0')
*--cp = L'0';
break;
 
case DEC:
/* many numbers are 1 digit */
if (_uquad < 10) {
*--cp = to_char(_uquad);
break;
}
#ifdef _WANT_IO_C99_FORMATS
ndig = 0;
#endif
do {
*--cp = to_char (_uquad % 10);
#ifdef _WANT_IO_C99_FORMATS
ndig++;
/* If (*grouping == CHAR_MAX) then no
more grouping */
if ((flags & GROUPING)
&& ndig == *grouping
&& *grouping != CHAR_MAX
&& _uquad > 9) {
*--cp = thousands_sep;
ndig = 0;
/* If (grouping[1] == '\0') then we
have to use *grouping character
(last grouping rule) for all
next cases. */
if (grouping[1] != '\0')
grouping++;
}
#endif
_uquad /= 10;
} while (_uquad != 0);
break;
 
case HEX:
do {
*--cp = xdigs[_uquad & 15];
_uquad >>= 4;
} while (_uquad);
break;
 
default:
cp = L"bug in vfprintf: bad base";
size = wcslen (cp);
goto skipsize;
}
}
/*
* ...result is to be converted to an 'alternate form'.
* For o conversion, it increases the precision to force
* the first digit of the result to be a zero."
* -- ANSI X3J11
*
* To demonstrate this case, compile and run:
* printf ("%#.0o",0);
*/
else if (base == OCT && (flags & ALT))
*--cp = L'0';
 
size = buf + BUF - cp;
skipsize:
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == L'\0')
goto done;
/* pretend it was %c with argument ch */
cp = buf;
*cp = ch;
size = 1;
sign = L'\0';
break;
}
 
/*
* All reasonable formats wind up here. At this point, `cp'
* points to a string which (if not flags&LADJUST) should be
* padded out to `width' places. If flags&ZEROPAD, it should
* first be prefixed by any sign or other prefix; otherwise,
* it should be blank padded before the prefix is emitted.
* After any left-hand padding and prefixing, emit zeroes
* required by a decimal [diouxX] precision, then print the
* string proper, then emit zeroes required by any leftover
* floating precision; finally, if LADJUST, pad with blanks.
* If flags&FPT, ch must be in [aAeEfg].
*
* Compute actual size, so we know how much to pad.
* size excludes decimal prec; realsz includes it.
*/
realsz = dprec > size ? dprec : size;
if (sign)
realsz++;
if (flags & HEXPREFIX)
realsz+= 2;
 
/* right-adjusting blank padding */
if ((flags & (LADJUST|ZEROPAD)) == 0)
PAD (width - realsz, blanks);
 
/* prefix */
if (sign)
PRINT (&sign, 1);
if (flags & HEXPREFIX)
PRINT (ox, 2);
 
/* right-adjusting zero padding */
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
PAD (width - realsz, zeroes);
 
/* leading zeroes from decimal precision */
PAD (dprec - size, zeroes);
 
/* the string or number proper */
#ifdef FLOATING_POINT
if ((flags & FPT) == 0) {
PRINT (cp, size);
} else { /* glue together f_p fragments */
if (ch >= L'f') { /* 'f' or 'g' */
if (_fpvalue == 0) {
/* kludge for __dtoa irregularity */
PRINT (L"0", 1);
if (expt < ndig || flags & ALT) {
PRINT (&decimal_point, 1);
PAD (ndig - 1, zeroes);
}
} else if (expt <= 0) {
PRINT (L"0", 1);
if (expt || ndig || flags & ALT) {
PRINT (&decimal_point, 1);
PAD (-expt, zeroes);
PRINT (cp, ndig);
}
} else {
wchar_t *convbuf = cp;
PRINTANDPAD(cp, convbuf + ndig,
lead, zeroes);
cp += lead;
#ifdef _WANT_IO_C99_FORMATS
if (flags & GROUPING) {
while (nseps > 0 || nrepeats > 0) {
if (nrepeats > 0)
nrepeats--;
else {
grouping--;
nseps--;
}
PRINT (&thousands_sep, 1);
PRINTANDPAD (cp, convbuf + ndig,
*grouping, zeroes);
cp += *grouping;
}
if (cp > convbuf + ndig)
cp = convbuf + ndig;
}
#endif
if (expt < ndig || flags & ALT)
PRINT (&decimal_point, 1);
PRINTANDPAD (cp, convbuf + ndig,
ndig - expt, zeroes);
}
 
} else { /* 'a', 'A', 'e', or 'E' */
if (ndig > 1 || flags & ALT) {
PRINT (cp, 1);
cp++;
PRINT (&decimal_point, 1);
if (_fpvalue) {
PRINT (cp, ndig - 1);
} else /* 0.[0..] */
/* __dtoa irregularity */
PAD (ndig - 1, zeroes);
} else /* XeYYY */
PRINT (cp, 1);
PRINT (expstr, expsize);
}
}
#else /* !FLOATING_POINT */
PRINT (cp, size);
#endif
/* left-adjusting padding (always blank) */
if (flags & LADJUST)
PAD (width - realsz, blanks);
 
/* finally, adjust ret */
ret += width > realsz ? width : realsz;
 
FLUSH (); /* copy out the I/O vectors */
 
if (malloc_buf != NULL) {
_free_r (data, malloc_buf);
malloc_buf = NULL;
}
}
done:
FLUSH ();
error:
if (malloc_buf != NULL)
_free_r (data, malloc_buf);
#ifndef STRING_ONLY
_newlib_flockfile_end (fp);
#endif
return (__sferror (fp) ? EOF : ret);
/* NOTREACHED */
}
 
#ifdef FLOATING_POINT
 
/* Using reentrant DATA, convert finite VALUE into a string of digits
with no decimal point, using NDIGITS precision and FLAGS as guides
to whether trailing zeros must be included. Set *SIGN to nonzero
if VALUE was negative. Set *DECPT to the exponent plus one. Set
*LENGTH to the length of the returned string. CH must be one of
[aAeEfFgG]; different from vfprintf.c:cvt(), the return string
lives in BUF regardless of CH. LEN is the length of BUF, except
when CH is [aA], in which case LEN is not in use. If BUF is not
large enough for the converted string, only the first LEN number
of characters will be returned in BUF, but *LENGTH will be set to
the full length of the string before the truncation. */
static wchar_t *
wcvt(struct _reent *data, _PRINTF_FLOAT_TYPE value, int ndigits, int flags,
wchar_t *sign, int *decpt, int ch, int *length, wchar_t *buf, int len)
{
int mode, dsgn;
# ifdef _NO_LONGDBL
union double_union tmp;
 
tmp.d = value;
if (word0 (tmp) & Sign_bit) { /* this will check for < 0 and -0.0 */
value = -value;
*sign = L'-';
} else
*sign = L'\0';
# else /* !_NO_LONGDBL */
union
{
struct ldieee ieee;
_LONG_DOUBLE val;
} ld;
 
ld.val = value;
if (ld.ieee.sign) { /* this will check for < 0 and -0.0 */
value = -value;
*sign = L'-';
} else
*sign = L'\0';
# endif /* !_NO_LONGDBL */
 
# ifdef _WANT_IO_C99_FORMATS
if (ch == L'a' || ch == L'A') {
wchar_t *digits, *bp, *rve;
/* This code assumes FLT_RADIX is a power of 2. The initial
division ensures the digit before the decimal will be less
than FLT_RADIX (unless it is rounded later). There is no
loss of precision in these calculations. */
value = FREXP (value, decpt) / 8;
if (!value)
*decpt = 1;
digits = ch == L'a' ? L"0123456789abcdef" : L"0123456789ABCDEF";
bp = buf;
do {
value *= 16;
mode = (int) value;
value -= mode;
*bp++ = digits[mode];
} while (ndigits-- && value);
if (value > 0.5 || (value == 0.5 && mode & 1)) {
/* round to even */
rve = bp;
while (*--rve == digits[0xf]) {
*rve = L'0';
}
*rve = *rve == L'9' ? digits[0xa] : *rve + 1;
} else {
while (ndigits-- >= 0) {
*bp++ = L'0';
}
}
*length = bp - buf;
return buf;
}
# endif /* _WANT_IO_C99_FORMATS */
if (ch == L'f' || ch == L'F') {
mode = 3; /* ndigits after the decimal point */
} else {
/* To obtain ndigits after the decimal point for the 'e'
* and 'E' formats, round to ndigits + 1 significant
* figures.
*/
if (ch == L'e' || ch == L'E') {
ndigits++;
}
mode = 2; /* ndigits significant digits */
}
 
{
char *digits, *bp, *rve;
#ifndef _MB_CAPABLE
int i;
#endif
 
digits = _DTOA_R (data, value, mode, ndigits, decpt, &dsgn, &rve);
 
if ((ch != L'g' && ch != L'G') || flags & ALT) { /* Print trailing zeros */
bp = digits + ndigits;
if (ch == L'f' || ch == L'F') {
if (*digits == L'0' && value)
*decpt = -ndigits + 1;
bp += *decpt;
}
if (value == 0) /* kludge for __dtoa irregularity */
rve = bp;
while (rve < bp)
*rve++ = '0';
}
 
*length = rve - digits; /* full length of the string */
#ifdef _MB_CAPABLE
_mbsnrtowcs_r (data, buf, (const char **) &digits, *length,
len, NULL);
#else
for (i = 0; i < *length && i < len; ++i)
buf[i] = (wchar_t) digits[i];
#endif
return buf;
}
}
 
static int
wexponent(wchar_t *p0, int exp, int fmtch)
{
register wchar_t *p, *t;
wchar_t expbuf[MAXEXPLEN];
# ifdef _WANT_IO_C99_FORMATS
int isa = fmtch == L'a' || fmtch == L'A';
# else
# define isa 0
# endif
 
p = p0;
*p++ = isa ? L'p' - L'a' + fmtch : fmtch;
if (exp < 0) {
exp = -exp;
*p++ = L'-';
}
else
*p++ = L'+';
t = expbuf + MAXEXPLEN;
if (exp > 9) {
do {
*--t = to_char (exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char (exp);
for (; t < expbuf + MAXEXPLEN; *p++ = *t++);
}
else {
if (!isa)
*p++ = L'0';
*p++ = to_char (exp);
}
return (p - p0);
}
#endif /* FLOATING_POINT */
 
 
#ifndef _NO_POS_ARGS
 
/* Positional argument support.
Written by Jeff Johnston
 
Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
 
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.
 
The name of Red Hat Incorporated may not be used to endorse
or promote products derived from this software without specific
prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 RED HAT INCORPORATED 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. */
 
/* function to get positional parameter N where n = N - 1 */
static union arg_val *
_DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
struct _reent *data _AND
int n _AND
wchar_t *fmt _AND
va_list *ap _AND
int *numargs_p _AND
union arg_val *args _AND
int *arg_type _AND
wchar_t **last_fmt)
{
wchar_t ch;
int number, flags;
int spec_type;
int numargs = *numargs_p;
__CH_CLASS chtype;
__STATE state, next_state;
__ACTION action;
int pos, last_arg;
int max_pos_arg = n;
/* Only need types that can be reached via vararg promotions. */
enum types { INT, LONG_INT, QUAD_INT, CHAR_PTR, DOUBLE, LONG_DOUBLE, WIDE_CHAR };
 
/* if this isn't the first call, pick up where we left off last time */
if (*last_fmt != NULL)
fmt = *last_fmt;
 
/* we need to process either to end of fmt string or until we have actually
read the desired parameter from the vararg list. */
while (*fmt && n >= numargs)
{
while (*fmt != L'\0' && *fmt != L'%')
fmt += 1;
 
if (*fmt == L'\0')
break;
state = START;
flags = 0;
pos = -1;
number = 0;
spec_type = INT;
 
/* Use state/action table to process format specifiers. We ignore invalid
formats and we are only interested in information that tells us how to
read the vararg list. */
while (state != DONE)
{
ch = *fmt++;
chtype = ch < (wchar_t) 256 ? __chclass[ch] : OTHER;
next_state = __state_table[state][chtype];
action = __action_table[state][chtype];
state = next_state;
 
switch (action)
{
case GETMOD: /* we have format modifier */
switch (ch)
{
case L'h':
/* No flag needed, since short and char promote to int. */
break;
case L'L':
flags |= LONGDBL;
break;
case L'q':
flags |= QUADINT;
break;
# ifdef _WANT_IO_C99_FORMATS
case L'j':
if (sizeof (intmax_t) == sizeof (long))
flags |= LONGINT;
else
flags |= QUADINT;
break;
case L'z':
if (sizeof (size_t) <= sizeof (int))
/* no flag needed */;
else if (sizeof (size_t) <= sizeof (long))
flags |= LONGINT;
else
/* POSIX states that at least one programming
environment must support size_t no wider than
long, but that means other environments can
have size_t as wide as long long. */
flags |= QUADINT;
break;
case L't':
if (sizeof (ptrdiff_t) <= sizeof (int))
/* no flag needed */;
else if (sizeof (ptrdiff_t) <= sizeof (long))
flags |= LONGINT;
else
/* POSIX states that at least one programming
environment must support ptrdiff_t no wider than
long, but that means other environments can
have ptrdiff_t as wide as long long. */
flags |= QUADINT;
break;
# endif /* _WANT_IO_C99_FORMATS */
case L'l':
default:
# if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG
if (*fmt == L'l')
{
flags |= QUADINT;
++fmt;
}
else
# endif
flags |= LONGINT;
break;
}
break;
case GETARG: /* we have format specifier */
{
numargs &= (MAX_POS_ARGS - 1);
/* process the specifier and translate it to a type to fetch from varargs */
switch (ch)
{
case L'd':
case L'i':
case L'o':
case L'x':
case L'X':
case L'u':
if (flags & LONGINT)
spec_type = LONG_INT;
# ifndef _NO_LONGLONG
else if (flags & QUADINT)
spec_type = QUAD_INT;
# endif
else
spec_type = INT;
break;
# ifdef _WANT_IO_C99_FORMATS
case L'a':
case L'A':
case L'F':
# endif
case L'f':
case L'g':
case L'G':
case L'E':
case L'e':
# ifndef _NO_LONGDBL
if (flags & LONGDBL)
spec_type = LONG_DOUBLE;
else
# endif
spec_type = DOUBLE;
break;
case L's':
# ifdef _WANT_IO_C99_FORMATS
case L'S': /* POSIX extension */
# endif
case L'p':
case L'n':
spec_type = CHAR_PTR;
break;
case L'c':
# ifdef _WANT_IO_C99_FORMATS
if (flags & LONGINT)
spec_type = WIDE_CHAR;
else
# endif
spec_type = INT;
break;
# ifdef _WANT_IO_C99_FORMATS
case L'C': /* POSIX extension */
spec_type = WIDE_CHAR;
break;
# endif
}
 
/* if we have a positional parameter, just store the type, otherwise
fetch the parameter from the vararg list */
if (pos != -1)
arg_type[pos] = spec_type;
else
{
switch (spec_type)
{
case LONG_INT:
args[numargs++].val_long = va_arg (*ap, long);
break;
case QUAD_INT:
args[numargs++].val_quad_t = va_arg (*ap, quad_t);
break;
case WIDE_CHAR:
args[numargs++].val_wint_t = va_arg (*ap, wint_t);
break;
case INT:
args[numargs++].val_int = va_arg (*ap, int);
break;
case CHAR_PTR:
args[numargs++].val_wchar_ptr_t = va_arg (*ap, wchar_t *);
break;
case DOUBLE:
args[numargs++].val_double = va_arg (*ap, double);
break;
case LONG_DOUBLE:
args[numargs++].val__LONG_DOUBLE = va_arg (*ap, _LONG_DOUBLE);
break;
}
}
}
break;
case GETPOS: /* we have positional specifier */
if (arg_type[0] == -1)
memset (arg_type, 0, sizeof (int) * MAX_POS_ARGS);
pos = number - 1;
max_pos_arg = (max_pos_arg > pos ? max_pos_arg : pos);
break;
case PWPOS: /* we have positional specifier for width or precision */
if (arg_type[0] == -1)
memset (arg_type, 0, sizeof (int) * MAX_POS_ARGS);
number -= 1;
arg_type[number] = INT;
max_pos_arg = (max_pos_arg > number ? max_pos_arg : number);
break;
case GETPWB: /* we require format pushback */
--fmt;
/* fallthrough */
case GETPW: /* we have a variable precision or width to acquire */
args[numargs++].val_int = va_arg (*ap, int);
break;
case NUMBER: /* we have a number to process */
number = (ch - '0');
while ((ch = *fmt) != '\0' && is_digit (ch))
{
number = number * 10 + (ch - '0');
++fmt;
}
break;
case SKIPNUM: /* we have a number to skip */
while ((ch = *fmt) != '\0' && is_digit (ch))
++fmt;
break;
case NOOP:
default:
break; /* do nothing */
}
}
}
 
/* process all arguments up to at least the one we are looking for and if we
have seen the end of the string, then process up to the max argument needed */
if (*fmt == '\0')
last_arg = max_pos_arg;
else
last_arg = n;
 
while (numargs <= last_arg)
{
switch (arg_type[numargs])
{
case LONG_INT:
args[numargs++].val_long = va_arg (*ap, long);
break;
case QUAD_INT:
args[numargs++].val_quad_t = va_arg (*ap, quad_t);
break;
case CHAR_PTR:
args[numargs++].val_wchar_ptr_t = va_arg (*ap, wchar_t *);
break;
case DOUBLE:
args[numargs++].val_double = va_arg (*ap, double);
break;
case LONG_DOUBLE:
args[numargs++].val__LONG_DOUBLE = va_arg (*ap, _LONG_DOUBLE);
break;
case WIDE_CHAR:
args[numargs++].val_wint_t = va_arg (*ap, wint_t);
break;
case INT:
default:
args[numargs++].val_int = va_arg (*ap, int);
break;
}
}
 
/* alter the global numargs value and keep a reference to the last bit of the fmt
string we processed here because the caller will continue processing where we started */
*numargs_p = numargs;
*last_fmt = fmt;
return &args[n];
}
#endif /* !_NO_POS_ARGS */
/contrib/sdk/sources/newlib/libc/stdio/vfwscanf.c
0,0 → 1,1499
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
 
/*
FUNCTION
<<vfwscanf>>, <<vwscanf>>, <<vswscanf>>---scan and format argument list from wide character input
 
INDEX
vfwscanf
INDEX
_vfwscanf
INDEX
vwscanf
INDEX
_vwscanf
INDEX
vswscanf
INDEX
_vswscanf
 
ANSI_SYNOPSIS
#include <stdio.h>
#include <stdarg.h>
int vwscanf(const wchar_t *__restrict <[fmt]>, va_list <[list]>);
int vfwscanf(FILE *__restrict <[fp]>,
const wchar_t *__restrict <[fmt]>, va_list <[list]>);
int vswscanf(const wchar_t *__restrict <[str]>,
const wchar_t *__restrict <[fmt]>, va_list <[list]>);
 
int _vwscanf(struct _reent *<[reent]>, const wchar_t *<[fmt]>,
va_list <[list]>);
int _vfwscanf(struct _reent *<[reent]>, FILE *<[fp]>,
const wchar_t *<[fmt]>, va_list <[list]>);
int _vswscanf(struct _reent *<[reent]>, const wchar_t *<[str]>,
const wchar_t *<[fmt]>, va_list <[list]>);
 
TRAD_SYNOPSIS
#include <stdio.h>
#include <varargs.h>
int vwscanf( <[fmt]>, <[ist]>)
wchar_t *__restrict <[fmt]>;
va_list <[list]>;
 
int vfwscanf( <[fp]>, <[fmt]>, <[list]>)
FILE *__restrict <[fp]>;
wchar_t *__restrict <[fmt]>;
va_list <[list]>;
 
int vswscanf( <[str]>, <[fmt]>, <[list]>)
wchar_t *__restrict <[str]>;
wchar_t *__restrict <[fmt]>;
va_list <[list]>;
 
int _vwscanf( <[reent]>, <[fmt]>, <[ist]>)
struct _reent *<[reent]>;
wchar_t *<[fmt]>;
va_list <[list]>;
 
int _vfwscanf( <[reent]>, <[fp]>, <[fmt]>, <[list]>)
struct _reent *<[reent]>;
FILE *<[fp]>;
wchar_t *<[fmt]>;
va_list <[list]>;
 
int _vswscanf( <[reent]>, <[str]>, <[fmt]>, <[list]>)
struct _reent *<[reent]>;
wchar_t *<[str]>;
wchar_t *<[fmt]>;
va_list <[list]>;
 
DESCRIPTION
<<vwscanf>>, <<vfwscanf>>, and <<vswscanf>> are (respectively) variants
of <<wscanf>>, <<fwscanf>>, and <<swscanf>>. They differ only in
allowing their caller to pass the variable argument list as a
<<va_list>> object (initialized by <<va_start>>) rather than
directly accepting a variable number of arguments.
 
RETURNS
The return values are consistent with the corresponding functions:
<<vwscanf>> returns the number of input fields successfully scanned,
converted, and stored; the return value does not include scanned
fields which were not stored.
 
If <<vwscanf>> attempts to read at end-of-file, the return value
is <<EOF>>.
 
If no fields were stored, the return value is <<0>>.
 
The routines <<_vwscanf>>, <<_vfwscanf>>, and <<_vswscanf>> are
reentrant versions which take an additional first parameter which points
to the reentrancy structure.
 
PORTABILITY
C99, POSIX-1.2008
*/
 
#include <_ansi.h>
#include <reent.h>
#include <newlib.h>
#include <ctype.h>
#include <wctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <wchar.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include "local.h"
 
#ifdef INTEGER_ONLY
#define VFWSCANF vfiwscanf
#define _VFWSCANF_R _vfiwscanf_r
#define __SVFWSCANF __svfiwscanf
#ifdef STRING_ONLY
# define __SVFWSCANF_R __ssvfiwscanf_r
#else
# define __SVFWSCANF_R __svfiwscanf_r
#endif
#else
#define VFWSCANF vfwscanf
#define _VFWSCANF_R _vfwscanf_r
#define __SVFWSCANF __svfwscanf
#ifdef STRING_ONLY
# define __SVFWSCANF_R __ssvfwscanf_r
#else
# define __SVFWSCANF_R __svfwscanf_r
#endif
#ifndef NO_FLOATING_POINT
#define FLOATING_POINT
#endif
#endif
 
#ifdef STRING_ONLY
#undef _newlib_flockfile_start
#undef _newlib_flockfile_exit
#undef _newlib_flockfile_end
#define _newlib_flockfile_start(x) {}
#define _newlib_flockfile_exit(x) {}
#define _newlib_flockfile_end(x) {}
#define _ungetwc_r _sungetwc_r
#define __srefill_r __ssrefill_r
#define _fgetwc_r _sfgetwc_r
#endif
 
#ifdef FLOATING_POINT
#include <math.h>
#include <float.h>
#include <locale.h>
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
#include "../locale/lnumeric.h"
#endif
 
/* Currently a test is made to see if long double processing is warranted.
This could be changed in the future should the _ldtoa_r code be
preferred over _dtoa_r. */
#define _NO_LONGDBL
#if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
#undef _NO_LONGDBL
extern _LONG_DOUBLE _wcstold_r _PARAMS((wchar_t *s, wchar_t **sptr));
#endif
 
#include "floatio.h"
 
#if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX)
# define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
#else
# define BUF MB_LEN_MAX
#endif
 
/* An upper bound for how long a long prints in decimal. 4 / 13 approximates
log (2). Add one char for roundoff compensation and one for the sign. */
#define MAX_LONG_LEN ((CHAR_BIT * sizeof (long) - 1) * 4 / 13 + 2)
#else
#define BUF 40
#endif
 
#define _NO_LONGLONG
#if defined _WANT_IO_LONG_LONG \
&& (defined __GNUC__ || __STDC_VERSION__ >= 199901L)
# undef _NO_LONGLONG
#endif
 
#define _NO_POS_ARGS
#ifdef _WANT_IO_POS_ARGS
# undef _NO_POS_ARGS
# ifdef NL_ARGMAX
# define MAX_POS_ARGS NL_ARGMAX
# else
# define MAX_POS_ARGS 32
# endif
 
static void * get_arg (int, va_list *, int *, void **);
#endif /* _WANT_IO_POS_ARGS */
 
/*
* Flags used during conversion.
*/
 
#define LONG 0x01 /* l: long or double */
#define LONGDBL 0x02 /* L/ll: long double or long long */
#define SHORT 0x04 /* h: short */
#define CHAR 0x08 /* hh: 8 bit integer */
#define SUPPRESS 0x10 /* suppress assignment */
#define POINTER 0x20 /* weird %p pointer (`fake hex') */
#define NOSKIP 0x40 /* do not skip blanks */
 
/*
* The following are used in numeric conversions only:
* SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
* SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
*/
 
#define SIGNOK 0x80 /* +/- is (still) legal */
#define NDIGITS 0x100 /* no digits detected */
 
#define DPTOK 0x200 /* (float) decimal point is still legal */
#define EXPOK 0x400 /* (float) exponent (e+3, etc) still legal */
 
#define PFXOK 0x200 /* 0x prefix is (still) legal */
#define NZDIGITS 0x400 /* no zero digits detected */
#define HAVESIGN 0x10000 /* sign detected */
 
/*
* Conversion types.
*/
 
#define CT_CHAR 0 /* %c conversion */
#define CT_CCL 1 /* %[...] conversion */
#define CT_STRING 2 /* %s conversion */
#define CT_INT 3 /* integer, i.e., wcstol or wcstoul */
#define CT_FLOAT 4 /* floating, i.e., wcstod */
 
#define INCCL(_c) \
(cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) : \
(wmemchr(ccls, (_c), ccle - ccls) != NULL))
 
/*
* vfwscanf
*/
 
#ifndef STRING_ONLY
 
#ifndef _REENT_ONLY
 
int
_DEFUN(VFWSCANF, (fp, fmt, ap),
register FILE *__restrict fp _AND
_CONST wchar_t *__restrict fmt _AND
va_list ap)
{
struct _reent *reent = _REENT;
 
CHECK_INIT(reent, fp);
return __SVFWSCANF_R (reent, fp, fmt, ap);
}
 
int
_DEFUN(__SVFWSCANF, (fp, fmt0, ap),
register FILE *fp _AND
wchar_t _CONST *fmt0 _AND
va_list ap)
{
return __SVFWSCANF_R (_REENT, fp, fmt0, ap);
}
 
#endif /* !_REENT_ONLY */
 
int
_DEFUN(_VFWSCANF_R, (data, fp, fmt, ap),
struct _reent *data _AND
register FILE *fp _AND
_CONST wchar_t *fmt _AND
va_list ap)
{
CHECK_INIT(data, fp);
return __SVFWSCANF_R (data, fp, fmt, ap);
}
#endif /* !STRING_ONLY */
 
#ifdef STRING_ONLY
/* When dealing with the swscanf family, we don't want to use the
* regular ungetwc which will drag in file I/O items we don't need.
* So, we create our own trimmed-down version. */
static wint_t
_DEFUN(_sungetwc_r, (data, fp, ch),
struct _reent *data _AND
wint_t wc _AND
register FILE *fp)
{
if (wc == WEOF)
return (WEOF);
 
/* After ungetc, we won't be at eof anymore */
fp->_flags &= ~__SEOF;
 
/*
* If we are in the middle of ungetwc'ing, just continue.
* This may require expanding the current ungetc buffer.
*/
 
if (HASUB (fp))
{
if (fp->_r >= fp->_ub._size && __submore (data, fp))
{
return EOF;
}
fp->_p -= sizeof (wchar_t);
*fp->_p = (wchar_t) wc;
fp->_r += sizeof (wchar_t);
return wc;
}
 
/*
* If we can handle this by simply backing up, do so,
* but never replace the original character.
* (This makes swscanf() work when scanning `const' data.)
*/
 
if (fp->_bf._base != NULL && fp->_p > fp->_bf._base
&& ((wchar_t *)fp->_p)[-1] == wc)
{
fp->_p -= sizeof (wchar_t);
fp->_r += sizeof (wchar_t);
return wc;
}
 
/*
* Create an ungetc buffer.
* Initially, we will use the `reserve' buffer.
*/
 
fp->_ur = fp->_r;
fp->_up = fp->_p;
fp->_ub._base = fp->_ubuf;
fp->_ub._size = sizeof (fp->_ubuf);
fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - sizeof (wchar_t)];
*(wchar_t *) fp->_p = wc;
fp->_r = 2;
return wc;
}
 
extern int __ssrefill_r _PARAMS ((struct _reent *ptr, register FILE * fp));
 
static size_t
_DEFUN(_sfgetwc_r, (ptr, fp),
struct _reent * ptr _AND
FILE * fp)
{
wchar_t wc;
 
if (fp->_r <= 0 && __ssrefill_r (ptr, fp))
return (WEOF);
wc = *(wchar_t *) fp->_p;
fp->_p += sizeof (wchar_t);
fp->_r -= sizeof (wchar_t);
return (wc);
}
#endif /* STRING_ONLY */
 
int
_DEFUN(__SVFWSCANF_R, (rptr, fp, fmt0, ap),
struct _reent *rptr _AND
register FILE *fp _AND
wchar_t _CONST *fmt0 _AND
va_list ap)
{
register wchar_t *fmt = (wchar_t *) fmt0;
register wint_t c; /* character from format, or conversion */
register size_t width; /* field width, or 0 */
register wchar_t *p = NULL; /* points into all kinds of strings */
register int n; /* handy integer */
register int flags; /* flags as defined above */
register wchar_t *p0; /* saves original value of p when necessary */
int nassigned; /* number of fields assigned */
int nread; /* number of characters consumed from fp */
#ifndef _NO_POS_ARGS
int N; /* arg number */
int arg_index = 0; /* index into args processed directly */
int numargs = 0; /* number of varargs read */
void *args[MAX_POS_ARGS]; /* positional args read */
int is_pos_arg; /* is current format positional? */
#endif
int base = 0; /* base argument to wcstol/wcstoul */
 
mbstate_t mbs; /* value to keep track of multibyte state */
 
#define CCFN_PARAMS _PARAMS((struct _reent *, const wchar_t *, wchar_t **, int))
unsigned long (*ccfn)CCFN_PARAMS=0; /* conversion function (wcstol/wcstoul) */
wchar_t buf[BUF]; /* buffer for numeric conversions */
const wchar_t *ccls; /* character class start */
const wchar_t *ccle; /* character class end */
int cclcompl = 0; /* ccl is complemented? */
wint_t wi; /* handy wint_t */
char *mbp = NULL; /* multibyte string pointer for %c %s %[ */
size_t nconv; /* number of bytes in mb. conversion */
char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
 
char *cp;
short *sp;
int *ip;
#ifdef FLOATING_POINT
float *flp;
_LONG_DOUBLE *ldp;
double *dp;
wchar_t decpt;
#endif
long *lp;
#ifndef _NO_LONGLONG
long long *llp;
#endif
 
/* `basefix' is used to avoid `if' tests in the integer scanner */
static _CONST short basefix[17] =
{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
 
/* Macro to support positional arguments */
#ifndef _NO_POS_ARGS
# define GET_ARG(n, ap, type) \
((type) (is_pos_arg \
? (n < numargs \
? args[n] \
: get_arg (n, &ap, &numargs, args)) \
: (arg_index++ < numargs \
? args[n] \
: (numargs < MAX_POS_ARGS \
? args[numargs++] = va_arg (ap, void *) \
: va_arg (ap, void *)))))
#else
# define GET_ARG(n, ap, type) (va_arg (ap, type))
#endif
 
#ifdef FLOATING_POINT
#ifdef _MB_CAPABLE
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
decpt = *__get_current_numeric_locale ()->wdecimal_point;
#else
{
size_t nconv;
 
memset (&mbs, '\0', sizeof (mbs));
nconv = _mbrtowc_r (rptr, &decpt,
_localeconv_r (rptr)->decimal_point,
MB_CUR_MAX, &mbs);
if (nconv == (size_t) -1 || nconv == (size_t) -2)
decpt = L'.';
}
#endif /* !__HAVE_LOCALE_INFO_EXTENDED__ */
#else
decpt = (wchar_t) *_localeconv_r (rptr)->decimal_point;
#endif /* !_MB_CAPABLE */
#endif /* FLOATING_POINT */
 
_newlib_flockfile_start (fp);
 
ORIENT (fp, 1);
 
nassigned = 0;
nread = 0;
ccls = ccle = NULL;
for (;;)
{
c = *fmt++;
if (c == L'\0')
goto all_done;
if (iswspace (c))
{
while ((c = _fgetwc_r (rptr, fp)) != WEOF && iswspace(c))
;
if (c != WEOF)
_ungetwc_r (rptr, c, fp);
continue;
}
if (c != L'%')
goto literal;
width = 0;
flags = 0;
#ifndef _NO_POS_ARGS
N = arg_index;
is_pos_arg = 0;
#endif
 
/*
* switch on the format. continue if done; break once format
* type is derived.
*/
 
again:
c = *fmt++;
 
switch (c)
{
case L'%':
literal:
if ((wi = _fgetwc_r (rptr, fp)) == WEOF)
goto input_failure;
if (wi != c)
{
_ungetwc_r (rptr, wi, fp);
goto input_failure;
}
nread++;
continue;
 
case L'*':
flags |= SUPPRESS;
goto again;
case L'l':
#if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG
if (*fmt == L'l') /* Check for 'll' = long long (SUSv3) */
{
++fmt;
flags |= LONGDBL;
}
else
#endif
flags |= LONG;
goto again;
case L'L':
flags |= LONGDBL;
goto again;
case L'h':
#ifdef _WANT_IO_C99_FORMATS
if (*fmt == 'h') /* Check for 'hh' = char int (SUSv3) */
{
++fmt;
flags |= CHAR;
}
else
#endif
flags |= SHORT;
goto again;
#ifdef _WANT_IO_C99_FORMATS
case L'j': /* intmax_t */
if (sizeof (intmax_t) == sizeof (long))
flags |= LONG;
else
flags |= LONGDBL;
goto again;
case L't': /* ptrdiff_t */
if (sizeof (ptrdiff_t) < sizeof (int))
/* POSIX states ptrdiff_t is 16 or more bits, as
is short. */
flags |= SHORT;
else if (sizeof (ptrdiff_t) == sizeof (int))
/* no flag needed */;
else if (sizeof (ptrdiff_t) <= sizeof (long))
flags |= LONG;
else
/* POSIX states that at least one programming
environment must support ptrdiff_t no wider than
long, but that means other environments can
have ptrdiff_t as wide as long long. */
flags |= LONGDBL;
goto again;
case L'z': /* size_t */
if (sizeof (size_t) < sizeof (int))
/* POSIX states size_t is 16 or more bits, as is short. */
flags |= SHORT;
else if (sizeof (size_t) == sizeof (int))
/* no flag needed */;
else if (sizeof (size_t) <= sizeof (long))
flags |= LONG;
else
/* POSIX states that at least one programming
environment must support size_t no wider than
long, but that means other environments can
have size_t as wide as long long. */
flags |= LONGDBL;
goto again;
#endif /* _WANT_IO_C99_FORMATS */
 
case L'0':
case L'1':
case L'2':
case L'3':
case L'4':
case L'5':
case L'6':
case L'7':
case L'8':
case L'9':
width = width * 10 + c - L'0';
goto again;
 
#ifndef _NO_POS_ARGS
case L'$':
if (width <= MAX_POS_ARGS)
{
N = width - 1;
is_pos_arg = 1;
width = 0;
goto again;
}
rptr->_errno = EINVAL;
goto input_failure;
#endif /* !_NO_POS_ARGS */
 
case L'd':
c = CT_INT;
ccfn = (unsigned long (*)CCFN_PARAMS)_wcstol_r;
base = 10;
break;
 
case L'i':
c = CT_INT;
ccfn = (unsigned long (*)CCFN_PARAMS)_wcstol_r;
base = 0;
break;
 
case L'o':
c = CT_INT;
ccfn = _wcstoul_r;
base = 8;
break;
 
case L'u':
c = CT_INT;
ccfn = _wcstoul_r;
base = 10;
break;
 
case L'X':
case L'x':
flags |= PFXOK; /* enable 0x prefixing */
c = CT_INT;
ccfn = _wcstoul_r;
base = 16;
break;
 
#ifdef FLOATING_POINT
# ifdef _WANT_IO_C99_FORMATS
case L'A':
case L'a':
case L'F':
# endif
case L'E':
case L'G':
case L'e':
case L'f':
case L'g':
c = CT_FLOAT;
break;
#endif
 
#ifdef _WANT_IO_C99_FORMATS
case L'S':
flags |= LONG;
/* FALLTHROUGH */
#endif
 
case L's':
c = CT_STRING;
break;
 
case L'[':
ccls = fmt;
if (*fmt == '^')
{
cclcompl = 1;
++fmt;
}
else
cclcompl = 0;
if (*fmt == ']')
fmt++;
while (*fmt != '\0' && *fmt != ']')
fmt++;
ccle = fmt;
fmt++;
flags |= NOSKIP;
c = CT_CCL;
break;
 
#ifdef _WANT_IO_C99_FORMATS
case 'C':
flags |= LONG;
/* FALLTHROUGH */
#endif
 
case 'c':
flags |= NOSKIP;
c = CT_CHAR;
break;
 
case 'p': /* pointer format is like hex */
flags |= POINTER | PFXOK;
c = CT_INT;
ccfn = _wcstoul_r;
base = 16;
break;
 
case 'n':
if (flags & SUPPRESS) /* ??? */
continue;
#ifdef _WANT_IO_C99_FORMATS
if (flags & CHAR)
{
cp = GET_ARG (N, ap, char *);
*cp = nread;
}
else
#endif
if (flags & SHORT)
{
sp = GET_ARG (N, ap, short *);
*sp = nread;
}
else if (flags & LONG)
{
lp = GET_ARG (N, ap, long *);
*lp = nread;
}
#ifndef _NO_LONGLONG
else if (flags & LONGDBL)
{
llp = GET_ARG (N, ap, long long*);
*llp = nread;
}
#endif
else
{
ip = GET_ARG (N, ap, int *);
*ip = nread;
}
continue;
 
/*
* Disgusting backwards compatibility hacks. XXX
*/
case L'\0': /* compat */
_newlib_flockfile_exit (fp);
return EOF;
 
default: /* compat */
goto match_failure;
}
 
/*
* Consume leading white space, except for formats that
* suppress this.
*/
if ((flags & NOSKIP) == 0)
{
while ((wi = _fgetwc_r (rptr, fp)) != WEOF && iswspace (wi))
nread++;
if (wi == WEOF)
goto input_failure;
_ungetwc_r (rptr, wi, fp);
}
 
/*
* Do the conversion.
*/
switch (c)
{
 
case CT_CHAR:
/* scan arbitrary characters (sets NOSKIP) */
if (width == 0)
width = 1;
if (flags & LONG)
{
if (!(flags & SUPPRESS))
p = GET_ARG(N, ap, wchar_t *);
n = 0;
while (width-- != 0 && (wi = _fgetwc_r (rptr, fp)) != WEOF)
{
if (!(flags & SUPPRESS))
*p++ = (wchar_t) wi;
n++;
}
if (n == 0)
goto input_failure;
nread += n;
if (!(flags & SUPPRESS))
nassigned++;
}
else
{
if (!(flags & SUPPRESS))
mbp = GET_ARG(N, ap, char *);
n = 0;
memset ((_PTR)&mbs, '\0', sizeof (mbstate_t));
while (width != 0 && (wi = _fgetwc_r (rptr, fp)) != WEOF)
{
if (width >= MB_CUR_MAX && !(flags & SUPPRESS))
{
nconv = _wcrtomb_r (rptr, mbp, wi, &mbs);
if (nconv == (size_t) -1)
goto input_failure;
}
else
{
nconv = _wcrtomb_r (rptr, mbbuf, wi, &mbs);
if (nconv == (size_t) -1)
goto input_failure;
if (nconv > width)
{
_ungetwc_r (rptr, wi, fp);
break;
}
if (!(flags & SUPPRESS))
memcpy(mbp, mbbuf, nconv);
}
if (!(flags & SUPPRESS))
mbp += nconv;
width -= nconv;
n++;
}
if (n == 0)
goto input_failure;
nread += n;
if (!(flags & SUPPRESS))
nassigned++;
}
break;
 
case CT_CCL:
/* scan a (nonempty) character class (sets NOSKIP) */
if (width == 0)
width = (size_t) ~0; /* `infinity' */
/* take only those things in the class */
if ((flags & SUPPRESS) && (flags & LONG))
{
n = 0;
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width-- != 0 && INCCL (wi))
n++;
if (wi != WEOF)
_ungetwc_r (rptr, wi, fp);
if (n == 0)
goto match_failure;
}
else if (flags & LONG)
{
p0 = p = GET_ARG(N, ap, wchar_t *);
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width-- != 0 && INCCL (wi))
*p++ = (wchar_t) wi;
if (wi != WEOF)
_ungetwc_r (rptr, wi, fp);
n = p - p0;
if (n == 0)
goto match_failure;
*p = L'\0';
nassigned++;
}
else
{
if (!(flags & SUPPRESS))
mbp = GET_ARG(N, ap, char *);
n = 0;
memset ((_PTR) &mbs, '\0', sizeof (mbstate_t));
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width-- != 0 && INCCL (wi))
{
if (width >= MB_CUR_MAX && !(flags & SUPPRESS))
{
nconv = _wcrtomb_r (rptr, mbp, wi, &mbs);
if (nconv == (size_t) -1)
goto input_failure;
}
else
{
nconv = wcrtomb(mbbuf, wi, &mbs);
if (nconv == (size_t) -1)
goto input_failure;
if (nconv > width)
break;
if (!(flags & SUPPRESS))
memcpy(mbp, mbbuf, nconv);
}
if (!(flags & SUPPRESS))
mbp += nconv;
width -= nconv;
n++;
}
if (wi != WEOF)
_ungetwc_r (rptr, wi, fp);
if (!(flags & SUPPRESS))
{
*mbp = 0;
nassigned++;
}
}
nread += n;
break;
 
case CT_STRING:
/* like CCL, but zero-length string OK, & no NOSKIP */
if (width == 0)
width = (size_t)~0;
if ((flags & SUPPRESS) && (flags & LONG))
{
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width-- != 0 && !iswspace (wi))
nread++;
if (wi != WEOF)
_ungetwc_r (rptr, wi, fp);
}
else if (flags & LONG)
{
p0 = p = GET_ARG(N, ap, wchar_t *);
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width-- != 0 && !iswspace (wi))
{
*p++ = (wchar_t) wi;
nread++;
}
if (wi != WEOF)
_ungetwc_r (rptr, wi, fp);
*p = L'\0';
nassigned++;
}
else
{
if (!(flags & SUPPRESS))
mbp = GET_ARG(N, ap, char *);
memset ((_PTR) &mbs, '\0', sizeof (mbstate_t));
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width != 0 && !iswspace (wi))
{
if (width >= MB_CUR_MAX && !(flags & SUPPRESS))
{
nconv = wcrtomb(mbp, wi, &mbs);
if (nconv == (size_t)-1)
goto input_failure;
}
else
{
nconv = wcrtomb(mbbuf, wi, &mbs);
if (nconv == (size_t)-1)
goto input_failure;
if (nconv > width)
break;
if (!(flags & SUPPRESS))
memcpy(mbp, mbbuf, nconv);
}
if (!(flags & SUPPRESS))
mbp += nconv;
width -= nconv;
nread++;
}
if (wi != WEOF)
_ungetwc_r (rptr, wi, fp);
if (!(flags & SUPPRESS))
{
*mbp = 0;
nassigned++;
}
}
continue;
 
case CT_INT:
{
/* scan an integer as if by wcstol/wcstoul */
if (width == 0 || width > sizeof (buf) / sizeof (*buf) - 1)
width = sizeof(buf) / sizeof (*buf) - 1;
flags |= SIGNOK | NDIGITS | NZDIGITS;
for (p = buf; width; width--)
{
c = _fgetwc_r (rptr, fp);
/*
* Switch on the character; `goto ok' if we
* accept it as a part of number.
*/
switch (c)
{
/*
* The digit 0 is always legal, but is special.
* For %i conversions, if no digits (zero or nonzero)
* have been scanned (only signs), we will have base==0.
* In that case, we should set it to 8 and enable 0x
* prefixing. Also, if we have not scanned zero digits
* before this, do not turn off prefixing (someone else
* will turn it off if we have scanned any nonzero digits).
*/
case L'0':
if (base == 0)
{
base = 8;
flags |= PFXOK;
}
if (flags & NZDIGITS)
flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
else
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
 
/* 1 through 7 always legal */
case L'1':
case L'2':
case L'3':
case L'4':
case L'5':
case L'6':
case L'7':
base = basefix[base];
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
 
/* digits 8 and 9 ok iff decimal or hex */
case L'8':
case L'9':
base = basefix[base];
if (base <= 8)
break; /* not legal here */
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
 
/* letters ok iff hex */
case L'A':
case L'B':
case L'C':
case L'D':
case L'E':
case L'F':
case L'a':
case L'b':
case L'c':
case L'd':
case L'e':
case L'f':
/* no need to fix base here */
if (base <= 10)
break; /* not legal here */
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
 
/* sign ok only as first character */
case L'+':
case L'-':
if (flags & SIGNOK)
{
flags &= ~SIGNOK;
flags |= HAVESIGN;
goto ok;
}
break;
 
/* x ok iff flag still set & single 0 seen */
case L'x':
case L'X':
if ((flags & PFXOK) && p == buf + 1 + !!(flags & HAVESIGN))
{
base = 16;/* if %i */
flags &= ~PFXOK;
goto ok;
}
break;
}
 
/*
* If we got here, c is not a legal character
* for a number. Stop accumulating digits.
*/
if (c != WEOF)
_ungetwc_r (rptr, c, fp);
break;
ok:
/*
* c is legal: store it and look at the next.
*/
*p++ = (wchar_t) c;
}
/*
* If we had only a sign, it is no good; push back the sign.
* If the number ends in `x', it was [sign] '0' 'x', so push back
* the x and treat it as [sign] '0'.
* Use of ungetc here and below assumes ASCII encoding; we are only
* pushing back 7-bit characters, so casting to unsigned char is
* not necessary.
*/
if (flags & NDIGITS)
{
if (p > buf)
_ungetwc_r (rptr, *--p, fp); /* [-+xX] */
goto match_failure;
}
c = p[-1];
if (c == L'x' || c == L'X')
{
--p;
_ungetwc_r (rptr, c, fp);
}
if ((flags & SUPPRESS) == 0)
{
unsigned long res;
 
*p = 0;
res = (*ccfn) (rptr, buf, (wchar_t **) NULL, base);
if (flags & POINTER)
{
void **vp = GET_ARG (N, ap, void **);
#ifndef _NO_LONGLONG
if (sizeof (uintptr_t) > sizeof (unsigned long))
{
unsigned long long resll;
resll = _wcstoull_r (rptr, buf, (wchar_t **) NULL, base);
*vp = (void *) (uintptr_t) resll;
}
else
#endif /* !_NO_LONGLONG */
*vp = (void *) (uintptr_t) res;
}
#ifdef _WANT_IO_C99_FORMATS
else if (flags & CHAR)
{
cp = GET_ARG (N, ap, char *);
*cp = res;
}
#endif
else if (flags & SHORT)
{
sp = GET_ARG (N, ap, short *);
*sp = res;
}
else if (flags & LONG)
{
lp = GET_ARG (N, ap, long *);
*lp = res;
}
#ifndef _NO_LONGLONG
else if (flags & LONGDBL)
{
unsigned long long resll;
if (ccfn == _wcstoul_r)
resll = _wcstoull_r (rptr, buf, (wchar_t **) NULL, base);
else
resll = _wcstoll_r (rptr, buf, (wchar_t **) NULL, base);
llp = GET_ARG (N, ap, long long*);
*llp = resll;
}
#endif
else
{
ip = GET_ARG (N, ap, int *);
*ip = res;
}
nassigned++;
}
nread += p - buf;
break;
}
#ifdef FLOATING_POINT
case CT_FLOAT:
{
/* scan a floating point number as if by wcstod */
/* This code used to assume that the number of digits is reasonable.
However, ANSI / ISO C makes no such stipulation; we have to get
exact results even when there is an unreasonable amount of
leading zeroes. */
long leading_zeroes = 0;
long zeroes, exp_adjust;
wchar_t *exp_start = NULL;
unsigned width_left = 0;
char nancount = 0;
char infcount = 0;
#ifdef hardway
if (width == 0 || width > sizeof (buf) - 1)
#else
/* size_t is unsigned, hence this optimisation */
if (width - 1 > sizeof (buf) - 2)
#endif
{
width_left = width - (sizeof (buf) - 1);
width = sizeof (buf) - 1;
}
flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
zeroes = 0;
exp_adjust = 0;
for (p = buf; width; )
{
c = _fgetwc_r (rptr, fp);
/*
* This code mimicks the integer conversion
* code, but is much simpler.
*/
switch (c)
{
case L'0':
if (flags & NDIGITS)
{
flags &= ~SIGNOK;
zeroes++;
if (width_left)
{
width_left--;
width++;
}
goto fskip;
}
/* Fall through. */
case L'1':
case L'2':
case L'3':
case L'4':
case L'5':
case L'6':
case L'7':
case L'8':
case L'9':
if (nancount + infcount == 0)
{
flags &= ~(SIGNOK | NDIGITS);
goto fok;
}
break;
 
case L'+':
case L'-':
if (flags & SIGNOK)
{
flags &= ~SIGNOK;
goto fok;
}
break;
case L'n':
case L'N':
if (nancount == 0 && zeroes == 0
&& (flags & (NDIGITS | DPTOK | EXPOK)) ==
(NDIGITS | DPTOK | EXPOK))
{
flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS);
nancount = 1;
goto fok;
}
if (nancount == 2)
{
nancount = 3;
goto fok;
}
if (infcount == 1 || infcount == 4)
{
infcount++;
goto fok;
}
break;
case L'a':
case L'A':
if (nancount == 1)
{
nancount = 2;
goto fok;
}
break;
case L'i':
if (infcount == 0 && zeroes == 0
&& (flags & (NDIGITS | DPTOK | EXPOK)) ==
(NDIGITS | DPTOK | EXPOK))
{
flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS);
infcount = 1;
goto fok;
}
if (infcount == 3 || infcount == 5)
{
infcount++;
goto fok;
}
break;
case L'f':
case L'F':
if (infcount == 2)
{
infcount = 3;
goto fok;
}
break;
case L't':
case L'T':
if (infcount == 6)
{
infcount = 7;
goto fok;
}
break;
case L'y':
case L'Y':
if (infcount == 7)
{
infcount = 8;
goto fok;
}
break;
case L'e':
case L'E':
/* no exponent without some digits */
if ((flags & (NDIGITS | EXPOK)) == EXPOK
|| ((flags & EXPOK) && zeroes))
{
if (! (flags & DPTOK))
{
exp_adjust = zeroes - leading_zeroes;
exp_start = p;
}
flags =
(flags & ~(EXPOK | DPTOK)) |
SIGNOK | NDIGITS;
zeroes = 0;
goto fok;
}
break;
default:
if ((wchar_t) c == decpt && (flags & DPTOK))
{
flags &= ~(SIGNOK | DPTOK);
leading_zeroes = zeroes;
goto fok;
}
break;
}
if (c != WEOF)
_ungetwc_r (rptr, c, fp);
break;
fok:
*p++ = c;
fskip:
width--;
++nread;
}
if (zeroes)
flags &= ~NDIGITS;
/* We may have a 'N' or possibly even [sign] 'N' 'a' as the
start of 'NaN', only to run out of chars before it was
complete (or having encountered a non-matching char). So
check here if we have an outstanding nancount, and if so
put back the chars we did swallow and treat as a failed
match.
 
FIXME - we still don't handle NAN([0xdigits]). */
if (nancount - 1U < 2U) /* nancount && nancount < 3 */
{
/* Newlib's ungetc works even if we called __srefill in
the middle of a partial parse, but POSIX does not
guarantee that in all implementations of ungetc. */
while (p > buf)
{
_ungetwc_r (rptr, *--p, fp); /* [-+nNaA] */
--nread;
}
goto match_failure;
}
/* Likewise for 'inf' and 'infinity'. But be careful that
'infinite' consumes only 3 characters, leaving the stream
at the second 'i'. */
if (infcount - 1U < 7U) /* infcount && infcount < 8 */
{
if (infcount >= 3) /* valid 'inf', but short of 'infinity' */
while (infcount-- > 3)
{
_ungetwc_r (rptr, *--p, fp); /* [iInNtT] */
--nread;
}
else
{
while (p > buf)
{
_ungetwc_r (rptr, *--p, fp); /* [-+iInN] */
--nread;
}
goto match_failure;
}
}
/*
* If no digits, might be missing exponent digits
* (just give back the exponent) or might be missing
* regular digits, but had sign and/or decimal point.
*/
if (flags & NDIGITS)
{
if (flags & EXPOK)
{
/* no digits at all */
while (p > buf)
{
_ungetwc_r (rptr, *--p, fp); /* [-+.] */
--nread;
}
goto match_failure;
}
/* just a bad exponent (e and maybe sign) */
c = *--p;
--nread;
if (c != L'e' && c != L'E')
{
_ungetwc_r (rptr, c, fp); /* [-+] */
c = *--p;
--nread;
}
_ungetwc_r (rptr, c, fp); /* [eE] */
}
if ((flags & SUPPRESS) == 0)
{
double res = 0;
#ifdef _NO_LONGDBL
#define QUAD_RES res;
#else /* !_NO_LONG_DBL */
long double qres = 0;
#define QUAD_RES qres;
#endif /* !_NO_LONG_DBL */
long new_exp = 0;
 
*p = 0;
if ((flags & (DPTOK | EXPOK)) == EXPOK)
{
exp_adjust = zeroes - leading_zeroes;
new_exp = -exp_adjust;
exp_start = p;
}
else if (exp_adjust)
new_exp = _wcstol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust;
if (exp_adjust)
{
 
/* If there might not be enough space for the new exponent,
truncate some trailing digits to make room. */
if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN)
exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;
swprintf (exp_start, MAX_LONG_LEN, L"e%ld", new_exp);
}
 
/* FIXME: We don't have wcstold yet. */
#if 0//ndef _NO_LONGDBL /* !_NO_LONGDBL */
if (flags & LONGDBL)
qres = _wcstold_r (rptr, buf, NULL);
else
#endif
res = _wcstod_r (rptr, buf, NULL);
 
if (flags & LONG)
{
dp = GET_ARG (N, ap, double *);
*dp = res;
}
else if (flags & LONGDBL)
{
ldp = GET_ARG (N, ap, _LONG_DOUBLE *);
*ldp = QUAD_RES;
}
else
{
flp = GET_ARG (N, ap, float *);
if (isnan (res))
*flp = nanf (NULL);
else
*flp = res;
}
nassigned++;
}
break;
}
#endif /* FLOATING_POINT */
}
}
input_failure:
/* On read failure, return EOF failure regardless of matches; errno
should have been set prior to here. On EOF failure (including
invalid format string), return EOF if no matches yet, else number
of matches made prior to failure. */
_newlib_flockfile_exit (fp);
return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF;
match_failure:
all_done:
/* Return number of matches, which can be 0 on match failure. */
_newlib_flockfile_end (fp);
return nassigned;
}
 
#ifndef _NO_POS_ARGS
/* Process all intermediate arguments. Fortunately, with wscanf, all
intermediate arguments are sizeof(void*), so we don't need to scan
ahead in the format string. */
static void *
get_arg (int n, va_list *ap, int *numargs_p, void **args)
{
int numargs = *numargs_p;
while (n >= numargs)
args[numargs++] = va_arg (*ap, void *);
*numargs_p = numargs;
return args[n];
}
#endif /* !_NO_POS_ARGS */
/contrib/sdk/sources/newlib/libc/stdio/vswprintf.c
0,0 → 1,82
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* doc in vfwprintf.c */
 
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <limits.h>
#include <stdarg.h>
#include <errno.h>
 
#include "local.h"
 
int
_DEFUN(_vswprintf_r, (ptr, str, size, fmt, ap),
struct _reent *ptr _AND
wchar_t *str _AND
size_t size _AND
const wchar_t *fmt _AND
va_list ap)
{
int ret;
FILE f;
 
if (size > INT_MAX / sizeof (wchar_t))
{
ptr->_errno = EOVERFLOW; /* POSIX extension */
return EOF;
}
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = (size > 0 ? (size - 1) * sizeof (wchar_t) : 0);
f._file = -1; /* No file. */
ret = _svfwprintf_r (ptr, &f, fmt, ap);
/* _svfwprintf_r() does not put in a terminating NUL, so add one if
* appropriate, which is whenever size is > 0. _svfwprintf_r() stops
* after n-1, so always just put at the end. */
if (size > 0) {
*(wchar_t *)f._p = L'\0'; /* terminate the string */
}
if(ret >= size) {
/* _svfwprintf_r() returns how many wide characters it would have printed
* if there were enough space. Return an error if too big to fit in str,
* unlike snprintf, which returns the size needed. */
ptr->_errno = EOVERFLOW; /* POSIX extension */
ret = -1;
}
return ret;
}
 
#ifndef _REENT_ONLY
 
int
_DEFUN(vswprintf, (str, size, fmt, ap),
wchar_t *__restrict str _AND
size_t size _AND
const wchar_t *__restrict fmt _AND
va_list ap)
{
return _vswprintf_r (_REENT, str, size, fmt, ap);
}
 
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdio/vswscanf.c
0,0 → 1,62
/*
* Code created by modifying scanf.c which has following copyright.
*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Doc in vfwscanf.c */
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
 
/*
* vsscanf
*/
 
#ifndef _REENT_ONLY
 
int
vswscanf (_CONST wchar_t *__restrict str, _CONST wchar_t * __restrict fmt,
va_list ap)
{
return _vswscanf_r (_REENT, str, fmt, ap);
}
 
#endif /* !_REENT_ONLY */
 
int
_vswscanf_r (struct _reent *ptr, _CONST wchar_t *str, _CONST wchar_t *fmt,
va_list ap)
{
FILE f;
 
f._flags = __SRD | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._r = wcslen (str) * sizeof (wchar_t);
f._read = __seofread;
f._ub._base = NULL;
f._lb._base = NULL;
f._file = -1; /* No file. */
return __ssvfwscanf_r (ptr, &f, fmt, ap);
}
/contrib/sdk/sources/newlib/libc/stdio/vwprintf.c
0,0 → 1,49
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* doc in vfwprintf.c */
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
#include "local.h"
 
#ifndef _REENT_ONLY
 
int
_DEFUN(vwprintf, (fmt, ap),
_CONST wchar_t *__restrict fmt _AND
va_list ap)
{
struct _reent *reent = _REENT;
 
_REENT_SMALL_CHECK_INIT (reent);
return _vfwprintf_r (reent, _stdout_r (reent), fmt, ap);
}
 
#endif /* !_REENT_ONLY */
 
int
_DEFUN(_vwprintf_r, (ptr, fmt, ap),
struct _reent *ptr _AND
_CONST wchar_t *fmt _AND
va_list ap)
{
_REENT_SMALL_CHECK_INIT (ptr);
return _vfwprintf_r (ptr, _stdout_r (ptr), fmt, ap);
}
/contrib/sdk/sources/newlib/libc/stdio/vwscanf.c
0,0 → 1,51
/*-
* Code created by modifying scanf.c which has following copyright.
*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Doc in vfwscanf.c */
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
 
#ifndef _REENT_ONLY
 
int
vwscanf (_CONST wchar_t *__restrict fmt, va_list ap)
{
struct _reent *reent = _REENT;
 
_REENT_SMALL_CHECK_INIT (reent);
return __svfwscanf_r (reent, _stdin_r (reent), fmt, ap);
}
 
#endif /* !_REENT_ONLY */
 
int
_vwscanf_r (struct _reent *ptr, _CONST wchar_t *fmt, va_list ap)
{
_REENT_SMALL_CHECK_INIT (ptr);
return __svfwscanf_r (ptr, _stdin_r (ptr), fmt, ap);
}
 
/contrib/sdk/sources/newlib/libc/stdio/wprintf.c
0,0 → 1,58
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* doc in swprintf.c */
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
#include "local.h"
 
int
_DEFUN(_wprintf_r, (ptr, fmt),
struct _reent *ptr _AND
const wchar_t *fmt _DOTS)
{
int ret;
va_list ap;
 
_REENT_SMALL_CHECK_INIT (ptr);
va_start (ap, fmt);
ret = _vfwprintf_r (ptr, _stdout_r (ptr), fmt, ap);
va_end (ap);
return ret;
}
 
#ifndef _REENT_ONLY
 
int
_DEFUN(wprintf, (fmt),
const wchar_t *__restrict fmt _DOTS)
{
int ret;
va_list ap;
struct _reent *ptr = _REENT;
 
_REENT_SMALL_CHECK_INIT (ptr);
va_start (ap, fmt);
ret = _vfwprintf_r (ptr, _stdout_r (ptr), fmt, ap);
va_end (ap);
return ret;
}
 
#endif /* ! _REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdio/wscanf.c
0,0 → 1,56
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Doc in swscanf.c */
 
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
#include "local.h"
 
#ifndef _REENT_ONLY
 
int
wscanf(_CONST wchar_t *__restrict fmt, ...)
{
int ret;
va_list ap;
struct _reent *reent = _REENT;
 
_REENT_SMALL_CHECK_INIT (reent);
va_start (ap, fmt);
ret = _vfwscanf_r (reent, _stdin_r (reent), fmt, ap);
va_end (ap);
return ret;
}
 
#endif /* !_REENT_ONLY */
 
int
_wscanf_r(struct _reent *ptr, _CONST wchar_t *fmt, ...)
{
int ret;
va_list ap;
 
_REENT_SMALL_CHECK_INIT (ptr);
va_start (ap, fmt);
ret = _vfwscanf_r (ptr, _stdin_r (ptr), fmt, ap);
va_end (ap);
return (ret);
}
 
/contrib/sdk/sources/newlib/libc/stdlib/btowc.c
0,0 → 1,33
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <reent.h>
#include <string.h>
#include "local.h"
 
wint_t
btowc (int c)
{
mbstate_t mbs;
int retval = 0;
wchar_t pwc;
unsigned char b;
 
if (c == EOF)
return WEOF;
 
b = (unsigned char)c;
 
/* Put mbs in initial state. */
memset (&mbs, '\0', sizeof (mbs));
 
_REENT_CHECK_MISC(_REENT);
 
retval = __mbtowc (_REENT, &pwc, (const char *) &b, 1,
__locale_charset (), &mbs);
 
if (retval != 0 && retval != 1)
return WEOF;
 
return (wint_t)pwc;
}
/contrib/sdk/sources/newlib/libc/stdlib/ldtoa.c
0,0 → 1,3868
/* Extended precision arithmetic functions for long double I/O.
* This program has been placed in the public domain.
*/
 
#include <_ansi.h>
#include <reent.h>
#include <string.h>
#include <stdlib.h>
#include "mprec.h"
 
/* These are the externally visible entries. */
/* linux name: long double _IO_strtold (char *, char **); */
long double _strtold (char *, char **);
char *_ldtoa_r (struct _reent *, long double, int, int, int *, int *,
char **);
int _ldcheck (long double *);
#if 0
void _IO_ldtostr (long double *, char *, int, int, char);
#endif
 
/* Number of 16 bit words in external x type format */
#define NE 10
 
/* Number of 16 bit words in internal format */
#define NI (NE+3)
 
/* Array offset to exponent */
#define E 1
 
/* Array offset to high guard word */
#define M 2
 
/* Number of bits of precision */
#define NBITS ((NI-4)*16)
 
/* Maximum number of decimal digits in ASCII conversion
* = NBITS*log10(2)
*/
#define NDEC (NBITS*8/27)
 
/* The exponent of 1.0 */
#define EXONE (0x3fff)
 
/* Maximum exponent digits - base 10 */
#define MAX_EXP_DIGITS 5
 
/* Control structure for long double conversion including rounding precision values.
* rndprc can be set to 80 (if NE=6), 64, 56, 53, or 24 bits.
*/
typedef struct
{
int rlast;
int rndprc;
int rw;
int re;
int outexpon;
unsigned short rmsk;
unsigned short rmbit;
unsigned short rebit;
unsigned short rbit[NI];
unsigned short equot[NI];
} LDPARMS;
 
static void esub (_CONST short unsigned int *a, _CONST short unsigned int *b,
short unsigned int *c, LDPARMS * ldp);
static void emul (_CONST short unsigned int *a, _CONST short unsigned int *b,
short unsigned int *c, LDPARMS * ldp);
static void ediv (_CONST short unsigned int *a, _CONST short unsigned int *b,
short unsigned int *c, LDPARMS * ldp);
static int ecmp (_CONST short unsigned int *a, _CONST short unsigned int *b);
static int enormlz (short unsigned int *x);
static int eshift (short unsigned int *x, int sc);
static void eshup1 (register short unsigned int *x);
static void eshup8 (register short unsigned int *x);
static void eshup6 (register short unsigned int *x);
static void eshdn1 (register short unsigned int *x);
static void eshdn8 (register short unsigned int *x);
static void eshdn6 (register short unsigned int *x);
static void eneg (short unsigned int *x);
static void emov (register _CONST short unsigned int *a,
register short unsigned int *b);
static void eclear (register short unsigned int *x);
static void einfin (register short unsigned int *x, register LDPARMS * ldp);
static void efloor (short unsigned int *x, short unsigned int *y,
LDPARMS * ldp);
static void etoasc (short unsigned int *x, char *string, int ndigs,
int outformat, LDPARMS * ldp);
 
union uconv
{
unsigned short pe;
long double d;
};
 
#if LDBL_MANT_DIG == 24
static void e24toe (short unsigned int *pe, short unsigned int *y,
LDPARMS * ldp);
#elif LDBL_MANT_DIG == 53
static void e53toe (short unsigned int *pe, short unsigned int *y,
LDPARMS * ldp);
#elif LDBL_MANT_DIG == 64
static void e64toe (short unsigned int *pe, short unsigned int *y,
LDPARMS * ldp);
#else
static void e113toe (short unsigned int *pe, short unsigned int *y,
LDPARMS * ldp);
#endif
 
/* econst.c */
/* e type constants used by high precision check routines */
 
#if NE == 10
/* 0.0 */
static _CONST unsigned short ezero[NE] = { 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};
 
/* 1.0E0 */
static _CONST unsigned short eone[NE] = { 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,
};
 
#else
 
/* 0.0 */
static _CONST unsigned short ezero[NE] = {
0, 0000000, 0000000, 0000000, 0000000, 0000000,
};
 
/* 1.0E0 */
static _CONST unsigned short eone[NE] = {
0, 0000000, 0000000, 0000000, 0100000, 0x3fff,
};
 
#endif
 
/* Debugging routine for displaying errors */
#ifdef DEBUG
/* Notice: the order of appearance of the following
* messages is bound to the error codes defined
* in mconf.h.
*/
static _CONST char *_CONST ermsg[7] = {
"unknown", /* error code 0 */
"domain", /* error code 1 */
"singularity", /* et seq. */
"overflow",
"underflow",
"total loss of precision",
"partial loss of precision"
};
 
#define mtherr(name, code) printf( "\n%s %s error\n", name, ermsg[code] );
#else
#define mtherr(name, code)
#endif
 
/* ieee.c
*
* Extended precision IEEE binary floating point arithmetic routines
*
* Numbers are stored in C language as arrays of 16-bit unsigned
* short integers. The arguments of the routines are pointers to
* the arrays.
*
*
* External e type data structure, simulates Intel 8087 chip
* temporary real format but possibly with a larger significand:
*
* NE-1 significand words (least significant word first,
* most significant bit is normally set)
* exponent (value = EXONE for 1.0,
* top bit is the sign)
*
*
* Internal data structure of a number (a "word" is 16 bits):
*
* ei[0] sign word (0 for positive, 0xffff for negative)
* ei[1] biased exponent (value = EXONE for the number 1.0)
* ei[2] high guard word (always zero after normalization)
* ei[3]
* to ei[NI-2] significand (NI-4 significand words,
* most significant word first,
* most significant bit is set)
* ei[NI-1] low guard word (0x8000 bit is rounding place)
*
*
*
* Routines for external format numbers
*
* asctoe( string, e ) ASCII string to extended double e type
* asctoe64( string, &d ) ASCII string to long double
* asctoe53( string, &d ) ASCII string to double
* asctoe24( string, &f ) ASCII string to single
* asctoeg( string, e, prec, ldp ) ASCII string to specified precision
* e24toe( &f, e, ldp ) IEEE single precision to e type
* e53toe( &d, e, ldp ) IEEE double precision to e type
* e64toe( &d, e, ldp ) IEEE long double precision to e type
* e113toe( &d, e, ldp ) IEEE long double precision to e type
* eabs(e) absolute value
* eadd( a, b, c ) c = b + a
* eclear(e) e = 0
* ecmp (a, b) Returns 1 if a > b, 0 if a == b,
* -1 if a < b, -2 if either a or b is a NaN.
* ediv( a, b, c, ldp ) c = b / a
* efloor( a, b, ldp ) truncate to integer, toward -infinity
* efrexp( a, exp, s ) extract exponent and significand
* eifrac( e, &l, frac ) e to long integer and e type fraction
* euifrac( e, &l, frac ) e to unsigned long integer and e type fraction
* einfin( e, ldp ) set e to infinity, leaving its sign alone
* eldexp( a, n, b ) multiply by 2**n
* emov( a, b ) b = a
* emul( a, b, c, ldp ) c = b * a
* eneg(e) e = -e
* eround( a, b ) b = nearest integer value to a
* esub( a, b, c, ldp ) c = b - a
* e24toasc( &f, str, n ) single to ASCII string, n digits after decimal
* e53toasc( &d, str, n ) double to ASCII string, n digits after decimal
* e64toasc( &d, str, n ) long double to ASCII string
* etoasc(e,str,n,fmt,ldp)e to ASCII string, n digits after decimal
* etoe24( e, &f ) convert e type to IEEE single precision
* etoe53( e, &d ) convert e type to IEEE double precision
* etoe64( e, &d ) convert e type to IEEE long double precision
* ltoe( &l, e ) long (32 bit) integer to e type
* ultoe( &l, e ) unsigned long (32 bit) integer to e type
* eisneg( e ) 1 if sign bit of e != 0, else 0
* eisinf( e ) 1 if e has maximum exponent (non-IEEE)
* or is infinite (IEEE)
* eisnan( e ) 1 if e is a NaN
* esqrt( a, b ) b = square root of a
*
*
* Routines for internal format numbers
*
* eaddm( ai, bi ) add significands, bi = bi + ai
* ecleaz(ei) ei = 0
* ecleazs(ei) set ei = 0 but leave its sign alone
* ecmpm( ai, bi ) compare significands, return 1, 0, or -1
* edivm( ai, bi, ldp ) divide significands, bi = bi / ai
* emdnorm(ai,l,s,exp,ldp) normalize and round off
* emovi( a, ai ) convert external a to internal ai
* emovo( ai, a, ldp ) convert internal ai to external a
* emovz( ai, bi ) bi = ai, low guard word of bi = 0
* emulm( ai, bi, ldp ) multiply significands, bi = bi * ai
* enormlz(ei) left-justify the significand
* eshdn1( ai ) shift significand and guards down 1 bit
* eshdn8( ai ) shift down 8 bits
* eshdn6( ai ) shift down 16 bits
* eshift( ai, n ) shift ai n bits up (or down if n < 0)
* eshup1( ai ) shift significand and guards up 1 bit
* eshup8( ai ) shift up 8 bits
* eshup6( ai ) shift up 16 bits
* esubm( ai, bi ) subtract significands, bi = bi - ai
*
*
* The result is always normalized and rounded to NI-4 word precision
* after each arithmetic operation.
*
* Exception flags are NOT fully supported.
*
* Define USE_INFINITY in mconf.h for support of infinity; otherwise a
* saturation arithmetic is implemented.
*
* Define NANS for support of Not-a-Number items; otherwise the
* arithmetic will never produce a NaN output, and might be confused
* by a NaN input.
* If NaN's are supported, the output of ecmp(a,b) is -2 if
* either a or b is a NaN. This means asking if(ecmp(a,b) < 0)
* may not be legitimate. Use if(ecmp(a,b) == -1) for less-than
* if in doubt.
* Signaling NaN's are NOT supported; they are treated the same
* as quiet NaN's.
*
* Denormals are always supported here where appropriate (e.g., not
* for conversion to DEC numbers).
*/
 
/*
* Revision history:
*
* 5 Jan 84 PDP-11 assembly language version
* 6 Dec 86 C language version
* 30 Aug 88 100 digit version, improved rounding
* 15 May 92 80-bit long double support
* 22 Nov 00 Revised to fit into newlib by Jeff Johnston <jjohnstn@redhat.com>
*
* Author: S. L. Moshier.
*
* Copyright (c) 1984,2000 S.L. Moshier
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION
* OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
* SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
*/
 
#include <stdio.h>
/* #include "\usr\include\stdio.h" */
/*#include "ehead.h"*/
/*#include "mconf.h"*/
/* mconf.h
*
* Common include file for math routines
*
*
*
* SYNOPSIS:
*
* #include "mconf.h"
*
*
*
* DESCRIPTION:
*
* This file contains definitions for error codes that are
* passed to the common error handling routine mtherr()
* (which see).
*
* The file also includes a conditional assembly definition
* for the type of computer arithmetic (IEEE, DEC, Motorola
* IEEE, or UNKnown).
*
* For Digital Equipment PDP-11 and VAX computers, certain
* IBM systems, and others that use numbers with a 56-bit
* significand, the symbol DEC should be defined. In this
* mode, most floating point constants are given as arrays
* of octal integers to eliminate decimal to binary conversion
* errors that might be introduced by the compiler.
*
* For computers, such as IBM PC, that follow the IEEE
* Standard for Binary Floating Point Arithmetic (ANSI/IEEE
* Std 754-1985), the symbol IBMPC should be defined. These
* numbers have 53-bit significands. In this mode, constants
* are provided as arrays of hexadecimal 16 bit integers.
*
* To accommodate other types of computer arithmetic, all
* constants are also provided in a normal decimal radix
* which one can hope are correctly converted to a suitable
* format by the available C language compiler. To invoke
* this mode, the symbol UNK is defined.
*
* An important difference among these modes is a predefined
* set of machine arithmetic constants for each. The numbers
* MACHEP (the machine roundoff error), MAXNUM (largest number
* represented), and several other parameters are preset by
* the configuration symbol. Check the file const.c to
* ensure that these values are correct for your computer.
*
* For ANSI C compatibility, define ANSIC equal to 1. Currently
* this affects only the atan2() function and others that use it.
*/
 
/* Constant definitions for math error conditions
*/
 
#define DOMAIN 1 /* argument domain error */
#define SING 2 /* argument singularity */
#define OVERFLOW 3 /* overflow range error */
#define UNDERFLOW 4 /* underflow range error */
#define TLOSS 5 /* total loss of precision */
#define PLOSS 6 /* partial loss of precision */
 
#define EDOM 33
#define ERANGE 34
 
typedef struct
{
double r;
double i;
} cmplx;
 
/* Type of computer arithmetic */
 
#ifndef DEC
#ifdef __IEEE_LITTLE_ENDIAN
#define IBMPC 1
#else /* !__IEEE_LITTLE_ENDIAN */
#define MIEEE 1
#endif /* !__IEEE_LITTLE_ENDIAN */
#endif /* !DEC */
 
/* Define 1 for ANSI C atan2() function
* See atan.c and clog.c.
*/
#define ANSIC 1
 
/*define VOLATILE volatile*/
#define VOLATILE
 
#define NANS
#define USE_INFINITY
 
/* NaN's require infinity support. */
#ifdef NANS
#ifndef INFINITY
#define USE_INFINITY
#endif
#endif
 
/* This handles 64-bit long ints. */
#define LONGBITS (8 * sizeof(long))
 
 
static void eaddm (short unsigned int *x, short unsigned int *y);
static void esubm (short unsigned int *x, short unsigned int *y);
static void emdnorm (short unsigned int *s, int lost, int subflg,
long int exp, int rcntrl, LDPARMS * ldp);
static int asctoeg (char *ss, short unsigned int *y, int oprec,
LDPARMS * ldp);
static void enan (short unsigned int *nan, int size);
#if LDBL_MANT_DIG == 24
static void toe24 (short unsigned int *x, short unsigned int *y);
#elif LDBL_MANT_DIG == 53
static void toe53 (short unsigned int *x, short unsigned int *y);
#elif LDBL_MANT_DIG == 64
static void toe64 (short unsigned int *a, short unsigned int *b);
#else
static void toe113 (short unsigned int *a, short unsigned int *b);
#endif
static void eiremain (short unsigned int *den, short unsigned int *num,
LDPARMS * ldp);
static int ecmpm (register short unsigned int *a,
register short unsigned int *b);
static int edivm (short unsigned int *den, short unsigned int *num,
LDPARMS * ldp);
static int emulm (short unsigned int *a, short unsigned int *b,
LDPARMS * ldp);
static int eisneg (_CONST short unsigned int *x);
static int eisinf (_CONST short unsigned int *x);
static void emovi (_CONST short unsigned int *a, short unsigned int *b);
static void emovo (short unsigned int *a, short unsigned int *b,
LDPARMS * ldp);
static void emovz (register short unsigned int *a,
register short unsigned int *b);
static void ecleaz (register short unsigned int *xi);
static void eadd1 (_CONST short unsigned int *a, _CONST short unsigned int *b,
short unsigned int *c, int subflg, LDPARMS * ldp);
static int eisnan (_CONST short unsigned int *x);
static int eiisnan (short unsigned int *x);
 
#ifdef DEC
static void etodec (), todec (), dectoe ();
#endif
 
/*
; Clear out entire external format number.
;
; unsigned short x[];
; eclear( x );
*/
 
static void
eclear (register short unsigned int *x)
{
register int i;
 
for (i = 0; i < NE; i++)
*x++ = 0;
}
 
 
 
/* Move external format number from a to b.
*
* emov( a, b );
*/
 
static void
emov (register _CONST short unsigned int *a, register short unsigned int *b)
{
register int i;
 
for (i = 0; i < NE; i++)
*b++ = *a++;
}
 
 
/*
; Negate external format number
;
; unsigned short x[NE];
; eneg( x );
*/
 
static void
eneg (short unsigned int *x)
{
 
#ifdef NANS
if (eisnan (x))
return;
#endif
x[NE - 1] ^= 0x8000; /* Toggle the sign bit */
}
 
 
 
/* Return 1 if external format number is negative,
* else return zero.
*/
static int
eisneg (_CONST short unsigned int *x)
{
 
#ifdef NANS
if (eisnan (x))
return (0);
#endif
if (x[NE - 1] & 0x8000)
return (1);
else
return (0);
}
 
 
/* Return 1 if external format number has maximum possible exponent,
* else return zero.
*/
static int
eisinf (_CONST short unsigned int *x)
{
 
if ((x[NE - 1] & 0x7fff) == 0x7fff)
{
#ifdef NANS
if (eisnan (x))
return (0);
#endif
return (1);
}
else
return (0);
}
 
/* Check if e-type number is not a number.
*/
static int
eisnan (_CONST short unsigned int *x)
{
 
#ifdef NANS
int i;
/* NaN has maximum exponent */
if ((x[NE - 1] & 0x7fff) != 0x7fff)
return (0);
/* ... and non-zero significand field. */
for (i = 0; i < NE - 1; i++)
{
if (*x++ != 0)
return (1);
}
#endif
return (0);
}
 
/*
; Fill entire number, including exponent and significand, with
; largest possible number. These programs implement a saturation
; value that is an ordinary, legal number. A special value
; "infinity" may also be implemented; this would require tests
; for that value and implementation of special rules for arithmetic
; operations involving inifinity.
*/
 
static void
einfin (register short unsigned int *x, register LDPARMS * ldp)
{
register int i;
 
#ifdef USE_INFINITY
for (i = 0; i < NE - 1; i++)
*x++ = 0;
*x |= 32767;
ldp = ldp;
#else
for (i = 0; i < NE - 1; i++)
*x++ = 0xffff;
*x |= 32766;
if (ldp->rndprc < NBITS)
{
if (ldp->rndprc == 113)
{
*(x - 9) = 0;
*(x - 8) = 0;
}
if (ldp->rndprc == 64)
{
*(x - 5) = 0;
}
if (ldp->rndprc == 53)
{
*(x - 4) = 0xf800;
}
else
{
*(x - 4) = 0;
*(x - 3) = 0;
*(x - 2) = 0xff00;
}
}
#endif
}
 
/* Move in external format number,
* converting it to internal format.
*/
static void
emovi (_CONST short unsigned int *a, short unsigned int *b)
{
register _CONST unsigned short *p;
register unsigned short *q;
int i;
 
q = b;
p = a + (NE - 1); /* point to last word of external number */
/* get the sign bit */
if (*p & 0x8000)
*q++ = 0xffff;
else
*q++ = 0;
/* get the exponent */
*q = *p--;
*q++ &= 0x7fff; /* delete the sign bit */
#ifdef USE_INFINITY
if ((*(q - 1) & 0x7fff) == 0x7fff)
{
#ifdef NANS
if (eisnan (a))
{
*q++ = 0;
for (i = 3; i < NI; i++)
*q++ = *p--;
return;
}
#endif
for (i = 2; i < NI; i++)
*q++ = 0;
return;
}
#endif
/* clear high guard word */
*q++ = 0;
/* move in the significand */
for (i = 0; i < NE - 1; i++)
*q++ = *p--;
/* clear low guard word */
*q = 0;
}
 
 
/* Move internal format number out,
* converting it to external format.
*/
static void
emovo (short unsigned int *a, short unsigned int *b, LDPARMS * ldp)
{
register unsigned short *p, *q;
unsigned short i;
 
p = a;
q = b + (NE - 1); /* point to output exponent */
/* combine sign and exponent */
i = *p++;
if (i)
*q-- = *p++ | 0x8000;
else
*q-- = *p++;
#ifdef USE_INFINITY
if (*(p - 1) == 0x7fff)
{
#ifdef NANS
if (eiisnan (a))
{
enan (b, NBITS);
return;
}
#endif
einfin (b, ldp);
return;
}
#endif
/* skip over guard word */
++p;
/* move the significand */
for (i = 0; i < NE - 1; i++)
*q-- = *p++;
}
 
 
/* Clear out internal format number.
*/
 
static void
ecleaz (register short unsigned int *xi)
{
register int i;
 
for (i = 0; i < NI; i++)
*xi++ = 0;
}
 
/* same, but don't touch the sign. */
 
static void
ecleazs (register short unsigned int *xi)
{
register int i;
 
++xi;
for (i = 0; i < NI - 1; i++)
*xi++ = 0;
}
 
 
 
 
/* Move internal format number from a to b.
*/
static void
emovz (register short unsigned int *a, register short unsigned int *b)
{
register int i;
 
for (i = 0; i < NI - 1; i++)
*b++ = *a++;
/* clear low guard word */
*b = 0;
}
 
/* Return nonzero if internal format number is a NaN.
*/
 
static int
eiisnan (short unsigned int *x)
{
int i;
 
if ((x[E] & 0x7fff) == 0x7fff)
{
for (i = M + 1; i < NI; i++)
{
if (x[i] != 0)
return (1);
}
}
return (0);
}
 
#if LDBL_MANT_DIG == 64
 
/* Return nonzero if internal format number is infinite. */
static int
eiisinf (unsigned short x[])
{
 
#ifdef NANS
if (eiisnan (x))
return (0);
#endif
if ((x[E] & 0x7fff) == 0x7fff)
return (1);
return (0);
}
#endif /* LDBL_MANT_DIG == 64 */
 
/*
; Compare significands of numbers in internal format.
; Guard words are included in the comparison.
;
; unsigned short a[NI], b[NI];
; cmpm( a, b );
;
; for the significands:
; returns +1 if a > b
; 0 if a == b
; -1 if a < b
*/
static int
ecmpm (register short unsigned int *a, register short unsigned int *b)
{
int i;
 
a += M; /* skip up to significand area */
b += M;
for (i = M; i < NI; i++)
{
if (*a++ != *b++)
goto difrnt;
}
return (0);
 
difrnt:
if (*(--a) > *(--b))
return (1);
else
return (-1);
}
 
 
/*
; Shift significand down by 1 bit
*/
 
static void
eshdn1 (register short unsigned int *x)
{
register unsigned short bits;
int i;
 
x += M; /* point to significand area */
 
bits = 0;
for (i = M; i < NI; i++)
{
if (*x & 1)
bits |= 1;
*x >>= 1;
if (bits & 2)
*x |= 0x8000;
bits <<= 1;
++x;
}
}
 
 
 
/*
; Shift significand up by 1 bit
*/
 
static void
eshup1 (register short unsigned int *x)
{
register unsigned short bits;
int i;
 
x += NI - 1;
bits = 0;
 
for (i = M; i < NI; i++)
{
if (*x & 0x8000)
bits |= 1;
*x <<= 1;
if (bits & 2)
*x |= 1;
bits <<= 1;
--x;
}
}
 
 
 
/*
; Shift significand down by 8 bits
*/
 
static void
eshdn8 (register short unsigned int *x)
{
register unsigned short newbyt, oldbyt;
int i;
 
x += M;
oldbyt = 0;
for (i = M; i < NI; i++)
{
newbyt = *x << 8;
*x >>= 8;
*x |= oldbyt;
oldbyt = newbyt;
++x;
}
}
 
/*
; Shift significand up by 8 bits
*/
 
static void
eshup8 (register short unsigned int *x)
{
int i;
register unsigned short newbyt, oldbyt;
 
x += NI - 1;
oldbyt = 0;
 
for (i = M; i < NI; i++)
{
newbyt = *x >> 8;
*x <<= 8;
*x |= oldbyt;
oldbyt = newbyt;
--x;
}
}
 
/*
; Shift significand up by 16 bits
*/
 
static void
eshup6 (register short unsigned int *x)
{
int i;
register unsigned short *p;
 
p = x + M;
x += M + 1;
 
for (i = M; i < NI - 1; i++)
*p++ = *x++;
 
*p = 0;
}
 
/*
; Shift significand down by 16 bits
*/
 
static void
eshdn6 (register short unsigned int *x)
{
int i;
register unsigned short *p;
 
x += NI - 1;
p = x + 1;
 
for (i = M; i < NI - 1; i++)
*(--p) = *(--x);
 
*(--p) = 0;
}
/*
; Add significands
; x + y replaces y
*/
 
static void
eaddm (short unsigned int *x, short unsigned int *y)
{
register unsigned long a;
int i;
unsigned int carry;
 
x += NI - 1;
y += NI - 1;
carry = 0;
for (i = M; i < NI; i++)
{
a = (unsigned long) (*x) + (unsigned long) (*y) + carry;
if (a & 0x10000)
carry = 1;
else
carry = 0;
*y = (unsigned short) a;
--x;
--y;
}
}
 
/*
; Subtract significands
; y - x replaces y
*/
 
static void
esubm (short unsigned int *x, short unsigned int *y)
{
unsigned long a;
int i;
unsigned int carry;
 
x += NI - 1;
y += NI - 1;
carry = 0;
for (i = M; i < NI; i++)
{
a = (unsigned long) (*y) - (unsigned long) (*x) - carry;
if (a & 0x10000)
carry = 1;
else
carry = 0;
*y = (unsigned short) a;
--x;
--y;
}
}
 
 
/* Divide significands */
 
 
/* Multiply significand of e-type number b
by 16-bit quantity a, e-type result to c. */
 
static void
m16m (short unsigned int a, short unsigned int *b, short unsigned int *c)
{
register unsigned short *pp;
register unsigned long carry;
unsigned short *ps;
unsigned short p[NI];
unsigned long aa, m;
int i;
 
aa = a;
pp = &p[NI - 2];
*pp++ = 0;
*pp = 0;
ps = &b[NI - 1];
 
for (i = M + 1; i < NI; i++)
{
if (*ps == 0)
{
--ps;
--pp;
*(pp - 1) = 0;
}
else
{
m = (unsigned long) aa **ps--;
carry = (m & 0xffff) + *pp;
*pp-- = (unsigned short) carry;
carry = (carry >> 16) + (m >> 16) + *pp;
*pp = (unsigned short) carry;
*(pp - 1) = carry >> 16;
}
}
for (i = M; i < NI; i++)
c[i] = p[i];
}
 
 
/* Divide significands. Neither the numerator nor the denominator
is permitted to have its high guard word nonzero. */
 
 
static int
edivm (short unsigned int *den, short unsigned int *num, LDPARMS * ldp)
{
int i;
register unsigned short *p;
unsigned long tnum;
unsigned short j, tdenm, tquot;
unsigned short tprod[NI + 1];
unsigned short *equot = ldp->equot;
 
p = &equot[0];
*p++ = num[0];
*p++ = num[1];
 
for (i = M; i < NI; i++)
{
*p++ = 0;
}
eshdn1 (num);
tdenm = den[M + 1];
for (i = M; i < NI; i++)
{
/* Find trial quotient digit (the radix is 65536). */
tnum = (((unsigned long) num[M]) << 16) + num[M + 1];
 
/* Do not execute the divide instruction if it will overflow. */
if ((tdenm * 0xffffUL) < tnum)
tquot = 0xffff;
else
tquot = tnum / tdenm;
 
/* Prove that the divide worked. */
/*
tcheck = (unsigned long )tquot * tdenm;
if( tnum - tcheck > tdenm )
tquot = 0xffff;
*/
/* Multiply denominator by trial quotient digit. */
m16m (tquot, den, tprod);
/* The quotient digit may have been overestimated. */
if (ecmpm (tprod, num) > 0)
{
tquot -= 1;
esubm (den, tprod);
if (ecmpm (tprod, num) > 0)
{
tquot -= 1;
esubm (den, tprod);
}
}
/*
if( ecmpm( tprod, num ) > 0 )
{
eshow( "tprod", tprod );
eshow( "num ", num );
printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",
tnum, den[M+1], tquot );
}
*/
esubm (tprod, num);
/*
if( ecmpm( num, den ) >= 0 )
{
eshow( "num ", num );
eshow( "den ", den );
printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",
tnum, den[M+1], tquot );
}
*/
equot[i] = tquot;
eshup6 (num);
}
/* test for nonzero remainder after roundoff bit */
p = &num[M];
j = 0;
for (i = M; i < NI; i++)
{
j |= *p++;
}
if (j)
j = 1;
 
for (i = 0; i < NI; i++)
num[i] = equot[i];
 
return ((int) j);
}
 
 
 
/* Multiply significands */
static int
emulm (short unsigned int *a, short unsigned int *b, LDPARMS * ldp)
{
unsigned short *p, *q;
unsigned short pprod[NI];
unsigned short j;
int i;
unsigned short *equot = ldp->equot;
 
equot[0] = b[0];
equot[1] = b[1];
for (i = M; i < NI; i++)
equot[i] = 0;
 
j = 0;
p = &a[NI - 1];
q = &equot[NI - 1];
for (i = M + 1; i < NI; i++)
{
if (*p == 0)
{
--p;
}
else
{
m16m (*p--, b, pprod);
eaddm (pprod, equot);
}
j |= *q;
eshdn6 (equot);
}
 
for (i = 0; i < NI; i++)
b[i] = equot[i];
 
/* return flag for lost nonzero bits */
return ((int) j);
}
 
 
/*
static void eshow(str, x)
char *str;
unsigned short *x;
{
int i;
 
printf( "%s ", str );
for( i=0; i<NI; i++ )
printf( "%04x ", *x++ );
printf( "\n" );
}
*/
 
 
/*
* Normalize and round off.
*
* The internal format number to be rounded is "s".
* Input "lost" indicates whether the number is exact.
* This is the so-called sticky bit.
*
* Input "subflg" indicates whether the number was obtained
* by a subtraction operation. In that case if lost is nonzero
* then the number is slightly smaller than indicated.
*
* Input "exp" is the biased exponent, which may be negative.
* the exponent field of "s" is ignored but is replaced by
* "exp" as adjusted by normalization and rounding.
*
* Input "rcntrl" is the rounding control.
*/
 
 
static void
emdnorm (short unsigned int *s, int lost, int subflg, long int exp,
int rcntrl, LDPARMS * ldp)
{
int i, j;
unsigned short r;
 
/* Normalize */
j = enormlz (s);
 
/* a blank significand could mean either zero or infinity. */
#ifndef USE_INFINITY
if (j > NBITS)
{
ecleazs (s);
return;
}
#endif
exp -= j;
#ifndef USE_INFINITY
if (exp >= 32767L)
goto overf;
#else
if ((j > NBITS) && (exp < 32767L))
{
ecleazs (s);
return;
}
#endif
if (exp < 0L)
{
if (exp > (long) (-NBITS - 1))
{
j = (int) exp;
i = eshift (s, j);
if (i)
lost = 1;
}
else
{
ecleazs (s);
return;
}
}
/* Round off, unless told not to by rcntrl. */
if (rcntrl == 0)
goto mdfin;
/* Set up rounding parameters if the control register changed. */
if (ldp->rndprc != ldp->rlast)
{
ecleaz (ldp->rbit);
switch (ldp->rndprc)
{
default:
case NBITS:
ldp->rw = NI - 1; /* low guard word */
ldp->rmsk = 0xffff;
ldp->rmbit = 0x8000;
ldp->rebit = 1;
ldp->re = ldp->rw - 1;
break;
case 113:
ldp->rw = 10;
ldp->rmsk = 0x7fff;
ldp->rmbit = 0x4000;
ldp->rebit = 0x8000;
ldp->re = ldp->rw;
break;
case 64:
ldp->rw = 7;
ldp->rmsk = 0xffff;
ldp->rmbit = 0x8000;
ldp->rebit = 1;
ldp->re = ldp->rw - 1;
break;
/* For DEC arithmetic */
case 56:
ldp->rw = 6;
ldp->rmsk = 0xff;
ldp->rmbit = 0x80;
ldp->rebit = 0x100;
ldp->re = ldp->rw;
break;
case 53:
ldp->rw = 6;
ldp->rmsk = 0x7ff;
ldp->rmbit = 0x0400;
ldp->rebit = 0x800;
ldp->re = ldp->rw;
break;
case 24:
ldp->rw = 4;
ldp->rmsk = 0xff;
ldp->rmbit = 0x80;
ldp->rebit = 0x100;
ldp->re = ldp->rw;
break;
}
ldp->rbit[ldp->re] = ldp->rebit;
ldp->rlast = ldp->rndprc;
}
 
/* Shift down 1 temporarily if the data structure has an implied
* most significant bit and the number is denormal.
* For rndprc = 64 or NBITS, there is no implied bit.
* But Intel long double denormals lose one bit of significance even so.
*/
#if IBMPC
if ((exp <= 0) && (ldp->rndprc != NBITS))
#else
if ((exp <= 0) && (ldp->rndprc != 64) && (ldp->rndprc != NBITS))
#endif
{
lost |= s[NI - 1] & 1;
eshdn1 (s);
}
/* Clear out all bits below the rounding bit,
* remembering in r if any were nonzero.
*/
r = s[ldp->rw] & ldp->rmsk;
if (ldp->rndprc < NBITS)
{
i = ldp->rw + 1;
while (i < NI)
{
if (s[i])
r |= 1;
s[i] = 0;
++i;
}
}
s[ldp->rw] &= ~ldp->rmsk;
if ((r & ldp->rmbit) != 0)
{
if (r == ldp->rmbit)
{
if (lost == 0)
{ /* round to even */
if ((s[ldp->re] & ldp->rebit) == 0)
goto mddone;
}
else
{
if (subflg != 0)
goto mddone;
}
}
eaddm (ldp->rbit, s);
}
mddone:
#if IBMPC
if ((exp <= 0) && (ldp->rndprc != NBITS))
#else
if ((exp <= 0) && (ldp->rndprc != 64) && (ldp->rndprc != NBITS))
#endif
{
eshup1 (s);
}
if (s[2] != 0)
{ /* overflow on roundoff */
eshdn1 (s);
exp += 1;
}
mdfin:
s[NI - 1] = 0;
if (exp >= 32767L)
{
#ifndef USE_INFINITY
overf:
#endif
#ifdef USE_INFINITY
s[1] = 32767;
for (i = 2; i < NI - 1; i++)
s[i] = 0;
#else
s[1] = 32766;
s[2] = 0;
for (i = M + 1; i < NI - 1; i++)
s[i] = 0xffff;
s[NI - 1] = 0;
if ((ldp->rndprc < 64) || (ldp->rndprc == 113))
{
s[ldp->rw] &= ~ldp->rmsk;
if (ldp->rndprc == 24)
{
s[5] = 0;
s[6] = 0;
}
}
#endif
return;
}
if (exp < 0)
s[1] = 0;
else
s[1] = (unsigned short) exp;
}
 
 
 
/*
; Subtract external format numbers.
;
; unsigned short a[NE], b[NE], c[NE];
; LDPARMS *ldp;
; esub( a, b, c, ldp ); c = b - a
*/
 
static void
esub (_CONST short unsigned int *a, _CONST short unsigned int *b,
short unsigned int *c, LDPARMS * ldp)
{
 
#ifdef NANS
if (eisnan (a))
{
emov (a, c);
return;
}
if (eisnan (b))
{
emov (b, c);
return;
}
/* Infinity minus infinity is a NaN.
* Test for subtracting infinities of the same sign.
*/
if (eisinf (a) && eisinf (b) && ((eisneg (a) ^ eisneg (b)) == 0))
{
mtherr ("esub", DOMAIN);
enan (c, NBITS);
return;
}
#endif
eadd1 (a, b, c, 1, ldp);
}
 
 
 
static void
eadd1 (_CONST short unsigned int *a, _CONST short unsigned int *b,
short unsigned int *c, int subflg, LDPARMS * ldp)
{
unsigned short ai[NI], bi[NI], ci[NI];
int i, lost, j, k;
long lt, lta, ltb;
 
#ifdef USE_INFINITY
if (eisinf (a))
{
emov (a, c);
if (subflg)
eneg (c);
return;
}
if (eisinf (b))
{
emov (b, c);
return;
}
#endif
emovi (a, ai);
emovi (b, bi);
if (subflg)
ai[0] = ~ai[0];
 
/* compare exponents */
lta = ai[E];
ltb = bi[E];
lt = lta - ltb;
if (lt > 0L)
{ /* put the larger number in bi */
emovz (bi, ci);
emovz (ai, bi);
emovz (ci, ai);
ltb = bi[E];
lt = -lt;
}
lost = 0;
if (lt != 0L)
{
if (lt < (long) (-NBITS - 1))
goto done; /* answer same as larger addend */
k = (int) lt;
lost = eshift (ai, k); /* shift the smaller number down */
}
else
{
/* exponents were the same, so must compare significands */
i = ecmpm (ai, bi);
if (i == 0)
{ /* the numbers are identical in magnitude */
/* if different signs, result is zero */
if (ai[0] != bi[0])
{
eclear (c);
return;
}
/* if same sign, result is double */
/* double denomalized tiny number */
if ((bi[E] == 0) && ((bi[3] & 0x8000) == 0))
{
eshup1 (bi);
goto done;
}
/* add 1 to exponent unless both are zero! */
for (j = 1; j < NI - 1; j++)
{
if (bi[j] != 0)
{
/* This could overflow, but let emovo take care of that. */
ltb += 1;
break;
}
}
bi[E] = (unsigned short) ltb;
goto done;
}
if (i > 0)
{ /* put the larger number in bi */
emovz (bi, ci);
emovz (ai, bi);
emovz (ci, ai);
}
}
if (ai[0] == bi[0])
{
eaddm (ai, bi);
subflg = 0;
}
else
{
esubm (ai, bi);
subflg = 1;
}
emdnorm (bi, lost, subflg, ltb, 64, ldp);
 
done:
emovo (bi, c, ldp);
}
 
 
 
/*
; Divide.
;
; unsigned short a[NE], b[NE], c[NE];
; LDPARMS *ldp;
; ediv( a, b, c, ldp ); c = b / a
*/
static void
ediv (_CONST short unsigned int *a, _CONST short unsigned int *b,
short unsigned int *c, LDPARMS * ldp)
{
unsigned short ai[NI], bi[NI];
int i;
long lt, lta, ltb;
 
#ifdef NANS
/* Return any NaN input. */
if (eisnan (a))
{
emov (a, c);
return;
}
if (eisnan (b))
{
emov (b, c);
return;
}
/* Zero over zero, or infinity over infinity, is a NaN. */
if (((ecmp (a, ezero) == 0) && (ecmp (b, ezero) == 0))
|| (eisinf (a) && eisinf (b)))
{
mtherr ("ediv", DOMAIN);
enan (c, NBITS);
return;
}
#endif
/* Infinity over anything else is infinity. */
#ifdef USE_INFINITY
if (eisinf (b))
{
if (eisneg (a) ^ eisneg (b))
*(c + (NE - 1)) = 0x8000;
else
*(c + (NE - 1)) = 0;
einfin (c, ldp);
return;
}
if (eisinf (a))
{
eclear (c);
return;
}
#endif
emovi (a, ai);
emovi (b, bi);
lta = ai[E];
ltb = bi[E];
if (bi[E] == 0)
{ /* See if numerator is zero. */
for (i = 1; i < NI - 1; i++)
{
if (bi[i] != 0)
{
ltb -= enormlz (bi);
goto dnzro1;
}
}
eclear (c);
return;
}
dnzro1:
 
if (ai[E] == 0)
{ /* possible divide by zero */
for (i = 1; i < NI - 1; i++)
{
if (ai[i] != 0)
{
lta -= enormlz (ai);
goto dnzro2;
}
}
if (ai[0] == bi[0])
*(c + (NE - 1)) = 0;
else
*(c + (NE - 1)) = 0x8000;
einfin (c, ldp);
mtherr ("ediv", SING);
return;
}
dnzro2:
 
i = edivm (ai, bi, ldp);
/* calculate exponent */
lt = ltb - lta + EXONE;
emdnorm (bi, i, 0, lt, 64, ldp);
/* set the sign */
if (ai[0] == bi[0])
bi[0] = 0;
else
bi[0] = 0Xffff;
emovo (bi, c, ldp);
}
 
 
 
/*
; Multiply.
;
; unsigned short a[NE], b[NE], c[NE];
; LDPARMS *ldp
; emul( a, b, c, ldp ); c = b * a
*/
static void
emul (_CONST short unsigned int *a, _CONST short unsigned int *b,
short unsigned int *c, LDPARMS * ldp)
{
unsigned short ai[NI], bi[NI];
int i, j;
long lt, lta, ltb;
 
#ifdef NANS
/* NaN times anything is the same NaN. */
if (eisnan (a))
{
emov (a, c);
return;
}
if (eisnan (b))
{
emov (b, c);
return;
}
/* Zero times infinity is a NaN. */
if ((eisinf (a) && (ecmp (b, ezero) == 0))
|| (eisinf (b) && (ecmp (a, ezero) == 0)))
{
mtherr ("emul", DOMAIN);
enan (c, NBITS);
return;
}
#endif
/* Infinity times anything else is infinity. */
#ifdef USE_INFINITY
if (eisinf (a) || eisinf (b))
{
if (eisneg (a) ^ eisneg (b))
*(c + (NE - 1)) = 0x8000;
else
*(c + (NE - 1)) = 0;
einfin (c, ldp);
return;
}
#endif
emovi (a, ai);
emovi (b, bi);
lta = ai[E];
ltb = bi[E];
if (ai[E] == 0)
{
for (i = 1; i < NI - 1; i++)
{
if (ai[i] != 0)
{
lta -= enormlz (ai);
goto mnzer1;
}
}
eclear (c);
return;
}
mnzer1:
 
if (bi[E] == 0)
{
for (i = 1; i < NI - 1; i++)
{
if (bi[i] != 0)
{
ltb -= enormlz (bi);
goto mnzer2;
}
}
eclear (c);
return;
}
mnzer2:
 
/* Multiply significands */
j = emulm (ai, bi, ldp);
/* calculate exponent */
lt = lta + ltb - (EXONE - 1);
emdnorm (bi, j, 0, lt, 64, ldp);
/* calculate sign of product */
if (ai[0] == bi[0])
bi[0] = 0;
else
bi[0] = 0xffff;
emovo (bi, c, ldp);
}
 
 
 
#if LDBL_MANT_DIG > 64
static void
e113toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
{
register unsigned short r;
unsigned short *e, *p;
unsigned short yy[NI];
int denorm, i;
 
e = pe;
denorm = 0;
ecleaz (yy);
#ifdef IBMPC
e += 7;
#endif
r = *e;
yy[0] = 0;
if (r & 0x8000)
yy[0] = 0xffff;
r &= 0x7fff;
#ifdef USE_INFINITY
if (r == 0x7fff)
{
#ifdef NANS
#ifdef IBMPC
for (i = 0; i < 7; i++)
{
if (pe[i] != 0)
{
enan (y, NBITS);
return;
}
}
#else /* !IBMPC */
for (i = 1; i < 8; i++)
{
if (pe[i] != 0)
{
enan (y, NBITS);
return;
}
}
#endif /* !IBMPC */
#endif /* NANS */
eclear (y);
einfin (y, ldp);
if (*e & 0x8000)
eneg (y);
return;
}
#endif /* INFINITY */
yy[E] = r;
p = &yy[M + 1];
#ifdef IBMPC
for (i = 0; i < 7; i++)
*p++ = *(--e);
#else /* IBMPC */
++e;
for (i = 0; i < 7; i++)
*p++ = *e++;
#endif /* IBMPC */
/* If denormal, remove the implied bit; else shift down 1. */
if (r == 0)
{
yy[M] = 0;
}
else
{
yy[M] = 1;
eshift (yy, -1);
}
emovo (yy, y, ldp);
}
 
/* move out internal format to ieee long double */
static void
toe113 (short unsigned int *a, short unsigned int *b)
{
register unsigned short *p, *q;
unsigned short i;
 
#ifdef NANS
if (eiisnan (a))
{
enan (b, 113);
return;
}
#endif
p = a;
#ifdef MIEEE
q = b;
#else
q = b + 7; /* point to output exponent */
#endif
 
/* If not denormal, delete the implied bit. */
if (a[E] != 0)
{
eshup1 (a);
}
/* combine sign and exponent */
i = *p++;
#ifdef MIEEE
if (i)
*q++ = *p++ | 0x8000;
else
*q++ = *p++;
#else
if (i)
*q-- = *p++ | 0x8000;
else
*q-- = *p++;
#endif
/* skip over guard word */
++p;
/* move the significand */
#ifdef MIEEE
for (i = 0; i < 7; i++)
*q++ = *p++;
#else
for (i = 0; i < 7; i++)
*q-- = *p++;
#endif
}
#endif /* LDBL_MANT_DIG > 64 */
 
 
#if LDBL_MANT_DIG == 64
static void
e64toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
{
unsigned short yy[NI];
unsigned short *p, *q, *e;
int i;
 
e = pe;
p = yy;
 
for (i = 0; i < NE - 5; i++)
*p++ = 0;
#ifdef IBMPC
for (i = 0; i < 5; i++)
*p++ = *e++;
#endif
#ifdef DEC
for (i = 0; i < 5; i++)
*p++ = *e++;
#endif
#ifdef MIEEE
p = &yy[0] + (NE - 1);
*p-- = *e++;
++e; /* MIEEE skips over 2nd short */
for (i = 0; i < 4; i++)
*p-- = *e++;
#endif
 
#ifdef IBMPC
/* For Intel long double, shift denormal significand up 1
-- but only if the top significand bit is zero. */
if ((yy[NE - 1] & 0x7fff) == 0 && (yy[NE - 2] & 0x8000) == 0)
{
unsigned short temp[NI + 1];
emovi (yy, temp);
eshup1 (temp);
emovo (temp, y, ldp);
return;
}
#endif
#ifdef USE_INFINITY
/* Point to the exponent field. */
p = &yy[NE - 1];
if ((*p & 0x7fff) == 0x7fff)
{
#ifdef NANS
#ifdef IBMPC
for (i = 0; i < 4; i++)
{
if ((i != 3 && pe[i] != 0)
/* Check for Intel long double infinity pattern. */
|| (i == 3 && pe[i] != 0x8000))
{
enan (y, NBITS);
return;
}
}
#endif
#ifdef MIEEE
for (i = 2; i <= 5; i++)
{
if (pe[i] != 0)
{
enan (y, NBITS);
return;
}
}
#endif
#endif /* NANS */
eclear (y);
einfin (y, ldp);
if (*p & 0x8000)
eneg (y);
return;
}
#endif /* USE_INFINITY */
p = yy;
q = y;
for (i = 0; i < NE; i++)
*q++ = *p++;
}
 
/* move out internal format to ieee long double */
static void
toe64 (short unsigned int *a, short unsigned int *b)
{
register unsigned short *p, *q;
unsigned short i;
 
#ifdef NANS
if (eiisnan (a))
{
enan (b, 64);
return;
}
#endif
#ifdef IBMPC
/* Shift Intel denormal significand down 1. */
if (a[E] == 0)
eshdn1 (a);
#endif
p = a;
#ifdef MIEEE
q = b;
#else
q = b + 4; /* point to output exponent */
/* NOTE: Intel data type is 96 bits wide, clear the last word here. */
*(q + 1) = 0;
#endif
 
/* combine sign and exponent */
i = *p++;
#ifdef MIEEE
if (i)
*q++ = *p++ | 0x8000;
else
*q++ = *p++;
*q++ = 0; /* leave 2nd short blank */
#else
if (i)
*q-- = *p++ | 0x8000;
else
*q-- = *p++;
#endif
/* skip over guard word */
++p;
/* move the significand */
#ifdef MIEEE
for (i = 0; i < 4; i++)
*q++ = *p++;
#else
#ifdef USE_INFINITY
#ifdef IBMPC
if (eiisinf (a))
{
/* Intel long double infinity. */
*q-- = 0x8000;
*q-- = 0;
*q-- = 0;
*q = 0;
return;
}
#endif /* IBMPC */
#endif /* USE_INFINITY */
for (i = 0; i < 4; i++)
*q-- = *p++;
#endif
}
 
#endif /* LDBL_MANT_DIG == 64 */
 
#if LDBL_MANT_DIG == 53
/*
; Convert IEEE double precision to e type
; double d;
; unsigned short x[N+2];
; e53toe( &d, x );
*/
static void
e53toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
{
#ifdef DEC
 
dectoe (pe, y); /* see etodec.c */
 
#else
 
register unsigned short r;
register unsigned short *p, *e;
unsigned short yy[NI];
int denorm, k;
 
e = pe;
denorm = 0; /* flag if denormalized number */
ecleaz (yy);
#ifdef IBMPC
e += 3;
#endif
#ifdef DEC
e += 3;
#endif
r = *e;
yy[0] = 0;
if (r & 0x8000)
yy[0] = 0xffff;
yy[M] = (r & 0x0f) | 0x10;
r &= ~0x800f; /* strip sign and 4 significand bits */
#ifdef USE_INFINITY
if (r == 0x7ff0)
{
#ifdef NANS
#ifdef IBMPC
if (((pe[3] & 0xf) != 0) || (pe[2] != 0)
|| (pe[1] != 0) || (pe[0] != 0))
{
enan (y, NBITS);
return;
}
#else /* !IBMPC */
if (((pe[0] & 0xf) != 0) || (pe[1] != 0)
|| (pe[2] != 0) || (pe[3] != 0))
{
enan (y, NBITS);
return;
}
#endif /* !IBMPC */
#endif /* NANS */
eclear (y);
einfin (y, ldp);
if (yy[0])
eneg (y);
return;
}
#endif
r >>= 4;
/* If zero exponent, then the significand is denormalized.
* So, take back the understood high significand bit. */
if (r == 0)
{
denorm = 1;
yy[M] &= ~0x10;
}
r += EXONE - 01777;
yy[E] = r;
p = &yy[M + 1];
#ifdef IBMPC
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
#else /* !IBMPC */
++e;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
#endif /* !IBMPC */
(void) eshift (yy, -5);
if (denorm)
{ /* if zero exponent, then normalize the significand */
if ((k = enormlz (yy)) > NBITS)
ecleazs (yy);
else
yy[E] -= (unsigned short) (k - 1);
}
emovo (yy, y, ldp);
#endif /* !DEC */
}
 
/*
; e type to IEEE double precision
; double d;
; unsigned short x[NE];
; etoe53( x, &d );
*/
 
#ifdef DEC
 
static void
etoe53 (x, e)
unsigned short *x, *e;
{
etodec (x, e); /* see etodec.c */
}
 
static void
toe53 (x, y)
unsigned short *x, *y;
{
todec (x, y);
}
 
#else
 
static void
toe53 (short unsigned int *x, short unsigned int *y)
{
unsigned short i;
unsigned short *p;
 
 
#ifdef NANS
if (eiisnan (x))
{
enan (y, 53);
return;
}
#endif
p = &x[0];
#ifdef IBMPC
y += 3;
#endif
#ifdef DEC
y += 3;
#endif
*y = 0; /* output high order */
if (*p++)
*y = 0x8000; /* output sign bit */
 
i = *p++;
if (i >= (unsigned int) 2047)
{ /* Saturate at largest number less than infinity. */
#ifdef USE_INFINITY
*y |= 0x7ff0;
#ifdef IBMPC
*(--y) = 0;
*(--y) = 0;
*(--y) = 0;
#else /* !IBMPC */
++y;
*y++ = 0;
*y++ = 0;
*y++ = 0;
#endif /* IBMPC */
#else /* !USE_INFINITY */
*y |= (unsigned short) 0x7fef;
#ifdef IBMPC
*(--y) = 0xffff;
*(--y) = 0xffff;
*(--y) = 0xffff;
#else /* !IBMPC */
++y;
*y++ = 0xffff;
*y++ = 0xffff;
*y++ = 0xffff;
#endif
#endif /* !USE_INFINITY */
return;
}
if (i == 0)
{
(void) eshift (x, 4);
}
else
{
i <<= 4;
(void) eshift (x, 5);
}
i |= *p++ & (unsigned short) 0x0f; /* *p = xi[M] */
*y |= (unsigned short) i; /* high order output already has sign bit set */
#ifdef IBMPC
*(--y) = *p++;
*(--y) = *p++;
*(--y) = *p;
#else /* !IBMPC */
++y;
*y++ = *p++;
*y++ = *p++;
*y++ = *p++;
#endif /* !IBMPC */
}
 
#endif /* not DEC */
#endif /* LDBL_MANT_DIG == 53 */
 
#if LDBL_MANT_DIG == 24
/*
; Convert IEEE single precision to e type
; float d;
; unsigned short x[N+2];
; dtox( &d, x );
*/
void
e24toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
{
register unsigned short r;
register unsigned short *p, *e;
unsigned short yy[NI];
int denorm, k;
 
e = pe;
denorm = 0; /* flag if denormalized number */
ecleaz (yy);
#ifdef IBMPC
e += 1;
#endif
#ifdef DEC
e += 1;
#endif
r = *e;
yy[0] = 0;
if (r & 0x8000)
yy[0] = 0xffff;
yy[M] = (r & 0x7f) | 0200;
r &= ~0x807f; /* strip sign and 7 significand bits */
#ifdef USE_INFINITY
if (r == 0x7f80)
{
#ifdef NANS
#ifdef MIEEE
if (((pe[0] & 0x7f) != 0) || (pe[1] != 0))
{
enan (y, NBITS);
return;
}
#else /* !MIEEE */
if (((pe[1] & 0x7f) != 0) || (pe[0] != 0))
{
enan (y, NBITS);
return;
}
#endif /* !MIEEE */
#endif /* NANS */
eclear (y);
einfin (y, ldp);
if (yy[0])
eneg (y);
return;
}
#endif
r >>= 7;
/* If zero exponent, then the significand is denormalized.
* So, take back the understood high significand bit. */
if (r == 0)
{
denorm = 1;
yy[M] &= ~0200;
}
r += EXONE - 0177;
yy[E] = r;
p = &yy[M + 1];
#ifdef IBMPC
*p++ = *(--e);
#endif
#ifdef DEC
*p++ = *(--e);
#endif
#ifdef MIEEE
++e;
*p++ = *e++;
#endif
(void) eshift (yy, -8);
if (denorm)
{ /* if zero exponent, then normalize the significand */
if ((k = enormlz (yy)) > NBITS)
ecleazs (yy);
else
yy[E] -= (unsigned short) (k - 1);
}
emovo (yy, y, ldp);
}
 
static void
toe24 (short unsigned int *x, short unsigned int *y)
{
unsigned short i;
unsigned short *p;
 
#ifdef NANS
if (eiisnan (x))
{
enan (y, 24);
return;
}
#endif
p = &x[0];
#ifdef IBMPC
y += 1;
#endif
#ifdef DEC
y += 1;
#endif
*y = 0; /* output high order */
if (*p++)
*y = 0x8000; /* output sign bit */
 
i = *p++;
if (i >= 255)
{ /* Saturate at largest number less than infinity. */
#ifdef USE_INFINITY
*y |= (unsigned short) 0x7f80;
#ifdef IBMPC
*(--y) = 0;
#endif
#ifdef DEC
*(--y) = 0;
#endif
#ifdef MIEEE
++y;
*y = 0;
#endif
#else /* !USE_INFINITY */
*y |= (unsigned short) 0x7f7f;
#ifdef IBMPC
*(--y) = 0xffff;
#endif
#ifdef DEC
*(--y) = 0xffff;
#endif
#ifdef MIEEE
++y;
*y = 0xffff;
#endif
#endif /* !USE_INFINITY */
return;
}
if (i == 0)
{
(void) eshift (x, 7);
}
else
{
i <<= 7;
(void) eshift (x, 8);
}
i |= *p++ & (unsigned short) 0x7f; /* *p = xi[M] */
*y |= i; /* high order output already has sign bit set */
#ifdef IBMPC
*(--y) = *p;
#endif
#ifdef DEC
*(--y) = *p;
#endif
#ifdef MIEEE
++y;
*y = *p;
#endif
}
#endif /* LDBL_MANT_DIG == 24 */
 
/* Compare two e type numbers.
*
* unsigned short a[NE], b[NE];
* ecmp( a, b );
*
* returns +1 if a > b
* 0 if a == b
* -1 if a < b
* -2 if either a or b is a NaN.
*/
static int
ecmp (_CONST short unsigned int *a, _CONST short unsigned int *b)
{
unsigned short ai[NI], bi[NI];
register unsigned short *p, *q;
register int i;
int msign;
 
#ifdef NANS
if (eisnan (a) || eisnan (b))
return (-2);
#endif
emovi (a, ai);
p = ai;
emovi (b, bi);
q = bi;
 
if (*p != *q)
{ /* the signs are different */
/* -0 equals + 0 */
for (i = 1; i < NI - 1; i++)
{
if (ai[i] != 0)
goto nzro;
if (bi[i] != 0)
goto nzro;
}
return (0);
nzro:
if (*p == 0)
return (1);
else
return (-1);
}
/* both are the same sign */
if (*p == 0)
msign = 1;
else
msign = -1;
i = NI - 1;
do
{
if (*p++ != *q++)
{
goto diff;
}
}
while (--i > 0);
 
return (0); /* equality */
 
 
 
diff:
 
if (*(--p) > *(--q))
return (msign); /* p is bigger */
else
return (-msign); /* p is littler */
}
 
 
/*
; Shift significand
;
; Shifts significand area up or down by the number of bits
; given by the variable sc.
*/
static int
eshift (short unsigned int *x, int sc)
{
unsigned short lost;
unsigned short *p;
 
if (sc == 0)
return (0);
 
lost = 0;
p = x + NI - 1;
 
if (sc < 0)
{
sc = -sc;
while (sc >= 16)
{
lost |= *p; /* remember lost bits */
eshdn6 (x);
sc -= 16;
}
 
while (sc >= 8)
{
lost |= *p & 0xff;
eshdn8 (x);
sc -= 8;
}
 
while (sc > 0)
{
lost |= *p & 1;
eshdn1 (x);
sc -= 1;
}
}
else
{
while (sc >= 16)
{
eshup6 (x);
sc -= 16;
}
 
while (sc >= 8)
{
eshup8 (x);
sc -= 8;
}
 
while (sc > 0)
{
eshup1 (x);
sc -= 1;
}
}
if (lost)
lost = 1;
return ((int) lost);
}
 
 
 
/*
; normalize
;
; Shift normalizes the significand area pointed to by argument
; shift count (up = positive) is returned.
*/
static int
enormlz (short unsigned int *x)
{
register unsigned short *p;
int sc;
 
sc = 0;
p = &x[M];
if (*p != 0)
goto normdn;
++p;
if (*p & 0x8000)
return (0); /* already normalized */
while (*p == 0)
{
eshup6 (x);
sc += 16;
/* With guard word, there are NBITS+16 bits available.
* return true if all are zero.
*/
if (sc > NBITS)
return (sc);
}
/* see if high byte is zero */
while ((*p & 0xff00) == 0)
{
eshup8 (x);
sc += 8;
}
/* now shift 1 bit at a time */
while ((*p & 0x8000) == 0)
{
eshup1 (x);
sc += 1;
if (sc > (NBITS + 16))
{
mtherr ("enormlz", UNDERFLOW);
return (sc);
}
}
return (sc);
 
/* Normalize by shifting down out of the high guard word
of the significand */
normdn:
 
if (*p & 0xff00)
{
eshdn8 (x);
sc -= 8;
}
while (*p != 0)
{
eshdn1 (x);
sc -= 1;
 
if (sc < -NBITS)
{
mtherr ("enormlz", OVERFLOW);
return (sc);
}
}
return (sc);
}
 
 
 
 
/* Convert e type number to decimal format ASCII string.
* The constants are for 64 bit precision.
*/
 
#define NTEN 12
#define MAXP 4096
 
#if NE == 10
static _CONST unsigned short etens[NTEN + 1][NE] = {
{0x6576, 0x4a92, 0x804a, 0x153f,
0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
{0x6a32, 0xce52, 0x329a, 0x28ce,
0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
{0x526c, 0x50ce, 0xf18b, 0x3d28,
0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
{0x9c66, 0x58f8, 0xbc50, 0x5c54,
0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
{0x851e, 0xeab7, 0x98fe, 0x901b,
0xddbb, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
{0x0235, 0x0137, 0x36b1, 0x336c,
0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
{0x50f8, 0x25fb, 0xc76b, 0x6b71,
0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
{0x0000, 0x0000, 0x0000, 0x0000,
0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
};
 
static _CONST unsigned short emtens[NTEN + 1][NE] = {
{0x2030, 0xcffc, 0xa1c3, 0x8123,
0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
{0x8264, 0xd2cb, 0xf2ea, 0x12d4,
0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */
{0xf53f, 0xf698, 0x6bd3, 0x0158,
0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
{0xe731, 0x04d4, 0xe3f2, 0xd332,
0x7132, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
{0xa23e, 0x5308, 0xfefb, 0x1155,
0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
{0xe26d, 0xdbde, 0xd05d, 0xb3f6,
0xac7c, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
{0x2a20, 0x6224, 0x47b3, 0x98d7,
0x3f23, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
{0x0b5b, 0x4af2, 0xa581, 0x18ed,
0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
{0xbf71, 0xa9b3, 0x7989, 0xbe68,
0x4c2e, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
{0x3d4d, 0x7c3d, 0x36ba, 0x0d2b,
0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
{0xc155, 0xa4a8, 0x404e, 0x6113,
0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
{0xd70a, 0x70a3, 0x0a3d, 0xa3d7,
0x3d70, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
{0xcccd, 0xcccc, 0xcccc, 0xcccc,
0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */
};
#else
static _CONST unsigned short etens[NTEN + 1][NE] = {
{0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
{0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
{0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
{0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
{0xddbc, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
{0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
{0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
{0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
{0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
{0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
{0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
{0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
{0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
};
 
static _CONST unsigned short emtens[NTEN + 1][NE] = {
{0x2de4, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
{0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */
{0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
{0x7133, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
{0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
{0xac7d, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
{0x3f24, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
{0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
{0x4c2f, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
{0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
{0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
{0x3d71, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
{0xcccd, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */
};
#endif
 
 
 
/* ASCII string outputs for unix */
 
 
#if 0
void
_IO_ldtostr (x, string, ndigs, flags, fmt)
long double *x;
char *string;
int ndigs;
int flags;
char fmt;
{
unsigned short w[NI];
char *t, *u;
LDPARMS rnd;
LDPARMS *ldp = &rnd;
 
rnd.rlast = -1;
rnd.rndprc = NBITS;
 
if (sizeof (long double) == 16)
e113toe ((unsigned short *) x, w, ldp);
else
e64toe ((unsigned short *) x, w, ldp);
 
etoasc (w, string, ndigs, -1, ldp);
if (ndigs == 0 && flags == 0)
{
/* Delete the decimal point unless alternate format. */
t = string;
while (*t != '.')
++t;
u = t + 1;
while (*t != '\0')
*t++ = *u++;
}
if (*string == ' ')
{
t = string;
u = t + 1;
while (*t != '\0')
*t++ = *u++;
}
if (fmt == 'E')
{
t = string;
while (*t != 'e')
++t;
*t = 'E';
}
}
 
#endif
 
/* This routine will not return more than NDEC+1 digits. */
 
char *
_ldtoa_r (struct _reent *ptr, long double d, int mode, int ndigits,
int *decpt, int *sign, char **rve)
{
unsigned short e[NI];
char *s, *p;
int i, j, k;
int orig_ndigits;
LDPARMS rnd;
LDPARMS *ldp = &rnd;
char *outstr;
char outbuf[NDEC + MAX_EXP_DIGITS + 10];
union uconv du;
du.d = d;
 
orig_ndigits = ndigits;
rnd.rlast = -1;
rnd.rndprc = NBITS;
 
_REENT_CHECK_MP (ptr);
 
/* reentrancy addition to use mprec storage pool */
if (_REENT_MP_RESULT (ptr))
{
_REENT_MP_RESULT (ptr)->_k = _REENT_MP_RESULT_K (ptr);
_REENT_MP_RESULT (ptr)->_maxwds = 1 << _REENT_MP_RESULT_K (ptr);
Bfree (ptr, _REENT_MP_RESULT (ptr));
_REENT_MP_RESULT (ptr) = 0;
}
 
#if LDBL_MANT_DIG == 24
e24toe (&du.pe, e, ldp);
#elif LDBL_MANT_DIG == 53
e53toe (&du.pe, e, ldp);
#elif LDBL_MANT_DIG == 64
e64toe (&du.pe, e, ldp);
#else
e113toe (&du.pe, e, ldp);
#endif
 
if (eisneg (e))
*sign = 1;
else
*sign = 0;
/* Mode 3 is "f" format. */
if (mode != 3)
ndigits -= 1;
/* Mode 0 is for %.999 format, which is supposed to give a
minimum length string that will convert back to the same binary value.
For now, just ask for 20 digits which is enough but sometimes too many. */
if (mode == 0)
ndigits = 20;
 
/* This sanity limit must agree with the corresponding one in etoasc, to
keep straight the returned value of outexpon. */
if (ndigits > NDEC)
ndigits = NDEC;
 
etoasc (e, outbuf, ndigits, mode, ldp);
s = outbuf;
if (eisinf (e) || eisnan (e))
{
*decpt = 9999;
goto stripspaces;
}
*decpt = ldp->outexpon + 1;
 
/* Transform the string returned by etoasc into what the caller wants. */
 
/* Look for decimal point and delete it from the string. */
s = outbuf;
while (*s != '\0')
{
if (*s == '.')
goto yesdecpt;
++s;
}
goto nodecpt;
 
yesdecpt:
 
/* Delete the decimal point. */
while (*s != '\0')
{
*s = *(s + 1);
++s;
}
 
nodecpt:
 
/* Back up over the exponent field. */
while (*s != 'E' && s > outbuf)
--s;
*s = '\0';
 
stripspaces:
 
/* Strip leading spaces and sign. */
p = outbuf;
while (*p == ' ' || *p == '-')
++p;
 
/* Find new end of string. */
s = outbuf;
while ((*s++ = *p++) != '\0')
;
--s;
 
/* Strip trailing zeros. */
if (mode == 2)
k = 1;
else if (ndigits > ldp->outexpon)
k = ndigits;
else
k = ldp->outexpon;
 
while (*(s - 1) == '0' && ((s - outbuf) > k))
*(--s) = '\0';
 
/* In f format, flush small off-scale values to zero.
Rounding has been taken care of by etoasc. */
if (mode == 3 && ((ndigits + ldp->outexpon) < 0))
{
s = outbuf;
*s = '\0';
*decpt = 0;
}
 
/* reentrancy addition to use mprec storage pool */
/* we want to have enough space to hold the formatted result */
 
if (mode == 3) /* f format, account for sign + dec digits + decpt + frac */
i = *decpt + orig_ndigits + 3;
else /* account for sign + max precision digs + E + exp sign + exponent */
i = orig_ndigits + MAX_EXP_DIGITS + 4;
 
j = sizeof (__ULong);
for (_REENT_MP_RESULT_K (ptr) = 0;
sizeof (_Bigint) - sizeof (__ULong) + j <= i; j <<= 1)
_REENT_MP_RESULT_K (ptr)++;
_REENT_MP_RESULT (ptr) = Balloc (ptr, _REENT_MP_RESULT_K (ptr));
 
/* Copy from internal temporary buffer to permanent buffer. */
outstr = (char *) _REENT_MP_RESULT (ptr);
strcpy (outstr, outbuf);
 
if (rve)
*rve = outstr + (s - outbuf);
 
return outstr;
}
 
/* Routine used to tell if long double is NaN or Infinity or regular number.
Returns: 0 = regular number
1 = Nan
2 = Infinity
*/
int
_ldcheck (long double *d)
{
unsigned short e[NI];
LDPARMS rnd;
LDPARMS *ldp = &rnd;
 
union uconv du;
 
rnd.rlast = -1;
rnd.rndprc = NBITS;
du.d = *d;
#if LDBL_MANT_DIG == 24
e24toe (&du.pe, e, ldp);
#elif LDBL_MANT_DIG == 53
e53toe (&du.pe, e, ldp);
#elif LDBL_MANT_DIG == 64
e64toe (&du.pe, e, ldp);
#else
e113toe (&du.pe, e, ldp);
#endif
 
if ((e[NE - 1] & 0x7fff) == 0x7fff)
{
#ifdef NANS
if (eisnan (e))
return (1);
#endif
return (2);
}
else
return (0);
} /* _ldcheck */
 
static void
etoasc (short unsigned int *x, char *string, int ndigits, int outformat,
LDPARMS * ldp)
{
long digit;
unsigned short y[NI], t[NI], u[NI], w[NI];
_CONST unsigned short *p, *r, *ten;
unsigned short sign;
int i, j, k, expon, rndsav, ndigs;
char *s, *ss;
unsigned short m;
unsigned short *equot = ldp->equot;
 
ndigs = ndigits;
rndsav = ldp->rndprc;
#ifdef NANS
if (eisnan (x))
{
sprintf (string, " NaN ");
expon = 9999;
goto bxit;
}
#endif
ldp->rndprc = NBITS; /* set to full precision */
emov (x, y); /* retain external format */
if (y[NE - 1] & 0x8000)
{
sign = 0xffff;
y[NE - 1] &= 0x7fff;
}
else
{
sign = 0;
}
expon = 0;
ten = &etens[NTEN][0];
emov (eone, t);
/* Test for zero exponent */
if (y[NE - 1] == 0)
{
for (k = 0; k < NE - 1; k++)
{
if (y[k] != 0)
goto tnzro; /* denormalized number */
}
goto isone; /* legal all zeros */
}
tnzro:
 
/* Test for infinity.
*/
if (y[NE - 1] == 0x7fff)
{
if (sign)
sprintf (string, " -Infinity ");
else
sprintf (string, " Infinity ");
expon = 9999;
goto bxit;
}
 
/* Test for exponent nonzero but significand denormalized.
* This is an error condition.
*/
if ((y[NE - 1] != 0) && ((y[NE - 2] & 0x8000) == 0))
{
mtherr ("etoasc", DOMAIN);
sprintf (string, "NaN");
expon = 9999;
goto bxit;
}
 
/* Compare to 1.0 */
i = ecmp (eone, y);
if (i == 0)
goto isone;
 
if (i < 0)
{ /* Number is greater than 1 */
/* Convert significand to an integer and strip trailing decimal zeros. */
emov (y, u);
u[NE - 1] = EXONE + NBITS - 1;
 
p = &etens[NTEN - 4][0];
m = 16;
do
{
ediv (p, u, t, ldp);
efloor (t, w, ldp);
for (j = 0; j < NE - 1; j++)
{
if (t[j] != w[j])
goto noint;
}
emov (t, u);
expon += (int) m;
noint:
p += NE;
m >>= 1;
}
while (m != 0);
 
/* Rescale from integer significand */
u[NE - 1] += y[NE - 1] - (unsigned int) (EXONE + NBITS - 1);
emov (u, y);
/* Find power of 10 */
emov (eone, t);
m = MAXP;
p = &etens[0][0];
while (ecmp (ten, u) <= 0)
{
if (ecmp (p, u) <= 0)
{
ediv (p, u, u, ldp);
emul (p, t, t, ldp);
expon += (int) m;
}
m >>= 1;
if (m == 0)
break;
p += NE;
}
}
else
{ /* Number is less than 1.0 */
/* Pad significand with trailing decimal zeros. */
if (y[NE - 1] == 0)
{
while ((y[NE - 2] & 0x8000) == 0)
{
emul (ten, y, y, ldp);
expon -= 1;
}
}
else
{
emovi (y, w);
for (i = 0; i < NDEC + 1; i++)
{
if ((w[NI - 1] & 0x7) != 0)
break;
/* multiply by 10 */
emovz (w, u);
eshdn1 (u);
eshdn1 (u);
eaddm (w, u);
u[1] += 3;
while (u[2] != 0)
{
eshdn1 (u);
u[1] += 1;
}
if (u[NI - 1] != 0)
break;
if (eone[NE - 1] <= u[1])
break;
emovz (u, w);
expon -= 1;
}
emovo (w, y, ldp);
}
k = -MAXP;
p = &emtens[0][0];
r = &etens[0][0];
emov (y, w);
emov (eone, t);
while (ecmp (eone, w) > 0)
{
if (ecmp (p, w) >= 0)
{
emul (r, w, w, ldp);
emul (r, t, t, ldp);
expon += k;
}
k /= 2;
if (k == 0)
break;
p += NE;
r += NE;
}
ediv (t, eone, t, ldp);
}
isone:
/* Find the first (leading) digit. */
emovi (t, w);
emovz (w, t);
emovi (y, w);
emovz (w, y);
eiremain (t, y, ldp);
digit = equot[NI - 1];
while ((digit == 0) && (ecmp (y, ezero) != 0))
{
eshup1 (y);
emovz (y, u);
eshup1 (u);
eshup1 (u);
eaddm (u, y);
eiremain (t, y, ldp);
digit = equot[NI - 1];
expon -= 1;
}
s = string;
if (sign)
*s++ = '-';
else
*s++ = ' ';
/* Examine number of digits requested by caller. */
if (outformat == 3)
ndigs += expon;
/*
else if( ndigs < 0 )
ndigs = 0;
*/
if (ndigs > NDEC)
ndigs = NDEC;
if (digit == 10)
{
*s++ = '1';
*s++ = '.';
if (ndigs > 0)
{
*s++ = '0';
ndigs -= 1;
}
expon += 1;
if (ndigs < 0)
{
ss = s;
goto doexp;
}
}
else
{
*s++ = (char) digit + '0';
*s++ = '.';
}
/* Generate digits after the decimal point. */
for (k = 0; k <= ndigs; k++)
{
/* multiply current number by 10, without normalizing */
eshup1 (y);
emovz (y, u);
eshup1 (u);
eshup1 (u);
eaddm (u, y);
eiremain (t, y, ldp);
*s++ = (char) equot[NI - 1] + '0';
}
digit = equot[NI - 1];
--s;
ss = s;
/* round off the ASCII string */
if (digit > 4)
{
/* Test for critical rounding case in ASCII output. */
if (digit == 5)
{
emovo (y, t, ldp);
if (ecmp (t, ezero) != 0)
goto roun; /* round to nearest */
if (ndigs < 0 || (*(s - 1 - (*(s - 1) == '.')) & 1) == 0)
goto doexp; /* round to even */
}
/* Round up and propagate carry-outs */
roun:
--s;
k = *s & 0x7f;
/* Carry out to most significant digit? */
if (ndigs < 0)
{
/* This will print like "1E-6". */
*s = '1';
expon += 1;
goto doexp;
}
else if (k == '.')
{
--s;
k = *s;
k += 1;
*s = (char) k;
/* Most significant digit carries to 10? */
if (k > '9')
{
expon += 1;
*s = '1';
}
goto doexp;
}
/* Round up and carry out from less significant digits */
k += 1;
*s = (char) k;
if (k > '9')
{
*s = '0';
goto roun;
}
}
doexp:
#ifdef __GO32__
if (expon >= 0)
sprintf (ss, "e+%02d", expon);
else
sprintf (ss, "e-%02d", -expon);
#else
sprintf (ss, "E%d", expon);
#endif
bxit:
ldp->rndprc = rndsav;
ldp->outexpon = expon;
}
 
 
#if 0 /* Broken, unusable implementation of strtold */
 
/*
; ASCTOQ
; ASCTOQ.MAC LATEST REV: 11 JAN 84
; SLM, 3 JAN 78
;
; Convert ASCII string to quadruple precision floating point
;
; Numeric input is free field decimal number
; with max of 15 digits with or without
; decimal point entered as ASCII from teletype.
; Entering E after the number followed by a second
; number causes the second number to be interpreted
; as a power of 10 to be multiplied by the first number
; (i.e., "scientific" notation).
;
; Usage:
; asctoq( string, q );
*/
 
long double
_strtold (char *s, char **se)
{
union uconv x;
LDPARMS rnd;
LDPARMS *ldp = &rnd;
int lenldstr;
 
rnd.rlast = -1;
rnd.rndprc = NBITS;
 
lenldstr = asctoeg (s, &x.pe, LDBL_MANT_DIG, ldp);
if (se)
*se = s + lenldstr;
return x.d;
}
 
#define REASONABLE_LEN 200
 
static int
asctoeg (char *ss, short unsigned int *y, int oprec, LDPARMS * ldp)
{
unsigned short yy[NI], xt[NI], tt[NI];
int esign, decflg, sgnflg, nexp, exp, prec, lost;
int k, trail, c, rndsav;
long lexp;
unsigned short nsign;
_CONST unsigned short *p;
char *sp, *s, *lstr;
int lenldstr;
int mflag = 0;
char tmpstr[REASONABLE_LEN];
 
/* Copy the input string. */
c = strlen (ss) + 2;
if (c <= REASONABLE_LEN)
lstr = tmpstr;
else
{
lstr = (char *) calloc (c, 1);
mflag = 1;
}
s = ss;
lenldstr = 0;
while (*s == ' ') /* skip leading spaces */
{
++s;
++lenldstr;
}
sp = lstr;
for (k = 0; k < c; k++)
{
if ((*sp++ = *s++) == '\0')
break;
}
*sp = '\0';
s = lstr;
 
rndsav = ldp->rndprc;
ldp->rndprc = NBITS; /* Set to full precision */
lost = 0;
nsign = 0;
decflg = 0;
sgnflg = 0;
nexp = 0;
exp = 0;
prec = 0;
ecleaz (yy);
trail = 0;
 
nxtcom:
k = *s - '0';
if ((k >= 0) && (k <= 9))
{
/* Ignore leading zeros */
if ((prec == 0) && (decflg == 0) && (k == 0))
goto donchr;
/* Identify and strip trailing zeros after the decimal point. */
if ((trail == 0) && (decflg != 0))
{
sp = s;
while ((*sp >= '0') && (*sp <= '9'))
++sp;
/* Check for syntax error */
c = *sp & 0x7f;
if ((c != 'e') && (c != 'E') && (c != '\0')
&& (c != '\n') && (c != '\r') && (c != ' ') && (c != ','))
goto error;
--sp;
while (*sp == '0')
*sp-- = 'z';
trail = 1;
if (*s == 'z')
goto donchr;
}
/* If enough digits were given to more than fill up the yy register,
* continuing until overflow into the high guard word yy[2]
* guarantees that there will be a roundoff bit at the top
* of the low guard word after normalization.
*/
if (yy[2] == 0)
{
if (decflg)
nexp += 1; /* count digits after decimal point */
eshup1 (yy); /* multiply current number by 10 */
emovz (yy, xt);
eshup1 (xt);
eshup1 (xt);
eaddm (xt, yy);
ecleaz (xt);
xt[NI - 2] = (unsigned short) k;
eaddm (xt, yy);
}
else
{
/* Mark any lost non-zero digit. */
lost |= k;
/* Count lost digits before the decimal point. */
if (decflg == 0)
nexp -= 1;
}
prec += 1;
goto donchr;
}
 
switch (*s)
{
case 'z':
break;
case 'E':
case 'e':
goto expnt;
case '.': /* decimal point */
if (decflg)
goto error;
++decflg;
break;
case '-':
nsign = 0xffff;
if (sgnflg)
goto error;
++sgnflg;
break;
case '+':
if (sgnflg)
goto error;
++sgnflg;
break;
case ',':
case ' ':
case '\0':
case '\n':
case '\r':
goto daldone;
case 'i':
case 'I':
goto infinite;
default:
error:
#ifdef NANS
enan (yy, NI * 16);
#else
mtherr ("asctoe", DOMAIN);
ecleaz (yy);
#endif
goto aexit;
}
donchr:
++s;
goto nxtcom;
 
/* Exponent interpretation */
expnt:
 
esign = 1;
exp = 0;
++s;
/* check for + or - */
if (*s == '-')
{
esign = -1;
++s;
}
if (*s == '+')
++s;
while ((*s >= '0') && (*s <= '9'))
{
exp *= 10;
exp += *s++ - '0';
if (exp > 4977)
{
if (esign < 0)
goto zero;
else
goto infinite;
}
}
if (esign < 0)
exp = -exp;
if (exp > 4932)
{
infinite:
ecleaz (yy);
yy[E] = 0x7fff; /* infinity */
goto aexit;
}
if (exp < -4977)
{
zero:
ecleaz (yy);
goto aexit;
}
 
daldone:
nexp = exp - nexp;
/* Pad trailing zeros to minimize power of 10, per IEEE spec. */
while ((nexp > 0) && (yy[2] == 0))
{
emovz (yy, xt);
eshup1 (xt);
eshup1 (xt);
eaddm (yy, xt);
eshup1 (xt);
if (xt[2] != 0)
break;
nexp -= 1;
emovz (xt, yy);
}
if ((k = enormlz (yy)) > NBITS)
{
ecleaz (yy);
goto aexit;
}
lexp = (EXONE - 1 + NBITS) - k;
emdnorm (yy, lost, 0, lexp, 64, ldp);
/* convert to external format */
 
 
/* Multiply by 10**nexp. If precision is 64 bits,
* the maximum relative error incurred in forming 10**n
* for 0 <= n <= 324 is 8.2e-20, at 10**180.
* For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947.
* For 0 >= n >= -999, it is -1.55e-19 at 10**-435.
*/
lexp = yy[E];
if (nexp == 0)
{
k = 0;
goto expdon;
}
esign = 1;
if (nexp < 0)
{
nexp = -nexp;
esign = -1;
if (nexp > 4096)
{ /* Punt. Can't handle this without 2 divides. */
emovi (etens[0], tt);
lexp -= tt[E];
k = edivm (tt, yy, ldp);
lexp += EXONE;
nexp -= 4096;
}
}
p = &etens[NTEN][0];
emov (eone, xt);
exp = 1;
do
{
if (exp & nexp)
emul (p, xt, xt, ldp);
p -= NE;
exp = exp + exp;
}
while (exp <= MAXP);
 
emovi (xt, tt);
if (esign < 0)
{
lexp -= tt[E];
k = edivm (tt, yy, ldp);
lexp += EXONE;
}
else
{
lexp += tt[E];
k = emulm (tt, yy, ldp);
lexp -= EXONE - 1;
}
 
expdon:
 
/* Round and convert directly to the destination type */
if (oprec == 53)
lexp -= EXONE - 0x3ff;
else if (oprec == 24)
lexp -= EXONE - 0177;
#ifdef DEC
else if (oprec == 56)
lexp -= EXONE - 0201;
#endif
ldp->rndprc = oprec;
emdnorm (yy, k, 0, lexp, 64, ldp);
 
aexit:
 
ldp->rndprc = rndsav;
yy[0] = nsign;
switch (oprec)
{
#ifdef DEC
case 56:
todec (yy, y); /* see etodec.c */
break;
#endif
#if LDBL_MANT_DIG == 53
case 53:
toe53 (yy, y);
break;
#elif LDBL_MANT_DIG == 24
case 24:
toe24 (yy, y);
break;
#elif LDBL_MANT_DIG == 64
case 64:
toe64 (yy, y);
break;
#elif LDBL_MANT_DIG == 113
case 113:
toe113 (yy, y);
break;
#else
case NBITS:
emovo (yy, y, ldp);
break;
#endif
}
lenldstr += s - lstr;
if (mflag)
free (lstr);
return lenldstr;
}
 
#endif
 
/* y = largest integer not greater than x
* (truncated toward minus infinity)
*
* unsigned short x[NE], y[NE]
* LDPARMS *ldp
*
* efloor( x, y, ldp );
*/
static _CONST unsigned short bmask[] = {
0xffff,
0xfffe,
0xfffc,
0xfff8,
0xfff0,
0xffe0,
0xffc0,
0xff80,
0xff00,
0xfe00,
0xfc00,
0xf800,
0xf000,
0xe000,
0xc000,
0x8000,
0x0000,
};
 
static void
efloor (short unsigned int *x, short unsigned int *y, LDPARMS * ldp)
{
register unsigned short *p;
int e, expon, i;
unsigned short f[NE];
 
emov (x, f); /* leave in external format */
expon = (int) f[NE - 1];
e = (expon & 0x7fff) - (EXONE - 1);
if (e <= 0)
{
eclear (y);
goto isitneg;
}
/* number of bits to clear out */
e = NBITS - e;
emov (f, y);
if (e <= 0)
return;
 
p = &y[0];
while (e >= 16)
{
*p++ = 0;
e -= 16;
}
/* clear the remaining bits */
*p &= bmask[e];
/* truncate negatives toward minus infinity */
isitneg:
 
if ((unsigned short) expon & (unsigned short) 0x8000)
{
for (i = 0; i < NE - 1; i++)
{
if (f[i] != y[i])
{
esub (eone, y, y, ldp);
break;
}
}
}
}
 
 
 
static void
eiremain (short unsigned int *den, short unsigned int *num, LDPARMS * ldp)
{
long ld, ln;
unsigned short j;
unsigned short *equot = ldp->equot;
 
ld = den[E];
ld -= enormlz (den);
ln = num[E];
ln -= enormlz (num);
ecleaz (equot);
while (ln >= ld)
{
if (ecmpm (den, num) <= 0)
{
esubm (den, num);
j = 1;
}
else
{
j = 0;
}
eshup1 (equot);
equot[NI - 1] |= j;
eshup1 (num);
ln -= 1;
}
emdnorm (num, 0, 0, ln, 0, ldp);
}
 
/* NaN bit patterns
*/
#ifdef MIEEE
#if !defined(__mips)
static _CONST unsigned short nan113[8] = {
0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
};
 
static _CONST unsigned short nan64[6] = {
0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
};
static _CONST unsigned short nan53[4] = { 0x7fff, 0xffff, 0xffff, 0xffff };
static _CONST unsigned short nan24[2] = { 0x7fff, 0xffff };
#elif defined(__mips_nan2008) /* __mips */
static _CONST unsigned short nan113[8] = { 0x7fff, 0x8000, 0, 0, 0, 0, 0, 0 };
static _CONST unsigned short nan64[6] = { 0x7fff, 0xc000, 0, 0, 0, 0 };
static _CONST unsigned short nan53[4] = { 0x7ff8, 0, 0, 0 };
static _CONST unsigned short nan24[2] = { 0x7fc0, 0 };
#else /* __mips && !__mips_nan2008 */
static _CONST unsigned short nan113[8] = {
0x7fff, 0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
};
 
static _CONST unsigned short nan64[6] = {
0x7fff, 0xbfff, 0xffff, 0xffff, 0xffff, 0xffff
};
static _CONST unsigned short nan53[4] = { 0x7ff7, 0xffff, 0xffff, 0xffff };
static _CONST unsigned short nan24[2] = { 0x7fbf, 0xffff };
#endif /* __mips && !__mips_nan2008 */
#else /* !MIEEE */
#if !defined(__mips) || defined(__mips_nan2008)
static _CONST unsigned short nan113[8] = { 0, 0, 0, 0, 0, 0, 0x8000, 0x7fff };
static _CONST unsigned short nan64[6] = { 0, 0, 0, 0, 0xc000, 0x7fff };
static _CONST unsigned short nan53[4] = { 0, 0, 0, 0x7ff8 };
static _CONST unsigned short nan24[2] = { 0, 0x7fc0 };
#else /* __mips && !__mips_nan2008 */
static _CONST unsigned short nan113[8] = {
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x7fff, 0x7fff
};
 
static _CONST unsigned short nan64[6] = {
0xffff, 0xffff, 0xffff, 0xffff, 0xbfff, 0x7fff
};
static _CONST unsigned short nan53[4] = { 0xffff, 0xffff, 0xffff, 0x7ff7 };
static _CONST unsigned short nan24[2] = { 0xffff, 0x7fbf };
#endif /* __mips && !__mips_nan2008 */
#endif /* !MIEEE */
 
 
static void
enan (short unsigned int *nan, int size)
{
int i, n;
_CONST unsigned short *p;
 
switch (size)
{
#ifndef DEC
case 113:
n = 8;
p = nan113;
break;
 
case 64:
n = 6;
p = nan64;
break;
 
case 53:
n = 4;
p = nan53;
break;
 
case 24:
n = 2;
p = nan24;
break;
 
case NBITS:
#if !defined(__mips) || defined(__mips_nan2008)
for (i = 0; i < NE - 2; i++)
*nan++ = 0;
*nan++ = 0xc000;
#else /* __mips && !__mips_nan2008 */
for (i = 0; i < NE - 2; i++)
*nan++ = 0xffff;
*nan++ = 0xbfff;
#endif /* __mips && !__mips_nan2008 */
*nan++ = 0x7fff;
return;
 
case NI * 16:
*nan++ = 0;
*nan++ = 0x7fff;
*nan++ = 0;
#if !defined(__mips) || defined(__mips_nan2008)
*nan++ = 0xc000;
for (i = 4; i < NI - 1; i++)
*nan++ = 0;
#else /* __mips && !__mips_nan2008 */
*nan++ = 0xbfff;
for (i = 4; i < NI - 1; i++)
*nan++ = 0xffff;
#endif /* __mips && !__mips_nan2008 */
*nan++ = 0;
return;
#endif
default:
mtherr ("enan", DOMAIN);
return;
}
for (i = 0; i < n; i++)
*nan++ = *p++;
}
/contrib/sdk/sources/newlib/libc/stdlib/mblen.c
0,0 → 1,81
/*
FUNCTION
<<mblen>>---minimal multibyte length function
 
INDEX
mblen
 
ANSI_SYNOPSIS
#include <stdlib.h>
int mblen(const char *<[s]>, size_t <[n]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
int mblen(<[s]>, <[n]>)
const char *<[s]>;
size_t <[n]>;
 
DESCRIPTION
When _MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<mblen>>. In this case, the
only ``multi-byte character sequences'' recognized are single bytes,
and thus <<1>> is returned unless <[s]> is the null pointer or
has a length of 0 or is the empty string.
 
When _MB_CAPABLE is defined, this routine calls <<_mbtowc_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
 
RETURNS
This implementation of <<mblen>> returns <<0>> if
<[s]> is <<NULL>> or the empty string; it returns <<1>> if not _MB_CAPABLE or
the character is a single-byte character; it returns <<-1>>
if the multi-byte character is invalid; otherwise it returns
the number of bytes in the multibyte character.
 
PORTABILITY
<<mblen>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
 
<<mblen>> requires no supporting OS subroutines.
*/
 
#ifndef _REENT_ONLY
 
#include <newlib.h>
#include <stdlib.h>
#include <wchar.h>
#include "local.h"
 
int
_DEFUN (mblen, (s, n),
const char *s _AND
size_t n)
{
#ifdef _MB_CAPABLE
int retval = 0;
struct _reent *reent = _REENT;
mbstate_t *state;
_REENT_CHECK_MISC(reent);
state = &(_REENT_MBLEN_STATE(reent));
retval = __mbtowc (reent, NULL, s, n, __locale_charset (), state);
if (retval < 0)
{
state->__count = 0;
return -1;
}
else
return retval;
#else /* not _MB_CAPABLE */
if (s == NULL || *s == '\0')
return 0;
if (n == 0)
return -1;
return 1;
#endif /* not _MB_CAPABLE */
}
 
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdlib/mblen_r.c
0,0 → 1,77
/*
FUNCTION
<<_mblen_r>>---reentrant minimal multibyte length function
 
INDEX
_mblen_r
 
ANSI_SYNOPSIS
#include <stdlib.h>
int _mblen_r(struct _reent *<[r]>, const char *<[s]>, size_t <[n]>, int *<[state]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
int _mblen_r(<[r]>, <[s]>, <[n]>, <[state]>)
struct _reent *<[r]>;
const char *<[s]>;
size_t <[n]>;
int *<[state]>;
 
DESCRIPTION
When _MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<_mblen_r>>. In this case, the
only ``multi-byte character sequences'' recognized are single bytes,
and thus <<1>> is returned unless <[s]> is the null pointer or
has a length of 0 or is the empty string.
 
When _MB_CAPABLE is defined, this routine calls <<_mbtowc_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
 
RETURNS
This implementation of <<_mblen_r>> returns <<0>> if
<[s]> is <<NULL>> or the empty string; it returns <<1>> if not _MB_CAPABLE or
the character is a single-byte character; it returns <<-1>>
if the multi-byte character is invalid; otherwise it returns
the number of bytes in the multibyte character.
 
PORTABILITY
<<_mblen>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
 
<<_mblen_r>> requires no supporting OS subroutines.
*/
 
#include <newlib.h>
#include <stdlib.h>
#include <wchar.h>
#include "local.h"
 
int
_DEFUN (_mblen_r, (r, s, n, state),
struct _reent *r _AND
const char *s _AND
size_t n _AND
mbstate_t *state)
{
#ifdef _MB_CAPABLE
int retval;
retval = __mbtowc (r, NULL, s, n, __locale_charset (), state);
 
if (retval < 0)
{
state->__count = 0;
return -1;
}
 
return retval;
#else /* not _MB_CAPABLE */
if (s == NULL || *s == '\0')
return 0;
if (n == 0)
return -1;
return 1;
#endif /* not _MB_CAPABLE */
}
 
/contrib/sdk/sources/newlib/libc/stdlib/mbrlen.c
0,0 → 1,22
#include <reent.h>
#include <newlib.h>
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
 
size_t
mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps)
{
#ifdef _MB_CAPABLE
if (ps == NULL)
{
struct _reent *reent = _REENT;
 
_REENT_CHECK_MISC(reent);
ps = &(_REENT_MBRLEN_STATE(reent));
}
#endif
 
return mbrtowc(NULL, s, n, ps);
}
/contrib/sdk/sources/newlib/libc/stdlib/mbsinit.c
0,0 → 1,14
#include <reent.h>
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
 
int
mbsinit(const mbstate_t *ps)
{
if (ps == NULL || ps->__count == 0)
return 1;
else
return 0;
}
/contrib/sdk/sources/newlib/libc/stdlib/mbsnrtowcs.c
0,0 → 1,182
/*
FUNCTION
<<mbsrtowcs>>, <<mbsnrtowcs>>---convert a character string to a wide-character string
 
INDEX
mbsrtowcs
INDEX
_mbsrtowcs_r
INDEX
mbsnrtowcs
INDEX
_mbsnrtowcs_r
 
ANSI_SYNOPSIS
#include <wchar.h>
size_t mbsrtowcs(wchar_t *__restrict <[dst]>,
const char **__restrict <[src]>,
size_t <[len]>,
mbstate_t *__restrict <[ps]>);
 
#include <wchar.h>
size_t _mbsrtowcs_r(struct _reent *<[ptr]>, wchar_t *<[dst]>,
const char **<[src]>, size_t <[len]>,
mbstate_t *<[ps]>);
 
#include <wchar.h>
size_t mbsnrtowcs(wchar_t *__ restrict <[dst]>,
const char **__restrict <[src]>, size_t <[nms]>,
size_t <[len]>, mbstate_t *__restrict <[ps]>);
 
#include <wchar.h>
size_t _mbsnrtowcs_r(struct _reent *<[ptr]>, wchar_t *<[dst]>,
const char **<[src]>, size_t <[nms]>,
size_t <[len]>, mbstate_t *<[ps]>);
 
TRAD_SYNOPSIS
#include <wchar.h>
size_t mbsrtowcs(<[dst]>, <[src]>, <[len]>, <[ps]>)
wchar_t *__restrict <[dst]>;
const char **__restrict <[src]>;
size_t <[len]>;
mbstate_t *__restrict <[ps]>;
 
#include <wchar.h>
size_t _mbsrtowcs_r(<[ptr]>, <[dst]>, <[src]>, <[len]>, <[ps]>)
struct _reent *<[ptr]>;
wchar_t *<[dst]>;
const char **<[src]>;
size_t <[len]>;
mbstate_t *<[ps]>;
 
#include <wchar.h>
size_t mbsnrtowcs(<[dst]>, <[src]>, <[nms]>, <[len]>, <[ps]>)
wchar_t *__restrict <[dst]>;
const char **__restrict <[src]>;
size_t <[nms]>;
size_t <[len]>;
mbstate_t *__restrict <[ps]>;
 
#include <wchar.h>
size_t _mbsnrtowcs_r(<[ptr]>, <[dst]>, <[src]>, <[nms]>, <[len]>, <[ps]>)
struct _reent *<[ptr]>;
wchar_t *<[dst]>;
const char **<[src]>;
size_t <[nms]>;
size_t <[len]>;
mbstate_t *<[ps]>;
 
DESCRIPTION
The <<mbsrtowcs>> function converts a sequence of multibyte characters
pointed to indirectly by <[src]> into a sequence of corresponding wide
characters and stores at most <[len]> of them in the wchar_t array pointed
to by <[dst]>, until it encounters a terminating null character ('\0').
 
If <[dst]> is NULL, no characters are stored.
 
If <[dst]> is not NULL, the pointer pointed to by <[src]> is updated to point
to the character after the one that conversion stopped at. If conversion
stops because a null character is encountered, *<[src]> is set to NULL.
 
The mbstate_t argument, <[ps]>, is used to keep track of the shift state. If
it is NULL, <<mbsrtowcs>> uses an internal, static mbstate_t object, which
is initialized to the initial conversion state at program startup.
 
The <<mbsnrtowcs>> function behaves identically to <<mbsrtowcs>>, except that
conversion stops after reading at most <[nms]> bytes from the buffer pointed
to by <[src]>.
 
RETURNS
The <<mbsrtowcs>> and <<mbsnrtowcs>> functions return the number of wide
characters stored in the array pointed to by <[dst]> if successful, otherwise
it returns (size_t)-1.
 
PORTABILITY
<<mbsrtowcs>> is defined by the C99 standard.
<<mbsnrtowcs>> is defined by the POSIX.1-2008 standard.
*/
 
#include <reent.h>
#include <newlib.h>
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
 
size_t
_DEFUN (_mbsnrtowcs_r, (r, dst, src, nms, len, ps),
struct _reent *r _AND
wchar_t *dst _AND
const char **src _AND
size_t nms _AND
size_t len _AND
mbstate_t *ps)
{
wchar_t *ptr = dst;
const char *tmp_src;
size_t max;
size_t count = 0;
int bytes;
 
#ifdef _MB_CAPABLE
if (ps == NULL)
{
_REENT_CHECK_MISC(r);
ps = &(_REENT_MBSRTOWCS_STATE(r));
}
#endif
 
if (dst == NULL)
{
/* Ignore original len value and do not alter src pointer if the
dst pointer is NULL. */
len = (size_t)-1;
tmp_src = *src;
src = &tmp_src;
}
max = len;
while (len > 0)
{
bytes = _mbrtowc_r (r, ptr, *src, nms, ps);
if (bytes > 0)
{
*src += bytes;
nms -= bytes;
++count;
ptr = (dst == NULL) ? NULL : ptr + 1;
--len;
}
else if (bytes == -2)
{
*src += nms;
return count;
}
else if (bytes == 0)
{
*src = NULL;
return count;
}
else
{
ps->__count = 0;
r->_errno = EILSEQ;
return (size_t)-1;
}
}
 
return (size_t)max;
}
 
#ifndef _REENT_ONLY
size_t
_DEFUN (mbsnrtowcs, (dst, src, nms, len, ps),
wchar_t *__restrict dst _AND
const char **__restrict src _AND
size_t nms _AND
size_t len _AND
mbstate_t *__restrict ps)
{
return _mbsnrtowcs_r (_REENT, dst, src, nms, len, ps);
}
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdlib/mbsrtowcs.c
0,0 → 1,31
/* doc in mbsnrtowcs.c */
 
#include <reent.h>
#include <newlib.h>
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
 
size_t
_DEFUN (_mbsrtowcs_r, (r, dst, src, len, ps),
struct _reent *r _AND
wchar_t *dst _AND
const char **src _AND
size_t len _AND
mbstate_t *ps)
{
return _mbsnrtowcs_r (r, dst, src, (size_t) -1, len, ps);
}
 
#ifndef _REENT_ONLY
size_t
_DEFUN (mbsrtowcs, (dst, src, len, ps),
wchar_t *__restrict dst _AND
const char **__restrict src _AND
size_t len _AND
mbstate_t *__restrict ps)
{
return _mbsnrtowcs_r (_REENT, dst, src, (size_t) -1, len, ps);
}
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdlib/mbstowcs.c
0,0 → 1,83
/*
FUNCTION
<<mbstowcs>>---minimal multibyte string to wide char converter
 
INDEX
mbstowcs
 
ANSI_SYNOPSIS
#include <stdlib.h>
int mbstowcs(wchar_t *restrict <[pwc]>, const char *restrict <[s]>, size_t <[n]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
int mbstowcs(<[pwc]>, <[s]>, <[n]>)
wchar_t *<[pwc]>;
const char *<[s]>;
size_t <[n]>;
 
DESCRIPTION
When _MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<mbstowcs>>. In this case, the
only ``multi-byte character sequences'' recognized are single bytes,
and they are ``converted'' to wide-char versions simply by byte
extension.
 
When _MB_CAPABLE is defined, this routine calls <<_mbstowcs_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
 
RETURNS
This implementation of <<mbstowcs>> returns <<0>> if
<[s]> is <<NULL>> or is the empty string;
it returns <<-1>> if _MB_CAPABLE and one of the
multi-byte characters is invalid or incomplete;
otherwise it returns the minimum of: <<n>> or the
number of multi-byte characters in <<s>> plus 1 (to
compensate for the nul character).
If the return value is -1, the state of the <<pwc>> string is
indeterminate. If the input has a length of 0, the output
string will be modified to contain a wchar_t nul terminator.
 
PORTABILITY
<<mbstowcs>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
 
<<mbstowcs>> requires no supporting OS subroutines.
*/
 
#ifndef _REENT_ONLY
 
#include <newlib.h>
#include <stdlib.h>
#include <wchar.h>
 
size_t
_DEFUN (mbstowcs, (pwcs, s, n),
wchar_t *__restrict pwcs _AND
const char *__restrict s _AND
size_t n)
{
#ifdef _MB_CAPABLE
mbstate_t state;
state.__count = 0;
return _mbstowcs_r (_REENT, pwcs, s, n, &state);
#else /* not _MB_CAPABLE */
int count = 0;
if (n != 0) {
do {
if ((*pwcs++ = (wchar_t) *s++) == 0)
break;
count++;
} while (--n != 0);
}
return count;
#endif /* not _MB_CAPABLE */
}
 
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdlib/mbstowcs_r.c
0,0 → 1,38
#include <stdlib.h>
#include <wchar.h>
#include "local.h"
 
size_t
_DEFUN (_mbstowcs_r, (reent, pwcs, s, n, state),
struct _reent *r _AND
wchar_t *__restrict pwcs _AND
const char *__restrict s _AND
size_t n _AND
mbstate_t *state)
{
size_t ret = 0;
char *t = (char *)s;
int bytes;
 
if (!pwcs)
n = (size_t) 1; /* Value doesn't matter as long as it's not 0. */
while (n > 0)
{
bytes = __mbtowc (r, pwcs, t, MB_CUR_MAX, __locale_charset (), state);
if (bytes < 0)
{
state->__count = 0;
return -1;
}
else if (bytes == 0)
break;
t += bytes;
++ret;
if (pwcs)
{
++pwcs;
--n;
}
}
return ret;
}
/contrib/sdk/sources/newlib/libc/stdlib/random.c
0,0 → 1,82
/*
FUNCTION
<<random>>, <<srandom>>---pseudo-random numbers
 
INDEX
random
INDEX
srandom
 
ANSI_SYNOPSIS
#define _XOPEN_SOURCE 500
#include <stdlib.h>
long int random(void);
void srandom(unsigned int <[seed]>);
 
 
 
DESCRIPTION
<<random>> returns a different integer each time it is called; each
integer is chosen by an algorithm designed to be unpredictable, so
that you can use <<random>> when you require a random number.
The algorithm depends on a static variable called the ``random seed'';
starting with a given value of the random seed always produces the
same sequence of numbers in successive calls to <<random>>.
 
You can set the random seed using <<srandom>>; it does nothing beyond
storing its argument in the static variable used by <<rand>>. You can
exploit this to make the pseudo-random sequence less predictable, if
you wish, by using some other unpredictable value (often the least
significant parts of a time-varying value) as the random seed before
beginning a sequence of calls to <<rand>>; or, if you wish to ensure
(for example, while debugging) that successive runs of your program
use the same ``random'' numbers, you can use <<srandom>> to set the same
random seed at the outset.
 
RETURNS
<<random>> returns the next pseudo-random integer in sequence; it is a
number between <<0>> and <<RAND_MAX>> (inclusive).
 
<<srandom>> does not return a result.
 
NOTES
<<random>> and <<srandom>> are unsafe for multi-threaded applications.
 
_XOPEN_SOURCE may be any value >= 500.
 
PORTABILITY
<<random>> is required by XSI. This implementation uses the same
algorithm as <<rand>>.
 
<<random>> requires no supporting OS subroutines.
*/
 
#ifndef _REENT_ONLY
 
#include <stdlib.h>
#include <reent.h>
 
void
_DEFUN (srandom, (seed), unsigned int seed)
{
struct _reent *reent = _REENT;
 
_REENT_CHECK_RAND48(reent);
_REENT_RAND_NEXT(reent) = seed;
}
 
long int
_DEFUN_VOID (random)
{
struct _reent *reent = _REENT;
 
/* This multiplier was obtained from Knuth, D.E., "The Art of
Computer Programming," Vol 2, Seminumerical Algorithms, Third
Edition, Addison-Wesley, 1998, p. 106 (line 26) & p. 108 */
_REENT_CHECK_RAND48(reent);
_REENT_RAND_NEXT(reent) =
_REENT_RAND_NEXT(reent) * __extension__ 6364136223846793005LL + 1;
return (long int)((_REENT_RAND_NEXT(reent) >> 32) & RAND_MAX);
}
 
#endif /* _REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdlib/wcsnrtombs.c
0,0 → 1,188
/*
FUNCTION
<<wcsrtombs>>, <<wcsnrtombs>>---convert a wide-character string to a character string
 
INDEX
wcsrtombs
INDEX
_wcsrtombs_r
INDEX
wcsnrtombs
INDEX
_wcsnrtombs_r
 
ANSI_SYNOPSIS
#include <wchar.h>
size_t wcsrtombs(char *__restrict <[dst]>,
const wchar_t **__restrict <[src]>, size_t <[len]>,
mbstate_t *__restrict <[ps]>);
 
#include <wchar.h>
size_t _wcsrtombs_r(struct _reent *<[ptr]>, char *<[dst]>,
const wchar_t **<[src]>, size_t <[len]>,
mbstate_t *<[ps]>);
 
#include <wchar.h>
size_t wcsnrtombs(char *__restrict <[dst]>,
const wchar_t **__restrict <[src]>,
size_t <[nwc]>, size_t <[len]>,
mbstate_t *__restrict <[ps]>);
 
#include <wchar.h>
size_t _wcsnrtombs_r(struct _reent *<[ptr]>, char *<[dst]>,
const wchar_t **<[src]>, size_t <[nwc]>,
size_t <[len]>, mbstate_t *<[ps]>);
 
TRAD_SYNOPSIS
#include <wchar.h>
size_t wcsrtombs(<[dst]>, <[src]>, <[len]>, <[ps]>)
char *__restrict <[dst]>;
const wchar_t **__restrict <[src]>;
size_t <[len]>;
mbstate_t *__restrict <[ps]>;
 
#include <wchar.h>
size_t _wcsrtombs_r(<[ptr]>, <[dst]>, <[src]>, <[len]>, <[ps]>)
struct _rent *<[ptr]>;
char *<[dst]>;
const wchar_t **<[src]>;
size_t <[len]>;
mbstate_t *<[ps]>;
 
#include <wchar.h>
size_t wcsnrtombs(<[dst]>, <[src]>, <[nwc]>, <[len]>, <[ps]>)
char *__restrict <[dst]>;
const wchar_t **__restrict <[src]>;
size_t <[nwc]>;
size_t <[len]>;
mbstate_t *__restrict <[ps]>;
 
#include <wchar.h>
size_t _wcsnrtombs_r(<[ptr]>, <[dst]>, <[src]>, <[nwc]>, <[len]>, <[ps]>)
struct _rent *<[ptr]>;
char *<[dst]>;
const wchar_t **<[src]>;
size_t <[nwc]>;
size_t <[len]>;
mbstate_t *<[ps]>;
 
DESCRIPTION
The <<wcsrtombs>> function converts a string of wide characters indirectly
pointed to by <[src]> to a corresponding multibyte character string stored in
the array pointed to by <[dst]>. No more than <[len]> bytes are written to
<[dst]>.
 
If <[dst]> is NULL, no characters are stored.
 
If <[dst]> is not NULL, the pointer pointed to by <[src]> is updated to point
to the character after the one that conversion stopped at. If conversion
stops because a null character is encountered, *<[src]> is set to NULL.
 
The mbstate_t argument, <[ps]>, is used to keep track of the shift state. If
it is NULL, <<wcsrtombs>> uses an internal, static mbstate_t object, which
is initialized to the initial conversion state at program startup.
 
The <<wcsnrtombs>> function behaves identically to <<wcsrtombs>>, except that
conversion stops after reading at most <[nwc]> characters from the buffer
pointed to by <[src]>.
 
RETURNS
The <<wcsrtombs>> and <<wcsnrtombs>> functions return the number of bytes
stored in the array pointed to by <[dst]> (not including any terminating
null), if successful, otherwise it returns (size_t)-1.
 
PORTABILITY
<<wcsrtombs>> is defined by C99 standard.
<<wcsnrtombs>> is defined by the POSIX.1-2008 standard.
*/
 
#include <reent.h>
#include <newlib.h>
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "local.h"
 
size_t
_DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps),
struct _reent *r _AND
char *dst _AND
const wchar_t **src _AND
size_t nwc _AND
size_t len _AND
mbstate_t *ps)
{
char *ptr = dst;
char buff[10];
wchar_t *pwcs;
size_t n;
int i;
 
#ifdef _MB_CAPABLE
if (ps == NULL)
{
_REENT_CHECK_MISC(r);
ps = &(_REENT_WCSRTOMBS_STATE(r));
}
#endif
 
/* If no dst pointer, treat len as maximum possible value. */
if (dst == NULL)
len = (size_t)-1;
 
n = 0;
pwcs = (wchar_t *)(*src);
 
while (n < len && nwc-- > 0)
{
int count = ps->__count;
wint_t wch = ps->__value.__wch;
int bytes = __wctomb (r, buff, *pwcs, __locale_charset (), ps);
if (bytes == -1)
{
r->_errno = EILSEQ;
ps->__count = 0;
return (size_t)-1;
}
if (n + bytes <= len)
{
n += bytes;
if (dst)
{
for (i = 0; i < bytes; ++i)
*ptr++ = buff[i];
++(*src);
}
if (*pwcs++ == 0x00)
{
if (dst)
*src = NULL;
ps->__count = 0;
return n - 1;
}
}
else
{
/* not enough room, we must back up state to before __wctomb call */
ps->__count = count;
ps->__value.__wch = wch;
len = 0;
}
}
 
return n;
}
 
#ifndef _REENT_ONLY
size_t
_DEFUN (wcsnrtombs, (dst, src, nwc, len, ps),
char *__restrict dst _AND
const wchar_t **__restrict src _AND
size_t nwc _AND
size_t len _AND
mbstate_t *__restrict ps)
{
return _wcsnrtombs_r (_REENT, dst, src, nwc, len, ps);
}
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdlib/wcsrtombs.c
0,0 → 1,28
/* Doc in wcsnrtombs.c */
 
#include <reent.h>
#include <newlib.h>
#include <wchar.h>
 
size_t
_DEFUN (_wcsrtombs_r, (r, dst, src, len, ps),
struct _reent *r _AND
char *dst _AND
const wchar_t **src _AND
size_t len _AND
mbstate_t *ps)
{
return _wcsnrtombs_r (r, dst, src, (size_t) -1, len, ps);
}
 
#ifndef _REENT_ONLY
size_t
_DEFUN (wcsrtombs, (dst, src, len, ps),
char *__restrict dst _AND
const wchar_t **__restrict src _AND
size_t len _AND
mbstate_t *__restrict ps)
{
return _wcsnrtombs_r (_REENT, dst, src, (size_t) -1, len, ps);
}
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdlib/wcstod.c
0,0 → 1,232
/*
FUNCTION
<<wcstod>>, <<wcstof>>---wide char string to double or float
 
INDEX
wcstod
INDEX
_wcstod_r
INDEX
wcstof
INDEX
_wcstof_r
 
ANSI_SYNOPSIS
#include <stdlib.h>
double wcstod(const wchar_t *__restrict <[str]>,
wchar_t **__restrict <[tail]>);
float wcstof(const wchar_t *__restrict <[str]>,
wchar_t **__restrict <[tail]>);
 
double _wcstod_r(void *<[reent]>,
const wchar_t *<[str]>, wchar_t **<[tail]>);
float _wcstof_r(void *<[reent]>,
const wchar_t *<[str]>, wchar_t **<[tail]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
double wcstod(<[str]>,<[tail]>)
wchar_t *__restrict <[str]>;
wchar_t **__restrict <[tail]>;
 
float wcstof(<[str]>,<[tail]>)
wchar_t *__restrict <[str]>;
wchar_t **__restrict <[tail]>;
 
double _wcstod_r(<[reent]>,<[str]>,<[tail]>)
wchar_t *<[reent]>;
wchar_t *<[str]>;
wchar_t **<[tail]>;
 
float _wcstof_r(<[reent]>,<[str]>,<[tail]>)
wchar_t *<[reent]>;
wchar_t *<[str]>;
wchar_t **<[tail]>;
 
DESCRIPTION
The function <<wcstod>> parses the wide character string <[str]>,
producing a substring which can be converted to a double
value. The substring converted is the longest initial
subsequence of <[str]>, beginning with the first
non-whitespace character, that has one of these formats:
.[+|-]<[digits]>[.[<[digits]>]][(e|E)[+|-]<[digits]>]
.[+|-].<[digits]>[(e|E)[+|-]<[digits]>]
.[+|-](i|I)(n|N)(f|F)[(i|I)(n|N)(i|I)(t|T)(y|Y)]
.[+|-](n|N)(a|A)(n|N)[<(>[<[hexdigits]>]<)>]
.[+|-]0(x|X)<[hexdigits]>[.[<[hexdigits]>]][(p|P)[+|-]<[digits]>]
.[+|-]0(x|X).<[hexdigits]>[(p|P)[+|-]<[digits]>]
The substring contains no characters if <[str]> is empty, consists
entirely of whitespace, or if the first non-whitespace
character is something other than <<+>>, <<->>, <<.>>, or a
digit, and cannot be parsed as infinity or NaN. If the platform
does not support NaN, then NaN is treated as an empty substring.
If the substring is empty, no conversion is done, and
the value of <[str]> is stored in <<*<[tail]>>>. Otherwise,
the substring is converted, and a pointer to the final string
(which will contain at least the terminating null character of
<[str]>) is stored in <<*<[tail]>>>. If you want no
assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>.
<<wcstof>> is identical to <<wcstod>> except for its return type.
 
This implementation returns the nearest machine number to the
input decimal string. Ties are broken by using the IEEE
round-even rule. However, <<wcstof>> is currently subject to
double rounding errors.
 
The alternate functions <<_wcstod_r>> and <<_wcstof_r>> are
reentrant versions of <<wcstod>> and <<wcstof>>, respectively.
The extra argument <[reent]> is a pointer to a reentrancy structure.
 
RETURNS
Return the converted substring value, if any. If
no conversion could be performed, 0 is returned. If the
correct value is out of the range of representable values,
plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is
stored in errno. If the correct value would cause underflow, 0
is returned and <<ERANGE>> is stored in errno.
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
 
/*-
* Copyright (c) 2002 Tim J. Robbins
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <errno.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>
#include <math.h>
 
double
_DEFUN (_wcstod_r, (ptr, nptr, endptr),
struct _reent *ptr _AND
_CONST wchar_t *nptr _AND
wchar_t **endptr)
{
static const mbstate_t initial;
mbstate_t mbs;
double val;
char *buf, *end;
const wchar_t *wcp;
size_t len;
 
while (iswspace(*nptr))
nptr++;
 
/*
* Convert the supplied numeric wide char. string to multibyte.
*
* We could attempt to find the end of the numeric portion of the
* wide char. string to avoid converting unneeded characters but
* choose not to bother; optimising the uncommon case where
* the input string contains a lot of text after the number
* duplicates a lot of strtod()'s functionality and slows down the
* most common cases.
*/
wcp = nptr;
mbs = initial;
if ((len = _wcsrtombs_r(ptr, NULL, &wcp, 0, &mbs)) == (size_t)-1) {
if (endptr != NULL)
*endptr = (wchar_t *)nptr;
return (0.0);
}
if ((buf = _malloc_r(ptr, len + 1)) == NULL)
return (0.0);
mbs = initial;
_wcsrtombs_r(ptr, buf, &wcp, len + 1, &mbs);
 
/* Let strtod() do most of the work for us. */
val = _strtod_r(ptr, buf, &end);
 
/*
* We only know where the number ended in the _multibyte_
* representation of the string. If the caller wants to know
* where it ended, count multibyte characters to find the
* corresponding position in the wide char string.
*/
if (endptr != NULL) {
/* The only valid multibyte char in a float converted by
strtod/wcstod is the radix char. What we do here is,
figure out if the radix char was in the valid leading
float sequence in the incoming string. If so, the
multibyte float string is strlen(radix char) - 1 bytes
longer than the incoming wide char string has characters.
To fix endptr, reposition end as if the radix char was
just one byte long. The resulting difference (end - buf)
is then equivalent to the number of valid wide characters
in the input string. */
len = strlen (_localeconv_r (ptr)->decimal_point);
if (len > 1) {
char *d = strstr (buf,
_localeconv_r (ptr)->decimal_point);
if (d && d < end)
end -= len - 1;
}
*endptr = (wchar_t *)nptr + (end - buf);
}
 
_free_r(ptr, buf);
 
return (val);
}
 
float
_DEFUN (_wcstof_r, (ptr, nptr, endptr),
struct _reent *ptr _AND
_CONST wchar_t *nptr _AND
wchar_t **endptr)
{
double retval = _wcstod_r (ptr, nptr, endptr);
if (isnan (retval))
return nanf (NULL);
return (float)retval;
}
 
#ifndef _REENT_ONLY
 
double
_DEFUN (wcstod, (nptr, endptr),
_CONST wchar_t *__restrict nptr _AND wchar_t **__restrict endptr)
{
return _wcstod_r (_REENT, nptr, endptr);
}
 
float
_DEFUN (wcstof, (nptr, endptr),
_CONST wchar_t *__restrict nptr _AND
wchar_t **__restrict endptr)
{
double retval = _wcstod_r (_REENT, nptr, endptr);
if (isnan (retval))
return nanf (NULL);
return (float)retval;
}
 
#endif
/contrib/sdk/sources/newlib/libc/stdlib/wcstol.c
0,0 → 1,227
/*
FUNCTION
<<wcstol>>---wide string to long
 
INDEX
wcstol
INDEX
_wcstol_r
 
ANSI_SYNOPSIS
#include <wchar.h>
long wcstol(const wchar_t *__restrict <[s]>,
wchar_t **__restrict <[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 *__restrict <[s]>;
wchar_t **__restrict <[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 *__restrict s _AND
wchar_t **__restrict ptr _AND
int base)
{
return _wcstol_r (_REENT, s, ptr, base);
}
 
#endif
/contrib/sdk/sources/newlib/libc/stdlib/wcstold.c
0,0 → 1,108
/*
(C) Copyright IBM Corp. 2009
 
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* 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.
* Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>
#include "local.h"
 
long double
wcstold (const wchar_t *__restrict nptr, wchar_t **__restrict endptr)
{
#ifdef _LDBL_EQ_DBL
/* On platforms where long double is as wide as double. */
return wcstod(nptr, endptr);
 
#else /* This is a duplicate of the code in wcstod.c, but converted to long double. */
 
static const mbstate_t initial;
mbstate_t mbs;
long double val;
char *buf, *end;
const wchar_t *wcp;
size_t len;
 
while (iswspace (*nptr))
nptr++;
 
/* Convert the supplied numeric wide char string to multibyte. */
wcp = nptr;
mbs = initial;
if ((len = wcsrtombs (NULL, &wcp, 0, &mbs)) == (size_t)-1)
{
if (endptr != NULL)
*endptr = (wchar_t *) nptr;
return 0.0L;
}
 
if ((buf = malloc (len + 1)) == NULL)
return 0.0L;
 
mbs = initial;
wcsrtombs (buf, &wcp, len + 1, &mbs);
 
val = strtold (buf, &end);
 
/* We only know where the number ended in the _multibyte_
representation of the string. If the caller wants to know
where it ended, count multibyte characters to find the
corresponding position in the wide char string. */
 
if (endptr != NULL)
{
/* The only valid multibyte char in a float converted by
strtold/wcstold is the radix char. What we do here is,
figure out if the radix char was in the valid leading
float sequence in the incoming string. If so, the
multibyte float string is strlen (radix char) - 1 bytes
longer than the incoming wide char string has characters.
To fix endptr, reposition end as if the radix char was
just one byte long. The resulting difference (end - buf)
is then equivalent to the number of valid wide characters
in the input string. */
len = strlen (localeconv ()->decimal_point);
if (len > 1)
{
char *d = strstr (buf, localeconv ()->decimal_point);
 
if (d && d < end)
end -= len - 1;
}
 
*endptr = (wchar_t *) nptr + (end - buf);
}
 
free (buf);
 
return val;
#endif /* _LDBL_EQ_DBL */
}
/contrib/sdk/sources/newlib/libc/stdlib/wcstoll.c
0,0 → 1,139
/*
FUNCTION
<<wcstoll>>---wide string to long long
 
INDEX
wcstoll
INDEX
_wcstoll_r
 
ANSI_SYNOPSIS
#include <wchar.h>
long long wcstoll(const wchar_t *__restrict <[s]>,
wchar_t **__restrict <[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 *__restrict <[s]>;
wchar_t **__restrict <[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 *__restrict s _AND
wchar_t **__restrict ptr _AND
int base)
{
return _wcstoll_r (_REENT, s, ptr, base);
}
 
#endif
/contrib/sdk/sources/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__ */
/contrib/sdk/sources/newlib/libc/stdlib/wcstombs.c
0,0 → 1,83
/*
FUNCTION
<<wcstombs>>---minimal wide char string to multibyte string converter
 
INDEX
wcstombs
 
ANSI_SYNOPSIS
#include <stdlib.h>
size_t wcstombs(char *restrict <[s]>, const wchar_t *restrict <[pwc]>, size_t <[n]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
size_t wcstombs(<[s]>, <[pwc]>, <[n]>)
char *<[s]>;
const wchar_t *<[pwc]>;
size_t <[n]>;
 
DESCRIPTION
When _MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<wcstombs>>. In this case,
all wide-characters are expected to represent single bytes and so
are converted simply by casting to char.
 
When _MB_CAPABLE is defined, this routine calls <<_wcstombs_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
 
RETURNS
This implementation of <<wcstombs>> returns <<0>> if
<[s]> is <<NULL>> or is the empty string;
it returns <<-1>> if _MB_CAPABLE and one of the
wide-char characters does not represent a valid multi-byte character;
otherwise it returns the minimum of: <<n>> or the
number of bytes that are transferred to <<s>>, not including the
nul terminator.
 
If the return value is -1, the state of the <<pwc>> string is
indeterminate. If the input has a length of 0, the output
string will be modified to contain a wchar_t nul terminator if
<<n>> > 0.
 
PORTABILITY
<<wcstombs>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
 
<<wcstombs>> requires no supporting OS subroutines.
*/
 
#ifndef _REENT_ONLY
 
#include <newlib.h>
#include <stdlib.h>
#include <wchar.h>
 
size_t
_DEFUN (wcstombs, (s, pwcs, n),
char *__restrict s _AND
const wchar_t *__restrict pwcs _AND
size_t n)
{
#ifdef _MB_CAPABLE
mbstate_t state;
state.__count = 0;
return _wcstombs_r (_REENT, s, pwcs, n, &state);
#else /* not _MB_CAPABLE */
int count = 0;
if (n != 0) {
do {
if ((*s++ = (char) *pwcs++) == 0)
break;
count++;
} while (--n != 0);
}
return count;
#endif /* not _MB_CAPABLE */
}
 
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/stdlib/wcstombs_r.c
0,0 → 1,48
#include <stdlib.h>
#include <wchar.h>
#include "local.h"
 
size_t
_DEFUN (_wcstombs_r, (reent, s, pwcs, n, state),
struct _reent *r _AND
char *__restrict s _AND
const wchar_t *__restrict pwcs _AND
size_t n _AND
mbstate_t *state)
{
char *ptr = s;
size_t max = n;
char buff[8];
int i, bytes, num_to_copy;
 
if (s == NULL)
{
size_t num_bytes = 0;
while (*pwcs != 0)
{
bytes = __wctomb (r, buff, *pwcs++, __locale_charset (), state);
if (bytes == -1)
return -1;
num_bytes += bytes;
}
return num_bytes;
}
else
{
while (n > 0)
{
bytes = __wctomb (r, buff, *pwcs, __locale_charset (), state);
if (bytes == -1)
return -1;
num_to_copy = (n > bytes ? bytes : (int)n);
for (i = 0; i < num_to_copy; ++i)
*ptr++ = buff[i];
if (*pwcs == 0x00)
return ptr - s - (n >= bytes);
++pwcs;
n -= num_to_copy;
}
return max;
}
}
/contrib/sdk/sources/newlib/libc/stdlib/wcstoul.c
0,0 → 1,207
/*
FUNCTION
<<wcstoul>>---wide string to unsigned long
 
INDEX
wcstoul
INDEX
_wcstoul_r
 
ANSI_SYNOPSIS
#include <wchar.h>
unsigned long wcstoul(const wchar_t *__restrict <[s]>,
wchar_t **__restrict <[ptr]>, int <[base]>);
 
unsigned long _wcstoul_r(void *<[reent]>, const wchar_t *<[s]>,
wchar_t **<[ptr]>, int <[base]>);
 
TRAD_SYNOPSIS
#include <wchar.h>
unsigned long wcstoul(<[s]>, <[ptr]>, <[base]>)
wchar_t *__restrict <[s]>;
wchar_t **__restrict <[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 <wchar.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 *__restrict s _AND
wchar_t **__restrict ptr _AND
int base)
{
return _wcstoul_r (_REENT, s, ptr, base);
}
 
#endif
/contrib/sdk/sources/newlib/libc/stdlib/wcstoull.c
0,0 → 1,140
/*
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 *__restrict <[s]>,
wchar_t **__restrict <[ptr]>, int <[base]>);
 
unsigned long long _wcstoull_r(void *<[reent]>, const wchar_t *<[s]>,
wchar_t **<[ptr]>, int <[base]>);
 
TRAD_SYNOPSIS
#include <wchar.h>
unsigned long long wcstoull(<[s]>, <[ptr]>, <[base]>)
wchar_t *__restrict <[s]>;
wchar_t **__restrict <[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: an optional sign (<<+>> or <<->>),
a possible <<0x>> indicating hexadecimal radix or a possible <0> indicating
octal 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 <<0>> and sets <<errno>> to <<EINVAL>> if the value of
<[base]> is not supported.
 
<<wcstoull>> returns the converted value, if any. If no conversion was
made, <<0>> is returned.
 
<<wcstoull>> returns <<ULLONG_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 <wchar.h>
#include <reent.h>
 
#ifndef _REENT_ONLY
 
unsigned long long
_DEFUN (wcstoull, (s, ptr, base),
_CONST wchar_t *__restrict s _AND
wchar_t **__restrict ptr _AND
int base)
{
return _wcstoull_r (_REENT, s, ptr, base);
}
 
#endif
/contrib/sdk/sources/newlib/libc/stdlib/wcstoull_r.c
0,0 → 1,130
/*
This code is based on wcstoul.c which has the following copyright.
It is used to convert a wide string into an unsigned long long.
unsigned long long _wcstoull_r (struct _reent *rptr, const wchar_t *s,
wchar_t **ptr, int base);
 
*/
 
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
 
#ifdef __GNUC__
 
#define _GNU_SOURCE
#include <_ansi.h>
#include <limits.h>
#include <wchar.h>
#include <wctype.h>
#include <errno.h>
#include <reent.h>
 
/* Make up for older non-compliant limits.h. (This is a C99/POSIX function,
* and both require ULLONG_MAX in limits.h.) */
#if !defined(ULLONG_MAX)
# define ULLONG_MAX ULONG_LONG_MAX
#endif
 
/*
* Convert a wide string to an unsigned long long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
unsigned long long
_DEFUN (_wcstoull_r, (rptr, nptr, endptr, base),
struct _reent *rptr _AND
_CONST wchar_t *nptr _AND
wchar_t **endptr _AND
int base)
{
register const wchar_t *s = nptr;
register unsigned long long acc;
register int c;
register unsigned long long cutoff;
register int neg = 0, any, cutlim;
 
if(base < 0 || base == 1 || base > 36) {
rptr->_errno = EINVAL;
return(0ULL);
}
/*
* See strtol for comments as to the logic used.
*/
do {
c = *s++;
} while (iswspace(c));
if (c == L'-') {
neg = 1;
c = *s++;
} else if (c == L'+')
c = *s++;
if ((base == 0 || base == 16) &&
c == L'0' && (*s == L'x' || *s == L'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == L'0' ? 8 : 10;
cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base;
cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base;
for (acc = 0, any = 0;; c = *s++) {
if (iswdigit(c))
c -= L'0';
else if (iswalpha(c))
c -= iswupper(c) ? L'A' - 10 : L'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = ULLONG_MAX;
rptr->_errno = ERANGE;
} else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = (wchar_t *) (any ? s - 1 : nptr);
return (acc);
}
 
#endif /* __GNUC__ */
/contrib/sdk/sources/newlib/libc/stdlib/wctob.c
0,0 → 1,26
#include <reent.h>
#include <wchar.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "local.h"
 
int
wctob (wint_t wc)
{
struct _reent *reent;
mbstate_t mbs;
unsigned char pmb[MB_LEN_MAX];
 
if (wc == WEOF)
return EOF;
 
/* Put mbs in initial state. */
memset (&mbs, '\0', sizeof (mbs));
 
reent = _REENT;
_REENT_CHECK_MISC(reent);
 
return __wctomb (reent, (char *) pmb, wc, __locale_charset (), &mbs) == 1
? (int) pmb[0] : EOF;
}
/contrib/sdk/sources/newlib/libc/stdlib/wctomb.c
0,0 → 1,81
/*
FUNCTION
<<wctomb>>---minimal wide char to multibyte converter
 
INDEX
wctomb
 
ANSI_SYNOPSIS
#include <stdlib.h>
int wctomb(char *<[s]>, wchar_t <[wchar]>);
 
TRAD_SYNOPSIS
#include <stdlib.h>
int wctomb(<[s]>, <[wchar]>)
char *<[s]>;
wchar_t <[wchar]>;
 
DESCRIPTION
When _MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<wctomb>>. The
only ``wide characters'' recognized are single bytes,
and they are ``converted'' to themselves.
 
When _MB_CAPABLE is defined, this routine calls <<_wctomb_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
 
Each call to <<wctomb>> modifies <<*<[s]>>> unless <[s]> is a null
pointer or _MB_CAPABLE is defined and <[wchar]> is invalid.
 
RETURNS
This implementation of <<wctomb>> returns <<0>> if
<[s]> is <<NULL>>; it returns <<-1>> if _MB_CAPABLE is enabled
and the wchar is not a valid multi-byte character, it returns <<1>>
if _MB_CAPABLE is not defined or the wchar is in reality a single
byte character, otherwise it returns the number of bytes in the
multi-byte character.
 
PORTABILITY
<<wctomb>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
 
<<wctomb>> requires no supporting OS subroutines.
*/
 
#ifndef _REENT_ONLY
 
#include <newlib.h>
#include <stdlib.h>
#include <errno.h>
#include "local.h"
 
int
_DEFUN (wctomb, (s, wchar),
char *s _AND
wchar_t wchar)
{
#ifdef _MB_CAPABLE
struct _reent *reent = _REENT;
 
_REENT_CHECK_MISC(reent);
 
return __wctomb (reent, s, wchar, __locale_charset (),
&(_REENT_WCTOMB_STATE(reent)));
#else /* not _MB_CAPABLE */
if (s == NULL)
return 0;
 
/* Verify that wchar is a valid single-byte character. */
if ((size_t)wchar >= 0x100) {
errno = EILSEQ;
return -1;
}
 
*s = (char) wchar;
return 1;
#endif /* not _MB_CAPABLE */
}
 
#endif /* !_REENT_ONLY */