/* moddef2.c (emx+gcc) -- Copyright (c) 1992-1995 by Eberhard Mattes */ #include #include #include "port.h" #include "deffile.h" #define FALSE 0 #define TRUE 1 typedef int _md_callback (struct _md *md, const _md_stmt *stmt, _md_token token, void *arg); static int error (struct _md *md, _md_callback *callback, _md_stmt *stmt, _md_token stmt_token, _md_error code, void *arg) { stmt->error.code = code; stmt->error.stmt = stmt_token; return callback (md, stmt, _MD_parseerror, arg); } static _md_token sync (struct _md *md) { _md_token token; token = _md_get_token (md); for (;;) switch (token) { case _MD_BASE: case _MD_CODE: case _MD_DATA: case _MD_DESCRIPTION: case _MD_EXETYPE: case _MD_EXPORTS: case _MD_HEAPSIZE: case _MD_IMPORTS: case _MD_OLD: case _MD_PROTMODE: case _MD_REALMODE: case _MD_SEGMENTS: case _MD_STACKSIZE: case _MD_STUB: case _MD_eof: case _MD_ioerror: case _MD_missingquote: return token; default: token = _md_next_token (md); break; } } #define ERROR(CODE) \ do { result = error (md, callback, &stmt, stmt_token, (CODE), arg); \ if (result != 0) return result; \ token = sync (md); goto next_stmt;} while (FALSE) #define CALLBACK \ do { result = callback (md, &stmt, stmt_token, arg); \ if (result != 0) return result; } while (FALSE) int _md_parse (struct _md *md, _md_callback *callback, void *arg) { _md_token token, stmt_token; _md_stmt stmt; const char *s; long n; int ok, result; token = _md_get_token (md); stmt_token = token; switch (stmt_token) { case _MD_eof: ERROR (_MDE_EMPTY); break; case _MD_NAME: token = _md_next_token (md); stmt.name.name[0] = 0; if (token == _MD_quote || token == _MD_word) { _strncpy (stmt.name.name, _md_get_string (md), sizeof (stmt.name.name)); token = _md_next_token (md); } switch (token) { case _MD_WINDOWAPI: stmt.name.pmtype = _MDT_WINDOWAPI; token = _md_next_token (md); break; case _MD_WINDOWCOMPAT: stmt.name.pmtype = _MDT_WINDOWCOMPAT; token = _md_next_token (md); break; case _MD_NOTWINDOWCOMPAT: stmt.name.pmtype = _MDT_NOTWINDOWCOMPAT; token = _md_next_token (md); break; default: stmt.name.pmtype = _MDT_DEFAULT; break; } stmt.name.newfiles = FALSE; if (token == _MD_NEWFILES) { stmt.name.newfiles = TRUE; token = _md_next_token (md); } CALLBACK; break; case _MD_LIBRARY: token = _md_next_token (md); if (token == _MD_quote || token == _MD_word) { _strncpy (stmt.library.name, _md_get_string (md), sizeof (stmt.library.name)); token = _md_next_token (md); } switch (token) { case _MD_INITGLOBAL: stmt.library.init = _MDIT_GLOBAL; token = _md_next_token (md); break; case _MD_INITINSTANCE: stmt.library.init = _MDIT_INSTANCE; token = _md_next_token (md); break; default: stmt.library.init = _MDIT_DEFAULT; break; } switch (token) { case _MD_TERMGLOBAL: stmt.library.term = _MDIT_GLOBAL; token = _md_next_token (md); break; case _MD_TERMINSTANCE: stmt.library.term = _MDIT_INSTANCE; token = _md_next_token (md); break; default: stmt.library.term = _MDIT_DEFAULT; break; } if (token == _MD_PRIVATELIB) token = _md_next_token (md); CALLBACK; break; case _MD_VIRTUAL: case _MD_PHYSICAL: token = _md_next_token (md); if (token != _MD_DEVICE) ERROR (_MDE_DEVICE_EXPECTED); token = _md_next_token (md); stmt.device.name[0] = 0; if (token == _MD_quote || token == _MD_word) { _strncpy (stmt.device.name, _md_get_string (md), sizeof (stmt.device.name)); token = _md_next_token (md); } CALLBACK; break; default: break; } next_stmt: while (token != _MD_eof) { stmt_token = token; switch (stmt_token) { case _MD_BASE: token = _md_next_token (md); if (token != _MD_equal) ERROR (_MDE_EQUAL_EXPECTED); token = _md_next_token (md); if (token != _MD_number) ERROR (_MDE_NUMBER_EXPECTED); stmt.base.addr = _md_get_number (md); token = _md_next_token (md); CALLBACK; break; case _MD_CODE: token = _md_next_token (md); stmt.segment.segname[0] = 0; stmt.segment.classname[0] = 0; stmt.segment.attr = 0; ok = TRUE; while (ok) { switch (token) { case _MD_CONFORMING: stmt.segment.attr |= _MDS_CONFORMING; break; case _MD_DISCARDABLE: stmt.segment.attr |= _MDS_DISCARDABLE; break; case _MD_EXECUTEONLY: stmt.segment.attr |= _MDS_EXECUTEONLY; break; case _MD_EXECUTEREAD: stmt.segment.attr |= _MDS_EXECUTEREAD; break; case _MD_FIXED: stmt.segment.attr |= _MDS_FIXED; break; case _MD_IOPL: stmt.segment.attr |= _MDS_IOPL; break; case _MD_LOADONCALL: stmt.segment.attr |= _MDS_LOADONCALL; break; case _MD_MOVEABLE: stmt.segment.attr |= _MDS_MOVEABLE; break; case _MD_NOIOPL: stmt.segment.attr |= _MDS_NOIOPL; break; case _MD_NONCONFORMING: stmt.segment.attr |= _MDS_NONCONFORMING; break; case _MD_NONDISCARDABLE: stmt.segment.attr |= _MDS_NONDISCARDABLE; break; case _MD_NONSHARED: case _MD_IMPURE: stmt.segment.attr |= _MDS_NONSHARED; break; case _MD_PRELOAD: stmt.segment.attr |= _MDS_PRELOAD; break; case _MD_SHARED: case _MD_PURE: stmt.segment.attr |= _MDS_SHARED; break; default: ok = FALSE; break; } if (ok) token = _md_next_token (md); } CALLBACK; break; case _MD_DATA: token = _md_next_token (md); stmt.segment.segname[0] = 0; stmt.segment.classname[0] = 0; stmt.segment.attr = 0; ok = TRUE; while (ok) { switch (token) { case _MD_FIXED: stmt.segment.attr |= _MDS_FIXED; break; case _MD_IOPL: stmt.segment.attr |= _MDS_IOPL; break; case _MD_LOADONCALL: stmt.segment.attr |= _MDS_LOADONCALL; break; case _MD_MOVEABLE: stmt.segment.attr |= _MDS_MOVEABLE; break; case _MD_MULTIPLE: stmt.segment.attr |= _MDS_MULTIPLE; break; case _MD_NOIOPL: stmt.segment.attr |= _MDS_NOIOPL; break; case _MD_NONE: stmt.segment.attr |= _MDS_NONE; break; case _MD_NONSHARED: case _MD_IMPURE: stmt.segment.attr |= _MDS_NONSHARED; break; case _MD_PRELOAD: stmt.segment.attr |= _MDS_PRELOAD; break; case _MD_READONLY: stmt.segment.attr |= _MDS_READONLY; break; case _MD_READWRITE: stmt.segment.attr |= _MDS_READWRITE; break; case _MD_SHARED: case _MD_PURE: stmt.segment.attr |= _MDS_SHARED; break; case _MD_SINGLE: stmt.segment.attr |= _MDS_SINGLE; break; default: ok = FALSE; break; } if (ok) token = _md_next_token (md); } CALLBACK; break; case _MD_DESCRIPTION: token = _md_next_token (md); if (token != _MD_quote) ERROR (_MDE_STRING_EXPECTED); s = _md_get_string (md); if (*s == 0 || strlen (s) > 255) ERROR (_MDE_STRING_TOO_LONG); _strncpy (stmt.descr.string, s, sizeof (stmt.descr.string)); token = _md_next_token (md); CALLBACK; break; case _MD_EXETYPE: token = _md_next_token (md); switch (token) { case _MD_OS2: stmt.exetype.type = _MDX_OS2; token = _md_next_token (md); break; case _MD_UNKNOWN: stmt.exetype.type = _MDX_UNKNOWN; token = _md_next_token (md); break; case _MD_WINDOWS: stmt.exetype.type = _MDX_WINDOWS; stmt.exetype.major_version = 0; stmt.exetype.minor_version = 0; token = _md_next_token (md); if (token == _MD_number) { stmt.exetype.major_version = _md_get_number (md); token = _md_next_token (md); if (token == _MD_dot) { token = _md_next_token (md); if (token == _MD_number) { stmt.exetype.minor_version = _md_get_number (md); token = _md_next_token (md); } } } break; default: stmt.exetype.type = _MDX_DEFAULT; break; } CALLBACK; break; case _MD_EXPORTS: token = _md_next_token (md); while (token == _MD_quote || token == _MD_word) { stmt.export.ordinal = 0; stmt.export.pwords = 0; stmt.export.flags = 0; stmt.export.internalname[0] = 0; _strncpy (stmt.export.entryname, _md_get_string (md), sizeof (stmt.export.entryname)); token = _md_next_token (md); if (token == _MD_equal) { token = _md_next_token (md); if (token != _MD_quote && token != _MD_word) ERROR (_MDE_NAME_EXPECTED); _strncpy (stmt.export.internalname, _md_get_string (md), sizeof (stmt.export.internalname)); token = _md_next_token (md); } if (token == _MD_at) { stmt.export.flags |= _MDEP_ORDINAL; token = _md_next_token (md); if (token != _MD_number) ERROR (_MDE_NUMBER_EXPECTED); n = _md_get_number (md); if (n < 1 || n > 65535) ERROR (_MDE_INVALID_ORDINAL); stmt.export.ordinal = n; token = _md_next_token (md); if (token == _MD_NONAME) { stmt.export.flags |= _MDEP_NONAME; token = _md_next_token (md); } else if (token == _MD_RESIDENTNAME) { stmt.export.flags |= _MDEP_RESIDENTNAME; token = _md_next_token (md); } } if (token == _MD_NODATA) { stmt.export.flags |= _MDEP_NODATA; token = _md_next_token (md); } if (token == _MD_number) { stmt.export.flags |= _MDEP_PWORDS; stmt.export.pwords = _md_get_number (md); token = _md_next_token (md); } CALLBACK; } break; case _MD_HEAPSIZE: token = _md_next_token (md); if (token == _MD_number) { stmt.heapsize.maxval = FALSE; stmt.heapsize.size = _md_get_number (md); } else if (token == _MD_MAXVAL) { stmt.heapsize.size = 0; stmt.heapsize.maxval = TRUE; } else ERROR (_MDE_NUMBER_EXPECTED); token = _md_next_token (md); CALLBACK; break; case _MD_IMPORTS: token = _md_next_token (md); while (token == _MD_quote || token == _MD_word) { _strncpy (stmt.import.modulename, _md_get_string (md), sizeof (stmt.import.modulename)); stmt.import.entryname[0] = 0; stmt.import.internalname[0] = 0; stmt.import.ordinal = 0; stmt.import.flags = 0; token = _md_next_token (md); if (token == _MD_equal) { _strncpy (stmt.import.internalname, stmt.import.modulename, sizeof (stmt.import.internalname)); token = _md_next_token (md); if (token != _MD_quote && token != _MD_word) ERROR (_MDE_NAME_EXPECTED); _strncpy (stmt.import.modulename, _md_get_string (md), sizeof (stmt.import.modulename)); token = _md_next_token (md); } if (token != _MD_dot) ERROR (_MDE_DOT_EXPECTED); token = _md_next_token (md); if (token == _MD_word) _strncpy (stmt.import.entryname, _md_get_string (md), sizeof (stmt.import.entryname)); else if (token == _MD_number) { stmt.import.flags |= _MDIP_ORDINAL; n = _md_get_number (md); if (n < 1 || n > 65535) ERROR (_MDE_INVALID_ORDINAL); stmt.import.ordinal = n; } else ERROR (_MDE_NUMBER_EXPECTED); token = _md_next_token (md); CALLBACK; } break; case _MD_OLD: token = _md_next_token (md); if (token != _MD_quote) ERROR (_MDE_STRING_EXPECTED); _strncpy (stmt.old.name, _md_get_string (md), sizeof (stmt.old.name)); token = _md_next_token (md); CALLBACK; break; case _MD_PROTMODE: case _MD_REALMODE: token = _md_next_token (md); CALLBACK; break; case _MD_SEGMENTS: token = _md_next_token (md); while (token == _MD_quote || token == _MD_word) { _strncpy (stmt.segment.segname, _md_get_string (md), sizeof (stmt.segment.segname)); token = _md_next_token (md); if (token == _MD_CLASS) { token = _md_next_token (md); if (token != _MD_quote && token != _MD_word) ERROR (_MDE_NAME_EXPECTED); _strncpy (stmt.segment.classname, _md_get_string (md), sizeof (stmt.segment.classname)); token = _md_next_token (md); } else stmt.segment.classname[0] = 0; stmt.segment.attr = 0; ok = TRUE; while (ok) { switch (token) { case _MD_ALIAS: stmt.segment.attr |= _MDS_ALIAS; break; case _MD_CONFORMING: stmt.segment.attr |= _MDS_CONFORMING; break; case _MD_DISCARDABLE: stmt.segment.attr |= _MDS_DISCARDABLE; break; case _MD_EXECUTEONLY: stmt.segment.attr |= _MDS_EXECUTEONLY; break; case _MD_EXECUTEREAD: stmt.segment.attr |= _MDS_EXECUTEREAD; break; case _MD_FIXED: stmt.segment.attr |= _MDS_FIXED; break; case _MD_INVALID: stmt.segment.attr |= _MDS_INVALID; break; case _MD_IOPL: stmt.segment.attr |= _MDS_IOPL; break; case _MD_LOADONCALL: stmt.segment.attr |= _MDS_LOADONCALL; break; case _MD_MIXED1632: stmt.segment.attr |= _MDS_MIXED1632; break; case _MD_MOVEABLE: stmt.segment.attr |= _MDS_MOVEABLE; break; case _MD_NOIOPL: stmt.segment.attr |= _MDS_NOIOPL; break; case _MD_NONCONFORMING: stmt.segment.attr |= _MDS_NONCONFORMING; break; case _MD_NONDISCARDABLE: stmt.segment.attr |= _MDS_NONDISCARDABLE; break; case _MD_NONSHARED: case _MD_IMPURE: stmt.segment.attr |= _MDS_NONSHARED; break; case _MD_PRELOAD: stmt.segment.attr |= _MDS_PRELOAD; break; case _MD_READONLY: stmt.segment.attr |= _MDS_READONLY; break; case _MD_READWRITE: stmt.segment.attr |= _MDS_READWRITE; break; case _MD_SHARED: case _MD_PURE: stmt.segment.attr |= _MDS_SHARED; break; default: ok = FALSE; break; } if (ok) token = _md_next_token (md); } CALLBACK; } break; case _MD_STACKSIZE: token = _md_next_token (md); if (token != _MD_number) ERROR (_MDE_NUMBER_EXPECTED); stmt.stacksize.size = _md_get_number (md); token = _md_next_token (md); CALLBACK; break; case _MD_STUB: token = _md_next_token (md); if (token == _MD_quote) { _strncpy (stmt.stub.name, _md_get_string (md), sizeof (stmt.stub.name)); stmt.stub.none = FALSE; } else if (token == _MD_NONE) { stmt.stub.name[0] = 0; stmt.stub.none = TRUE; } else ERROR (_MDE_STRING_EXPECTED); token = _md_next_token (md); CALLBACK; break; case _MD_ioerror: ERROR (_MDE_IO_ERROR); break; case _MD_missingquote: ERROR (_MDE_MISSING_QUOTE); break; default: ERROR (_MDE_INVALID_STMT); } } return 0; }