#ifndef _STDIO_H
#define _STDIO_H

/*			s t d i o
 *
 *		Author: C. E. Chew
 *		Date:   August 1989
 *
 * (C) Copyright C E Chew
 *
 * Feel free to copy, use and distribute this software provided:
 *
 *	1. you do not pretend that you wrote it
 *	2. you leave this copyright notice intact.
 *
 * Definitions and user interface for the stream io package.
 *
 * Patchlevel 2.1
 */

/* Site specific definitions */
/*@*/
#define _STDIO_VA_LIST_		char *
#define _STDIO_SIZE_T_		unsigned long	  /* type returned by sizeof */
#define _STDIO_USIZE_T_		size_t
/*=*/

/* Definitions based on ANSI compiler */
#ifdef		__STDC__
# ifndef	_STDIO_P_
#   define	_STDIO_P_(x)		x
# endif
# ifndef	_STDIO_VA_
#   define	_STDIO_VA_		, ...
# endif
# ifndef	_STDIO_UCHAR_
#   define	_STDIO_UCHAR_		0
# endif
#else
# ifndef	_STDIO_P_
#   define	_STDIO_P_(x)		()
# endif
# ifndef	_STDIO_VA_
#   define	_STDIO_VA_
# endif
# ifndef	_STDIO_UCHAR_
#   define	_STDIO_UCHAR_		(0xff)
# endif
#endif

#ifndef		_STDIO_VA_LIST_
#  define	_STDIO_VA_LIST_		void *
#endif

#ifndef		_STDIO_SIZE_T_
#  define	_STDIO_SIZE_T_		unsigned int
#endif

#ifndef		_STDIO_USIZE_T_
#  define	_STDIO_USIZE_T_		unsigned int
#endif

/* ANSI Definitions */
#define BUFSIZ 1024			/* default buffer size */

#ifndef	NULL
# define NULL		((void *) 0)	/* null pointer */
#endif

#define EOF		(-1)		/* eof flag */
#define FOPEN_MAX	16		/* minimum guarantee */
#define FILENAME_MAX	127		/* maximum length of file name */

#define SEEK_SET	0		/* seek from beginning */
#define SEEK_CUR	1		/* seek from here */
#define SEEK_END	2		/* seek from end */

#ifndef TMP_MAX
#define TMP_MAX		(0xffff)	/* maximum number of temporaries */
#endif

#define L_tmpnam	(5 + 8 + 4 + 1 + 1) /* length of temporary file name */

#ifndef _FPOS_T
# define _FPOS_T
  typedef long fpos_t;			/* stream positioning */
#endif

#ifndef	_SIZE_T
# define _SIZE_T
  typedef _STDIO_SIZE_T_ size_t;	/* sizeof type */
#endif

#define _IOFBF		000000		/* fully buffered io */
#define _IOREAD		000001		/* opened for reading */
#define _IOWRITE	000002		/* opened for writing */
#define _IONBF		000004		/* unbuffered */
#define _IOMYBUF	000010		/* allocated buffer */
#define _IOPOOLBUF	000020		/* buffer belongs to pool */
#define _IOEOF		000040		/* eof encountered */
#define _IOERR		000100		/* error encountered */
#define _IOSTRING	000200		/* strings */
#define _IOLBF		000400		/* line buffered */
#define _IORW		001000		/* opened for reading and writing */
#define _IOAPPEND	002000		/* append mode */
#define _IOINSERT	004000		/* insert into __iop chain */
#define _IOSTDX		030000		/* standard stream */
#define _IOTTY		040000		/* stream attached to tty */

#define _IOSTDIN	010000		/* stdin indication */
#define _IOSTDOUT	020000		/* stdout indication */
#define _IOSTDERR	030000		/* stderr indication */

#define _IORETAIN	(_IOSTDX | _IOINSERT)	/* flags to be retained */

/* Implementation Definitions */

typedef char __stdiobuf_t;		/* stdio buffer type */
typedef _STDIO_USIZE_T_ __stdiosize_t;	/* unsigned size_t */

typedef struct __iobuf {
  __stdiobuf_t *__rptr;			/* pointer into read buffer */
  __stdiobuf_t *__rend;			/* point at end of read buffer */
  __stdiobuf_t *__wptr;			/* pointer into write buffer */
  __stdiobuf_t *__wend;			/* point at end of write buffer */
  __stdiobuf_t *__base;			/* base of buffer */
  __stdiosize_t __bufsiz;		/* size of buffer */
  short __flag;				/* flags */
  char __file;				/* channel number */
  __stdiobuf_t __buf;			/* small buffer */
  int (*__filbuf) _STDIO_P_((struct __iobuf *));      /* fill input buffer */
  int (*__flsbuf) _STDIO_P_((int, struct __iobuf *)); /* flush output buffer */
  int (*__flush) _STDIO_P_((struct __iobuf *));	/* flush buffer */
  struct __iobuf *__next;		/* next in chain */
} FILE;

extern FILE __stdin;			/* stdin */
extern FILE __stdout;			/* stdout */
extern FILE __stderr;			/* stderr */

#define stdin		(&__stdin)
#define stdout		(&__stdout)
#define stderr		(&__stderr)

/* ANSI Stdio Requirements */

#ifdef	__GNUC__
static __inline int _STDIO_GETC_(FILE *fp)
{
  char *rptr = fp->__rptr;
  int c;

  if (rptr >= fp->__rend)
   c = (*fp->__filbuf)(fp);
  else {
    c = (unsigned char) *rptr++;
    fp->__rptr = rptr;
  }
  return c;
}
#else
#if	_STDIO_UCHAR_
# define _STDIO_GETC_(p)	((p)->__rptr>=(p)->__rend\
			         ?(*(p)->__filbuf)(p)\
			         :(int)(*(p)->__rptr++&_STDIO_UCHAR_))
#else
# define _STDIO_GETC_(p)	((p)->__rptr>=(p)->__rend\
			         ?(*(p)->__filbuf)(p)\
			         :(int)((unsigned char)(*(p)->__rptr++)))
#endif
#endif
int	getc		_STDIO_P_((FILE *));
#define getc(p)		_STDIO_GETC_(p)

int	getchar		_STDIO_P_((void));
#define getchar()	getc(stdin)

#ifdef	__GNUC__
static __inline int _STDIO_PUTC_(int x, FILE *fp)
{
  char *wptr = fp->__wptr;
  int c;

  if (wptr >= fp->__wend)
    c = (*fp->__flsbuf)(x, fp);
  else {
    *wptr++ = x;
    fp->__wptr = wptr;
    c = (unsigned char) x;
  }
  return c;
}
#else
#if	_STDIO_UCHAR_
# define _STDIO_PUTC_(x,p)	((p)->__wptr>=(p)->__wend\
                                 ?(*(p)->__flsbuf)((x),(p))\
                                 :(int)(*(p)->__wptr++=(x)&_STDIO_UCHAR_))
#else
# define _STDIO_PUTC_(x,p)	((p)->__wptr>=(p)->__wend\
                                 ?(*(p)->__flsbuf)((x),(p))\
	                         :(int)((unsigned char)(*(p)->__wptr++=(x))))
#endif
#endif
int	putc		_STDIO_P_((int, FILE *));
#define putc(x,p)	_STDIO_PUTC_(x,p)

int	putchar		_STDIO_P_((int));
#define	putchar(x)	putc(x,stdout)

#define _STDIO_FEOF_(p)		(((p)->__flag&_IOEOF)!=0)
int	feof		_STDIO_P_((FILE *));
#define feof(p)		_STDIO_FEOF_(p)

#define _STDIO_FERROR_(p)	(((p)->__flag&_IOERR)!=0)
int	ferror		_STDIO_P_((FILE *));
#define ferror(p)	_STDIO_FERROR_(p)

#define _STDIO_CLEARERR_(p)	((p)->__flag&=~(_IOEOF|_IOERR))
void	clearerr	_STDIO_P_((FILE *));
#define clearerr(p)	_STDIO_CLEARERR_(p)

FILE 	*fopen		_STDIO_P_((const char *, const char *));
FILE	*freopen	_STDIO_P_((const char *, const char *, FILE *));
int	fflush		_STDIO_P_((FILE *));
int	fclose		_STDIO_P_((FILE *));

int	fgetpos		_STDIO_P_((FILE *, fpos_t *));
int	fsetpos		_STDIO_P_((FILE *, const fpos_t *));
long	ftell		_STDIO_P_((FILE *));
int	fseek		_STDIO_P_((FILE *, long, int));
void	rewind		_STDIO_P_((FILE *));

int	fgetc		_STDIO_P_((FILE *));
int	fputc		_STDIO_P_((int, FILE *));
__stdiosize_t	fread	_STDIO_P_((void *, __stdiosize_t,
				   __stdiosize_t, FILE *));
__stdiosize_t	fwrite	_STDIO_P_((const void *, __stdiosize_t,
				   __stdiosize_t, FILE *));

int	getw		_STDIO_P_((FILE *));
int	putw		_STDIO_P_((int, FILE *));
char	*gets		_STDIO_P_((char *));
char	*fgets		_STDIO_P_((char *, int, FILE *));
int	puts		_STDIO_P_((const char *));
int	fputs		_STDIO_P_((const char *, FILE *));

int	ungetc		_STDIO_P_((int, FILE *));

int	printf		_STDIO_P_((const char * _STDIO_VA_));
int	fprintf		_STDIO_P_((FILE *, const char * _STDIO_VA_));
int	sprintf		_STDIO_P_((char *, const char * _STDIO_VA_));
int	vprintf		_STDIO_P_((const char *, _STDIO_VA_LIST_));
int	vfprintf	_STDIO_P_((FILE *, const char *, _STDIO_VA_LIST_));
int	vsprintf	_STDIO_P_((char *, const char *, _STDIO_VA_LIST_));
int	scanf		_STDIO_P_((const char * _STDIO_VA_));
int	fscanf		_STDIO_P_((FILE *, const char * _STDIO_VA_));
int	sscanf		_STDIO_P_((const char *, const char * _STDIO_VA_));

void	setbuf		_STDIO_P_((FILE *, char *));
int	setvbuf		_STDIO_P_((FILE *, char *, int, __stdiosize_t));

int	rename		_STDIO_P_((const char *, const char *));
int	remove		_STDIO_P_((const char *));

void	perror		_STDIO_P_((const char *));

char *	tmpnam		_STDIO_P_((char *));
FILE *	tmpfile		_STDIO_P_((void));

/* Posix Definitions */
#ifdef	_POSIX_SOURCE
# undef		_STDIO_POSIX_
# define	_STDIO_POSIX_
#endif
#if	_POSIX_1_SOURCE > 0
# undef		_STDIO_POSIX_
# define	_STDIO_POSIX_
#endif

#ifdef QDOS
# undef		_STDIO_POSIX_
# define	_STDIO_POSIX_
#endif


#ifdef	_STDIO_POSIX_
#ifndef QDOS
# define P_tmpdir "/tmp/"
#else
# define P_tmpdir "ram1_"
#endif
# define L_ctermid		9
  char * ctermid		_STDIO_P_((char *s));

# define L_cuserid		9
  char * cuserid		_STDIO_P_((char *s));

  FILE * fdopen			_STDIO_P_((int, const char *));

# define _STDIO_FILENO_(p)	((p)->__file)
  int    fileno			_STDIO_P_((FILE *));
# define fileno(p)		_STDIO_FILENO_(p)
#endif

#ifdef QDOS
/*
 *  The following additions are for UNIX compatibility
 */
int  pclose     _STDIO_P_((FILE *));
FILE *popen     _STDIO_P_((const char *, const char *));
/*
 *  The following additions are for Lattice compatibility
 */
#define clrerr  clearerr
FILE *fopene    _STDIO_P_((const char *, const char *, int));
int   getch     _STDIO_P_((void));
int   getche    _STDIO_P_((void));
int   kbhit     _STDIO_P_((void));
int   putch     _STDIO_P_((int));
int   ungetch   _STDIO_P_((int));
void  setnbf    _STDIO_P_((FILE *));
/*
 *  The following are additions specially for QDOS
 */
long fgetchid   _STDIO_P_((FILE *));
FILE *fusechid  _STDIO_P_((long));
#endif /* QDOS

/* Namespace Conservation */
#undef	_STDIO_POSIX_
#undef	_STDIO_P_
#undef	_STDIO_VA_
#undef	_STDIO_VA_LIST_
/*ndef	_STDIO_UCHAR_*/
#undef	_STDIO_SIZE_T_
#undef	_STDIO_USIZE_T_
#endif

