/*
  libc-style File I/O Routines for Quake III: Arena
  Copyright 2001  PhaethonH <phaethon@linux.ucla.edu>

  Permission granted to copy, modify, distribute, or otherwise use this code,
  provided this copyright notice remains intact
*/

/* Last revision 2002.03.09 */


#ifndef _PH_FILEIO_H_
#define _PH_FILEIO_H_


enum {
  MAX_FILES = 40,
  FILE_ACTIVE =   0x00000001,
  FILE_BUFFED =   0x00000002,
  FILE_READ =     0x00000004,
  FILE_WRITE =    0x00000008,
  FILE_BINARY =   0x00000010,  /* Explicit binary mode. */
  FILE_ERROR =    0x00000020,  /* Error condition exists. */

  SEEK_SET = 0,
  SEEK_CUR = 1,
  SEEK_END = 2,

  EOL_UNKNOWN = 0, /* textfile line terminator style. */
  EOL_UNIX,  /* Un*x-style (LF) */
  EOL_CPM, /* CPM-style (CRLF) */
  EOL_MAC, /* MacOS-style (CR) */

  ENONE = 0,
  ENAMETOOLONG,
  EFAULT,
  EMFILE,
  ENFILE,
  EACCESS,
  EBADF,
  EINVAL,
  sys_nerr,
};



/* According to the BSD manpage for stdio(3), the following are implemented as macros: */
#define EOF (-1)
#define BUFSIZ 1024
#define FILENAME_MAX 144
//#define FILENAME_MAX MAX_FILEPATH
#define FOPEN_MAX 40

#define L_cuserid    0
#define L_ctermid    0
#define L_tmpnam    10   /* Length of filenames created by tmpnam. */
//#define NULL (0)
//#define SEEK_END
//#define SEEK_SET
//#define fwopen  ---  WTF???
#define stdin   (&(_qfiles[0]))
#define stdout  (&(_qfiles[1]))
#define stderr  (&(_qfiles[2]))
#define getc(stream)     (fgetc(stream))
#define getchar          (fgetc(stdin))
#define putc(c, stream)  (fputc(c, stream))
#define putchar(c)       (fputc(c, stdout))

/* The following macro functions shadow real functions, and can be #undef'd to invoke the real function (or so says the manpage):
  feof
  ferror
  clearerr
  fileno
  getc
  getchar
  putc
  putchar
*/








/****************************
** Global variable  errno   **
 ****************************/

extern int errno;
extern char *sys_errlist[sys_nerr];



struct qfile_s {
  int flags;   /* Various and sundry bitmasks. */
  int fd;      /* QVM file descriptor number. */
  long len;    /* Filesize, to check for EOF condition. */
  long pos;    /* Position into file, to check for EOF condition. */
  int buf;     /* unget/peek buffer. */
  int eol;     /* End-Of-Line style. */
  int eolcheck; /* Last EOL-looking character for auto-detect. */
  char *buffer; /* block/line buffering buffer. */
  char name[FILENAME_MAX];
};

typedef struct qfile_s FILE;

extern FILE _qfiles[FOPEN_MAX];



/*** CHAOS - Construct, Destruct ***/

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



/*** CLOTHO - Data In ***/

size_t fread (void *, size_t, size_t, FILE *);
int fgetc (FILE *);
int ungetc (int, FILE *);
char * fgets (char *, int, FILE *);



/*** ATROPOS - Data Out ***/

int fputc (int, FILE *);
size_t fwrite (const void *, size_t, size_t, FILE *);
int fputs (const char *, FILE *);
int fflush (FILE *);
int fprintf (FILE *, const char *, ...);
int printf (const char *, ...);



/*** CHARON - Traveling the stream ***/

long ftell (FILE *);
int fseek (FILE *, long, int);
int rewind (FILE *);



/*** LACHESIS - file status ***/

int feof (FILE *);
int fileno (FILE *);
int ferror (FILE *);
void clearerr (FILE *);



/*** IRIS - messages ***/

char * strerror (int);
void perror (const char *);
int sprint (char *, const char *, ...);


#endif /* _PH_FILEIO_H_ */
