/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 */ |