/contrib/sdk/sources/newlib/libc/stdio/clearerr.c |
---|
0,0 → 1,71 |
/* |
* 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 |
<<clearerr>>---clear file or stream error indicator |
INDEX |
clearerr |
ANSI_SYNOPSIS |
#include <stdio.h> |
void clearerr(FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
void clearerr(<[fp]>) |
FILE *<[fp]>; |
DESCRIPTION |
The <<stdio>> functions maintain an error indicator with each file |
pointer <[fp]>, to record whether any read or write errors have |
occurred on the associated file or stream. Similarly, it maintains an |
end-of-file indicator to record whether there is no more data in the |
file. |
Use <<clearerr>> to reset both of these indicators. |
See <<ferror>> and <<feof>> to query the two indicators. |
RETURNS |
<<clearerr>> does not return a result. |
PORTABILITY |
ANSI C requires <<clearerr>>. |
No supporting OS subroutines are required. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include "local.h" |
/* A subroutine version of the macro clearerr. */ |
#undef clearerr |
_VOID |
_DEFUN(clearerr, (fp), |
FILE * fp) |
{ |
CHECK_INIT(_REENT, fp); |
_flockfile (fp); |
__sclearerr (fp); |
_funlockfile (fp); |
} |
/contrib/sdk/sources/newlib/libc/stdio/diprintf.c |
---|
0,0 → 1,82 |
/* Copyright (C) 2005, 2007 Shaun Jackman |
* Permission to use, copy, modify, and distribute this software |
* is freely granted, provided that this notice is preserved. |
*/ |
/* |
FUNCTION |
<<diprintf>>, <<vdiprintf>>---print to a file descriptor (integer only) |
INDEX |
diprintf |
INDEX |
_diprintf_r |
INDEX |
vdiprintf |
INDEX |
_vdiprintf_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
#include <stdarg.h> |
int diprintf(int <[fd]>, const char *<[format]>, ...); |
int vdiprintf(int <[fd]>, const char *<[format]>, va_list <[ap]>); |
int _diprintf_r(struct _reent *<[ptr]>, int <[fd]>, |
const char *<[format]>, ...); |
int _vdiprintf_r(struct _reent *<[ptr]>, int <[fd]>, |
const char *<[format]>, va_list <[ap]>); |
DESCRIPTION |
<<diprintf>> and <<vdiprintf>> are similar to <<dprintf>> and <<vdprintf>>, |
except that only integer format specifiers are processed. |
The functions <<_diprintf_r>> and <<_vdiprintf_r>> are simply |
reentrant versions of the functions above. |
RETURNS |
Similar to <<dprintf>> and <<vdprintf>>. |
PORTABILITY |
This set of functions is an integer-only extension, and is not portable. |
Supporting OS subroutines required: <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <stdarg.h> |
int |
_DEFUN(_diprintf_r, (ptr, fd, format), |
struct _reent *ptr _AND |
int fd _AND |
const char *format _DOTS) |
{ |
va_list ap; |
int n; |
va_start (ap, format); |
n = _vdiprintf_r (ptr, fd, format, ap); |
va_end (ap); |
return n; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(diprintf, (fd, format), |
int fd _AND |
const char *format _DOTS) |
{ |
va_list ap; |
int n; |
va_start (ap, format); |
n = _vdiprintf_r (_REENT, fd, format, ap); |
va_end (ap); |
return n; |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/dprintf.c |
---|
0,0 → 1,87 |
/* Copyright 2005, 2007 Shaun Jackman |
* Permission to use, copy, modify, and distribute this software |
* is freely granted, provided that this notice is preserved. |
*/ |
/* |
FUNCTION |
<<dprintf>>, <<vdprintf>>---print to a file descriptor |
INDEX |
dprintf |
INDEX |
_dprintf_r |
INDEX |
vdprintf |
INDEX |
_vdprintf_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
#include <stdarg.h> |
int dprintf(int <[fd]>, const char *<[format]>, ...); |
int vdprintf(int <[fd]>, const char *<[format]>, va_list <[ap]>); |
int _dprintf_r(struct _reent *<[ptr]>, int <[fd]>, |
const char *<[format]>, ...); |
int _vdprintf_r(struct _reent *<[ptr]>, int <[fd]>, |
const char *<[format]>, va_list <[ap]>); |
DESCRIPTION |
<<dprintf>> and <<vdprintf>> allow printing a format, similarly to |
<<printf>>, but write to a file descriptor instead of to a <<FILE>> |
stream. |
The functions <<_dprintf_r>> and <<_vdprintf_r>> are simply |
reentrant versions of the functions above. |
RETURNS |
The return value and errors are exactly as for <<write>>, except that |
<<errno>> may also be set to <<ENOMEM>> if the heap is exhausted. |
PORTABILITY |
This function is originally a GNU extension in glibc and is not portable. |
Supporting OS subroutines required: <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <stdarg.h> |
#include "local.h" |
int |
_DEFUN(_dprintf_r, (ptr, fd, format), |
struct _reent *ptr _AND |
int fd _AND |
const char *format _DOTS) |
{ |
va_list ap; |
int n; |
_REENT_SMALL_CHECK_INIT (ptr); |
va_start (ap, format); |
n = _vdprintf_r (ptr, fd, format, ap); |
va_end (ap); |
return n; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(dprintf, (fd, format), |
int fd _AND |
const char *format _DOTS) |
{ |
va_list ap; |
int n; |
struct _reent *ptr = _REENT; |
_REENT_SMALL_CHECK_INIT (ptr); |
va_start (ap, format); |
n = _vdprintf_r (ptr, fd, format, ap); |
va_end (ap); |
return n; |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fclose.c |
---|
0,0 → 1,119 |
/* |
* 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 |
<<fclose>>---close a file |
INDEX |
fclose |
INDEX |
_fclose_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int fclose(FILE *<[fp]>); |
int _fclose_r(struct _reent *<[reent]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int fclose(<[fp]>) |
FILE *<[fp]>; |
int fclose(<[fp]>) |
struct _reent *<[reent]> |
FILE *<[fp]>; |
DESCRIPTION |
If the file or stream identified by <[fp]> is open, <<fclose>> closes |
it, after first ensuring that any pending data is written (by calling |
<<fflush(<[fp]>)>>). |
The alternate function <<_fclose_r>> is a reentrant version. |
The extra argument <[reent]> is a pointer to a reentrancy structure. |
RETURNS |
<<fclose>> returns <<0>> if successful (including when <[fp]> is |
<<NULL>> or not an open file); otherwise, it returns <<EOF>>. |
PORTABILITY |
<<fclose>> is required by ANSI C. |
Required OS subroutines: <<close>>, <<fstat>>, <<isatty>>, <<lseek>>, |
<<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <sys/lock.h> |
#include "local.h" |
int |
_DEFUN(_fclose_r, (rptr, fp), |
struct _reent *rptr _AND |
register FILE * fp) |
{ |
int r; |
if (fp == NULL) |
return (0); /* on NULL */ |
CHECK_INIT (rptr, fp); |
_flockfile (fp); |
if (fp->_flags == 0) /* not open! */ |
{ |
_funlockfile (fp); |
return (0); |
} |
/* Unconditionally flush to allow special handling for seekable read |
files to reposition file to last byte processed as opposed to |
last byte read ahead into the buffer. */ |
r = _fflush_r (rptr, fp); |
if (fp->_close != NULL && fp->_close (rptr, fp->_cookie) < 0) |
r = EOF; |
if (fp->_flags & __SMBF) |
_free_r (rptr, (char *) fp->_bf._base); |
if (HASUB (fp)) |
FREEUB (rptr, fp); |
if (HASLB (fp)) |
FREELB (rptr, fp); |
__sfp_lock_acquire (); |
fp->_flags = 0; /* release this FILE for reuse */ |
_funlockfile (fp); |
#ifndef __SINGLE_THREAD__ |
__lock_close_recursive (fp->_lock); |
#endif |
__sfp_lock_release (); |
return (r); |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fclose, (fp), |
register FILE * fp) |
{ |
return _fclose_r(_REENT, fp); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/fdopen.c |
---|
0,0 → 1,144 |
/* |
* 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 |
<<fdopen>>---turn open file into a stream |
INDEX |
fdopen |
INDEX |
_fdopen_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
FILE *fdopen(int <[fd]>, const char *<[mode]>); |
FILE *_fdopen_r(struct _reent *<[reent]>, |
int <[fd]>, const char *<[mode]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
FILE *fdopen(<[fd]>, <[mode]>) |
int <[fd]>; |
char *<[mode]>; |
FILE *_fdopen_r(<[reent]>, <[fd]>, <[mode]>) |
struct _reent *<[reent]>; |
int <[fd]>; |
char *<[mode]>); |
DESCRIPTION |
<<fdopen>> produces a file descriptor of type <<FILE *>>, from a |
descriptor for an already-open file (returned, for example, by the |
system subroutine <<open>> rather than by <<fopen>>). |
The <[mode]> argument has the same meanings as in <<fopen>>. |
RETURNS |
File pointer or <<NULL>>, as for <<fopen>>. |
PORTABILITY |
<<fdopen>> is ANSI. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <sys/types.h> |
#include <sys/fcntl.h> |
#include <stdio.h> |
#include <errno.h> |
#include "local.h" |
#include <_syslist.h> |
FILE * |
_DEFUN(_fdopen_r, (ptr, fd, mode), |
struct _reent *ptr _AND |
int fd _AND |
_CONST char *mode) |
{ |
register FILE *fp; |
int flags, oflags; |
#ifdef HAVE_FCNTL |
int fdflags, fdmode; |
#endif |
if ((flags = __sflags (ptr, mode, &oflags)) == 0) |
return 0; |
/* make sure the mode the user wants is a subset of the actual mode */ |
#ifdef HAVE_FCNTL |
if ((fdflags = _fcntl_r (ptr, fd, F_GETFL, 0)) < 0) |
return 0; |
fdmode = fdflags & O_ACCMODE; |
if (fdmode != O_RDWR && (fdmode != (oflags & O_ACCMODE))) |
{ |
ptr->_errno = EBADF; |
return 0; |
} |
#endif |
if ((fp = __sfp (ptr)) == 0) |
return 0; |
_flockfile (fp); |
fp->_flags = flags; |
/* POSIX recommends setting the O_APPEND bit on fd to match append |
streams. Someone may later clear O_APPEND on fileno(fp), but the |
stream must still remain in append mode. Rely on __sflags |
setting __SAPP properly. */ |
#ifdef HAVE_FCNTL |
if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) |
_fcntl_r (ptr, fd, F_SETFL, fdflags | O_APPEND); |
#endif |
fp->_file = fd; |
fp->_cookie = (_PTR) fp; |
#undef _read |
#undef _write |
#undef _seek |
#undef _close |
fp->_read = __sread; |
fp->_write = __swrite; |
fp->_seek = __sseek; |
fp->_close = __sclose; |
#ifdef __SCLE |
/* Explicit given mode results in explicit setting mode on fd */ |
if (oflags & O_BINARY) |
setmode (fp->_file, O_BINARY); |
else if (oflags & O_TEXT) |
setmode (fp->_file, O_TEXT); |
if (__stextmode (fp->_file)) |
fp->_flags |= __SCLE; |
#endif |
_funlockfile (fp); |
return fp; |
} |
#ifndef _REENT_ONLY |
FILE * |
_DEFUN(fdopen, (fd, mode), |
int fd _AND |
_CONST char *mode) |
{ |
return _fdopen_r (_REENT, fd, mode); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/fflush.c |
---|
0,0 → 1,247 |
/* |
* 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 |
<<fflush>>---flush buffered file output |
INDEX |
fflush |
INDEX |
_fflush_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int fflush(FILE *<[fp]>); |
int _fflush_r(struct _reent *<[reent]>, FILE *<[fp]>); |
DESCRIPTION |
The <<stdio>> output functions can buffer output before delivering it |
to the host system, in order to minimize the overhead of system calls. |
Use <<fflush>> to deliver any such pending output (for the file |
or stream identified by <[fp]>) to the host system. |
If <[fp]> is <<NULL>>, <<fflush>> delivers pending output from all |
open files. |
Additionally, if <[fp]> is a seekable input stream visiting a file |
descriptor, set the position of the file descriptor to match next |
unread byte, useful for obeying POSIX semantics when ending a process |
without consuming all input from the stream. |
The alternate function <<_fflush_r>> is a reentrant version, where the |
extra argument <[reent]> is a pointer to a reentrancy structure, and |
<[fp]> must not be NULL. |
RETURNS |
<<fflush>> returns <<0>> unless it encounters a write error; in that |
situation, it returns <<EOF>>. |
PORTABILITY |
ANSI C requires <<fflush>>. The behavior on input streams is only |
specified by POSIX, and not all implementations follow POSIX rules. |
No supporting OS subroutines are required. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include <errno.h> |
#include "local.h" |
/* Flush a single file, or (if fp is NULL) all files. */ |
/* Core function which does not lock file pointer. This gets called |
directly from __srefill. */ |
int |
_DEFUN(__sflush_r, (ptr, fp), |
struct _reent *ptr _AND |
register FILE * fp) |
{ |
register unsigned char *p; |
register int n, t; |
t = fp->_flags; |
if ((t & __SWR) == 0) |
{ |
/* For a read stream, an fflush causes the next seek to be |
unoptimized (i.e. forces a system-level seek). This conforms |
to the POSIX and SUSv3 standards. */ |
fp->_flags |= __SNPT; |
/* For a seekable stream with buffered read characters, we will attempt |
a seek to the current position now. A subsequent read will then get |
the next byte from the file rather than the buffer. This conforms |
to the POSIX and SUSv3 standards. Note that the standards allow |
this seek to be deferred until necessary, but we choose to do it here |
to make the change simpler, more contained, and less likely |
to miss a code scenario. */ |
if ((fp->_r > 0 || fp->_ur > 0) && fp->_seek != NULL) |
{ |
int tmp_errno; |
#ifdef __LARGE64_FILES |
_fpos64_t curoff; |
#else |
_fpos_t curoff; |
#endif |
/* Save last errno and set errno to 0, so we can check if a device |
returns with a valid position -1. We restore the last errno if |
no other error condition has been encountered. */ |
tmp_errno = ptr->_errno; |
ptr->_errno = 0; |
/* Get the physical position we are at in the file. */ |
if (fp->_flags & __SOFF) |
curoff = fp->_offset; |
else |
{ |
/* We don't know current physical offset, so ask for it. |
Only ESPIPE and EINVAL are ignorable. */ |
#ifdef __LARGE64_FILES |
if (fp->_flags & __SL64) |
curoff = fp->_seek64 (ptr, fp->_cookie, 0, SEEK_CUR); |
else |
#endif |
curoff = fp->_seek (ptr, fp->_cookie, 0, SEEK_CUR); |
if (curoff == -1L && ptr->_errno != 0) |
{ |
int result = EOF; |
if (ptr->_errno == ESPIPE || ptr->_errno == EINVAL) |
{ |
result = 0; |
ptr->_errno = tmp_errno; |
} |
else |
fp->_flags |= __SERR; |
return result; |
} |
} |
if (fp->_flags & __SRD) |
{ |
/* Current offset is at end of buffer. Compensate for |
characters not yet read. */ |
curoff -= fp->_r; |
if (HASUB (fp)) |
curoff -= fp->_ur; |
} |
/* Now physically seek to after byte last read. */ |
#ifdef __LARGE64_FILES |
if (fp->_flags & __SL64) |
curoff = fp->_seek64 (ptr, fp->_cookie, curoff, SEEK_SET); |
else |
#endif |
curoff = fp->_seek (ptr, fp->_cookie, curoff, SEEK_SET); |
if (curoff != -1 || ptr->_errno == 0 |
|| ptr->_errno == ESPIPE || ptr->_errno == EINVAL) |
{ |
/* Seek successful or ignorable error condition. |
We can clear read buffer now. */ |
fp->_flags &= ~__SNPT; |
fp->_r = 0; |
fp->_p = fp->_bf._base; |
if ((fp->_flags & __SOFF) && (curoff != -1 || ptr->_errno == 0)) |
fp->_offset = curoff; |
ptr->_errno = tmp_errno; |
if (HASUB (fp)) |
FREEUB (ptr, fp); |
} |
else |
{ |
fp->_flags |= __SERR; |
return EOF; |
} |
} |
return 0; |
} |
if ((p = fp->_bf._base) == NULL) |
{ |
/* Nothing to flush. */ |
return 0; |
} |
n = fp->_p - p; /* write this much */ |
/* |
* Set these immediately to avoid problems with longjmp |
* and to allow exchange buffering (via setvbuf) in user |
* write function. |
*/ |
fp->_p = p; |
fp->_w = t & (__SLBF | __SNBF) ? 0 : fp->_bf._size; |
while (n > 0) |
{ |
t = fp->_write (ptr, fp->_cookie, (char *) p, n); |
if (t <= 0) |
{ |
fp->_flags |= __SERR; |
return EOF; |
} |
p += t; |
n -= t; |
} |
return 0; |
} |
int |
_DEFUN(_fflush_r, (ptr, fp), |
struct _reent *ptr _AND |
register FILE * fp) |
{ |
int ret; |
#ifdef _REENT_SMALL |
/* For REENT_SMALL platforms, it is possible we are being |
called for the first time on a std stream. This std |
stream can belong to a reentrant struct that is not |
_REENT. If CHECK_INIT gets called below based on _REENT, |
we will end up changing said file pointers to the equivalent |
std stream off of _REENT. This causes unexpected behavior if |
there is any data to flush on the _REENT std stream. There |
are two alternatives to fix this: 1) make a reentrant fflush |
or 2) simply recognize that this file has nothing to flush |
and return immediately before performing a CHECK_INIT. Choice |
2 is implemented here due to its simplicity. */ |
if (fp->_bf._base == NULL) |
return 0; |
#endif /* _REENT_SMALL */ |
CHECK_INIT (ptr, fp); |
if (!fp->_flags) |
return 0; |
_flockfile (fp); |
ret = __sflush_r (ptr, fp); |
_funlockfile (fp); |
return ret; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fflush, (fp), |
register FILE * fp) |
{ |
if (fp == NULL) |
return _fwalk_reent (_GLOBAL_REENT, _fflush_r); |
return _fflush_r (_REENT, fp); |
} |
#endif /* _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fgetc.c |
---|
0,0 → 1,106 |
/* |
* 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 |
<<fgetc>>---get a character from a file or stream |
INDEX |
fgetc |
INDEX |
_fgetc_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int fgetc(FILE *<[fp]>); |
#include <stdio.h> |
int _fgetc_r(struct _reent *<[ptr]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int fgetc(<[fp]>) |
FILE *<[fp]>; |
#include <stdio.h> |
int _fgetc_r(<[ptr]>, <[fp]>) |
struct _reent *<[ptr]>; |
FILE *<[fp]>; |
DESCRIPTION |
Use <<fgetc>> to get the next single character from the file or stream |
identified by <[fp]>. As a side effect, <<fgetc>> advances the file's |
current position indicator. |
For a macro version of this function, see <<getc>>. |
The function <<_fgetc_r>> is simply a reentrant version of |
<<fgetc>> that is passed the additional reentrant structure |
pointer argument: <[ptr]>. |
RETURNS |
The next character (read as an <<unsigned char>>, and cast to |
<<int>>), unless there is no more data, or the host system reports a |
read error; in either of these situations, <<fgetc>> returns <<EOF>>. |
You can distinguish the two situations that cause an <<EOF>> result by |
using the <<ferror>> and <<feof>> functions. |
PORTABILITY |
ANSI C requires <<fgetc>>. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include "local.h" |
int |
_DEFUN(_fgetc_r, (ptr, fp), |
struct _reent * ptr _AND |
FILE * fp) |
{ |
int result; |
CHECK_INIT(ptr, fp); |
_flockfile (fp); |
result = __sgetc_r (ptr, fp); |
_funlockfile (fp); |
return result; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fgetc, (fp), |
FILE * fp) |
{ |
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) |
int result; |
CHECK_INIT(_REENT, fp); |
_flockfile (fp); |
result = __sgetc_r (_REENT, fp); |
_funlockfile (fp); |
return result; |
#else |
return _fgetc_r (_REENT, fp); |
#endif |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fgets.c |
---|
0,0 → 1,187 |
/* |
* 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 |
<<fgets>>---get character string from a file or stream |
INDEX |
fgets |
INDEX |
_fgets_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
char *fgets(char *<[buf]>, int <[n]>, FILE *<[fp]>); |
#include <stdio.h> |
char *_fgets_r(struct _reent *<[ptr]>, char *<[buf]>, int <[n]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
char *fgets(<[buf]>,<[n]>,<[fp]>) |
char *<[buf]>; |
int <[n]>; |
FILE *<[fp]>; |
#include <stdio.h> |
char *_fgets_r(<[ptr]>, <[buf]>,<[n]>,<[fp]>) |
struct _reent *<[ptr]>; |
char *<[buf]>; |
int <[n]>; |
FILE *<[fp]>; |
DESCRIPTION |
Reads at most <[n-1]> characters from <[fp]> until a newline |
is found. The characters including to the newline are stored |
in <[buf]>. The buffer is terminated with a 0. |
The <<_fgets_r>> function is simply the reentrant version of |
<<fgets>> and is passed an additional reentrancy structure |
pointer: <[ptr]>. |
RETURNS |
<<fgets>> 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 |
<<fgets>> should replace all uses of <<gets>>. Note however |
that <<fgets>> returns all of the data, while <<gets>> removes |
the trailing newline (with no indication that it has done so.) |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include <string.h> |
#include "local.h" |
/* |
* Read at most n-1 characters from the given file. |
* Stop when a newline has been read, or the count runs out. |
* Return first argument, or NULL if no characters were read. |
*/ |
char * |
_DEFUN(_fgets_r, (ptr, buf, n, fp), |
struct _reent * ptr _AND |
char *buf _AND |
int n _AND |
FILE * fp) |
{ |
size_t len; |
char *s; |
unsigned char *p, *t; |
if (n < 2) /* sanity check */ |
return 0; |
s = buf; |
CHECK_INIT(ptr, fp); |
_flockfile (fp); |
#ifdef __SCLE |
if (fp->_flags & __SCLE) |
{ |
int c; |
/* Sorry, have to do it the slow way */ |
while (--n > 0 && (c = __sgetc_r (ptr, fp)) != EOF) |
{ |
*s++ = c; |
if (c == '\n') |
break; |
} |
if (c == EOF && s == buf) |
{ |
_funlockfile (fp); |
return NULL; |
} |
*s = 0; |
_funlockfile (fp); |
return buf; |
} |
#endif |
n--; /* leave space for NUL */ |
do |
{ |
/* |
* If the buffer is empty, refill it. |
*/ |
if ((len = fp->_r) <= 0) |
{ |
if (__srefill_r (ptr, fp)) |
{ |
/* EOF: stop with partial or no line */ |
if (s == buf) |
{ |
_funlockfile (fp); |
return 0; |
} |
break; |
} |
len = fp->_r; |
} |
p = fp->_p; |
/* |
* Scan through at most n bytes of the current buffer, |
* looking for '\n'. If found, copy up to and including |
* newline, and stop. Otherwise, copy entire chunk |
* and loop. |
*/ |
if (len > n) |
len = n; |
t = (unsigned char *) memchr ((_PTR) p, '\n', len); |
if (t != 0) |
{ |
len = ++t - p; |
fp->_r -= len; |
fp->_p = t; |
_CAST_VOID memcpy ((_PTR) s, (_PTR) p, len); |
s[len] = 0; |
_funlockfile (fp); |
return (buf); |
} |
fp->_r -= len; |
fp->_p += len; |
_CAST_VOID memcpy ((_PTR) s, (_PTR) p, len); |
s += len; |
} |
while ((n -= len) != 0); |
*s = 0; |
_funlockfile (fp); |
return buf; |
} |
#ifndef _REENT_ONLY |
char * |
_DEFUN(fgets, (buf, n, fp), |
char *buf _AND |
int n _AND |
FILE * fp) |
{ |
return _fgets_r (_REENT, buf, n, fp); |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fileno.c |
---|
0,0 → 1,62 |
/* |
* 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 |
<<fileno>>---return file descriptor associated with stream |
INDEX |
fileno |
ANSI_SYNOPSIS |
#include <stdio.h> |
int fileno(FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int fileno(<[fp]>) |
FILE *<[fp]>; |
DESCRIPTION |
You can use <<fileno>> to return the file descriptor identified by <[fp]>. |
RETURNS |
<<fileno>> returns a non-negative integer when successful. |
If <[fp]> is not an open stream, <<fileno>> returns -1. |
PORTABILITY |
<<fileno>> is not part of ANSI C. |
POSIX requires <<fileno>>. |
Supporting OS subroutines required: none. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include "local.h" |
int |
_DEFUN(fileno, (f), |
FILE * f) |
{ |
int result; |
CHECK_INIT (_REENT, f); |
_flockfile (f); |
result = __sfileno (f); |
_funlockfile (f); |
return result; |
} |
/contrib/sdk/sources/newlib/libc/stdio/findfp.c |
---|
0,0 → 1,294 |
/* |
* 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. |
*/ |
/* No user fns here. Pesch 15apr92. */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <errno.h> |
#include <string.h> |
#include <fcntl.h> |
#include <sys/lock.h> |
#include "local.h" |
#ifdef _REENT_SMALL |
const struct __sFILE_fake __sf_fake_stdin = |
{_NULL, 0, 0, 0, 0, {_NULL, 0}, 0, _NULL}; |
const struct __sFILE_fake __sf_fake_stdout = |
{_NULL, 0, 0, 0, 0, {_NULL, 0}, 0, _NULL}; |
const struct __sFILE_fake __sf_fake_stderr = |
{_NULL, 0, 0, 0, 0, {_NULL, 0}, 0, _NULL}; |
#endif |
static _VOID |
_DEFUN(std, (ptr, flags, file, data), |
FILE *ptr _AND |
int flags _AND |
int file _AND |
struct _reent *data) |
{ |
ptr->_p = 0; |
ptr->_r = 0; |
ptr->_w = 0; |
ptr->_flags = flags; |
ptr->_flags2 = 0; |
ptr->_file = file; |
ptr->_bf._base = 0; |
ptr->_bf._size = 0; |
ptr->_lbfsize = 0; |
memset (&ptr->_mbstate, 0, sizeof (_mbstate_t)); |
ptr->_cookie = ptr; |
ptr->_read = __sread; |
#ifndef __LARGE64_FILES |
ptr->_write = __swrite; |
#else /* __LARGE64_FILES */ |
ptr->_write = __swrite64; |
ptr->_seek64 = __sseek64; |
ptr->_flags |= __SL64; |
#endif /* __LARGE64_FILES */ |
ptr->_seek = __sseek; |
ptr->_close = __sclose; |
#if !defined(__SINGLE_THREAD__) && !defined(_REENT_SMALL) |
__lock_init_recursive (ptr->_lock); |
/* |
* #else |
* lock is already initialized in __sfp |
*/ |
#endif |
#ifdef __SCLE |
if (__stextmode (ptr->_file)) |
ptr->_flags |= __SCLE; |
#endif |
} |
struct _glue * |
_DEFUN(__sfmoreglue, (d, n), |
struct _reent *d _AND |
register int n) |
{ |
struct _glue *g; |
FILE *p; |
g = (struct _glue *) _malloc_r (d, sizeof (*g) + n * sizeof (FILE)); |
if (g == NULL) |
return NULL; |
p = (FILE *) (g + 1); |
g->_next = NULL; |
g->_niobs = n; |
g->_iobs = p; |
memset (p, 0, n * sizeof (FILE)); |
return g; |
} |
/* |
* Find a free FILE for fopen et al. |
*/ |
FILE * |
_DEFUN(__sfp, (d), |
struct _reent *d) |
{ |
FILE *fp; |
int n; |
struct _glue *g; |
__sfp_lock_acquire (); |
if (!_GLOBAL_REENT->__sdidinit) |
__sinit (_GLOBAL_REENT); |
for (g = &_GLOBAL_REENT->__sglue;; g = g->_next) |
{ |
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) |
if (fp->_flags == 0) |
goto found; |
if (g->_next == NULL && |
(g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL) |
break; |
} |
__sfp_lock_release (); |
d->_errno = ENOMEM; |
return NULL; |
found: |
fp->_file = -1; /* no file */ |
fp->_flags = 1; /* reserve this slot; caller sets real flags */ |
fp->_flags2 = 0; |
#ifndef __SINGLE_THREAD__ |
__lock_init_recursive (fp->_lock); |
#endif |
__sfp_lock_release (); |
fp->_p = NULL; /* no current pointer */ |
fp->_w = 0; /* nothing to read or write */ |
fp->_r = 0; |
fp->_bf._base = NULL; /* no buffer */ |
fp->_bf._size = 0; |
fp->_lbfsize = 0; /* not line buffered */ |
memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); |
/* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */ |
fp->_ub._base = NULL; /* no ungetc buffer */ |
fp->_ub._size = 0; |
fp->_lb._base = NULL; /* no line buffer */ |
fp->_lb._size = 0; |
return fp; |
} |
/* |
* exit() calls _cleanup() through *__cleanup, set whenever we |
* open or buffer a file. This chicanery is done so that programs |
* that do not use stdio need not link it all in. |
* |
* The name `_cleanup' is, alas, fairly well known outside stdio. |
*/ |
_VOID |
_DEFUN(_cleanup_r, (ptr), |
struct _reent *ptr) |
{ |
_CAST_VOID _fwalk(ptr, fclose); |
/* _CAST_VOID _fwalk (ptr, fflush); */ /* `cheating' */ |
} |
#ifndef _REENT_ONLY |
_VOID |
_DEFUN_VOID(_cleanup) |
{ |
_cleanup_r (_GLOBAL_REENT); |
} |
#endif |
/* |
* __sinit() is called whenever stdio's internal variables must be set up. |
*/ |
_VOID |
_DEFUN(__sinit, (s), |
struct _reent *s) |
{ |
__sinit_lock_acquire (); |
if (s->__sdidinit) |
{ |
__sinit_lock_release (); |
return; |
} |
/* make sure we clean up on exit */ |
s->__cleanup = _cleanup_r; /* conservative */ |
s->__sdidinit = 1; |
s->__sglue._next = NULL; |
#ifndef _REENT_SMALL |
s->__sglue._niobs = 3; |
s->__sglue._iobs = &s->__sf[0]; |
#else |
s->__sglue._niobs = 0; |
s->__sglue._iobs = NULL; |
s->_stdin = __sfp(s); |
s->_stdout = __sfp(s); |
s->_stderr = __sfp(s); |
#endif |
std (s->_stdin, __SRD, 0, s); |
/* On platforms that have true file system I/O, we can verify |
whether stdout is an interactive terminal or not, as part of |
__smakebuf on first use of the stream. For all other platforms, |
we will default to line buffered mode here. Technically, POSIX |
requires both stdin and stdout to be line-buffered, but tradition |
leaves stdin alone on systems without fcntl. */ |
#ifdef HAVE_FCNTL |
std (s->_stdout, __SWR, 1, s); |
#else |
std (s->_stdout, __SWR | __SLBF, 1, s); |
#endif |
/* POSIX requires stderr to be opened for reading and writing, even |
when the underlying fd 2 is write-only. */ |
std (s->_stderr, __SRW | __SNBF, 2, s); |
__sinit_lock_release (); |
} |
#ifndef __SINGLE_THREAD__ |
__LOCK_INIT_RECURSIVE(static, __sfp_lock); |
__LOCK_INIT_RECURSIVE(static, __sinit_lock); |
_VOID |
_DEFUN_VOID(__sfp_lock_acquire) |
{ |
__lock_acquire_recursive (__sfp_lock); |
} |
_VOID |
_DEFUN_VOID(__sfp_lock_release) |
{ |
__lock_release_recursive (__sfp_lock); |
} |
_VOID |
_DEFUN_VOID(__sinit_lock_acquire) |
{ |
__lock_acquire_recursive (__sinit_lock); |
} |
_VOID |
_DEFUN_VOID(__sinit_lock_release) |
{ |
__lock_release_recursive (__sinit_lock); |
} |
/* Walkable file locking routine. */ |
static int |
_DEFUN(__fp_lock, (ptr), |
FILE * ptr) |
{ |
_flockfile (ptr); |
return 0; |
} |
/* Walkable file unlocking routine. */ |
static int |
_DEFUN(__fp_unlock, (ptr), |
FILE * ptr) |
{ |
_funlockfile (ptr); |
return 0; |
} |
_VOID |
_DEFUN_VOID(__fp_lock_all) |
{ |
__sfp_lock_acquire (); |
_CAST_VOID _fwalk (_REENT, __fp_lock); |
} |
_VOID |
_DEFUN_VOID(__fp_unlock_all) |
{ |
_CAST_VOID _fwalk (_REENT, __fp_unlock); |
__sfp_lock_release (); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/fiprintf.c |
---|
0,0 → 1,55 |
/* |
* 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 siprintf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdarg.h> |
int |
_DEFUN(_fiprintf_r, (ptr, fp, fmt), |
struct _reent *ptr _AND |
FILE * fp _AND |
const char *fmt _DOTS) |
{ |
int ret; |
va_list ap; |
va_start (ap, fmt); |
ret = _vfiprintf_r (ptr, fp, fmt, ap); |
va_end (ap); |
return ret; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fiprintf, (fp, fmt), |
FILE * fp _AND |
const char *fmt _DOTS) |
{ |
int ret; |
va_list ap; |
va_start (ap, fmt); |
ret = _vfiprintf_r (_REENT, fp, fmt, ap); |
va_end (ap); |
return ret; |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fiscanf.c |
---|
0,0 → 1,78 |
/* |
* 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. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include "local.h" |
#ifndef _REENT_ONLY |
int |
#ifdef _HAVE_STDC |
fiscanf(FILE *fp, _CONST char *fmt, ...) |
#else |
fiscanf(FILE *fp, fmt, va_alist) |
FILE *fp; |
char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = __svfiscanf_r (_REENT, fp, fmt, ap); |
va_end (ap); |
return ret; |
} |
#endif /* !_REENT_ONLY */ |
int |
#ifdef _HAVE_STDC |
_fiscanf_r(struct _reent *ptr, FILE *fp, _CONST char *fmt, ...) |
#else |
_fiscanf_r(ptr, FILE *fp, fmt, va_alist) |
struct _reent *ptr; |
FILE *fp; |
char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = __svfiscanf_r (ptr, fp, fmt, ap); |
va_end (ap); |
return (ret); |
} |
/contrib/sdk/sources/newlib/libc/stdio/flags.c |
---|
0,0 → 1,86 |
/* |
* Copyright (c) 1990 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
*/ |
/* No user fns here. Pesch 15apr92 */ |
#include <_ansi.h> |
#include <stdio.h> |
#include <time.h> |
#include <fcntl.h> |
#include <errno.h> |
#include <sys/types.h> |
/* |
* Return the (stdio) flags for a given mode. Store the flags |
* to be passed to an open() syscall through *optr. |
* Return 0 on error. |
*/ |
int |
_DEFUN(__sflags, (ptr, mode, optr), |
struct _reent *ptr _AND |
register char *mode _AND |
int *optr) |
{ |
register int ret, m, o; |
switch (mode[0]) |
{ |
case 'r': /* open for reading */ |
ret = __SRD; |
m = O_RDONLY; |
o = 0; |
break; |
case 'w': /* open for writing */ |
ret = __SWR; |
m = O_WRONLY; |
o = O_CREAT | O_TRUNC; |
break; |
case 'a': /* open for appending */ |
ret = __SWR | __SAPP; |
m = O_WRONLY; |
o = O_CREAT | O_APPEND; |
break; |
default: /* illegal mode */ |
ptr->_errno = EINVAL; |
return (0); |
} |
if (mode[1] && (mode[1] == '+' || mode[2] == '+')) |
{ |
ret = (ret & ~(__SRD | __SWR)) | __SRW; |
m = O_RDWR; |
} |
if (mode[1] && (mode[1] == 'b' || mode[2] == 'b')) |
{ |
#ifdef O_BINARY |
m |= O_BINARY; |
#endif |
} |
#ifdef __CYGWIN__ |
else if (mode[1] && (mode[1] == 't' || mode[2] == 't')) |
#else |
else |
#endif |
{ |
#ifdef O_TEXT |
m |= O_TEXT; |
#endif |
} |
*optr = m | o; |
return ret; |
} |
/contrib/sdk/sources/newlib/libc/stdio/floatio.h |
---|
0,0 → 1,32 |
/* |
* 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. |
* |
* %W% (Berkeley) %G% |
*/ |
/* |
* Floating point scanf/printf (input/output) definitions. |
*/ |
#ifdef _NO_LONGDBL |
/* 11-bit exponent (VAX G floating point) is 308 decimal digits */ |
#define MAXEXP 308 |
#else /* !_NO_LONGDBL */ |
/* 15-bit exponent (Intel extended floating point) is 4932 decimal digits */ |
#define MAXEXP 4932 |
#endif /* !_NO_LONGDBL */ |
/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */ |
#define MAXFRACT 39 |
/contrib/sdk/sources/newlib/libc/stdio/fopen.c |
---|
0,0 → 1,184 |
/* |
* 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 |
<<fopen>>---open a file |
INDEX |
fopen |
INDEX |
_fopen_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
FILE *fopen(const char *<[file]>, const char *<[mode]>); |
FILE *_fopen_r(struct _reent *<[reent]>, |
const char *<[file]>, const char *<[mode]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
FILE *fopen(<[file]>, <[mode]>) |
char *<[file]>; |
char *<[mode]>; |
FILE *_fopen_r(<[reent]>, <[file]>, <[mode]>) |
struct _reent *<[reent]>; |
char *<[file]>; |
char *<[mode]>; |
DESCRIPTION |
<<fopen>> initializes the data structures needed to read or write a |
file. Specify the file's name as the string at <[file]>, and the kind |
of access you need to the file with the string at <[mode]>. |
The alternate function <<_fopen_r>> is a reentrant version. |
The extra argument <[reent]> is a pointer to a reentrancy structure. |
Three fundamental kinds of access are available: read, write, and append. |
<<*<[mode]>>> must begin with one of the three characters `<<r>>', |
`<<w>>', or `<<a>>', to select one of these: |
o+ |
o r |
Open the file for reading; the operation will fail if the file does |
not exist, or if the host system does not permit you to read it. |
o w |
Open the file for writing @emph{from the beginning} of the file: |
effectively, this always creates a new file. If the file whose name you |
specified already existed, its old contents are discarded. |
o a |
Open the file for appending data, that is writing from the end of |
file. When you open a file this way, all data always goes to the |
current end of file; you cannot change this using <<fseek>>. |
o- |
Some host systems distinguish between ``binary'' and ``text'' files. |
Such systems may perform data transformations on data written to, or |
read from, files opened as ``text''. |
If your system is one of these, then you can append a `<<b>>' to any |
of the three modes above, to specify that you are opening the file as |
a binary file (the default is to open the file as a text file). |
`<<rb>>', then, means ``read binary''; `<<wb>>', ``write binary''; and |
`<<ab>>', ``append binary''. |
To make C programs more portable, the `<<b>>' is accepted on all |
systems, whether or not it makes a difference. |
Finally, you might need to both read and write from the same file. |
You can also append a `<<+>>' to any of the three modes, to permit |
this. (If you want to append both `<<b>>' and `<<+>>', you can do it |
in either order: for example, <<"rb+">> means the same thing as |
<<"r+b">> when used as a mode string.) |
Use <<"r+">> (or <<"rb+">>) to permit reading and writing anywhere in |
an existing file, without discarding any data; <<"w+">> (or <<"wb+">>) |
to create a new file (or begin by discarding all data from an old one) |
that permits reading and writing anywhere in it; and <<"a+">> (or |
<<"ab+">>) to permit reading anywhere in an existing file, but writing |
only at the end. |
RETURNS |
<<fopen>> returns a file pointer which you can use for other file |
operations, unless the file you requested could not be opened; in that |
situation, the result is <<NULL>>. If the reason for failure was an |
invalid string at <[mode]>, <<errno>> is set to <<EINVAL>>. |
PORTABILITY |
<<fopen>> is required by ANSI C. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#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 <errno.h> |
#include <sys/lock.h> |
#ifdef __CYGWIN__ |
#include <fcntl.h> |
#endif |
#include "local.h" |
FILE * |
_DEFUN(_fopen_r, (ptr, file, mode), |
struct _reent *ptr _AND |
_CONST char *file _AND |
_CONST char *mode) |
{ |
register FILE *fp; |
register int f; |
int flags, oflags; |
if ((flags = __sflags (ptr, mode, &oflags)) == 0) |
return NULL; |
if ((fp = __sfp (ptr)) == NULL) |
return NULL; |
if ((f = _open_r (ptr, file, oflags, 0666)) < 0) |
{ |
__sfp_lock_acquire (); |
fp->_flags = 0; /* release */ |
#ifndef __SINGLE_THREAD__ |
__lock_close_recursive (fp->_lock); |
#endif |
__sfp_lock_release (); |
return NULL; |
} |
_flockfile (fp); |
fp->_file = f; |
fp->_flags = flags; |
fp->_cookie = (_PTR) fp; |
fp->_read = __sread; |
fp->_write = __swrite; |
fp->_seek = __sseek; |
fp->_close = __sclose; |
if (fp->_flags & __SAPP) |
_fseek_r (ptr, fp, 0, SEEK_END); |
#ifdef __SCLE |
if (__stextmode (fp->_file)) |
fp->_flags |= __SCLE; |
#endif |
_funlockfile (fp); |
return fp; |
} |
#ifndef _REENT_ONLY |
FILE * |
_DEFUN(fopen, (file, mode), |
_CONST char *file _AND |
_CONST char *mode) |
{ |
return _fopen_r (_REENT, file, mode); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/fprintf.c |
---|
0,0 → 1,55 |
/* |
* 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 sprintf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdarg.h> |
int |
_DEFUN(_fprintf_r, (ptr, fp, fmt), |
struct _reent *ptr _AND |
FILE *fp _AND |
const char *fmt _DOTS) |
{ |
int ret; |
va_list ap; |
va_start (ap, fmt); |
ret = _vfprintf_r (ptr, fp, fmt, ap); |
va_end (ap); |
return ret; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fprintf, (fp, fmt), |
FILE *fp _AND |
const char *fmt _DOTS) |
{ |
int ret; |
va_list ap; |
va_start (ap, fmt); |
ret = _vfprintf_r (_REENT, fp, fmt, ap); |
va_end (ap); |
return ret; |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fputc.c |
---|
0,0 → 1,109 |
/* |
* 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 |
<<fputc>>---write a character on a stream or file |
INDEX |
fputc |
INDEX |
_fputc_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int fputc(int <[ch]>, FILE *<[fp]>); |
#include <stdio.h> |
int _fputc_r(struct _rent *<[ptr]>, int <[ch]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int fputc(<[ch]>, <[fp]>) |
int <[ch]>; |
FILE *<[fp]>; |
#include <stdio.h> |
int _fputc_r(<[ptr]>, <[ch]>, <[fp]>) |
struct _reent *<[ptr]>; |
int <[ch]>; |
FILE *<[fp]>; |
DESCRIPTION |
<<fputc>> converts the argument <[ch]> from an <<int>> to an |
<<unsigned char>>, then writes it to the file or stream identified by |
<[fp]>. |
If the file was opened with append mode (or if the stream cannot |
support positioning), then the new character goes at the end of the |
file or stream. Otherwise, the new character is written at the |
current value of the position indicator, and the position indicator |
oadvances by one. |
For a macro version of this function, see <<putc>>. |
The <<_fputc_r>> function is simply a reentrant version of <<fputc>> |
that takes an additional reentrant structure argument: <[ptr]>. |
RETURNS |
If successful, <<fputc>> returns its argument <[ch]>. If an error |
intervenes, the result is <<EOF>>. You can use `<<ferror(<[fp]>)>>' to |
query for errors. |
PORTABILITY |
<<fputc>> is required by ANSI C. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include "local.h" |
int |
_DEFUN(_fputc_r, (ptr, ch, file), |
struct _reent *ptr _AND |
int ch _AND |
FILE * file) |
{ |
int result; |
CHECK_INIT(ptr, file); |
_flockfile (file); |
result = _putc_r (ptr, ch, file); |
_funlockfile (file); |
return result; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fputc, (ch, file), |
int ch _AND |
FILE * file) |
{ |
#if !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED) |
int result; |
CHECK_INIT(_REENT, file); |
_flockfile (file); |
result = _putc_r (_REENT, ch, file); |
_funlockfile (file); |
return result; |
#else |
return _fputc_r (_REENT, ch, file); |
#endif |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fputs.c |
---|
0,0 → 1,106 |
/* |
* 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 |
<<fputs>>---write a character string in a file or stream |
INDEX |
fputs |
INDEX |
_fputs_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int fputs(const char *<[s]>, FILE *<[fp]>); |
#include <stdio.h> |
int _fputs_r(struct _reent *<[ptr]>, const char *<[s]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int fputs(<[s]>, <[fp]>) |
char *<[s]>; |
FILE *<[fp]>; |
#include <stdio.h> |
int _fputs_r(<[ptr]>, <[s]>, <[fp]>) |
struct _reent *<[ptr]>; |
char *<[s]>; |
FILE *<[fp]>; |
DESCRIPTION |
<<fputs>> writes the string at <[s]> (but without the trailing null) |
to the file or stream identified by <[fp]>. |
<<_fputs_r>> is simply the reentrant version of <<fputs>> that takes |
an additional reentrant struct pointer argument: <[ptr]>. |
RETURNS |
If successful, the result is <<0>>; otherwise, the result is <<EOF>>. |
PORTABILITY |
ANSI C requires <<fputs>>, but does not specify that the result on |
success must be <<0>>; any non-negative value is permitted. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include <string.h> |
#include "fvwrite.h" |
#include "local.h" |
/* |
* Write the given string to the given file. |
*/ |
int |
_DEFUN(_fputs_r, (ptr, s, fp), |
struct _reent * ptr _AND |
char _CONST * s _AND |
FILE * fp) |
{ |
int result; |
struct __suio uio; |
struct __siov iov; |
iov.iov_base = s; |
iov.iov_len = uio.uio_resid = strlen (s); |
uio.uio_iov = &iov; |
uio.uio_iovcnt = 1; |
CHECK_INIT(ptr, fp); |
_flockfile (fp); |
ORIENT (fp, -1); |
result = __sfvwrite_r (ptr, fp, &uio); |
_funlockfile (fp); |
return result; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fputs, (s, fp), |
char _CONST * s _AND |
FILE * fp) |
{ |
return _fputs_r (_REENT, s, fp); |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fputwc.c |
---|
0,0 → 1,177 |
/*- |
* 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 |
<<fputwc>>, <<putwc>>---write a wide character on a stream or file |
INDEX |
fputwc |
INDEX |
_fputwc_r |
INDEX |
putwc |
INDEX |
_putwc_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
#include <wchar.h> |
wint_t fputwc(wchar_t <[wc]>, FILE *<[fp]>); |
#include <stdio.h> |
#include <wchar.h> |
wint_t _fputwc_r(struct _reent *<[ptr]>, wchar_t <[wc]>, FILE *<[fp]>); |
#include <stdio.h> |
#include <wchar.h> |
wint_t putwc(wchar_t <[wc]>, FILE *<[fp]>); |
#include <stdio.h> |
#include <wchar.h> |
wint_t _putwc_r(struct _reent *<[ptr]>, wchar_t <[wc]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
#include <wchar.h> |
wint_t fputwc(<[wc]>, <[fp]>) |
wchar_t <[wc]>; |
FILE *<[fp]>; |
#include <stdio.h> |
#include <wchar.h> |
wint_t _fputwc_r(<[ptr]>, <[wc]>, <[fp]>) |
struct _reent *<[ptr]>; |
wchar_t <[wc]>; |
FILE *<[fp]>; |
#include <stdio.h> |
#include <wchar.h> |
wint_t putwc(<[wc]>, <[fp]>) |
wchar_t <[wc]>; |
FILE *<[fp]>; |
#include <stdio.h> |
#include <wchar.h> |
wint_t _putwc_r(<[ptr]>, <[wc]>, <[fp]>) |
struct _reent *<[ptr]>; |
wchar_t <[wc]>; |
FILE *<[fp]>; |
DESCRIPTION |
<<fputwc>> writes the wide character argument <[wc]> to the file or |
stream identified by <[fp]>. |
If the file was opened with append mode (or if the stream cannot |
support positioning), then the new wide character goes at the end of the |
file or stream. Otherwise, the new wide character is written at the |
current value of the position indicator, and the position indicator |
oadvances by one. |
The <<putwc>> function or macro functions identically to <<fputwc>>. It |
may be implemented as a macro, and may evaluate its argument more than |
once. There is no reason ever to use it. |
The <<_fputwc_r>> and <<_putwc_r>> functions are simply reentrant versions |
of <<fputwc>> and <<putwc>> that take an additional reentrant structure |
argument: <[ptr]>. |
RETURNS |
If successful, <<fputwc>> and <<putwc>> return their argument <[wc]>. |
If an error intervenes, the result is <<EOF>>. You can use |
`<<ferror(<[fp]>)>>' to query for errors. |
PORTABILITY |
C99, POSIX.1-2001 |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <errno.h> |
#include <limits.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <wchar.h> |
#include "local.h" |
static wint_t |
_DEFUN(__fputwc, (ptr, wc, fp), |
struct _reent *ptr _AND |
wchar_t wc _AND |
FILE *fp) |
{ |
char buf[MB_LEN_MAX]; |
size_t i, len; |
if (MB_CUR_MAX == 1 && wc > 0 && wc <= UCHAR_MAX) |
{ |
/* |
* Assume single-byte locale with no special encoding. |
* A more careful test would be to check |
* _CurrentRuneLocale->encoding. |
*/ |
*buf = (unsigned char)wc; |
len = 1; |
} |
else |
{ |
if ((len = _wcrtomb_r (ptr, buf, wc, &fp->_mbstate)) == (size_t) -1) |
{ |
fp->_flags |= __SERR; |
return WEOF; |
} |
} |
for (i = 0; i < len; i++) |
if (__sputc_r (ptr, (unsigned char) buf[i], fp) == EOF) |
return WEOF; |
return (wint_t) wc; |
} |
wint_t |
_DEFUN(_fputwc_r, (ptr, wc, fp), |
struct _reent *ptr _AND |
wchar_t wc _AND |
FILE *fp) |
{ |
wint_t r; |
_flockfile (fp); |
ORIENT(fp, 1); |
r = __fputwc(ptr, wc, fp); |
_funlockfile (fp); |
return r; |
} |
wint_t |
_DEFUN(fputwc, (wc, fp), |
wchar_t wc _AND |
FILE *fp) |
{ |
CHECK_INIT(_REENT, fp); |
return _fputwc_r (_REENT, wc, fp); |
} |
/contrib/sdk/sources/newlib/libc/stdio/fread.c |
---|
0,0 → 1,258 |
/* |
* 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 |
<<fread>>---read array elements from a file |
INDEX |
fread |
INDEX |
_fread_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>, |
FILE *<[fp]>); |
#include <stdio.h> |
size_t _fread_r(struct _reent *<[ptr]>, void *<[buf]>, |
size_t <[size]>, size_t <[count]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
size_t fread(<[buf]>, <[size]>, <[count]>, <[fp]>) |
char *<[buf]>; |
size_t <[size]>; |
size_t <[count]>; |
FILE *<[fp]>; |
#include <stdio.h> |
size_t _fread_r(<[ptr]>, <[buf]>, <[size]>, <[count]>, <[fp]>) |
struct _reent *<[ptr]>; |
char *<[buf]>; |
size_t <[size]>; |
size_t <[count]>; |
FILE *<[fp]>; |
DESCRIPTION |
<<fread>> attempts to copy, from the file or stream identified by |
<[fp]>, <[count]> elements (each of size <[size]>) into memory, |
starting at <[buf]>. <<fread>> may copy fewer elements than |
<[count]> if an error, or end of file, intervenes. |
<<fread>> also advances the file position indicator (if any) for |
<[fp]> by the number of @emph{characters} actually read. |
<<_fread_r>> is simply the reentrant version of <<fread>> that |
takes an additional reentrant structure pointer argument: <[ptr]>. |
RETURNS |
The result of <<fread>> is the number of elements it succeeded in |
reading. |
PORTABILITY |
ANSI C requires <<fread>>. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include <string.h> |
#include <malloc.h> |
#include "local.h" |
#ifdef __SCLE |
static size_t |
_DEFUN(crlf_r, (ptr, fp, buf, count, eof), |
struct _reent * ptr _AND |
FILE * fp _AND |
char * buf _AND |
size_t count _AND |
int eof) |
{ |
int r; |
char *s, *d, *e; |
if (count == 0) |
return 0; |
e = buf + count; |
for (s=d=buf; s<e-1; s++) |
{ |
if (*s == '\r' && s[1] == '\n') |
s++; |
*d++ = *s; |
} |
if (s < e) |
{ |
if (*s == '\r') |
{ |
int c = __sgetc_raw_r (ptr, fp); |
if (c == '\n') |
*s = '\n'; |
else |
ungetc (c, fp); |
} |
*d++ = *s++; |
} |
while (d < e) |
{ |
r = _getc_r (ptr, fp); |
if (r == EOF) |
return count - (e-d); |
*d++ = r; |
} |
return count; |
} |
#endif |
size_t |
_DEFUN(_fread_r, (ptr, buf, size, count, fp), |
struct _reent * ptr _AND |
_PTR buf _AND |
size_t size _AND |
size_t count _AND |
FILE * fp) |
{ |
register size_t resid; |
register char *p; |
register int r; |
size_t total; |
if ((resid = count * size) == 0) |
return 0; |
CHECK_INIT(ptr, fp); |
_flockfile (fp); |
ORIENT (fp, -1); |
if (fp->_r < 0) |
fp->_r = 0; |
total = resid; |
p = buf; |
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) |
/* Optimize unbuffered I/O. */ |
if (fp->_flags & __SNBF) |
{ |
/* First copy any available characters from ungetc buffer. */ |
int copy_size = resid > fp->_r ? fp->_r : resid; |
_CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) copy_size); |
fp->_p += copy_size; |
fp->_r -= copy_size; |
p += copy_size; |
resid -= copy_size; |
/* If still more data needed, free any allocated ungetc buffer. */ |
if (HASUB (fp) && resid > 0) |
FREEUB (ptr, fp); |
/* Finally read directly into user's buffer if needed. */ |
while (resid > 0) |
{ |
int rc = 0; |
/* save fp buffering state */ |
void *old_base = fp->_bf._base; |
void * old_p = fp->_p; |
int old_size = fp->_bf._size; |
/* allow __refill to use user's buffer */ |
fp->_bf._base = (unsigned char *) p; |
fp->_bf._size = resid; |
fp->_p = (unsigned char *) p; |
rc = __srefill_r (ptr, fp); |
/* restore fp buffering back to original state */ |
fp->_bf._base = old_base; |
fp->_bf._size = old_size; |
fp->_p = old_p; |
resid -= fp->_r; |
p += fp->_r; |
fp->_r = 0; |
if (rc) |
{ |
#ifdef __SCLE |
if (fp->_flags & __SCLE) |
{ |
_funlockfile (fp); |
return crlf_r (ptr, fp, buf, total-resid, 1) / size; |
} |
#endif |
_funlockfile (fp); |
return (total - resid) / size; |
} |
} |
} |
else |
#endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */ |
{ |
while (resid > (r = fp->_r)) |
{ |
_CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r); |
fp->_p += r; |
/* fp->_r = 0 ... done in __srefill */ |
p += r; |
resid -= r; |
if (__srefill_r (ptr, fp)) |
{ |
/* no more input: return partial result */ |
#ifdef __SCLE |
if (fp->_flags & __SCLE) |
{ |
_funlockfile (fp); |
return crlf_r (ptr, fp, buf, total-resid, 1) / size; |
} |
#endif |
_funlockfile (fp); |
return (total - resid) / size; |
} |
} |
_CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid); |
fp->_r -= resid; |
fp->_p += resid; |
} |
/* Perform any CR/LF clean-up if necessary. */ |
#ifdef __SCLE |
if (fp->_flags & __SCLE) |
{ |
_funlockfile (fp); |
return crlf_r(ptr, fp, buf, total, 0) / size; |
} |
#endif |
_funlockfile (fp); |
return count; |
} |
#ifndef _REENT_ONLY |
size_t |
_DEFUN(fread, (buf, size, count, fp), |
_PTR buf _AND |
size_t size _AND |
size_t count _AND |
FILE * fp) |
{ |
return _fread_r (_REENT, buf, size, count, fp); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/freopen.c |
---|
0,0 → 1,247 |
/* |
* 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 |
<<freopen>>---open a file using an existing file descriptor |
INDEX |
freopen |
INDEX |
_freopen_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
FILE *freopen(const char *<[file]>, const char *<[mode]>, |
FILE *<[fp]>); |
FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>, |
const char *<[mode]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
FILE *freopen(<[file]>, <[mode]>, <[fp]>) |
char *<[file]>; |
char *<[mode]>; |
FILE *<[fp]>; |
FILE *_freopen_r(<[ptr]>, <[file]>, <[mode]>, <[fp]>) |
struct _reent *<[ptr]>; |
char *<[file]>; |
char *<[mode]>; |
FILE *<[fp]>; |
DESCRIPTION |
Use this variant of <<fopen>> if you wish to specify a particular file |
descriptor <[fp]> (notably <<stdin>>, <<stdout>>, or <<stderr>>) for |
the file. |
If <[fp]> was associated with another file or stream, <<freopen>> |
closes that other file or stream (but ignores any errors while closing |
it). |
<[file]> and <[mode]> are used just as in <<fopen>>. |
If <[file]> is <<NULL>>, the underlying stream is modified rather than |
closed. The file cannot be given a more permissive access mode (for |
example, a <[mode]> of "w" will fail on a read-only file descriptor), |
but can change status such as append or binary mode. If modification |
is not possible, failure occurs. |
RETURNS |
If successful, the result is the same as the argument <[fp]>. If the |
file cannot be opened as specified, the result is <<NULL>>. |
PORTABILITY |
ANSI C requires <<freopen>>. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <time.h> |
#include <stdio.h> |
#include <string.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <stdlib.h> |
#include <sys/lock.h> |
#include "local.h" |
/* |
* Re-direct an existing, open (probably) file to some other file. |
*/ |
FILE * |
_DEFUN(_freopen_r, (ptr, file, mode, fp), |
struct _reent *ptr _AND |
const char *file _AND |
const char *mode _AND |
register FILE *fp) |
{ |
register int f; |
int flags, oflags; |
int e = 0; |
CHECK_INIT (ptr, fp); |
_flockfile (fp); |
if ((flags = __sflags (ptr, mode, &oflags)) == 0) |
{ |
_funlockfile (fp); |
_fclose_r (ptr, fp); |
return NULL; |
} |
/* |
* Remember whether the stream was open to begin with, and |
* which file descriptor (if any) was associated with it. |
* If it was attached to a descriptor, defer closing it, |
* so that, e.g., freopen("/dev/stdin", "r", stdin) works. |
* This is unnecessary if it was not a Unix file. |
*/ |
if (fp->_flags == 0) |
fp->_flags = __SEOF; /* hold on to it */ |
else |
{ |
if (fp->_flags & __SWR) |
_fflush_r (ptr, fp); |
/* |
* If close is NULL, closing is a no-op, hence pointless. |
* If file is NULL, the file should not be closed. |
*/ |
if (fp->_close != NULL && file != NULL) |
fp->_close (ptr, fp->_cookie); |
} |
/* |
* Now get a new descriptor to refer to the new file, or reuse the |
* existing file descriptor if file is NULL. |
*/ |
if (file != NULL) |
{ |
f = _open_r (ptr, (char *) file, oflags, 0666); |
e = ptr->_errno; |
} |
else |
{ |
#ifdef HAVE_FCNTL |
int oldflags; |
/* |
* Reuse the file descriptor, but only if the new access mode is |
* equal or less permissive than the old. F_SETFL correctly |
* ignores creation flags. |
*/ |
f = fp->_file; |
if ((oldflags = _fcntl_r (ptr, f, F_GETFL, 0)) == -1 |
|| ! ((oldflags & O_ACCMODE) == O_RDWR |
|| ((oldflags ^ oflags) & O_ACCMODE) == 0) |
|| _fcntl_r (ptr, f, F_SETFL, oflags) == -1) |
f = -1; |
#else |
/* We cannot modify without fcntl support. */ |
f = -1; |
#endif |
#ifdef __SCLE |
/* |
* F_SETFL doesn't change textmode. Don't mess with modes of ttys. |
*/ |
if (0 <= f && ! _isatty_r (ptr, f) |
&& setmode (f, oflags & (O_BINARY | O_TEXT)) == -1) |
f = -1; |
#endif |
if (f < 0) |
{ |
e = EBADF; |
if (fp->_close != NULL) |
fp->_close (ptr, fp->_cookie); |
} |
} |
/* |
* Finish closing fp. Even if the open succeeded above, |
* we cannot keep fp->_base: it may be the wrong size. |
* This loses the effect of any setbuffer calls, |
* but stdio has always done this before. |
*/ |
if (fp->_flags & __SMBF) |
_free_r (ptr, (char *) fp->_bf._base); |
fp->_w = 0; |
fp->_r = 0; |
fp->_p = NULL; |
fp->_bf._base = NULL; |
fp->_bf._size = 0; |
fp->_lbfsize = 0; |
if (HASUB (fp)) |
FREEUB (ptr, fp); |
fp->_ub._size = 0; |
if (HASLB (fp)) |
FREELB (ptr, fp); |
fp->_lb._size = 0; |
fp->_flags & ~__SORD; |
fp->_flags2 = 0; |
memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); |
if (f < 0) |
{ /* did not get it after all */ |
__sfp_lock_acquire (); |
fp->_flags = 0; /* set it free */ |
ptr->_errno = e; /* restore in case _close clobbered */ |
_funlockfile (fp); |
#ifndef __SINGLE_THREAD__ |
__lock_close_recursive (fp->_lock); |
#endif |
__sfp_lock_release (); |
return NULL; |
} |
fp->_flags = flags; |
fp->_file = f; |
fp->_cookie = (_PTR) fp; |
fp->_read = __sread; |
fp->_write = __swrite; |
fp->_seek = __sseek; |
fp->_close = __sclose; |
#ifdef __SCLE |
if (__stextmode (fp->_file)) |
fp->_flags |= __SCLE; |
#endif |
_funlockfile (fp); |
return fp; |
} |
#ifndef _REENT_ONLY |
FILE * |
_DEFUN(freopen, (file, mode, fp), |
_CONST char *file _AND |
_CONST char *mode _AND |
register FILE *fp) |
{ |
return _freopen_r (_REENT, file, mode, fp); |
} |
#endif /*!_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fscanf.c |
---|
0,0 → 1,78 |
/* |
* 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. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include "local.h" |
#ifndef _REENT_ONLY |
int |
#ifdef _HAVE_STDC |
fscanf(FILE *fp, _CONST char *fmt, ...) |
#else |
fscanf(FILE *fp, fmt, va_alist) |
FILE *fp; |
char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _vfscanf_r (_REENT, fp, fmt, ap); |
va_end (ap); |
return ret; |
} |
#endif /* !_REENT_ONLY */ |
int |
#ifdef _HAVE_STDC |
_fscanf_r(struct _reent *ptr, FILE *fp, _CONST char *fmt, ...) |
#else |
_fscanf_r(ptr, FILE *fp, fmt, va_alist) |
struct _reent *ptr; |
FILE *fp; |
char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _vfscanf_r (ptr, fp, fmt, ap); |
va_end (ap); |
return (ret); |
} |
/contrib/sdk/sources/newlib/libc/stdio/fseek.c |
---|
0,0 → 1,397 |
/* |
* 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 |
<<fseek>>, <<fseeko>>---set file position |
INDEX |
fseek |
INDEX |
fseeko |
INDEX |
_fseek_r |
INDEX |
_fseeko_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int fseek(FILE *<[fp]>, long <[offset]>, int <[whence]>) |
int fseeko(FILE *<[fp]>, off_t <[offset]>, int <[whence]>) |
int _fseek_r(struct _reent *<[ptr]>, FILE *<[fp]>, |
long <[offset]>, int <[whence]>) |
int _fseeko_r(struct _reent *<[ptr]>, FILE *<[fp]>, |
off_t <[offset]>, int <[whence]>) |
TRAD_SYNOPSIS |
#include <stdio.h> |
int fseek(<[fp]>, <[offset]>, <[whence]>) |
FILE *<[fp]>; |
long <[offset]>; |
int <[whence]>; |
int fseeko(<[fp]>, <[offset]>, <[whence]>) |
FILE *<[fp]>; |
off_t <[offset]>; |
int <[whence]>; |
int _fseek_r(<[ptr]>, <[fp]>, <[offset]>, <[whence]>) |
struct _reent *<[ptr]>; |
FILE *<[fp]>; |
long <[offset]>; |
int <[whence]>; |
int _fseeko_r(<[ptr]>, <[fp]>, <[offset]>, <[whence]>) |
struct _reent *<[ptr]>; |
FILE *<[fp]>; |
off_t <[offset]>; |
int <[whence]>; |
DESCRIPTION |
Objects of type <<FILE>> can have a ``position'' that records how much |
of the file your program has already read. Many of the <<stdio>> functions |
depend on this position, and many change it as a side effect. |
You can use <<fseek>>/<<fseeko>> to set the position for the file identified by |
<[fp]>. The value of <[offset]> determines the new position, in one |
of three ways selected by the value of <[whence]> (defined as macros |
in `<<stdio.h>>'): |
<<SEEK_SET>>---<[offset]> is the absolute file position (an offset |
from the beginning of the file) desired. <[offset]> must be positive. |
<<SEEK_CUR>>---<[offset]> is relative to the current file position. |
<[offset]> can meaningfully be either positive or negative. |
<<SEEK_END>>---<[offset]> is relative to the current end of file. |
<[offset]> can meaningfully be either positive (to increase the size |
of the file) or negative. |
See <<ftell>>/<<ftello>> to determine the current file position. |
RETURNS |
<<fseek>>/<<fseeko>> return <<0>> when successful. On failure, the |
result is <<EOF>>. The reason for failure is indicated in <<errno>>: |
either <<ESPIPE>> (the stream identified by <[fp]> doesn't support |
repositioning) or <<EINVAL>> (invalid file position). |
PORTABILITY |
ANSI C requires <<fseek>>. |
<<fseeko>> is defined by the Single Unix specification. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <string.h> |
#include <time.h> |
#include <fcntl.h> |
#include <stdlib.h> |
#include <errno.h> |
#include <sys/stat.h> |
#include "local.h" |
#define POS_ERR (-(_fpos_t)1) |
/* |
* Seek the given file to the given offset. |
* `Whence' must be one of the three SEEK_* macros. |
*/ |
int |
_DEFUN(_fseek_r, (ptr, fp, offset, whence), |
struct _reent *ptr _AND |
register FILE *fp _AND |
long offset _AND |
int whence) |
{ |
_fpos_t _EXFNPTR(seekfn, (struct _reent *, _PTR, _fpos_t, int)); |
_fpos_t target; |
_fpos_t curoff = 0; |
size_t n; |
#ifdef __USE_INTERNAL_STAT64 |
struct stat64 st; |
#else |
struct stat st; |
#endif |
int havepos; |
/* Make sure stdio is set up. */ |
CHECK_INIT (ptr, fp); |
_flockfile (fp); |
/* If we've been doing some writing, and we're in append mode |
then we don't really know where the filepos is. */ |
if (fp->_flags & __SAPP && fp->_flags & __SWR) |
{ |
/* So flush the buffer and seek to the end. */ |
_fflush_r (ptr, fp); |
} |
/* Have to be able to seek. */ |
if ((seekfn = fp->_seek) == NULL) |
{ |
ptr->_errno = ESPIPE; /* ??? */ |
_funlockfile (fp); |
return EOF; |
} |
/* |
* Change any SEEK_CUR to SEEK_SET, and check `whence' argument. |
* After this, whence is either SEEK_SET or SEEK_END. |
*/ |
switch (whence) |
{ |
case SEEK_CUR: |
/* |
* In order to seek relative to the current stream offset, |
* we have to first find the current stream offset a la |
* ftell (see ftell for details). |
*/ |
_fflush_r (ptr, fp); /* may adjust seek offset on append stream */ |
if (fp->_flags & __SOFF) |
curoff = fp->_offset; |
else |
{ |
curoff = seekfn (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR); |
if (curoff == -1L) |
{ |
_funlockfile (fp); |
return EOF; |
} |
} |
if (fp->_flags & __SRD) |
{ |
curoff -= fp->_r; |
if (HASUB (fp)) |
curoff -= fp->_ur; |
} |
else if (fp->_flags & __SWR && fp->_p != NULL) |
curoff += fp->_p - fp->_bf._base; |
offset += curoff; |
whence = SEEK_SET; |
havepos = 1; |
break; |
case SEEK_SET: |
case SEEK_END: |
havepos = 0; |
break; |
default: |
ptr->_errno = EINVAL; |
_funlockfile (fp); |
return (EOF); |
} |
/* |
* Can only optimise if: |
* reading (and not reading-and-writing); |
* not unbuffered; and |
* this is a `regular' Unix file (and hence seekfn==__sseek). |
* We must check __NBF first, because it is possible to have __NBF |
* and __SOPT both set. |
*/ |
if (fp->_bf._base == NULL) |
__smakebuf_r (ptr, fp); |
if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT)) |
goto dumb; |
if ((fp->_flags & __SOPT) == 0) |
{ |
if (seekfn != __sseek |
|| fp->_file < 0 |
#ifdef __USE_INTERNAL_STAT64 |
|| _fstat64_r (ptr, fp->_file, &st) |
#else |
|| _fstat_r (ptr, fp->_file, &st) |
#endif |
|| (st.st_mode & S_IFMT) != S_IFREG) |
{ |
fp->_flags |= __SNPT; |
goto dumb; |
} |
#ifdef HAVE_BLKSIZE |
fp->_blksize = st.st_blksize; |
#else |
fp->_blksize = 1024; |
#endif |
fp->_flags |= __SOPT; |
} |
/* |
* We are reading; we can try to optimise. |
* Figure out where we are going and where we are now. |
*/ |
if (whence == SEEK_SET) |
target = offset; |
else |
{ |
#ifdef __USE_INTERNAL_STAT64 |
if (_fstat64_r (ptr, fp->_file, &st)) |
#else |
if (_fstat_r (ptr, fp->_file, &st)) |
#endif |
goto dumb; |
target = st.st_size + offset; |
} |
if ((long)target != target) |
{ |
ptr->_errno = EOVERFLOW; |
_funlockfile (fp); |
return EOF; |
} |
if (!havepos) |
{ |
if (fp->_flags & __SOFF) |
curoff = fp->_offset; |
else |
{ |
curoff = seekfn (ptr, fp->_cookie, 0L, SEEK_CUR); |
if (curoff == POS_ERR) |
goto dumb; |
} |
curoff -= fp->_r; |
if (HASUB (fp)) |
curoff -= fp->_ur; |
} |
/* |
* Compute the number of bytes in the input buffer (pretending |
* that any ungetc() input has been discarded). Adjust current |
* offset backwards by this count so that it represents the |
* file offset for the first byte in the current input buffer. |
*/ |
if (HASUB (fp)) |
{ |
curoff += fp->_r; /* kill off ungetc */ |
n = fp->_up - fp->_bf._base; |
curoff -= n; |
n += fp->_ur; |
} |
else |
{ |
n = fp->_p - fp->_bf._base; |
curoff -= n; |
n += fp->_r; |
} |
/* |
* If the target offset is within the current buffer, |
* simply adjust the pointers, clear EOF, undo ungetc(), |
* and return. |
*/ |
if (target >= curoff && target < curoff + n) |
{ |
register int o = target - curoff; |
fp->_p = fp->_bf._base + o; |
fp->_r = n - o; |
if (HASUB (fp)) |
FREEUB (ptr, fp); |
fp->_flags &= ~__SEOF; |
memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); |
_funlockfile (fp); |
return 0; |
} |
/* |
* The place we want to get to is not within the current buffer, |
* but we can still be kind to the kernel copyout mechanism. |
* By aligning the file offset to a block boundary, we can let |
* the kernel use the VM hardware to map pages instead of |
* copying bytes laboriously. Using a block boundary also |
* ensures that we only read one block, rather than two. |
*/ |
curoff = target & ~(fp->_blksize - 1); |
if (seekfn (ptr, fp->_cookie, curoff, SEEK_SET) == POS_ERR) |
goto dumb; |
fp->_r = 0; |
fp->_p = fp->_bf._base; |
if (HASUB (fp)) |
FREEUB (ptr, fp); |
fp->_flags &= ~__SEOF; |
n = target - curoff; |
if (n) |
{ |
if (__srefill_r (ptr, fp) || fp->_r < n) |
goto dumb; |
fp->_p += n; |
fp->_r -= n; |
} |
memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); |
_funlockfile (fp); |
return 0; |
/* |
* We get here if we cannot optimise the seek ... just |
* do it. Allow the seek function to change fp->_bf._base. |
*/ |
dumb: |
if (_fflush_r (ptr, fp) |
|| seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR) |
{ |
_funlockfile (fp); |
return EOF; |
} |
/* success: clear EOF indicator and discard ungetc() data */ |
if (HASUB (fp)) |
FREEUB (ptr, fp); |
fp->_p = fp->_bf._base; |
fp->_r = 0; |
/* fp->_w = 0; *//* unnecessary (I think...) */ |
fp->_flags &= ~__SEOF; |
/* Reset no-optimization flag after successful seek. The |
no-optimization flag may be set in the case of a read |
stream that is flushed which by POSIX/SUSv3 standards, |
means that a corresponding seek must not optimize. The |
optimization is then allowed if no subsequent flush |
is performed. */ |
fp->_flags &= ~__SNPT; |
memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); |
_funlockfile (fp); |
return 0; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fseek, (fp, offset, whence), |
register FILE *fp _AND |
long offset _AND |
int whence) |
{ |
return _fseek_r (_REENT, fp, offset, whence); |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fseeko.c |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2002, Red Hat Inc. |
* 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. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
int |
_DEFUN(_fseeko_r, (ptr, fp, offset, whence), |
struct _reent *ptr _AND |
register FILE *fp _AND |
_off_t offset _AND |
int whence) |
{ |
return _fseek_r (ptr, fp, (long)offset, whence); |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(fseeko, (fp, offset, whence), |
register FILE *fp _AND |
_off_t offset _AND |
int whence) |
{ |
/* for now we simply cast since off_t should be long */ |
return _fseek_r (_REENT, fp, (long)offset, whence); |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/ftell.c |
---|
0,0 → 1,177 |
/* |
* 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 |
<<ftell>>, <<ftello>>---return position in a stream or file |
INDEX |
ftell |
INDEX |
ftello |
INDEX |
_ftell_r |
INDEX |
_ftello_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
long ftell(FILE *<[fp]>); |
off_t ftello(FILE *<[fp]>); |
long _ftell_r(struct _reent *<[ptr]>, FILE *<[fp]>); |
off_t _ftello_r(struct _reent *<[ptr]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
long ftell(<[fp]>) |
FILE *<[fp]>; |
off_t ftello(<[fp]>) |
FILE *<[fp]>; |
long _ftell_r(<[ptr]>, <[fp]>) |
struct _reent *<[ptr]>; |
FILE *<[fp]>; |
off_t _ftello_r(<[ptr]>, <[fp]>) |
struct _reent *<[ptr]>; |
FILE *<[fp]>; |
DESCRIPTION |
Objects of type <<FILE>> can have a ``position'' that records how much |
of the file your program has already read. Many of the <<stdio>> functions |
depend on this position, and many change it as a side effect. |
The result of <<ftell>>/<<ftello>> is the current position for a file |
identified by <[fp]>. If you record this result, you can later |
use it with <<fseek>>/<<fseeko>> to return the file to this |
position. The difference between <<ftell>> and <<ftello>> is that |
<<ftell>> returns <<long>> and <<ftello>> returns <<off_t>>. |
In the current implementation, <<ftell>>/<<ftello>> simply uses a character |
count to represent the file position; this is the same number that |
would be recorded by <<fgetpos>>. |
RETURNS |
<<ftell>>/<<ftello>> return the file position, if possible. If they cannot do |
this, they return <<-1L>>. Failure occurs on streams that do not support |
positioning; the global <<errno>> indicates this condition with the |
value <<ESPIPE>>. |
PORTABILITY |
<<ftell>> is required by the ANSI C standard, but the meaning of its |
result (when successful) is not specified beyond requiring that it be |
acceptable as an argument to <<fseek>>. In particular, other |
conforming C implementations may return a different result from |
<<ftell>> than what <<fgetpos>> records. |
<<ftello>> is defined by the Single Unix specification. |
No supporting OS subroutines are required. |
*/ |
#if defined(LIBC_SCCS) && !defined(lint) |
static char sccsid[] = "%W% (Berkeley) %G%"; |
#endif /* LIBC_SCCS and not lint */ |
/* |
* ftell: return current offset. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <errno.h> |
#include "local.h" |
long |
_DEFUN(_ftell_r, (ptr, fp), |
struct _reent *ptr _AND |
register FILE * fp) |
{ |
_fpos_t pos; |
/* Ensure stdio is set up. */ |
CHECK_INIT (ptr, fp); |
_flockfile (fp); |
if (fp->_seek == NULL) |
{ |
ptr->_errno = ESPIPE; |
_funlockfile (fp); |
return -1L; |
} |
/* Find offset of underlying I/O object, then adjust for buffered |
bytes. Flush a write stream, since the offset may be altered if |
the stream is appending. Do not flush a read stream, since we |
must not lose the ungetc buffer. */ |
if (fp->_flags & __SWR) |
_fflush_r (ptr, fp); |
if (fp->_flags & __SOFF) |
pos = fp->_offset; |
else |
{ |
pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR); |
if (pos == -1L) |
{ |
_funlockfile (fp); |
return pos; |
} |
} |
if (fp->_flags & __SRD) |
{ |
/* |
* Reading. Any unread characters (including |
* those from ungetc) cause the position to be |
* smaller than that in the underlying object. |
*/ |
pos -= fp->_r; |
if (HASUB (fp)) |
pos -= fp->_ur; |
} |
else if ((fp->_flags & __SWR) && fp->_p != NULL) |
{ |
/* |
* Writing. Any buffered characters cause the |
* position to be greater than that in the |
* underlying object. |
*/ |
pos += fp->_p - fp->_bf._base; |
} |
_funlockfile (fp); |
if ((long)pos != pos) |
{ |
pos = -1; |
ptr->_errno = EOVERFLOW; |
} |
return pos; |
} |
#ifndef _REENT_ONLY |
long |
_DEFUN(ftell, (fp), |
register FILE * fp) |
{ |
return _ftell_r (_REENT, fp); |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/ftello.c |
---|
0,0 → 1,40 |
/* |
* Copyright (c) 2002, Red Hat Inc. |
* 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. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
_off_t |
_DEFUN(_ftello_r, (ptr, fp), |
struct _reent * ptr _AND |
register FILE * fp) |
{ |
/* for now we simply cast since off_t should be long */ |
return (_off_t)_ftell_r (ptr, fp); |
} |
#ifndef _REENT_ONLY |
_off_t |
_DEFUN(ftello, (fp), |
register FILE * fp) |
{ |
return (_off_t)_ftell_r (_REENT, fp); |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/fvwrite.c |
---|
0,0 → 1,267 |
/* |
* 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. |
*/ |
/* No user fns here. Pesch 15apr92. */ |
#include <_ansi.h> |
#include <stdio.h> |
#include <string.h> |
#include <stdlib.h> |
#include <errno.h> |
#include "local.h" |
#include "fvwrite.h" |
#define MIN(a, b) ((a) < (b) ? (a) : (b)) |
#define COPY(n) _CAST_VOID memmove ((_PTR) fp->_p, (_PTR) p, (size_t) (n)) |
#define GETIOV(extra_work) \ |
while (len == 0) \ |
{ \ |
extra_work; \ |
p = iov->iov_base; \ |
len = iov->iov_len; \ |
iov++; \ |
} |
/* |
* Write some memory regions. Return zero on success, EOF on error. |
* |
* This routine is large and unsightly, but most of the ugliness due |
* to the three different kinds of output buffering is handled here. |
*/ |
int |
_DEFUN(__sfvwrite_r, (ptr, fp, uio), |
struct _reent *ptr _AND |
register FILE *fp _AND |
register struct __suio *uio) |
{ |
register size_t len; |
register _CONST char *p = NULL; |
register struct __siov *iov; |
register int w, s; |
char *nl; |
int nlknown, nldist; |
if ((len = uio->uio_resid) == 0) |
return 0; |
/* make sure we can write */ |
if (cantwrite (ptr, fp)) |
return EOF; |
iov = uio->uio_iov; |
len = 0; |
#ifdef __SCLE |
if (fp->_flags & __SCLE) /* text mode */ |
{ |
do |
{ |
GETIOV (;); |
while (len > 0) |
{ |
if (putc (*p, fp) == EOF) |
return EOF; |
p++; |
len--; |
uio->uio_resid--; |
} |
} |
while (uio->uio_resid > 0); |
return 0; |
} |
#endif |
if (fp->_flags & __SNBF) |
{ |
/* |
* Unbuffered: write up to BUFSIZ bytes at a time. |
*/ |
do |
{ |
GETIOV (;); |
w = fp->_write (ptr, fp->_cookie, p, MIN (len, BUFSIZ)); |
if (w <= 0) |
goto err; |
p += w; |
len -= w; |
} |
while ((uio->uio_resid -= w) != 0); |
} |
else if ((fp->_flags & __SLBF) == 0) |
{ |
/* |
* Fully buffered: fill partially full buffer, if any, |
* and then flush. If there is no partial buffer, write |
* one _bf._size byte chunk directly (without copying). |
* |
* String output is a special case: write as many bytes |
* as fit, but pretend we wrote everything. This makes |
* snprintf() return the number of bytes needed, rather |
* than the number used, and avoids its write function |
* (so that the write function can be invalid). If |
* we are dealing with the asprintf routines, we will |
* dynamically increase the buffer size as needed. |
*/ |
do |
{ |
GETIOV (;); |
w = fp->_w; |
if (fp->_flags & __SSTR) |
{ |
if (len >= w && fp->_flags & (__SMBF | __SOPT)) |
{ /* must be asprintf family */ |
unsigned char *str; |
int curpos = (fp->_p - fp->_bf._base); |
/* Choose a geometric growth factor to avoid |
quadratic realloc behavior, but use a rate less |
than (1+sqrt(5))/2 to accomodate malloc |
overhead. asprintf EXPECTS us to overallocate, so |
that it can add a trailing \0 without |
reallocating. The new allocation should thus be |
max(prev_size*1.5, curpos+len+1). */ |
int newsize = fp->_bf._size * 3 / 2; |
if (newsize < curpos + len + 1) |
newsize = curpos + len + 1; |
if (fp->_flags & __SOPT) |
{ |
/* asnprintf leaves original buffer alone. */ |
str = (unsigned char *)_malloc_r (ptr, newsize); |
if (!str) |
{ |
ptr->_errno = ENOMEM; |
goto err; |
} |
memcpy (str, fp->_bf._base, curpos); |
fp->_flags = (fp->_flags & ~__SOPT) | __SMBF; |
} |
else |
{ |
str = (unsigned char *)_realloc_r (ptr, fp->_bf._base, |
newsize); |
if (!str) |
{ |
/* Free buffer which is no longer used. */ |
_free_r (ptr, fp->_bf._base); |
/* Ensure correct errno, even if free changed it. */ |
ptr->_errno = ENOMEM; |
goto err; |
} |
} |
fp->_bf._base = str; |
fp->_p = str + curpos; |
fp->_bf._size = newsize; |
w = len; |
fp->_w = newsize - curpos; |
} |
if (len < w) |
w = len; |
COPY (w); /* copy MIN(fp->_w,len), */ |
fp->_w -= w; |
fp->_p += w; |
w = len; /* but pretend copied all */ |
} |
else if (fp->_p > fp->_bf._base && len > w) |
{ |
/* fill and flush */ |
COPY (w); |
/* fp->_w -= w; *//* unneeded */ |
fp->_p += w; |
if (_fflush_r (ptr, fp)) |
goto err; |
} |
else if (len >= (w = fp->_bf._size)) |
{ |
/* write directly */ |
w = fp->_write (ptr, fp->_cookie, p, w); |
if (w <= 0) |
goto err; |
} |
else |
{ |
/* fill and done */ |
w = len; |
COPY (w); |
fp->_w -= w; |
fp->_p += w; |
} |
p += w; |
len -= w; |
} |
while ((uio->uio_resid -= w) != 0); |
} |
else |
{ |
/* |
* Line buffered: like fully buffered, but we |
* must check for newlines. Compute the distance |
* to the first newline (including the newline), |
* or `infinity' if there is none, then pretend |
* that the amount to write is MIN(len,nldist). |
*/ |
nlknown = 0; |
nldist = 0; |
do |
{ |
GETIOV (nlknown = 0); |
if (!nlknown) |
{ |
nl = memchr ((_PTR) p, '\n', len); |
nldist = nl ? nl + 1 - p : len + 1; |
nlknown = 1; |
} |
s = MIN (len, nldist); |
w = fp->_w + fp->_bf._size; |
if (fp->_p > fp->_bf._base && s > w) |
{ |
COPY (w); |
/* fp->_w -= w; */ |
fp->_p += w; |
if (_fflush_r (ptr, fp)) |
goto err; |
} |
else if (s >= (w = fp->_bf._size)) |
{ |
w = fp->_write (ptr, fp->_cookie, p, w); |
if (w <= 0) |
goto err; |
} |
else |
{ |
w = s; |
COPY (w); |
fp->_w -= w; |
fp->_p += w; |
} |
if ((nldist -= w) == 0) |
{ |
/* copied the newline: flush and forget */ |
if (_fflush_r (ptr, fp)) |
goto err; |
nlknown = 0; |
} |
p += w; |
len -= w; |
} |
while ((uio->uio_resid -= w) != 0); |
} |
return 0; |
err: |
fp->_flags |= __SERR; |
return EOF; |
} |
/contrib/sdk/sources/newlib/libc/stdio/fvwrite.h |
---|
0,0 → 1,36 |
/* |
* 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. |
*/ |
/* %W% (Berkeley) %G% */ |
#include <_ansi.h> |
/* |
* I/O descriptors for __sfvwrite_r(). |
*/ |
struct __siov { |
_CONST _PTR iov_base; |
size_t iov_len; |
}; |
struct __suio { |
struct __siov *uio_iov; |
int uio_iovcnt; |
int uio_resid; |
}; |
extern int _EXFUN(__sfvwrite_r,(struct _reent *, FILE *, struct __suio *)); |
extern int _EXFUN(__swsetup_r,(struct _reent *, FILE *)); |
/contrib/sdk/sources/newlib/libc/stdio/fwalk.c |
---|
0,0 → 1,86 |
/* |
* 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. |
*/ |
/* No user fns here. Pesch 15apr92. */ |
#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 <stdlib.h> |
#include <errno.h> |
#include "local.h" |
int |
_DEFUN(_fwalk, (ptr, function), |
struct _reent *ptr _AND |
register int (*function) (FILE *)) |
{ |
register FILE *fp; |
register int n, ret = 0; |
register struct _glue *g; |
/* |
* It should be safe to walk the list without locking it; |
* new nodes are only added to the end and none are ever |
* removed. |
* |
* Avoid locking this list while walking it or else you will |
* introduce a potential deadlock in [at least] refill.c. |
*/ |
for (g = &ptr->__sglue; g != NULL; g = g->_next) |
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) |
if (fp->_flags != 0) |
{ |
if (fp->_flags != 0 && fp->_flags != 1 && fp->_file != -1) |
ret |= (*function) (fp); |
} |
return ret; |
} |
/* Special version of __fwalk where the function pointer is a reentrant |
I/O function (e.g. _fclose_r). */ |
int |
_DEFUN(_fwalk_reent, (ptr, reent_function), |
struct _reent *ptr _AND |
register int (*reent_function) (struct _reent *, FILE *)) |
{ |
register FILE *fp; |
register int n, ret = 0; |
register struct _glue *g; |
/* |
* It should be safe to walk the list without locking it; |
* new nodes are only added to the end and none are ever |
* removed. |
* |
* Avoid locking this list while walking it or else you will |
* introduce a potential deadlock in [at least] refill.c. |
*/ |
for (g = &ptr->__sglue; g != NULL; g = g->_next) |
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) |
if (fp->_flags != 0) |
{ |
if (fp->_flags != 0 && fp->_flags != 1 && fp->_file != -1) |
ret |= (*reent_function) (ptr, fp); |
} |
return ret; |
} |
/contrib/sdk/sources/newlib/libc/stdio/fwrite.c |
---|
0,0 → 1,143 |
/* |
* 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 |
<<fwrite>>---write array elements |
INDEX |
fwrite |
INDEX |
_fwrite_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
size_t fwrite(const void *<[buf]>, size_t <[size]>, |
size_t <[count]>, FILE *<[fp]>); |
#include <stdio.h> |
size_t _fwrite_r(struct _reent *<[ptr]>, const void *<[buf]>, size_t <[size]>, |
size_t <[count]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
size_t fwrite(<[buf]>, <[size]>, <[count]>, <[fp]>) |
char *<[buf]>; |
size_t <[size]>; |
size_t <[count]>; |
FILE *<[fp]>; |
#include <stdio.h> |
size_t _fwrite_r(<[ptr]>, <[buf]>, <[size]>, <[count]>, <[fp]>) |
struct _reent *<[ptr]>; |
char *<[buf]>; |
size_t <[size]>; |
size_t <[count]>; |
FILE *<[fp]>; |
DESCRIPTION |
<<fwrite>> attempts to copy, starting from the memory location |
<[buf]>, <[count]> elements (each of size <[size]>) into the file or |
stream identified by <[fp]>. <<fwrite>> may copy fewer elements than |
<[count]> if an error intervenes. |
<<fwrite>> also advances the file position indicator (if any) for |
<[fp]> by the number of @emph{characters} actually written. |
<<_fwrite_r>> is simply the reentrant version of <<fwrite>> that |
takes an additional reentrant structure argument: <[ptr]>. |
RETURNS |
If <<fwrite>> succeeds in writing all the elements you specify, the |
result is the same as the argument <[count]>. In any event, the |
result is the number of complete elements that <<fwrite>> copied to |
the file. |
PORTABILITY |
ANSI C requires <<fwrite>>. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#if defined(LIBC_SCCS) && !defined(lint) |
static char sccsid[] = "%W% (Berkeley) %G%"; |
#endif /* LIBC_SCCS and not lint */ |
#include <_ansi.h> |
#include <stdio.h> |
#include <string.h> |
#if 0 |
#include <sys/stdc.h> |
#endif |
#include "local.h" |
#if 1 |
#include "fvwrite.h" |
#endif |
/* |
* Write `count' objects (each size `size') from memory to the given file. |
* Return the number of whole objects written. |
*/ |
size_t |
_DEFUN(_fwrite_r, (ptr, buf, size, count, fp), |
struct _reent * ptr _AND |
_CONST _PTR buf _AND |
size_t size _AND |
size_t count _AND |
FILE * fp) |
{ |
size_t n; |
struct __suio uio; |
struct __siov iov; |
iov.iov_base = buf; |
uio.uio_resid = iov.iov_len = n = count * size; |
uio.uio_iov = &iov; |
uio.uio_iovcnt = 1; |
/* |
* The usual case is success (__sfvwrite_r returns 0); |
* skip the divide if this happens, since divides are |
* generally slow and since this occurs whenever size==0. |
*/ |
CHECK_INIT(ptr, fp); |
_flockfile (fp); |
ORIENT (fp, -1); |
if (__sfvwrite_r (ptr, fp, &uio) == 0) |
{ |
_funlockfile (fp); |
return count; |
} |
_funlockfile (fp); |
return (n - uio.uio_resid) / size; |
} |
#ifndef _REENT_ONLY |
size_t |
_DEFUN(fwrite, (buf, size, count, fp), |
_CONST _PTR buf _AND |
size_t size _AND |
size_t count _AND |
FILE * fp) |
{ |
return _fwrite_r (_REENT, buf, size, count, fp); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/local.h |
---|
0,0 → 1,229 |
/* |
* 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. |
* |
* %W% (UofMD/Berkeley) %G% |
*/ |
/* |
* Information local to this implementation of stdio, |
* in particular, macros and private variables. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdarg.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <stdio.h> |
#ifdef __SCLE |
# include <io.h> |
#endif |
extern u_char *_EXFUN(__sccl, (char *, u_char *fmt)); |
extern int _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); |
extern int _EXFUN(__ssvfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); |
extern int _EXFUN(__svfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); |
extern int _EXFUN(__ssvfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); |
extern int _EXFUN(__svfwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list)); |
extern int _EXFUN(__ssvfwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list)); |
extern int _EXFUN(__svfiwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list)); |
extern int _EXFUN(__ssvfiwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list)); |
int _EXFUN(_svfprintf_r,(struct _reent *, FILE *, const char *, |
va_list) |
_ATTRIBUTE ((__format__ (__printf__, 3, 0)))); |
int _EXFUN(_svfiprintf_r,(struct _reent *, FILE *, const char *, |
va_list) |
_ATTRIBUTE ((__format__ (__printf__, 3, 0)))); |
int _EXFUN(_svfwprintf_r,(struct _reent *, FILE *, const wchar_t *, |
va_list)); |
int _EXFUN(_svfiwprintf_r,(struct _reent *, FILE *, const wchar_t *, |
va_list)); |
extern FILE *_EXFUN(__sfp,(struct _reent *)); |
extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*)); |
extern int _EXFUN(__sflush_r,(struct _reent *,FILE *)); |
extern int _EXFUN(__srefill_r,(struct _reent *,FILE *)); |
extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *, |
int)); |
extern _READ_WRITE_RETURN_TYPE _EXFUN(__seofread,(struct _reent *, void *, |
char *, int)); |
extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(struct _reent *, void *, |
const char *, int)); |
extern _fpos_t _EXFUN(__sseek,(struct _reent *, void *, _fpos_t, int)); |
extern int _EXFUN(__sclose,(struct _reent *, void *)); |
extern int _EXFUN(__stextmode,(int)); |
extern _VOID _EXFUN(__sinit,(struct _reent *)); |
extern _VOID _EXFUN(_cleanup_r,(struct _reent *)); |
extern _VOID _EXFUN(__smakebuf_r,(struct _reent *, FILE *)); |
extern int _EXFUN(_fwalk,(struct _reent *, int (*)(FILE *))); |
extern int _EXFUN(_fwalk_reent,(struct _reent *, int (*)(struct _reent *, FILE *))); |
struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n)); |
extern int _EXFUN(__submore, (struct _reent *, FILE *)); |
#ifdef __LARGE64_FILES |
extern _fpos64_t _EXFUN(__sseek64,(struct _reent *, void *, _fpos64_t, int)); |
extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *, |
const char *, int)); |
#endif |
/* Called by the main entry point fns to ensure stdio has been initialized. */ |
#ifdef _REENT_SMALL |
#define CHECK_INIT(ptr, fp) \ |
do \ |
{ \ |
if ((ptr) && !(ptr)->__sdidinit) \ |
__sinit (ptr); \ |
if ((fp) == (FILE *)&__sf_fake_stdin) \ |
(fp) = _stdin_r(ptr); \ |
else if ((fp) == (FILE *)&__sf_fake_stdout) \ |
(fp) = _stdout_r(ptr); \ |
else if ((fp) == (FILE *)&__sf_fake_stderr) \ |
(fp) = _stderr_r(ptr); \ |
} \ |
while (0) |
#else /* !_REENT_SMALL */ |
#define CHECK_INIT(ptr, fp) \ |
do \ |
{ \ |
if ((ptr) && !(ptr)->__sdidinit) \ |
__sinit (ptr); \ |
} \ |
while (0) |
#endif /* !_REENT_SMALL */ |
#define CHECK_STD_INIT(ptr) \ |
do \ |
{ \ |
if ((ptr) && !(ptr)->__sdidinit) \ |
__sinit (ptr); \ |
} \ |
while (0) |
/* Return true and set errno and stream error flag iff the given FILE |
cannot be written now. */ |
#define cantwrite(ptr, fp) \ |
((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \ |
__swsetup_r(ptr, fp)) |
/* Test whether the given stdio file has an active ungetc buffer; |
release such a buffer, without restoring ordinary unread data. */ |
#define HASUB(fp) ((fp)->_ub._base != NULL) |
#define FREEUB(ptr, fp) { \ |
if ((fp)->_ub._base != (fp)->_ubuf) \ |
_free_r(ptr, (char *)(fp)->_ub._base); \ |
(fp)->_ub._base = NULL; \ |
} |
/* Test for an fgetline() buffer. */ |
#define HASLB(fp) ((fp)->_lb._base != NULL) |
#define FREELB(ptr, fp) { _free_r(ptr,(char *)(fp)->_lb._base); \ |
(fp)->_lb._base = NULL; } |
/* |
* Set the orientation for a stream. If o > 0, the stream has wide- |
* orientation. If o < 0, the stream has byte-orientation. |
*/ |
#define ORIENT(fp,ori) \ |
do \ |
{ \ |
if (!((fp)->_flags & __SORD)) \ |
{ \ |
(fp)->_flags |= __SORD; \ |
if (ori > 0) \ |
(fp)->_flags2 |= __SWID; \ |
else \ |
(fp)->_flags2 &= ~__SWID; \ |
} \ |
} \ |
while (0) |
/* WARNING: _dcvt is defined in the stdlib directory, not here! */ |
char *_EXFUN(_dcvt,(struct _reent *, char *, double, int, int, char, int)); |
char *_EXFUN(_sicvt,(char *, short, char)); |
char *_EXFUN(_icvt,(char *, int, char)); |
char *_EXFUN(_licvt,(char *, long, char)); |
#ifdef __GNUC__ |
char *_EXFUN(_llicvt,(char *, long long, char)); |
#endif |
#define CVT_BUF_SIZE 128 |
#define NDYNAMIC 4 /* add four more whenever necessary */ |
#ifdef __SINGLE_THREAD__ |
#define __sfp_lock_acquire() |
#define __sfp_lock_release() |
#define __sinit_lock_acquire() |
#define __sinit_lock_release() |
#else |
_VOID _EXFUN(__sfp_lock_acquire,(_VOID)); |
_VOID _EXFUN(__sfp_lock_release,(_VOID)); |
_VOID _EXFUN(__sinit_lock_acquire,(_VOID)); |
_VOID _EXFUN(__sinit_lock_release,(_VOID)); |
#endif |
/* Types used in positional argument support in vfprinf/vfwprintf. |
The implementation is char/wchar_t dependent but the class and state |
tables are only defined once in vfprintf.c. */ |
typedef enum { |
ZERO, /* '0' */ |
DIGIT, /* '1-9' */ |
DOLLAR, /* '$' */ |
MODFR, /* spec modifier */ |
SPEC, /* format specifier */ |
DOT, /* '.' */ |
STAR, /* '*' */ |
FLAG, /* format flag */ |
OTHER, /* all other chars */ |
MAX_CH_CLASS /* place-holder */ |
} __CH_CLASS; |
typedef enum { |
START, /* start */ |
SFLAG, /* seen a flag */ |
WDIG, /* seen digits in width area */ |
WIDTH, /* processed width */ |
SMOD, /* seen spec modifier */ |
SDOT, /* seen dot */ |
VARW, /* have variable width specifier */ |
VARP, /* have variable precision specifier */ |
PREC, /* processed precision */ |
VWDIG, /* have digits in variable width specification */ |
VPDIG, /* have digits in variable precision specification */ |
DONE, /* done */ |
MAX_STATE, /* place-holder */ |
} __STATE; |
typedef enum { |
NOOP, /* do nothing */ |
NUMBER, /* build a number from digits */ |
SKIPNUM, /* skip over digits */ |
GETMOD, /* get and process format modifier */ |
GETARG, /* get and process argument */ |
GETPW, /* get variable precision or width */ |
GETPWB, /* get variable precision or width and pushback fmt char */ |
GETPOS, /* get positional parameter value */ |
PWPOS, /* get positional parameter value for variable width or precision */ |
} __ACTION; |
extern _CONST __CH_CLASS __chclass[256]; |
extern _CONST __STATE __state_table[MAX_STATE][MAX_CH_CLASS]; |
extern _CONST __ACTION __action_table[MAX_STATE][MAX_CH_CLASS]; |
/contrib/sdk/sources/newlib/libc/stdio/makebuf.c |
---|
0,0 → 1,113 |
/* |
* 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. |
*/ |
/* No user fns here. Pesch 15apr92. */ |
#include <_ansi.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <sys/stat.h> |
#include <sys/types.h> |
#include <sys/unistd.h> |
#include "local.h" |
#define _DEFAULT_ASPRINTF_BUFSIZE 64 |
/* |
* Allocate a file buffer, or switch to unbuffered I/O. |
* Per the ANSI C standard, ALL tty devices default to line buffered. |
* |
* As a side effect, we set __SOPT or __SNPT (en/dis-able fseek |
* optimization) right after the _fstat() that finds the buffer size. |
*/ |
_VOID |
_DEFUN(__smakebuf_r, (ptr, fp), |
struct _reent *ptr _AND |
register FILE *fp) |
{ |
register size_t size, couldbetty; |
register _PTR p; |
#ifdef __USE_INTERNAL_STAT64 |
struct stat64 st; |
#else |
struct stat st; |
#endif |
if (fp->_flags & __SNBF) |
{ |
fp->_bf._base = fp->_p = fp->_nbuf; |
fp->_bf._size = 1; |
return; |
} |
#ifdef __USE_INTERNAL_STAT64 |
if (fp->_file < 0 || _fstat64_r (ptr, fp->_file, &st) < 0) |
#else |
if (fp->_file < 0 || _fstat_r (ptr, fp->_file, &st) < 0) |
#endif |
{ |
couldbetty = 0; |
/* Check if we are be called by asprintf family for initial buffer. */ |
if (fp->_flags & __SMBF) |
size = _DEFAULT_ASPRINTF_BUFSIZE; |
else |
size = BUFSIZ; |
/* do not try to optimise fseek() */ |
fp->_flags |= __SNPT; |
} |
else |
{ |
couldbetty = (st.st_mode & S_IFMT) == S_IFCHR; |
#ifdef HAVE_BLKSIZE |
size = st.st_blksize <= 0 ? BUFSIZ : st.st_blksize; |
#else |
size = BUFSIZ; |
#endif |
/* |
* Optimize fseek() only if it is a regular file. |
* (The test for __sseek is mainly paranoia.) |
*/ |
if ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek) |
{ |
fp->_flags |= __SOPT; |
#ifdef HAVE_BLKSIZE |
fp->_blksize = st.st_blksize; |
#else |
fp->_blksize = 1024; |
#endif |
} |
else |
fp->_flags |= __SNPT; |
} |
if ((p = _malloc_r (ptr, size)) == NULL) |
{ |
if (!(fp->_flags & __SSTR)) |
{ |
fp->_flags |= __SNBF; |
fp->_bf._base = fp->_p = fp->_nbuf; |
fp->_bf._size = 1; |
} |
} |
else |
{ |
ptr->__cleanup = _cleanup_r; |
fp->_flags |= __SMBF; |
fp->_bf._base = fp->_p = (unsigned char *) p; |
fp->_bf._size = size; |
if (couldbetty && _isatty_r (ptr, fp->_file)) |
fp->_flags |= __SLBF; |
} |
} |
/contrib/sdk/sources/newlib/libc/stdio/printf.c |
---|
0,0 → 1,57 |
/* |
* 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 sprintf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdarg.h> |
#include "local.h" |
int |
_DEFUN(_printf_r, (ptr, fmt), |
struct _reent *ptr _AND |
const char *fmt _DOTS) |
{ |
int ret; |
va_list ap; |
_REENT_SMALL_CHECK_INIT (ptr); |
va_start (ap, fmt); |
ret = _vfprintf_r (ptr, _stdout_r (ptr), fmt, ap); |
va_end (ap); |
return ret; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(printf, (fmt), |
const char *fmt _DOTS) |
{ |
int ret; |
va_list ap; |
struct _reent *ptr = _REENT; |
_REENT_SMALL_CHECK_INIT (ptr); |
va_start (ap, fmt); |
ret = _vfprintf_r (ptr, _stdout_r (ptr), fmt, ap); |
va_end (ap); |
return ret; |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/putc.c |
---|
0,0 → 1,124 |
/* |
* 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 |
<<putc>>---write a character (macro) |
INDEX |
putc |
INDEX |
_putc_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int putc(int <[ch]>, FILE *<[fp]>); |
#include <stdio.h> |
int _putc_r(struct _reent *<[ptr]>, int <[ch]>, FILE *<[fp]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int putc(<[ch]>, <[fp]>) |
int <[ch]>; |
FILE *<[fp]>; |
#include <stdio.h> |
int _putc_r(<[ptr]>, <[ch]>, <[fp]>) |
struct _reent *<[ptr]>; |
int <[ch]>; |
FILE *<[fp]>; |
DESCRIPTION |
<<putc>> is a macro, defined in <<stdio.h>>. <<putc>> |
writes the argument <[ch]> to the file or stream identified by |
<[fp]>, after converting it from an <<int>> to an <<unsigned char>>. |
If the file was opened with append mode (or if the stream cannot |
support positioning), then the new character goes at the end of the |
file or stream. Otherwise, the new character is written at the |
current value of the position indicator, and the position indicator |
advances by one. |
For a subroutine version of this macro, see <<fputc>>. |
The <<_putc_r>> function is simply the reentrant version of |
<<putc>> that takes an additional reentrant structure argument: <[ptr]>. |
RETURNS |
If successful, <<putc>> returns its argument <[ch]>. If an error |
intervenes, the result is <<EOF>>. You can use `<<ferror(<[fp]>)>>' to |
query for errors. |
PORTABILITY |
ANSI C requires <<putc>>; it suggests, but does not require, that |
<<putc>> be implemented as a macro. The standard explicitly permits |
macro implementations of <<putc>> to use the <[fp]> argument more than once; |
therefore, in a portable program, you should not use an expression |
with side effects as this argument. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#if defined(LIBC_SCCS) && !defined(lint) |
static char sccsid[] = "%W% (Berkeley) %G%"; |
#endif /* LIBC_SCCS and not lint */ |
#include <_ansi.h> |
#include <stdio.h> |
#include "local.h" |
/* |
* A subroutine version of the macro putc. |
*/ |
#undef putc |
int |
_DEFUN(_putc_r, (ptr, c, fp), |
struct _reent *ptr _AND |
int c _AND |
register FILE *fp) |
{ |
int result; |
CHECK_INIT (ptr, fp); |
_flockfile (fp); |
result = __sputc_r (ptr, c, fp); |
_funlockfile (fp); |
return result; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(putc, (c, fp), |
int c _AND |
register FILE *fp) |
{ |
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) |
int result; |
CHECK_INIT (_REENT, fp); |
_flockfile (fp); |
result = __sputc_r (_REENT, c, fp); |
_funlockfile (fp); |
return result; |
#else |
return _putc_r (_REENT, c, fp); |
#endif |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/putchar.c |
---|
0,0 → 1,97 |
/* |
* 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 |
<<putchar>>---write a character (macro) |
INDEX |
putchar |
INDEX |
_putchar_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int putchar(int <[ch]>); |
int _putchar_r(struct _reent *<[reent]>, int <[ch]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int putchar(<[ch]>) |
int <[ch]>; |
int _putchar_r(<[reent]>, <[ch]>) |
struct _reent *<[reent]>; |
int <[ch]>; |
DESCRIPTION |
<<putchar>> is a macro, defined in <<stdio.h>>. <<putchar>> |
writes its argument to the standard output stream, |
after converting it from an <<int>> to an <<unsigned char>>. |
The alternate function <<_putchar_r>> is a reentrant version. The |
extra argument <[reent]> is a pointer to a reentrancy structure. |
RETURNS |
If successful, <<putchar>> returns its argument <[ch]>. If an error |
intervenes, the result is <<EOF>>. You can use `<<ferror(stdin)>>' to |
query for errors. |
PORTABILITY |
ANSI C requires <<putchar>>; it suggests, but does not require, that |
<<putchar>> be implemented as a macro. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#if defined(LIBC_SCCS) && !defined(lint) |
static char sccsid[] = "%W% (Berkeley) %G%"; |
#endif /* LIBC_SCCS and not lint */ |
/* |
* A subroutine version of the macro putchar. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include "local.h" |
#undef putchar |
int |
_DEFUN(_putchar_r, (ptr, c), |
struct _reent *ptr _AND |
int c) |
{ |
_REENT_SMALL_CHECK_INIT (ptr); |
return _putc_r (ptr, c, _stdout_r (ptr)); |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(putchar, (c), |
int c) |
{ |
_REENT_SMALL_CHECK_INIT (_REENT); |
return _putc_r (_REENT, c, _stdout_r (_REENT)); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/puts.c |
---|
0,0 → 1,106 |
/* |
* 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 |
<<puts>>---write a character string |
INDEX |
puts |
INDEX |
_puts_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int puts(const char *<[s]>); |
int _puts_r(struct _reent *<[reent]>, const char *<[s]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int puts(<[s]>) |
char *<[s]>; |
int _puts_r(<[reent]>, <[s]>) |
struct _reent *<[reent]>; |
char *<[s]>; |
DESCRIPTION |
<<puts>> writes the string at <[s]> (followed by a newline, instead of |
the trailing null) to the standard output stream. |
The alternate function <<_puts_r>> is a reentrant version. The extra |
argument <[reent]> is a pointer to a reentrancy structure. |
RETURNS |
If successful, the result is a nonnegative integer; otherwise, the |
result is <<EOF>>. |
PORTABILITY |
ANSI C requires <<puts>>, but does not specify that the result on |
success must be <<0>>; any non-negative value is permitted. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#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 <string.h> |
#include "fvwrite.h" |
#include "local.h" |
/* |
* Write the given string to stdout, appending a newline. |
*/ |
int |
_DEFUN(_puts_r, (ptr, s), |
struct _reent *ptr _AND |
_CONST char * s) |
{ |
size_t c = strlen (s); |
struct __suio uio; |
struct __siov iov[2]; |
iov[0].iov_base = s; |
iov[0].iov_len = c; |
iov[1].iov_base = "\n"; |
iov[1].iov_len = 1; |
uio.uio_resid = c + 1; |
uio.uio_iov = &iov[0]; |
uio.uio_iovcnt = 2; |
_REENT_SMALL_CHECK_INIT (ptr); |
ORIENT (stdout, -1); |
return (__sfvwrite_r (ptr, _stdout_r (ptr), &uio) ? EOF : '\n'); |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(puts, (s), |
char _CONST * s) |
{ |
return _puts_r (_REENT, s); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/refill.c |
---|
0,0 → 1,138 |
/* |
* 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. |
*/ |
/* No user fns here. Pesch 15apr92. */ |
#include <_ansi.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <errno.h> |
#include "local.h" |
static int |
_DEFUN(lflush, (fp), |
FILE *fp) |
{ |
if ((fp->_flags & (__SLBF | __SWR)) == (__SLBF | __SWR)) |
return fflush (fp); |
return 0; |
} |
/* |
* Refill a stdio buffer. |
* Return EOF on eof or error, 0 otherwise. |
*/ |
int |
_DEFUN(__srefill_r, (ptr, fp), |
struct _reent * ptr _AND |
register FILE * fp) |
{ |
/* make sure stdio is set up */ |
CHECK_INIT (ptr, fp); |
ORIENT (fp, -1); |
fp->_r = 0; /* largely a convenience for callers */ |
#ifndef __CYGWIN__ |
/* SysV does not make this test; take it out for compatibility */ |
if (fp->_flags & __SEOF) |
return EOF; |
#endif |
/* if not already reading, have to be reading and writing */ |
if ((fp->_flags & __SRD) == 0) |
{ |
if ((fp->_flags & __SRW) == 0) |
{ |
ptr->_errno = EBADF; |
fp->_flags |= __SERR; |
return EOF; |
} |
/* switch to reading */ |
if (fp->_flags & __SWR) |
{ |
if (_fflush_r (ptr, fp)) |
return EOF; |
fp->_flags &= ~__SWR; |
fp->_w = 0; |
fp->_lbfsize = 0; |
} |
fp->_flags |= __SRD; |
} |
else |
{ |
/* |
* We were reading. If there is an ungetc buffer, |
* we must have been reading from that. Drop it, |
* restoring the previous buffer (if any). If there |
* is anything in that buffer, return. |
*/ |
if (HASUB (fp)) |
{ |
FREEUB (ptr, fp); |
if ((fp->_r = fp->_ur) != 0) |
{ |
fp->_p = fp->_up; |
return 0; |
} |
} |
} |
if (fp->_bf._base == NULL) |
__smakebuf_r (ptr, fp); |
/* |
* Before reading from a line buffered or unbuffered file, |
* flush all line buffered output files, per the ANSI C |
* standard. |
*/ |
if (fp->_flags & (__SLBF | __SNBF)) |
{ |
/* Ignore this file in _fwalk to avoid potential deadlock. */ |
short orig_flags = fp->_flags; |
fp->_flags = 1; |
_CAST_VOID _fwalk (_GLOBAL_REENT, lflush); |
fp->_flags = orig_flags; |
/* Now flush this file without locking it. */ |
if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) |
__sflush_r (ptr, fp); |
} |
fp->_p = fp->_bf._base; |
fp->_r = fp->_read (ptr, fp->_cookie, (char *) fp->_p, fp->_bf._size); |
#ifndef __CYGWIN__ |
if (fp->_r <= 0) |
#else |
if (fp->_r > 0) |
fp->_flags &= ~__SEOF; |
else |
#endif |
{ |
if (fp->_r == 0) |
fp->_flags |= __SEOF; |
else |
{ |
fp->_r = 0; |
fp->_flags |= __SERR; |
} |
return EOF; |
} |
return 0; |
} |
/contrib/sdk/sources/newlib/libc/stdio/remove.c |
---|
0,0 → 1,91 |
/* |
* 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 |
<<remove>>---delete a file's name |
INDEX |
remove |
INDEX |
_remove_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int remove(char *<[filename]>); |
int _remove_r(struct _reent *<[reent]>, char *<[filename]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int remove(<[filename]>) |
char *<[filename]>; |
int _remove_r(<[reent]>, <[filename]>) |
struct _reent *<[reent]>; |
char *<[filename]>; |
DESCRIPTION |
Use <<remove>> to dissolve the association between a particular |
filename (the string at <[filename]>) and the file it represents. |
After calling <<remove>> with a particular filename, you will no |
longer be able to open the file by that name. |
In this implementation, you may use <<remove>> on an open file without |
error; existing file descriptors for the file will continue to access |
the file's data until the program using them closes the file. |
The alternate function <<_remove_r>> is a reentrant version. The |
extra argument <[reent]> is a pointer to a reentrancy structure. |
RETURNS |
<<remove>> returns <<0>> if it succeeds, <<-1>> if it fails. |
PORTABILITY |
ANSI C requires <<remove>>, but only specifies that the result on |
failure be nonzero. The behavior of <<remove>> when you call it on an |
open file may vary among implementations. |
Supporting OS subroutine required: <<unlink>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <sys/kos_io.h> |
int |
_DEFUN(_remove_r, (ptr, filename), |
struct _reent *ptr _AND |
_CONST char *filename) |
{ |
return delete_file(filename)==0 ? 0: -1; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(remove, (filename), |
_CONST char *filename) |
{ |
return delete_file(filename)==0 ? 0: -1; |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/rename.c |
---|
0,0 → 1,80 |
/* |
* 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 |
<<rename>>---rename a file |
INDEX |
rename |
ANSI_SYNOPSIS |
#include <stdio.h> |
int rename(const char *<[old]>, const char *<[new]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int rename(<[old]>, <[new]>) |
char *<[old]>; |
char *<[new]>; |
DESCRIPTION |
Use <<rename>> to establish a new name (the string at <[new]>) for a |
file now known by the string at <[old]>. After a successful |
<<rename>>, the file is no longer accessible by the string at <[old]>. |
If <<rename>> fails, the file named <<*<[old]>>> is unaffected. The |
conditions for failure depend on the host operating system. |
RETURNS |
The result is either <<0>> (when successful) or <<-1>> (when the file |
could not be renamed). |
PORTABILITY |
ANSI C requires <<rename>>, but only specifies that the result on |
failure be nonzero. The effects of using the name of an existing file |
as <<*<[new]>>> may vary from one implementation to another. |
Supporting OS subroutines required: <<link>>, <<unlink>>, or <<rename>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <sys/unistd.h> |
int |
_DEFUN (_rename_r, (ptr, old, new), |
struct _reent *ptr _AND |
_CONST char *old _AND |
_CONST char *new) |
{ |
return -1; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(rename, (old, new), |
_CONST char *old _AND |
_CONST char *new) |
{ |
return -1; |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/rget.c |
---|
0,0 → 1,59 |
/* |
* 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. |
*/ |
/* No user fns here. Pesch 15apr92. */ |
#if defined(LIBC_SCCS) && !defined(lint) |
static char sccsid[] = "%W% (Berkeley) %G%"; |
#endif /* LIBC_SCCS and not lint */ |
#include <_ansi.h> |
#include <stdio.h> |
#include <errno.h> |
#include "local.h" |
/* |
* Handle getc() when the buffer ran out: |
* Refill, then return the first character |
* in the newly-filled buffer. |
*/ |
int |
_DEFUN(__srget_r, (ptr, fp), |
struct _reent *ptr _AND |
register FILE *fp) |
{ |
/* Ensure that any fake std stream is resolved before |
we call __srefill_r so we may access the true read buffer. */ |
CHECK_INIT(ptr, fp); |
if (__srefill_r (ptr, fp) == 0) |
{ |
fp->_r--; |
return *fp->_p++; |
} |
return EOF; |
} |
/* This function isn't any longer declared in stdio.h, but it's |
required for backward compatibility with applications built against |
earlier dynamically built newlib libraries. */ |
int |
_DEFUN(__srget, (fp), |
register FILE *fp) |
{ |
return __srget_r (_REENT, fp); |
} |
/contrib/sdk/sources/newlib/libc/stdio/sccl.c |
---|
0,0 → 1,127 |
/*- |
* 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. |
*/ |
/* Split from vfscanf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <newlib.h> |
#include <stdio.h> |
#include "local.h" |
/* |
* Fill in the given table from the scanset at the given format |
* (just after `['). Return a pointer to the character past the |
* closing `]'. The table has a 1 wherever characters should be |
* considered part of the scanset. |
*/ |
u_char * |
_DEFUN(__sccl, (tab, fmt), |
register char *tab _AND |
register u_char *fmt) |
{ |
register int c, n, v; |
/* first `clear' the whole table */ |
c = *fmt++; /* first char hat => negated scanset */ |
if (c == '^') |
{ |
v = 1; /* default => accept */ |
c = *fmt++; /* get new first char */ |
} |
else |
v = 0; /* default => reject */ |
/* should probably use memset here */ |
for (n = 0; n < 256; n++) |
tab[n] = v; |
if (c == 0) |
return fmt - 1; /* format ended before closing ] */ |
/* |
* Now set the entries corresponding to the actual scanset to the |
* opposite of the above. |
* |
* The first character may be ']' (or '-') without being special; the |
* last character may be '-'. |
*/ |
v = 1 - v; |
for (;;) |
{ |
tab[c] = v; /* take character c */ |
doswitch: |
n = *fmt++; /* and examine the next */ |
switch (n) |
{ |
case 0: /* format ended too soon */ |
return fmt - 1; |
case '-': |
/* |
* A scanset of the form [01+-] is defined as `the digit 0, the |
* digit 1, the character +, the character -', but the effect of a |
* scanset such as [a-zA-Z0-9] is implementation defined. The V7 |
* Unix scanf treats `a-z' as `the letters a through z', but treats |
* `a-a' as `the letter a, the character -, and the letter a'. |
* |
* For compatibility, the `-' is not considerd to define a range if |
* the character following it is either a close bracket (required by |
* ANSI) or is not numerically greater than the character we just |
* stored in the table (c). |
*/ |
n = *fmt; |
if (n == ']' || n < c) |
{ |
c = '-'; |
break; /* resume the for(;;) */ |
} |
fmt++; |
do |
{ /* fill in the range */ |
tab[++c] = v; |
} |
while (c < n); |
#if 1 /* XXX another disgusting compatibility hack */ |
/* |
* Alas, the V7 Unix scanf also treats formats such |
* as [a-c-e] as `the letters a through e'. This too |
* is permitted by the standard.... |
*/ |
goto doswitch; |
#else |
c = *fmt++; |
if (c == 0) |
return fmt - 1; |
if (c == ']') |
return fmt; |
#endif |
break; |
case ']': /* end of scanset */ |
return fmt; |
default: /* just another character */ |
c = n; |
break; |
} |
} |
/* NOTREACHED */ |
} |
/contrib/sdk/sources/newlib/libc/stdio/setvbuf.c |
---|
0,0 → 1,198 |
/* |
* 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 |
<<setvbuf>>---specify file or stream buffering |
INDEX |
setvbuf |
ANSI_SYNOPSIS |
#include <stdio.h> |
int setvbuf(FILE *<[fp]>, char *<[buf]>, |
int <[mode]>, size_t <[size]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int setvbuf(<[fp]>, <[buf]>, <[mode]>, <[size]>) |
FILE *<[fp]>; |
char *<[buf]>; |
int <[mode]>; |
size_t <[size]>; |
DESCRIPTION |
Use <<setvbuf>> to specify what kind of buffering you want for the |
file or stream identified by <[fp]>, by using one of the following |
values (from <<stdio.h>>) as the <[mode]> argument: |
o+ |
o _IONBF |
Do not use a buffer: send output directly to the host system for the |
file or stream identified by <[fp]>. |
o _IOFBF |
Use full output buffering: output will be passed on to the host system |
only when the buffer is full, or when an input operation intervenes. |
o _IOLBF |
Use line buffering: pass on output to the host system at every |
newline, as well as when the buffer is full, or when an input |
operation intervenes. |
o- |
Use the <[size]> argument to specify how large a buffer you wish. You |
can supply the buffer itself, if you wish, by passing a pointer to a |
suitable area of memory as <[buf]>. Otherwise, you may pass <<NULL>> |
as the <[buf]> argument, and <<setvbuf>> will allocate the buffer. |
WARNINGS |
You may only use <<setvbuf>> before performing any file operation other |
than opening the file. |
If you supply a non-null <[buf]>, you must ensure that the associated |
storage continues to be available until you close the stream |
identified by <[fp]>. |
RETURNS |
A <<0>> result indicates success, <<EOF>> failure (invalid <[mode]> or |
<[size]> can cause failure). |
PORTABILITY |
Both ANSI C and the System V Interface Definition (Issue 2) require |
<<setvbuf>>. However, they differ on the meaning of a <<NULL>> buffer |
pointer: the SVID issue 2 specification says that a <<NULL>> buffer |
pointer requests unbuffered output. For maximum portability, avoid |
<<NULL>> buffer pointers. |
Both specifications describe the result on failure only as a |
nonzero value. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include "local.h" |
/* |
* Set one of the three kinds of buffering, optionally including a buffer. |
*/ |
int |
_DEFUN(setvbuf, (fp, buf, mode, size), |
register FILE * fp _AND |
char *buf _AND |
register int mode _AND |
register size_t size) |
{ |
int ret = 0; |
CHECK_INIT (_REENT, fp); |
_flockfile (fp); |
/* |
* Verify arguments. The `int' limit on `size' is due to this |
* particular implementation. |
*/ |
if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int)(_POINTER_INT) size < 0) |
{ |
_funlockfile (fp); |
return (EOF); |
} |
/* |
* Write current buffer, if any; drop read count, if any. |
* Make sure putc() will not think fp is line buffered. |
* Free old buffer if it was from malloc(). Clear line and |
* non buffer flags, and clear malloc flag. |
*/ |
_fflush_r (_REENT, fp); |
fp->_r = 0; |
fp->_lbfsize = 0; |
if (fp->_flags & __SMBF) |
_free_r (_REENT, (_PTR) fp->_bf._base); |
fp->_flags &= ~(__SLBF | __SNBF | __SMBF); |
if (mode == _IONBF) |
goto nbf; |
/* |
* Allocate buffer if needed. */ |
if (buf == NULL) |
{ |
/* we need this here because malloc() may return a pointer |
even if size == 0 */ |
if (!size) size = BUFSIZ; |
if ((buf = malloc (size)) == NULL) |
{ |
ret = EOF; |
/* Try another size... */ |
buf = malloc (BUFSIZ); |
size = BUFSIZ; |
} |
if (buf == NULL) |
{ |
/* Can't allocate it, let's try another approach */ |
nbf: |
fp->_flags |= __SNBF; |
fp->_w = 0; |
fp->_bf._base = fp->_p = fp->_nbuf; |
fp->_bf._size = 1; |
_funlockfile (fp); |
return (ret); |
} |
fp->_flags |= __SMBF; |
} |
/* |
* Now put back whichever flag is needed, and fix _lbfsize |
* if line buffered. Ensure output flush on exit if the |
* stream will be buffered at all. |
* If buf is NULL then make _lbfsize 0 to force the buffer |
* to be flushed and hence malloced on first use |
*/ |
switch (mode) |
{ |
case _IOLBF: |
fp->_flags |= __SLBF; |
fp->_lbfsize = buf ? -size : 0; |
/* FALLTHROUGH */ |
case _IOFBF: |
/* no flag */ |
_REENT->__cleanup = _cleanup_r; |
fp->_bf._base = fp->_p = (unsigned char *) buf; |
fp->_bf._size = size; |
break; |
} |
/* |
* Patch up write count if necessary. |
*/ |
if (fp->_flags & __SWR) |
fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size; |
_funlockfile (fp); |
return 0; |
} |
/contrib/sdk/sources/newlib/libc/stdio/siprintf.c |
---|
0,0 → 1,171 |
/* |
* 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 |
<<siprintf>>, <<fiprintf>>, <<iprintf>>, <<sniprintf>>, <<asiprintf>>, <<asniprintf>>---format output (integer only) |
INDEX |
fiprintf |
INDEX |
_fiprintf_r |
INDEX |
iprintf |
INDEX |
_iprintf_r |
INDEX |
siprintf |
INDEX |
_siprintf_r |
INDEX |
sniprintf |
INDEX |
_sniprintf_r |
INDEX |
asiprintf |
INDEX |
_asiprintf_r |
INDEX |
asniprintf |
INDEX |
_asniprintf_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int iprintf(const char *<[format]>, ...); |
int fiprintf(FILE *<[fd]>, const char *<[format]> , ...); |
int siprintf(char *<[str]>, const char *<[format]>, ...); |
int sniprintf(char *<[str]>, size_t <[size]>, const char *<[format]>, |
...); |
int asiprintf(char **<[strp]>, const char *<[format]>, ...); |
char *asniprintf(char *<[str]>, size_t *<[size]>, |
const char *<[format]>, ...); |
int _iprintf_r(struct _reent *<[ptr]>, const char *<[format]>, ...); |
int _fiprintf_r(struct _reent *<[ptr]>, FILE *<[fd]>, |
const char *<[format]>, ...); |
int _siprintf_r(struct _reent *<[ptr]>, char *<[str]>, |
const char *<[format]>, ...); |
int _sniprintf_r(struct _reent *<[ptr]>, char *<[str]>, size_t <[size]>, |
const char *<[format]>, ...); |
int _asiprintf_r(struct _reent *<[ptr]>, char **<[strp]>, |
const char *<[format]>, ...); |
char *_asniprintf_r(struct _reent *<[ptr]>, char *<[str]>, |
size_t *<[size]>, const char *<[format]>, ...); |
DESCRIPTION |
<<iprintf>>, <<fiprintf>>, <<siprintf>>, <<sniprintf>>, |
<<asiprintf>>, and <<asniprintf>> are the same as <<printf>>, |
<<fprintf>>, <<sprintf>>, <<snprintf>>, <<asprintf>>, and |
<<asnprintf>>, respectively, except that they restrict usage |
to non-floating-point format specifiers. |
<<_iprintf_r>>, <<_fiprintf_r>>, <<_asiprintf_r>>, |
<<_siprintf_r>>, <<_sniprintf_r>>, <<_asniprintf_r>> are |
simply reentrant versions of the functions above. |
RETURNS |
Similar to <<printf>>, <<fprintf>>, <<sprintf>>, <<snprintf>>, <<asprintf>>, |
and <<asnprintf>>. |
PORTABILITY |
<<iprintf>>, <<fiprintf>>, <<siprintf>>, <<sniprintf>>, <<asiprintf>>, |
and <<asniprintf>> are newlib extensions. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include <limits.h> |
#include "local.h" |
int |
#ifdef _HAVE_STDC |
_DEFUN(_siprintf_r, (ptr, str, fmt), |
struct _reent *ptr _AND |
char *str _AND |
_CONST char *fmt _DOTS) |
#else |
_siprintf_r(ptr, str, fmt, va_alist) |
struct _reent *ptr; |
char *str; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = INT_MAX; |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _svfiprintf_r (ptr, &f, fmt, ap); |
va_end (ap); |
*f._p = 0; |
return (ret); |
} |
#ifndef _REENT_ONLY |
int |
#ifdef _HAVE_STDC |
_DEFUN(siprintf, (str, fmt), |
char *str _AND |
_CONST char *fmt _DOTS) |
#else |
siprintf(str, fmt, va_alist) |
char *str; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = INT_MAX; |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _svfiprintf_r (_REENT, &f, fmt, ap); |
va_end (ap); |
*f._p = 0; |
return (ret); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/sniprintf.c |
---|
0,0 → 1,120 |
/* |
* 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. |
*/ |
/* This code created by modifying snprintf.c so copyright inherited. */ |
/* doc in siprintf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include <limits.h> |
#include <errno.h> |
#include "local.h" |
int |
#ifdef _HAVE_STDC |
_DEFUN (_sniprintf_r, (ptr, str, size, fmt), |
struct _reent *ptr _AND |
char *str _AND |
size_t size _AND |
_CONST char *fmt _DOTS) |
#else |
_sniprintf_r (ptr, str, size, fmt, va_alist) |
struct _reent *ptr; |
char *str; |
size_t size; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
if (size > INT_MAX) |
{ |
ptr->_errno = EOVERFLOW; |
return EOF; |
} |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = (size > 0 ? size - 1 : 0); |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _svfiprintf_r (ptr, &f, fmt, ap); |
va_end (ap); |
if (ret < EOF) |
ptr->_errno = EOVERFLOW; |
if (size > 0) |
*f._p = 0; |
return (ret); |
} |
#ifndef _REENT_ONLY |
int |
#ifdef _HAVE_STDC |
_DEFUN (sniprintf, (str, size, fmt), |
char *str _AND |
size_t size _AND |
_CONST char *fmt _DOTS) |
#else |
sniprintf (str, size, fmt, va_alist) |
char *str; |
size_t size; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
struct _reent *ptr = _REENT; |
if (size > INT_MAX) |
{ |
ptr->_errno = EOVERFLOW; |
return EOF; |
} |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = (size > 0 ? size - 1 : 0); |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _svfiprintf_r (ptr, &f, fmt, ap); |
va_end (ap); |
if (ret < EOF) |
ptr->_errno = EOVERFLOW; |
if (size > 0) |
*f._p = 0; |
return (ret); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/snprintf.c |
---|
0,0 → 1,119 |
/* |
* 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. |
*/ |
/* doc in sprintf.c */ |
/* This code created by modifying sprintf.c so copyright inherited. */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include <limits.h> |
#include <errno.h> |
#include "local.h" |
int |
#ifdef _HAVE_STDC |
_DEFUN(_snprintf_r, (ptr, str, size, fmt), |
struct _reent *ptr _AND |
char *str _AND |
size_t size _AND |
_CONST char *fmt _DOTS) |
#else |
_snprintf_r(ptr, str, size, fmt, va_alist) |
struct _reent *ptr; |
char *str; |
size_t size; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
if (size > INT_MAX) |
{ |
ptr->_errno = EOVERFLOW; |
return EOF; |
} |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = (size > 0 ? size - 1 : 0); |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _svfprintf_r (ptr, &f, fmt, ap); |
va_end (ap); |
if (ret < EOF) |
ptr->_errno = EOVERFLOW; |
if (size > 0) |
*f._p = 0; |
return (ret); |
} |
#ifndef _REENT_ONLY |
int |
#ifdef _HAVE_STDC |
_DEFUN(snprintf, (str, size, fmt), |
char *str _AND |
size_t size _AND |
_CONST char *fmt _DOTS) |
#else |
snprintf(str, size, fmt, va_alist) |
char *str; |
size_t size; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
struct _reent *ptr = _REENT; |
if (size > INT_MAX) |
{ |
ptr->_errno = EOVERFLOW; |
return EOF; |
} |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = (size > 0 ? size - 1 : 0); |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _svfprintf_r (ptr, &f, fmt, ap); |
va_end (ap); |
if (ret < EOF) |
ptr->_errno = EOVERFLOW; |
if (size > 0) |
*f._p = 0; |
return (ret); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/sprintf.c |
---|
0,0 → 1,640 |
/* |
* 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 |
<<sprintf>>, <<fprintf>>, <<printf>>, <<snprintf>>, <<asprintf>>, <<asnprintf>>---format output |
INDEX |
fprintf |
INDEX |
_fprintf_r |
INDEX |
printf |
INDEX |
_printf_r |
INDEX |
asprintf |
INDEX |
_asprintf_r |
INDEX |
sprintf |
INDEX |
_sprintf_r |
INDEX |
snprintf |
INDEX |
_snprintf_r |
INDEX |
asnprintf |
INDEX |
_asnprintf_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int printf(const char *<[format]>, ...); |
int fprintf(FILE *<[fd]>, const char *<[format]>, ...); |
int sprintf(char *<[str]>, const char *<[format]>, ...); |
int snprintf(char *<[str]>, size_t <[size]>, const char *<[format]>, |
...); |
int asprintf(char **<[strp]>, const char *<[format]>, ...); |
char *asnprintf(char *<[str]>, size_t *<[size]>, const char *<[format]>, |
...); |
int _printf_r(struct _reent *<[ptr]>, const char *<[format]>, ...); |
int _fprintf_r(struct _reent *<[ptr]>, FILE *<[fd]>, |
const char *<[format]>, ...); |
int _sprintf_r(struct _reent *<[ptr]>, char *<[str]>, |
const char *<[format]>, ...); |
int _snprintf_r(struct _reent *<[ptr]>, char *<[str]>, size_t <[size]>, |
const char *<[format]>, ...); |
int _asprintf_r(struct _reent *<[ptr]>, char **<[strp]>, |
const char *<[format]>, ...); |
char *_asnprintf_r(struct _reent *<[ptr]>, char *<[str]>, |
size_t *<[size]>, const char *<[format]>, ...); |
DESCRIPTION |
<<printf>> accepts a series of arguments, applies to each a |
format specifier from <<*<[format]>>>, and writes the |
formatted data to <<stdout>>, without a terminating NUL |
character. The behavior of <<printf>> is undefined if there |
are not enough arguments for the format. <<printf>> returns |
when it reaches the end of the format string. If there are |
more arguments than the format requires, excess arguments are |
ignored. |
<<fprintf>> is like <<printf>>, except that output is directed |
to the stream <[fd]> rather than <<stdout>>. |
<<sprintf>> is like <<printf>>, except that output is directed |
to the buffer <[str]>, and a terminating NUL is output. |
Behavior is undefined if more output is generated than the |
buffer can hold. |
<<snprintf>> is like <<sprintf>>, except that output is |
limited to at most <[size]> bytes, including the terminating |
<<NUL>>. As a special case, if <[size]> is 0, <[str]> can be |
NULL, and <<snprintf>> merely calculates how many bytes would |
be printed. |
<<asprintf>> is like <<sprintf>>, except that the output is |
stored in a dynamically allocated buffer, <[pstr]>, which |
should be freed later with <<free>>. |
<<asnprintf>> is like <<sprintf>>, except that the return type |
is either the original <[str]> if it was large enough, or a |
dynamically allocated string if the output exceeds *<[size]>; |
the length of the result is returned in *<[size]>. When |
dynamic allocation occurs, the contents of the original |
<[str]> may have been modified. |
For <<sprintf>>, <<snprintf>>, and <<asnprintf>>, 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 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+ |
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- |
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 <<printf>> |
performs. Here is a table of these: |
o+ |
o % |
Prints the percent character (<<%>>). |
o c |
Prints <[arg]> as single character. If the |
<<l>> size specifier is in effect, a multibyte |
character is printed. |
o C |
Short for <<%lc>>. A POSIX extension to the C standard. |
o s |
Prints the elements of a pointer to <<char>> |
until the precision or a null character is |
reached. If the <<l>> size specifier is in |
effect, the pointer is to an array of |
<<wchar_t>>, and the string is converted to |
multibyte characters before printing. |
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 D |
Newlib extension, short for <<%ld>>. |
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 O |
Newlib extension, short for <<%lo>>. |
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 U |
Newlib extension, short for <<%lu>>. |
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- |
O- |
<<_printf_r>>, <<_fprintf_r>>, <<_asprintf_r>>, |
<<_sprintf_r>>, <<_snprintf_r>>, <<_asnprintf_r>> are simply |
reentrant versions of the functions above. |
RETURNS |
On success, <<sprintf>> and <<asprintf>> return the number of bytes in |
the output string, except the concluding <<NUL>> is not counted. |
<<snprintf>> returns the number of bytes that would be in the output |
string, except the concluding <<NUL>> is not counted. <<printf>> and |
<<fprintf>> return the number of characters transmitted. |
<<asnprintf>> returns the original <[str]> if there was enough room, |
otherwise it returns an allocated string. |
If an error occurs, the result of <<printf>>, <<fprintf>>, |
<<snprintf>>, and <<asprintf>> is a negative value, and the result of |
<<asnprintf>> is NULL. No error returns occur for <<sprintf>>. For |
<<printf>> and <<fprintf>>, <<errno>> may be set according to |
<<fputc>>. For <<asprintf>> and <<asnprintf>>, <<errno>> may be set |
to ENOMEM if allocation fails, and for <<snprintf>>, <<errno>> may be |
set to EOVERFLOW if <[size]> or the output length exceeds INT_MAX. |
BUGS |
The ``''' (quote) flag does not work when locale's thousands_sep is not empty. |
PORTABILITY |
ANSI C requires <<printf>>, <<fprintf>>, <<sprintf>>, and |
<<snprintf>>. <<asprintf>> and <<asnprintf>> are newlib extensions. |
The ANSI C standard specifies that implementations must support at |
least formatted output of up to 509 characters. This implementation |
has no inherent limit. |
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> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include <limits.h> |
#include "local.h" |
int |
#ifdef _HAVE_STDC |
_DEFUN(_sprintf_r, (ptr, str, fmt), |
struct _reent *ptr _AND |
char *str _AND |
_CONST char *fmt _DOTS) |
#else |
_sprintf_r(ptr, str, fmt, va_alist) |
struct _reent *ptr; |
char *str; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = INT_MAX; |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _svfprintf_r (ptr, &f, fmt, ap); |
va_end (ap); |
*f._p = '\0'; /* terminate the string */ |
return (ret); |
} |
#ifndef _REENT_ONLY |
int |
#ifdef _HAVE_STDC |
_DEFUN(sprintf, (str, fmt), |
char *str _AND |
_CONST char *fmt _DOTS) |
#else |
sprintf(str, fmt, va_alist) |
char *str; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = INT_MAX; |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = _svfprintf_r (_REENT, &f, fmt, ap); |
va_end (ap); |
*f._p = '\0'; /* terminate the string */ |
return (ret); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/sscanf.c |
---|
0,0 → 1,469 |
/* |
* 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 |
<<sscanf>>, <<fscanf>>, <<scanf>>---scan and format input |
INDEX |
scanf |
INDEX |
_scanf_r |
INDEX |
fscanf |
INDEX |
_fscanf_r |
INDEX |
sscanf |
INDEX |
_sscanf_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int scanf(const char *<[format]>, ...); |
int fscanf(FILE *<[fd]>, const char *<[format]>, ...); |
int sscanf(const char *<[str]>, const char *<[format]>, ...); |
int _scanf_r(struct _reent *<[ptr]>, const char *<[format]>, ...); |
int _fscanf_r(struct _reent *<[ptr]>, FILE *<[fd]>, |
const char *<[format]>, ...); |
int _sscanf_r(struct _reent *<[ptr]>, const char *<[str]>, |
const char *<[format]>, ...); |
TRAD_SYNOPSIS |
#include <stdio.h> |
int scanf(<[format]> [, <[arg]>, ...]) |
char *<[format]>; |
int fscanf(<[fd]>, <[format]> [, <[arg]>, ...]); |
FILE *<[fd]>; |
char *<[format]>; |
int sscanf(<[str]>, <[format]> [, <[arg]>, ...]); |
char *<[str]>; |
char *<[format]>; |
int _scanf_r(<[ptr]>, <[format]> [, <[arg]>, ...]) |
struct _reent *<[ptr]>; |
char *<[format]>; |
int _fscanf_r(<[ptr]>, <[fd]>, <[format]> [, <[arg]>, ...]); |
struct _reent *<[ptr]>; |
FILE *<[fd]>; |
char *<[format]>; |
int _sscanf_r(<[ptr]>, <[str]>, <[format]> [, <[arg]>, ...]); |
struct _reent *<[ptr]>; |
char *<[str]>; |
char *<[format]>; |
DESCRIPTION |
<<scanf>> scans a series of input fields from standard input, |
one character at a time. Each field is interpreted according to |
a format specifier passed to <<scanf>> in the format string at |
<<*<[format]>>>. <<scanf>> 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. |
<<scanf>> often produces unexpected results if the input diverges from |
an expected pattern. Since the combination of <<gets>> or <<fgets>> |
followed by <<sscanf>> 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. |
<<fscanf>> and <<sscanf>> are identical to <<scanf>>, other than the |
source of input: <<fscanf>> reads from a file, and <<sscanf>> |
from a string. |
The routines <<_scanf_r>>, <<_fscanf_r>>, and <<_sscanf_r>> are reentrant |
versions of <<scanf>>, <<fscanf>>, and <<sscanf>> that take an additional |
first argument pointing to a reentrancy structure. |
The string at <<*<[format]>>> is a 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 <<scanf>> 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 <<scanf>> encounters a non-whitespace |
character in the format string it will read, but not store |
a matching non-whitespace character. |
Format specifications tell <<scanf>> 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, <<scanf>> |
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 character occurs |
before <[width]> character are read, the characters up |
to that character are read, converted, and stored. |
Then <<scanf>> 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 <<scanf>> |
interprets the data type of the corresponding argument. |
.Modifier Type(s) |
. hh d, i, o, u, x, n convert input to char, |
. store in char object |
. |
. h d, i, o, u, x, n convert input to short, |
. store in short object |
. |
. h D, I, O, U, X no effect |
. e, f, c, s, p |
. |
. j d, i, o, u, x, n convert input to intmax_t, |
. store in intmax_t object |
. |
. j all others no effect |
. |
. l d, i, o, u, x, n convert input to long, |
. store in long object |
. |
. l e, f, g convert input to double |
. store in a double object |
. |
. l D, I, O, U, X no effect |
. c, s, p |
. |
. ll d, i, o, u, x, n convert to long long, |
. store in long long |
. |
. L d, i, o, u, x, n convert to long long, |
. store in long long |
. |
. L e, f, g, E, G convert to long double, |
. store in long double |
. |
. L all others no effect |
. |
. t d, i, o, u, x, n convert input to ptrdiff_t, |
. store in ptrdiff_t object |
. |
. t all others no effect |
. |
. z d, i, o, u, x, n convert input to size_t, |
. store in size_t object |
. |
. z all others no effect |
. |
o <[type]> |
A character to specify what kind of conversion |
<<scanf>> performs. Here is a table of the conversion |
characters: |
o+ |
o % |
No conversion is done; the percent character (<<%>>) is stored. |
o c |
Scans one character. Corresponding <[arg]>: <<(char *arg)>>. |
o s |
Reads a character string into the array supplied. |
Corresponding <[arg]>: <<(char 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)>>. |
o d |
Reads a decimal integer into the corresponding <[arg]>: <<(int *arg)>>. |
o D |
Reads a decimal integer into the corresponding |
<[arg]>: <<(long *arg)>>. |
o o |
Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>. |
o O |
Reads an octal integer into the corresponding <[arg]>: <<(long *arg)>>. |
o u |
Reads an unsigned decimal integer into the corresponding |
<[arg]>: <<(unsigned int *arg)>>. |
o U |
Reads an unsigned decimal integer into the corresponding <[arg]>: |
<<(unsigned long *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 I |
Reads a decimal, octal or hexadecimal integer into the |
corresponding <[arg]>: <<(long *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 <<scanf>> 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 also a range facility |
which you can use as a shortcut. <<%[0-9] >> matches all decimal digits. |
The hyphen must not be the first or last character in the set. |
The character prior to the hyphen must be lexically less than the |
character after it. |
Here are some <[pattern]> examples: |
o+ |
o %[abcd] |
matches strings containing only <<a>>, <<b>>, <<c>>, and <<d>>. |
o %[^abcd] |
matches strings containing any characters except <<a>>, <<b>>, |
<<c>>, or <<d>> |
o %[A-DW-Z] |
matches strings containing <<A>>, <<B>>, <<C>>, <<D>>, <<W>>, |
<<X>>, <<Y>>, <<Z>> |
o %[z-a] |
matches the characters <<z>>, <<->>, and <<a>> |
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 |
<<scanf>> returns the number of input fields successfully |
scanned, converted and stored; the return value does |
not include scanned fields which were not stored. |
If <<scanf>> attempts to read at end-of-file, the return |
value is <<EOF>>. |
If no fields were stored, the return value is <<0>>. |
<<scanf>> might stop scanning a particular field before |
reaching the normal field end character, or may |
terminate entirely. |
<<scanf>> 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 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 character in the input field does not appear |
in the search set (or does appear in the inverted search set). |
O- |
When <<scanf>> 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. |
<<scanf>> will terminate under the following circumstances: |
O+ |
o The next character in the input field conflicts |
with a corresponding non-whitespace character in the |
format string. |
o The next character in the input field is <<EOF>>. |
o The format string has been exhausted. |
O- |
When the format string contains a character sequence that is |
not part of a format specification, the same character |
sequence must appear in the input; <<scanf>> will |
scan but not store the matched characters. If a |
conflict occurs, the first conflicting character remains in the input |
as if it had never been read. |
PORTABILITY |
<<scanf>> is ANSI C. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <string.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include "local.h" |
#ifndef _REENT_ONLY |
#ifdef _HAVE_STDC |
int |
_DEFUN(sscanf, (str, fmt), |
_CONST char *str _AND |
_CONST char *fmt _DOTS) |
#else |
int |
sscanf(str, fmt, va_alist) |
_CONST char *str; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
f._flags = __SRD | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._r = strlen (str); |
f._read = __seofread; |
f._ub._base = NULL; |
f._lb._base = NULL; |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = __ssvfscanf_r (_REENT, &f, fmt, ap); |
va_end (ap); |
return ret; |
} |
#endif /* !_REENT_ONLY */ |
#ifdef _HAVE_STDC |
int |
_DEFUN(_sscanf_r, (ptr, str, fmt), |
struct _reent *ptr _AND |
_CONST char *str _AND |
_CONST char *fmt _DOTS) |
#else |
int |
_sscanf_r(ptr, str, fmt, va_alist) |
struct _reent *ptr; |
_CONST char *str; |
_CONST char *fmt; |
va_dcl |
#endif |
{ |
int ret; |
va_list ap; |
FILE f; |
f._flags = __SRD | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._r = strlen (str); |
f._read = __seofread; |
f._ub._base = NULL; |
f._lb._base = NULL; |
f._file = -1; /* No file. */ |
#ifdef _HAVE_STDC |
va_start (ap, fmt); |
#else |
va_start (ap); |
#endif |
ret = __ssvfscanf_r (ptr, &f, fmt, ap); |
va_end (ap); |
return ret; |
} |
/contrib/sdk/sources/newlib/libc/stdio/stdio.c |
---|
0,0 → 1,150 |
/* |
* 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. |
*/ |
/* No user fns here. Pesch 15apr92. */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <sys/types.h> |
#include <fcntl.h> |
#include <sys/unistd.h> |
#include "local.h" |
/* |
* Small standard I/O/seek/close functions. |
* These maintain the `known seek offset' for seek optimisation. |
*/ |
_READ_WRITE_RETURN_TYPE |
_DEFUN(__sread, (ptr, cookie, buf, n), |
struct _reent *ptr _AND |
void *cookie _AND |
char *buf _AND |
int n) |
{ |
register FILE *fp = (FILE *) cookie; |
register int ret; |
#ifdef __SCLE |
int oldmode = 0; |
if (fp->_flags & __SCLE) |
oldmode = setmode (fp->_file, O_BINARY); |
#endif |
ret = _read_r (ptr, fp->_file, buf, n); |
#ifdef __SCLE |
if (oldmode) |
setmode (fp->_file, oldmode); |
#endif |
/* If the read succeeded, update the current offset. */ |
if (ret >= 0) |
fp->_offset += ret; |
else |
fp->_flags &= ~__SOFF; /* paranoia */ |
return ret; |
} |
/* Dummy function used in sscanf/swscanf. */ |
_READ_WRITE_RETURN_TYPE |
_DEFUN(__seofread, (ptr, cookie, buf, len), |
struct _reent *_ptr _AND |
_PTR cookie _AND |
char *buf _AND |
int len) |
{ |
return 0; |
} |
_READ_WRITE_RETURN_TYPE |
_DEFUN(__swrite, (ptr, cookie, buf, n), |
struct _reent *ptr _AND |
void *cookie _AND |
char const *buf _AND |
int n) |
{ |
register FILE *fp = (FILE *) cookie; |
int w; |
#ifdef __SCLE |
int oldmode=0; |
#endif |
if (fp->_flags & __SAPP) |
_lseek_r (ptr, fp->_file, (_off_t) 0, SEEK_END); |
fp->_flags &= ~__SOFF; /* in case O_APPEND mode is set */ |
#ifdef __SCLE |
if (fp->_flags & __SCLE) |
oldmode = setmode (fp->_file, O_BINARY); |
#endif |
w = _write_r (ptr, fp->_file, buf, n); |
#ifdef __SCLE |
if (oldmode) |
setmode (fp->_file, oldmode); |
#endif |
return w; |
} |
_fpos_t |
_DEFUN(__sseek, (ptr, cookie, offset, whence), |
struct _reent *ptr _AND |
void *cookie _AND |
_fpos_t offset _AND |
int whence) |
{ |
register FILE *fp = (FILE *) cookie; |
register _off_t ret; |
ret = _lseek_r (ptr, fp->_file, (_off_t) offset, whence); |
if (ret == -1L) |
fp->_flags &= ~__SOFF; |
else |
{ |
fp->_flags |= __SOFF; |
fp->_offset = ret; |
} |
return ret; |
} |
int |
_DEFUN(__sclose, (ptr, cookie), |
struct _reent *ptr _AND |
void *cookie) |
{ |
FILE *fp = (FILE *) cookie; |
return _close_r (ptr, fp->_file); |
} |
#ifdef __SCLE |
int |
_DEFUN(__stextmode, (fd), |
int fd) |
{ |
#ifdef __CYGWIN__ |
extern int _cygwin_istext_for_stdio (int); |
return _cygwin_istext_for_stdio (fd); |
#else |
return 0; |
#endif |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/tmpfile.c |
---|
0,0 → 1,96 |
/* |
FUNCTION |
<<tmpfile>>---create a temporary file |
INDEX |
tmpfile |
INDEX |
_tmpfile_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
FILE *tmpfile(void); |
FILE *_tmpfile_r(struct _reent *<[reent]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
FILE *tmpfile(); |
FILE *_tmpfile_r(<[reent]>) |
struct _reent *<[reent]>; |
DESCRIPTION |
Create a temporary file (a file which will be deleted automatically), |
using a name generated by <<tmpnam>>. The temporary file is opened with |
the mode <<"wb+">>, permitting you to read and write anywhere in it |
as a binary file (without any data transformations the host system may |
perform for text files). |
The alternate function <<_tmpfile_r>> is a reentrant version. The |
argument <[reent]> is a pointer to a reentrancy structure. |
RETURNS |
<<tmpfile>> normally returns a pointer to the temporary file. If no |
temporary file could be created, the result is NULL, and <<errno>> |
records the reason for failure. |
PORTABILITY |
Both ANSI C and the System V Interface Definition (Issue 2) require |
<<tmpfile>>. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>, |
<<isatty>>, <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>. |
<<tmpfile>> also requires the global pointer <<environ>>. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <sys/stat.h> |
#ifndef O_BINARY |
# define O_BINARY 0 |
#endif |
FILE * |
_DEFUN(_tmpfile_r, (ptr), |
struct _reent *ptr) |
{ |
FILE *fp; |
int e; |
char *f; |
char buf[L_tmpnam]; |
int fd; |
do |
{ |
if ((f = _tmpnam_r (ptr, buf)) == NULL) |
return NULL; |
fd = _open_r (ptr, f, O_RDWR | O_CREAT | O_EXCL | O_BINARY, |
S_IRUSR | S_IWUSR); |
} |
while (fd < 0 && ptr->_errno == EEXIST); |
if (fd < 0) |
return NULL; |
fp = _fdopen_r (ptr, fd, "wb+"); |
e = ptr->_errno; |
if (!fp) |
_close_r (ptr, fd); |
_CAST_VOID _remove_r (ptr, f); |
ptr->_errno = e; |
return fp; |
} |
#ifndef _REENT_ONLY |
FILE * |
_DEFUN_VOID(tmpfile) |
{ |
return _tmpfile_r (_REENT); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/tmpnam.c |
---|
0,0 → 1,209 |
/* |
* tmpname.c |
* Original Author: G. Haley |
*/ |
/* |
FUNCTION |
<<tmpnam>>, <<tempnam>>---name for a temporary file |
INDEX |
tmpnam |
INDEX |
tempnam |
INDEX |
_tmpnam_r |
INDEX |
_tempnam_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
char *tmpnam(char *<[s]>); |
char *tempnam(char *<[dir]>, char *<[pfx]>); |
char *_tmpnam_r(struct _reent *<[reent]>, char *<[s]>); |
char *_tempnam_r(struct _reent *<[reent]>, char *<[dir]>, char *<[pfx]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
char *tmpnam(<[s]>) |
char *<[s]>; |
char *tempnam(<[dir]>, <[pfx]>) |
char *<[dir]>; |
char *<[pfx]>; |
char *_tmpnam_r(<[reent]>, <[s]>) |
struct _reent *<[reent]>; |
char *<[s]>; |
char *_tempnam_r(<[reent]>, <[dir]>, <[pfx]>) |
struct *<[reent]>; |
char *<[dir]>; |
char *<[pfx]>; |
DESCRIPTION |
Use either of these functions to generate a name for a temporary file. |
The generated name is guaranteed to avoid collision with other files |
(for up to <<TMP_MAX>> calls of either function). |
<<tmpnam>> generates file names with the value of <<P_tmpdir>> |
(defined in `<<stdio.h>>') as the leading directory component of the path. |
You can use the <<tmpnam>> argument <[s]> to specify a suitable area |
of memory for the generated filename; otherwise, you can call |
<<tmpnam(NULL)>> to use an internal static buffer. |
<<tempnam>> allows you more control over the generated filename: you |
can use the argument <[dir]> to specify the path to a directory for |
temporary files, and you can use the argument <[pfx]> to specify a |
prefix for the base filename. |
If <[dir]> is <<NULL>>, <<tempnam>> will attempt to use the value of |
environment variable <<TMPDIR>> instead; if there is no such value, |
<<tempnam>> uses the value of <<P_tmpdir>> (defined in `<<stdio.h>>'). |
If you don't need any particular prefix to the basename of temporary |
files, you can pass <<NULL>> as the <[pfx]> argument to <<tempnam>>. |
<<_tmpnam_r>> and <<_tempnam_r>> are reentrant versions of <<tmpnam>> |
and <<tempnam>> respectively. The extra argument <[reent]> is a |
pointer to a reentrancy structure. |
WARNINGS |
The generated filenames are suitable for temporary files, but do not |
in themselves make files temporary. Files with these names must still |
be explicitly removed when you no longer want them. |
If you supply your own data area <[s]> for <<tmpnam>>, you must ensure |
that it has room for at least <<L_tmpnam>> elements of type <<char>>. |
RETURNS |
Both <<tmpnam>> and <<tempnam>> return a pointer to the newly |
generated filename. |
PORTABILITY |
ANSI C requires <<tmpnam>>, but does not specify the use of |
<<P_tmpdir>>. The System V Interface Definition (Issue 2) requires |
both <<tmpnam>> and <<tempnam>>. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>, |
<<isatty>>, <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>. |
The global pointer <<environ>> is also required. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <fcntl.h> |
#include <reent.h> |
#include <errno.h> |
/* Try to open the file specified, if it can't be opened then try |
another one. Return nonzero if successful, otherwise zero. */ |
static int |
_DEFUN(worker, (ptr, result, part1, part2, part3, part4), |
struct _reent *ptr _AND |
char *result _AND |
_CONST char *part1 _AND |
_CONST char *part2 _AND |
int part3 _AND |
int *part4) |
{ |
/* Generate the filename and make sure that there isn't one called |
it already. */ |
while (1) |
{ |
int t; |
_sprintf_r (ptr, result, "%s/%s%x.%x", part1, part2, part3, *part4); |
(*part4)++; |
t = _open_r (ptr, result, O_RDONLY, 0); |
if (t == -1) |
{ |
if (ptr->_errno == ENOSYS) |
{ |
result[0] = '\0'; |
return 0; |
} |
break; |
} |
_close_r (ptr, t); |
} |
return 1; |
} |
char * |
_DEFUN(_tmpnam_r, (p, s), |
struct _reent *p _AND |
char *s) |
{ |
char *result; |
int pid; |
if (s == NULL) |
{ |
/* ANSI states we must use an internal static buffer if s is NULL */ |
_REENT_CHECK_EMERGENCY(p); |
result = _REENT_EMERGENCY(p); |
} |
else |
{ |
result = s; |
} |
pid = _getpid_r (p); |
if (worker (p, result, P_tmpdir, "t", pid, &p->_inc)) |
{ |
p->_inc++; |
return result; |
} |
return NULL; |
} |
char * |
_DEFUN(_tempnam_r, (p, dir, pfx), |
struct _reent *p _AND |
_CONST char *dir _AND |
_CONST char *pfx) |
{ |
char *filename; |
int length; |
_CONST char *prefix = (pfx) ? pfx : ""; |
if (dir == NULL && (dir = getenv ("TMPDIR")) == NULL) |
dir = P_tmpdir; |
/* two 8 digit numbers + . / */ |
length = strlen (dir) + strlen (prefix) + (4 * sizeof (int)) + 2 + 1; |
filename = _malloc_r (p, length); |
if (filename) |
{ |
if (! worker (p, filename, dir, prefix, |
_getpid_r (p) ^ (int) (_POINTER_INT) p, &p->_inc)) |
return NULL; |
} |
return filename; |
} |
#ifndef _REENT_ONLY |
char * |
_DEFUN(tempnam, (dir, pfx), |
_CONST char *dir _AND |
_CONST char *pfx) |
{ |
return _tempnam_r (_REENT, dir, pfx); |
} |
char * |
_DEFUN(tmpnam, (s), |
char *s) |
{ |
return _tmpnam_r (_REENT, s); |
} |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/ungetc.c |
---|
0,0 → 1,217 |
/* |
* 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 |
<<ungetc>>---push data back into a stream |
INDEX |
ungetc |
INDEX |
_ungetc_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
int ungetc(int <[c]>, FILE *<[stream]>); |
int _ungetc_r(struct _reent *<[reent]>, int <[c]>, FILE *<[stream]>); |
DESCRIPTION |
<<ungetc>> is used to return bytes back to <[stream]> to be read again. |
If <[c]> is EOF, the stream is unchanged. Otherwise, the unsigned |
char <[c]> is put back on the stream, and subsequent reads will see |
the bytes pushed back in reverse order. Pushed byes 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 <<_ungetc_r>> is a reentrant version. The |
extra argument <[reent]> is a pointer to a reentrancy structure. |
RETURNS |
The character pushed back, or <<EOF>> on error. |
PORTABILITY |
ANSI C requires <<ungetc>>, but only requires a pushback buffer of one |
byte; although this implementation can handle multiple bytes, not all |
can. Pushing back a signed char is a common application bug. |
Supporting OS subroutines required: <<sbrk>>. |
*/ |
#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 <stdlib.h> |
#include <string.h> |
#include "local.h" |
/* |
* Expand the ungetc buffer `in place'. That is, adjust fp->_p when |
* the buffer moves, so that it points the same distance from the end, |
* and move the bytes in the buffer around as necessary so that they |
* are all at the end (stack-style). |
*/ |
/*static*/ |
int |
_DEFUN(__submore, (rptr, fp), |
struct _reent *rptr _AND |
register FILE *fp) |
{ |
register int i; |
register unsigned char *p; |
if (fp->_ub._base == fp->_ubuf) |
{ |
/* |
* Get a new buffer (rather than expanding the old one). |
*/ |
if ((p = (unsigned char *) _malloc_r (rptr, (size_t) BUFSIZ)) == NULL) |
return EOF; |
fp->_ub._base = p; |
fp->_ub._size = BUFSIZ; |
p += BUFSIZ - sizeof (fp->_ubuf); |
for (i = sizeof (fp->_ubuf); --i >= 0;) |
p[i] = fp->_ubuf[i]; |
fp->_p = p; |
return 0; |
} |
i = fp->_ub._size; |
p = (unsigned char *) _realloc_r (rptr, (_PTR) (fp->_ub._base), i << 1); |
if (p == NULL) |
return EOF; |
_CAST_VOID memcpy ((_PTR) (p + i), (_PTR) p, (size_t) i); |
fp->_p = p + i; |
fp->_ub._base = p; |
fp->_ub._size = i << 1; |
return 0; |
} |
int |
_DEFUN(_ungetc_r, (rptr, c, fp), |
struct _reent *rptr _AND |
int c _AND |
register FILE *fp) |
{ |
if (c == EOF) |
return (EOF); |
/* Ensure stdio has been initialized. |
??? Might be able to remove this as some other stdio routine should |
have already been called to get the char we are un-getting. */ |
CHECK_INIT (rptr, fp); |
_flockfile (fp); |
ORIENT (fp, -1); |
/* After ungetc, we won't be at eof anymore */ |
fp->_flags &= ~__SEOF; |
if ((fp->_flags & __SRD) == 0) |
{ |
/* |
* Not already reading: no good unless reading-and-writing. |
* Otherwise, flush any current write stuff. |
*/ |
if ((fp->_flags & __SRW) == 0) |
{ |
_funlockfile (fp); |
return EOF; |
} |
if (fp->_flags & __SWR) |
{ |
if (_fflush_r (rptr, fp)) |
{ |
_funlockfile (fp); |
return EOF; |
} |
fp->_flags &= ~__SWR; |
fp->_w = 0; |
fp->_lbfsize = 0; |
} |
fp->_flags |= __SRD; |
} |
c = (unsigned char) c; |
/* |
* If we are in the middle of ungetc'ing, just continue. |
* This may require expanding the current ungetc buffer. |
*/ |
if (HASUB (fp)) |
{ |
if (fp->_r >= fp->_ub._size && __submore (rptr, fp)) |
{ |
_funlockfile (fp); |
return EOF; |
} |
*--fp->_p = c; |
fp->_r++; |
_funlockfile (fp); |
return c; |
} |
/* |
* If we can handle this by simply backing up, do so, |
* but never replace the original character. |
* (This makes sscanf() work when scanning `const' data.) |
*/ |
if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && fp->_p[-1] == c) |
{ |
fp->_p--; |
fp->_r++; |
_funlockfile (fp); |
return c; |
} |
/* |
* 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->_ubuf[sizeof (fp->_ubuf) - 1] = c; |
fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1]; |
fp->_r = 1; |
_funlockfile (fp); |
return c; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(ungetc, (c, fp), |
int c _AND |
register FILE *fp) |
{ |
return _ungetc_r (_REENT, c, fp); |
} |
#endif /* !_REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/vasniprintf.c |
---|
0,0 → 1,71 |
/* Copyright (C) 2007, 2008 Eric Blake |
* Permission to use, copy, modify, and distribute this software |
* is freely granted, provided that this notice is preserved. |
*/ |
/* This code was derived from asprintf.c */ |
/* doc in viprintf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdarg.h> |
#include <limits.h> |
#include <errno.h> |
#include "local.h" |
char * |
_DEFUN(_vasniprintf_r, (ptr, buf, lenp, fmt, ap), |
struct _reent *ptr _AND |
char *buf _AND |
size_t *lenp _AND |
const char *fmt _AND |
va_list ap) |
{ |
int ret; |
FILE f; |
size_t len = *lenp; |
if (buf && len) |
{ |
/* mark an existing buffer, but allow allocation of larger string */ |
f._flags = __SWR | __SSTR | __SOPT; |
} |
else |
{ |
/* mark a zero-length reallocatable buffer */ |
f._flags = __SWR | __SSTR | __SMBF; |
len = 0; |
buf = NULL; |
} |
f._bf._base = f._p = (unsigned char *) buf; |
/* For now, inherit the 32-bit signed limit of FILE._bf._size. |
FIXME - it would be nice to rewrite sys/reent.h to support size_t |
for _size. */ |
if (len > INT_MAX) |
{ |
ptr->_errno = EOVERFLOW; |
return NULL; |
} |
f._bf._size = f._w = len; |
f._file = -1; /* No file. */ |
ret = _svfiprintf_r (ptr, &f, fmt, ap); |
if (ret < 0) |
return NULL; |
*lenp = ret; |
*f._p = '\0'; |
return (char *) f._bf._base; |
} |
#ifndef _REENT_ONLY |
char * |
_DEFUN(vasniprintf, (buf, lenp, fmt, ap), |
char *buf _AND |
size_t *lenp _AND |
const char *fmt _AND |
va_list ap) |
{ |
return _vasniprintf_r (_REENT, buf, lenp, fmt, ap); |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/vasnprintf.c |
---|
0,0 → 1,71 |
/* Copyright (C) 2007 Eric Blake |
* Permission to use, copy, modify, and distribute this software |
* is freely granted, provided that this notice is preserved. |
*/ |
/* This code was derived from asprintf.c */ |
/* doc in vfprintf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdarg.h> |
#include <limits.h> |
#include <errno.h> |
#include "local.h" |
char * |
_DEFUN(_vasnprintf_r, (ptr, buf, lenp, fmt, ap), |
struct _reent *ptr _AND |
char *buf _AND |
size_t *lenp _AND |
const char *fmt _AND |
va_list ap) |
{ |
int ret; |
FILE f; |
size_t len = *lenp; |
if (buf && len) |
{ |
/* mark an existing buffer, but allow allocation of larger string */ |
f._flags = __SWR | __SSTR | __SOPT; |
} |
else |
{ |
/* mark a zero-length reallocatable buffer */ |
f._flags = __SWR | __SSTR | __SMBF; |
len = 0; |
buf = NULL; |
} |
f._bf._base = f._p = (unsigned char *) buf; |
/* For now, inherit the 32-bit signed limit of FILE._bf._size. |
FIXME - it would be nice to rewrite sys/reent.h to support size_t |
for _size. */ |
if (len > INT_MAX) |
{ |
ptr->_errno = EOVERFLOW; |
return NULL; |
} |
f._bf._size = f._w = len; |
f._file = -1; /* No file. */ |
ret = _svfprintf_r (ptr, &f, fmt, ap); |
if (ret < 0) |
return NULL; |
*lenp = ret; |
*f._p = '\0'; |
return (char *) f._bf._base; |
} |
#ifndef _REENT_ONLY |
char * |
_DEFUN(vasnprintf, (buf, lenp, fmt, ap), |
char *buf _AND |
size_t *lenp _AND |
const char *fmt _AND |
va_list ap) |
{ |
return _vasnprintf_r (_REENT, buf, lenp, fmt, ap); |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/vdiprintf.c |
---|
0,0 → 1,47 |
/* Copyright 2005, 2007 Shaun Jackman |
* Permission to use, copy, modify, and distribute this software |
* is freely granted, provided that this notice is preserved. |
*/ |
/* doc in diprintf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <stdarg.h> |
#include "local.h" |
int |
_DEFUN(_vdiprintf_r, (ptr, fd, format, ap), |
struct _reent *ptr _AND |
int fd _AND |
const char *format _AND |
va_list ap) |
{ |
char *p; |
char buf[512]; |
size_t n = sizeof buf; |
_REENT_SMALL_CHECK_INIT (ptr); |
p = _vasniprintf_r (ptr, buf, &n, format, ap); |
if (!p) |
return -1; |
n = _write_r (ptr, fd, p, n); |
if (p != buf) |
_free_r (ptr, p); |
return n; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(vdiprintf, (fd, format, ap), |
int fd _AND |
const char *format _AND |
va_list ap) |
{ |
return _vdiprintf_r (_REENT, fd, format, ap); |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/vdprintf.c |
---|
0,0 → 1,47 |
/* Copyright 2005, 2007 Shaun Jackman |
* Permission to use, copy, modify, and distribute this software |
* is freely granted, provided that this notice is preserved. |
*/ |
/* doc in dprintf.c */ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <stdarg.h> |
#include "local.h" |
int |
_DEFUN(_vdprintf_r, (ptr, fd, format, ap), |
struct _reent *ptr _AND |
int fd _AND |
const char *format _AND |
va_list ap) |
{ |
char *p; |
char buf[512]; |
size_t n = sizeof buf; |
_REENT_SMALL_CHECK_INIT (ptr); |
p = _vasnprintf_r (ptr, buf, &n, format, ap); |
if (!p) |
return -1; |
n = _write_r (ptr, fd, p, n); |
if (p != buf) |
_free_r (ptr, p); |
return n; |
} |
#ifndef _REENT_ONLY |
int |
_DEFUN(vdprintf, (fd, format, ap), |
int fd _AND |
const char *format _AND |
va_list ap) |
{ |
return _vdprintf_r (_REENT, fd, format, ap); |
} |
#endif /* ! _REENT_ONLY */ |
/contrib/sdk/sources/newlib/libc/stdio/vfieeefp.h |
---|
0,0 → 1,283 |
/**************************************************************** |
* |
* The author of this software is David M. Gay. |
* |
* Copyright (c) 1991 by AT&T. |
* |
* 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, NEITHER THE AUTHOR NOR AT&T MAKES ANY |
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY |
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. |
* |
***************************************************************/ |
/* Please send bug reports to |
David M. Gay |
AT&T Bell Laboratories, Room 2C-463 |
600 Mountain Avenue |
Murray Hill, NJ 07974-2070 |
U.S.A. |
dmg@research.att.com or research!dmg |
*/ |
/* This header file is a modification of mprec.h that only contains floating |
point union code. */ |
#include <newlib.h> |
#include <ieeefp.h> |
#include <math.h> |
#include <float.h> |
#include <errno.h> |
#include <sys/config.h> |
#ifdef __IEEE_LITTLE_ENDIAN |
#define IEEE_8087 |
#endif |
#ifdef __IEEE_BIG_ENDIAN |
#define IEEE_MC68k |
#endif |
#ifdef __Z8000__ |
#define Just_16 |
#endif |
#ifdef Unsigned_Shifts |
#define Sign_Extend(a,b) if (b < 0) a |= (__uint32_t)0xffff0000; |
#else |
#define Sign_Extend(a,b) /*no-op*/ |
#endif |
#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 |
Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. |
#endif |
#ifdef _WANT_IO_LONG_DOUBLE |
/* If we are going to examine or modify specific bits in a long double using |
the lword0 or lwordx macros, then we must wrap the long double inside |
a union. This is necessary to avoid undefined behavior according to |
the ANSI C spec. */ |
#ifdef IEEE_8087 |
#if LDBL_MANT_DIG == 24 |
struct ldieee |
{ |
unsigned manh:23; |
unsigned exp:8; |
unsigned sign:1; |
}; |
#elif LDBL_MANT_DIG == 53 |
struct ldieee |
{ |
unsigned manl:20; |
unsigned manh:32; |
unsigned exp:11; |
unsigned sign:1; |
}; |
#elif LDBL_MANT_DIG == 64 |
struct ldieee |
{ |
unsigned manl:32; |
unsigned manh:32; |
unsigned exp:15; |
unsigned sign:1; |
}; |
#elif LDBL_MANT_DIG > 64 |
struct ldieee |
{ |
unsigned manl3:16; |
unsigned manl2:32; |
unsigned manl:32; |
unsigned manh:32; |
unsigned exp:15; |
unsigned sign:1; |
}; |
#endif /* LDBL_MANT_DIG */ |
#else /* !IEEE_8087 */ |
#if LDBL_MANT_DIG == 24 |
struct ldieee |
{ |
unsigned sign:1; |
unsigned exp:8; |
unsigned manh:23; |
}; |
#elif LDBL_MANT_DIG == 53 |
struct ldieee |
{ |
unsigned sign:1; |
unsigned exp:11; |
unsigned manh:32; |
unsigned manl:20; |
}; |
#elif LDBL_MANT_DIG == 64 |
struct ldieee |
{ |
unsigned sign:1; |
unsigned exp:15; |
unsigned manh:32; |
unsigned manl:32; |
}; |
#elif LDBL_MANT_DIG > 64 |
struct ldieee |
{ |
unsigned sign:1; |
unsigned exp:15; |
unsigned manh:32; |
unsigned manl:32; |
unsigned manl2:32; |
unsigned manl3;16; |
}; |
#endif /* LDBL_MANT_DIG */ |
#endif /* !IEEE_8087 */ |
#endif /* _WANT_IO_LONG_DOUBLE */ |
/* If we are going to examine or modify specific bits in a double using |
the word0 and/or word1 macros, then we must wrap the double inside |
a union. This is necessary to avoid undefined behavior according to |
the ANSI C spec. */ |
union double_union |
{ |
double d; |
__uint32_t i[2]; |
}; |
#ifdef IEEE_8087 |
#define word0(x) (x.i[1]) |
#define word1(x) (x.i[0]) |
#else |
#define word0(x) (x.i[0]) |
#define word1(x) (x.i[1]) |
#endif |
/* #define P DBL_MANT_DIG */ |
/* Ten_pmax = floor(P*log(2)/log(5)) */ |
/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ |
/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ |
/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ |
#if defined(IEEE_8087) + defined(IEEE_MC68k) |
#if defined (_DOUBLE_IS_32BITS) |
#define Exp_shift 23 |
#define Exp_shift1 23 |
#define Exp_msk1 ((__uint32_t)0x00800000L) |
#define Exp_msk11 ((__uint32_t)0x00800000L) |
#define Exp_mask ((__uint32_t)0x7f800000L) |
#define P 24 |
#define Bias 127 |
#define IEEE_Arith |
#define Emin (-126) |
#define Exp_1 ((__uint32_t)0x3f800000L) |
#define Exp_11 ((__uint32_t)0x3f800000L) |
#define Ebits 8 |
#define Frac_mask ((__uint32_t)0x007fffffL) |
#define Frac_mask1 ((__uint32_t)0x007fffffL) |
#define Ten_pmax 10 |
#define Sign_bit ((__uint32_t)0x80000000L) |
#define Ten_pmax 10 |
#define Bletch 2 |
#define Bndry_mask ((__uint32_t)0x007fffffL) |
#define Bndry_mask1 ((__uint32_t)0x007fffffL) |
#define LSB 1 |
#define Sign_bit ((__uint32_t)0x80000000L) |
#define Log2P 1 |
#define Tiny0 0 |
#define Tiny1 1 |
#define Quick_max 5 |
#define Int_max 6 |
#define Infinite(x) (word0(x) == ((__uint32_t)0x7f800000L)) |
#undef word0 |
#undef word1 |
#define word0(x) (x.i[0]) |
#define word1(x) 0 |
#else |
#define Exp_shift 20 |
#define Exp_shift1 20 |
#define Exp_msk1 ((__uint32_t)0x100000L) |
#define Exp_msk11 ((__uint32_t)0x100000L) |
#define Exp_mask ((__uint32_t)0x7ff00000L) |
#define P 53 |
#define Bias 1023 |
#define IEEE_Arith |
#define Emin (-1022) |
#define Exp_1 ((__uint32_t)0x3ff00000L) |
#define Exp_11 ((__uint32_t)0x3ff00000L) |
#define Ebits 11 |
#define Frac_mask ((__uint32_t)0xfffffL) |
#define Frac_mask1 ((__uint32_t)0xfffffL) |
#define Ten_pmax 22 |
#define Bletch 0x10 |
#define Bndry_mask ((__uint32_t)0xfffffL) |
#define Bndry_mask1 ((__uint32_t)0xfffffL) |
#define LSB 1 |
#define Sign_bit ((__uint32_t)0x80000000L) |
#define Log2P 1 |
#define Tiny0 0 |
#define Tiny1 1 |
#define Quick_max 14 |
#define Int_max 14 |
#define Infinite(x) (word0(x) == ((__uint32_t)0x7ff00000L)) /* sufficient test for here */ |
#endif |
#else |
#undef Sudden_Underflow |
#define Sudden_Underflow |
#ifdef IBM |
#define Exp_shift 24 |
#define Exp_shift1 24 |
#define Exp_msk1 ((__uint32_t)0x1000000L) |
#define Exp_msk11 ((__uint32_t)0x1000000L) |
#define Exp_mask ((__uint32_t)0x7f000000L) |
#define P 14 |
#define Bias 65 |
#define Exp_1 ((__uint32_t)0x41000000L) |
#define Exp_11 ((__uint32_t)0x41000000L) |
#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ |
#define Frac_mask ((__uint32_t)0xffffffL) |
#define Frac_mask1 ((__uint32_t)0xffffffL) |
#define Bletch 4 |
#define Ten_pmax 22 |
#define Bndry_mask ((__uint32_t)0xefffffL) |
#define Bndry_mask1 ((__uint32_t)0xffffffL) |
#define LSB 1 |
#define Sign_bit ((__uint32_t)0x80000000L) |
#define Log2P 4 |
#define Tiny0 ((__uint32_t)0x100000L) |
#define Tiny1 0 |
#define Quick_max 14 |
#define Int_max 15 |
#else /* VAX */ |
#define Exp_shift 23 |
#define Exp_shift1 7 |
#define Exp_msk1 0x80 |
#define Exp_msk11 ((__uint32_t)0x800000L) |
#define Exp_mask ((__uint32_t)0x7f80L) |
#define P 56 |
#define Bias 129 |
#define Exp_1 ((__uint32_t)0x40800000L) |
#define Exp_11 ((__uint32_t)0x4080L) |
#define Ebits 8 |
#define Frac_mask ((__uint32_t)0x7fffffL) |
#define Frac_mask1 ((__uint32_t)0xffff007fL) |
#define Ten_pmax 24 |
#define Bletch 2 |
#define Bndry_mask ((__uint32_t)0xffff007fL) |
#define Bndry_mask1 ((__uint32_t)0xffff007fL) |
#define LSB ((__uint32_t)0x10000L) |
#define Sign_bit ((__uint32_t)0x8000L) |
#define Log2P 1 |
#define Tiny0 0x80 |
#define Tiny1 0 |
#define Quick_max 15 |
#define Int_max 15 |
#endif |
#endif |
/contrib/sdk/sources/newlib/libc/stdio/vfprintf.c |
---|
0,0 → 1,2190 |
/* |
* 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. |
* 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. |
*/ |
/* |
FUNCTION |
<<vfprintf>>, <<vprintf>>, <<vsprintf>>, <<vsnprintf>>, <<vasprintf>>, <<vasnprintf>>---format argument list |
INDEX |
vfprintf |
INDEX |
_vfprintf_r |
INDEX |
vprintf |
INDEX |
_vprintf_r |
INDEX |
vsprintf |
INDEX |
_vsprintf_r |
INDEX |
vsnprintf |
INDEX |
_vsnprintf_r |
INDEX |
vasprintf |
INDEX |
_vasprintf_r |
INDEX |
vasnprintf |
INDEX |
_vasnprintf_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
#include <stdarg.h> |
int vprintf(const char *<[fmt]>, va_list <[list]>); |
int vfprintf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>); |
int vsprintf(char *<[str]>, const char *<[fmt]>, va_list <[list]>); |
int vsnprintf(char *<[str]>, size_t <[size]>, const char *<[fmt]>, |
va_list <[list]>); |
int vasprintf(char **<[strp]>, const char *<[fmt]>, va_list <[list]>); |
char *vasnprintf(char *<[str]>, size_t *<[size]>, const char *<[fmt]>, |
va_list <[list]>); |
int _vprintf_r(struct _reent *<[reent]>, const char *<[fmt]>, |
va_list <[list]>); |
int _vfprintf_r(struct _reent *<[reent]>, FILE *<[fp]>, |
const char *<[fmt]>, va_list <[list]>); |
int _vsprintf_r(struct _reent *<[reent]>, char *<[str]>, |
const char *<[fmt]>, va_list <[list]>); |
int _vasprintf_r(struct _reent *<[reent]>, char **<[str]>, |
const char *<[fmt]>, va_list <[list]>); |
int _vsnprintf_r(struct _reent *<[reent]>, char *<[str]>, |
size_t <[size]>, const char *<[fmt]>, va_list <[list]>); |
char *_vasnprintf_r(struct _reent *<[reent]>, char *<[str]>, |
size_t *<[size]>, const char *<[fmt]>, va_list <[list]>); |
DESCRIPTION |
<<vprintf>>, <<vfprintf>>, <<vasprintf>>, <<vsprintf>>, <<vsnprintf>>, |
and <<vasnprintf>> are (respectively) variants of <<printf>>, |
<<fprintf>>, <<asprintf>>, <<sprintf>>, <<snprintf>>, and |
<<asnprintf>>. 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>>. |
<<_vprintf_r>>, <<_vfprintf_r>>, <<_vasprintf_r>>, <<_vsprintf_r>>, |
<<_vsnprintf_r>>, and <<_vasnprintf_r>> are reentrant versions of the |
above. |
RETURNS |
The return values are consistent with the corresponding functions. |
PORTABILITY |
ANSI C requires <<vprintf>>, <<vfprintf>>, <<vsprintf>>, and |
<<vsnprintf>>. The remaining functions are newlib extensions. |
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#if defined(LIBC_SCCS) && !defined(lint) |
/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/ |
static char *rcsid = "$Id: vfprintf.c,v 1.43 2002/08/13 02:40:06 fitzsim Exp $"; |
#endif /* LIBC_SCCS and not lint */ |
/* |
* Actual printf innards. |
* |
* This code is large and complicated... |
*/ |
#include <newlib.h> |
#ifdef INTEGER_ONLY |
# define VFPRINTF vfiprintf |
# ifdef STRING_ONLY |
# define _VFPRINTF_R _svfiprintf_r |
# else |
# define _VFPRINTF_R _vfiprintf_r |
# endif |
#else |
# define VFPRINTF vfprintf |
# ifdef STRING_ONLY |
# define _VFPRINTF_R _svfprintf_r |
# else |
# define _VFPRINTF_R _vfprintf_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 "../stdlib/local.h" |
#include "fvwrite.h" |
#include "vfieeefp.h" |
/* 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 |
#ifdef STRING_ONLY |
#define __SPRINT __ssprint_r |
#else |
#define __SPRINT __sprint_r |
#endif |
/* The __sprint_r/__ssprint_r functions are shared between all versions of |
vfprintf and vfwprintf. They must only be defined once, which we do in |
the INTEGER_ONLY versions here. */ |
#ifdef STRING_ONLY |
#ifdef INTEGER_ONLY |
int |
_DEFUN(__ssprint_r, (ptr, fp, uio), |
struct _reent *ptr _AND |
FILE *fp _AND |
register struct __suio *uio) |
{ |
register size_t len; |
register int w; |
register struct __siov *iov; |
register _CONST char *p = NULL; |
iov = uio->uio_iov; |
len = 0; |
if (uio->uio_resid == 0) { |
uio->uio_iovcnt = 0; |
return (0); |
} |
do { |
while (len == 0) { |
p = iov->iov_base; |
len = iov->iov_len; |
iov++; |
} |
w = fp->_w; |
if (len >= w && fp->_flags & (__SMBF | __SOPT)) { |
/* must be asprintf family */ |
unsigned char *str; |
int curpos = (fp->_p - fp->_bf._base); |
/* Choose a geometric growth factor to avoid |
* quadratic realloc behavior, but use a rate less |
* than (1+sqrt(5))/2 to accomodate malloc |
* overhead. asprintf EXPECTS us to overallocate, so |
* that it can add a trailing \0 without |
* reallocating. The new allocation should thus be |
* max(prev_size*1.5, curpos+len+1). */ |
int newsize = fp->_bf._size * 3 / 2; |
if (newsize < curpos + len + 1) |
newsize = curpos + len + 1; |
if (fp->_flags & __SOPT) |
{ |
/* asnprintf leaves original buffer alone. */ |
str = (unsigned char *)_malloc_r (ptr, newsize); |
if (!str) |
{ |
ptr->_errno = ENOMEM; |
goto err; |
} |
memcpy (str, fp->_bf._base, curpos); |
fp->_flags = (fp->_flags & ~__SOPT) | __SMBF; |
} |
else |
{ |
str = (unsigned char *)_realloc_r (ptr, fp->_bf._base, |
newsize); |
if (!str) { |
/* Free unneeded buffer. */ |
_free_r (ptr, fp->_bf._base); |
/* Ensure correct errno, even if free |
* changed it. */ |
ptr->_errno = ENOMEM; |
goto err; |
} |
} |
fp->_bf._base = str; |
fp->_p = str + curpos; |
fp->_bf._size = newsize; |
w = len; |
fp->_w = newsize - curpos; |
} |
if (len < w) |
w = len; |
(void)memmove ((_PTR) fp->_p, (_PTR) p, (size_t) (w)); |
fp->_w -= w; |
fp->_p += w; |
w = len; /* pretend we copied all */ |
p += w; |
len -= w; |
} while ((uio->uio_resid -= w) != 0); |
uio->uio_resid = 0; |
uio->uio_iovcnt = 0; |
return 0; |
err: |
fp->_flags |= __SERR; |
uio->uio_resid = 0; |
uio->uio_iovcnt = 0; |
return EOF; |
} |
#else /* !INTEGER_ONLY */ |
int __ssprint_r (struct _reent *, FILE *, register struct __suio *); |
#endif /* !INTEGER_ONLY */ |
#else /* !STRING_ONLY */ |
#ifdef INTEGER_ONLY |
/* |
* Flush out all the vectors defined by the given uio, |
* then reset it so that it can be reused. |
*/ |
int |
_DEFUN(__sprint_r, (ptr, fp, uio), |
struct _reent *ptr _AND |
FILE *fp _AND |
register struct __suio *uio) |
{ |
register int err = 0; |
if (uio->uio_resid == 0) { |
uio->uio_iovcnt = 0; |
return (0); |
} |
if (fp->_flags2 & __SWID) { |
struct __siov *iov; |
wchar_t *p; |
int i, len; |
iov = uio->uio_iov; |
for (; uio->uio_resid != 0; |
uio->uio_resid -= len * sizeof (wchar_t), iov++) { |
p = (wchar_t *) iov->iov_base; |
len = iov->iov_len / sizeof (wchar_t); |
for (i = 0; i < len; i++) { |
if (_fputwc_r (ptr, p[i], fp) == WEOF) { |
err = -1; |
goto out; |
} |
} |
} |
} else |
err = __sfvwrite_r(ptr, fp, uio); |
out: |
uio->uio_resid = 0; |
uio->uio_iovcnt = 0; |
return (err); |
} |
#else /* !INTEGER_ONLY */ |
int __sprint_r (struct _reent *, FILE *, register struct __suio *); |
#endif /* !INTEGER_ONLY */ |
/* |
* 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(__sbprintf, (rptr, fp, fmt, ap), |
struct _reent *rptr _AND |
register FILE *fp _AND |
_CONST char *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 = _VFPRINTF_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 /* !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 char *cvt(struct _reent *, _PRINTF_FLOAT_TYPE, int, int, char *, int *, |
int, int *, char *); |
static int exponent(char *, 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 %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 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; |
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, char *fmt, |
va_list *ap, int *numargs, union arg_val *args, |
int *arg_type, char **last_fmt)); |
#endif /* !_NO_POS_ARGS */ |
/* |
* Macros for converting digits to letters and vice versa |
*/ |
#define to_digit(c) ((c) - '0') |
#define is_digit(c) ((unsigned)to_digit (c) <= 9) |
#define to_char(n) ((n) + '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 |
int _EXFUN(_VFPRINTF_R, (struct _reent *, FILE *, _CONST char *, va_list)); |
#ifndef STRING_ONLY |
int |
_DEFUN(VFPRINTF, (fp, fmt0, ap), |
FILE * fp _AND |
_CONST char *fmt0 _AND |
va_list ap) |
{ |
int result; |
result = _VFPRINTF_R (_REENT, fp, fmt0, ap); |
return result; |
} |
#endif /* STRING_ONLY */ |
int |
_DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap), |
struct _reent *data _AND |
FILE * fp _AND |
_CONST char *fmt0 _AND |
va_list ap) |
{ |
register char *fmt; /* format string */ |
register int ch; /* character from fmt */ |
register int n, m; /* handy integers (short term usage) */ |
register char *cp; /* handy char pointer (short term usage) */ |
register struct __siov *iovp;/* for PRINT macro */ |
register int flags; /* flags as above */ |
char *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 */ |
char *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 */ |
char sign; /* sign prefix (' ', '+', '-', or \0) */ |
#ifdef _WANT_IO_C99_FORMATS |
/* locale specific numeric grouping */ |
char *thousands_sep; |
size_t thsnd_len; |
const char *grouping; |
#endif |
#ifdef FLOATING_POINT |
char *decimal_point = _localeconv_r (data)->decimal_point; |
size_t decp_len = strlen (decimal_point); |
char 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 */ |
char 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 |
#ifdef _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; /* size of converted field or string */ |
char *xdigs = NULL; /* digits for [xX] conversion */ |
#define NIOV 8 |
struct __suio uio; /* output information: summary */ |
struct __siov iov[NIOV];/* ... and individual io vectors */ |
char buf[BUF]; /* space for %c, %S, %[diouxX], %[aA] */ |
char ox[2]; /* space for 0x hex-prefix */ |
#ifdef _MB_CAPABLE |
wchar_t wc; |
mbstate_t state; /* mbtowc calls from library must not change state */ |
#endif |
char *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 char blanks[PADSIZE] = |
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; |
static _CONST char zeroes[PADSIZE] = |
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; |
#ifdef _MB_CAPABLE |
memset (&state, '\0', sizeof (state)); |
#endif |
/* |
* BEWARE, these `goto error' on error, and PAD uses `n'. |
*/ |
#define PRINT(ptr, len) { \ |
iovp->iov_base = (ptr); \ |
iovp->iov_len = (len); \ |
uio.uio_resid += (len); \ |
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; \ |
} |
/* 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); |
_flockfile (fp); |
ORIENT(fp, -1); |
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ |
if (cantwrite (data, fp)) { |
_funlockfile (fp); |
return (EOF); |
} |
/* optimise fprintf(stderr) (and other unbuffered Unix files) */ |
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && |
fp->_file >= 0) { |
_funlockfile (fp); |
return (__sbprintf (data, fp, fmt0, ap)); |
} |
#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 = (char *)fmt0; |
uio.uio_iov = iovp = iov; |
uio.uio_resid = 0; |
uio.uio_iovcnt = 0; |
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; |
#ifdef _MB_CAPABLE |
while ((n = __mbtowc (data, &wc, fmt, MB_CUR_MAX, |
__locale_charset (), &state)) != 0) { |
if (n < 0) { |
/* Wave invalid chars through. */ |
memset (&state, 0, sizeof state); |
n = 1; |
} |
else if (wc == '%') |
break; |
fmt += n; |
} |
#else |
while (*fmt != '\0' && *fmt != '%') |
fmt += 1; |
#endif |
if ((m = fmt - cp) != 0) { |
PRINT (cp, m); |
ret += m; |
} |
#ifdef _MB_CAPABLE |
if (n <= 0) |
goto done; |
#else |
if (*fmt == '\0') |
goto done; |
#endif |
fmt_anchor = fmt; |
fmt++; /* skip over '%' */ |
flags = 0; |
dprec = 0; |
width = 0; |
prec = -1; |
sign = '\0'; |
#ifdef FLOATING_POINT |
lead = 0; |
#endif |
#ifdef _WANT_IO_C99_FORMATS |
nseps = nrepeats = 0; |
#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 '\'': |
thousands_sep = _localeconv_r (data)->thousands_sep; |
thsnd_len = strlen (thousands_sep); |
grouping = _localeconv_r (data)->grouping; |
if (thsnd_len > 0 && grouping && *grouping) |
flags |= GROUPING; |
goto rflag; |
#endif |
case ' ': |
/* |
* ``If the space and + flags both appear, the space |
* flag will be ignored.'' |
* -- ANSI X3J11 |
*/ |
if (!sign) |
sign = ' '; |
goto rflag; |
case '#': |
flags |= ALT; |
goto rflag; |
case '*': |
#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)) { |
char *old_fmt = fmt; |
n = 0; |
ch = *fmt++; |
do { |
n = 10 * n + to_digit (ch); |
ch = *fmt++; |
} while (is_digit (ch)); |
if (ch == '$') { |
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 '-': |
flags |= LADJUST; |
goto rflag; |
case '+': |
sign = '+'; |
goto rflag; |
case '.': |
if ((ch = *fmt++) == '*') { |
#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)) { |
char *old_fmt = fmt; |
n = 0; |
ch = *fmt++; |
do { |
n = 10 * n + to_digit (ch); |
ch = *fmt++; |
} while (is_digit (ch)); |
if (ch == '$') { |
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 '0': |
/* |
* ``Note that 0 is taken as a flag, not as the |
* beginning of a field width.'' |
* -- ANSI X3J11 |
*/ |
flags |= ZEROPAD; |
goto rflag; |
case '1': case '2': case '3': case '4': |
case '5': case '6': case '7': case '8': case '9': |
n = 0; |
do { |
n = 10 * n + to_digit (ch); |
ch = *fmt++; |
} while (is_digit (ch)); |
#ifndef _NO_POS_ARGS |
if (ch == '$') { |
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': |
flags |= LONGDBL; |
goto rflag; |
#endif |
case 'h': |
#ifdef _WANT_IO_C99_FORMATS |
if (*fmt == 'h') { |
fmt++; |
flags |= CHARINT; |
} else |
#endif |
flags |= SHORTINT; |
goto rflag; |
case 'l': |
#if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG |
if (*fmt == 'l') { |
fmt++; |
flags |= QUADINT; |
} else |
#endif |
flags |= LONGINT; |
goto rflag; |
case 'q': /* extension */ |
flags |= QUADINT; |
goto rflag; |
#ifdef _WANT_IO_C99_FORMATS |
case 'j': |
if (sizeof (intmax_t) == sizeof (long)) |
flags |= LONGINT; |
else |
flags |= QUADINT; |
goto rflag; |
case '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 '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 'C': |
#endif /* _WANT_IO_C99_FORMATS */ |
case 'c': |
cp = buf; |
#ifdef _MB_CAPABLE |
if (ch == 'C' || (flags & LONGINT)) { |
mbstate_t ps; |
memset ((_PTR)&ps, '\0', sizeof (mbstate_t)); |
if ((size = (int)_wcrtomb_r (data, cp, |
(wchar_t)GET_ARG (N, ap, wint_t), |
&ps)) == -1) { |
fp->_flags |= __SERR; |
goto error; |
} |
} |
else |
#endif /* _MB_CAPABLE */ |
{ |
*cp = GET_ARG (N, ap, int); |
size = 1; |
} |
sign = '\0'; |
break; |
case 'D': /* extension */ |
flags |= LONGINT; |
/*FALLTHROUGH*/ |
case 'd': |
case 'i': |
_uquad = SARG (); |
#ifndef _NO_LONGLONG |
if ((quad_t)_uquad < 0) |
#else |
if ((long) _uquad < 0) |
#endif |
{ |
_uquad = -_uquad; |
sign = '-'; |
} |
base = DEC; |
goto number; |
#ifdef FLOATING_POINT |
# ifdef _WANT_IO_C99_FORMATS |
case 'a': |
case 'A': |
case 'F': |
# endif |
case 'e': |
case 'E': |
case 'f': |
case 'g': |
case '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 <= 'G') /* 'A', 'E', 'F', or 'G' */ |
cp = "INF"; |
else |
cp = "inf"; |
size = 3; |
flags &= ~ZEROPAD; |
break; |
} |
if (isnan (_fpvalue)) { |
if (ch <= 'G') /* 'A', 'E', 'F', or 'G' */ |
cp = "NAN"; |
else |
cp = "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 = '-'; |
if (ch <= 'G') /* 'A', 'E', 'F', or 'G' */ |
cp = "INF"; |
else |
cp = "inf"; |
size = 3; |
flags &= ~ZEROPAD; |
break; |
} |
if (expt == 1) { |
if (ch <= 'G') /* 'A', 'E', 'F', or 'G' */ |
cp = "NAN"; |
else |
cp = "nan"; |
size = 3; |
flags &= ~ZEROPAD; |
break; |
} |
# endif /* !_NO_LONGDBL */ |
# ifdef _WANT_IO_C99_FORMATS |
if (ch == 'a' || ch == 'A') { |
ox[0] = '0'; |
ox[1] = ch == 'a' ? 'x' : 'X'; |
flags |= HEXPREFIX; |
if (prec >= BUF) |
{ |
if ((malloc_buf = |
(char *)_malloc_r (data, prec + 1)) |
== NULL) |
{ |
fp->_flags |= __SERR; |
goto error; |
} |
cp = malloc_buf; |
} |
else |
cp = buf; |
} else |
# endif /* _WANT_IO_C99_FORMATS */ |
if (prec == -1) { |
prec = DEFPREC; |
} else if ((ch == 'g' || ch == 'G') && prec == 0) { |
prec = 1; |
} |
flags |= FPT; |
cp = cvt (data, _fpvalue, prec, flags, &softsign, |
&expt, ch, &ndig, cp); |
if (ch == 'g' || ch == 'G') { |
if (expt <= -4 || expt > prec) |
ch -= 2; /* 'e' or 'E' */ |
else |
ch = 'g'; |
} |
# ifdef _WANT_IO_C99_FORMATS |
else if (ch == 'F') |
ch = 'f'; |
# endif |
if (ch <= 'e') { /* 'a', 'A', 'e', or 'E' fmt */ |
--expt; |
expsize = exponent (expstr, expt, ch); |
size = expsize + ndig; |
if (ndig > 1 || flags & ALT) |
++size; |
# ifdef _WANT_IO_C99_FORMATS |
flags &= ~GROUPING; |
# endif |
} else { |
if (ch == '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) * thsnd_len; |
} else |
# endif |
lead = expt; |
} |
if (softsign) |
sign = '-'; |
break; |
#endif /* FLOATING_POINT */ |
case '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 'O': /* extension */ |
flags |= LONGINT; |
/*FALLTHROUGH*/ |
case 'o': |
_uquad = UARG (); |
base = OCT; |
#ifdef _WANT_IO_C99_FORMATS |
flags &= ~GROUPING; |
#endif |
goto nosign; |
case '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 = "0123456789abcdef"; |
flags |= HEXPREFIX; |
ox[0] = '0'; |
ox[1] = ch = 'x'; |
goto nosign; |
case 's': |
#ifdef _WANT_IO_C99_FORMATS |
case 'S': |
#endif |
sign = '\0'; |
cp = GET_ARG (N, ap, char_ptr_t); |
#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 = "(null)"; |
size = ((unsigned) prec > 6U) ? 6 : prec; |
} |
else |
#endif /* __OPTIMIZE_SIZE__ */ |
#ifdef _MB_CAPABLE |
if (ch == 'S' || (flags & LONGINT)) { |
mbstate_t ps; |
_CONST wchar_t *wcp; |
wcp = (_CONST wchar_t *)cp; |
size = m = 0; |
memset ((_PTR)&ps, '\0', sizeof (mbstate_t)); |
/* Count number of bytes needed for multibyte |
string that will be produced from widechar |
string. */ |
if (prec >= 0) { |
while (1) { |
if (wcp[m] == L'\0') |
break; |
if ((n = (int)_wcrtomb_r (data, |
buf, wcp[m], &ps)) == -1) { |
fp->_flags |= __SERR; |
goto error; |
} |
if (n + size > prec) |
break; |
m += 1; |
size += n; |
if (size == prec) |
break; |
} |
} |
else { |
if ((size = (int)_wcsrtombs_r (data, |
NULL, &wcp, 0, &ps)) == -1) { |
fp->_flags |= __SERR; |
goto error; |
} |
wcp = (_CONST wchar_t *)cp; |
} |
if (size == 0) |
break; |
if (size >= BUF) { |
if ((malloc_buf = |
(char *)_malloc_r (data, size + 1)) |
== NULL) { |
fp->_flags |= __SERR; |
goto error; |
} |
cp = malloc_buf; |
} else |
cp = buf; |
/* Convert widechar string to multibyte string. */ |
memset ((_PTR)&ps, '\0', sizeof (mbstate_t)); |
if (_wcsrtombs_r (data, cp, &wcp, size, &ps) |
!= size) { |
fp->_flags |= __SERR; |
goto error; |
} |
cp[size] = '\0'; |
} |
else |
#endif /* _MB_CAPABLE */ |
if (prec >= 0) { |
/* |
* can't use strlen; can only look for the |
* NUL in the first `prec' characters, and |
* strlen () will go further. |
*/ |
char *p = memchr (cp, 0, prec); |
if (p != NULL) { |
size = p - cp; |
if (size > prec) |
size = prec; |
} else |
size = prec; |
} else |
size = strlen (cp); |
break; |
case 'U': /* extension */ |
flags |= LONGINT; |
/*FALLTHROUGH*/ |
case 'u': |
_uquad = UARG (); |
base = DEC; |
goto nosign; |
case 'X': |
xdigs = "0123456789ABCDEF"; |
goto hex; |
case 'x': |
xdigs = "0123456789abcdef"; |
hex: _uquad = UARG (); |
base = HEX; |
/* leading 0x/X only if non-zero */ |
if (flags & ALT && _uquad != 0) { |
ox[0] = '0'; |
ox[1] = ch; |
flags |= HEXPREFIX; |
} |
#ifdef _WANT_IO_C99_FORMATS |
flags &= ~GROUPING; |
#endif |
/* unsigned conversions */ |
nosign: sign = '\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 != '0') |
*--cp = '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 -= thsnd_len; |
strncpy (cp, thousands_sep, |
thsnd_len); |
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 = "bug in vfprintf: bad base"; |
size = strlen (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 = '0'; |
size = buf + BUF - cp; |
skipsize: |
break; |
default: /* "%?" prints ?, unless ? is NUL */ |
if (ch == '\0') |
goto done; |
/* pretend it was %c with argument ch */ |
cp = buf; |
*cp = ch; |
size = 1; |
sign = '\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 >= 'f') { /* 'f' or 'g' */ |
if (_fpvalue == 0) { |
/* kludge for __dtoa irregularity */ |
PRINT ("0", 1); |
if (expt < ndig || flags & ALT) { |
PRINT (decimal_point, decp_len); |
PAD (ndig - 1, zeroes); |
} |
} else if (expt <= 0) { |
PRINT ("0", 1); |
if (expt || ndig || flags & ALT) { |
PRINT (decimal_point, decp_len); |
PAD (-expt, zeroes); |
PRINT (cp, ndig); |
} |
} else { |
char *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, thsnd_len); |
PRINTANDPAD (cp, convbuf + ndig, |
*grouping, zeroes); |
cp += *grouping; |
} |
if (cp > convbuf + ndig) |
cp = convbuf + ndig; |
} |
#endif |
if (expt < ndig || flags & ALT) |
PRINT (decimal_point, decp_len); |
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, decp_len); |
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 |
_funlockfile (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]; if it is [aA], then the return string lives in BUF, |
otherwise the return value shares the mprec reentrant storage. */ |
static char * |
cvt(struct _reent *data, _PRINTF_FLOAT_TYPE value, int ndigits, int flags, |
char *sign, int *decpt, int ch, int *length, char *buf) |
{ |
int mode, dsgn; |
char *digits, *bp, *rve; |
# 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 = '-'; |
} else |
*sign = '\000'; |
# 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 = '-'; |
} else |
*sign = '\000'; |
# endif /* !_NO_LONGDBL */ |
# ifdef _WANT_IO_C99_FORMATS |
if (ch == 'a' || ch == 'A') { |
/* 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 == 'a' ? "0123456789abcdef" : "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 = '0'; |
} |
*rve = *rve == '9' ? digits[0xa] : *rve + 1; |
} else { |
while (ndigits-- >= 0) { |
*bp++ = '0'; |
} |
} |
*length = bp - buf; |
return buf; |
} |
# endif /* _WANT_IO_C99_FORMATS */ |
if (ch == 'f' || ch == '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 == 'e' || ch == 'E') { |
ndigits++; |
} |
mode = 2; /* ndigits significant digits */ |
} |
digits = _DTOA_R (data, value, mode, ndigits, decpt, &dsgn, &rve); |
if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */ |
bp = digits + ndigits; |
if (ch == 'f' || ch == 'F') { |
if (*digits == '0' && value) |
*decpt = -ndigits + 1; |
bp += *decpt; |
} |
if (value == 0) /* kludge for __dtoa irregularity */ |
rve = bp; |
while (rve < bp) |
*rve++ = '0'; |
} |
*length = rve - digits; |
return (digits); |
} |
static int |
exponent(char *p0, int exp, int fmtch) |
{ |
register char *p, *t; |
char expbuf[MAXEXPLEN]; |
# ifdef _WANT_IO_C99_FORMATS |
int isa = fmtch == 'a' || fmtch == 'A'; |
# else |
# define isa 0 |
# endif |
p = p0; |
*p++ = isa ? 'p' - 'a' + fmtch : fmtch; |
if (exp < 0) { |
exp = -exp; |
*p++ = '-'; |
} |
else |
*p++ = '+'; |
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++ = '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. */ |
/* The below constant state tables are shared between all versions of |
vfprintf and vfwprintf. They must only be defined once, which we do in |
the STRING_ONLY/INTEGER_ONLY versions here. */ |
#if defined (STRING_ONLY) && defined(INTEGER_ONLY) |
_CONST __CH_CLASS __chclass[256] = { |
/* 00-07 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 08-0f */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 10-17 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 18-1f */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 20-27 */ FLAG, OTHER, OTHER, FLAG, DOLLAR, OTHER, OTHER, FLAG, |
/* 28-2f */ OTHER, OTHER, STAR, FLAG, OTHER, FLAG, DOT, OTHER, |
/* 30-37 */ ZERO, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, |
/* 38-3f */ DIGIT, DIGIT, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 40-47 */ OTHER, SPEC, OTHER, SPEC, SPEC, SPEC, SPEC, SPEC, |
/* 48-4f */ OTHER, OTHER, OTHER, OTHER, MODFR, OTHER, OTHER, SPEC, |
/* 50-57 */ OTHER, OTHER, OTHER, SPEC, OTHER, SPEC, OTHER, OTHER, |
/* 58-5f */ SPEC, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 60-67 */ OTHER, SPEC, OTHER, SPEC, SPEC, SPEC, SPEC, SPEC, |
/* 68-6f */ MODFR, SPEC, MODFR, OTHER, MODFR, OTHER, SPEC, SPEC, |
/* 70-77 */ SPEC, MODFR, OTHER, SPEC, MODFR, SPEC, OTHER, OTHER, |
/* 78-7f */ SPEC, OTHER, MODFR, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 80-87 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 88-8f */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 90-97 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* 98-9f */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* a0-a7 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* a8-af */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* b0-b7 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* b8-bf */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* c0-c7 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* c8-cf */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* d0-d7 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* d8-df */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* e0-e7 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* e8-ef */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* f0-f7 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
/* f8-ff */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, |
}; |
_CONST __STATE __state_table[MAX_STATE][MAX_CH_CLASS] = { |
/* '0' '1-9' '$' MODFR SPEC '.' '*' FLAG OTHER */ |
/* START */ { SFLAG, WDIG, DONE, SMOD, DONE, SDOT, VARW, SFLAG, DONE }, |
/* SFLAG */ { SFLAG, WDIG, DONE, SMOD, DONE, SDOT, VARW, SFLAG, DONE }, |
/* WDIG */ { DONE, DONE, WIDTH, SMOD, DONE, SDOT, DONE, DONE, DONE }, |
/* WIDTH */ { DONE, DONE, DONE, SMOD, DONE, SDOT, DONE, DONE, DONE }, |
/* SMOD */ { DONE, DONE, DONE, DONE, DONE, DONE, DONE, DONE, DONE }, |
/* SDOT */ { SDOT, PREC, DONE, SMOD, DONE, DONE, VARP, DONE, DONE }, |
/* VARW */ { DONE, VWDIG, DONE, SMOD, DONE, SDOT, DONE, DONE, DONE }, |
/* VARP */ { DONE, VPDIG, DONE, SMOD, DONE, DONE, DONE, DONE, DONE }, |
/* PREC */ { DONE, DONE, DONE, SMOD, DONE, DONE, DONE, DONE, DONE }, |
/* VWDIG */ { DONE, DONE, WIDTH, DONE, DONE, DONE, DONE, DONE, DONE }, |
/* VPDIG */ { DONE, DONE, PREC, DONE, DONE, DONE, DONE, DONE, DONE }, |
}; |
_CONST __ACTION __action_table[MAX_STATE][MAX_CH_CLASS] = { |
/* '0' '1-9' '$' MODFR SPEC '.' '*' FLAG OTHER */ |
/* START */ { NOOP, NUMBER, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP }, |
/* SFLAG */ { NOOP, NUMBER, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP }, |
/* WDIG */ { NOOP, NOOP, GETPOS, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP }, |
/* WIDTH */ { NOOP, NOOP, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP }, |
/* SMOD */ { NOOP, NOOP, NOOP, NOOP, GETARG, NOOP, NOOP, NOOP, NOOP }, |
/* SDOT */ { NOOP, SKIPNUM, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP }, |
/* VARW */ { NOOP, NUMBER, NOOP, GETPW, GETPWB, GETPW, NOOP, NOOP, NOOP }, |
/* VARP */ { NOOP, NUMBER, NOOP, GETPW, GETPWB, NOOP, NOOP, NOOP, NOOP }, |
/* PREC */ { NOOP, NOOP, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP }, |
/* VWDIG */ { NOOP, NOOP, PWPOS, NOOP, NOOP, NOOP, NOOP, NOOP, NOOP }, |
/* VPDIG */ { NOOP, NOOP, PWPOS, NOOP, NOOP, NOOP, NOOP, NOOP, NOOP }, |
}; |
#endif /* STRING_ONLY && INTEGER_ONLY */ |
/* 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 |
char *fmt _AND |
va_list *ap _AND |
int *numargs_p _AND |
union arg_val *args _AND |
int *arg_type _AND |
char **last_fmt) |
{ |
int 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 }; |
# ifdef _MB_CAPABLE |
wchar_t wc; |
mbstate_t wc_state; |
int nbytes; |
# endif |
/* if this isn't the first call, pick up where we left off last time */ |
if (*last_fmt != NULL) |
fmt = *last_fmt; |
# ifdef _MB_CAPABLE |
memset (&wc_state, '\0', sizeof (wc_state)); |
# endif |
/* 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) |
{ |
# ifdef _MB_CAPABLE |
while ((nbytes = __mbtowc (data, &wc, fmt, MB_CUR_MAX, |
__locale_charset (), &wc_state)) > 0) |
{ |
fmt += nbytes; |
if (wc == '%') |
break; |
} |
if (nbytes <= 0) |
break; |
# else |
while (*fmt != '\0' && *fmt != '%') |
fmt += 1; |
if (*fmt == '\0') |
break; |
# endif /* ! _MB_CAPABLE */ |
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 = __chclass[ch]; |
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 'h': |
/* No flag needed, since short and char promote to int. */ |
break; |
case 'L': |
flags |= LONGDBL; |
break; |
case 'q': |
flags |= QUADINT; |
break; |
# ifdef _WANT_IO_C99_FORMATS |
case 'j': |
if (sizeof (intmax_t) == sizeof (long)) |
flags |= LONGINT; |
else |
flags |= QUADINT; |
break; |
case '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 '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': |
default: |
# if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG |
if (*fmt == '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 'd': |
case 'i': |
case 'o': |
case 'x': |
case 'X': |
case '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; |
case 'D': |
case 'U': |
case 'O': |
spec_type = LONG_INT; |
break; |
# ifdef _WANT_IO_C99_FORMATS |
case 'a': |
case 'A': |
case 'F': |
# endif |
case 'f': |
case 'g': |
case 'G': |
case 'E': |
case 'e': |
# ifndef _NO_LONGDBL |
if (flags & LONGDBL) |
spec_type = LONG_DOUBLE; |
else |
# endif |
spec_type = DOUBLE; |
break; |
case 's': |
# ifdef _WANT_IO_C99_FORMATS |
case 'S': |
# endif |
case 'p': |
case 'n': |
spec_type = CHAR_PTR; |
break; |
case '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 'C': |
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_char_ptr_t = va_arg (*ap, char *); |
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_char_ptr_t = va_arg (*ap, char *); |
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/vfscanf.c |
---|
0,0 → 1,1620 |
/*- |
* 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 |
<<vfscanf>>, <<vscanf>>, <<vsscanf>>---format argument list |
INDEX |
vfscanf |
INDEX |
_vfscanf_r |
INDEX |
vscanf |
INDEX |
_vscanf_r |
INDEX |
vsscanf |
INDEX |
_vsscanf_r |
ANSI_SYNOPSIS |
#include <stdio.h> |
#include <stdarg.h> |
int vscanf(const char *<[fmt]>, va_list <[list]>); |
int vfscanf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>); |
int vsscanf(const char *<[str]>, const char *<[fmt]>, va_list <[list]>); |
int _vscanf_r(struct _reent *<[reent]>, const char *<[fmt]>, |
va_list <[list]>); |
int _vfscanf_r(struct _reent *<[reent]>, FILE *<[fp]>, const char *<[fmt]>, |
va_list <[list]>); |
int _vsscanf_r(struct _reent *<[reent]>, const char *<[str]>, |
const char *<[fmt]>, va_list <[list]>); |
TRAD_SYNOPSIS |
#include <stdio.h> |
#include <varargs.h> |
int vscanf( <[fmt]>, <[ist]>) |
char *<[fmt]>; |
va_list <[list]>; |
int vfscanf( <[fp]>, <[fmt]>, <[list]>) |
FILE *<[fp]>; |
char *<[fmt]>; |
va_list <[list]>; |
int vsscanf( <[str]>, <[fmt]>, <[list]>) |
char *<[str]>; |
char *<[fmt]>; |
va_list <[list]>; |
int _vscanf_r( <[reent]>, <[fmt]>, <[ist]>) |
struct _reent *<[reent]>; |
char *<[fmt]>; |
va_list <[list]>; |
int _vfscanf_r( <[reent]>, <[fp]>, <[fmt]>, <[list]>) |
struct _reent *<[reent]>; |
FILE *<[fp]>; |
char *<[fmt]>; |
va_list <[list]>; |
int _vsscanf_r( <[reent]>, <[str]>, <[fmt]>, <[list]>) |
struct _reent *<[reent]>; |
char *<[str]>; |
char *<[fmt]>; |
va_list <[list]>; |
DESCRIPTION |
<<vscanf>>, <<vfscanf>>, and <<vsscanf>> are (respectively) variants |
of <<scanf>>, <<fscanf>>, and <<sscanf>>. 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: |
<<vscanf>> returns the number of input fields successfully scanned, |
converted, and stored; the return value does not include scanned |
fields which were not stored. |
If <<vscanf>> attempts to read at end-of-file, the return value |
is <<EOF>>. |
If no fields were stored, the return value is <<0>>. |
The routines <<_vscanf_r>>, <<_vfscanf_f>>, and <<_vsscanf_r>> are |
reentrant versions which take an additional first parameter which points to the |
reentrancy structure. |
PORTABILITY |
These are GNU extensions. |
Supporting OS subroutines required: |
*/ |
#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" |
#include "../stdlib/local.h" |
#ifdef INTEGER_ONLY |
#define VFSCANF vfiscanf |
#define _VFSCANF_R _vfiscanf_r |
#define __SVFSCANF __svfiscanf |
#ifdef STRING_ONLY |
# define __SVFSCANF_R __ssvfiscanf_r |
#else |
# define __SVFSCANF_R __svfiscanf_r |
#endif |
#else |
#define VFSCANF vfscanf |
#define _VFSCANF_R _vfscanf_r |
#define __SVFSCANF __svfscanf |
#ifdef STRING_ONLY |
# define __SVFSCANF_R __ssvfscanf_r |
#else |
# define __SVFSCANF_R __svfscanf_r |
#endif |
#ifndef NO_FLOATING_POINT |
#define FLOATING_POINT |
#endif |
#endif |
#ifdef STRING_ONLY |
#undef _flockfile |
#undef _funlockfile |
#define _flockfile(x) {} |
#define _funlockfile(x) {} |
#define _ungetc_r _sungetc_r |
#define __srefill_r __ssrefill_r |
#define _fread_r _sfread_r |
#endif |
#ifdef FLOATING_POINT |
#include <math.h> |
#include <float.h> |
/* 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 _strtold _PARAMS((char *s, char **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 NNZDIGITS 0x800 /* no non-zero digits 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., strtol or strtoul */ |
#define CT_FLOAT 4 /* floating, i.e., strtod */ |
#if 0 |
#define u_char unsigned char |
#endif |
#define u_char char |
#define u_long unsigned long |
#ifndef _NO_LONGLONG |
typedef unsigned long long u_long_long; |
#endif |
/* |
* vfscanf |
*/ |
#define BufferEmpty (fp->_r <= 0 && __srefill_r(rptr, fp)) |
#ifndef STRING_ONLY |
#ifndef _REENT_ONLY |
int |
_DEFUN(VFSCANF, (fp, fmt, ap), |
register FILE *fp _AND |
_CONST char *fmt _AND |
va_list ap) |
{ |
CHECK_INIT(_REENT, fp); |
return __SVFSCANF_R (_REENT, fp, fmt, ap); |
} |
int |
_DEFUN(__SVFSCANF, (fp, fmt0, ap), |
register FILE *fp _AND |
char _CONST *fmt0 _AND |
va_list ap) |
{ |
return __SVFSCANF_R (_REENT, fp, fmt0, ap); |
} |
#endif /* !_REENT_ONLY */ |
int |
_DEFUN(_VFSCANF_R, (data, fp, fmt, ap), |
struct _reent *data _AND |
register FILE *fp _AND |
_CONST char *fmt _AND |
va_list ap) |
{ |
CHECK_INIT(data, fp); |
return __SVFSCANF_R (data, fp, fmt, ap); |
} |
#endif /* !STRING_ONLY */ |
#if defined (STRING_ONLY) && defined (INTEGER_ONLY) |
/* When dealing with the sscanf family, we don't want to use the |
* regular ungetc which will drag in file I/O items we don't need. |
* So, we create our own trimmed-down version. */ |
int |
_DEFUN(_sungetc_r, (data, fp, ch), |
struct _reent *data _AND |
int c _AND |
register FILE *fp) |
{ |
if (c == EOF) |
return (EOF); |
/* After ungetc, we won't be at eof anymore */ |
fp->_flags &= ~__SEOF; |
c = (unsigned char) c; |
/* |
* If we are in the middle of ungetc'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 = c; |
fp->_r++; |
return c; |
} |
/* |
* If we can handle this by simply backing up, do so, |
* but never replace the original character. |
* (This makes sscanf() work when scanning `const' data.) |
*/ |
if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && fp->_p[-1] == c) |
{ |
fp->_p--; |
fp->_r++; |
return c; |
} |
/* |
* 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->_ubuf[sizeof (fp->_ubuf) - 1] = c; |
fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1]; |
fp->_r = 1; |
return c; |
} |
/* String only version of __srefill_r for sscanf family. */ |
int |
_DEFUN(__ssrefill_r, (ptr, fp), |
struct _reent * ptr _AND |
register FILE * fp) |
{ |
/* |
* Our only hope of further input is the ungetc buffer. |
* If there is anything in that buffer to read, return. |
*/ |
if (HASUB (fp)) |
{ |
FREEUB (ptr, fp); |
if ((fp->_r = fp->_ur) != 0) |
{ |
fp->_p = fp->_up; |
return 0; |
} |
} |
/* Otherwise we are out of character input. */ |
fp->_p = fp->_bf._base; |
fp->_r = 0; |
fp->_flags |= __SEOF; |
return EOF; |
} |
size_t |
_DEFUN(_sfread_r, (ptr, buf, size, count, fp), |
struct _reent * ptr _AND |
_PTR buf _AND |
size_t size _AND |
size_t count _AND |
FILE * fp) |
{ |
register size_t resid; |
register char *p; |
register int r; |
size_t total; |
if ((resid = count * size) == 0) |
return 0; |
total = resid; |
p = buf; |
while (resid > (r = fp->_r)) |
{ |
_CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r); |
fp->_p += r; |
fp->_r = 0; |
p += r; |
resid -= r; |
if (__ssrefill_r (ptr, fp)) |
{ |
/* no more input: return partial result */ |
return (total - resid) / size; |
} |
} |
_CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid); |
fp->_r -= resid; |
fp->_p += resid; |
return count; |
} |
#else /* !STRING_ONLY || !INTEGER_ONLY */ |
int _EXFUN (_sungetc_r, (struct _reent *, int, register FILE *)); |
int _EXFUN (__ssrefill_r, (struct _reent *, register FILE *)); |
size_t _EXFUN (_sfread_r, (struct _reent *, _PTR buf, size_t, size_t, FILE *)); |
#endif /* !STRING_ONLY || !INTEGER_ONLY */ |
int |
_DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), |
struct _reent *rptr _AND |
register FILE *fp _AND |
char _CONST *fmt0 _AND |
va_list ap) |
{ |
register u_char *fmt = (u_char *) fmt0; |
register int c; /* character from format, or conversion */ |
register size_t width; /* field width, or 0 */ |
register char *p; /* points into all kinds of strings */ |
register int n; /* handy integer */ |
register int flags; /* flags as defined above */ |
register char *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 strtol/strtoul */ |
int nbytes = 1; /* number of bytes read from fmt string */ |
wchar_t wc; /* wchar to use to read format string */ |
wchar_t *wcp; /* handy wide character pointer */ |
size_t mbslen; /* length of converted multibyte sequence */ |
#ifdef _MB_CAPABLE |
mbstate_t state; /* value to keep track of multibyte state */ |
#endif |
#define CCFN_PARAMS _PARAMS((struct _reent *, const char *, char **, int)) |
u_long (*ccfn)CCFN_PARAMS=0; /* conversion function (strtol/strtoul) */ |
char ccltab[256]; /* character class table for %[...] */ |
char buf[BUF]; /* buffer for numeric conversions */ |
unsigned char *lptr; /* literal pointer */ |
char *cp; |
short *sp; |
int *ip; |
#ifdef FLOATING_POINT |
float *flp; |
_LONG_DOUBLE *ldp; |
double *dp; |
#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 |
_flockfile (fp); |
ORIENT (fp, -1); |
nassigned = 0; |
nread = 0; |
#ifdef _MB_CAPABLE |
memset (&state, 0, sizeof (state)); |
#endif |
for (;;) |
{ |
#ifndef _MB_CAPABLE |
wc = *fmt; |
#else |
nbytes = __mbtowc (rptr, &wc, fmt, MB_CUR_MAX, __locale_charset (), |
&state); |
if (nbytes < 0) { |
wc = 0xFFFD; /* Unicode replacement character */ |
nbytes = 1; |
memset (&state, 0, sizeof (state)); |
} |
#endif |
fmt += nbytes; |
if (wc == 0) |
goto all_done; |
if (nbytes == 1 && isspace (wc)) |
{ |
for (;;) |
{ |
if (BufferEmpty || !isspace (*fp->_p)) |
break; |
nread++, fp->_r--, fp->_p++; |
} |
continue; |
} |
if (wc != '%') |
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 '%': |
literal: |
lptr = fmt - nbytes; |
for (n = 0; n < nbytes; ++n) |
{ |
if (BufferEmpty) |
goto input_failure; |
if (*fp->_p != *lptr) |
goto match_failure; |
fp->_r--, fp->_p++; |
nread++; |
++lptr; |
} |
continue; |
case '*': |
flags |= SUPPRESS; |
goto again; |
case 'l': |
#if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG |
if (*fmt == 'l') /* Check for 'll' = long long (SUSv3) */ |
{ |
++fmt; |
flags |= LONGDBL; |
} |
else |
#endif |
flags |= LONG; |
goto again; |
case 'L': |
flags |= LONGDBL; |
goto again; |
case '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 'j': /* intmax_t */ |
if (sizeof (intmax_t) == sizeof (long)) |
flags |= LONG; |
else |
flags |= LONGDBL; |
goto again; |
case '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 '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 '0': |
case '1': |
case '2': |
case '3': |
case '4': |
case '5': |
case '6': |
case '7': |
case '8': |
case '9': |
width = width * 10 + c - '0'; |
goto again; |
#ifndef _NO_POS_ARGS |
case '$': |
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 */ |
/* |
* Conversions. Those marked `compat' are for |
* 4.[123]BSD compatibility. |
* |
* (According to ANSI, E and X formats are supposed to |
* the same as e and x. Sorry about that.) |
*/ |
case 'D': /* compat */ |
flags |= LONG; |
/* FALLTHROUGH */ |
case 'd': |
c = CT_INT; |
ccfn = (u_long (*)CCFN_PARAMS)_strtol_r; |
base = 10; |
break; |
case 'i': |
c = CT_INT; |
ccfn = (u_long (*)CCFN_PARAMS)_strtol_r; |
base = 0; |
break; |
case 'O': /* compat */ |
flags |= LONG; |
/* FALLTHROUGH */ |
case 'o': |
c = CT_INT; |
ccfn = _strtoul_r; |
base = 8; |
break; |
case 'u': |
c = CT_INT; |
ccfn = _strtoul_r; |
base = 10; |
break; |
case 'X': |
case 'x': |
flags |= PFXOK; /* enable 0x prefixing */ |
c = CT_INT; |
ccfn = _strtoul_r; |
base = 16; |
break; |
#ifdef FLOATING_POINT |
# ifdef _WANT_IO_C99_FORMATS |
case 'a': |
case 'A': |
case 'F': |
# endif |
case 'E': |
case 'G': |
case 'e': |
case 'f': |
case 'g': |
c = CT_FLOAT; |
break; |
#endif |
#ifdef _WANT_IO_C99_FORMATS |
case 'S': |
flags |= LONG; |
/* FALLTHROUGH */ |
#endif |
case 's': |
c = CT_STRING; |
break; |
case '[': |
fmt = (u_char *) __sccl (ccltab, (unsigned char *) 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 = _strtoul_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 '\0': /* compat */ |
_funlockfile (fp); |
return EOF; |
default: /* compat */ |
if (isupper (c)) |
flags |= LONG; |
c = CT_INT; |
ccfn = (u_long (*)CCFN_PARAMS)_strtol_r; |
base = 10; |
break; |
} |
/* |
* We have a conversion that requires input. |
*/ |
if (BufferEmpty) |
goto input_failure; |
/* |
* Consume leading white space, except for formats that |
* suppress this. |
*/ |
if ((flags & NOSKIP) == 0) |
{ |
while (isspace (*fp->_p)) |
{ |
nread++; |
if (--fp->_r > 0) |
fp->_p++; |
else |
if (__srefill_r (rptr, fp)) |
goto input_failure; |
} |
/* |
* Note that there is at least one character in the |
* buffer, so conversions that do not set NOSKIP ca |
* no longer result in an input failure. |
*/ |
} |
/* |
* Do the conversion. |
*/ |
switch (c) |
{ |
case CT_CHAR: |
/* scan arbitrary characters (sets NOSKIP) */ |
if (width == 0) |
width = 1; |
#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2 |
if (flags & LONG) |
{ |
mbstate_t state; |
memset (&state, 0, sizeof (mbstate_t)); |
if ((flags & SUPPRESS) == 0) |
wcp = GET_ARG (N, ap, wchar_t *); |
else |
wcp = NULL; |
n = 0; |
while (width != 0) |
{ |
if (n == MB_CUR_MAX) |
goto input_failure; |
buf[n++] = *fp->_p; |
fp->_r -= 1; |
fp->_p += 1; |
if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state)) |
== (size_t)-1) |
goto input_failure; /* Invalid sequence */ |
if (mbslen == 0 && !(flags & SUPPRESS)) |
*wcp = L'\0'; |
if (mbslen != (size_t)-2) /* Incomplete sequence */ |
{ |
nread += n; |
width -= 1; |
if (!(flags & SUPPRESS)) |
wcp += 1; |
n = 0; |
} |
if (BufferEmpty) |
{ |
if (n != 0) |
goto input_failure; |
break; |
} |
} |
if (!(flags & SUPPRESS)) |
nassigned++; |
} |
else |
#endif |
if (flags & SUPPRESS) |
{ |
size_t sum = 0; |
for (;;) |
{ |
if ((n = fp->_r) < (int)width) |
{ |
sum += n; |
width -= n; |
fp->_p += n; |
if (__srefill_r (rptr, fp)) |
{ |
if (sum == 0) |
goto input_failure; |
break; |
} |
} |
else |
{ |
sum += width; |
fp->_r -= width; |
fp->_p += width; |
break; |
} |
} |
nread += sum; |
} |
else |
{ |
size_t r = _fread_r (rptr, (_PTR) GET_ARG (N, ap, char *), 1, width, fp); |
if (r == 0) |
goto input_failure; |
nread += r; |
nassigned++; |
} |
break; |
case CT_CCL: |
/* scan a (nonempty) character class (sets NOSKIP) */ |
if (width == 0) |
width = ~0; /* `infinity' */ |
/* take only those things in the class */ |
if (flags & SUPPRESS) |
{ |
n = 0; |
while (ccltab[*fp->_p]) |
{ |
n++, fp->_r--, fp->_p++; |
if (--width == 0) |
break; |
if (BufferEmpty) |
{ |
if (n == 0) |
goto input_failure; |
break; |
} |
} |
if (n == 0) |
goto match_failure; |
} |
else |
{ |
p0 = p = GET_ARG (N, ap, char *); |
while (ccltab[*fp->_p]) |
{ |
fp->_r--; |
*p++ = *fp->_p++; |
if (--width == 0) |
break; |
if (BufferEmpty) |
{ |
if (p == p0) |
goto input_failure; |
break; |
} |
} |
n = p - p0; |
if (n == 0) |
goto match_failure; |
*p = 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 !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2 |
if (flags & LONG) |
{ |
/* Process %S and %ls placeholders */ |
mbstate_t state; |
memset (&state, 0, sizeof (mbstate_t)); |
if ((flags & SUPPRESS) == 0) |
wcp = GET_ARG (N, ap, wchar_t *); |
else |
wcp = &wc; |
n = 0; |
while (!isspace (*fp->_p) && width != 0) |
{ |
if (n == MB_CUR_MAX) |
goto input_failure; |
buf[n++] = *fp->_p; |
fp->_r -= 1; |
fp->_p += 1; |
if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state)) |
== (size_t)-1) |
goto input_failure; |
if (mbslen == 0) |
*wcp = L'\0'; |
if (mbslen != (size_t)-2) /* Incomplete sequence */ |
{ |
if (iswspace(*wcp)) |
{ |
while (n != 0) |
_ungetc_r (rptr, (unsigned char) buf[--n], fp); |
break; |
} |
nread += n; |
width -= 1; |
if ((flags & SUPPRESS) == 0) |
wcp += 1; |
n = 0; |
} |
if (BufferEmpty) |
{ |
if (n != 0) |
goto input_failure; |
break; |
} |
} |
if (!(flags & SUPPRESS)) |
{ |
*wcp = L'\0'; |
nassigned++; |
} |
} |
else |
#endif |
if (flags & SUPPRESS) |
{ |
n = 0; |
while (!isspace (*fp->_p)) |
{ |
n++, fp->_r--, fp->_p++; |
if (--width == 0) |
break; |
if (BufferEmpty) |
break; |
} |
nread += n; |
} |
else |
{ |
p0 = p = GET_ARG (N, ap, char *); |
while (!isspace (*fp->_p)) |
{ |
fp->_r--; |
*p++ = *fp->_p++; |
if (--width == 0) |
break; |
if (BufferEmpty) |
break; |
} |
*p = 0; |
nread += p - p0; |
nassigned++; |
} |
continue; |
case CT_INT: |
{ |
/* scan an integer as if by strtol/strtoul */ |
unsigned width_left = 0; |
int skips = 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 | NZDIGITS | NNZDIGITS; |
for (p = buf; width; width--) |
{ |
c = *fp->_p; |
/* |
* 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 '0': |
if (! (flags & NNZDIGITS)) |
goto ok; |
if (base == 0) |
{ |
base = 8; |
flags |= PFXOK; |
} |
if (flags & NZDIGITS) |
{ |
flags &= ~(SIGNOK | NZDIGITS | NDIGITS); |
goto ok; |
} |
flags &= ~(SIGNOK | PFXOK | NDIGITS); |
if (width_left) |
{ |
width_left--; |
width++; |
} |
++skips; |
goto skip; |
/* 1 through 7 always legal */ |
case '1': |
case '2': |
case '3': |
case '4': |
case '5': |
case '6': |
case '7': |
base = basefix[base]; |
flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS); |
goto ok; |
/* digits 8 and 9 ok iff decimal or hex */ |
case '8': |
case '9': |
base = basefix[base]; |
if (base <= 8) |
break; /* not legal here */ |
flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS); |
goto ok; |
/* letters ok iff hex */ |
case 'A': |
case 'B': |
case 'C': |
case 'D': |
case 'E': |
case 'F': |
case 'a': |
case 'b': |
case 'c': |
case 'd': |
case 'e': |
case 'f': |
/* no need to fix base here */ |
if (base <= 10) |
break; /* not legal here */ |
flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS); |
goto ok; |
/* sign ok only as first character */ |
case '+': |
case '-': |
if (flags & SIGNOK) |
{ |
flags &= ~SIGNOK; |
goto ok; |
} |
break; |
/* x ok iff flag still set & single 0 seen */ |
case 'x': |
case 'X': |
if ((flags & (PFXOK | NZDIGITS)) == PFXOK) |
{ |
base = 16;/* if %i */ |
flags &= ~PFXOK; |
/* We must reset the NZDIGITS and NDIGITS |
flags that would have been unset by seeing |
the zero that preceded the X or x. */ |
flags |= NZDIGITS | NDIGITS; |
goto ok; |
} |
break; |
} |
/* |
* If we got here, c is not a legal character |
* for a number. Stop accumulating digits. |
*/ |
break; |
ok: |
/* |
* c is legal: store it and look at the next. |
*/ |
*p++ = c; |
skip: |
if (--fp->_r > 0) |
fp->_p++; |
else |
if (__srefill_r (rptr, fp)) |
break; /* EOF */ |
} |
/* |
* 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) |
_ungetc_r (rptr, *--p, fp); /* [-+xX] */ |
if (p == buf) |
goto match_failure; |
} |
if ((flags & SUPPRESS) == 0) |
{ |
u_long res; |
*p = 0; |
res = (*ccfn) (rptr, buf, (char **) NULL, base); |
if (flags & POINTER) |
{ |
void **vp = GET_ARG (N, ap, void **); |
#ifndef _NO_LONGLONG |
if (sizeof (uintptr_t) > sizeof (u_long)) |
{ |
u_long_long resll; |
resll = _strtoull_r (rptr, buf, (char **) 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) |
{ |
u_long_long resll; |
if (ccfn == _strtoul_r) |
resll = _strtoull_r (rptr, buf, (char **) NULL, base); |
else |
resll = _strtoll_r (rptr, buf, (char **) 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 + skips; |
break; |
} |
#ifdef FLOATING_POINT |
case CT_FLOAT: |
{ |
/* scan a floating point number as if by strtod */ |
/* 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; |
char *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 = *fp->_p; |
/* |
* This code mimicks the integer conversion |
* code, but is much simpler. |
*/ |
switch (c) |
{ |
case '0': |
if (flags & NDIGITS) |
{ |
flags &= ~SIGNOK; |
zeroes++; |
if (width_left) |
{ |
width_left--; |
width++; |
} |
goto fskip; |
} |
/* Fall through. */ |
case '1': |
case '2': |
case '3': |
case '4': |
case '5': |
case '6': |
case '7': |
case '8': |
case '9': |
if (nancount + infcount == 0) |
{ |
flags &= ~(SIGNOK | NDIGITS); |
goto fok; |
} |
break; |
case '+': |
case '-': |
if (flags & SIGNOK) |
{ |
flags &= ~SIGNOK; |
goto fok; |
} |
break; |
case 'n': |
case '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 'a': |
case 'A': |
if (nancount == 1) |
{ |
nancount = 2; |
goto fok; |
} |
break; |
case 'i': |
case '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 'f': |
case 'F': |
if (infcount == 2) |
{ |
infcount = 3; |
goto fok; |
} |
break; |
case 't': |
case 'T': |
if (infcount == 6) |
{ |
infcount = 7; |
goto fok; |
} |
break; |
case 'y': |
case 'Y': |
if (infcount == 7) |
{ |
infcount = 8; |
goto fok; |
} |
break; |
case '.': |
if (flags & DPTOK) |
{ |
flags &= ~(SIGNOK | DPTOK); |
leading_zeroes = zeroes; |
goto fok; |
} |
break; |
case 'e': |
case '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; |
} |
break; |
fok: |
*p++ = c; |
fskip: |
width--; |
++nread; |
if (--fp->_r > 0) |
fp->_p++; |
else |
if (__srefill_r (rptr, fp)) |
break; /* EOF */ |
} |
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) |
{ |
_ungetc_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) |
{ |
_ungetc_r (rptr, *--p, fp); /* [iInNtT] */ |
--nread; |
} |
else |
{ |
while (p > buf) |
{ |
_ungetc_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) |
{ |
_ungetc_r (rptr, *--p, fp); /* [-+.] */ |
--nread; |
} |
goto match_failure; |
} |
/* just a bad exponent (e and maybe sign) */ |
c = *--p; |
--nread; |
if (c != 'e' && c != 'E') |
{ |
_ungetc_r (rptr, c, fp); /* [-+] */ |
c = *--p; |
--nread; |
} |
_ungetc_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 = _strtol_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; |
sprintf (exp_start, "e%ld", new_exp); |
} |
/* Current _strtold routine is markedly slower than |
_strtod_r. Only use it if we have a long double |
result. */ |
#ifndef _NO_LONGDBL /* !_NO_LONGDBL */ |
if (flags & LONGDBL) |
qres = _strtold (buf, NULL); |
else |
#endif |
res = _strtod_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. */ |
_funlockfile (fp); |
return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF; |
match_failure: |
all_done: |
/* Return number of matches, which can be 0 on match failure. */ |
_funlockfile (fp); |
return nassigned; |
} |
#ifndef _NO_POS_ARGS |
/* Process all intermediate arguments. Fortunately, with scanf, 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/vscanf.c |
---|
0,0 → 1,52 |
/*- |
* 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. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include "local.h" |
#ifndef _REENT_ONLY |
int |
_DEFUN(vscanf, (fmt, ap), |
_CONST char *fmt _AND |
va_list ap) |
{ |
_REENT_SMALL_CHECK_INIT (_REENT); |
return __svfscanf_r (_REENT, _stdin_r (_REENT), fmt, ap); |
} |
#endif /* !_REENT_ONLY */ |
int |
_DEFUN(_vscanf_r, (ptr, fmt, ap), |
struct _reent *ptr _AND |
_CONST char *fmt _AND |
va_list ap) |
{ |
_REENT_SMALL_CHECK_INIT (ptr); |
return __svfscanf_r (ptr, _stdin_r (ptr), fmt, ap); |
} |
/contrib/sdk/sources/newlib/libc/stdio/vsnprintf.c |
---|
0,0 → 1,72 |
/* |
* 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 vfprintf.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 <limits.h> |
#include <stdarg.h> |
#include <errno.h> |
#include "local.h" |
#ifndef _REENT_ONLY |
int |
_DEFUN(vsnprintf, (str, size, fmt, ap), |
char *str _AND |
size_t size _AND |
const char *fmt _AND |
va_list ap) |
{ |
return _vsnprintf_r (_REENT, str, size, fmt, ap); |
} |
#endif /* !_REENT_ONLY */ |
int |
_DEFUN(_vsnprintf_r, (ptr, str, size, fmt, ap), |
struct _reent *ptr _AND |
char *str _AND |
size_t size _AND |
const char *fmt _AND |
va_list ap) |
{ |
int ret; |
FILE f; |
if (size > INT_MAX) |
{ |
ptr->_errno = EOVERFLOW; |
return EOF; |
} |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = (size > 0 ? size - 1 : 0); |
f._file = -1; /* No file. */ |
ret = _svfprintf_r (ptr, &f, fmt, ap); |
if (ret < EOF) |
ptr->_errno = EOVERFLOW; |
if (size > 0) |
*f._p = 0; |
return ret; |
} |
/contrib/sdk/sources/newlib/libc/stdio/vsprintf.c |
---|
0,0 → 1,61 |
/* |
* 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 vfprintf.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 <limits.h> |
#include <stdarg.h> |
#include "local.h" |
#ifndef _REENT_ONLY |
int |
_DEFUN(vsprintf, (str, fmt, ap), |
char *str _AND |
const char *fmt _AND |
va_list ap) |
{ |
return _vsprintf_r (_REENT, str, fmt, ap); |
} |
#endif /* !_REENT_ONLY */ |
int |
_DEFUN(_vsprintf_r, (ptr, str, fmt, ap), |
struct _reent *ptr _AND |
char *str _AND |
const char *fmt _AND |
va_list ap) |
{ |
int ret; |
FILE f; |
f._flags = __SWR | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._w = INT_MAX; |
f._file = -1; /* No file. */ |
ret = _svfprintf_r (ptr, &f, fmt, ap); |
*f._p = 0; |
return ret; |
} |
/contrib/sdk/sources/newlib/libc/stdio/vsscanf.c |
---|
0,0 → 1,65 |
/* |
* 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. |
*/ |
#include <_ansi.h> |
#include <reent.h> |
#include <stdio.h> |
#include <string.h> |
#ifdef _HAVE_STDC |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include "local.h" |
/* |
* vsscanf |
*/ |
#ifndef _REENT_ONLY |
int |
_DEFUN(vsscanf, (str, fmt, ap), |
_CONST char *str _AND |
_CONST char *fmt _AND |
va_list ap) |
{ |
return _vsscanf_r (_REENT, str, fmt, ap); |
} |
#endif /* !_REENT_ONLY */ |
int |
_DEFUN(_vsscanf_r, (ptr, str, fmt, ap), |
struct _reent *ptr _AND |
_CONST char *str _AND |
_CONST char *fmt _AND |
va_list ap) |
{ |
FILE f; |
f._flags = __SRD | __SSTR; |
f._bf._base = f._p = (unsigned char *) str; |
f._bf._size = f._r = strlen (str); |
f._read = __seofread; |
f._ub._base = NULL; |
f._lb._base = NULL; |
f._file = -1; /* No file. */ |
return __ssvfscanf_r (ptr, &f, fmt, ap); |
} |
/contrib/sdk/sources/newlib/libc/stdio/wbuf.c |
---|
0,0 → 1,96 |
/* |
* 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. |
*/ |
/* No user fns here. Pesch 15apr92. */ |
#if defined(LIBC_SCCS) && !defined(lint) |
static char sccsid[] = "%W% (Berkeley) %G%"; |
#endif /* LIBC_SCCS and not lint */ |
#include <_ansi.h> |
#include <stdio.h> |
#include <errno.h> |
#include "local.h" |
#include "fvwrite.h" |
/* |
* Write the given character into the (probably full) buffer for |
* the given file. Flush the buffer out if it is or becomes full, |
* or if c=='\n' and the file is line buffered. |
*/ |
int |
_DEFUN(__swbuf_r, (ptr, c, fp), |
struct _reent *ptr _AND |
register int c _AND |
register FILE *fp) |
{ |
register int n; |
/* Ensure stdio has been initialized. */ |
CHECK_INIT (ptr, fp); |
/* |
* In case we cannot write, or longjmp takes us out early, |
* make sure _w is 0 (if fully- or un-buffered) or -_bf._size |
* (if line buffered) so that we will get called again. |
* If we did not do this, a sufficient number of putc() |
* calls might wrap _w from negative to positive. |
*/ |
fp->_w = fp->_lbfsize; |
if (cantwrite (ptr, fp)) |
return EOF; |
c = (unsigned char) c; |
ORIENT (fp, -1); |
/* |
* If it is completely full, flush it out. Then, in any case, |
* stuff c into the buffer. If this causes the buffer to fill |
* completely, or if c is '\n' and the file is line buffered, |
* flush it (perhaps a second time). The second flush will always |
* happen on unbuffered streams, where _bf._size==1; fflush() |
* guarantees that putc() will always call wbuf() by setting _w |
* to 0, so we need not do anything else. |
*/ |
n = fp->_p - fp->_bf._base; |
if (n >= fp->_bf._size) |
{ |
if (_fflush_r (ptr, fp)) |
return EOF; |
n = 0; |
} |
fp->_w--; |
*fp->_p++ = c; |
if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n')) |
if (_fflush_r (ptr, fp)) |
return EOF; |
return c; |
} |
/* This function isn't any longer declared in stdio.h, but it's |
required for backward compatibility with applications built against |
earlier dynamically built newlib libraries. */ |
int |
_DEFUN(__swbuf, (c, fp), |
register int c _AND |
register FILE *fp) |
{ |
return __swbuf_r (_REENT, c, fp); |
} |
/contrib/sdk/sources/newlib/libc/stdio/wsetup.c |
---|
0,0 → 1,94 |
/* No user fns here. Pesch 15apr92. */ |
/* |
* 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. |
*/ |
#include <_ansi.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <errno.h> |
#include "local.h" |
/* |
* Various output routines call wsetup to be sure it is safe to write, |
* because either _flags does not include __SWR, or _buf is NULL. |
* _wsetup returns 0 if OK to write, nonzero and set errno otherwise. |
*/ |
int |
_DEFUN(__swsetup_r, (ptr, fp), |
struct _reent *ptr _AND |
register FILE * fp) |
{ |
/* Make sure stdio is set up. */ |
CHECK_INIT (_REENT, fp); |
/* |
* If we are not writing, we had better be reading and writing. |
*/ |
if ((fp->_flags & __SWR) == 0) |
{ |
if ((fp->_flags & __SRW) == 0) |
{ |
ptr->_errno = EBADF; |
fp->_flags |= __SERR; |
return EOF; |
} |
if (fp->_flags & __SRD) |
{ |
/* clobber any ungetc data */ |
if (HASUB (fp)) |
FREEUB (ptr, fp); |
fp->_flags &= ~(__SRD | __SEOF); |
fp->_r = 0; |
fp->_p = fp->_bf._base; |
} |
fp->_flags |= __SWR; |
} |
/* |
* Make a buffer if necessary, then set _w. |
* A string I/O file should not explicitly allocate a buffer |
* unless asprintf is being used. |
*/ |
if (fp->_bf._base == NULL |
&& (!(fp->_flags & __SSTR) || (fp->_flags & __SMBF))) |
__smakebuf_r (ptr, fp); |
if (fp->_flags & __SLBF) |
{ |
/* |
* It is line buffered, so make _lbfsize be -_bufsize |
* for the putc() macro. We will change _lbfsize back |
* to 0 whenever we turn off __SWR. |
*/ |
fp->_w = 0; |
fp->_lbfsize = -fp->_bf._size; |
} |
else |
fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size; |
if (!fp->_bf._base && (fp->_flags & __SMBF)) |
{ |
/* __smakebuf_r set errno, but not flag */ |
fp->_flags |= __SERR; |
return EOF; |
} |
return 0; |
} |