/* <stdio.h>
 *
 *	This defines a DEC C compatible standard I/O interface.
 */
#ifndef _STDIO_H
# define _STDIO_H
# ifdef __cplusplus
extern "C" {
# endif

#if defined(__STDC__) && !defined(_STDDEF_H)
# include <stddef.h>	/* get size_t, NULL */
#endif

/*
 *	The maximum number of files we can have open at a time
 *	(not really; blocks of this many are chained together by vaxcrtl)
 */
#define _NFILE 20

/*
 *	STDIO buffer size
 */

#define BUFSIZ 32768

/*
 *	Arguments to setvbuf()
 */
#define _IOLBF 1	/* line buffered */
#define _IOFBF 2	/* fully buffered */
/* #def _IONBF 4 */	/* unbuffered (really defined below) */

/*
 *	This is what the DEC C stdio FILE structure looks like
 */
struct	_iobuf	{
	int	_cnt;			/* # of characters in the buffer */
	char	*_ptr;			/* Pointer into the buffer	 */
	char	*_base;			/* Pointer to start of buffer	 */
	unsigned char	_flag;			/* STDIO flags			 */
#define _IOREAD		0001			/* Open for reading	 */
#define _IOWRT		0002			/* Open for writing	 */
#define _IONBF		0004			/* No buffer		 */
#define _IOMYBUF	0010			/* Using "my" buffer	 */
#define _IOEOF		0020			/* At End Of File	 */
#define _IOERR		0040			/* I/O error has occured */
#define _IOSTRG		0100			/* Doing I/O to a string */
#define _IORW		0200			/* Open for read/write	 */
	unsigned char	_file;			/* File descriptor		 */
	unsigned char	_pad1;
	unsigned char	_pad2;
};

/*
 *	Instead of passing around pointers to _iobuf structures, VAXCRTL
 *	passes around pointers to pointers.
 */
typedef struct _iobuf *FILE;

/*
 *	Cookie used by fgetpos() and fsetpos() [alternatives to ftell/fseek]
 *	Internally, it's a 6-byte RFA plus a 2-byte offset within record.
 */
typedef struct _FPOS_T { unsigned : 32, : 32; } fpos_t;

/*
 *	Also, stdin/stdout/stderr need to be defined
 */
#define stdin	(decc$ga_stdin)
#define stdout	(decc$ga_stdout)
#define stderr	(decc$ga_stderr)
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;

/*
 *	Define NULL and EOF
 */
#ifndef __STDC__	/* got it from <stddef.h> if __STDC__ */
# define NULL 0
#endif
#define EOF	(-1)

#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_EOF SEEK_END	/* VAX C compatability */

#define FOPEN_MAX 8	/* minimum number simultaneously open files */
#define OPEN_MAX  8	/* ditto (note: minimum _guaranteed_; more possible) */
#define TMP_MAX  32	/* minimum number of unique names tmpnam() gives */
#define FILENAME_MAX 256 /* longest filename */

/*
 *	Buffer sizes for various return values
 */
#define L_ctermid	64	/* size of device name */
#define L_cuserid	16	/* size of user name */
#define L_tmpnam	256	/* size of file name */
#define L_lcltmpnam	256	/* size of file local name */
#define L_nettmpnam	256	/* size of file network name */

/*
 *	Define the stdio macros; note that getc and putc are function calls.
 */

int	decc$getchar(void);
int	decc$putchar(int c);

#define getc decc$getc
int	getc(FILE *fp);


#define getchar() \
	((*stdin) ? \
	(((((*stdin)->_cnt > 0) & !((*stdin)->_flag & 0x40)) ? \
	( (*stdin)->_cnt--, \
	((int) ((unsigned char) *((*stdin)->_ptr++)))) : \
	decc$getchar())) : \
	decc$getchar())   

#define putc(x, fp)	fputc((x), fp)
#define putchar(x)	fputc((x), stdout)

#define feof(fp)	(((*fp)->_flag & _IOEOF)!=0)
#define ferror(fp)	(((*fp)->_flag & _IOERR)!=0)
#define fileno(fp)	((*fp)->_file)
#define clearerr(fp)	((*fp)->_flag &= ~(_IOERR|_IOEOF))

/* DEC C compatibility, prototypes in unixio.h */
#define open decc$open
#define close decc$close
#define read decc$read
#define write decc$write
#define decc$record_read(fp, buf, max_size) decc$read(fileno(fp), (buf), (max_size))
#define decc$record_write(fp, buf, size) fwrite((buf), (size), 1, (fp))

# define ___gdecl(_func, _arglist) _func _arglist

/*
 *	Declare stdio routines
 */
#ifdef __STDC__

#define fclose decc$fclose
#define fgets decc$fgets
#define fopen decc$fopen
#define fputc decc$fputc
#define fputs decc$fputs
#define fread decc$fread
#define fwrite decc$fwrite
#define freopen decc$freopen
#define fdopen decc$fdopen

/* access */
FILE	*fopen(const char *name, const char *mode, ...);
FILE	*fdopen(int file_desc, const char *mode);
FILE	*freopen(const char *name, const char *mode, FILE *stream, ...);
#define fflush(x) decc$fflush(x)
int	 fflush(FILE *stream);
int	 fclose(FILE *stream);

/* unformatted input/output */
int	 fgetc(FILE *file_ptr);
int decc$fgetc  (FILE *__stream);
#define fgetc(fp) \
	((*fp) ? \
	(((((*fp)->_cnt > 0) & !((*fp)->_flag & 0x40)) ? \
	( (*fp)->_cnt--, \
	((int) ((unsigned char) *((*fp)->_ptr++)))) : \
	decc$fgetc(fp))) : \
	decc$fgetc(fp))

#define ungetc decc$ungetc
#define fputc decc$fputc
int	 ungetc(int c, FILE *stream);
int	 fputc(int, FILE *stream);
int	 getw(FILE *streamfile_ptr);
int	 putw(int, FILE *stream);
char	*gets(char *);
int	 puts(const char *);
char	*fgets(char *, int, FILE *stream);
int	 fputs(const char *, FILE *stream);
size_t	 fread(void *, size_t, size_t, FILE *stream);
size_t	 fwrite(const void *, size_t, size_t, FILE *stream);

#if __IEEE_FLOAT
#define printf decc$txprintf
#define fprintf decc$txfprintf
#define sprintf decc$txsprintf
#define fscanf decc$txfscanf
#define sscanf decc$txsscanf
#define scanf decc$txscanf
#endif
#if __G_FLOAT
#define printf decc$gxprintf
#define fprintf decc$gxfprintf
#define sprintf decc$gxsprintf
#define fscanf decc$gxfscanf
#define sscanf decc$gxsscanf
#define scanf decc$gxscanf
#endif

/* formatted input/output */
/*#include <stdarg.h>*/
/*# define ___va_list_t va_list*/
#include <va-alpha.h>
# define ___va_list_t __gnuc_va_list
int  ___gdecl(scanf, 	(const char *, ...));
int  ___gdecl(printf, 	(const char *, ...));
int  ___gdecl(vprintf, 	(const char *, ___va_list_t));
int  ___gdecl(fscanf, 	(FILE *stream, const char *, ...));
int  ___gdecl(fprintf, 	(FILE *stream, const char *, ...));
int  ___gdecl(vfprintf, (FILE *stream, const char *, ___va_list_t));
int  ___gdecl(sscanf, 	(const char *, const char *, ...));
int  ___gdecl(sprintf, 	(char *, const char *, ...));
int  ___gdecl(vsprintf, (char *, const char *, ___va_list_t));
# undef ___va_list_t

/* positioning */
#define fseek decc$fseek
#define ftell decc$ftell
#define rewind decc$rewind
int	 fseek(FILE *stream, long, int);
long	 ftell(FILE *stream);
int	 fsetpos(FILE *stream, const fpos_t *);
int	 fgetpos(FILE *stream, fpos_t *);
int	 rewind(FILE *stream);

/* miscellaneous */
#define perror decc$perror
#define remove decc$remove
#define tmpnam decc$tmpnam

void	 perror(const char *);
int	 remove(const char *);
void	 setbuf(FILE *stream, char *);
int	 setvbuf(FILE *stream, char *, int, size_t);
char	*fgetname(FILE *stream, char *, ...); /* optional arg is VMS vs shell name format */
char	*tmpnam(char *);
FILE	*tmpfile(void);

#else	/*!__STDC__ => -traditional */

FILE	*fopen(), *fdopen(), *freopen();
int	 fflush(), fclose();
int	 fgetc(), ungetc(), fputc(), getw(), putw(), puts(), fputs();
char	*gets(), *fgets();
unsigned fread(), fwrite();
int	___gdecl(scanf, ());
int	___gdecl(printf, ());
int	___gdecl(vprintf, ());
int	___gdecl(fscanf, ());
int	___gdecl(fprintf, ());
int	___gdecl(vfprintf, ());
int	___gdecl(sscanf, ());
int	___gdecl(sprintf, ());
int	___gdecl(vsprintf, ());
long	 ftell();
int	 fseek(), fgetpos(), fsetpos(), rewind();
void	 perror(), setbuf();
int	 remove();
int	 setvbuf();
char	*fgetname(), *tmpnam();
FILE	*tmpfile();

#endif	/*?__STDC__*/

#undef ___gdecl		/*__GFLOAT__*/

# ifdef __cplusplus
}
# endif

#endif	/*_STDIO_H*/
