/* $Id: mksystab.c,v 1.1 2003/01/05 18:08:11 robd Exp $ * * PROJECT : ReactOS / POSIX+ Subsystem * DESCRIPTION: Build the system calls table for * DESCRIPTION: the POSIX+ LPC server process. * NOTE : this code is supposed to be portable. * AUTHOR : Emanuele Aliberti * DATE : 2001-05-26 * REVISIONS * 2002-03-19 EA added stub file generation * 2002-04-06 EA added to the CVS repository */ #include #include #include #include #define PARSER_CONTEXT_LINE_SIZE 1024 #define PARSER_CONTEXT_INTERFACE_SIZE 64 const char * myname = "mksystab"; const char * syscall_name_prefix = "syscall_"; const char * proxy_name_prefix = "psxss_"; typedef enum { METHOD_SUCCESS, METHOD_EOF, METHOD_FAILURE } METHOD_TYPE; typedef struct _PARSER_CONTEXT { int line_number; int id; char line [PARSER_CONTEXT_LINE_SIZE]; char status; char interface [PARSER_CONTEXT_INTERFACE_SIZE]; int argc; } PARSER_CONTEXT, * PPARSER_CONTEXT; typedef struct _MFILE { char * name; FILE * fp; char * fopen_mode; METHOD_TYPE (*prologue)(int,PPARSER_CONTEXT); METHOD_TYPE (*iter)(int,PPARSER_CONTEXT); METHOD_TYPE (*epilog)(int,PPARSER_CONTEXT); } MFILE, * PMFILE; /* MFILE file table */ METHOD_TYPE db_prologue (int self, PPARSER_CONTEXT context); METHOD_TYPE db_iter (int self, PPARSER_CONTEXT context); METHOD_TYPE db_epilog (int self, PPARSER_CONTEXT context); METHOD_TYPE systab_prologue (int self, PPARSER_CONTEXT context); METHOD_TYPE systab_iter (int self, PPARSER_CONTEXT context); METHOD_TYPE systab_epilog (int self, PPARSER_CONTEXT context); METHOD_TYPE psx_include_prologue (int self, PPARSER_CONTEXT context); METHOD_TYPE psx_include_iter (int self, PPARSER_CONTEXT context); METHOD_TYPE psx_include_epilog (int self, PPARSER_CONTEXT context); METHOD_TYPE server_include_prologue (int self, PPARSER_CONTEXT context); METHOD_TYPE server_include_iter (int self, PPARSER_CONTEXT context); METHOD_TYPE server_include_epilog (int self, PPARSER_CONTEXT context); METHOD_TYPE stubs_prologue (int self, PPARSER_CONTEXT context); METHOD_TYPE stubs_iter (int self, PPARSER_CONTEXT context); METHOD_TYPE stubs_epilog (int self, PPARSER_CONTEXT context); MFILE mf [] = { { NULL, NULL, "r", db_prologue, db_iter, db_epilog }, /* it must be 1st */ { NULL, NULL, "w", systab_prologue, systab_iter, systab_epilog }, { NULL, NULL, "w", server_include_prologue, server_include_iter, server_include_epilog }, { NULL, NULL, "w", psx_include_prologue, psx_include_iter, psx_include_epilog }, { NULL, NULL, "w", stubs_prologue, stubs_iter, stubs_epilog } }; /* mf objects methods */ int mf_open (int index) { mf [index].fp = fopen (mf [index].name, mf [index].fopen_mode); if (NULL == mf [index].fp) { fprintf (stderr, "%s: error %d while opening \"%s\".", myname, errno, mf [index].name); return METHOD_FAILURE; } return METHOD_SUCCESS; } void mf_close (int index) { fclose (mf[index].fp); } /* db file methods */ METHOD_TYPE db_prologue (int self, PPARSER_CONTEXT context) { if (METHOD_FAILURE == mf_open (self)) { return METHOD_FAILURE; } fprintf (stderr, "Processing \"%s\"...\n", mf [self].name); return METHOD_SUCCESS; } METHOD_TYPE db_iter (int self, PPARSER_CONTEXT context) { char * eol; do { if (feof(mf [self].fp)) { return METHOD_EOF; } if (NULL == fgets (context->line, PARSER_CONTEXT_LINE_SIZE, mf [self].fp)) { return METHOD_EOF; } ++ context->line_number; eol = strchr(context->line, '\n'); if (eol) { *eol = '\0'; } /* Is line empty or a comment? */ } while (0 == strlen (context->line) || context->line[0] == '#'); /* Line is not a comment nor an empty line */ if (3 != sscanf (context->line, "%c%s%d", & context->status, context->interface, & context->argc)) { fprintf (stderr, "Syntax error at line %d.\n", context->line_number); return METHOD_FAILURE; } return METHOD_SUCCESS; } METHOD_TYPE db_epilog (int self, PPARSER_CONTEXT context) { mf_close (self); return METHOD_SUCCESS; } /* systab file methods */ METHOD_TYPE systab_prologue (int self, PPARSER_CONTEXT context) { if (METHOD_FAILURE == mf_open (self)) { return METHOD_FAILURE; } fprintf (mf[self].fp, "/* POSIX+ system calls (machine generated: do not edit!) */\n"); fprintf (mf[self].fp, "#include \n"); fprintf (mf[self].fp, "#include \n"); fprintf (mf[self].fp, "PSX_SYSTEM_CALL SystemCall [] =\n"); fprintf (mf[self].fp, "{\n"); return METHOD_SUCCESS; } METHOD_TYPE systab_iter (int self, PPARSER_CONTEXT context) { switch (context->status) { case '+': case '-': /* unimplemented interface */ fprintf (mf[self].fp, "(void*)%s%s,\n", syscall_name_prefix, context->interface); break; default: fprintf (stderr, "%s: unknown interface status \"%c\" at line %d.\n", myname, context->status, context->line_number); return METHOD_FAILURE; } return METHOD_SUCCESS; } METHOD_TYPE systab_epilog (int self, PPARSER_CONTEXT context) { fprintf (mf[self].fp, "0\n};\n"); fputs ("/* EOF */", mf[self].fp); return METHOD_SUCCESS; } /* server/include file methods */ METHOD_TYPE server_include_prologue (int self, PPARSER_CONTEXT context) { if (METHOD_FAILURE == mf_open (self)) { return METHOD_FAILURE; } fprintf (mf[self].fp, "/* POSIX+ system calls (machine generated: do not edit!) */\n"); fprintf (mf[self].fp, "#ifndef _SERVER_SYSCALL_H\n"); fprintf (mf[self].fp, "#define _SERVER_SYSCALL_H\n"); return METHOD_SUCCESS; } METHOD_TYPE server_include_iter (int self, PPARSER_CONTEXT context) { char interface [PARSER_CONTEXT_INTERFACE_SIZE*2]; sprintf (interface, "%s%s", syscall_name_prefix, context->interface); fprintf (mf[self].fp, "NTSTATUS STDCALL %s (PPSX_MAX_MESSAGE);\n", interface); return METHOD_SUCCESS; } METHOD_TYPE server_include_epilog (int self, PPARSER_CONTEXT context) { fprintf (mf[self].fp, "#endif /* ndef _SERVER_SYSCALL_H */\n"); fputs ("/* EOF */", mf[self].fp); return METHOD_SUCCESS; } /* psx/include file methods */ METHOD_TYPE psx_include_prologue (int self, PPARSER_CONTEXT context) { if (METHOD_FAILURE == mf_open (self)) { return METHOD_FAILURE; } fprintf (mf[self].fp, "/* POSIX+ system calls (machine generated: do not edit!) */\n"); fprintf (mf[self].fp, "#ifndef _PSX_SYSCALL_H\n"); fprintf (mf[self].fp, "#define _PSX_SYSCALL_H\n"); return METHOD_SUCCESS; } METHOD_TYPE psx_include_iter (int self, PPARSER_CONTEXT context) { char interface [PARSER_CONTEXT_INTERFACE_SIZE*2]; sprintf (interface, "%s%s", proxy_name_prefix, context->interface); fprintf (mf[self].fp, "#define %s %d\n", strupr(interface), context->id ++); return METHOD_SUCCESS; } METHOD_TYPE psx_include_epilog (int self, PPARSER_CONTEXT context) { fprintf (mf[self].fp, "#define PSX_SYSCALL_APIPORT_COUNT %d\n", context->id ++); fprintf (mf[self].fp, "#endif /* ndef _PSX_SYSCALL_H */\n"); fputs ("/* EOF */", mf[self].fp); return METHOD_SUCCESS; } /* stubs file methods */ METHOD_TYPE stubs_prologue (int self, PPARSER_CONTEXT context) { if (METHOD_FAILURE == mf_open (self)) { return METHOD_FAILURE; } fprintf( mf[self].fp, "/* POSIX+ system calls not yet implemented */\n" "/* (machine generated: do not edit!) */\n" "#include \n"); return METHOD_SUCCESS; } METHOD_TYPE stubs_iter (int self, PPARSER_CONTEXT context) { if ('-' == context->status) { fprintf ( mf[self].fp, "NTSTATUS STDCALL %s%s(PPSX_MAX_MESSAGE Msg){Msg->PsxHeader.Status=STATUS_NOT_IMPLEMENTED;return(STATUS_SUCCESS);}\n", syscall_name_prefix, context->interface ); } return METHOD_SUCCESS; } METHOD_TYPE stubs_epilog (int self, PPARSER_CONTEXT context) { fputs ("/* EOF */", mf[self].fp); return METHOD_SUCCESS; } /* main loop */ METHOD_TYPE mksystab () { int index; int index_top = (sizeof mf / sizeof mf[0]); int iterate = 1; PARSER_CONTEXT context; METHOD_TYPE mt; /* initialize the parser's context */ context.line_number = 0; context.id = 0; /* prologue */ for (index = 0; index < index_top; index ++) { if (METHOD_FAILURE == mf[index].prologue (index, & context)) { return METHOD_FAILURE; } } /* iter */ while (iterate) { for (index = 0; index < index_top; index ++) { mt = mf[index].iter (index, & context); if (METHOD_EOF == mt) { if (0 == index) /* input MUST be 1st MFILE */ { iterate = 0; break; /* input reached EOF */ } return METHOD_FAILURE; } else if (METHOD_FAILURE == mt) { return METHOD_FAILURE; } } } /* epilog */ for (index = 0; index < index_top; index ++) { if (METHOD_FAILURE == mf[index].epilog (index, & context)) { return METHOD_FAILURE; } } /* done */ return METHOD_SUCCESS; } /* entry point */ int main (int argc, char **argv) { int status = 0; int index; /* Check user parameters */ if ((1 + (sizeof mf / sizeof (MFILE))) != argc) { printf ("ReactOS Operating System - POSIX+ Environment Subsystem\n"); printf ("Build the system calls table of the POSIX+ server.\n\n"); printf ("usage: %s syscall.db syscall.c syscall.h syscall.h stubs.c\n", argv[0]); exit (METHOD_FAILURE); } /* initialize descriptors */ for (index = 0; index < (sizeof mf / sizeof mf[0]); index ++) { mf [index].name = argv [index + 1]; } /* do process them */ status = mksystab (); return (status); } /* EOF */