cechew@bruce.OZ (Earl Chew) (09/29/89)
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 3 (of 6)."
# Contents: _file.c _fopen.c _open3.c _update.c bitset.h fgets.c
# fread.c fwrite.c gets.c makefile.dos makefile.unx setvbuf.c
# tmpnam.c
# Wrapped by cechew@bruce on Fri Sep 29 16:23:38 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f '_file.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'_file.c'\"
else
echo shar: Extracting \"'_file.c'\" \(1834 characters\)
sed "s/^X//" >'_file.c' <<'END_OF_FILE'
X/* _ f i l e
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * Allocate and initialise a FILE structure. If the pointer passed
X * to the function is NULL, a FILE will be allocated, otherwise
X * the one specified will be used. The function will return
X * a pointer to the FILE structure, or NULL if it fails.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
X#if _IOREAD != 1 || _IOWRITE != 2
X _IOREAD == 1 and _IOWRITE == 2 assumed
X#endif
X
Xstatic int (*filtable[]) P((FILE *)) =
X {_brdupdate, _brdonly, (int (*) P((FILE *))) _bfail};
X
Xstatic int (*flstable[]) P((int, FILE *)) =
X {_bwrupdate, (int (*) P((int, FILE *))) _bfail, _bwronly};
X
XFILE *_file(T(FILE *fp, fp), T(int fd, fd), T(short flags, flags))
X
XD(FILE *fp) /* stream */
XD(int fd) /* channel */
XD(short flags) /* flags */
X
X{
X/* Allocate or find a file structure */
X if (fp == NULL) {
X for (fp = _iop; fp != NULL && TESTFLAG(fp, ~_IOSTATIC); fp = fp->_next)
X if (fileno(fp) == fd)
X return NULL;
X
X/* Existing descriptor hopefully is _IOSTATIC */
X if (fp != NULL)
X flags |= _IOSTATIC;
X
X/* No existing descriptor */
X else {
X if ((fp = (FILE *) malloc(sizeof(*fp))) == NULL)
X return NULL;
X
X fp->_next = _iop;
X _iop = fp;
X }
X }
X
X/* Stream descriptor needs to be initialised */
X fp->_rend = NULL;
X fp->_rptr = NULL;
X fp->_wend = NULL;
X fp->_wptr = NULL;
X fp->_base = NULL;
X fp->_scan = NULL;
X fp->_bufsiz = 0;
X fp->_flag = flags;
X fp->_file = fd;
X
X flags &= _IOREAD | _IOWRITE;
X fp->_filbuf = filtable[flags];
X fp->_flsbuf = flstable[flags];
X fp->_flush = (int (*) P((FILE *))) _bsucceed;
X
X return fp;
X}
END_OF_FILE
if test 1834 -ne `wc -c <'_file.c'`; then
echo shar: \"'_file.c'\" unpacked with wrong size!
fi
# end of '_file.c'
fi
if test -f '_fopen.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'_fopen.c'\"
else
echo shar: Extracting \"'_fopen.c'\" \(1817 characters\)
sed "s/^X//" >'_fopen.c' <<'END_OF_FILE'
X/* _ f o p e n
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * This function scans the mode with which a channel should be
X * opened. It then opens the channel using that mode and returns
X * the channel number to the caller. On error, the value -1 will
X * be returned.
X *
X * If the function succeeds, the flags argument will be set to the
X * mode with which the channel was opened. If the fd argument is
X * -1, the channel will be allocated, otherwise the specified channel
X * will be used.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
X#define CREATMODE 0666 /* mode to creat file */
X
Xint _fopen(T(const char *name, name), T(const char *mode, mode),
X T(int fd, fd), T(short *flags, flags))
X
XD(char *name) /* name of file */
XD(char *mode) /* mode to open */
XD(int fd) /* allocated channel */
XD(short *flags) /* stdio flags */
X
X{
X int openmode; /* mode for open */
X int readwrite; /* basic mode */
X int update; /* read and write required */
X
X readwrite = *mode++;
X if (*mode == 'b')
X mode++;
X if ((update = *mode == '+') != 0) {
X *flags = _IORW;
X openmode = O_RDWR;
X }
X
X if (readwrite == 'r') {
X
X if (! update) {
X *flags = _IOREAD;
X openmode = O_RDONLY;
X }
X
X if (fd < 0)
X fd = open(name, openmode, CREATMODE);
X }
X
X else {
X if (! update) {
X *flags = _IOWRITE;
X openmode = O_WRONLY;
X }
X
X openmode |= O_CREAT;
X if (readwrite != 'a')
X openmode |= O_TRUNC;
X else {
X openmode |= O_APPEND;
X#ifndef OPEN3
X *flags |= _IOAPPEND;
X#endif
X }
X
X if (fd < 0)
X fd = open(name, openmode, CREATMODE);
X }
X
X return fd;
X}
END_OF_FILE
if test 1817 -ne `wc -c <'_fopen.c'`; then
echo shar: \"'_fopen.c'\" unpacked with wrong size!
fi
# end of '_fopen.c'
fi
if test -f '_open3.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'_open3.c'\"
else
echo shar: Extracting \"'_open3.c'\" \(1934 characters\)
sed "s/^X//" >'_open3.c' <<'END_OF_FILE'
X/* _ o p e n 3
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * For those ancient systems without three argument opens, we fake it.
X * The following code works for:
X *
X * r O_RDONLY
X * w O_WRONLY | O_CREAT | O_TRUNC
X * a O_WRONLY | O_CREAT | O_APPEND
X * r+ O_RDWR
X * w+ O_RDWR | O_CREAT | O_TRUNC
X * a+ O_RDWR | O_CREAT | O_APPEND
X * other modes may not work
X *
X * Code based on open3.c from Bruce Evan's stdio. It is necessary to
X * set the umask to zero so that creat works implies that open works.
X * The O_APPEND mode is ignored since two argument opens don't support
X * it at all.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X/*VARARGS2*/
X/*ARGSUSED*/
X
X#ifndef OPEN3
X
X#undef open
X
Xint _open3(T(const char *path, path), T(int mode, mode), VA_ALIST)
X
XD(char *path) /* path to open */
XD(int mode) /* mode to open with */
XVA_DCL
X
X{
X int fd; /* file descriptor */
X int mask; /* saved umask */
X int perms; /* permissions */
X VA_LIST arg; /* argument vector */
X
X/* r, a, r+ and a+ modes */
X if ((mode & O_TRUNC) == 0) {
X if ((fd = open(path, mode & (O_WRONLY|O_RDONLY|O_RDWR))) >= 0 ||
X (mode & O_CREAT) == 0 ||
X errno != ENOENT)
X return fd;
X
X/* Fall through on a and a+ modes => couldn't open because ENOENT */
X }
X
X/* Extract file permissions */
X VA_START(arg, mode);
X perms = VA_ARG(arg, int);
X VA_END(arg);
X
X/* w and a modes */
X if ((mode & (O_WRONLY|O_RDONLY|O_RDWR)) != O_RDWR)
X fd = creat(path, perms);
X
X/* w+ and a+ modes */
X else {
X mask = umask(0);
X if ((fd = creat(path, perms)) >= 0) {
X (void) close(fd);
X fd = open(path, O_RDWR);
X (void) chmod(path, ~mask & perms);
X }
X (void) umask(mask);
X }
X
X return fd;
X}
X#endif
END_OF_FILE
if test 1934 -ne `wc -c <'_open3.c'`; then
echo shar: \"'_open3.c'\" unpacked with wrong size!
fi
# end of '_open3.c'
fi
if test -f '_update.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'_update.c'\"
else
echo shar: Extracting \"'_update.c'\" \(1695 characters\)
sed "s/^X//" >'_update.c' <<'END_OF_FILE'
X/* _ u p d a t e
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * This file contains the additional buffering functions required
X * to implement the update modes of access (r+, w+ and a+).
X *
X * The functions perform adjustments to the FILE descriptor before
X * passing control to the appropriate rdonly or wronly function.
X *
X * The functions are placed here so that they will not be linked
X * in to a basic stdio application unless they are absolutely
X * necessary (specifically if _fopen() or fseek() are used).
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
X/* Check and initialise a read update stream
X *
X * _brdupdate is intended for read/write streams. It will check
X * that the stream has a buffer and will cope with direction
X * changes. The fill function will then be directed to _brd.
X */
Xint _brdupdate(T(FILE *fp, fp))
X
XD(FILE *fp) /* stream */
X
X{
X if (TESTFLAG(fp, (_IOWRITE | _IOEOF | _IOERR)))
X return EOF;
X
X SETFLAG(fp, _IOREAD);
X
X return _brdonly(fp);
X}
X
X/* Check and initialise a write update stream.
X *
X * _bwrupdate is intended for read/write streams. It will check
X * that the stream has a buffer and will cope with direction
X * changes. The flush function will then be directed to _bwr.
X */
Xint _bwrupdate(T(int c, c), T(FILE *fp, fp))
X
XD(int c) /* character to write */
XD(FILE *fp) /* stream */
X
X{
X if (GETFLAG(fp, (_IOREAD | _IOEOF)) == _IOREAD || TESTFLAG(fp, _IOERR))
X return EOF;
X
X SETFLAG(fp, _IOWRITE);
X CLEARFLAG(fp, _IOREAD);
X
X return _bwronly(c, fp);
X}
END_OF_FILE
if test 1695 -ne `wc -c <'_update.c'`; then
echo shar: \"'_update.c'\" unpacked with wrong size!
fi
# end of '_update.c'
fi
if test -f 'bitset.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'bitset.h'\"
else
echo shar: Extracting \"'bitset.h'\" \(2335 characters\)
sed "s/^X//" >'bitset.h' <<'END_OF_FILE'
X/* b i t s e t
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * This implements a set of operators to manipulate bitsets
X * is a machine independent way. It may be necessary for other
X * machines to set up the constants at the front (such as the
X * width of int, etc).
X *
X * To avoid double evaluation of the argument in some of the
X * macros, define the data structure as follows:
X *
X * 1. the bitset is int []
X * 2. the first int will be used as scratch int [0]
X * 3. all the following elements will be used for the bitset proper
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X/* Declare the relative sizing of the components */
X
X#define _BITELEMENT unsigned int
X#define _BITSINCHAR CHAR_BIT
X
X/* Determine how many bits there are in an elemental bitset */
X
X#define _BITS (sizeof(_BITELEMENT)*_BITSINCHAR)
X
X/* Declare the relative offsets of the pieces in the structure */
X
X#define _BIT_SCRATCH_ 0
X#define _BIT_SET_ 1
X
X/* Define how to find a bit within a bitset */
X
X#define _BITSIZE_(n) (((n)+_BITS-1)/_BITS)
X#define _BITGROUP_(n) ((n)/_BITS)
X#define _BITMASK_(n) (1<<((n)%_BITS))
X
X/* Define how to find a bit within the data structure */
X
X#define _BITSIZE(n) (_BITSIZE_(n)+_BIT_SET_)
X#define _BITGROUP(n) (_BITGROUP_(n)+_BIT_SET_)
X#define _BITMASK(n) (_BITMASK_(n))
X
X/*
X * Declare a bitset of length n bits
X */
X
X#define bitstring(name, n) _BITELEMENT name[_BITSIZE(n)]
X
X/*
X * Clear all elements of the bitset
X */
X
X#define bitempty(name, n) MEMSET(&name[_BIT_SET_], 0, \
X _BITSIZE_(n)*sizeof(_BITELEMENT))
X
X/*
X * Set all elements of the bitset
X */
X
X#define bitfill(name, n) (_BITFILL(&name[_BIT_SET_], ~0, \
X _BITSIZE_(n)*sizeof(_BITELEMENT)))
X
X/*
X * Set one bit in the bitset
X */
X
X#define bitset(name, n) (name[_BIT_SCRATCH_]=(n), \
X name[_BITGROUP(name[_BIT_SCRATCH_])] |= \
X _BITMASK(name[_BIT_SCRATCH_]))
X
X/*
X * Clear one bit in the bitset
X */
X
X#define bitclear(name, n) (name[_BIT_SCRATCH_]=(n), \
X name[_BITGROUP(name[_BIT_SCRATCH_])] &= \
X ~_BITMASK(name[_BIT_SCRATCH_]))
X
X/*
X * Test one bit in the bitset
X */
X
X#define bittest(name, n) (name[_BIT_SCRATCH_]=(n), \
X name[_BITGROUP(name[_BIT_SCRATCH_])] & \
X _BITMASK(name[_BIT_SCRATCH_]))
END_OF_FILE
if test 2335 -ne `wc -c <'bitset.h'`; then
echo shar: \"'bitset.h'\" unpacked with wrong size!
fi
# end of 'bitset.h'
fi
if test -f 'fgets.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fgets.c'\"
else
echo shar: Extracting \"'fgets.c'\" \(1751 characters\)
sed "s/^X//" >'fgets.c' <<'END_OF_FILE'
X/* f g e t s
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * Read a line from the specified stream. The function will read
X * characters until n-1 characters are read or a newline character
X * is read or an EOF is encountered. The string is then terminated
X * with a null character. The newline character is placed into the
X * string, unlike gets which strips the newline character. The
X * function returns the first argument, but will return the NULL
X * pointer if no character was read before EOF was read.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
Xchar *fgets(T(char *buf, buf), T(int n, n), T(FILE *fp, fp))
X
XD(char *buf) /* buffer for input */
XD(int n) /* size of buffer */
XD(FILE *fp) /* stream */
X
X{
X int ch; /* character read */
X _stdiobuf_t *q; /* input buffer pointer */
X _stdiobuf_t *s; /* output buffer */
X unsigned int bytesleft; /* bytes left in current load */
X
X if (n <= 1)
X return n > 0 ? (buf[0] = 0, buf) : NULL;
X
X if (fp == stdin && TESTFLAG(stdout, _IOLBF))
X (void) FFLUSH(stdout);
X
X for (s = (_stdiobuf_t *) buf, --n; ; ) {
X if ((bytesleft = BYTESINREADBUFFER(fp)) != 0) {
X if (bytesleft > n)
X bytesleft = n;
X n -= bytesleft;
X q = GETREADPTR(fp);
X UNROLL_DO(fgetsbytes, bytesleft, if ((*s++ = *q++) == '\n') break);
X SETREADPTR(fp, q);
X }
X *s = 0;
X if (bytesleft != 0 || n == 0)
X return buf;
X if ((ch = getc(fp)) == EOF)
X return s == (_stdiobuf_t *) buf ? NULL : buf;
X if ((*s++ = ch) == '\n' || --n == 0) {
X *s = 0;
X return buf;
X }
X }
X}
END_OF_FILE
if test 1751 -ne `wc -c <'fgets.c'`; then
echo shar: \"'fgets.c'\" unpacked with wrong size!
fi
# end of 'fgets.c'
fi
if test -f 'fread.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fread.c'\"
else
echo shar: Extracting \"'fread.c'\" \(2968 characters\)
sed "s/^X//" >'fread.c' <<'END_OF_FILE'
X/* f r e a d
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * Read a series of records from an input stream. The function
X * returns the number of items (not bytes) read. The function
X * stops reading when the number of items is satisfied or when
X * EOF is encountered.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
Xsize_t fread(T(void *ptr, ptr), T(size_t size, size),
X T(size_t nitems, nitems), T(FILE *fp, fp))
X
XD(void *ptr) /* buffer */
XD(size_t size) /* size of record */
XD(size_t nitems) /* number of items */
XD(FILE *fp) /* stream */
X
X{
X int red; /* bytes read in read call */
X _stdiobuf_t *p; /* buffer pointer */
X _stdiobuf_t *q; /* pointer into getc buffer */
X unsigned int itemsleft; /* whole or partial items left */
X unsigned int nextover; /* bytes left over next iteration */
X unsigned int leftover; /* bytes left over this iteration */
X unsigned int readitem; /* whole items to read */
X unsigned int readsize; /* amount of data to read */
X unsigned int oversize; /* readsize less leftover */
X
X if (CHECKREAD(fp) ||
X (itemsleft = nitems) == 0 ||
X size == 0)
X return 0;
X
X/* Flush stdout */
X if (fp == stdin && TESTFLAG(stdout, _IOLBF))
X (void) FFLUSH(stdout);
X
X/* Fix void * casting problems */
X p = (_stdiobuf_t *) ptr;
X
X/* Absorb as much data from the input buffer as possible */
X nextover = 0;
X readitem = 0;
X if ((readsize = BYTESINREADBUFFER(fp)) != 0) {
X if (readsize/size >= itemsleft) {
X readsize = itemsleft*size;
X readitem = itemsleft;
X }
X else {
X readitem = readsize/size;
X nextover = (leftover = readsize%size) != 0 ? size - leftover : 0;
X }
X q = GETREADPTR(fp);
X if (readsize > FREADTHRESHOLD) {
X MEMCPY(p, q, readsize);
X p += readsize;
X q += readsize;
X }
X else {
X do
X *p++ = *q++;
X while (--readsize);
X }
X SETREADPTR(fp, q);
X }
X
X/* The rest of the data comes from the file directly */
X for ( ; (itemsleft -= readitem) != 0; p += readsize) {
X leftover = nextover;
X readsize = INT_MAX;
X readitem = 0;
X
X/* Very large objects will require several large reads */
X if (readsize < leftover)
X nextover = leftover - readsize;
X
X/* Account for end of last object and start of new ones */
X else {
X if (leftover != 0)
X readitem = 1;
X oversize = readsize - leftover;
X if ((readitem += oversize/size) < itemsleft)
X nextover = size - oversize%size;
X else {
X readitem = itemsleft;
X readsize = leftover + itemsleft*size;
X if (leftover != 0)
X readsize -= size;
X }
X }
X
X red = _ioread(fileno(fp), (char *) p, (int) readsize);
X
X if (red != readsize) {
X if (red != -1 && red > leftover)
X itemsleft -= 1 + (red-leftover)/size;
X break;
X }
X }
X return nitems-itemsleft;
X}
END_OF_FILE
if test 2968 -ne `wc -c <'fread.c'`; then
echo shar: \"'fread.c'\" unpacked with wrong size!
fi
# end of 'fread.c'
fi
if test -f 'fwrite.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fwrite.c'\"
else
echo shar: Extracting \"'fwrite.c'\" \(3345 characters\)
sed "s/^X//" >'fwrite.c' <<'END_OF_FILE'
X/* f w r i t e
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * This function writes a series of records to the output stream.
X * The function returns the number of items written to the stream.
X * Writing stops when the correct number of items have been written
X * or when the function encounters an error.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
Xsize_t fwrite(T(void *ptr, ptr), T(size_t size, size),
X T(size_t nitems, nitems), T(FILE *fp, fp))
X
XD(void *ptr) /* buffer */
XD(size_t size) /* size of item */
XD(size_t nitems) /* number of items */
XD(FILE *fp) /* stream */
X
X{
X int wrote; /* bytes written in write call */
X _stdiobuf_t *p; /* buffer pointer */
X _stdiobuf_t *q; /* output buffer pointer */
X unsigned int itemsleft; /* whole or partial items left */
X unsigned int leftover; /* bytes left over this iteration */
X unsigned int nextover; /* bytes left over next iteration */
X unsigned int writesize; /* size of write */
X unsigned int writeitem; /* whole items written */
X unsigned int oversize; /* writesize less leftover */
X unsigned int writebytes; /* total bytes to write (small) */
X unsigned int bytesleft; /* bytes left to write (small) */
X
X/* Items left to write */
X if (CHECKWRITE(fp) || (itemsleft = nitems) == 0 || size == 0)
X return 0;
X
X/* Fix void * casting problems */
X p = (_stdiobuf_t *) ptr;
X
X/* Small amounts go via putc */
X if (! TESTFLAG(fp, _IONBF) &&
X (UNUSEDINWRITEBUFFER(fp)+BUFFERSIZE(fp))/size > itemsleft) {
X SETSCAN(fp);
X writebytes = bytesleft = itemsleft*size;
X do {
X if ((writesize = UNUSEDINWRITEBUFFER(fp)) > bytesleft)
X writesize = bytesleft;
X
X if (writesize == 0) {
X if (FFLUSH(fp))
X break;
X }
X else {
X bytesleft -= writesize;
X q = GETWRITEPTR(fp);
X if (writesize > FWRITETHRESHOLD) {
X MEMCPY(q, p, writesize);
X p += writesize;
X q += writesize;
X }
X else {
X do
X *q++ = *p++;
X while (--writesize);
X }
X SETWRITEPTR(fp, q);
X }
X } while (bytesleft != 0);
X
X if (TESTFLAG(fp, _IOLBF))
X (void) FFLUSH(fp);
X
X return (writebytes-bytesleft)/size;
X }
X
X/* Large amounts get fed directly to the file */
X if (BYTESINWRITEBUFFER(fp) != 0 && FFLUSH(fp))
X return 0;
X
X/* The rest of the data goes to the file directly */
X for (nextover=writeitem=0; (itemsleft -= writeitem) != 0; p += writesize) {
X leftover = nextover;
X writesize = INT_MAX;
X writeitem = 0;
X
X/* Very large objects will require several large writes */
X if (writesize < leftover)
X nextover = leftover - writesize;
X
X/* Account for end of last object and start of new ones */
X else {
X if (leftover != 0)
X writeitem = 1;
X oversize = writesize - leftover;
X if ((writeitem += oversize/size) < itemsleft)
X nextover = size - oversize%size;
X else {
X writeitem = itemsleft;
X writesize = leftover + itemsleft*size;
X if (leftover != 0)
X writesize -= size;
X }
X }
X
X wrote = _iowrite(fileno(fp), (char *) p, (int) writesize);
X
X if (wrote != writesize) {
X if (wrote != -1 && wrote > leftover)
X itemsleft -= 1 + (wrote-leftover)/size;
X break;
X }
X }
X return nitems-itemsleft;
X}
END_OF_FILE
if test 3345 -ne `wc -c <'fwrite.c'`; then
echo shar: \"'fwrite.c'\" unpacked with wrong size!
fi
# end of 'fwrite.c'
fi
if test -f 'gets.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'gets.c'\"
else
echo shar: Extracting \"'gets.c'\" \(1481 characters\)
sed "s/^X//" >'gets.c' <<'END_OF_FILE'
X/* g e t s
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * Read a line from stdin. The line is read up until the next
X * newline character or EOF is encountered. The newline
X * character is not inserted into the buffer, but the buffer
X * is terminated with a null character. No checks are made
X * that the line will fit into the buffer. The function returns
X * a pointer to the buffer. If EOF is encountered before any
X * characters have been read, the NULL pointer is returned.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
Xchar *gets(T(char *buf, buf))
X
XD(char *buf) /* input buffer */
X
X{
X int ch; /* next character */
X _stdiobuf_t *q; /* input buffer pointer */
X _stdiobuf_t *s; /* user's buffer pointer */
X unsigned int bytesleft; /* bytes left in current load */
X
X if (TESTFLAG(stdout, _IOLBF))
X (void) FFLUSH(stdout);
X
X for (s = (_stdiobuf_t *) buf; ;*s++ = ch) {
X if ((bytesleft = BYTESINREADBUFFER(stdin)) != 0) {
X q = GETREADPTR(stdin);
X UNROLL_DO(fgetsbytes, bytesleft, if ((*s++ = *q++) == '\n') break);
X SETREADPTR(stdin, q);
X }
X if (bytesleft != 0) {
X *--s = 0;
X return buf;
X }
X *s = 0;
X if ((ch = getc(stdin)) == EOF)
X return s == (_stdiobuf_t *) buf ? NULL : buf;
X if (ch == '\n')
X return buf;
X }
X}
END_OF_FILE
if test 1481 -ne `wc -c <'gets.c'`; then
echo shar: \"'gets.c'\" unpacked with wrong size!
fi
# end of 'gets.c'
fi
if test -f 'makefile.dos' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.dos'\"
else
echo shar: Extracting \"'makefile.dos'\" \(1880 characters\)
sed "s/^X//" >'makefile.dos' <<'END_OF_FILE'
X# Makefile for BSD
X#
XSTDIO= stdio.lib
XALL= *.c *.g *.h *.sh *.txt makefile.* *.cfg
XETC= end.lib
XEXIT= exit.obj _fakfls.obj
XLIBOBJ= _allocbu.obj _file.obj _fopen.obj \
X _ioread.obj _iowrite.obj _misc.obj \
X _open3.obj _os.obj _rename.obj \
X _stdio.obj _update.obj _vfscanf.obj \
X _vscanf.obj _vsscanf.obj \
X atexit.obj clearerr.obj ctermid.obj \
X cuserid.obj fclose.obj fdopen.obj \
X feof.obj ferror.obj fflush.obj \
X fgetc.obj fgets.obj fileno.obj \
X fopen.obj fprintf.obj fputc.obj \
X fputs.obj fread.obj freopen.obj \
X fscanf.obj fseek.obj ftell.obj \
X fwrite.obj getc.obj getchar.obj \
X gets.obj getw.obj perror.obj \
X printf.obj putc.obj putchar.obj \
X puts.obj putw.obj remove.obj \
X rewind.obj scanf.obj setbuf.obj \
X setvbuf.obj sprintf.obj sscanf.obj \
X tmpfile.obj tmpnam.obj ungetc.obj \
X vfprintf.obj vprintf.obj vsprintf.obj
XTESTEXE= xercise xexit xfputs xfwrite \
X xprintf xputc xputs xsprintf
XTESTOBJ= xercise.obj xexit.obj xfputs.obj xfwrite.obj \
X xprintf.obj xputc.obj xputs.obj xsprintf.obj
X#
X.SUFFIXES: .obj .c
X.c.obj:
X mcc -v -c -I. $<
X#
Xall: $(TESTEXE)
X#
Xxercise: xercise.obj $(STDIO) $(ETC)
X mcc -v -o xercise xercise.obj $(STDIO) $(ETC)
Xxexit: xexit.obj $(STDIO) $(ETC)
X mcc -v -o xexit xexit.obj $(STDIO) $(ETC)
Xxfwrite: xfwrite.obj $(STDIO) $(ETC)
X mcc -v -o xfwrite xfwrite.obj $(STDIO) $(ETC)
Xxprintf: xprintf.obj $(STDIO) $(ETC)
X mcc -v -o xprintf xprintf.obj $(STDIO) $(ETC)
Xxputc: xputc.obj $(STDIO) $(ETC)
X mcc -v -o xputc xputc.obj $(STDIO) $(ETC)
Xxputs: xputs.obj $(STDIO) $(ETC)
X mcc -v -o xputs xputs.obj $(STDIO) $(ETC)
Xxsprintf: xsprintf.obj $(STDIO) $(ETC)
X mcc -v -o xsprintf xsprintf.obj $(STDIO) $(ETC)
X#
X$(STDIO): $(LIBOBJ)
X rm -f $(STDIO)
X lib $(STDIO) + $(LIBOBJ) ;
X$(ETC): $(EXIT)
X rm -f $(ETC)
X lib $(ETC) + $(EXIT) ;
X#
X$(LIBOBJ) $(EXIT): stdiolib.h stdio.h
X#
X$(TESTOBJ): stdio.h
X#
Xarc:
X rm -f stdio.arc
X pkarc a stdio $(ALL)
END_OF_FILE
if test 1880 -ne `wc -c <'makefile.dos'`; then
echo shar: \"'makefile.dos'\" unpacked with wrong size!
fi
# end of 'makefile.dos'
fi
if test -f 'makefile.unx' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.unx'\"
else
echo shar: Extracting \"'makefile.unx'\" \(2257 characters\)
sed "s/^X//" >'makefile.unx' <<'END_OF_FILE'
X# Makefile for BSD
X#
XCFLAGS= -I. -I/usr/include -DMANUAL -gx
X#
XSTDIO= stdio.a
XALL= *.c *.g *.h *.sh *.txt makefile.* *.cfg
XLIBOBJ= _allocbu.o _file.o _fopen.o \
X _ioread.o _iowrite.o _misc.o \
X _open3.o _os.o _rename.o \
X _stdio.o _update.o _vfscanf.o \
X _vscanf.o _vsscanf.o \
X atexit.o clearerr.o ctermid.o \
X cuserid.o fclose.o fdopen.o \
X feof.o ferror.o fflush.o \
X fgetc.o fgets.o fileno.o \
X fopen.o fprintf.o fputc.o \
X fputs.o fread.o freopen.o \
X fscanf.o fseek.o ftell.o \
X fwrite.o getc.o getchar.o \
X gets.o getw.o perror.o \
X printf.o putc.o putchar.o \
X puts.o putw.o remove.o \
X rewind.o scanf.o setbuf.o \
X setvbuf.o sprintf.o sscanf.o \
X tmpfile.o tmpnam.o ungetc.o \
X vfprintf.o vprintf.o vsprintf.o
XEXIT= exit.o _fakfls.o
XTESTEXE= xercise xexit xfputs xfwrite \
X xprintf xputc xputs xsprintf
XTESTOBJ= xercise.o xexit.o xfputs.o xfwrite.o \
X xprintf.o xputc.o xputs.o xsprintf.o
X#
Xall: $(TESTEXE)
X#
Xinstall:
X sh yinstall.sh
X#
Xxercise: xercise.o $(STDIO)
X cc -o xercise xercise.o $(STDIO)
Xxexit: xexit.o $(STDIO)
X cc -o xexit xexit.o $(STDIO)
Xxfputs: xfputs.o $(STDIO)
X cc -o xfputs xfputs.o $(STDIO)
Xxfwrite: xfwrite.o $(STDIO)
X cc -o xfwrite xfwrite.o $(STDIO)
Xxprintf: xprintf.o $(STDIO)
X cc -o xprintf xprintf.o $(STDIO)
Xxputc: xputc.o $(STDIO)
X cc -o xputc xputc.o $(STDIO)
Xxputs: xputs.o $(STDIO)
X cc -o xputs xputs.o $(STDIO)
Xxsprintf: xsprintf.o $(STDIO)
X cc -o xsprintf xsprintf.o $(STDIO)
X#
X$(STDIO): $(LIBOBJ) $(EXIT)
X /bin/rm -f $(STDIO)
X ar cr $(STDIO) `lorder $(LIBOBJ) | tsort` $(EXIT)
X#
X$(LIBOBJ) $(EXIT): stdiolib.h stdio.h
X#
X$(TESTOBJ): stdio.h
X#
Xarc:
X rm -f stdio.arc
X arc a stdio.arc $(ALL)
X#
Xtar:
X rm -f stdio.tar.Z
X tar cvf - $(ALL) | compress > stdio.tar.Z
X#
Xshar:
X ls $(ALL) | \
X sed -e '/^site\.h/d' \
X -e '/^stdio\.h/d' \
X -e 's/^x.*/& Exercise file/' \
X -e 's/^y.*\.c/& Installation file/' \
X -e 's/^y.*\.sh/& Installation script/' \
X -e 's/^.*\.txt/& Documentation/' \
X -e 's/^makefile\..*/& Makefile/' \
X -e 's/^[0-9a-z_]*\.g$$/& Header file source/' \
X -e 's/^[0-9a-z_]*\.h$$/& Header file/' \
X -e 's/^[0-9a-z_]*\.c$$/& Stdio source code/' | \
X makekit -nstdio. -s30k -oMANIFEST
X#
Xlint:
X lint -n -I. -I/usr/include -DBSD `echo $(LIBOBJ) $(EXIT) | sed 's/\.o/.c/g'`
END_OF_FILE
if test 2257 -ne `wc -c <'makefile.unx'`; then
echo shar: \"'makefile.unx'\" unpacked with wrong size!
fi
# end of 'makefile.unx'
fi
if test -f 'setvbuf.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'setvbuf.c'\"
else
echo shar: Extracting \"'setvbuf.c'\" \(1555 characters\)
sed "s/^X//" >'setvbuf.c' <<'END_OF_FILE'
X/* s e t v b u f
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * Set the type of buffering to be used on this stream. This
X * must be called before any read or write has been done on
X * the stream. It is legal to make a stream unbuffered and
X * then at some subsequent time, make it buffered.
X *
X * Input streams cannot be line buffered. Attempts to do so
X * will make them fully buffered instead.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
Xint setvbuf(T(FILE *fp, fp), T(char *buf, buf),
X T(int type, type), T(unsigned int size, size))
X
XD(FILE *fp) /* stream */
XD(char *buf) /* buffer */
XD(int type) /* type of buffering */
XD(unsigned int size) /* size of buffer */
X
X{
X if (TESTFLAG(fp, _IONBF))
X fp->_base = NULL;
X
X if (fp->_base != NULL)
X return EOF;
X
X CLEARFLAG(fp, (_IOFBF | _IONBF | _IOLBF));
X
X if (type == _IOFBF || type == _IOLBF) {
X if (size == 0)
X return EOF;
X
X if (buf == NULL) {
X if ((buf = (char *) malloc(size)) == NULL)
X return EOF;
X else
X SETFLAG(fp, _IOMYBUF);
X }
X
X fp->_base = (_stdiobuf_t *) buf;
X fp->_bufsiz = size;
X
X if (TESTFLAG(fp, _IOREAD))
X type = _IOFBF;
X }
X else if (type == _IONBF) {
X fp->_base = &fp->_buf;
X fp->_bufsiz = sizeof(fp->_buf);
X }
X else
X return EOF;
X
X SETFLAG(fp, type);
X CHECKNEXTREAD(fp);
X CHECKNEXTWRITE(fp);
X return 0;
X}
END_OF_FILE
if test 1555 -ne `wc -c <'setvbuf.c'`; then
echo shar: \"'setvbuf.c'\" unpacked with wrong size!
fi
# end of 'setvbuf.c'
fi
if test -f 'tmpnam.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tmpnam.c'\"
else
echo shar: Extracting \"'tmpnam.c'\" \(2182 characters\)
sed "s/^X//" >'tmpnam.c' <<'END_OF_FILE'
X/* t m p n a m
X *
X * (C) Copyright C E Chew
X *
X * Feel free to copy, use and distribute this software provided:
X *
X * 1. you do not pretend that you wrote it
X * 2. you leave this copyright notice intact.
X *
X * Make a temporary file name. The file name is based on the
X * current process id. Following the process id will be a
X * sequence number. The filename format is:
X *
X * PPPPPPPPS.SSS
X *
X * where P represents the pid in hexadecimal, and S represents
X * the sequence number in hexadecimal. The string P_tmpdir is
X * prefixed to the filename yielding the path of a temporary file.
X *
X * The temporary name will be placed in the string passed in,
X * or if that is null, it will be placed in a static area. The
X * function will return a pointer to the name.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X#define P_tmpdir "/tmp/" /* temporary directory */
X#define L_tmpdir (sizeof(P_tmpdir)-1) /* length of tmpdir */
X#define L_pid 8 /* length of pid code */
X#define L_sep 1 /* length of separator */
X#define L_seq 4 /* length of the sequence */
X
X/*LINTLIBRARY*/
X
Xchar *tmpnam(T(char *s, s))
X
XD(char *s) /* name */
X
X{
X static char name[L_tmpnam]; /* default place */
X static time_t seq = 0; /* sequence number */
X static pid_t pid = -1; /* process id */
X struct stat sbuf; /* stat buffer */
X char *p; /* name generator */
X unsigned int v; /* conversion value */
X int d; /* digits to generate */
X int j; /* counter */
X
X if (pid < 0)
X pid = getpid();
X if (seq == 0)
X seq = time((time_t *) 0);
X
X do {
X
X/* Generate name backwards */
X if ((p = s) == 0)
X p = name;
X p += L_tmpnam-1;
X *p = 0;
X
X/* Fill in last characters */
X v = (unsigned int) seq;
X d = L_seq;
X j = 2;
X for (;;) {
X do {
X *--p = "0123456789abcdef"[v & 0xf];
X v >>= 4;
X } while (--d);
X
X if (--j == 0)
X break;
X
X p[-1] = p[0];
X *p-- = '.';
X
X v = (unsigned int) pid;
X d = L_pid;
X }
X
X/* Fill in directory prefix */
X s = &P_tmpdir[L_tmpdir];
X d = L_tmpdir;
X do
X *--p = *--s;
X while (--d);
X
X/* Advance for next name */
X seq++;
X
X } while (stat(p, &sbuf) >= 0);
X
X return p;
X}
END_OF_FILE
if test 2182 -ne `wc -c <'tmpnam.c'`; then
echo shar: \"'tmpnam.c'\" unpacked with wrong size!
fi
# end of 'tmpnam.c'
fi
echo shar: End of archive 3 \(of 6\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 6 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Earl Chew, Dept of Computer Science, Monash University, Australia 3168
ARPA: cechew%bruce.cs.monash.oz.au@uunet.uu.net ACS : cechew@bruce.oz