/* sys/emx.h (emx+gcc) */

/* Must be included before any other head files */

#if defined (__cplusplus)
extern "C" {
#endif

#define FALSE 0
#define TRUE  1

extern __const__ int _nfiles;
extern char ** _org_environ;

#define _SIZE_T
typedef unsigned long size_t;

struct stat;
struct timeval;
struct timeb;
struct _fd_set;
struct _FILE;

#define _TM
struct tm
{
  int tm_sec;     /* 0..59 */
  int tm_min;     /* 0..59 */
  int tm_hour;    /* 0..23 */
  int tm_mday;    /* 1..31 */
  int tm_mon;     /* 0..11 */
  int tm_year;    /* 0(:=1900).. */
  int tm_wday;    /* 0..6 */
  int tm_yday;    /* 0..365 */
  int tm_isdst;   /* 0 */
};

struct _new_proc
{
  unsigned long  arg_off;
  unsigned long  env_off;
  unsigned long  fname_off;
  unsigned short arg_sel;
  unsigned short env_sel;
  unsigned short fname_sel;
  unsigned short arg_count;
  unsigned short arg_size;
  unsigned short env_count;
  unsigned short env_size;
  unsigned short mode;
};

struct _find
{
  char           reserved[21];
  unsigned char  attr;
  unsigned short time;
  unsigned short date;
  unsigned short size_lo;         /* split due to alignment problems */
  unsigned short size_hi;
  char name[257];                 /* Big buffer for OS/2             */
};

struct _select
{
  int              nfds;
  struct _fd_set * readfds;
  struct _fd_set * writefds;
  struct _fd_set * exceptfds;
  struct timeval * timeout;
};


#if defined (_EMXLIBC_DLL)
#define _NFILES 256
#else
#define _NFILES 40
#endif

/* Low-level i/o */

/*      O_ACCMODE   0x00000003 */
/*      O_NDELAY    0x00000004 */
/*      O_APPEND    0x00000008 */
/*      O_TEXT      0x00000010 */
#define F_EOF       0x00000020
#define F_TERMIO    0x00000040
#define F_DEV       0x00000080
/*      O_BINARY    0x00000100 */
/*      O_CREAT     0x00000200 */
/*      O_TRUNC     0x00000400 */
/*      O_EXCL      0x00000800 */
#define F_NPIPE     0x00001000

/* stdio */

/*      _IOREAD     0x00000001 */
/*      _IOWRT      0x00000002 */
/*      _IORW       0x00000004 */
/*      _IOEOF      0x00000008 */
/*      _IOERR      0x00000010 */
/*      _IOLBF      0x00000020 */
/*      _IONBF      0x00000040 */
#define _IOOPEN     0x00000080
#define _IOBUFMASK  0x00000700
#define _IOBUFNONE  0x00000000
#define _IOBUFUSER  0x00000100
#define _IOBUFCHAR  0x00000200
#define _IOBUFLIB   0x00000300
#define _IOBUFTMP   0x00000400
#define _IOTMP      0x00000800
#define _IOSPECIAL  0x00001000
#define _IOREREAD   0x00002000

#define _FLUSH_FLUSH  (-1)
#define _FLUSH_READ   (-2)

/* argv[i][-1] contains some flag bits: */

#define _ARG_DQUOTE   0x01          /* Argument quoted (")                  */
#define _ARG_RESPONSE 0x02          /* Argument read from response file     */
#define _ARG_WILDCARD 0x04          /* Argument expanded from wildcard      */
#define _ARG_ENV      0x08          /* Argument from environment            */
#define _ARG_NONZERO  0x80          /* Always set, to avoid end of string   */

/* _uflags constants */

#define _UF_SIG_BENIGN 0x0001       /* Benign signal handlers               */

extern int _files[];
extern int _lookahead[];

extern void (*_atexit_v[32])(void);
extern int _atexit_n;

extern int _tzset_flag;

extern int _nls_init_flag;

#define alloca __builtin_alloca

unsigned __alarm (unsigned sec);
void *__brk (void *addr);
void __cgets (char *buffer);
int __chdir (__const__ char *name);
int __chmod (__const__ char *name, int flag, int attr);
int __chdrive (char drive);
int __chsize (int handle, long length);
long long __clock (void);
int __close (int handle);
int __core (int handle);
int __dup (int handle);
int __dup2 (int handle1, int handle2);
int __endthread (int tid);
int __execname (char *buf, size_t bufsize);
void __exit (int ret) __attribute__ ((noreturn));
int __fcntl (int handle, int request, int arg);
int __filesys (__const__ char *drive, char *name, size_t size);
int __findfirst (__const__ char *name, int attr, struct _find *fp);
int __findnext (struct _find *fp);
int __fork (void);
int __fstat (int handle, struct stat *buffer);
int __fsync (int handle);
void __ftime (struct timeb *ptr);
int __ftruncate (int handle, long length);
int __getcwd (char *buffer, char drive);
char __getdrive (void);
int __getpid (void);
int __getppid (void);
int __initthread (void *preg);
int __ioctl1 (int handle, int code);
int __ioctl2 (int handle, int request, int arg);
int __kill (int pid, int sig);
int __lseek (int handle, long offset, int origin);
void *__memaccess (unsigned first, unsigned last, int flag);
int __memavail (void);
int __mkdir (__const__ char *name);
int __newthread (int tid);
void __nls_memupr (unsigned char *buf, size_t size);
int __open (__const__ char *name, int flags);
void __pause (void);
int __pipe (int *two_handles, int pipe_size);
int __portaccess (unsigned first, unsigned last);
int __ptrace (int request, int pid, int addr, int data);
int __raise (int sig);
int __read (int handle, void *buf, size_t nbyte);
int __read_kbd (int echo, int wait, int sig);
int __remove (__const__ char *name);
int __rename (__const__ char *old_name, __const__ char *new_name);
int __rmdir (__const__ char *name);
void *__sbrk (int incr);
void __scrsize (int *dst);
int __select (struct _select *args);
void (*__signal (int sig, void (*handler)()))(int sig);
unsigned __sleep (unsigned sec);
unsigned __sleep2 (unsigned millisec);
int __spawnve (struct _new_proc *np);
int __stat (__const__ char *name, struct stat *buffer);
int __swchar (int flag, int new_char);
int __syserrno (void);
void __timezone (int distance);
int __uflags (int mask, int new_flags);
long __ulimit (int cmd, long new_limit);
int __umask (int pmode);
void __unwind2 (void *xcpt_reg_ptr);
int __utimes (__const__ char *name, __const__ struct timeval *tvp);
int __wait (int *status);
int __waitpid (int pid, int *status, int options);
int __write (int handle, __const__ void *buf, size_t nbyte);

void _cleanup (void);
int _day (int year, int month, int day);
int _endbuf1 (struct _FILE *stream);
void _fbuf (struct _FILE *stream);
struct _FILE *_fopen (struct _FILE *dst, __const__ char *fname,
    __const__ char *mode, int shmode);
int _flushstream (struct _FILE *stream, int c);
int _fxam (double x);
int _fxaml (long double x);
int _input (struct _FILE *stream, __const__ char *format, char *arg_ptr);
int _mktime (struct tm *t);
struct _FILE *_newstream (void);
int _output (struct _FILE *stream, __const__ char *format, char *arg_ptr);
int _sopen (__const__ char *name, int oflag, int shflag, char *va);
int _tmpbuf1 (struct _FILE *stream, void *buf);

#define nbuf(s) (((s)->flags & _IOBUFMASK) == _IOBUFNONE)
#define cbuf(s) (((s)->flags & _IOBUFMASK) == _IOBUFCHAR)
#define ubuf(s) (((s)->flags & _IOBUFMASK) == _IOBUFUSER)
#define lbuf(s) (((s)->flags & _IOBUFMASK) == _IOBUFLIB)
#define tbuf(s) (((s)->flags & _IOBUFMASK) == _IOBUFTMP)

#define bbuf(s) (ubuf (s) || lbuf (s) || tbuf (s))

#define _tmpbuf(s,b) (nbuf (s) || cbuf (s) \
                      ? b = alloca (BUFSIZ), _tmpbuf1 (s, b) : 0)
#define _endbuf(s) (tbuf (s) ? _endbuf1 (s) : 0)

/* Replace some bits in an lvalue */

#define SETBITS(dst,mask,newb) ((dst) = ((dst) & ~(mask)) | ((newb) & (mask)))

#define FX_P_NAN       1
#define FX_N_NAN       3
#define FX_P_NORMAL    4
#define FX_P_INFINITY  5
#define FX_N_NORMAL    6
#define FX_N_INFINITY  7
#define FX_P_ZERO      8
#define FX_P_EMPTY     9
#define FX_N_ZERO     10
#define FX_N_EMPTY    11
#define FX_P_DENORMAL 12
#define FX_N_DENORMAL 14

#define _A_NORMAL 0x00  /* No attributes */
#define _A_RDONLY 0x01  /* Read-only     */
#define _A_HIDDEN 0x02  /* Hidden        */
#define _A_SYSTEM 0x04  /* System        */
#define _A_VOLID  0x08  /* Volume label  */
#define _A_SUBDIR 0x10  /* Directory     */
#define _A_ARCH   0x20  /* Archive       */

/* Define NO_LDBL for debugging: GDB does not yet support the long
   double type. */

#if defined (NO_LDBL)
#define DOUBLE  double
#define FLOOR   floor
#define LOG10   log10
#define POW     pow
#define FXAM    _fxam
#define DIG     DBL_DIG
#else
#define DOUBLE  long double
#define FLOOR   _floorl
#define LOG10   _log10l
#define POW     _powl
#define FXAM    _fxaml
#define DIG     LDBL_DIG
#endif

int _cvt_float_decimal (DOUBLE x, char *dst);
void _cvt_round (char *dst, int *pxp, int prec, int lim);
void _cvt_remove_zeros (char *digits, int keep);
const char *_cvt_nan (int xam);


#if defined (__MT__)

struct _thread
{
  int             _th_errno;                /* comes first, cf. errnofun.s */
  void          * _th_arg;
  void          (*_th_start)(void *arg);
  unsigned char * _th_strtok_ptr;
  char            _th_asctime_buf[26+2];    /* 2 chars for padding */
  char            _th_tmpnam_buf[16];       /* cf. stdio.h */
  struct tm       _th_gmtime_buf;
  unsigned int    _th_rand;                 /* Used by rand() */
  void          * _th_store;                /* Pointer to user data */
  int             _th_reserved[998];        /* 4096 bytes, total */
};

struct _thread *_thread (void);
int _tid (void);
void _heap_lock (void);
void _heap_unlock (void);

#define HEAP_LOCK   _heap_lock()
#define HEAP_UNLOCK _heap_unlock()

#else

#define HEAP_LOCK
#define HEAP_UNLOCK

#endif /* defined (__MT__) */

#if defined (__cplusplus)
}
#endif
