[comp.os.minix] Stdio V2 - Part 4 of 6

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 4 (of 6)."
# Contents:  0_notes.txt _stdio.c _vfscanf.c stdio.g yinstall.sh
# Wrapped by cechew@bruce on Fri Sep 29 16:23:39 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f '0_notes.txt' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'0_notes.txt'\"
else
echo shar: Extracting \"'0_notes.txt'\" \(5027 characters\)
sed "s/^X//" >'0_notes.txt' <<'END_OF_FILE'
Xyinstall
X========
X
XYou can try the yinstall script to generate the appropriate values for
Xconfig.h. Once the script runs successfully, it should generate a file
Xnamed site.h. Either compile with MANUAL defined (cc -DMANUAL) or edit
Xconfig.h so that MANUAL is defined. This should cause site.h to be included
Xduring the compilation. Look at makefile.unx to see how to compile with MANUAL.
XIf this fails, you'll have to edit config.h `manually'!
X
Xconfig.h
X========
X
XEnvironment dependent definitions should be encapsulated within this file.
XSome attempt has been made to make this as painless as possible. In particular
Xthe (broken) Minix environment is catered for. When Posix conformance is
Xachieved, it should be possible to take out the Minix hacks. The definitions in
Xthis file control the type of code generated and the include files that are
Xbrought in.
X
X * _BSD
X *	Select BSD environment.
X
XThis causes additional code and #defines to be made so that the BSD environment
X(at least the one here) looks a bit more like Posix. This is only referenced in
Xthis file.
X
X * _MINIX
X *	Selects Minix environment.
X
XDitto, but for Minix. Again, this should only be referenced in this file.
X
X * MANUAL
X *	Select code control manually, otherwise it will
X *	be selected `automatically' based on __STDC__
X *	and operating system selection (defaults to _MINIX
X *	if no system selected).
X
XGuess most of the following parameters based on what you've specified for the
Xsystem and whether or not it's __STDC__. If no system is specified, it's
XMinix.
X
X * PROTOTYPE
X *	Function prototype inclusion.
X
XFor ANSI compilers, prototypes are used to for all function declarations.
X
X * MEMORY
X *	Use memory.h. If this is not defined, users must provide
X *	definitions for MEMCPY, MEMSET and MEMCHR.
X * MYMEMCPY
X *	Use stdio code for memcpy.
X * MYMEMCHR
X *	Use stdio code for memchr.
X * MYMEMSET
X *	Use stdio code for memset.
X * STDARG
X *	Use stdarg.h instead or varargs.h.
X * LIMITS
X *	Use limits.h.
X * STRING
X *	Use string.h.
X * MEMSTR
X *	Use memchr to do fast strlen.
X * OPEN3
X *	Use three argument opens.
X * SYSTYPES
X *	Use sys/types.h.
X * TIME
X *	Use time.h.
X
XThese should be self explanatory. Minix time.h and sys/types.h are incomplete.
XAutomatic selection of OPEN3 is based on OCREAT and friends. This implies that
Xfcntl.h should be #included before config.h (as it is in stdiolib.h).
X
X * UNSIGNEDCHAR
X *	Use (int) ((unsigned char) (x)) for unsigned casts instead
X *	of (x) & ((1 << CHAR_BIT) - 1).
X
X(unsigned char) casting on Minix cc is broken.
X
X * FREADTHRESHOLD
X * FWRITETHRESHOLD
X *	Threshold beyond which fwrite or fread will use memcpy() to
X *	do the transfer instead of PUTC().
X
XSelf explanatory.
X
X * MEMSET(s,v,n)
X *	Set a piece of memory to the specified value.
X * MEMCPY(d,s,n)
X *	Copy a piece of memory of length n from s to d. No return
X *	value expected.
X * MEMCHR(s,c,n)
X *	Look in a piece of memory s of length n for character c. Return
X *	a pointer to the c if found, otherwise null.
X
XFor Minix these are simply hooks into memset, memcpy and memchr. The versions
Xin string.h are not particularly fast and there is little to be gained. Fast
Xversions are easily coded in assembler to make use of repeated aligned word
Xoperations. Perhaps I'll post these later.
X
X * TOLOWER(c)
X *	Convert uppercase to lowercase.
X
XMinix ctypes.h is incomplete.
X
XIt is suggested that you alter config.h by activating MANUAL and selecting
Xthe options you wish. In addition to this, you can add extra systems to the
XPosix hacking part.
X
Xstdio.h
X=======
X
XThe book says that this file must be self-sufficient. This causes problems
Xsince stdio requires knowledge of size_t and whether to use varargs or
Xstdargs.
X
XThe definition of size_t is wrapped within _SIZE_T. It may be necessary to wrap
Xthis using another name depending on the other components of the library.
X
X__STDC__ is used to control the varargs/stdargs stuff as well as the inclusion
Xof prototypes.
X
X(unsigned char) casting in Minix is broken. Unfortunately, stdio.h cannot
Xinclude config.h thus the kludges for this have to be made independently of
Xconfig.h. __STDIO_UCHAR__ defines the number of bits to mask off to get a
Xint to unsigned char to int. If this is defined to be 0, then it is assumed
Xthat an (unsigned char) cast will work.
X
XIf the commented definitions preceeding the __STDC__ test are activated (by
Xremoving the comment markers), then these definitions will override those
Xselected by the __STDC__ section.
X
XIt is suggested that you use this method to override the selections rather than
Xhacking the __STDC__ tests.
X
Xstdiolib.h
X==========
X
XThis sets up _all_ the maros for the stdio code. It makes use of config.h and
Xstdio.h. Apart from the function prototype stuff, this file attempts to hide
Xthe underlying _iobuf implementation from the stdio code through the use of
Xmacros. This has been useful, particularly when I chose to change the _iobuf
Xstructure to use multiple buffer pointers instead of the usual single _ptr.
X
XYou shouldn't have to to modify this file at all.
END_OF_FILE
if test 5027 -ne `wc -c <'0_notes.txt'`; then
    echo shar: \"'0_notes.txt'\" unpacked with wrong size!
fi
# end of '0_notes.txt'
fi
if test -f '_stdio.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'_stdio.c'\"
else
echo shar: Extracting \"'_stdio.c'\" \(5462 characters\)
sed "s/^X//" >'_stdio.c' <<'END_OF_FILE'
X/*			_ s t d i o
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 basic buffering mechanism for the
X * FILE structures.
X *
X * Normally there are three open streams with pointers declared
X * in <stdio.h>:
X *
X *	stdin	standard input file
X *	stdout	standard output file
X *	stderr	standard error file
X *
X * The read functions return the next character that was read from the
X * file, otherwise EOF on error.
X *
X * The write functions return the character that was written to the
X * file, otherwise EOF on error.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include "stdiolib.h"
X
X/*LINTLIBRARY*/
X
XFILE _stderr = {NULL, NULL, NULL, NULL, NULL, NULL, 0,
X		_IOSTATIC|_IOWRITE|_IONBF, 2, 0,
X                (int (*) P((FILE *))) _bfail,
X		_bwronly,
X		(int (*) P((FILE *))) _bsucceed,
X		NULL};
XFILE _stdout = {NULL, NULL, NULL, NULL, NULL, NULL, 0,
X		_IOSTATIC|_IOWRITE, 1, 0,
X                (int (*) P((FILE *))) _bfail,
X		_bwronly,
X		(int (*) P((FILE *))) _bsucceed,
X		&_stderr};
XFILE _stdin  = {NULL, NULL, NULL, NULL, NULL, NULL, 0,
X		_IOSTATIC|_IOREAD, 0, 0,
X                _brdonly,
X		(int (*) P((int, FILE *))) _bfail,
X		(int (*) P((FILE *))) _bsucceed,
X		&_stdout};
X
XFILE *_iop = &_stdin;
X
X#ifdef		MSDOS
Xint _wrapstdio = 1;
Xint _fmode = O_BINARY;
X#endif
X
X/* Flush all streams
X *
X * Flushes all output buffers. This ensures that all streams
X * are written out and closed. It's main purpose is to ensure
X * that all streams are flushed on exit. exit() knows about
X * the existence of _ioflush.
X */
Xvoid _ioflush(T(void,))
X
X{
X  FILE *fp;				/* FILE chain */
X  FILE *fpn;				/* next in FILE chain */
X
X  for (fp = _iop; fp != 0; fp = fpn) {
X    fpn = fp->_next;
X    (void) FFLUSH(fp);
X    (void) close(fileno(fp));
X  }
X}
X
X/* Check and initialise a readonly stream
X *
X * _brdonly is intended for read only streams. It will check
X * that the stream has a buffer. The fill function will then
X * be directed to _brd.
X */
Xint _brdonly(T(FILE *fp, fp))
X
XD(FILE *fp)				/* stream */
X
X{
X  _stdiobuf_t *p;			/* pointer to end */
X
X  p = fp->_rend;
X
X  if (! HASBUFFER(fp) && _allocbuf(fp) < 0)
X    return EOF;
X
X  INITREADBUFFER(fp, 0);
X  SETFILBUF(fp, _brd);
X  SETFLUSH(fp, _brdflush);
X
X  return p ? 0 : _brd(fp);
X}
X
X/* Fill read buffer
X *
X * _brd is the main function that fills the output buffer
X * then reads a character.
X */
Xint _brd(T(FILE *fp, fp))
X
XD(FILE *fp)				/* stream */
X
X{
X  int bytes;				/* bytes read */
X  _stdiobuf_t *nlp;			/* \n pointer */
X  int offset;				/* roll back offset */
X
X  if (GETFLAG(fp, (_IOREAD | _IOERR | _IOEOF)) == _IOREAD) {
X
X/* Flush stdout if we're reading from stdin */
X    if (fp == stdin && TESTFLAG(stdout, _IOLBF))
X      (void) FFLUSH(stdout);
X
X/* Read data into the buffer */
X    bytes = _ioread(fileno(fp), (char *) fp->_base,
X		    TESTFLAG(fp, _IONBF) ? 1 : fp->_bufsiz);
X
X    if (bytes > 0) {
X      if (TESTFLAG(fp, _IOLBF)                                           &&
X	  (nlp = (_stdiobuf_t *) MEMCHR(fp->_base, '\n', bytes)) != NULL &&
X	  (offset = nlp - (fp->_base + bytes) + 1) != 0                  &&
X	  lseek(fileno(fp), (long) offset, SEEK_CUR) != -1L)
X	bytes += offset;
X
X      INITREADBUFFER(fp, bytes);
X      return FGETC(fp);
X    }
X
X    INITREADBUFFER(fp, 0);
X    SETFLAG(fp, bytes ? (_IOERR|_IOEOF) : _IOEOF);
X  }
X
X  return EOF;
X}
X
X/* Flush a read buffer
X *
X * _brdflush is a function that flushes the input buffer.
X */
Xint _brdflush(T(FILE *fp, fp))
X
XD(FILE *fp)				/* stream */
X
X{
X  if (! TESTFLAG(fp, _IOERR)) {
X    if (! TESTFLAG(fp, _IOEOF) &&
X        lseek(fileno(fp), (long) (-BYTESINREADBUFFER(fp)), SEEK_CUR) != -1L)
X      INITREADBUFFER(fp, 0);
X    return 0;
X  }
X  SETFLAG(fp, _IOERR);
X  return EOF;
X}
X
X/* Check and initialise a writeonly stream
X *
X * _bwronly is intended for write only streams. It will check
X * that the stream has a buffer. The flush function will then
X * be directed to _bwr.
X */
Xint _bwronly(T(int c, c), T(FILE *fp, fp))
X
XD(int c)				/* character to write */
XD(FILE *fp)				/* stream */
X
X{
X  _stdiobuf_t *p;			/* pointer to end */
X
X  p = fp->_wend;
X
X  SETIOFLUSH();
X
X  if (! HASBUFFER(fp) && _allocbuf(fp) < 0)
X    return EOF;
X
X  INITWRITEBUFFER(fp);
X  SETFLSBUF(fp, _bwr);
X  SETFLUSH(fp, _bwrflush);
X
X  return p ? 0 : _bwr(c, fp);
X}
X
X/* Flush a write buffer and write a character
X *
X * _bwr is the main function that flushes the output buffer
X * then writes a character.
X */
Xint _bwr(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, (_IOWRITE | _IOERR)) == _IOWRITE) {
X    for (;;) {
X      if (UNUSEDINWRITEBUFFER(fp) > 0) {
X	if (((FPUTC(c, fp) != '\n'   || ! TESTFLAG(fp, _IOLBF)) &&
X	     ! TESTFLAG(fp, _IONBF)) || ! FFLUSH(fp))
X	  return UCHAR(c);
X	break;
X      }
X      if (FFLUSH(fp))
X	break;
X    }
X  }
X  return EOF;
X}
X
X/* Flush a write buffer
X *
X * _bwrflush is a function that flushes the output buffer.
X */
Xint _bwrflush(T(FILE *fp, fp))
X
XD(FILE *fp)				/* stream */
X
X{
X  int length;				/* bytes to write */
X
X  if (! TESTFLAG(fp, _IOERR)
X#ifndef		OPEN3
X      && (! TESTFLAG(fp, _IOAPPEND) || lseek(fileno(fp), 0L, SEEK_END) != -1L)
X#endif
X     ) {
X    length = BYTESINWRITEBUFFER(fp);
X    INITWRITEBUFFER(fp);
X    if (_iowrite(fileno(fp), (char *) fp->_base, length) == length)
X      return 0;
X  }
X  SETFLAG(fp, _IOERR);
X  return EOF;
X}
END_OF_FILE
if test 5462 -ne `wc -c <'_stdio.c'`; then
    echo shar: \"'_stdio.c'\" unpacked with wrong size!
fi
# end of '_stdio.c'
fi
if test -f '_vfscanf.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'_vfscanf.c'\"
else
echo shar: Extracting \"'_vfscanf.c'\" \(6284 characters\)
sed "s/^X//" >'_vfscanf.c' <<'END_OF_FILE'
X/*				v f s c a n 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 * Formatted read from a stream. This function uses varargs to
X * obtain the argument list. It is the basis of the family of
X * scanf functions in this stdio implementation.
X *
X * The user is referred to the manual page for a full
X * description of the formats available.
X *
X * The function returns EOF on end of input, and a short count
X * for missing or illegal data items.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X#include <ctype.h>
X#include "stdiolib.h"
X#include "bitset.h"
X
X#define CHARSET		(1 << CHAR_BIT)
X
X#define WHITESPACE(c)	((c)==' '||(c)=='\t'||(c)=='\n')
X#define NEXTCH()	(ch = getc(fp))
X#define ENDFIELD() \
X  if (fieldok) { \
X    if (! noassign) items++; \
X  } \
X  else \
X    goto Putback;
X
Xint _vfscanf(T(FILE *fp, fp), T(const char *fmt, fmt), T(VA_LIST args, args))
X
XD(FILE *fp)			/* stream */
XD(char *fmt)			/* format */
XD(VA_LIST args)			/* arguments */
X
X{
X  bitstring(cset, CHARSET);	/* set for %[] */
X  int items;			/* number of items done */
X  int ch;			/* next character */
X  int lch;			/* lowercase version of character */
X  int i;			/* general index */
X  char *p;			/* string pointer */
X  char skipspace;		/* force white space skip */
X  char noassign;		/* do not do assignment */
X  char longflag;		/* pointer is long */
X  char shortflag;		/* pointer is short */
X  char fieldok;			/* this field parsed ok */
X  char invertedset;		/* inverted set */
X  char sign;			/* conversion is signed */
X  char negative;		/* number is negative */
X  int fieldwidth;		/* width of field */
X  unsigned radix;		/* radix for conversion */
X  unsigned lastdigit;		/* last digit (0-9) in radix */
X  long longv;			/* long value for conversion */
X
X/* Prime the look ahead character */
X  if (NEXTCH() == EOF)
X    return EOF;
X
X  for (items = 0; ; fmt++) {
X
X/* Skip whitespace in format */
X    for (skipspace = 0; WHITESPACE(*fmt); fmt++)
X      skipspace = 1;
X
X/* Check for end of format or end of input */
X    if (*fmt == 0 || ch == EOF)
X      goto Putback;
X
X/* Check for verbatim character */
X    if (*fmt != '%') {
X      while (WHITESPACE(ch))
X        NEXTCH();
X
X      if (ch != *fmt)
X        goto Putback;
X
X      NEXTCH();
X      continue;
X    }
X
X/* Format precursor seen --- see if assignment required */
X    if ((noassign = *++fmt == '*') != 0)
X      fmt++;
X
X/* Check for width specification */
X    fieldwidth = -1;
X    if (*fmt >= '0' && *fmt <= '9') {
X      for (fieldwidth = 0; *fmt >= '0' && *fmt <= '9'; )
X        fieldwidth = fieldwidth * 10 + *fmt++ - '0';
X    }
X
X/* Check for long or short pointers */
X    if ((longflag = *fmt == 'l') != 0 || (shortflag = *fmt == 'h') != 0)
X      fmt++;
X
X/* Skip whitespace in the input stream */
X    if (skipspace || (*fmt != 'c' && *fmt != '[')) {
X      while (WHITESPACE(ch))
X        NEXTCH();
X    }
X
X/* Assume that field is not parsed */
X    fieldok = 0;
X
X    switch (*fmt) {
X
X    case 'O': longflag = 1;
X    case 'o': radix = 8;  lastdigit = '7'; sign = 0; goto oxud;
X    case 'U': longflag = 1;
X    case 'u': radix = 10; lastdigit = '9'; sign = 0; goto oxud;
X    case 'D': longflag = 1;
X    case 'd': radix = 10; lastdigit = '9'; sign = 1; goto oxud;
X    case 'X': longflag = 1;
X    case 'x': radix = 16; lastdigit = '9'; sign = 0;
X
Xoxud:
X      longv = 0;
X      negative = 0;
X
X/* Look for sign if number is signed */
X      if (fieldwidth != 0 && sign && ch == '+')
X	NEXTCH();
X      else if (fieldwidth != 0 && sign && ch == '-') {
X	negative = 1;
X	NEXTCH();
X      }
X
X/* Scan and convert */
X      while (fieldwidth < 0 || fieldwidth--) {
X	if (ch >= '0' && ch <= lastdigit)
X	  ch -= '0';
X	else {
X	  lch = TOLOWER(ch);
X	  if (lch >= 'a' && (lch += 10 - 'a') < radix)
X	    ch = lch;
X	  else
X	    break;
X	}
X	longv = longv * radix + ch;
X	NEXTCH();
X	fieldok = 1;
X      }
X
X/* Complete the conversion */      
X      if (! noassign) {
X	if (negative)
X	  longv = -longv;
X	if (longflag)
X	  if (sign) *VA_ARG(args, long *)           = longv;
X	  else      *VA_ARG(args, unsigned long *)  = longv;
X	else if (shortflag)
X	  if (sign) *VA_ARG(args, short *)          = (short) longv;
X	  else      *VA_ARG(args, unsigned short *) = (unsigned short) longv;
X	else
X	  if (sign) *VA_ARG(args, int *)            = (int) longv;
X	  else      *VA_ARG(args, unsigned int *)   = (unsigned int) longv;
X      }
X      ENDFIELD();
X      break;
X
X    case 'c':
X      if (fieldwidth == -1)
X	fieldwidth = 1;
X
X/* Initialise the string pointer */	
X      if (! noassign)
X        p = VA_ARG(args, char *);
X	
X      while (fieldwidth-- && ch >= 0) {
X	if (! noassign)
X	  *p++ = ch;
X	NEXTCH();
X	fieldok = 1;
X      }
X      ENDFIELD();
X      break;
X
X    case 's':
X
X/* Initialise the string pointer */    
X      if (! noassign)
X	p = VA_ARG(args, char *);
X	
X      while (fieldwidth < 0 || fieldwidth--) {
X        if (ch <= 0 || WHITESPACE(ch))
X	  break;
X	if (! noassign)
X	  *p++ = ch;
X	NEXTCH();
X	fieldok = 1;
X      }
X
X/* Terminate the string with a null */
X      if (! noassign)
X	*p++ = 0;
X      ENDFIELD();
X      break;
X
X    case '[':
X
X /* Clear the bit set */
X      bitempty(cset, CHARSET);
X
X/* Check for inverted set */
X      if ((invertedset = *++fmt == '^') != 0)
X	fmt++;
X
X/* Check for right bracket in set */
X      if (*fmt == ']')
X        bitset(cset, *fmt++);
X
X/* Scan	search set, setting bits */
X      while (*fmt != 0 && *fmt != ']') {
X	if (fmt[1] != '-' || fmt[2] == ']' || fmt[2] == 0 || fmt[0] > fmt[2])
X	  bitset(cset, *fmt++);
X	else {
X	  for (i = fmt[0]; i <= fmt[2]; i++)
X	    bitset(cset, i);
X	  fmt += 3;
X	}
X      }
X
X/* Check for unsatisfactory set construction */
X      if (*fmt != ']')
X	goto Putback;
X
X/* Initialise string pointer */
X      if (! noassign)
X	p = VA_ARG(args, char *);
X
X/* Scan input for satisfactory characters */
X      while (fieldwidth < 0 || fieldwidth--) {
X        if (WHITESPACE(ch) || ch <= 0 || ! (bittest(cset, ch) ^ invertedset))
X	  break;
X	if (! noassign)
X	  *p++ = ch;
X	NEXTCH();
X	fieldok = 1;
X      }
X
X/* Terminate string with null */
X      if (! noassign)
X	*p++ = 0;
X      ENDFIELD();
X      break;
X    }
X  }
X
X/* Restore the look ahead character */
XPutback:
X  if (ch != EOF)
X    (void) ungetc(ch, fp);
X  return items;
X}
END_OF_FILE
if test 6284 -ne `wc -c <'_vfscanf.c'`; then
    echo shar: \"'_vfscanf.c'\" unpacked with wrong size!
fi
# end of '_vfscanf.c'
fi
if test -f 'stdio.g' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stdio.g'\"
else
echo shar: Extracting \"'stdio.g'\" \(6569 characters\)
sed "s/^X//" >'stdio.g' <<'END_OF_FILE'
X#ifndef _STDIO_H
X#define _STDIO_H
X
X/*			s t d i o
X *
X *		Author: C. E. Chew
X *		Date:   August 1989
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 * Definitions and user interface for the stream io package.
X *
X * Patchlevel 2.0
X *
X * Edit History:
X */
X
X/* Site specific definitions */
X/*+*/
X/*efine	__STDIO_P__(x)*/
X/*efine	__STDIO_VA__*/
X/*efine	__STDIO_UCHAR__*/
X/*efine	__STDIO_VA_LIST__*/
X/*-*/
X
X/* Defintions based on ANSI compiler */
X#ifdef		__STDC__
X# ifndef	__STDIO_P__
X#   define	__STDIO_P__(x)		x
X# endif
X# ifndef	__STDIO_VA__
X#   define	__STDIO_VA__		, ...
X# endif
X# ifndef	__STDIO_UCHAR__
X#   define	__STDIO_UCHAR__		0
X# endif
X#else
X# ifndef	__STDIO_P__
X#   define	__STDIO_P__(x)		()
X# endif
X# ifndef	__STDIO_VA__
X#   define	__STDIO_VA__
X# endif
X# ifndef	__STDIO_UCHAR__
X#   define	__STDIO_UCHAR__		(0xff)
X# endif
X#endif
X
X#ifndef		__STDIO_VA_LIST__
X#  define	__STDIO_VA_LIST__	char *
X#endif
X
X/* ANSI Definitions */
X#define BUFSIZ 1024			/* default buffer size */
X
X#ifndef	NULL
X# define NULL		(0)		/* null pointer */
X#endif
X
X#define EOF		(-1)		/* eof flag */
X#define FOPEN_MAX	16		/* minimum guarantee */
X#define FILENAME_MAX	127		/* maximum length of file name */
X
X#define SEEK_SET	0		/* seek from beginning */
X#define SEEK_CUR	1		/* seek from here */
X#define SEEK_END	2		/* seek from end */
X
X#define TMP_MAX		(0xffff)	/* maximum number of temporaries */
X
X#define L_tmpnam	(5 + 8 + 4 + 1 + 1) /* length of temporary file name */
X
Xtypedef long fpos_t;			/* stream positioning */
X
X#ifndef	_SIZE_T
X# define _SIZE_T
X  typedef unsigned int size_t;		/* sizeof type */
X#endif
X
X#define _IOFBF		00000		/* fully buffered io */
X#define _IOREAD		00001		/* opened for reading */
X#define _IOWRITE	00002		/* opened for writing */
X#define _IONBF		00004		/* unbuffered */
X#define _IOMYBUF	00010		/* allocated buffer */
X#define _IOEOF		00020		/* eof encountered */
X#define _IOERR		00040		/* error encountered */
X#define _IOSTRING	00100		/* strings */
X#define _IOLBF		00200		/* line buffered */
X#define _IORW		00400		/* opened for reading and writing */
X#define _IOAPPEND	01000		/* append mode */
X#define _IOSTATIC	02000		/* static FILE */
X
X/* Implementation Definitions */
X
Xtypedef char _stdiobuf_t;		/* stdio buffer type */
X
Xtypedef struct _iobuf {
X _stdiobuf_t *_rptr;			/* pointer into read buffer */
X _stdiobuf_t *_rend;			/* point at end of read buffer */
X _stdiobuf_t *_wptr;			/* pointer into write buffer */
X _stdiobuf_t *_wend;			/* point at end of write buffer */
X _stdiobuf_t *_base;			/* base of buffer */
X _stdiobuf_t *_scan;			/* scan point */
X int _bufsiz;				/* size of buffer */
X short _flag;				/* flags */
X char _file;				/* channel number */
X _stdiobuf_t _buf;			/* small buffer */
X int (*_filbuf) __STDIO_P__((struct _iobuf *));	/* fill input buffer */
X int (*_flsbuf) __STDIO_P__((int, struct _iobuf *)); /* flush output buffer */
X int (*_flush) __STDIO_P__((struct _iobuf *));	/* flush buffer */
X struct _iobuf *_next;			/* next file */
X} FILE;
X
Xextern FILE _stdin;			/* stdin */
Xextern FILE _stdout;			/* stdout */
Xextern FILE _stderr;			/* stderr */
X
X#define stdin		(&_stdin)
X#define stdout		(&_stdout)
X#define stderr		(&_stderr)
X
X/* ANSI Stdio Requirements */
X
Xint	getc		__STDIO_P__((FILE *));
X#if	__STDIO_UCHAR__
X# define getc(p)	((p)->_rptr<(p)->_rend\
X			 ?(int)(*(p)->_rptr++)&__STDIO_UCHAR__\
X			 :(*(p)->_filbuf)(p))
X#else
X# define getc(p)	((p)->_rptr<(p)->_rend\
X			 ?(int)((unsigned char)(*(p)->_rptr++))\
X			 :(*(p)->_filbuf)(p))
X#endif
X
Xint	getchar		__STDIO_P__((void));
X#define getchar()	getc(stdin)
X
Xint	putc		__STDIO_P__((int, FILE *));
X#if	__STDIO_UCHAR__
X# define putc(x,p)	((p)->_wptr<(p)->_wend\
X                         ?(int)(*(p)->_wptr++=(x))&__STDIO_UCHAR__\
X	                 :(*(p)->_flsbuf)((x),(p)))
X#else
X# define putc(x,p)	((p)->_wptr<(p)->_wend\
X                         ?(int)((unsigned char)(*(p)->_wptr++=(x)))\
X	                 :(*(p)->_flsbuf)((x),(p)))
X#endif
X
Xint	putchar		__STDIO_P__((int));
X#define	putchar(x)	putc(x,stdout)
X
Xint	feof		__STDIO_P__((FILE *));
X#define feof(p)		(((p)->_flag&_IOEOF)!=0)
X
Xint	ferror		__STDIO_P__((FILE *));
X#define ferror(p)	(((p)->_flag&_IOERR)!=0)
X
Xvoid	clearerr	__STDIO_P__((FILE *));
X#define clearerr(p)	((p)->_flag&=~(_IOEOF|_IOERR))
X
XFILE 	*fopen		__STDIO_P__((const char *, const char *));
XFILE	*freopen	__STDIO_P__((const char *, const char *, FILE *));
Xint	fflush		__STDIO_P__((FILE *));
Xint	fclose		__STDIO_P__((FILE *));
X
Xint	fgetpos		__STDIO_P__((FILE *, fpos_t *));
Xint	fsetpos		__STDIO_P__((FILE *, fpos_t *));
Xlong	ftell		__STDIO_P__((FILE *));
Xint	fseek		__STDIO_P__((FILE *, long, int));
Xvoid	rewind		__STDIO_P__((FILE *));
X
Xint	fgetc		__STDIO_P__((FILE *));
Xint	fputc		__STDIO_P__((int, FILE *));
Xsize_t	fread		__STDIO_P__((void *, size_t, size_t, FILE *));
Xsize_t	fwrite		__STDIO_P__((void *, size_t, size_t, FILE *));
X
Xint	getw		__STDIO_P__((FILE *));
Xint	putw		__STDIO_P__((int, FILE *));
Xchar	*gets		__STDIO_P__((char *));
Xchar	*fgets		__STDIO_P__((char *, int, FILE *));
Xint	puts		__STDIO_P__((const char *));
Xint	fputs		__STDIO_P__((const char *, FILE *));
X
Xint	ungetc		__STDIO_P__((int, FILE *));
X
Xint	printf		__STDIO_P__((const char * __STDIO_VA__));
Xint	fprintf		__STDIO_P__((FILE *, const char * __STDIO_VA__));
Xint	sprintf		__STDIO_P__((char *, const char * __STDIO_VA__));
Xint	vprintf		__STDIO_P__((const char *, __STDIO_VA_LIST__));
Xint	vfprintf	__STDIO_P__((FILE *, const char *, __STDIO_VA_LIST__));
Xint	vsprintf	__STDIO_P__((char *, const char *, __STDIO_VA_LIST__));
Xint	scanf		__STDIO_P__((const char * __STDIO_VA__));
Xint	fscanf		__STDIO_P__((FILE *, const char * __STDIO_VA__));
Xint	sscanf		__STDIO_P__((const char *, const char * __STDIO_VA__));
X
Xvoid	setbuf		__STDIO_P__((FILE *, char *));
Xint	setvbuf		__STDIO_P__((FILE *, char *, int, size_t));
X
Xint	rename		__STDIO_P__((const char *, const char *));
Xint	remove		__STDIO_P__((const char *));
X
Xvoid	perror		__STDIO_P__((const char *));
X
Xchar *	tmpnam		__STDIO_P__((char *));
XFILE *	tmpfile		__STDIO_P__((void));
X
X/* Posix Definitions */
Xint	unlink		__STDIO_P__((const char *));
X#define remove(x)	unlink((x))
X
X#define L_ctermid	9
Xchar *	ctermid		__STDIO_P__((char *s));
X
X#define L_cuserid	9
Xchar *	cuserid		__STDIO_P__((char *s));
X
XFILE	*fdopen		__STDIO_P__((int, const char *));
X
Xint	fileno		__STDIO_P__((FILE *));
X#define fileno(p)	((p)->_file)
X
X#undef	__STDIO_P__
X#undef	__STDIO_VA__
X#undef	__STDIO_VA_LIST__
X/*ndef	__STDIO_UCHAR__*/
X#endif
END_OF_FILE
if test 6569 -ne `wc -c <'stdio.g'`; then
    echo shar: \"'stdio.g'\" unpacked with wrong size!
fi
# end of 'stdio.g'
fi
if test -f 'yinstall.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'yinstall.sh'\"
else
echo shar: Extracting \"'yinstall.sh'\" \(5461 characters\)
sed "s/^X//" >'yinstall.sh' <<'END_OF_FILE'
X#!/bin/sh
X
X#
X# Name source and target files
X#
XSITE=site.h
XSTDIOG=stdio.g
XSTDIOH=stdio.h
X
X#
X# Determine how to echo without trailing new line
X#
Xif echo '\c' | grep -s . ; then
X  ECHO='echo -n'
X  NONL=
Xelse
X  ECHO=echo
X  NONL='\c'
Xfi
X
X#
X# Nice heading to show what's about to happen
X#
Xecho ""
Xecho "Stdio Installation Script"
Xecho ""
Xecho "Place site details in ${SITE}"
Xecho "Create ${STDIOH} from ${STDIOG}"
X${ECHO} "Is this acceptable? ${NONL}"
Xread YN
Xif test ${YN} != "y" ; then
X  exit 1
Xfi
Xecho ""
X
X#
X# Determine where to find C compiler
X#
X${ECHO} "Searching for cc... ${NONL}"
XCC=cc
Xif ( ${CC} -o ynull ynull.c ) 2>/dev/null ; then
X  echo "  found"
Xelse
X  echo ""
X  ${ECHO} "Type in your cc command:  ${NONL}"
X  read CC
Xfi
Xrm -f ynull
X
X#
X# Determine locate of C preprocessor
X#
X${ECHO} "Searching for cpp... ${NONL}"
XCPP=/lib/cpp
Xif ( ${CPP} <ynull.c 1>/dev/null ) 2>/dev/null ; then
X  echo " found"
Xelse
X  echo ""
X  ${ECHO} "Type in your cpp command: ${NONL}"
X  read CPP
Xfi
X
X#
X# Initialise configuration specification
X#
Xrm -f ${SITE}
X
X#
X# Initialise stdio.g modifications
X#
Xecho ""
Xecho "Creating ${STDIOH}..."
X${CC} -o ystdc ystdc.c
X${CC} -o yuchar yuchar.c
X${CC} -o yumask yumask.c
XVA=`if ${CPP} <ystdarg.c 2>/dev/null ; then :
Xelse ${CPP} <yvarargs.c 2>/dev/null
Xfi | grep '^[ 	]*typedef[ 	].*[^A-Za-z0-9_]va_list' |
Xsed 's/[ 	]*typedef[ 	]*\(.*[^A-Za-z0-9_]\)va_list[^A-Za-z0-9_]*/\1/'`
Xif ./yuchar ; then
X  UCHAR='0'
Xelse
X  UCHAR=`./yumask`
Xfi
Xif ./ystdc ; then
X  PROTOTYPE='x'
X  VALIST=', ...'
Xelse
X  PROTOTYPE='()'
X  VALIST=''
Xfi
Xrm -f ystdio
Xecho "/\/\*\-\*\// a\\" >>ystdio
Xecho "/*+*/\\" >>ystdio
Xecho "#define __STDIO_P__(x)		${PROTOTYPE}\\" | tee -a ystdio |
Xsed 's/\\$//'
Xecho "#define __STDIO_VA__		${VA}\\"        | tee -a ystdio |
Xsed 's/\\$//'
Xecho "#define __STDIO_UCHAR__		${UCHAR}\\"     | tee -a ystdio |
Xsed 's/\\$//'
Xecho "#define __STDIO_VA_LIST__		${VALIST}\\"    | tee -a ystdio |
Xsed 's/\\$//'
Xecho "/*-*/" >>ystdio
Xecho "/\/\*\+\*\//,/\/\*\-\*\//d" >>ystdio
Xsed -f ystdio <${STDIOG} >${STDIOH}
Xrm -f ystdio
X
X#
X# Check out the system
X#
Xecho ""
Xecho "Checking for ANSI conformant compiler environment..."
Xif ./ystdc ; then
X  echo "#define PROTOTYPE"
X  echo "#define STDARG"
X  echo "#define LIMITS"
Xelse
X  echo "/*efine PROTOTYPE*/"
X  if ${CC} -o ystdarg ystdarg.c 1>/dev/null 2>&1 ; then
X    echo "#define STDARG"
X  else
X    echo "/*efine STDARG*/"
X  fi
X  echo "/*efine LIMITS*/"
X  ${CC} -o ylimits ylimits.c
X  ./ylimits
Xfi | tee -a ${SITE}
Xrm -f ystdc ystdarg ylimits yumask yuchar
X
Xecho ""
Xecho "Checking compiler for correct (int) ((unsigned char) (x)) casts..."
Xif test ${UCHAR} = '0' ; then
X  echo "#define UNSIGNEDCHAR"
Xelse
X  echo "/*efine UNSIGNEDCHAR*/"
Xfi | tee -a ${SITE}
X
Xecho ""
Xecho "Checking for memory.h functions..."
Xif ${CC} -o ymemory ymemory.c 1>/dev/null 2>&1 ; then
X  echo "#define MEMORY"
X  echo "/*efine MYMEMCPY*/"
X  echo "/*efine MYMEMCHR*/"
X  echo "/*efine MYMEMSET*/"
X  ${CC} -o ystrlen ystrlen.c
X  ${CC} -o ymemlen ymemlen.c
X  ${CC} -o ylen ylen.c
X  if ( time ./ystrlen ; time ./ymemlen ) 2>&1 | ./ylen ; then
X    echo "#define MEMSTR"
X  else
X    echo "/*efine MEMSTR*/"
X  fi
Xelse
X  echo "/*efine MEMORY*/"
X  if ${CC} -o ybcopy ybcopy.c 1>/dev/null 2>&1 ; then
X    echo "void bcopy();"
X    echo "#define MEMCPY(a,b,c) bcopy((b),(a),(c))"
X    echo "/*efine MYMEMCPY*/"
X  else
X    echo "#define MYMEMCPY"
X  fi
X  echo "#define MYMEMCHR"
X  echo "#define MYMEMSET"
X  echo "/*efine MEMSTR*/"
Xfi | tee -a ${SITE}
Xrm -f ymemory ybcopy ystrlen ymemlen ylen
X
Xecho ""
Xecho "Checking for string.h functions..."
Xif ${CPP} <ystring.c 1>/dev/null 2>&1 ; then
X  echo "#define STRING"
Xelse
X  echo "/*efine STRING*/"
X  if ${CPP} <ystrings.c 1>/dev/null 2>&1 ; then
X    echo "#include <strings.h>"
X  fi
Xfi | tee -a ${SITE}
Xrm -f ystring
X
Xecho ""
Xecho "Checking for careless tolower..."
X${CC} -o ylower ylower.c
Xif ./ylower ; then
X  if ${CPP} <ylower.c | grep -s '[^a-z_]tolower' ; then :
X  else echo "int tolower();"
X  fi
X  echo "#define TOLOWER tolower"
Xelse
X  echo "#define TOLOWER(c) (isupper((c)) ? tolower((c)) : (c))"
Xfi | tee -a ${SITE}
Xrm -f ylower
X
Xecho ""
Xecho "Checking for 3 argument opens..."
Xif ${CC} -o yopen yopen.c ; then
X  echo "#define OPEN3"
Xelse
X  echo "/*efine OPEN3*/"
Xfi | tee -a ${SITE}
Xrm -f yopen
X
Xecho ""
Xecho "Checking for rename function..."
Xif ${CC} -o yrename yrename.c ; then
X  echo "#define RENAME"
Xelse
X  echo "/*efine RENAME*/"
Xfi | tee -a ${SITE}
Xrm -f yrename
X
Xecho ""
Xecho "Emitting defaults..."
Xif : ; then
X  echo "#define SYSTYPES"
Xfi | tee -a ${SITE}
X
Xecho ""
Xecho "Checking sys/types.h and time.h for Posix typedefs..."
Xif ${CPP} <ytypes.c 2>/dev/null >ytypes ; then
X  if grep -s off_t ytypes ; then :
X  else echo "typedef long off_t;		/* best guess */"
X  fi
X  if grep -s pid_t ytypes ; then :
X  else echo "typedef int pid_t;			/* best guess */"
X  fi
X  if grep -s uid_t ytypes ; then :
X  else echo "typedef int uid_t;			/* best guess */"
X  fi
X  if grep -s time_t ytypes ; then :
X  else
X    if ${CPP} <ytime.c 2>/dev/null | grep -s time_t 2>/dev/null ; then
X      echo "#define TIME"
X    else
X      echo "/*efine TIME*/"
X      echo "typedef long time_t;		/* best guess */"
X    fi
X  fi
X  if grep -s mode_t ytypes ; then :
X  else echo "typedef int mode_t;		/* best guess */"
X  fi
X  echo "#define _SIZE_T			/* redefinition in stdio.h */"
X  if grep -s size_t ytypes ; then :
X  else echo "typedef unsigned int size_t;	/* best guess */"
X  fi
Xfi | tee -a ${SITE}
Xrm -f ytypes
X
X
Xexit 0
END_OF_FILE
if test 5461 -ne `wc -c <'yinstall.sh'`; then
    echo shar: \"'yinstall.sh'\" unpacked with wrong size!
fi
# end of 'yinstall.sh'
fi
echo shar: End of archive 4 \(of 6\).
cp /dev/null ark4isdone
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