/* sys/moddef.h (emx+gcc) */

#if !defined (_SYS_MODDEF_H)
#define _SYS_MODDEF_H

#if defined (__cplusplus)
extern "C" {
#endif

struct _md;

#define _MDT_DEFAULT            0
#define _MDT_WINDOWAPI          1
#define _MDT_WINDOWCOMPAT       2
#define _MDT_NOTWINDOWCOMPAT    3

#define _MDIT_DEFAULT           0
#define _MDIT_INSTANCE          1
#define _MDIT_GLOBAL            2

#define _MDS_ALIAS              0x000001
#define _MDS_CONFORMING         0x000002
#define _MDS_DISCARDABLE        0x000004
#define _MDS_EXECUTEONLY        0x000008
#define _MDS_EXECUTEREAD        0x000010
#define _MDS_FIXED              0x000020
#define _MDS_INVALID            0x000040
#define _MDS_IOPL               0x000080
#define _MDS_LOADONCALL         0x000100
#define _MDS_MIXED1632          0x000200
#define _MDS_MOVEABLE           0x000400
#define _MDS_MULTIPLE           0x000800
#define _MDS_NOIOPL             0x001000
#define _MDS_NONCONFORMING      0x002000
#define _MDS_NONDISCARDABLE     0x004000
#define _MDS_NONE               0x008000
#define _MDS_NONSHARED          0x010000
#define _MDS_PRELOAD            0x020000
#define _MDS_READONLY           0x040000
#define _MDS_READWRITE          0x080000
#define _MDS_SHARED             0x100000
#define _MDS_SINGLE             0x200000

#define _MDX_DEFAULT            0
#define _MDX_UNKNOWN            1
#define _MDX_OS2                2
#define _MDX_WINDOWS            3

#define _MDEP_ORDINAL           0x0001
#define _MDEP_RESIDENTNAME      0x0002
#define _MDEP_NONAME            0x0004
#define _MDEP_NODATA            0x0008
#define _MDEP_PWORDS            0x0010

#define _MDIP_ORDINAL           0x0001

typedef enum
{
  _MD_ALIAS, _MD_BASE, _MD_CLASS, _MD_CODE, _MD_CONFORMING,
  _MD_CONTIGUOUS, _MD_DATA, _MD_DESCRIPTION, _MD_DEV386, _MD_DEVICE,
  _MD_DISCARDABLE, _MD_DOS4, _MD_DYNAMIC, _MD_EXECUTEONLY,
  _MD_EXECUTEREAD, _MD_EXETYPE, _MD_EXPANDDOWN, _MD_EXPORTS,
  _MD_FIXED, _MD_HEAPSIZE, _MD_HUGE, _MD_IMPORTS, _MD_IMPURE,
  _MD_INCLUDE, _MD_INITGLOBAL, _MD_INITINSTANCE, _MD_INVALID,
  _MD_IOPL, _MD_LIBRARY, _MD_LOADONCALL, _MD_MAXVAL, _MD_MIXED1632,
  _MD_MOVEABLE, _MD_MULTIPLE, _MD_NAME, _MD_NEWFILES, _MD_NODATA,
  _MD_NOEXPANDDOWN, _MD_NOIOPL, _MD_NONAME, _MD_NONCONFORMING,
  _MD_NONDISCARDABLE, _MD_NONE, _MD_NONPERMANENT, _MD_NONSHARED,
  _MD_NOTWINDOWCOMPAT, _MD_OBJECTS, _MD_OLD, _MD_ORDER, _MD_OS2,
  _MD_PERMANENT, _MD_PHYSICAL, _MD_PRELOAD, _MD_PRIVATE,
  _MD_PRIVATELIB, _MD_PROTECT, _MD_PROTMODE, _MD_PURE, _MD_READONLY,
  _MD_READWRITE, _MD_REALMODE, _MD_RESIDENT, _MD_RESIDENTNAME,
  _MD_SEGMENTS, _MD_SHARED, _MD_SINGLE, _MD_STACKSIZE, _MD_STUB,
  _MD_SWAPPABLE, _MD_TERMGLOBAL, _MD_TERMINSTANCE, _MD_UNKNOWN,
  _MD_VIRTUAL, _MD_WINDOWAPI, _MD_WINDOWCOMPAT, _MD_WINDOWS,
  /* The following tokens are no keywords: */
  _MD_dot, _MD_at, _MD_equal, _MD_quote, _MD_number, _MD_word,
  _MD_eof, _MD_ioerror, _MD_missingquote,
  /* Special `token' for _md_parse() callback: */
  _MD_parseerror
} _md_token;

typedef enum
{
  _MDE_IO_ERROR,
  _MDE_MISSING_QUOTE,
  _MDE_EMPTY,
  _MDE_NAME_EXPECTED,
  _MDE_STRING_EXPECTED,
  _MDE_NUMBER_EXPECTED,
  _MDE_DEVICE_EXPECTED,
  _MDE_EQUAL_EXPECTED,
  _MDE_DOT_EXPECTED,
  _MDE_STRING_TOO_LONG,
  _MDE_INVALID_ORDINAL,
  _MDE_INVALID_STMT
} _md_error;

typedef union
{
  struct
    {
      _md_error code;
      _md_token stmt;
    } error;                    /* Error */
  struct
    {
      unsigned long addr;
    } base;                     /* BASE */
  struct
    {
      char string[256];
    } descr;                    /* DESCRIPTION */
  struct
    {
      char name[256];
    } device;                   /* PHYSICAL DEVICE and VIRTUAL DEVICE */
  struct
    {
      int type;
      int minor_version;
      int major_version;
    } exetype;                  /* EXETYPE */
  struct
    {
      char entryname[256];
      char internalname[256];
      int ordinal;
      int pwords;
      unsigned flags;
    } export;                   /* EXPORTS */
  struct
    {
      char entryname[256];
      char internalname[256];
      char modulename[256];
      int ordinal;
      unsigned flags;
    } import;                   /* IMPORTS */
  struct
    {
      unsigned long size;
      int maxval;
    } heapsize;                 /* HEAPSIZE */
  struct
    {
      char name[256];
      int init;
      int term;
    } library;                  /* LIBRARY */
  struct
    {
      char name[256];
      int pmtype;
      int newfiles;
    } name;                     /* NAME */
  struct
    {
      char name[256];
    } old;                      /* OLD */
  struct
    {
      char segname[256];
      char classname[256];
      unsigned attr;
    } segment;                  /* SEGMENTS, CODE, DATA */
  struct
    {
      unsigned long size;
    } stacksize;                /* STACKSIZE */
  struct
    {
      char name[256];
      int none;
    } stub;                     /* STUB */
} _md_stmt;


long _md_get_linenumber (const struct _md *md);
long _md_get_number (const struct _md *md);
const char *_md_get_string (const struct _md *md);
_md_token _md_get_token (const struct _md *md);

_md_token _md_next_token (struct _md *md);

int _md_close (struct _md *md);
struct _md *_md_open (const char *fname);
struct _md *_md_use_file (FILE *f);

int _md_parse (struct _md *md,
               int (*callback)(struct _md *md, const _md_stmt *stmt,
                               _md_token token, void *arg),
               void *arg);

const char *_md_errmsg (_md_error code);

#if defined (__cplusplus)
}
#endif

#endif /* !defined (_SYS_MODDEF_H) */
