1 /* $Id: mksystab.c,v 1.1 2002/04/06 16:07:34 ea Exp $
3 * PROJECT : ReactOS / POSIX+ Subsystem
4 * DESCRIPTION: Build the system calls table for
5 * DESCRIPTION: the POSIX+ LPC server process.
6 * NOTE : this code is supposed to be portable.
7 * AUTHOR : Emanuele Aliberti
10 * 2002-03-19 EA added stub file generation
11 * 2002-04-02 EA added to the CVS repository
18 #define PARSER_CONTEXT_LINE_SIZE 1024
19 #define PARSER_CONTEXT_INTERFACE_SIZE 64
21 const char * myname
= "mksystab";
23 const char * syscall_name_prefix
= "syscall_";
24 const char * proxy_name_prefix
= "psxss_";
32 typedef struct _PARSER_CONTEXT
36 char line
[PARSER_CONTEXT_LINE_SIZE
];
38 char interface
[PARSER_CONTEXT_INTERFACE_SIZE
];
41 } PARSER_CONTEXT
, * PPARSER_CONTEXT
;
48 METHOD_TYPE (*prologue
)(int,PPARSER_CONTEXT
);
49 METHOD_TYPE (*iter
)(int,PPARSER_CONTEXT
);
50 METHOD_TYPE (*epilog
)(int,PPARSER_CONTEXT
);
54 /* MFILE file table */
56 METHOD_TYPE
db_prologue (int self
, PPARSER_CONTEXT context
);
57 METHOD_TYPE
db_iter (int self
, PPARSER_CONTEXT context
);
58 METHOD_TYPE
db_epilog (int self
, PPARSER_CONTEXT context
);
60 METHOD_TYPE
systab_prologue (int self
, PPARSER_CONTEXT context
);
61 METHOD_TYPE
systab_iter (int self
, PPARSER_CONTEXT context
);
62 METHOD_TYPE
systab_epilog (int self
, PPARSER_CONTEXT context
);
64 METHOD_TYPE
psx_include_prologue (int self
, PPARSER_CONTEXT context
);
65 METHOD_TYPE
psx_include_iter (int self
, PPARSER_CONTEXT context
);
66 METHOD_TYPE
psx_include_epilog (int self
, PPARSER_CONTEXT context
);
68 METHOD_TYPE
server_include_prologue (int self
, PPARSER_CONTEXT context
);
69 METHOD_TYPE
server_include_iter (int self
, PPARSER_CONTEXT context
);
70 METHOD_TYPE
server_include_epilog (int self
, PPARSER_CONTEXT context
);
72 METHOD_TYPE
stubs_prologue (int self
, PPARSER_CONTEXT context
);
73 METHOD_TYPE
stubs_iter (int self
, PPARSER_CONTEXT context
);
74 METHOD_TYPE
stubs_epilog (int self
, PPARSER_CONTEXT context
);
79 { NULL
, NULL
, "r", db_prologue
, db_iter
, db_epilog
}, /* it must be 1st */
80 { NULL
, NULL
, "w", systab_prologue
, systab_iter
, systab_epilog
},
81 { NULL
, NULL
, "w", server_include_prologue
, server_include_iter
, server_include_epilog
},
82 { NULL
, NULL
, "w", psx_include_prologue
, psx_include_iter
, psx_include_epilog
},
83 { NULL
, NULL
, "w", stubs_prologue
, stubs_iter
, stubs_epilog
}
87 /* mf objects methods */
89 int mf_open (int index
)
91 mf
[index
].fp
= fopen (mf
[index
].name
, mf
[index
].fopen_mode
);
92 if (NULL
== mf
[index
].fp
)
94 fprintf (stderr
, "%s: error %d while opening \"%s\".", myname
, errno
, mf
[index
].name
);
95 return METHOD_FAILURE
;
97 return METHOD_SUCCESS
;
100 void mf_close (int index
)
102 fclose (mf
[index
].fp
);
105 /* db file methods */
107 METHOD_TYPE
db_prologue (int self
, PPARSER_CONTEXT context
)
109 if (METHOD_FAILURE
== mf_open (self
))
111 return METHOD_FAILURE
;
113 fprintf (stderr
, "Processing \"%s\"...\n", mf
[self
].name
);
114 return METHOD_SUCCESS
;
117 METHOD_TYPE
db_iter (int self
, PPARSER_CONTEXT context
)
123 if (feof(mf
[self
].fp
))
127 if (NULL
== fgets (context
->line
, PARSER_CONTEXT_LINE_SIZE
, mf
[self
].fp
))
131 ++ context
->line_number
;
132 eol
= strchr(context
->line
, '\n');
137 /* Is line empty or a comment? */
138 } while (0 == strlen (context
->line
) || context
->line
[0] == '#');
139 /* Line is not a comment nor an empty line */
140 if (3 != sscanf (context
->line
, "%c%s%d", & context
->status
, context
->interface
, & context
->argc
))
142 fprintf (stderr
, "Syntax error at line %d.\n", context
->line_number
);
143 return METHOD_FAILURE
;
145 return METHOD_SUCCESS
;
148 METHOD_TYPE
db_epilog (int self
, PPARSER_CONTEXT context
)
151 return METHOD_SUCCESS
;
154 /* systab file methods */
156 METHOD_TYPE
systab_prologue (int self
, PPARSER_CONTEXT context
)
158 if (METHOD_FAILURE
== mf_open (self
))
160 return METHOD_FAILURE
;
162 fprintf (mf
[self
].fp
, "/* POSIX+ system calls (machine generated: do not edit!) */\n");
163 fprintf (mf
[self
].fp
, "#include <psxss.h>\n");
164 fprintf (mf
[self
].fp
, "#include <syscall.h>\n");
165 fprintf (mf
[self
].fp
, "PSX_SYSTEM_CALL SystemCall [] =\n");
166 fprintf (mf
[self
].fp
, "{\n");
167 return METHOD_SUCCESS
;
170 METHOD_TYPE
systab_iter (int self
, PPARSER_CONTEXT context
)
172 switch (context
->status
)
175 case '-': /* unimplemented interface */
176 fprintf (mf
[self
].fp
, "(void*)%s%s,\n", syscall_name_prefix
, context
->interface
);
179 fprintf (stderr
, "%s: unknown interface status \"%c\" at line %d.\n",
180 myname
, context
->status
, context
->line_number
);
181 return METHOD_FAILURE
;
183 return METHOD_SUCCESS
;
186 METHOD_TYPE
systab_epilog (int self
, PPARSER_CONTEXT context
)
188 fprintf (mf
[self
].fp
, "0\n};\n");
189 fputs ("/* EOF */", mf
[self
].fp
);
190 return METHOD_SUCCESS
;
194 /* server/include file methods */
196 METHOD_TYPE
server_include_prologue (int self
, PPARSER_CONTEXT context
)
198 if (METHOD_FAILURE
== mf_open (self
))
200 return METHOD_FAILURE
;
202 fprintf (mf
[self
].fp
, "/* POSIX+ system calls (machine generated: do not edit!) */\n");
203 fprintf (mf
[self
].fp
, "#ifndef _SERVER_SYSCALL_H\n");
204 fprintf (mf
[self
].fp
, "#define _SERVER_SYSCALL_H\n");
205 return METHOD_SUCCESS
;
208 METHOD_TYPE
server_include_iter (int self
, PPARSER_CONTEXT context
)
210 char interface
[PARSER_CONTEXT_INTERFACE_SIZE
*2];
212 sprintf (interface
, "%s%s", syscall_name_prefix
, context
->interface
);
213 fprintf (mf
[self
].fp
, "NTSTATUS STDCALL %s (PPSX_MAX_MESSAGE);\n", interface
);
215 return METHOD_SUCCESS
;
218 METHOD_TYPE
server_include_epilog (int self
, PPARSER_CONTEXT context
)
220 fprintf (mf
[self
].fp
, "#endif /* ndef _SERVER_SYSCALL_H */\n");
221 fputs ("/* EOF */", mf
[self
].fp
);
222 return METHOD_SUCCESS
;
226 /* psx/include file methods */
228 METHOD_TYPE
psx_include_prologue (int self
, PPARSER_CONTEXT context
)
230 if (METHOD_FAILURE
== mf_open (self
))
232 return METHOD_FAILURE
;
234 fprintf (mf
[self
].fp
, "/* POSIX+ system calls (machine generated: do not edit!) */\n");
235 fprintf (mf
[self
].fp
, "#ifndef _PSX_SYSCALL_H\n");
236 fprintf (mf
[self
].fp
, "#define _PSX_SYSCALL_H\n");
237 return METHOD_SUCCESS
;
240 METHOD_TYPE
psx_include_iter (int self
, PPARSER_CONTEXT context
)
242 char interface
[PARSER_CONTEXT_INTERFACE_SIZE
*2];
244 sprintf (interface
, "%s%s", proxy_name_prefix
, context
->interface
);
245 fprintf (mf
[self
].fp
, "#define %s %d\n", strupr(interface
), context
->id
++);
247 return METHOD_SUCCESS
;
250 METHOD_TYPE
psx_include_epilog (int self
, PPARSER_CONTEXT context
)
252 fprintf (mf
[self
].fp
, "#endif /* ndef _PSX_SYSCALL_H */\n");
253 fputs ("/* EOF */", mf
[self
].fp
);
254 return METHOD_SUCCESS
;
258 /* stubs file methods */
260 METHOD_TYPE
stubs_prologue (int self
, PPARSER_CONTEXT context
)
262 if (METHOD_FAILURE
== mf_open (self
))
264 return METHOD_FAILURE
;
266 fprintf( mf
[self
].fp
,
267 "/* POSIX+ system calls not yet implemented */\n"
268 "/* (machine generated: do not edit!) */\n"
269 "#include <psxss.h>\n");
270 return METHOD_SUCCESS
;
273 METHOD_TYPE
stubs_iter (int self
, PPARSER_CONTEXT context
)
275 if ('-' == context
->status
)
279 "NTSTATUS STDCALL %s%s(PPSX_MAX_MESSAGE Msg){Msg->PsxHeader.Status=STATUS_NOT_IMPLEMENTED;return(STATUS_SUCCESS);}\n",
284 return METHOD_SUCCESS
;
287 METHOD_TYPE
stubs_epilog (int self
, PPARSER_CONTEXT context
)
289 fputs ("/* EOF */", mf
[self
].fp
);
290 return METHOD_SUCCESS
;
296 METHOD_TYPE
mksystab ()
299 int index_top
= (sizeof mf
/ sizeof mf
[0]);
301 PARSER_CONTEXT context
;
304 /* initialize the parser's context */
305 context
.line_number
= 0;
309 for (index
= 0; index
< index_top
; index
++)
311 if (METHOD_FAILURE
== mf
[index
].prologue (index
, & context
))
313 return METHOD_FAILURE
;
319 for (index
= 0; index
< index_top
; index
++)
321 mt
= mf
[index
].iter (index
, & context
);
322 if (METHOD_EOF
== mt
)
324 if (0 == index
) /* input MUST be 1st MFILE */
327 break; /* input reached EOF */
329 return METHOD_FAILURE
;
331 else if (METHOD_FAILURE
== mt
)
333 return METHOD_FAILURE
;
338 for (index
= 0; index
< index_top
; index
++)
340 if (METHOD_FAILURE
== mf
[index
].epilog (index
, & context
))
342 return METHOD_FAILURE
;
347 return METHOD_SUCCESS
;
352 int main (int argc
, char **argv
)
357 /* Check user parameters */
358 if ((1 + (sizeof mf
/ sizeof (MFILE
))) != argc
)
360 printf ("ReactOS Operating System - POSIX+ Environment Subsystem\n");
361 printf ("Build the system calls table of the POSIX+ server.\n\n");
362 printf ("usage: %s syscall.db syscall.c syscall.h syscall.h stubs.c\n", argv
[0]);
363 exit (METHOD_FAILURE
);
365 /* initialize descriptors */
366 for (index
= 0; index
< (sizeof mf
/ sizeof mf
[0]); index
++)
368 mf
[index
].name
= argv
[index
+ 1];
371 /* do process them */
372 status
= mksystab ();