import from github
This commit is contained in:
63
agbcc/libc/stdio/clearerr.c
Normal file
63
agbcc/libc/stdio/clearerr.c
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#undef clearerr
|
||||
|
||||
_VOID
|
||||
_DEFUN (clearerr, (fp),
|
||||
FILE * fp)
|
||||
{
|
||||
__sclearerr (fp);
|
||||
}
|
82
agbcc/libc/stdio/fclose.c
Normal file
82
agbcc/libc/stdio/fclose.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<fclose>>---close a file
|
||||
|
||||
INDEX
|
||||
fclose
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fclose(FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fclose(<[fp]>)
|
||||
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]>)>>).
|
||||
|
||||
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>>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "local.h"
|
||||
|
||||
/*
|
||||
* Close a file.
|
||||
*/
|
||||
|
||||
int
|
||||
_DEFUN (fclose, (fp),
|
||||
register FILE * fp)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (fp == NULL)
|
||||
return (0); /* on NULL */
|
||||
|
||||
CHECK_INIT (fp);
|
||||
|
||||
if (fp->_flags == 0) /* not open! */
|
||||
return (0);
|
||||
r = fp->_flags & __SWR ? fflush (fp) : 0;
|
||||
if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0)
|
||||
r = EOF;
|
||||
if (fp->_flags & __SMBF)
|
||||
_free_r (fp->_data, (char *) fp->_bf._base);
|
||||
if (HASUB (fp))
|
||||
FREEUB (fp);
|
||||
if (HASLB (fp))
|
||||
FREELB (fp);
|
||||
fp->_flags = 0; /* release this FILE for reuse */
|
||||
return (r);
|
||||
}
|
116
agbcc/libc/stdio/fdopen.c
Normal file
116
agbcc/libc/stdio/fdopen.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
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(void *<[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]>)
|
||||
char *<[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 <sys/types.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "local.h"
|
||||
#include <_syslist.h>
|
||||
|
||||
extern int __sflags ();
|
||||
|
||||
FILE *
|
||||
_DEFUN (_fdopen_r, (ptr, fd, mode),
|
||||
struct _reent *ptr _AND
|
||||
int fd _AND
|
||||
_CONST char *mode)
|
||||
{
|
||||
register FILE *fp;
|
||||
int flags, oflags;
|
||||
#ifdef F_GETFL
|
||||
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 F_GETFL
|
||||
if ((fdflags = _fcntl (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;
|
||||
fp->_flags = flags;
|
||||
/*
|
||||
* If opened for appending, but underlying descriptor
|
||||
* does not have O_APPEND bit set, assert __SAPP so that
|
||||
* __swrite() will lseek to end before each write.
|
||||
*/
|
||||
if ((oflags & O_APPEND)
|
||||
#ifdef F_GETFL
|
||||
&& !(fdflags & O_APPEND)
|
||||
#endif
|
||||
)
|
||||
fp->_flags |= __SAPP;
|
||||
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;
|
||||
return fp;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
FILE *
|
||||
_DEFUN (fdopen, (fd, mode),
|
||||
int fd _AND
|
||||
_CONST char *mode)
|
||||
{
|
||||
return _fdopen_r (_REENT, fd, mode);
|
||||
}
|
||||
|
||||
#endif
|
40
agbcc/libc/stdio/feof.c
Normal file
40
agbcc/libc/stdio/feof.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<feof>>---test for end of file
|
||||
|
||||
INDEX
|
||||
feof
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int feof(FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int feof(<[fp]>)
|
||||
FILE *<[fp]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<feof>> tests whether or not the end of the file identified by <[fp]>
|
||||
has been reached.
|
||||
|
||||
RETURNS
|
||||
<<feof>> returns <<0>> if the end of file has not yet been reached; if
|
||||
at end of file, the result is nonzero.
|
||||
|
||||
PORTABILITY
|
||||
<<feof>> is required by ANSI C.
|
||||
|
||||
No supporting OS subroutines are required.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#undef feof
|
||||
|
||||
int
|
||||
_DEFUN (feof, (fp),
|
||||
FILE * fp)
|
||||
{
|
||||
return __sfeof (fp);
|
||||
}
|
67
agbcc/libc/stdio/ferror.c
Normal file
67
agbcc/libc/stdio/ferror.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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
|
||||
<<ferror>>---test whether read/write error has occurred
|
||||
|
||||
INDEX
|
||||
ferror
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int ferror(FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int ferror(<[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.
|
||||
Use <<ferror>> to query this indicator.
|
||||
|
||||
See <<clearerr>> to reset the error indicator.
|
||||
|
||||
RETURNS
|
||||
<<ferror>> returns <<0>> if no errors have occurred; it returns a
|
||||
nonzero value otherwise.
|
||||
|
||||
PORTABILITY
|
||||
ANSI C requires <<ferror>>.
|
||||
|
||||
No supporting OS subroutines are required.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "%W% (Berkeley) %G%";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* A subroutine version of the macro ferror. */
|
||||
|
||||
#undef ferror
|
||||
|
||||
int
|
||||
_DEFUN (ferror, (fp),
|
||||
FILE * fp)
|
||||
{
|
||||
return __sferror (fp);
|
||||
}
|
99
agbcc/libc/stdio/fflush.c
Normal file
99
agbcc/libc/stdio/fflush.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fflush(FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fflush(<[fp]>)
|
||||
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.
|
||||
|
||||
RETURNS
|
||||
<<fflush>> returns <<0>> unless it encounters a write error; in that
|
||||
situation, it returns <<EOF>>.
|
||||
|
||||
PORTABILITY
|
||||
ANSI C requires <<fflush>>.
|
||||
|
||||
No supporting OS subroutines are required.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "local.h"
|
||||
|
||||
/* Flush a single file, or (if fp is NULL) all files. */
|
||||
|
||||
int
|
||||
_DEFUN (fflush, (fp),
|
||||
register FILE * fp)
|
||||
{
|
||||
register unsigned char *p;
|
||||
register int n, t;
|
||||
|
||||
|
||||
|
||||
|
||||
if (fp == NULL)
|
||||
return _fwalk (_REENT, fflush);
|
||||
|
||||
CHECK_INIT (fp);
|
||||
|
||||
t = fp->_flags;
|
||||
if ((t & __SWR) == 0 || (p = fp->_bf._base) == NULL)
|
||||
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) (fp->_cookie, (char *) p, n);
|
||||
if (t <= 0)
|
||||
{
|
||||
fp->_flags |= __SERR;
|
||||
return EOF;
|
||||
}
|
||||
p += t;
|
||||
n -= t;
|
||||
}
|
||||
return 0;
|
||||
}
|
46
agbcc/libc/stdio/fgetc.c
Normal file
46
agbcc/libc/stdio/fgetc.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<fgetc>>---get a character from a file or stream
|
||||
|
||||
INDEX
|
||||
fgetc
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fgetc(FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fgetc(<[fp]>)
|
||||
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>>.
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
int
|
||||
_DEFUN (fgetc, (fp),
|
||||
FILE * fp)
|
||||
{
|
||||
return __sgetc (fp);
|
||||
}
|
61
agbcc/libc/stdio/fgetpos.c
Normal file
61
agbcc/libc/stdio/fgetpos.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<fgetpos>>---record position in a stream or file
|
||||
|
||||
INDEX
|
||||
fgetpos
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fgetpos(FILE *<[fp]>, fpos_t *<[pos]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fgetpos(<[fp]>, <[pos]>)
|
||||
FILE *<[fp]>;
|
||||
fpos_t *<[pos]>;
|
||||
|
||||
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 <<fgetpos>> to report on the current position for a file
|
||||
identified by <[fp]>; <<fgetpos>> will write a value
|
||||
representing that position at <<*<[pos]>>>. Later, you can
|
||||
use this value with <<fsetpos>> to return the file to this
|
||||
position.
|
||||
|
||||
In the current implementation, <<fgetpos>> simply uses a character
|
||||
count to represent the file position; this is the same number that
|
||||
would be returned by <<ftell>>.
|
||||
|
||||
RETURNS
|
||||
<<fgetpos>> returns <<0>> when successful. If <<fgetpos>> fails, the
|
||||
result is <<1>>. Failure occurs on streams that do not support
|
||||
positioning; the global <<errno>> indicates this condition with the
|
||||
value <<ESPIPE>>.
|
||||
|
||||
PORTABILITY
|
||||
<<fgetpos>> is required by the ANSI C standard, but the meaning of the
|
||||
value it records is not specified beyond requiring that it be
|
||||
acceptable as an argument to <<fsetpos>>. In particular, other
|
||||
conforming C implementations may return a different result from
|
||||
<<ftell>> than what <<fgetpos>> writes at <<*<[pos]>>>.
|
||||
|
||||
No supporting OS subroutines are required.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
_DEFUN (fgetpos, (fp, pos),
|
||||
FILE * fp _AND
|
||||
fpos_t * pos)
|
||||
{
|
||||
*pos = ftell (fp);
|
||||
|
||||
if (*pos != -1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
127
agbcc/libc/stdio/fgets.c
Normal file
127
agbcc/libc/stdio/fgets.c
Normal file
@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
FUNCTION
|
||||
<<fgets>>---get character string from a file or stream
|
||||
INDEX
|
||||
fgets
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
char *fgets(char *<[buf]>, int <[n]>, FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
char *fgets(<[buf]>,<[n]>,<[fp]>)
|
||||
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.
|
||||
|
||||
|
||||
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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern int __srefill ();
|
||||
|
||||
/*
|
||||
* 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, (buf, n, fp),
|
||||
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;
|
||||
n--; /* leave space for NUL */
|
||||
do
|
||||
{
|
||||
/*
|
||||
* If the buffer is empty, refill it.
|
||||
*/
|
||||
if ((len = fp->_r) <= 0)
|
||||
{
|
||||
if (__srefill (fp))
|
||||
{
|
||||
/* EOF: stop with partial or no line */
|
||||
if (s == buf)
|
||||
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;
|
||||
(void) memcpy ((_PTR) s, (_PTR) p, len);
|
||||
s[len] = 0;
|
||||
return (buf);
|
||||
}
|
||||
fp->_r -= len;
|
||||
fp->_p += len;
|
||||
(void) memcpy ((_PTR) s, (_PTR) p, len);
|
||||
s += len;
|
||||
}
|
||||
while ((n -= len) != 0);
|
||||
*s = 0;
|
||||
return buf;
|
||||
}
|
40
agbcc/libc/stdio/fileno.c
Normal file
40
agbcc/libc/stdio/fileno.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
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 <stdio.h>
|
||||
#include "local.h"
|
||||
|
||||
int
|
||||
_DEFUN (fileno, (f),
|
||||
FILE * f)
|
||||
{
|
||||
CHECK_INIT (f);
|
||||
return __sfileno (f);
|
||||
}
|
152
agbcc/libc/stdio/findfp.c
Normal file
152
agbcc/libc/stdio/findfp.c
Normal file
@ -0,0 +1,152 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "local.h"
|
||||
|
||||
static void
|
||||
std (ptr, flags, file, data)
|
||||
FILE *ptr;
|
||||
struct _reent *data;
|
||||
{
|
||||
ptr->_p = 0;
|
||||
ptr->_r = 0;
|
||||
ptr->_w = 0;
|
||||
ptr->_flags = flags;
|
||||
ptr->_file = file;
|
||||
ptr->_bf._base = 0;
|
||||
ptr->_lbfsize = 0;
|
||||
ptr->_cookie = ptr;
|
||||
ptr->_read = __sread;
|
||||
ptr->_write = __swrite;
|
||||
ptr->_seek = __sseek;
|
||||
ptr->_close = __sclose;
|
||||
ptr->_data = data;
|
||||
}
|
||||
|
||||
struct _glue *
|
||||
__sfmoreglue (d, n)
|
||||
struct _reent *d;
|
||||
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 *
|
||||
__sfp (d)
|
||||
struct _reent *d;
|
||||
{
|
||||
FILE *fp;
|
||||
int n;
|
||||
struct _glue *g;
|
||||
|
||||
if (!d->__sdidinit)
|
||||
__sinit (d);
|
||||
for (g = &d->__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;
|
||||
}
|
||||
d->_errno = ENOMEM;
|
||||
return NULL;
|
||||
|
||||
found:
|
||||
fp->_flags = 1; /* reserve this slot; caller sets real flags */
|
||||
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 */
|
||||
fp->_file = -1; /* no file */
|
||||
/* 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;
|
||||
fp->_data = d;
|
||||
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
|
||||
_cleanup_r (ptr)
|
||||
struct _reent *ptr;
|
||||
{
|
||||
/* (void) _fwalk(fclose); */
|
||||
(void) _fwalk (ptr, fflush); /* `cheating' */
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
void
|
||||
_cleanup ()
|
||||
{
|
||||
_cleanup_r (_REENT);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* __sinit() is called whenever stdio's internal variables must be set up.
|
||||
*/
|
||||
|
||||
void
|
||||
__sinit (s)
|
||||
struct _reent *s;
|
||||
{
|
||||
/* make sure we clean up on exit */
|
||||
s->__cleanup = _cleanup_r; /* conservative */
|
||||
s->__sdidinit = 1;
|
||||
|
||||
std (s->__sf + 0, __SRD, 0, s);
|
||||
std (s->__sf + 1, __SWR | __SLBF, 1, s);
|
||||
std (s->__sf + 2, __SWR | __SNBF, 2, s);
|
||||
|
||||
s->__sglue._next = NULL;
|
||||
s->__sglue._niobs = 3;
|
||||
s->__sglue._iobs = &s->__sf[0];
|
||||
}
|
77
agbcc/libc/stdio/fiprintf.c
Normal file
77
agbcc/libc/stdio/fiprintf.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<fiprintf>>---format output to file (integer only)
|
||||
INDEX
|
||||
fiprintf
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
int fiprintf(FILE *<[fd]>, const char *<[format]>, ...);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
int fiprintf(<[fd]>, <[format]> [, <[arg]>, ...]);
|
||||
FILE *<[fd]>;
|
||||
char *<[format]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<fiprintf>> is a restricted version of <<fprintf>>: it has the same
|
||||
arguments and behavior, save that it cannot perform any floating-point
|
||||
formatting---the <<f>>, <<g>>, <<G>>, <<e>>, and <<F>> type specifiers
|
||||
are not recognized.
|
||||
|
||||
RETURNS
|
||||
<<fiprintf>> returns the number of bytes in the output string,
|
||||
save that the concluding <<NULL>> is not counted.
|
||||
<<fiprintf>> returns when the end of the format string is
|
||||
encountered. If an error occurs, <<fiprintf>>
|
||||
returns <<EOF>>.
|
||||
|
||||
PORTABILITY
|
||||
<<fiprintf>> is not required by ANSI C.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
fiprintf (FILE * fp, const char *fmt,...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
ret = vfiprintf (fp, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <varargs.h>
|
||||
|
||||
int
|
||||
fiprintf (fp, fmt, va_alist)
|
||||
FILE *fp;
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap);
|
||||
ret = vfiprintf (fp, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
83
agbcc/libc/stdio/flags.c
Normal file
83
agbcc/libc/stdio/flags.c
Normal file
@ -0,0 +1,83 @@
|
||||
/* No user fns here. Pesch 15apr92 */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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
|
||||
__sflags (ptr, mode, optr)
|
||||
struct _reent *ptr;
|
||||
register char *mode;
|
||||
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[2] == '+')
|
||||
{
|
||||
ret = __SRW;
|
||||
m = O_RDWR;
|
||||
}
|
||||
if (mode[1] == 'b' || mode[2] == 'b')
|
||||
{
|
||||
#ifdef O_BINARY
|
||||
m |= O_BINARY;
|
||||
#endif
|
||||
}
|
||||
else if (mode[1] == 't' || mode[2] == 't')
|
||||
{
|
||||
#ifdef O_TEXT
|
||||
m |= O_TEXT;
|
||||
#endif
|
||||
}
|
||||
*optr = m | o;
|
||||
return ret;
|
||||
}
|
27
agbcc/libc/stdio/floatio.h
Normal file
27
agbcc/libc/stdio/floatio.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
|
||||
#define MAXEXP 308
|
||||
/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
|
||||
#define MAXFRACT 39
|
165
agbcc/libc/stdio/fopen.c
Normal file
165
agbcc/libc/stdio/fopen.c
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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(void *<[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]>)
|
||||
char *<[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 <stdio.h>
|
||||
#include <errno.h>
|
||||
#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 (fp->_data, file, oflags, 0666)) < 0)
|
||||
{
|
||||
fp->_flags = 0; /* release */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 (fp, 0, SEEK_END);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
FILE *
|
||||
_DEFUN (fopen, (file, mode),
|
||||
_CONST char *file _AND
|
||||
_CONST char *mode)
|
||||
{
|
||||
return _fopen_r (_REENT, file, mode);
|
||||
}
|
||||
|
||||
#endif
|
56
agbcc/libc/stdio/fprintf.c
Normal file
56
agbcc/libc/stdio/fprintf.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the University of California, Berkeley. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
fprintf (FILE * fp, const char *fmt,...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
ret = vfprintf (fp, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <varargs.h>
|
||||
|
||||
int
|
||||
fprintf (fp, fmt, va_alist)
|
||||
FILE *fp;
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap);
|
||||
ret = vfprintf (fp, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
51
agbcc/libc/stdio/fputc.c
Normal file
51
agbcc/libc/stdio/fputc.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<fputc>>---write a character on a stream or file
|
||||
|
||||
INDEX
|
||||
fputc
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fputc(int <[ch]>, FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fputc(<[ch]>, <[fp]>)
|
||||
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>>.
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
int
|
||||
_DEFUN (fputc, (ch, file),
|
||||
int ch _AND
|
||||
FILE * file)
|
||||
{
|
||||
return putc (ch, file);
|
||||
}
|
71
agbcc/libc/stdio/fputs.c
Normal file
71
agbcc/libc/stdio/fputs.c
Normal file
@ -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
|
||||
<<fputs>>---write a character string in a file or stream
|
||||
|
||||
INDEX
|
||||
fputs
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fputs(const char *<[s]>, FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fputs(<[s]>, <[fp]>)
|
||||
char *<[s]>;
|
||||
FILE *<[fp]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<fputs>> writes the string at <[s]> (but without the trailing null)
|
||||
to the file or stream identified by <[fp]>.
|
||||
|
||||
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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fvwrite.h"
|
||||
|
||||
/*
|
||||
* Write the given string to the given file.
|
||||
*/
|
||||
|
||||
int
|
||||
_DEFUN (fputs, (s, fp),
|
||||
char _CONST * s _AND
|
||||
FILE * fp)
|
||||
{
|
||||
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;
|
||||
return __sfvwrite (fp, &uio);
|
||||
}
|
97
agbcc/libc/stdio/fread.c
Normal file
97
agbcc/libc/stdio/fread.c
Normal file
@ -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
|
||||
<<fread>>---read array elements from a file
|
||||
|
||||
INDEX
|
||||
fread
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
size_t fread(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]>;
|
||||
|
||||
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.
|
||||
|
||||
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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include "local.h"
|
||||
|
||||
size_t
|
||||
_DEFUN (fread, (buf, size, count, fp),
|
||||
_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;
|
||||
if (fp->_r < 0)
|
||||
fp->_r = 0;
|
||||
total = resid;
|
||||
p = buf;
|
||||
while (resid > (r = fp->_r))
|
||||
{
|
||||
(void) memcpy ((void *) p, (void *) fp->_p, (size_t) r);
|
||||
fp->_p += r;
|
||||
/* fp->_r = 0 ... done in __srefill */
|
||||
p += r;
|
||||
resid -= r;
|
||||
if (__srefill (fp))
|
||||
{
|
||||
/* no more input: return partial result */
|
||||
return (total - resid) / size;
|
||||
}
|
||||
}
|
||||
(void) memcpy ((void *) p, (void *) fp->_p, resid);
|
||||
fp->_r -= resid;
|
||||
fp->_p += resid;
|
||||
return count;
|
||||
}
|
151
agbcc/libc/stdio/freopen.c
Normal file
151
agbcc/libc/stdio/freopen.c
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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
|
||||
<<freopen>>---open a file using an existing file descriptor
|
||||
|
||||
INDEX
|
||||
freopen
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
FILE *freopen(const char *<[file]>, const char *<[mode]>,
|
||||
FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
FILE *freopen(<[file]>, <[mode]>, <[fp]>)
|
||||
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>>.
|
||||
|
||||
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 <time.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include "local.h"
|
||||
|
||||
/*
|
||||
* Re-direct an existing, open (probably) file to some other file.
|
||||
*/
|
||||
|
||||
FILE *
|
||||
_DEFUN (freopen, (file, mode, fp),
|
||||
_CONST char *file _AND
|
||||
_CONST char *mode _AND
|
||||
register FILE *fp)
|
||||
{
|
||||
register int f;
|
||||
int flags, oflags, e;
|
||||
struct _reent *ptr;
|
||||
|
||||
CHECK_INIT (fp);
|
||||
ptr = fp->_data;
|
||||
|
||||
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
|
||||
{
|
||||
(void) fclose (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)
|
||||
(void) fflush (fp);
|
||||
/* if close is NULL, closing is a no-op, hence pointless */
|
||||
if (fp->_close != NULL)
|
||||
(void) (*fp->_close) (fp->_cookie);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now get a new descriptor to refer to the new file.
|
||||
*/
|
||||
|
||||
f = _open_r (ptr, (char *) file, oflags, 0666);
|
||||
e = ptr->_errno;
|
||||
|
||||
/*
|
||||
* 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 (fp);
|
||||
fp->_ub._size = 0;
|
||||
if (HASLB (fp))
|
||||
FREELB (fp);
|
||||
fp->_lb._size = 0;
|
||||
|
||||
if (f < 0)
|
||||
{ /* did not get it after all */
|
||||
fp->_flags = 0; /* set it free */
|
||||
ptr->_errno = e; /* restore in case _close clobbered */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fp->_flags = flags;
|
||||
fp->_file = f;
|
||||
fp->_cookie = (_PTR) fp;
|
||||
fp->_read = __sread;
|
||||
fp->_write = __swrite;
|
||||
fp->_seek = __sseek;
|
||||
fp->_close = __sclose;
|
||||
return fp;
|
||||
}
|
60
agbcc/libc/stdio/fscanf.c
Normal file
60
agbcc/libc/stdio/fscanf.c
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
extern int __svfscanf ();
|
||||
|
||||
int
|
||||
fscanf (FILE * fp, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
ret = __svfscanf (fp, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <varargs.h>
|
||||
|
||||
extern int __svfscanf ();
|
||||
|
||||
int
|
||||
fscanf (fp, fmt, va_alist)
|
||||
FILE *fp;
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap);
|
||||
ret = __svfscanf (fp, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
310
agbcc/libc/stdio/fseek.c
Normal file
310
agbcc/libc/stdio/fseek.c
Normal file
@ -0,0 +1,310 @@
|
||||
/*
|
||||
* 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>>---set file position
|
||||
|
||||
INDEX
|
||||
fseek
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fseek(FILE *<[fp]>, long <[offset]>, int <[whence]>)
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fseek(<[fp]>, <[offset]>, <[whence]>)
|
||||
FILE *<[fp]>;
|
||||
long <[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>> 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>> to determine the current file position.
|
||||
|
||||
RETURNS
|
||||
<<fseek>> returns <<0>> when successful. If <<fseek>> fails, 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>>.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <stdio.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
|
||||
fseek (fp, offset, whence)
|
||||
register FILE *fp;
|
||||
long offset;
|
||||
int whence;
|
||||
{
|
||||
struct _reent *ptr;
|
||||
fpos_t _EXFUN ((*seekfn), (void *, fpos_t, int));
|
||||
fpos_t target, curoff;
|
||||
size_t n;
|
||||
struct stat st;
|
||||
int havepos;
|
||||
|
||||
/* Make sure stdio is set up. */
|
||||
|
||||
CHECK_INIT (fp);
|
||||
ptr = fp->_data;
|
||||
|
||||
/* 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 (fp);
|
||||
}
|
||||
|
||||
/* Have to be able to seek. */
|
||||
|
||||
if ((seekfn = fp->_seek) == NULL)
|
||||
{
|
||||
ptr->_errno = ESPIPE; /* ??? */
|
||||
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(fp); /* may adjust seek offset on append stream */
|
||||
if (fp->_flags & __SOFF)
|
||||
curoff = fp->_offset;
|
||||
else
|
||||
{
|
||||
curoff = (*seekfn) (fp->_cookie, (fpos_t) 0, SEEK_CUR);
|
||||
if (curoff == -1L)
|
||||
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;
|
||||
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 (fp);
|
||||
if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
|
||||
goto dumb;
|
||||
if ((fp->_flags & __SOPT) == 0)
|
||||
{
|
||||
if (seekfn != __sseek
|
||||
|| fp->_file < 0
|
||||
|| _fstat_r (ptr, fp->_file, &st)
|
||||
|| (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
|
||||
{
|
||||
if (_fstat_r (ptr, fp->_file, &st))
|
||||
goto dumb;
|
||||
target = st.st_size + offset;
|
||||
}
|
||||
|
||||
if (!havepos)
|
||||
{
|
||||
if (fp->_flags & __SOFF)
|
||||
curoff = fp->_offset;
|
||||
else
|
||||
{
|
||||
curoff = (*seekfn) (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 the buffer was modified, we have to
|
||||
* skip this; see fgetline.c.)
|
||||
*/
|
||||
|
||||
if ((fp->_flags & __SMOD) == 0 &&
|
||||
target >= curoff && target < curoff + n)
|
||||
{
|
||||
register int o = target - curoff;
|
||||
|
||||
fp->_p = fp->_bf._base + o;
|
||||
fp->_r = n - o;
|
||||
if (HASUB (fp))
|
||||
FREEUB (fp);
|
||||
fp->_flags &= ~__SEOF;
|
||||
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) (fp->_cookie, curoff, SEEK_SET) == POS_ERR)
|
||||
goto dumb;
|
||||
fp->_r = 0;
|
||||
if (HASUB (fp))
|
||||
FREEUB (fp);
|
||||
fp->_flags &= ~__SEOF;
|
||||
n = target - curoff;
|
||||
if (n)
|
||||
{
|
||||
if (__srefill (fp) || fp->_r < n)
|
||||
goto dumb;
|
||||
fp->_p += n;
|
||||
fp->_r -= n;
|
||||
}
|
||||
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 (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR)
|
||||
return EOF;
|
||||
/* success: clear EOF indicator and discard ungetc() data */
|
||||
if (HASUB (fp))
|
||||
FREEUB (fp);
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = 0;
|
||||
/* fp->_w = 0; *//* unnecessary (I think...) */
|
||||
fp->_flags &= ~__SEOF;
|
||||
return 0;
|
||||
}
|
54
agbcc/libc/stdio/fsetpos.c
Normal file
54
agbcc/libc/stdio/fsetpos.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<fsetpos>>---restore position of a stream or file
|
||||
|
||||
INDEX
|
||||
fsetpos
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fsetpos(FILE *<[fp]>, const fpos_t *<[pos]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int fsetpos(<[fp]>, <[pos]>)
|
||||
FILE *<[fp]>;
|
||||
fpos_t *<[pos]>;
|
||||
|
||||
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 <<fsetpos>> to return the file identified by <[fp]> to a previous
|
||||
position <<*<[pos]>>> (after first recording it with <<fgetpos>>).
|
||||
|
||||
See <<fseek>> for a similar facility.
|
||||
|
||||
RETURNS
|
||||
<<fgetpos>> returns <<0>> when successful. If <<fgetpos>> fails, the
|
||||
result is <<1>>. 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 <<fsetpos>>, but does not specify the nature of
|
||||
<<*<[pos]>>> beyond identifying it as written by <<fgetpos>>.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
_DEFUN (fsetpos, (iop, pos),
|
||||
FILE * iop _AND
|
||||
_CONST fpos_t * pos)
|
||||
{
|
||||
int x = fseek (iop, *pos, SEEK_SET);
|
||||
|
||||
if (x != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
126
agbcc/libc/stdio/ftell.c
Normal file
126
agbcc/libc/stdio/ftell.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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>>---return position in a stream or file
|
||||
|
||||
INDEX
|
||||
ftell
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
long ftell(FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
long ftell(<[fp]>)
|
||||
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>> is the current position for a file
|
||||
identified by <[fp]>. If you record this result, you can later
|
||||
use it with <<fseek>> to return the file to this
|
||||
position.
|
||||
|
||||
In the current implementation, <<ftell>> simply uses a character
|
||||
count to represent the file position; this is the same number that
|
||||
would be recorded by <<fgetpos>>.
|
||||
|
||||
RETURNS
|
||||
<<ftell>> returns the file position, if possible. If it cannot do
|
||||
this, it returns <<-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.
|
||||
|
||||
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 <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "local.h"
|
||||
|
||||
long
|
||||
_DEFUN (ftell, (fp),
|
||||
register FILE * fp)
|
||||
{
|
||||
fpos_t pos;
|
||||
|
||||
/* Ensure stdio is set up. */
|
||||
|
||||
CHECK_INIT (fp);
|
||||
|
||||
if (fp->_seek == NULL)
|
||||
{
|
||||
fp->_data->_errno = ESPIPE;
|
||||
return -1L;
|
||||
}
|
||||
|
||||
/* Find offset of underlying I/O object, then
|
||||
adjust for buffered bytes. */
|
||||
fflush(fp); /* may adjust seek offset on append stream */
|
||||
if (fp->_flags & __SOFF)
|
||||
pos = fp->_offset;
|
||||
else
|
||||
{
|
||||
pos = (*fp->_seek) (fp->_cookie, (fpos_t) 0, SEEK_CUR);
|
||||
if (pos == -1L)
|
||||
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;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
195
agbcc/libc/stdio/fvwrite.c
Normal file
195
agbcc/libc/stdio/fvwrite.c
Normal file
@ -0,0 +1,195 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include "local.h"
|
||||
#include "fvwrite.h"
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define COPY(n) (void) memmove((void *) fp->_p, (void *) 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
|
||||
__sfvwrite (fp, uio)
|
||||
register FILE *fp;
|
||||
register struct __suio *uio;
|
||||
{
|
||||
register size_t len;
|
||||
register _CONST char *p;
|
||||
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 (fp))
|
||||
return EOF;
|
||||
|
||||
iov = uio->uio_iov;
|
||||
len = 0;
|
||||
if (fp->_flags & __SNBF)
|
||||
{
|
||||
/*
|
||||
* Unbuffered: write up to BUFSIZ bytes at a time.
|
||||
*/
|
||||
do
|
||||
{
|
||||
GETIOV (;);
|
||||
w = (*fp->_write) (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).
|
||||
*/
|
||||
do
|
||||
{
|
||||
GETIOV (;);
|
||||
w = fp->_w;
|
||||
if (fp->_flags & __SSTR)
|
||||
{
|
||||
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 (fp))
|
||||
goto err;
|
||||
}
|
||||
else if (len >= (w = fp->_bf._size))
|
||||
{
|
||||
/* write directly */
|
||||
w = (*fp->_write) (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;
|
||||
do
|
||||
{
|
||||
GETIOV (nlknown = 0);
|
||||
if (!nlknown)
|
||||
{
|
||||
nl = memchr ((void *) 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 (fp))
|
||||
goto err;
|
||||
}
|
||||
else if (s >= (w = fp->_bf._size))
|
||||
{
|
||||
w = (*fp->_write) (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 (fp))
|
||||
goto err;
|
||||
nlknown = 0;
|
||||
}
|
||||
p += w;
|
||||
len -= w;
|
||||
}
|
||||
while ((uio->uio_resid -= w) != 0);
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
fp->_flags |= __SERR;
|
||||
return EOF;
|
||||
}
|
38
agbcc/libc/stdio/fvwrite.h
Normal file
38
agbcc/libc/stdio/fvwrite.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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% */
|
||||
#include <_ansi.h>
|
||||
|
||||
/*
|
||||
* I/O descriptors for __sfvwrite().
|
||||
*/
|
||||
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,(FILE *, struct __suio *));
|
||||
extern int _EXFUN(__swsetup,(FILE *));
|
||||
|
||||
|
43
agbcc/libc/stdio/fwalk.c
Normal file
43
agbcc/libc/stdio/fwalk.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "%W% (Berkeley) %G%";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "local.h"
|
||||
|
||||
int
|
||||
_fwalk (ptr, function)
|
||||
struct _reent *ptr;
|
||||
register int (*function) ();
|
||||
{
|
||||
register FILE *fp;
|
||||
register int n, ret = 0;
|
||||
register struct _glue *g;
|
||||
|
||||
for (g = &ptr->__sglue; g != NULL; g = g->_next)
|
||||
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
|
||||
if (fp->_flags != 0)
|
||||
ret |= (*function) (fp);
|
||||
return ret;
|
||||
}
|
104
agbcc/libc/stdio/fwrite.c
Normal file
104
agbcc/libc/stdio/fwrite.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
size_t fwrite(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]>;
|
||||
|
||||
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.
|
||||
|
||||
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 <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, (buf, size, count, fp),
|
||||
_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 returns 0);
|
||||
* skip the divide if this happens, since divides are
|
||||
* generally slow and since this occurs whenever size==0.
|
||||
*/
|
||||
|
||||
if (__sfvwrite (fp, &uio) == 0)
|
||||
return count;
|
||||
return (n - uio.uio_resid) / size;
|
||||
}
|
80
agbcc/libc/stdio/getc.c
Normal file
80
agbcc/libc/stdio/getc.c
Normal file
@ -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
|
||||
<<getc>>---read a character (macro)
|
||||
|
||||
INDEX
|
||||
getc
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int getc(FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int getc(<[fp]>)
|
||||
FILE *<[fp]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<getc>> is a macro, defined in <<stdio.h>>. You can use <<getc>>
|
||||
to get the next single character from the file or stream
|
||||
identified by <[fp]>. As a side effect, <<getc>> advances the file's
|
||||
current position indicator.
|
||||
|
||||
For a subroutine version of this macro, see <<fgetc>>.
|
||||
|
||||
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, <<getc>> returns <<EOF>>.
|
||||
|
||||
You can distinguish the two situations that cause an <<EOF>> result by
|
||||
using the <<ferror>> and <<feof>> functions.
|
||||
|
||||
PORTABILITY
|
||||
ANSI C requires <<getc>>; it suggests, but does not require, that
|
||||
<<getc>> be implemented as a macro. The standard explicitly permits
|
||||
macro implementations of <<getc>> to use the argument more than once;
|
||||
therefore, in a portable program, you should not use an expression
|
||||
with side effects as the <<getc>> 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 <stdio.h>
|
||||
|
||||
/*
|
||||
* A subroutine version of the macro getc.
|
||||
*/
|
||||
|
||||
#undef getc
|
||||
|
||||
int
|
||||
getc (fp)
|
||||
register FILE *fp;
|
||||
{
|
||||
/* CHECK_INIT is called (eventually) by __srefill. */
|
||||
|
||||
return __sgetc (fp);
|
||||
}
|
96
agbcc/libc/stdio/getchar.c
Normal file
96
agbcc/libc/stdio/getchar.c
Normal file
@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
<<getchar>>---read a character (macro)
|
||||
|
||||
INDEX
|
||||
getchar
|
||||
INDEX
|
||||
_getchar_r
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int getchar(void);
|
||||
|
||||
int _getchar_r(void *<[reent]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int getchar();
|
||||
|
||||
int _getchar_r(<[reent]>)
|
||||
char * <[reent]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<getchar>> is a macro, defined in <<stdio.h>>. You can use <<getchar>>
|
||||
to get the next single character from the standard input stream.
|
||||
As a side effect, <<getchar>> advances the standard input's
|
||||
current position indicator.
|
||||
|
||||
The alternate function <<_getchar_r>> is a reentrant version. The
|
||||
extra argument <[reent]> is a pointer to a reentrancy structure.
|
||||
|
||||
|
||||
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, <<getchar>> returns <<EOF>>.
|
||||
|
||||
You can distinguish the two situations that cause an <<EOF>> result by
|
||||
using `<<ferror(stdin)>>' and `<<feof(stdin)>>'.
|
||||
|
||||
PORTABILITY
|
||||
ANSI C requires <<getchar>>; it suggests, but does not require, that
|
||||
<<getchar>> 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 getchar.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <reent.h>
|
||||
|
||||
#undef getchar
|
||||
|
||||
int
|
||||
_getchar_r (f)
|
||||
struct _reent *f;
|
||||
{
|
||||
return getc (_stdin_r (f));
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
int
|
||||
getchar ()
|
||||
{
|
||||
/* CHECK_INIT is called (eventually) by __srefill. */
|
||||
|
||||
return _getchar_r (_REENT);
|
||||
}
|
||||
|
||||
#endif
|
102
agbcc/libc/stdio/gets.c
Normal file
102
agbcc/libc/stdio/gets.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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
|
||||
<<gets>>---get character string (obsolete, use <<fgets>> instead)
|
||||
INDEX
|
||||
gets
|
||||
INDEX
|
||||
_gets_r
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
char *gets(char *<[buf]>);
|
||||
|
||||
char *_gets_r(void *<[reent]>, char *<[buf]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
char *gets(<[buf]>)
|
||||
char *<[buf]>;
|
||||
|
||||
char *_gets_r(<[reent]>, <[buf]>)
|
||||
char *<[reent]>;
|
||||
char *<[buf]>;
|
||||
|
||||
DESCRIPTION
|
||||
Reads characters from standard input until a newline is found.
|
||||
The characters up to the newline are stored in <[buf]>. The
|
||||
newline is discarded, and the buffer is terminated with a 0.
|
||||
|
||||
This is a @emph{dangerous} function, as it has no way of checking
|
||||
the amount of space available in <[buf]>. One of the attacks
|
||||
used by the Internet Worm of 1988 used this to overrun a
|
||||
buffer allocated on the stack of the finger daemon and
|
||||
overwrite the return address, causing the daemon to execute
|
||||
code downloaded into it over the connection.
|
||||
|
||||
The alternate function <<_gets_r>> is a reentrant version. The extra
|
||||
argument <[reent]> is a pointer to a reentrancy structure.
|
||||
|
||||
|
||||
RETURNS
|
||||
<<gets>> 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 end of file
|
||||
occurs with no data in the buffer, NULL is returned.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
char *
|
||||
_gets_r (ptr, buf)
|
||||
struct _reent *ptr;
|
||||
char *buf;
|
||||
{
|
||||
register int c;
|
||||
register char *s = buf;
|
||||
|
||||
while ((c = _getchar_r (ptr)) != '\n')
|
||||
if (c == EOF)
|
||||
if (s == buf)
|
||||
return NULL;
|
||||
else
|
||||
break;
|
||||
else
|
||||
*s++ = c;
|
||||
*s = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
char *
|
||||
gets (buf)
|
||||
char *buf;
|
||||
{
|
||||
return _gets_r (_REENT, buf);
|
||||
}
|
||||
|
||||
#endif
|
118
agbcc/libc/stdio/iprintf.c
Normal file
118
agbcc/libc/stdio/iprintf.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<iprintf>>---write formatted output (integer only)
|
||||
INDEX
|
||||
iprintf
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
int iprintf(const char *<[format]>, ...);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
int iprintf(<[format]> [, <[arg]>, ...])
|
||||
char *<[format]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<iprintf>> is a restricted version of <<printf>>: it has the same
|
||||
arguments and behavior, save that it cannot perform any floating-point
|
||||
formatting: the <<f>>, <<g>>, <<G>>, <<e>>, and <<F>> type specifiers
|
||||
are not recognized.
|
||||
|
||||
RETURNS
|
||||
<<iprintf>> returns the number of bytes in the output string,
|
||||
save that the concluding <<NULL>> is not counted.
|
||||
<<iprintf>> returns when the end of the format string is
|
||||
encountered. If an error occurs, <<iprintf>>
|
||||
returns <<EOF>>.
|
||||
|
||||
PORTABILITY
|
||||
<<iprintf>> is not required by ANSI C.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
iprintf (const char *fmt,...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
_stdout_r (_REENT)->_data = _REENT;
|
||||
ret = vfiprintf (stdout, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <varargs.h>
|
||||
|
||||
int
|
||||
iprintf (fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap);
|
||||
_stdout_r (_REENT)->_data = _REENT;
|
||||
ret = vfiprintf (stdout, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* ! _HAVE_STDC */
|
||||
#endif /* ! _REENT_ONLY */
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
_iprintf_r (struct _reent *ptr, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
ret = vfiprintf (_stdout_r (ptr), fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <varargs.h>
|
||||
|
||||
int
|
||||
_iprintf_r (data, fmt, va_alist)
|
||||
char *data;
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
int ret;
|
||||
struct _reent *ptr = data;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap);
|
||||
ret = vfiprintf (_stdout_r (ptr), fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
90
agbcc/libc/stdio/local.h
Normal file
90
agbcc/libc/stdio/local.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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% (UofMD/Berkeley) %G%
|
||||
*/
|
||||
|
||||
/*
|
||||
* Information local to this implementation of stdio,
|
||||
* in particular, macros and private variables.
|
||||
*/
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <stdarg.h>
|
||||
#include <reent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern int _EXFUN(__svfscanf,(FILE *, _CONST char *,va_list));
|
||||
extern FILE *_EXFUN(__sfp,(struct _reent *));
|
||||
extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*));
|
||||
extern int _EXFUN(__srefill,(FILE *));
|
||||
extern int _EXFUN(__sread,(void *, char *, int));
|
||||
extern int _EXFUN(__swrite,(void *, char const *, int));
|
||||
extern fpos_t _EXFUN(__sseek,(void *, fpos_t, int));
|
||||
extern int _EXFUN(__sclose,(void *));
|
||||
extern void _EXFUN(__sinit,(struct _reent *));
|
||||
extern void _EXFUN(_cleanup_r,(struct _reent *));
|
||||
extern void _EXFUN(__smakebuf,(FILE *));
|
||||
extern int _EXFUN(_fwalk,(struct _reent *, int (*)(FILE *)));
|
||||
struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n));
|
||||
extern int _EXFUN(__srefill,(FILE *fp));
|
||||
|
||||
/* Called by the main entry point fns to ensure stdio has been initialized. */
|
||||
|
||||
#define CHECK_INIT(fp) \
|
||||
do \
|
||||
{ \
|
||||
if ((fp)->_data == 0) \
|
||||
(fp)->_data = _REENT; \
|
||||
if (!(fp)->_data->__sdidinit) \
|
||||
__sinit ((fp)->_data); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Return true iff the given FILE cannot be written now. */
|
||||
|
||||
#define cantwrite(fp) \
|
||||
((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
|
||||
__swsetup(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(fp) { \
|
||||
if ((fp)->_ub._base != (fp)->_ubuf) \
|
||||
_free_r(fp->_data, (char *)(fp)->_ub._base); \
|
||||
(fp)->_ub._base = NULL; \
|
||||
}
|
||||
|
||||
/* Test for an fgetline() buffer. */
|
||||
|
||||
#define HASLB(fp) ((fp)->_lb._base != NULL)
|
||||
#define FREELB(fp) { _free_r(fp->_data,(char *)(fp)->_lb._base); (fp)->_lb._base = NULL; }
|
||||
|
||||
/* 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 */
|
96
agbcc/libc/stdio/makebuf.c
Normal file
96
agbcc/libc/stdio/makebuf.c
Normal file
@ -0,0 +1,96 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include "local.h"
|
||||
|
||||
/*
|
||||
* 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
|
||||
__smakebuf (fp)
|
||||
register FILE *fp;
|
||||
{
|
||||
register size_t size, couldbetty;
|
||||
register _PTR p;
|
||||
struct stat st;
|
||||
|
||||
if (fp->_flags & __SNBF)
|
||||
{
|
||||
fp->_bf._base = fp->_p = fp->_nbuf;
|
||||
fp->_bf._size = 1;
|
||||
return;
|
||||
}
|
||||
if (fp->_file < 0 || _fstat_r (fp->_data, fp->_file, &st) < 0)
|
||||
{
|
||||
couldbetty = 0;
|
||||
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 (fp->_data, size)) == NULL)
|
||||
{
|
||||
fp->_flags |= __SNBF;
|
||||
fp->_bf._base = fp->_p = fp->_nbuf;
|
||||
fp->_bf._size = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fp->_data->__cleanup = _cleanup_r;
|
||||
fp->_flags |= __SMBF;
|
||||
fp->_bf._base = fp->_p = (unsigned char *) p;
|
||||
fp->_bf._size = size;
|
||||
if (couldbetty && isatty (fp->_file))
|
||||
fp->_flags |= __SLBF;
|
||||
}
|
||||
}
|
215
agbcc/libc/stdio/mktemp.c
Normal file
215
agbcc/libc/stdio/mktemp.c
Normal file
@ -0,0 +1,215 @@
|
||||
/* This is file MKTEMP.C */
|
||||
/* This file may have been modified by DJ Delorie (Jan 1991). If so,
|
||||
** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
|
||||
** Rochester NH, 03867-2954, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
<<mktemp>>, <<mkstemp>>---generate unused file name
|
||||
|
||||
INDEX
|
||||
mktemp
|
||||
INDEX
|
||||
mkstemp
|
||||
INDEX
|
||||
_mktemp_r
|
||||
INDEX
|
||||
_mkstemp_r
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
char *mktemp(char *<[path]>);
|
||||
int mkstemp(char *<[path]>);
|
||||
|
||||
char *_mktemp_r(void *<[reent]>, char *<[path]>);
|
||||
int *_mkstemp_r(void *<[reent]>, char *<[path]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
char *mktemp(<[path]>)
|
||||
char *<[path]>;
|
||||
|
||||
int mkstemp(<[path]>)
|
||||
char *<[path]>;
|
||||
|
||||
char *_mktemp_r(<[reent]>, <[path]>)
|
||||
char *<[reent]>;
|
||||
char *<[path]>;
|
||||
|
||||
int _mkstemp_r(<[reent]>, <[path]>)
|
||||
char *<[reent]>;
|
||||
char *<[path]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<mktemp>> and <<mkstemp>> attempt to generate a file name that is not
|
||||
yet in use for any existing file. <<mkstemp>> creates the file and
|
||||
opens it for reading and writing; <<mktemp>> simply generates the file name.
|
||||
|
||||
You supply a simple pattern for the generated file name, as the string
|
||||
at <[path]>. The pattern should be a valid filename (including path
|
||||
information if you wish) ending with some number of `<<X>>'
|
||||
characters. The generated filename will match the leading part of the
|
||||
name you supply, with the trailing `<<X>>' characters replaced by some
|
||||
combination of digits and letters.
|
||||
|
||||
The alternate functions <<_mktemp_r>> and <<_mkstemp_r>> are reentrant
|
||||
versions. The extra argument <[reent]> is a pointer to a reentrancy
|
||||
structure.
|
||||
|
||||
RETURNS
|
||||
<<mktemp>> returns the pointer <[path]> to the modified string
|
||||
representing an unused filename, unless it could not generate one, or
|
||||
the pattern you provided is not suitable for a filename; in that case,
|
||||
it returns <<NULL>>.
|
||||
|
||||
<<mkstemp>> returns a file descriptor to the newly created file,
|
||||
unless it could not generate an unused filename, or the pattern you
|
||||
provided is not suitable for a filename; in that case, it returns
|
||||
<<-1>>.
|
||||
|
||||
PORTABILITY
|
||||
ANSI C does not require either <<mktemp>> or <<mkstemp>>; the System
|
||||
V Interface Definition requires <<mktemp>> as of Issue 2.
|
||||
|
||||
Supporting OS subroutines required: <<getpid>>, <<open>>, <<stat>>.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <reent.h>
|
||||
|
||||
static
|
||||
_DEFUN (_gettemp, (ptr, path, doopen),
|
||||
struct _reent *ptr _AND
|
||||
char *path _AND
|
||||
register int *doopen)
|
||||
{
|
||||
register char *start, *trv;
|
||||
struct stat sbuf;
|
||||
unsigned int pid;
|
||||
|
||||
pid = _getpid_r (ptr);
|
||||
for (trv = path; *trv; ++trv) /* extra X's get set to 0's */
|
||||
continue;
|
||||
while (*--trv == 'X')
|
||||
{
|
||||
*trv = (pid % 10) + '0';
|
||||
pid /= 10;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the target directory; if you have six X's and it
|
||||
* doesn't exist this runs for a *very* long time.
|
||||
*/
|
||||
|
||||
for (start = trv + 1;; --trv)
|
||||
{
|
||||
if (trv <= path)
|
||||
break;
|
||||
if (*trv == '/')
|
||||
{
|
||||
*trv = '\0';
|
||||
if (_stat_r (ptr, path, &sbuf))
|
||||
return (0);
|
||||
if (!(sbuf.st_mode & S_IFDIR))
|
||||
{
|
||||
ptr->_errno = ENOTDIR;
|
||||
return (0);
|
||||
}
|
||||
*trv = '/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (doopen)
|
||||
{
|
||||
if ((*doopen = _open_r (ptr, path, O_CREAT | O_EXCL | O_RDWR, 0600))
|
||||
>= 0)
|
||||
return 1;
|
||||
if (ptr->_errno != EEXIST)
|
||||
return 0;
|
||||
}
|
||||
else if (_stat_r (ptr, path, &sbuf))
|
||||
return (ptr->_errno == ENOENT ? 1 : 0);
|
||||
|
||||
/* tricky little algorithm for backward compatibility */
|
||||
for (trv = start;;)
|
||||
{
|
||||
if (!*trv)
|
||||
return 0;
|
||||
if (*trv == 'z')
|
||||
*trv++ = 'a';
|
||||
else
|
||||
{
|
||||
if (isdigit (*trv))
|
||||
*trv = 'a';
|
||||
else
|
||||
++ * trv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
_DEFUN (_mkstemp_r, (ptr, path),
|
||||
struct _reent *ptr _AND
|
||||
char *path)
|
||||
{
|
||||
int fd;
|
||||
|
||||
return (_gettemp (ptr, path, &fd) ? fd : -1);
|
||||
}
|
||||
|
||||
char *
|
||||
_DEFUN (_mktemp_r, (ptr, path),
|
||||
struct _reent *ptr _AND
|
||||
char *path)
|
||||
{
|
||||
return (_gettemp (ptr, path, (int *) NULL) ? path : (char *) NULL);
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
_DEFUN (mkstemp, (path),
|
||||
char *path)
|
||||
{
|
||||
int fd;
|
||||
|
||||
return (_gettemp (_REENT, path, &fd) ? fd : -1);
|
||||
}
|
||||
|
||||
char *
|
||||
_DEFUN (mktemp, (path),
|
||||
char *path)
|
||||
{
|
||||
return (_gettemp (_REENT, path, (int *) NULL) ? path : (char *) NULL);
|
||||
}
|
||||
|
||||
#endif /* ! defined (_REENT_ONLY) */
|
80
agbcc/libc/stdio/perror.c
Normal file
80
agbcc/libc/stdio/perror.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<perror>>---print an error message on standard error
|
||||
|
||||
INDEX
|
||||
perror
|
||||
INDEX
|
||||
_perror_r
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
void perror(char *<[prefix]>);
|
||||
|
||||
void _perror_r(void *<[reent]>, char *<[prefix]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
void perror(<[prefix]>)
|
||||
char *<[prefix]>;
|
||||
|
||||
void _perror_r(<[reent]>, <[prefix]>)
|
||||
char *<[reent]>;
|
||||
char *<[prefix]>;
|
||||
|
||||
DESCRIPTION
|
||||
Use <<perror>> to print (on standard error) an error message
|
||||
corresponding to the current value of the global variable <<errno>>.
|
||||
Unless you use <<NULL>> as the value of the argument <[prefix]>, the
|
||||
error message will begin with the string at <[prefix]>, followed by a
|
||||
colon and a space (<<: >>). The remainder of the error message is one
|
||||
of the strings described for <<strerror>>.
|
||||
|
||||
The alternate function <<_perror_r>> is a reentrant version. The
|
||||
extra argument <[reent]> is a pointer to a reentrancy structure.
|
||||
|
||||
|
||||
RETURNS
|
||||
<<perror>> returns no result.
|
||||
|
||||
PORTABILITY
|
||||
ANSI C requires <<perror>>, but the strings issued vary from one
|
||||
implementation to another.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
_DEFUN (_perror_r, (ptr, s),
|
||||
struct _reent *ptr _AND
|
||||
_CONST char *s)
|
||||
{
|
||||
char *error;
|
||||
|
||||
if (s != NULL && *s != '\0')
|
||||
{
|
||||
fputs (s, _stderr_r (ptr));
|
||||
fputs (": ", _stderr_r (ptr));
|
||||
}
|
||||
|
||||
if ((error = strerror (ptr->_errno)) != NULL)
|
||||
fputs (error, _stderr_r (ptr));
|
||||
|
||||
fputc ('\n', _stderr_r (ptr));
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
void
|
||||
_DEFUN (perror, (s),
|
||||
_CONST char *s)
|
||||
{
|
||||
_perror_r (_REENT, s);
|
||||
}
|
||||
|
||||
#endif
|
83
agbcc/libc/stdio/printf.c
Normal file
83
agbcc/libc/stdio/printf.c
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
_printf_r (struct _reent *ptr, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
ret = _vfprintf_r (ptr, _stdout_r (ptr), fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <varargs.h>
|
||||
|
||||
int
|
||||
_printf_r (ptr, fmt, va_alist)
|
||||
struct _reent *ptr;
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap);
|
||||
ret = _vfprintf_r (ptr, _stdout_r (ptr), fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
int
|
||||
printf (const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
_stdout_r (_REENT)->_data = _REENT;
|
||||
ret = vfprintf (_stdout_r (_REENT), fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <varargs.h>
|
||||
|
||||
int
|
||||
printf (fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap);
|
||||
_stdout_r (_REENT)->_data = _REENT;
|
||||
ret = vfprintf (_stdout_r (_REENT), fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* ! _HAVE_STDC */
|
||||
|
||||
#endif /* ! _REENT_ONLY */
|
84
agbcc/libc/stdio/putc.c
Normal file
84
agbcc/libc/stdio/putc.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int putc(int <[ch]>, FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int putc(<[ch]>, <[fp]>)
|
||||
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>>.
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
/*
|
||||
* A subroutine version of the macro putc.
|
||||
*/
|
||||
|
||||
#undef putc
|
||||
|
||||
int
|
||||
putc (c, fp)
|
||||
int c;
|
||||
register FILE *fp;
|
||||
{
|
||||
/* CHECK_INIT is (eventually) called by __swbuf. */
|
||||
|
||||
return __sputc (c, fp);
|
||||
}
|
94
agbcc/libc/stdio/putchar.c
Normal file
94
agbcc/libc/stdio/putchar.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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(void *<[reent]>, int <[ch]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int putchar(<[ch]>)
|
||||
int <[ch]>;
|
||||
|
||||
int _putchar_r(<[reent]>, <[ch]>)
|
||||
char *<[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 <stdio.h>
|
||||
|
||||
#undef putchar
|
||||
|
||||
int
|
||||
_putchar_r (ptr, c)
|
||||
struct _reent *ptr;
|
||||
int c;
|
||||
{
|
||||
return __sputc (c, _stdout_r (ptr));
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
int
|
||||
putchar (c)
|
||||
int c;
|
||||
{
|
||||
/* CHECK_INIT is (eventually) called by __swbuf. */
|
||||
|
||||
_putchar_r (_REENT, c);
|
||||
}
|
||||
|
||||
#endif
|
101
agbcc/libc/stdio/puts.c
Normal file
101
agbcc/libc/stdio/puts.c
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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(void *<[reent]>, const char *<[s]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int puts(<[s]>)
|
||||
char *<[s]>;
|
||||
|
||||
int _puts_r(<[reent]>, <[s]>)
|
||||
char *<[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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fvwrite.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;
|
||||
|
||||
return (__sfvwrite (_stdout_r (ptr), &uio) ? EOF : '\n');
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
int
|
||||
_DEFUN (puts, (s),
|
||||
char _CONST * s)
|
||||
{
|
||||
return _puts_r (_REENT, s);
|
||||
}
|
||||
|
||||
#endif
|
113
agbcc/libc/stdio/refill.c
Normal file
113
agbcc/libc/stdio/refill.c
Normal file
@ -0,0 +1,113 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include "local.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static int
|
||||
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, (fp),
|
||||
register FILE * fp)
|
||||
{
|
||||
/* make sure stdio is set up */
|
||||
|
||||
CHECK_INIT (fp);
|
||||
|
||||
fp->_r = 0; /* largely a convenience for callers */
|
||||
|
||||
/* SysV does not make this test; take it out for compatibility */
|
||||
if (fp->_flags & __SEOF)
|
||||
return EOF;
|
||||
|
||||
/* if not already reading, have to be reading and writing */
|
||||
if ((fp->_flags & __SRD) == 0)
|
||||
{
|
||||
if ((fp->_flags & __SRW) == 0)
|
||||
return EOF;
|
||||
/* switch to reading */
|
||||
if (fp->_flags & __SWR)
|
||||
{
|
||||
if (fflush (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 (fp);
|
||||
if ((fp->_r = fp->_ur) != 0)
|
||||
{
|
||||
fp->_p = fp->_up;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fp->_bf._base == NULL)
|
||||
__smakebuf (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))
|
||||
(void) _fwalk (fp->_data, lflush);
|
||||
fp->_p = fp->_bf._base;
|
||||
fp->_r = (*fp->_read) (fp->_cookie, (char *) fp->_p, fp->_bf._size);
|
||||
fp->_flags &= ~__SMOD; /* buffer contents are again pristine */
|
||||
if (fp->_r <= 0)
|
||||
{
|
||||
if (fp->_r == 0)
|
||||
fp->_flags |= __SEOF;
|
||||
else
|
||||
{
|
||||
fp->_r = 0;
|
||||
fp->_flags |= __SERR;
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
return 0;
|
||||
}
|
69
agbcc/libc/stdio/remove.c
Normal file
69
agbcc/libc/stdio/remove.c
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<remove>>---delete a file's name
|
||||
|
||||
INDEX
|
||||
remove
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int remove(char *<[filename]>);
|
||||
|
||||
int _remove_r(void *<[reent]>, char *<[filename]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int remove(<[filename]>)
|
||||
char *<[filename]>;
|
||||
|
||||
int _remove_r(<[reent]>, <[filename]>)
|
||||
char *<[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 <stdio.h>
|
||||
|
||||
int
|
||||
_remove_r (ptr, filename)
|
||||
struct _reent *ptr;
|
||||
_CONST char *filename;
|
||||
{
|
||||
if (_unlink_r (ptr, filename) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
int
|
||||
remove (filename)
|
||||
_CONST char *filename;
|
||||
{
|
||||
return _remove_r (_REENT, filename);
|
||||
}
|
||||
|
||||
#endif
|
86
agbcc/libc/stdio/rename.c
Normal file
86
agbcc/libc/stdio/rename.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<rename>>---rename a file
|
||||
|
||||
INDEX
|
||||
rename
|
||||
INDEX
|
||||
_rename_r
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int rename(const char *<[old]>, const char *<[new]>);
|
||||
|
||||
int _rename_r(void *<[reent]>,
|
||||
const char *<[old]>, const char *<[new]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
int rename(<[old]>, <[new]>)
|
||||
char *<[old]>;
|
||||
char *<[new]>;
|
||||
|
||||
int _rename_r(<[reent]>, <[old]>, <[new]>)
|
||||
char *<[reent]>;
|
||||
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.
|
||||
|
||||
The alternate function <<_rename_r>> is a reentrant version. The
|
||||
extra argument <[reent]> is a pointer to a reentrancy structure.
|
||||
|
||||
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 <stdio.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <reent.h>
|
||||
|
||||
int
|
||||
_rename_r (ptr, old, new)
|
||||
struct _reent *ptr;
|
||||
_CONST char *old;
|
||||
_CONST char *new;
|
||||
{
|
||||
#ifdef HAVE_RENAME
|
||||
return _rename (old,new);
|
||||
#else
|
||||
if (_link_r (ptr, old, new) == -1)
|
||||
return -1;
|
||||
|
||||
if (_unlink_r (ptr, old) == -1)
|
||||
{
|
||||
/* ??? Should we unlink new? (rhetorical question) */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
int
|
||||
rename (old, new)
|
||||
_CONST char *old;
|
||||
_CONST char *new;
|
||||
{
|
||||
return _rename_r (_REENT, old, new);
|
||||
}
|
||||
|
||||
#endif
|
60
agbcc/libc/stdio/rewind.c
Normal file
60
agbcc/libc/stdio/rewind.c
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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
|
||||
<<rewind>>---reinitialize a file or stream
|
||||
|
||||
INDEX
|
||||
rewind
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
void rewind(FILE *<[fp]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
void rewind(<[fp]>)
|
||||
FILE *<[fp]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<rewind>> returns the file position indicator (if any) for the file
|
||||
or stream identified by <[fp]> to the beginning of the file. It also
|
||||
clears any error indicator and flushes any pending output.
|
||||
|
||||
RETURNS
|
||||
<<rewind>> does not return a result.
|
||||
|
||||
PORTABILITY
|
||||
ANSI C requires <<rewind>>.
|
||||
|
||||
No supporting OS subroutines are required.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "%W% (Berkeley) %G%";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void
|
||||
_DEFUN (rewind, (fp),
|
||||
register FILE * fp)
|
||||
{
|
||||
(void) fseek(fp, 0L, SEEK_SET);
|
||||
clearerr(fp);
|
||||
}
|
43
agbcc/libc/stdio/rget.c
Normal file
43
agbcc/libc/stdio/rget.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "%W% (Berkeley) %G%";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "local.h"
|
||||
|
||||
/*
|
||||
* Handle getc() when the buffer ran out:
|
||||
* Refill, then return the first character
|
||||
* in the newly-filled buffer.
|
||||
*/
|
||||
|
||||
int
|
||||
__srget (fp)
|
||||
register FILE *fp;
|
||||
{
|
||||
if (__srefill (fp) == 0)
|
||||
{
|
||||
fp->_r--;
|
||||
return *fp->_p++;
|
||||
}
|
||||
return EOF;
|
||||
}
|
75
agbcc/libc/stdio/scanf.c
Normal file
75
agbcc/libc/stdio/scanf.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include "local.h"
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
int
|
||||
#ifdef _HAVE_STDC
|
||||
scanf (const char *fmt, ...)
|
||||
#else
|
||||
scanf (fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
va_start (ap, fmt);
|
||||
#else
|
||||
va_start (ap);
|
||||
#endif
|
||||
ret = __svfscanf (_stdin_r (_REENT), fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
#ifdef _HAVE_STDC
|
||||
_scanf_r (struct _reent *ptr, const char *fmt, ...)
|
||||
#else
|
||||
_scanf_r (ptr, fmt, va_alist)
|
||||
struct _reent *ptr;
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
va_start (ap, fmt);
|
||||
#else
|
||||
va_start (ap);
|
||||
#endif
|
||||
ret = __svfscanf (_stdin_r (ptr), fmt, ap);
|
||||
va_end (ap);
|
||||
return (ret);
|
||||
}
|
79
agbcc/libc/stdio/setbuf.c
Normal file
79
agbcc/libc/stdio/setbuf.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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
|
||||
<<setbuf>>---specify full buffering for a file or stream
|
||||
|
||||
INDEX
|
||||
setbuf
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
void setbuf(FILE *<[fp]>, char *<[buf]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
void setbuf(<[fp]>, <[buf]>)
|
||||
FILE *<[fp]>;
|
||||
char *<[buf]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<setbuf>> specifies that output to the file or stream identified by <[fp]>
|
||||
should be fully buffered. All output for this file will go to a
|
||||
buffer (of size <<BUFSIZ>>, specified in `<<stdio.h>>'). Output will
|
||||
be passed on to the host system only when the buffer is full, or when
|
||||
an input operation intervenes.
|
||||
|
||||
You may, if you wish, supply your own buffer by passing a pointer to
|
||||
it as the argument <[buf]>. It must have size <<BUFSIZ>>. You can
|
||||
also use <<NULL>> as the value of <[buf]>, to signal that the
|
||||
<<setbuf>> function is to allocate the buffer.
|
||||
|
||||
WARNINGS
|
||||
You may only use <<setbuf>> 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
|
||||
<<setbuf>> does not return a result.
|
||||
|
||||
PORTABILITY
|
||||
Both ANSI C and the System V Interface Definition (Issue 2) require
|
||||
<<setbuf>>. 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.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <stdio.h>
|
||||
#include "local.h"
|
||||
|
||||
void
|
||||
_DEFUN (setbuf, (fp, buf),
|
||||
FILE * fp _AND
|
||||
char *buf)
|
||||
{
|
||||
(void) setvbuf (fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
|
||||
}
|
186
agbcc/libc/stdio/setvbuf.c
Normal file
186
agbcc/libc/stdio/setvbuf.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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 (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)
|
||||
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.
|
||||
*/
|
||||
|
||||
(void) fflush (fp);
|
||||
fp->_r = 0;
|
||||
fp->_lbfsize = 0;
|
||||
if (fp->_flags & __SMBF)
|
||||
_free_r (fp->_data, (void *) fp->_bf._base);
|
||||
fp->_flags &= ~(__SLBF | __SNBF | __SMBF);
|
||||
|
||||
if (mode == _IONBF)
|
||||
goto nbf;
|
||||
|
||||
/*
|
||||
* Allocate buffer if needed. */
|
||||
if (buf == NULL)
|
||||
{
|
||||
if ((buf = malloc (size)) == NULL)
|
||||
{
|
||||
ret = EOF;
|
||||
/* Try another size... */
|
||||
buf = malloc (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;
|
||||
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 */
|
||||
fp->_data->__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;
|
||||
|
||||
return 0;
|
||||
}
|
70
agbcc/libc/stdio/siprintf.c
Normal file
70
agbcc/libc/stdio/siprintf.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<siprintf>>---write formatted output (integer only)
|
||||
INDEX
|
||||
siprintf
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
int siprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]);
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
<<siprintf>> is a restricted version of <<sprintf>>: it has the same
|
||||
arguments and behavior, save that it cannot perform any floating-point
|
||||
formatting: the <<f>>, <<g>>, <<G>>, <<e>>, and <<F>> type specifiers
|
||||
are not recognized.
|
||||
|
||||
RETURNS
|
||||
<<siprintf>> returns the number of bytes in the output string,
|
||||
save that the concluding <<NULL>> is not counted.
|
||||
<<siprintf>> returns when the end of the format string is
|
||||
encountered.
|
||||
|
||||
PORTABILITY
|
||||
<<siprintf>> is not required by ANSI C.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef _HAVE_STDC
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <_ansi.h>
|
||||
#include <reent.h>
|
||||
#include "local.h"
|
||||
|
||||
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._data = _REENT;
|
||||
#ifdef _HAVE_STDC
|
||||
va_start (ap, fmt);
|
||||
#else
|
||||
va_start (ap);
|
||||
#endif
|
||||
ret = vfiprintf (&f, fmt, ap);
|
||||
va_end (ap);
|
||||
*f._p = 0;
|
||||
return (ret);
|
||||
}
|
351
agbcc/libc/stdio/sprintf.c
Normal file
351
agbcc/libc/stdio/sprintf.c
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* 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
|
||||
<<printf>>, <<fprintf>>, <<sprintf>>---format output
|
||||
INDEX
|
||||
fprintf
|
||||
INDEX
|
||||
printf
|
||||
INDEX
|
||||
sprintf
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
int printf(const char *<[format]> [, <[arg]>, ...]);
|
||||
int fprintf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
|
||||
int sprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
int printf(<[format]> [, <[arg]>, ...])
|
||||
char *<[format]>;
|
||||
|
||||
int fprintf(<[fd]>, <[format]> [, <[arg]>, ...]);
|
||||
FILE *<[fd]>;
|
||||
char *<[format]>;
|
||||
|
||||
int sprintf(<[str]>, <[format]> [, <[arg]>, ...]);
|
||||
char *<[str]>;
|
||||
char *<[format]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<printf>> accepts a series of arguments, applies to each a
|
||||
format specifier from <<*<[format]>>>, and writes the
|
||||
formatted data to <<stdout>>, terminated with a null 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>> and <<sprintf>> are identical to <<printf>>, other than the
|
||||
destination of the formatted output: <<fprintf>> sends the
|
||||
output to a specified file <[fd]>, while <<sprintf>> stores the
|
||||
output in the specified char array <[str]>. For <<sprintf>>,
|
||||
the behavior is also undefined if the output <<*<[str]>>>
|
||||
overlaps with one of the arguments.
|
||||
<[format]> is a pointer to a charater 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:
|
||||
|
||||
. %[<[flags]>][<[width]>][.<[prec]>][<[size]>][<[type]>]
|
||||
|
||||
The fields of the conversion specification have the following meanings:
|
||||
|
||||
O+
|
||||
o <[flags]>
|
||||
|
||||
an optional sequence of characters which control
|
||||
output justification, numeric signs, decimal points,
|
||||
trailing zeroes, and octal and hex prefixes.
|
||||
The flag characters are minus (<<->>), plus (<<+>>),
|
||||
space ( ), zero (<<0>>), and sharp (<<#>>). They can
|
||||
appear in any combination.
|
||||
|
||||
o+
|
||||
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]>)
|
||||
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>>, <<e>>, <<E>>, <<f>>, <<g>>, or <<G>>: leading zeroes,
|
||||
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 next character:
|
||||
|
||||
o+
|
||||
o 0
|
||||
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 e, E 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 zeroes are removed.
|
||||
|
||||
o g or G
|
||||
same as <<e>> or <<E>>, but trailing zeroes
|
||||
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. Negative field widths
|
||||
are not supported; if you attempt to specify a negative field
|
||||
width, it is interpreted as a minus (<<->>) flag followed by a
|
||||
positive field width.
|
||||
|
||||
o <[prec]>
|
||||
|
||||
an optional field; if present, it is introduced with `<<.>>'
|
||||
(a period). This field gives the maximum number of
|
||||
characters to print in a conversion; the minimum number of
|
||||
digits of an integer to print, for conversions with <[type]>
|
||||
<<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>; the maximum number of
|
||||
significant digits, for the <<g>> and <<G>> conversions;
|
||||
or the number of digits to print after the decimal
|
||||
point, for <<e>>, <<E>>, and <<f>> conversions. 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. Supplying a negative
|
||||
precision is equivalent to omitting the precision.
|
||||
If only a period is specified the precision is zero.
|
||||
If a precision appears with any other conversion <[type]>
|
||||
than those listed here, the behavior is undefined.
|
||||
|
||||
o <[size]>
|
||||
|
||||
<<h>>, <<l>>, and <<L>> are optional size characters which
|
||||
override the default way that <<printf>> interprets the
|
||||
data type of the corresponding argument. <<h>> forces
|
||||
the following <<d>>, <<i>>, <<o>>, <<u>>, <<x>> or <<X>> conversion
|
||||
<[type]> to apply to a <<short>> or <<unsigned short>>. <<h>> also
|
||||
forces a following <<n>> <[type]> to apply to
|
||||
a pointer to a <<short>>. Similarily, an
|
||||
<<l>> forces the following <<d>>, <<i>>, <<o>>, <<u>>,
|
||||
<<x>> or <<X>> conversion <[type]> to apply to a <<long>> or
|
||||
<<unsigned long>>. <<l>> also forces a following <<n>> <[type]> to
|
||||
apply to a pointer to a <<long>>. If an <<h>>
|
||||
or an <<l>> appears with another conversion
|
||||
specifier, the behavior is undefined. <<L>> forces a
|
||||
following <<e>>, <<E>>, <<f>>, <<g>> or <<G>> conversion <[type]> to
|
||||
apply to a <<long double>> argument. If <<L>> appears with
|
||||
any other conversion <[type]>, the behavior is undefined.
|
||||
|
||||
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
|
||||
|
||||
o s
|
||||
prints characters until precision is reached or a null terminator
|
||||
is encountered; takes a string pointer
|
||||
|
||||
o d
|
||||
prints a signed decimal integer; takes an <<int>> (same as <<i>>)
|
||||
|
||||
o i
|
||||
prints a signed decimal integer; takes an <<int>> (same as <<d>>)
|
||||
|
||||
o o
|
||||
prints a signed octal integer; takes an <<int>>
|
||||
|
||||
o u
|
||||
prints an unsigned decimal integer; takes an <<int>>
|
||||
|
||||
o x
|
||||
prints an unsigned hexadecimal integer (using <<abcdef>> as
|
||||
digits beyond <<9>>); takes an <<int>>
|
||||
|
||||
o X
|
||||
prints an unsigned hexadecimal integer (using <<ABCDEF>> as
|
||||
digits beyond <<9>>); takes an <<int>>
|
||||
|
||||
o f
|
||||
prints a signed value of the form <<[-]9999.9999>>; takes
|
||||
a floating point number
|
||||
|
||||
o e
|
||||
prints a signed value of the form <<[-]9.9999e[+|-]999>>; takes a
|
||||
floating point number
|
||||
|
||||
o E
|
||||
prints the same way as <<e>>, but using <<E>> to introduce the
|
||||
exponent; takes a floating point number
|
||||
|
||||
o g
|
||||
prints a signed value in either <<f>> or <<e>> form, based on given
|
||||
value and precision---trailing zeros and the decimal point are
|
||||
printed only if necessary; takes a floating point number
|
||||
|
||||
o G
|
||||
prints the same way as <<g>>, but using <<E>> for the exponent if an
|
||||
exponent is needed; takes a floating point number
|
||||
|
||||
o n
|
||||
stores (in the same object) a count of the characters written;
|
||||
takes a pointer to <<int>>
|
||||
|
||||
o p
|
||||
prints a pointer in an implementation-defined format.
|
||||
This implementation treats the pointer as an
|
||||
<<unsigned long>> (same as <<Lu>>).
|
||||
o-
|
||||
O-
|
||||
|
||||
|
||||
RETURNS
|
||||
<<sprintf>> returns the number of bytes in the output string,
|
||||
save that the concluding <<NULL>> is not counted.
|
||||
<<printf>> and <<fprintf>> return the number of characters transmitted.
|
||||
If an error occurs, <<printf>> and <<fprintf>> return <<EOF>>. No
|
||||
error returns occur for <<sprintf>>.
|
||||
|
||||
PORTABILITY
|
||||
The ANSI C standard specifies that implementations must
|
||||
support at least formatted output of up to 509 characters.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef _HAVE_STDC
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <_ansi.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._data = ptr;
|
||||
#ifdef _HAVE_STDC
|
||||
va_start (ap, fmt);
|
||||
#else
|
||||
va_start (ap);
|
||||
#endif
|
||||
ret = vfprintf (&f, fmt, ap);
|
||||
va_end (ap);
|
||||
*f._p = 0;
|
||||
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._data = _REENT;
|
||||
#ifdef _HAVE_STDC
|
||||
va_start (ap, fmt);
|
||||
#else
|
||||
va_start (ap);
|
||||
#endif
|
||||
ret = vfprintf (&f, fmt, ap);
|
||||
va_end (ap);
|
||||
*f._p = 0;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#endif
|
386
agbcc/libc/stdio/sscanf.c
Normal file
386
agbcc/libc/stdio/sscanf.c
Normal file
@ -0,0 +1,386 @@
|
||||
/*
|
||||
* 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
|
||||
<<scanf>>, <<fscanf>>, <<sscanf>>---scan and format input
|
||||
|
||||
INDEX
|
||||
scanf
|
||||
INDEX
|
||||
fscanf
|
||||
INDEX
|
||||
sscanf
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
|
||||
int scanf(const char *<[format]> [, <[arg]>, ...]);
|
||||
int fscanf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
|
||||
int sscanf(const char *<[str]>, const char *<[format]>
|
||||
[, <[arg]>, ...]);
|
||||
|
||||
|
||||
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]>;
|
||||
|
||||
|
||||
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 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>>, <<l>>, and <<L>> are optional size characters which
|
||||
override the default way that <<scanf>> interprets the
|
||||
data type of the corresponding argument.
|
||||
|
||||
|
||||
.Modifier Type(s)
|
||||
. h d, i, o, u, x convert input to short,
|
||||
. store in short object
|
||||
.
|
||||
. h D, I, O, U, X no effect
|
||||
. e, f, c, s, n, p
|
||||
.
|
||||
. l d, i, o, u, x 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, n, p
|
||||
.
|
||||
. L d, i, o, u, x convert to long double,
|
||||
. store in long double
|
||||
.
|
||||
. L 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"
|
||||
|
||||
/* | ARGSUSED */
|
||||
/*SUPPRESS 590*/
|
||||
static
|
||||
int
|
||||
eofread (cookie, buf, len)
|
||||
_PTR cookie;
|
||||
char *buf;
|
||||
int len;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#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;
|
||||
f._bf._base = f._p = (unsigned char *) str;
|
||||
f._bf._size = f._r = strlen (str);
|
||||
f._read = eofread;
|
||||
f._ub._base = NULL;
|
||||
f._lb._base = NULL;
|
||||
f._data = _REENT;
|
||||
#ifdef _HAVE_STDC
|
||||
va_start (ap, fmt);
|
||||
#else
|
||||
va_start (ap);
|
||||
#endif
|
||||
ret = __svfscanf (&f, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
92
agbcc/libc/stdio/stdio.c
Normal file
92
agbcc/libc/stdio/stdio.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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 <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.
|
||||
*/
|
||||
|
||||
int
|
||||
__sread (cookie, buf, n)
|
||||
_PTR cookie;
|
||||
char *buf;
|
||||
int n;
|
||||
{
|
||||
register FILE *fp = (FILE *) cookie;
|
||||
register int ret;
|
||||
|
||||
ret = _read_r (fp->_data, fp->_file, buf, n);
|
||||
|
||||
/* If the read succeeded, update the current offset. */
|
||||
|
||||
if (ret >= 0)
|
||||
fp->_offset += ret;
|
||||
else
|
||||
fp->_flags &= ~__SOFF; /* paranoia */
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
__swrite (cookie, buf, n)
|
||||
_PTR cookie;
|
||||
char _CONST *buf;
|
||||
int n;
|
||||
{
|
||||
register FILE *fp = (FILE *) cookie;
|
||||
|
||||
if (fp->_flags & __SAPP)
|
||||
(void) _lseek_r (fp->_data, fp->_file, (off_t) 0, SEEK_END);
|
||||
fp->_flags &= ~__SOFF; /* in case O_APPEND mode is set */
|
||||
return _write_r (fp->_data, fp->_file, buf, n);
|
||||
}
|
||||
|
||||
fpos_t
|
||||
__sseek (cookie, offset, whence)
|
||||
_PTR cookie;
|
||||
fpos_t offset;
|
||||
int whence;
|
||||
{
|
||||
register FILE *fp = (FILE *) cookie;
|
||||
register off_t ret;
|
||||
|
||||
ret = _lseek_r (fp->_data, fp->_file, (off_t) offset, whence);
|
||||
if (ret == -1L)
|
||||
fp->_flags &= ~__SOFF;
|
||||
else
|
||||
{
|
||||
fp->_flags |= __SOFF;
|
||||
fp->_offset = ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
__sclose (cookie)
|
||||
_PTR cookie;
|
||||
{
|
||||
FILE *fp = (FILE *) cookie;
|
||||
|
||||
return _close_r (fp->_data, fp->_file);
|
||||
}
|
77
agbcc/libc/stdio/tmpfile.c
Normal file
77
agbcc/libc/stdio/tmpfile.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<tmpfile>>---create a temporary file
|
||||
|
||||
INDEX
|
||||
tmpfile
|
||||
INDEX
|
||||
_tmpfile_r
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
FILE *tmpfile(void);
|
||||
|
||||
FILE *_tmpfile_r(void *<[reent]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
FILE *tmpfile();
|
||||
|
||||
FILE *_tmpfile_r(<[reent]>)
|
||||
char *<[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 <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
FILE *
|
||||
_DEFUN (_tmpfile_r, (ptr),
|
||||
struct _reent *ptr)
|
||||
{
|
||||
FILE *fp;
|
||||
int e;
|
||||
char *f;
|
||||
char buf[L_tmpnam];
|
||||
|
||||
if ((f = _tmpnam_r (ptr, buf)) == NULL)
|
||||
return NULL;
|
||||
fp = fopen (f, "wb+");
|
||||
e = ptr->_errno;
|
||||
_CAST_VOID remove (f);
|
||||
ptr->_errno = e;
|
||||
return fp;
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
|
||||
FILE *
|
||||
_DEFUN_VOID (tmpfile)
|
||||
{
|
||||
return _tmpfile_r (_REENT);
|
||||
}
|
||||
|
||||
#endif
|
208
agbcc/libc/stdio/tmpnam.c
Normal file
208
agbcc/libc/stdio/tmpnam.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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(void *<[reent]>, char *<[s]>);
|
||||
char *_tempnam_r(void *<[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]>)
|
||||
char *<[reent]>;
|
||||
char *<[s]>;
|
||||
|
||||
char *_tempnam_r(<[reent]>, <[dir]>, <[pfx]>)
|
||||
char *<[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 <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
|
||||
worker (ptr, result, part1, part2, part3, part4)
|
||||
struct _reent *ptr;
|
||||
char *result;
|
||||
_CONST char *part1;
|
||||
_CONST char *part2;
|
||||
int part3;
|
||||
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 */
|
||||
result = p->_emergency;
|
||||
}
|
||||
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
|
145
agbcc/libc/stdio/ungetc.c
Normal file
145
agbcc/libc/stdio/ungetc.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "%W% (Berkeley) %G%";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#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
|
||||
__submore (fp)
|
||||
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 (fp->_data, (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 (fp->_data, (_PTR) (fp->_ub._base), i << 1);
|
||||
if (p == NULL)
|
||||
return EOF;
|
||||
(void) memcpy ((void *) (p + i), (void *) p, (size_t) i);
|
||||
fp->_p = p + i;
|
||||
fp->_ub._base = p;
|
||||
fp->_ub._size = i << 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ungetc (c, fp)
|
||||
int c;
|
||||
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 (fp);
|
||||
|
||||
/* 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)
|
||||
return EOF;
|
||||
if (fp->_flags & __SWR)
|
||||
{
|
||||
if (fflush (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 (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;
|
||||
}
|
921
agbcc/libc/stdio/vfprintf.c
Normal file
921
agbcc/libc/stdio/vfprintf.c
Normal file
@ -0,0 +1,921 @@
|
||||
/*
|
||||
FUNCTION
|
||||
<<vprintf>>, <<vfprintf>>, <<vsprintf>>---format argument list
|
||||
|
||||
INDEX
|
||||
vprintf
|
||||
INDEX
|
||||
vfprintf
|
||||
INDEX
|
||||
vsprintf
|
||||
|
||||
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 _vprintf_r(void *<[reent]>, const char *<[fmt]>,
|
||||
va_list <[list]>);
|
||||
int _vfprintf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
|
||||
va_list <[list]>);
|
||||
int _vsprintf_r(void *<[reent]>, char *<[str]>, const char *<[fmt]>,
|
||||
va_list <[list]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
#include <varargs.h>
|
||||
int vprintf( <[fmt]>, <[list]>)
|
||||
char *<[fmt]>;
|
||||
va_list <[list]>;
|
||||
|
||||
int vfprintf(<[fp]>, <[fmt]>, <[list]>)
|
||||
FILE *<[fp]>;
|
||||
char *<[fmt]>;
|
||||
va_list <[list]>;
|
||||
|
||||
int vsprintf(<[str]>, <[fmt]>, <[list]>)
|
||||
char *<[str]>;
|
||||
char *<[fmt]>;
|
||||
va_list <[list]>;
|
||||
|
||||
int _vprintf_r(<[reent]>, <[fmt]>, <[list]>)
|
||||
char *<[reent]>;
|
||||
char *<[fmt]>;
|
||||
va_list <[list]>;
|
||||
|
||||
int _vfprintf_r(<[reent]>, <[fp]>, <[fmt]>, <[list]>)
|
||||
char *<[reent]>;
|
||||
FILE *<[fp]>;
|
||||
char *<[fmt]>;
|
||||
va_list <[list]>;
|
||||
|
||||
int _vsprintf_r(<[reent]>, <[str]>, <[fmt]>, <[list]>)
|
||||
char *<[reent]>;
|
||||
char *<[str]>;
|
||||
char *<[fmt]>;
|
||||
va_list <[list]>;
|
||||
|
||||
DESCRIPTION
|
||||
<<vprintf>>, <<vfprintf>>, and <<vsprintf>> are (respectively)
|
||||
variants of <<printf>>, <<fprintf>>, and <<sprintf>>. 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:
|
||||
<<vsprintf>> returns the number of bytes in the output string,
|
||||
save that the concluding <<NULL>> is not counted.
|
||||
<<vprintf>> and <<vfprintf>> return the number of characters transmitted.
|
||||
If an error occurs, <<vprintf>> and <<vfprintf>> return <<EOF>>. No
|
||||
error returns occur for <<vsprintf>>.
|
||||
|
||||
PORTABILITY
|
||||
ANSI C requires all three functions.
|
||||
|
||||
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
||||
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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.26 1998/10/20 23:29:23 jjohnstn Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Actual printf innards.
|
||||
*
|
||||
* This code is large and complicated...
|
||||
*/
|
||||
|
||||
#ifdef INTEGER_ONLY
|
||||
#define VFPRINTF vfiprintf
|
||||
#define _VFPRINTF_R _vfiprintf_r
|
||||
#else
|
||||
#define VFPRINTF vfprintf
|
||||
#define _VFPRINTF_R _vfprintf_r
|
||||
#define FLOATING_POINT
|
||||
#endif
|
||||
|
||||
#define _NO_LONGLONG
|
||||
#if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
|
||||
# undef _NO_LONGLONG
|
||||
#endif
|
||||
|
||||
#include <_ansi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <reent.h>
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "local.h"
|
||||
#include "fvwrite.h"
|
||||
#include "ieeefp.h"
|
||||
|
||||
/*
|
||||
* Flush out all the vectors defined by the given uio,
|
||||
* then reset it so that it can be reused.
|
||||
*/
|
||||
static int
|
||||
__sprint(fp, uio)
|
||||
FILE *fp;
|
||||
register struct __suio *uio;
|
||||
{
|
||||
register int err;
|
||||
|
||||
if (uio->uio_resid == 0) {
|
||||
uio->uio_iovcnt = 0;
|
||||
return (0);
|
||||
}
|
||||
err = __sfvwrite(fp, uio);
|
||||
uio->uio_resid = 0;
|
||||
uio->uio_iovcnt = 0;
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
__sbprintf(fp, fmt, ap)
|
||||
register FILE *fp;
|
||||
const char *fmt;
|
||||
va_list ap;
|
||||
{
|
||||
int ret;
|
||||
FILE fake;
|
||||
unsigned char buf[BUFSIZ];
|
||||
|
||||
/* copy the important variables */
|
||||
fake._data = fp->_data;
|
||||
fake._flags = fp->_flags & ~__SNBF;
|
||||
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 */
|
||||
|
||||
/* do the work, then copy any error status */
|
||||
ret = VFPRINTF(&fake, fmt, ap);
|
||||
if (ret >= 0 && fflush(&fake))
|
||||
ret = EOF;
|
||||
if (fake._flags & __SERR)
|
||||
fp->_flags |= __SERR;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
#ifdef FLOATING_POINT
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include "floatio.h"
|
||||
|
||||
#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
|
||||
#define DEFPREC 6
|
||||
|
||||
static char *cvt _PARAMS((struct _reent *, double, int, int, char *, int *, int, int *));
|
||||
static int exponent _PARAMS((char *, int, int));
|
||||
|
||||
#else /* no FLOATING_POINT */
|
||||
|
||||
#define BUF 40
|
||||
|
||||
#endif /* FLOATING_POINT */
|
||||
|
||||
|
||||
/*
|
||||
* 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; unimplemented */
|
||||
#define LONGINT 0x010 /* long integer */
|
||||
#define QUADINT 0x020 /* quad integer */
|
||||
#define SHORTINT 0x040 /* short integer */
|
||||
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
|
||||
#define FPT 0x100 /* Floating point number */
|
||||
|
||||
int
|
||||
_DEFUN (VFPRINTF, (fp, fmt0, ap),
|
||||
FILE * fp _AND
|
||||
_CONST char *fmt0 _AND
|
||||
va_list ap)
|
||||
{
|
||||
return _VFPRINTF_R (fp->_data, fp, fmt0, ap);
|
||||
}
|
||||
|
||||
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 */
|
||||
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) */
|
||||
wchar_t wc;
|
||||
#ifdef FLOATING_POINT
|
||||
char *decimal_point = localeconv()->decimal_point;
|
||||
char softsign; /* temporary negative sign for floats */
|
||||
double _double; /* double precision arguments %[eEfgG] */
|
||||
int expt; /* integer value of exponent */
|
||||
int expsize; /* character count for expstr */
|
||||
int ndig; /* actual number of digits returned by cvt */
|
||||
char expstr[7]; /* buffer for exponent string */
|
||||
#endif
|
||||
|
||||
#ifndef _NO_LONGLONG
|
||||
#define quad_t long long
|
||||
#define u_quad_t unsigned long long
|
||||
#endif
|
||||
|
||||
#ifndef _NO_LONGLONG
|
||||
u_quad_t _uquad; /* integer arguments %[diouxX] */
|
||||
#else
|
||||
u_long _uquad;
|
||||
#endif
|
||||
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; /* 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, %[diouxX], %[eEfgG] */
|
||||
char ox[2]; /* space for 0x hex-prefix */
|
||||
int state = 0; /* mbtowc calls from library must not change state */
|
||||
|
||||
/*
|
||||
* 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'};
|
||||
|
||||
/*
|
||||
* 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(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 FLUSH() { \
|
||||
if (uio.uio_resid && __sprint(fp, &uio)) \
|
||||
goto error; \
|
||||
uio.uio_iovcnt = 0; \
|
||||
iovp = iov; \
|
||||
}
|
||||
|
||||
/*
|
||||
* To extend shorts properly, we need both signed and unsigned
|
||||
* argument extraction methods.
|
||||
*/
|
||||
#ifndef _NO_LONGLONG
|
||||
#define SARG() \
|
||||
(flags&QUADINT ? va_arg(ap, quad_t) : \
|
||||
flags&LONGINT ? va_arg(ap, long) : \
|
||||
flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
|
||||
(long)va_arg(ap, int))
|
||||
#define UARG() \
|
||||
(flags&QUADINT ? va_arg(ap, u_quad_t) : \
|
||||
flags&LONGINT ? va_arg(ap, u_long) : \
|
||||
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
|
||||
(u_long)va_arg(ap, u_int))
|
||||
#else
|
||||
#define SARG() \
|
||||
(flags&LONGINT ? va_arg(ap, long) : \
|
||||
flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
|
||||
(long)va_arg(ap, int))
|
||||
#define UARG() \
|
||||
(flags&LONGINT ? va_arg(ap, u_long) : \
|
||||
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
|
||||
(u_long)va_arg(ap, u_int))
|
||||
#endif
|
||||
|
||||
CHECK_INIT (fp);
|
||||
|
||||
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
|
||||
if (cantwrite(fp))
|
||||
return (EOF);
|
||||
|
||||
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
|
||||
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
|
||||
fp->_file >= 0)
|
||||
return (__sbprintf(fp, fmt0, ap));
|
||||
|
||||
fmt = (char *)fmt0;
|
||||
uio.uio_iov = iovp = iov;
|
||||
uio.uio_resid = 0;
|
||||
uio.uio_iovcnt = 0;
|
||||
ret = 0;
|
||||
|
||||
/*
|
||||
* Scan the format for conversions (`%' character).
|
||||
*/
|
||||
for (;;) {
|
||||
cp = fmt;
|
||||
while ((n = _mbtowc_r(_REENT, &wc, fmt, MB_CUR_MAX, &state)) > 0) {
|
||||
fmt += n;
|
||||
if (wc == '%') {
|
||||
fmt--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((m = fmt - cp) != 0) {
|
||||
PRINT(cp, m);
|
||||
ret += m;
|
||||
}
|
||||
if (n <= 0)
|
||||
goto done;
|
||||
fmt++; /* skip over '%' */
|
||||
|
||||
flags = 0;
|
||||
dprec = 0;
|
||||
width = 0;
|
||||
prec = -1;
|
||||
sign = '\0';
|
||||
|
||||
rflag: ch = *fmt++;
|
||||
reswitch: switch (ch) {
|
||||
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 '*':
|
||||
/*
|
||||
* ``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.
|
||||
*/
|
||||
if ((width = va_arg(ap, int)) >= 0)
|
||||
goto rflag;
|
||||
width = -width;
|
||||
/* FALLTHROUGH */
|
||||
case '-':
|
||||
flags |= LADJUST;
|
||||
goto rflag;
|
||||
case '+':
|
||||
sign = '+';
|
||||
goto rflag;
|
||||
case '.':
|
||||
if ((ch = *fmt++) == '*') {
|
||||
n = va_arg(ap, int);
|
||||
prec = n < 0 ? -1 : n;
|
||||
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));
|
||||
width = n;
|
||||
goto reswitch;
|
||||
#ifdef FLOATING_POINT
|
||||
case 'L':
|
||||
flags |= LONGDBL;
|
||||
goto rflag;
|
||||
#endif
|
||||
case 'h':
|
||||
flags |= SHORTINT;
|
||||
goto rflag;
|
||||
case 'l':
|
||||
if (*fmt == 'l') {
|
||||
fmt++;
|
||||
flags |= QUADINT;
|
||||
} else {
|
||||
flags |= LONGINT;
|
||||
}
|
||||
goto rflag;
|
||||
case 'q':
|
||||
flags |= QUADINT;
|
||||
goto rflag;
|
||||
case 'c':
|
||||
*(cp = buf) = va_arg(ap, int);
|
||||
size = 1;
|
||||
sign = '\0';
|
||||
break;
|
||||
case 'D':
|
||||
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
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'G':
|
||||
if (prec == -1) {
|
||||
prec = DEFPREC;
|
||||
} else if ((ch == 'g' || ch == 'G') && prec == 0) {
|
||||
prec = 1;
|
||||
}
|
||||
|
||||
if (flags & LONGDBL) {
|
||||
_double = (double) va_arg(ap, long double);
|
||||
} else {
|
||||
_double = va_arg(ap, double);
|
||||
}
|
||||
|
||||
/* do this before tricky precision changes */
|
||||
if (isinf(_double)) {
|
||||
if (_double < 0)
|
||||
sign = '-';
|
||||
cp = "Inf";
|
||||
size = 3;
|
||||
break;
|
||||
}
|
||||
if (isnan(_double)) {
|
||||
cp = "NaN";
|
||||
size = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
flags |= FPT;
|
||||
cp = cvt(data, _double, prec, flags, &softsign,
|
||||
&expt, ch, &ndig);
|
||||
if (ch == 'g' || ch == 'G') {
|
||||
if (expt <= -4 || expt > prec)
|
||||
ch = (ch == 'g') ? 'e' : 'E';
|
||||
else
|
||||
ch = 'g';
|
||||
}
|
||||
if (ch <= 'e') { /* 'e' or 'E' fmt */
|
||||
--expt;
|
||||
expsize = exponent(expstr, expt, ch);
|
||||
size = expsize + ndig;
|
||||
if (ndig > 1 || flags & ALT)
|
||||
++size;
|
||||
} else if (ch == 'f') { /* f fmt */
|
||||
if (expt > 0) {
|
||||
size = expt;
|
||||
if (prec || flags & ALT)
|
||||
size += prec + 1;
|
||||
} else /* "0.X" */
|
||||
size = prec + 2;
|
||||
} else if (expt >= ndig) { /* fixed g fmt */
|
||||
size = expt;
|
||||
if (flags & ALT)
|
||||
++size;
|
||||
} else
|
||||
size = ndig + (expt > 0 ?
|
||||
1 : 2 - expt);
|
||||
|
||||
if (softsign)
|
||||
sign = '-';
|
||||
break;
|
||||
#endif /* FLOATING_POINT */
|
||||
case 'n':
|
||||
#ifndef _NO_LONGLONG
|
||||
if (flags & QUADINT)
|
||||
*va_arg(ap, quad_t *) = ret;
|
||||
else
|
||||
#endif
|
||||
if (flags & LONGINT)
|
||||
*va_arg(ap, long *) = ret;
|
||||
else if (flags & SHORTINT)
|
||||
*va_arg(ap, short *) = ret;
|
||||
else
|
||||
*va_arg(ap, int *) = ret;
|
||||
continue; /* no output */
|
||||
case 'O':
|
||||
flags |= LONGINT;
|
||||
/*FALLTHROUGH*/
|
||||
case 'o':
|
||||
_uquad = UARG();
|
||||
base = OCT;
|
||||
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 = (u_long)(unsigned _POINTER_INT)va_arg(ap, void *);
|
||||
base = HEX;
|
||||
xdigs = "0123456789abcdef";
|
||||
flags |= HEXPREFIX;
|
||||
ch = 'x';
|
||||
goto nosign;
|
||||
case 's':
|
||||
if ((cp = va_arg(ap, char *)) == NULL)
|
||||
cp = "(null)";
|
||||
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);
|
||||
sign = '\0';
|
||||
break;
|
||||
case 'U':
|
||||
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)
|
||||
flags |= HEXPREFIX;
|
||||
|
||||
/* 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 */
|
||||
while (_uquad >= 10) {
|
||||
*--cp = to_char(_uquad % 10);
|
||||
_uquad /= 10;
|
||||
}
|
||||
*--cp = to_char(_uquad);
|
||||
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;
|
||||
}
|
||||
}
|
||||
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.
|
||||
*
|
||||
* 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++;
|
||||
else if (flags & HEXPREFIX)
|
||||
realsz+= 2;
|
||||
|
||||
/* right-adjusting blank padding */
|
||||
if ((flags & (LADJUST|ZEROPAD)) == 0)
|
||||
PAD(width - realsz, blanks);
|
||||
|
||||
/* prefix */
|
||||
if (sign) {
|
||||
PRINT(&sign, 1);
|
||||
} else if (flags & HEXPREFIX) {
|
||||
ox[0] = '0';
|
||||
ox[1] = ch;
|
||||
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 (_double == 0) {
|
||||
/* kludge for __dtoa irregularity */
|
||||
PRINT("0", 1);
|
||||
if (expt < ndig || (flags & ALT) != 0) {
|
||||
PRINT(decimal_point, 1);
|
||||
PAD(ndig - 1, zeroes);
|
||||
}
|
||||
} else if (expt <= 0) {
|
||||
PRINT("0", 1);
|
||||
PRINT(decimal_point, 1);
|
||||
PAD(-expt, zeroes);
|
||||
PRINT(cp, ndig);
|
||||
} else if (expt >= ndig) {
|
||||
PRINT(cp, ndig);
|
||||
PAD(expt - ndig, zeroes);
|
||||
if (flags & ALT)
|
||||
PRINT(".", 1);
|
||||
} else {
|
||||
PRINT(cp, expt);
|
||||
cp += expt;
|
||||
PRINT(".", 1);
|
||||
PRINT(cp, ndig-expt);
|
||||
}
|
||||
} else { /* 'e' or 'E' */
|
||||
if (ndig > 1 || flags & ALT) {
|
||||
ox[0] = *cp++;
|
||||
ox[1] = '.';
|
||||
PRINT(ox, 2);
|
||||
if (_double || flags & ALT == 0) {
|
||||
PRINT(cp, ndig-1);
|
||||
} else /* 0.[0..] */
|
||||
/* __dtoa irregularity */
|
||||
PAD(ndig - 1, zeroes);
|
||||
} else /* XeYYY */
|
||||
PRINT(cp, 1);
|
||||
PRINT(expstr, expsize);
|
||||
}
|
||||
}
|
||||
#else
|
||||
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 */
|
||||
}
|
||||
done:
|
||||
FLUSH();
|
||||
error:
|
||||
return (__sferror(fp) ? EOF : ret);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#ifdef FLOATING_POINT
|
||||
|
||||
extern char *_dtoa_r _PARAMS((struct _reent *, double, int,
|
||||
int, int *, int *, char **));
|
||||
|
||||
static char *
|
||||
cvt(data, value, ndigits, flags, sign, decpt, ch, length)
|
||||
struct _reent *data;
|
||||
double value;
|
||||
int ndigits, flags, *decpt, ch, *length;
|
||||
char *sign;
|
||||
{
|
||||
int mode, dsgn;
|
||||
char *digits, *bp, *rve;
|
||||
__ieee_double_shape_type tmp;
|
||||
|
||||
if (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 */
|
||||
}
|
||||
|
||||
tmp.value = value;
|
||||
if (tmp.number.sign) { /* this will check for < 0 and -0.0 */
|
||||
value = -value;
|
||||
*sign = '-';
|
||||
} else
|
||||
*sign = '\000';
|
||||
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') {
|
||||
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(p0, exp, fmtch)
|
||||
char *p0;
|
||||
int exp, fmtch;
|
||||
{
|
||||
register char *p, *t;
|
||||
char expbuf[MAXEXP];
|
||||
|
||||
p = p0;
|
||||
*p++ = fmtch;
|
||||
if (exp < 0) {
|
||||
exp = -exp;
|
||||
*p++ = '-';
|
||||
}
|
||||
else
|
||||
*p++ = '+';
|
||||
t = expbuf + MAXEXP;
|
||||
if (exp > 9) {
|
||||
do {
|
||||
*--t = to_char(exp % 10);
|
||||
} while ((exp /= 10) > 9);
|
||||
*--t = to_char(exp);
|
||||
for (; t < expbuf + MAXEXP; *p++ = *t++);
|
||||
}
|
||||
else {
|
||||
*p++ = '0';
|
||||
*p++ = to_char(exp);
|
||||
}
|
||||
return (p - p0);
|
||||
}
|
||||
#endif /* FLOATING_POINT */
|
905
agbcc/libc/stdio/vfscanf.c
Normal file
905
agbcc/libc/stdio/vfscanf.c
Normal file
@ -0,0 +1,905 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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 <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef _HAVE_STDC
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include "local.h"
|
||||
|
||||
#ifndef NO_FLOATING_POINT
|
||||
#define FLOATING_POINT
|
||||
#endif
|
||||
|
||||
#ifdef FLOATING_POINT
|
||||
#include "floatio.h"
|
||||
#define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
|
||||
#else
|
||||
#define BUF 40
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flags used during conversion.
|
||||
*/
|
||||
|
||||
#define LONG 0x01 /* l: long or double */
|
||||
#define LONGDBL 0x02 /* L: long double; unimplemented */
|
||||
#define SHORT 0x04 /* h: short */
|
||||
#define SUPPRESS 0x08 /* suppress assignment */
|
||||
#define POINTER 0x10 /* weird %p pointer (`fake hex') */
|
||||
#define NOSKIP 0x20 /* 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 0x40 /* +/- is (still) legal */
|
||||
#define NDIGITS 0x80 /* no digits detected */
|
||||
|
||||
#define DPTOK 0x100 /* (float) decimal point is still legal */
|
||||
#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
|
||||
|
||||
#define PFXOK 0x100 /* 0x prefix is (still) legal */
|
||||
#define NZDIGITS 0x200 /* no 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
|
||||
|
||||
/*static*/ u_char *__sccl ();
|
||||
|
||||
/*
|
||||
* vfscanf
|
||||
*/
|
||||
|
||||
#define BufferEmpty (fp->_r <= 0 && __srefill(fp))
|
||||
|
||||
int
|
||||
__svfscanf (fp, fmt0, ap)
|
||||
register FILE *fp;
|
||||
char _CONST *fmt0;
|
||||
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 */
|
||||
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 */
|
||||
|
||||
u_long (*ccfn) () = 0; /* conversion function (strtol/strtoul) */
|
||||
char ccltab[256]; /* character class table for %[...] */
|
||||
char buf[BUF]; /* buffer for numeric conversions */
|
||||
char *lptr; /* literal pointer */
|
||||
int state = 0; /* value to keep track of multibyte state */
|
||||
|
||||
short *sp;
|
||||
int *ip;
|
||||
float *flp;
|
||||
_LONG_DOUBLE *ldp;
|
||||
double *dp;
|
||||
long *lp;
|
||||
|
||||
/* `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};
|
||||
|
||||
nassigned = 0;
|
||||
nread = 0;
|
||||
for (;;)
|
||||
{
|
||||
#ifndef MB_CAPABLE
|
||||
wc = *fmt;
|
||||
#else
|
||||
nbytes = _mbtowc_r (_REENT, &wc, fmt, MB_CUR_MAX, &state);
|
||||
#endif
|
||||
fmt += nbytes;
|
||||
if (wc == 0)
|
||||
return nassigned;
|
||||
if (nbytes == 1 && isspace (wc))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (BufferEmpty)
|
||||
return nassigned;
|
||||
if (!isspace (*fp->_p))
|
||||
break;
|
||||
nread++, fp->_r--, fp->_p++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (wc != '%')
|
||||
goto literal;
|
||||
width = 0;
|
||||
flags = 0;
|
||||
|
||||
/*
|
||||
* 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':
|
||||
flags |= LONG;
|
||||
goto again;
|
||||
case 'L':
|
||||
flags |= LONGDBL;
|
||||
goto again;
|
||||
case 'h':
|
||||
flags |= SHORT;
|
||||
goto again;
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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 (*)())strtol;
|
||||
base = 10;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
c = CT_INT;
|
||||
ccfn = (u_long (*)())strtol;
|
||||
base = 0;
|
||||
break;
|
||||
|
||||
case 'O': /* compat */
|
||||
flags |= LONG;
|
||||
/* FALLTHROUGH */
|
||||
case 'o':
|
||||
c = CT_INT;
|
||||
ccfn = strtoul;
|
||||
base = 8;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
c = CT_INT;
|
||||
ccfn = strtoul;
|
||||
base = 10;
|
||||
break;
|
||||
|
||||
case 'X': /* compat XXX */
|
||||
case 'x':
|
||||
flags |= PFXOK; /* enable 0x prefixing */
|
||||
c = CT_INT;
|
||||
ccfn = strtoul;
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
#ifdef FLOATING_POINT
|
||||
case 'E': /* compat XXX */
|
||||
case 'G': /* compat XXX */
|
||||
/* ANSI says that E,G and X behave the same way as e,g,x */
|
||||
/* FALLTHROUGH */
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
c = CT_FLOAT;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 's':
|
||||
c = CT_STRING;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
fmt = __sccl (ccltab, fmt);
|
||||
flags |= NOSKIP;
|
||||
c = CT_CCL;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
flags |= NOSKIP;
|
||||
c = CT_CHAR;
|
||||
break;
|
||||
|
||||
case 'p': /* pointer format is like hex */
|
||||
flags |= POINTER | PFXOK;
|
||||
c = CT_INT;
|
||||
ccfn = strtoul;
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (flags & SUPPRESS) /* ??? */
|
||||
continue;
|
||||
if (flags & SHORT)
|
||||
{
|
||||
sp = va_arg (ap, short *);
|
||||
*sp = nread;
|
||||
}
|
||||
else if (flags & LONG)
|
||||
{
|
||||
lp = va_arg (ap, long *);
|
||||
*lp = nread;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip = va_arg (ap, int *);
|
||||
*ip = nread;
|
||||
}
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Disgusting backwards compatibility hacks. XXX
|
||||
*/
|
||||
case '\0': /* compat */
|
||||
return EOF;
|
||||
|
||||
default: /* compat */
|
||||
if (isupper (c))
|
||||
flags |= LONG;
|
||||
c = CT_INT;
|
||||
ccfn = (u_long (*)())strtol;
|
||||
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
|
||||
#ifndef CYGNUS_NEC
|
||||
if (__srefill (fp))
|
||||
#endif
|
||||
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 (flags & SUPPRESS)
|
||||
{
|
||||
size_t sum = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((n = fp->_r) < width)
|
||||
{
|
||||
sum += n;
|
||||
width -= n;
|
||||
fp->_p += n;
|
||||
#ifndef CYGNUS_NEC
|
||||
if (__srefill (fp))
|
||||
{
|
||||
#endif
|
||||
if (sum == 0)
|
||||
goto input_failure;
|
||||
break;
|
||||
#ifndef CYGNUS_NEC
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += width;
|
||||
fp->_r -= width;
|
||||
fp->_p += width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nread += sum;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CYGNUS_NEC
|
||||
/* Kludge city for the moment */
|
||||
char *dest = va_arg (ap, char *);
|
||||
int n = width;
|
||||
if (fp->_r == 0)
|
||||
goto input_failure;
|
||||
|
||||
while (n && fp->_r)
|
||||
{
|
||||
*dest++ = *(fp->_p++);
|
||||
n--;
|
||||
fp->_r--;
|
||||
nread++;
|
||||
}
|
||||
#else
|
||||
size_t r = fread ((_PTR) va_arg (ap, char *), 1, width, fp);
|
||||
|
||||
if (r == 0)
|
||||
goto input_failure;
|
||||
nread += r;
|
||||
#endif
|
||||
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 = va_arg (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 = ~0;
|
||||
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 = va_arg (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 */
|
||||
#ifdef hardway
|
||||
if (width == 0 || width > sizeof (buf) - 1)
|
||||
width = sizeof (buf) - 1;
|
||||
#else
|
||||
/* size_t is unsigned, hence this optimisation */
|
||||
if (--width > sizeof (buf) - 2)
|
||||
width = sizeof (buf) - 2;
|
||||
width++;
|
||||
#endif
|
||||
flags |= SIGNOK | NDIGITS | NZDIGITS;
|
||||
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 (base == 0)
|
||||
{
|
||||
base = 8;
|
||||
flags |= PFXOK;
|
||||
}
|
||||
if (flags & NZDIGITS)
|
||||
flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
|
||||
else
|
||||
flags &= ~(SIGNOK | PFXOK | NDIGITS);
|
||||
goto ok;
|
||||
|
||||
/* 1 through 7 always legal */
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
base = basefix[base];
|
||||
flags &= ~(SIGNOK | PFXOK | NDIGITS);
|
||||
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);
|
||||
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);
|
||||
goto ok;
|
||||
|
||||
/* sign ok only as first character */
|
||||
case '+':
|
||||
case '-':
|
||||
if (flags & SIGNOK)
|
||||
{
|
||||
flags &= ~SIGNOK;
|
||||
goto ok;
|
||||
}
|
||||
break;
|
||||
|
||||
/* x ok iff flag still set & 2nd char */
|
||||
case 'x':
|
||||
case 'X':
|
||||
if (flags & PFXOK && p == buf + 1)
|
||||
{
|
||||
base = 16;/* if %i */
|
||||
flags &= ~PFXOK;
|
||||
goto ok;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we got here, c is not a legal character
|
||||
* for a number. Stop accumulating digits.
|
||||
*/
|
||||
break;
|
||||
ok:
|
||||
/*
|
||||
* c is legal: store it and look at the next.
|
||||
*/
|
||||
*p++ = c;
|
||||
if (--fp->_r > 0)
|
||||
fp->_p++;
|
||||
else
|
||||
#ifndef CYGNUS_NEC
|
||||
if (__srefill (fp))
|
||||
#endif
|
||||
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'.
|
||||
*/
|
||||
if (flags & NDIGITS)
|
||||
{
|
||||
if (p > buf)
|
||||
_CAST_VOID ungetc (*(u_char *)-- p, fp);
|
||||
goto match_failure;
|
||||
}
|
||||
c = ((u_char *) p)[-1];
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
--p;
|
||||
/*(void)*/ ungetc (c, fp);
|
||||
}
|
||||
if ((flags & SUPPRESS) == 0)
|
||||
{
|
||||
u_long res;
|
||||
|
||||
*p = 0;
|
||||
res = (*ccfn) (buf, (char **) NULL, base);
|
||||
if (flags & POINTER)
|
||||
*(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
|
||||
else if (flags & SHORT)
|
||||
{
|
||||
sp = va_arg (ap, short *);
|
||||
*sp = res;
|
||||
}
|
||||
else if (flags & LONG)
|
||||
{
|
||||
lp = va_arg (ap, long *);
|
||||
*lp = res;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip = va_arg (ap, int *);
|
||||
*ip = res;
|
||||
}
|
||||
nassigned++;
|
||||
}
|
||||
nread += p - buf;
|
||||
break;
|
||||
|
||||
#ifdef FLOATING_POINT
|
||||
case CT_FLOAT:
|
||||
/* scan a floating point number as if by strtod */
|
||||
#ifdef hardway
|
||||
if (width == 0 || width > sizeof (buf) - 1)
|
||||
width = sizeof (buf) - 1;
|
||||
#else
|
||||
/* size_t is unsigned, hence this optimisation */
|
||||
if (--width > sizeof (buf) - 2)
|
||||
width = sizeof (buf) - 2;
|
||||
width++;
|
||||
#endif
|
||||
flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
|
||||
for (p = buf; width; width--)
|
||||
{
|
||||
c = *fp->_p;
|
||||
/*
|
||||
* This code mimicks the integer conversion
|
||||
* code, but is much simpler.
|
||||
*/
|
||||
switch (c)
|
||||
{
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
flags &= ~(SIGNOK | NDIGITS);
|
||||
goto fok;
|
||||
|
||||
case '+':
|
||||
case '-':
|
||||
if (flags & SIGNOK)
|
||||
{
|
||||
flags &= ~SIGNOK;
|
||||
goto fok;
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
if (flags & DPTOK)
|
||||
{
|
||||
flags &= ~(SIGNOK | DPTOK);
|
||||
goto fok;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
/* no exponent without some digits */
|
||||
if ((flags & (NDIGITS | EXPOK)) == EXPOK)
|
||||
{
|
||||
flags =
|
||||
(flags & ~(EXPOK | DPTOK)) |
|
||||
SIGNOK | NDIGITS;
|
||||
goto fok;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
fok:
|
||||
*p++ = c;
|
||||
if (--fp->_r > 0)
|
||||
fp->_p++;
|
||||
else
|
||||
#ifndef CYGNUS_NEC
|
||||
if (__srefill (fp))
|
||||
#endif
|
||||
break; /* EOF */
|
||||
}
|
||||
/*
|
||||
* 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 (*(u_char *)-- p, fp);
|
||||
goto match_failure;
|
||||
}
|
||||
/* just a bad exponent (e and maybe sign) */
|
||||
c = *(u_char *)-- p;
|
||||
if (c != 'e' && c != 'E')
|
||||
{
|
||||
_CAST_VOID ungetc (c, fp); /* sign */
|
||||
c = *(u_char *)-- p;
|
||||
}
|
||||
_CAST_VOID ungetc (c, fp);
|
||||
}
|
||||
if ((flags & SUPPRESS) == 0)
|
||||
{
|
||||
double res;
|
||||
|
||||
*p = 0;
|
||||
res = atof (buf);
|
||||
if (flags & LONG)
|
||||
{
|
||||
dp = va_arg (ap, double *);
|
||||
*dp = res;
|
||||
}
|
||||
else if (flags & LONGDBL)
|
||||
{
|
||||
ldp = va_arg (ap, _LONG_DOUBLE *);
|
||||
*ldp = res;
|
||||
}
|
||||
else
|
||||
{
|
||||
flp = va_arg (ap, float *);
|
||||
*flp = res;
|
||||
}
|
||||
nassigned++;
|
||||
}
|
||||
nread += p - buf;
|
||||
break;
|
||||
#endif /* FLOATING_POINT */
|
||||
}
|
||||
}
|
||||
input_failure:
|
||||
return nassigned ? nassigned : -1;
|
||||
match_failure:
|
||||
return nassigned;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*static*/
|
||||
u_char *
|
||||
__sccl (tab, fmt)
|
||||
register char *tab;
|
||||
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 */
|
||||
}
|
35
agbcc/libc/stdio/vprintf.c
Normal file
35
agbcc/libc/stdio/vprintf.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* doc in vfprintf.c */
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#ifdef _HAVE_STDC
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
vprintf (fmt, ap)
|
||||
char _CONST *fmt;
|
||||
va_list ap;
|
||||
{
|
||||
return vfprintf (stdout, fmt, ap);
|
||||
}
|
50
agbcc/libc/stdio/vsprintf.c
Normal file
50
agbcc/libc/stdio/vsprintf.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* doc in vfprintf.c */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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>
|
||||
#ifdef _HAVE_STDC
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
vsprintf (str, fmt, ap)
|
||||
char *str;
|
||||
char _CONST *fmt;
|
||||
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._data = _REENT;
|
||||
ret = vfprintf (&f, fmt, ap);
|
||||
*f._p = 0;
|
||||
return ret;
|
||||
}
|
81
agbcc/libc/stdio/wbuf.c
Normal file
81
agbcc/libc/stdio/wbuf.c
Normal file
@ -0,0 +1,81 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "%W% (Berkeley) %G%";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdio.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
|
||||
__swbuf (c, fp)
|
||||
register int c;
|
||||
register FILE *fp;
|
||||
{
|
||||
register int n;
|
||||
|
||||
/* Ensure stdio has been initialized. */
|
||||
|
||||
CHECK_INIT (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 (fp))
|
||||
return EOF;
|
||||
c = (unsigned char) c;
|
||||
|
||||
/*
|
||||
* 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 (fp))
|
||||
return EOF;
|
||||
n = 0;
|
||||
}
|
||||
fp->_w--;
|
||||
*fp->_p++ = c;
|
||||
if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
|
||||
if (fflush (fp))
|
||||
return EOF;
|
||||
return c;
|
||||
}
|
79
agbcc/libc/stdio/wsetup.c
Normal file
79
agbcc/libc/stdio/wsetup.c
Normal file
@ -0,0 +1,79 @@
|
||||
/* No user fns here. Pesch 15apr92. */
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.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 otherwise.
|
||||
*/
|
||||
|
||||
int
|
||||
_DEFUN (__swsetup, (fp),
|
||||
register FILE * fp)
|
||||
{
|
||||
/* Make sure stdio is set up. */
|
||||
|
||||
CHECK_INIT (fp);
|
||||
|
||||
/*
|
||||
* If we are not writing, we had better be reading and writing.
|
||||
*/
|
||||
|
||||
if ((fp->_flags & __SWR) == 0)
|
||||
{
|
||||
if ((fp->_flags & __SRW) == 0)
|
||||
return EOF;
|
||||
if (fp->_flags & __SRD)
|
||||
{
|
||||
/* clobber any ungetc data */
|
||||
if (HASUB (fp))
|
||||
FREEUB (fp);
|
||||
fp->_flags &= ~(__SRD | __SEOF);
|
||||
fp->_r = 0;
|
||||
fp->_p = fp->_bf._base;
|
||||
}
|
||||
fp->_flags |= __SWR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a buffer if necessary, then set _w.
|
||||
*/
|
||||
/* NOT NEEDED FOR CYGNUS SPRINTF ONLY jpg */
|
||||
if (fp->_bf._base == NULL)
|
||||
__smakebuf (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;
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user