source: trunk/emx/src/libmoddef/moddef2.c@ 3232

Last change on this file since 3232 was 1933, checked in by bird, 20 years ago

Allow empty definition strings.

  • Property cvs2svn:cvs-rev set to 1.3
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 20.5 KB
Line 
1/* moddef2.c (emx+gcc) -- Copyright (c) 1992-1995 by Eberhard Mattes */
2
3#include <stdio.h>
4#include <string.h>
5#include <sys/moddef.h>
6
7#define FALSE 0
8#define TRUE 1
9
10typedef int _md_callback (struct _md *md, const _md_stmt *stmt,
11 _md_token token, void *arg);
12
13static int error (struct _md *md, _md_callback *callback, _md_stmt *stmt,
14 _md_token stmt_token, _md_error code, void *arg)
15{
16 stmt->error.code = code;
17 stmt->error.stmt = stmt_token;
18 return callback (md, stmt, _MD_parseerror, arg);
19}
20
21static _md_token sync (struct _md *md)
22{
23 _md_token token;
24
25 token = _md_get_token (md);
26 for (;;)
27 switch (token)
28 {
29 case _MD_BASE:
30 case _MD_CODE:
31 case _MD_DATA:
32 case _MD_DESCRIPTION:
33 case _MD_EXETYPE:
34 case _MD_EXPORTS:
35 case _MD_HEAPSIZE:
36 case _MD_IMPORTS:
37 case _MD_OLD:
38 case _MD_PROTMODE:
39 case _MD_REALMODE:
40 case _MD_SEGMENTS:
41 case _MD_STACKSIZE:
42 case _MD_STUB:
43 case _MD_eof:
44 case _MD_ioerror:
45 case _MD_missingquote:
46 return token;
47 default:
48 token = _md_next_token (md);
49 break;
50 }
51}
52
53
54#define ERROR(CODE) \
55 do { result = error (md, callback, &stmt, stmt_token, (CODE), arg); \
56 if (result != 0) return result; \
57 token = sync (md); goto next_stmt;} while (FALSE)
58
59#define CALLBACK \
60 do { result = callback (md, &stmt, stmt_token, arg); \
61 if (result != 0) return result; } while (FALSE)
62
63int _md_parse (struct _md *md, _md_callback *callback, void *arg)
64{
65 _md_token token, stmt_token;
66 _md_stmt stmt;
67 const char *s;
68 long n;
69 int ok, result;
70
71 token = _md_get_token (md);
72 stmt_token = token;
73 stmt.line_number = _md_get_linenumber (md);
74 switch (stmt_token)
75 {
76 case _MD_eof:
77 ERROR (_MDE_EMPTY);
78 break;
79
80 case _MD_NAME:
81 stmt.line_number = _md_get_linenumber (md);
82 token = _md_next_token (md);
83 stmt.name.name[0] = 0;
84 if (token == _MD_quote || token == _MD_word)
85 {
86 _strncpy (stmt.name.name, _md_get_string (md),
87 sizeof (stmt.name.name));
88 token = _md_next_token (md);
89 }
90 switch (token)
91 {
92 case _MD_WINDOWAPI:
93 stmt.name.pmtype = _MDT_WINDOWAPI;
94 token = _md_next_token (md);
95 break;
96 case _MD_WINDOWCOMPAT:
97 stmt.name.pmtype = _MDT_WINDOWCOMPAT;
98 token = _md_next_token (md);
99 break;
100 case _MD_NOTWINDOWCOMPAT:
101 stmt.name.pmtype = _MDT_NOTWINDOWCOMPAT;
102 token = _md_next_token (md);
103 break;
104 default:
105 stmt.name.pmtype = _MDT_DEFAULT;
106 break;
107 }
108 stmt.name.newfiles = FALSE;
109 if (token == _MD_NEWFILES)
110 {
111 stmt.name.newfiles = TRUE;
112 token = _md_next_token (md);
113 }
114 CALLBACK;
115 break;
116
117 case _MD_LIBRARY:
118 stmt.line_number = _md_get_linenumber (md);
119 token = _md_next_token (md);
120 if (token == _MD_quote || token == _MD_word)
121 {
122 _strncpy (stmt.library.name, _md_get_string (md),
123 sizeof (stmt.library.name));
124 token = _md_next_token (md);
125 }
126 switch (token)
127 {
128 case _MD_INITGLOBAL:
129 stmt.library.init = _MDIT_GLOBAL;
130 token = _md_next_token (md);
131 break;
132 case _MD_INITINSTANCE:
133 stmt.library.init = _MDIT_INSTANCE;
134 token = _md_next_token (md);
135 break;
136 default:
137 stmt.library.init = _MDIT_DEFAULT;
138 break;
139 }
140 switch (token)
141 {
142 case _MD_TERMGLOBAL:
143 stmt.library.term = _MDIT_GLOBAL;
144 token = _md_next_token (md);
145 break;
146 case _MD_TERMINSTANCE:
147 stmt.library.term = _MDIT_INSTANCE;
148 token = _md_next_token (md);
149 break;
150 default:
151 stmt.library.term = _MDIT_DEFAULT;
152 break;
153 }
154 if (token == _MD_PRIVATELIB)
155 token = _md_next_token (md);
156 CALLBACK;
157 break;
158
159 case _MD_VIRTUAL:
160 case _MD_PHYSICAL:
161 stmt.line_number = _md_get_linenumber (md);
162 token = _md_next_token (md);
163 if (token != _MD_DEVICE)
164 ERROR (_MDE_DEVICE_EXPECTED);
165 token = _md_next_token (md);
166 stmt.device.name[0] = 0;
167 if (token == _MD_quote || token == _MD_word)
168 {
169 _strncpy (stmt.device.name, _md_get_string (md),
170 sizeof (stmt.device.name));
171 token = _md_next_token (md);
172 }
173 CALLBACK;
174 break;
175
176 default:
177 break;
178 }
179
180next_stmt:
181 while (token != _MD_eof)
182 {
183 stmt_token = token;
184 stmt.line_number = _md_get_linenumber (md);
185 switch (stmt_token)
186 {
187 case _MD_BASE:
188 token = _md_next_token (md);
189 if (token != _MD_equal)
190 ERROR (_MDE_EQUAL_EXPECTED);
191 token = _md_next_token (md);
192 if (token != _MD_number)
193 ERROR (_MDE_NUMBER_EXPECTED);
194 token = _md_next_token (md);
195 CALLBACK;
196 break;
197
198 case _MD_CODE:
199 token = _md_next_token (md);
200 stmt.segment.segname[0] = 0;
201 stmt.segment.classname[0] = 0;
202 stmt.segment.attr = 0;
203 ok = TRUE;
204 while (ok)
205 {
206 switch (token)
207 {
208 case _MD_CONFORMING:
209 stmt.segment.attr |= _MDS_CONFORMING;
210 break;
211 case _MD_DISCARDABLE:
212 stmt.segment.attr |= _MDS_DISCARDABLE;
213 break;
214 case _MD_EXECUTEONLY:
215 stmt.segment.attr |= _MDS_EXECUTEONLY;
216 break;
217 case _MD_EXECUTEREAD:
218 stmt.segment.attr |= _MDS_EXECUTEREAD;
219 break;
220 case _MD_FIXED:
221 stmt.segment.attr |= _MDS_FIXED;
222 break;
223 case _MD_IOPL:
224 stmt.segment.attr |= _MDS_IOPL;
225 break;
226 case _MD_LOADONCALL:
227 stmt.segment.attr |= _MDS_LOADONCALL;
228 break;
229 case _MD_MOVEABLE:
230 stmt.segment.attr |= _MDS_MOVEABLE;
231 break;
232 case _MD_NOIOPL:
233 stmt.segment.attr |= _MDS_NOIOPL;
234 break;
235 case _MD_NONCONFORMING:
236 stmt.segment.attr |= _MDS_NONCONFORMING;
237 break;
238 case _MD_NONDISCARDABLE:
239 stmt.segment.attr |= _MDS_NONDISCARDABLE;
240 break;
241 case _MD_NONSHARED:
242 case _MD_IMPURE:
243 stmt.segment.attr |= _MDS_NONSHARED;
244 break;
245 case _MD_PRELOAD:
246 stmt.segment.attr |= _MDS_PRELOAD;
247 break;
248 case _MD_SHARED:
249 case _MD_PURE:
250 stmt.segment.attr |= _MDS_SHARED;
251 break;
252 default:
253 ok = FALSE;
254 break;
255 }
256 if (ok)
257 token = _md_next_token (md);
258 }
259 CALLBACK;
260 break;
261
262 case _MD_DATA:
263 token = _md_next_token (md);
264 stmt.segment.segname[0] = 0;
265 stmt.segment.classname[0] = 0;
266 stmt.segment.attr = 0;
267 ok = TRUE;
268 while (ok)
269 {
270 switch (token)
271 {
272 case _MD_FIXED:
273 stmt.segment.attr |= _MDS_FIXED;
274 break;
275 case _MD_IOPL:
276 stmt.segment.attr |= _MDS_IOPL;
277 break;
278 case _MD_LOADONCALL:
279 stmt.segment.attr |= _MDS_LOADONCALL;
280 break;
281 case _MD_MOVEABLE:
282 stmt.segment.attr |= _MDS_MOVEABLE;
283 break;
284 case _MD_MULTIPLE:
285 stmt.segment.attr |= _MDS_MULTIPLE;
286 break;
287 case _MD_NOIOPL:
288 stmt.segment.attr |= _MDS_NOIOPL;
289 break;
290 case _MD_NONE:
291 stmt.segment.attr |= _MDS_NONE;
292 break;
293 case _MD_NONSHARED:
294 case _MD_IMPURE:
295 stmt.segment.attr |= _MDS_NONSHARED;
296 break;
297 case _MD_PRELOAD:
298 stmt.segment.attr |= _MDS_PRELOAD;
299 break;
300 case _MD_READONLY:
301 stmt.segment.attr |= _MDS_READONLY;
302 break;
303 case _MD_READWRITE:
304 stmt.segment.attr |= _MDS_READWRITE;
305 break;
306 case _MD_SHARED:
307 case _MD_PURE:
308 stmt.segment.attr |= _MDS_SHARED;
309 break;
310 case _MD_SINGLE:
311 stmt.segment.attr |= _MDS_SINGLE;
312 break;
313 default:
314 ok = FALSE;
315 break;
316 }
317 if (ok)
318 token = _md_next_token (md);
319 }
320 CALLBACK;
321 break;
322
323 case _MD_DESCRIPTION:
324 token = _md_next_token (md);
325 if (token != _MD_quote)
326 ERROR (_MDE_STRING_EXPECTED);
327 s = _md_get_string (md);
328 if (strlen (s) > 255)
329 ERROR (_MDE_STRING_TOO_LONG);
330 _strncpy (stmt.descr.string, s, sizeof (stmt.descr.string));
331 token = _md_next_token (md);
332 CALLBACK;
333 break;
334
335 case _MD_EXETYPE:
336 token = _md_next_token (md);
337 switch (token)
338 {
339 case _MD_OS2:
340 stmt.exetype.type = _MDX_OS2;
341 token = _md_next_token (md);
342 break;
343 case _MD_UNKNOWN:
344 stmt.exetype.type = _MDX_UNKNOWN;
345 token = _md_next_token (md);
346 break;
347 case _MD_WINDOWS:
348 stmt.exetype.type = _MDX_WINDOWS;
349 stmt.exetype.major_version = 0;
350 stmt.exetype.minor_version = 0;
351 token = _md_next_token (md);
352 if (token == _MD_number)
353 {
354 stmt.exetype.major_version = _md_get_number (md);
355 token = _md_next_token (md);
356 if (token == _MD_dot)
357 {
358 token = _md_next_token (md);
359 if (token == _MD_number)
360 {
361 stmt.exetype.minor_version = _md_get_number (md);
362 token = _md_next_token (md);
363 }
364 }
365 }
366 break;
367 default:
368 stmt.exetype.type = _MDX_DEFAULT;
369 break;
370 }
371 CALLBACK;
372 break;
373
374 case _MD_EXPORTS:
375 token = _md_next_token (md);
376 while (token == _MD_quote || token == _MD_word)
377 {
378 stmt.line_number = _md_get_linenumber (md);
379 stmt.export.ordinal = 0;
380 stmt.export.pwords = 0;
381 stmt.export.flags = 0;
382 stmt.export.internalname[0] = 0;
383 _strncpy (stmt.export.entryname, _md_get_string (md),
384 sizeof (stmt.export.entryname));
385 token = _md_next_token (md);
386 if (token == _MD_equal)
387 {
388 token = _md_next_token (md);
389 if (token != _MD_quote && token != _MD_word)
390 ERROR (_MDE_NAME_EXPECTED);
391 _strncpy (stmt.export.internalname, _md_get_string (md),
392 sizeof (stmt.export.internalname));
393 token = _md_next_token (md);
394 }
395 if (token == _MD_at)
396 {
397 stmt.export.flags |= _MDEP_ORDINAL;
398 token = _md_next_token (md);
399 if (token != _MD_number)
400 ERROR (_MDE_NUMBER_EXPECTED);
401 n = _md_get_number (md);
402 if (n < 1 || n > 65535)
403 ERROR (_MDE_INVALID_ORDINAL);
404 stmt.export.ordinal = n;
405 token = _md_next_token (md);
406 if (token == _MD_NONAME)
407 {
408 stmt.export.flags |= _MDEP_NONAME;
409 token = _md_next_token (md);
410 }
411 else if (token == _MD_RESIDENTNAME)
412 {
413 stmt.export.flags |= _MDEP_RESIDENTNAME;
414 token = _md_next_token (md);
415 }
416 }
417 if (token == _MD_NODATA)
418 {
419 stmt.export.flags |= _MDEP_NODATA;
420 token = _md_next_token (md);
421 }
422 if (token == _MD_number)
423 {
424 stmt.export.flags |= _MDEP_PWORDS;
425 stmt.export.pwords = _md_get_number (md);
426 token = _md_next_token (md);
427 }
428 CALLBACK;
429 }
430 break;
431
432 case _MD_HEAPSIZE:
433 token = _md_next_token (md);
434 if (token == _MD_number)
435 {
436 stmt.heapsize.maxval = FALSE;
437 stmt.heapsize.size = _md_get_number (md);
438 }
439 else if (token == _MD_MAXVAL)
440 {
441 stmt.heapsize.size = 0;
442 stmt.heapsize.maxval = TRUE;
443 }
444 else
445 ERROR (_MDE_NUMBER_EXPECTED);
446 token = _md_next_token (md);
447 CALLBACK;
448 break;
449
450 case _MD_IMPORTS:
451 token = _md_next_token (md);
452 while (token == _MD_quote || token == _MD_word)
453 {
454 stmt.line_number = _md_get_linenumber (md);
455 _strncpy (stmt.import.modulename, _md_get_string (md),
456 sizeof (stmt.import.modulename));
457 stmt.import.entryname[0] = 0;
458 stmt.import.internalname[0] = 0;
459 stmt.import.ordinal = 0;
460 stmt.import.flags = 0;
461 token = _md_next_token (md);
462 if (token == _MD_equal)
463 {
464 _strncpy (stmt.import.internalname, stmt.import.modulename,
465 sizeof (stmt.import.internalname));
466 token = _md_next_token (md);
467 if (token != _MD_quote && token != _MD_word)
468 ERROR (_MDE_NAME_EXPECTED);
469 _strncpy (stmt.import.modulename, _md_get_string (md),
470 sizeof (stmt.import.modulename));
471 token = _md_next_token (md);
472 }
473 if (token != _MD_dot)
474 ERROR (_MDE_DOT_EXPECTED);
475 token = _md_next_token (md);
476 if (token == _MD_word)
477 _strncpy (stmt.import.entryname, _md_get_string (md),
478 sizeof (stmt.import.entryname));
479 else if (token == _MD_number)
480 {
481 stmt.import.flags |= _MDIP_ORDINAL;
482 n = _md_get_number (md);
483 if (n < 1 || n > 65535)
484 ERROR (_MDE_INVALID_ORDINAL);
485 stmt.import.ordinal = n;
486 }
487 else
488 ERROR (_MDE_NUMBER_EXPECTED);
489 token = _md_next_token (md);
490 CALLBACK;
491 }
492 break;
493
494 case _MD_OLD:
495 token = _md_next_token (md);
496 if (token != _MD_quote)
497 ERROR (_MDE_STRING_EXPECTED);
498 _strncpy (stmt.old.name, _md_get_string (md),
499 sizeof (stmt.old.name));
500 token = _md_next_token (md);
501 CALLBACK;
502 break;
503
504 case _MD_PROTMODE:
505 case _MD_REALMODE:
506 token = _md_next_token (md);
507 CALLBACK;
508 break;
509
510 case _MD_SEGMENTS:
511 token = _md_next_token (md);
512 while (token == _MD_quote || token == _MD_word)
513 {
514 stmt.line_number = _md_get_linenumber (md);
515 _strncpy (stmt.segment.segname, _md_get_string (md),
516 sizeof (stmt.segment.segname));
517 token = _md_next_token (md);
518 if (token == _MD_CLASS)
519 {
520 token = _md_next_token (md);
521 if (token != _MD_quote && token != _MD_word)
522 ERROR (_MDE_NAME_EXPECTED);
523 _strncpy (stmt.segment.classname, _md_get_string (md),
524 sizeof (stmt.segment.classname));
525 token = _md_next_token (md);
526 }
527 else
528 stmt.segment.classname[0] = 0;
529 stmt.segment.attr = 0;
530 ok = TRUE;
531 while (ok)
532 {
533 switch (token)
534 {
535 case _MD_ALIAS:
536 stmt.segment.attr |= _MDS_ALIAS;
537 break;
538 case _MD_CONFORMING:
539 stmt.segment.attr |= _MDS_CONFORMING;
540 break;
541 case _MD_DISCARDABLE:
542 stmt.segment.attr |= _MDS_DISCARDABLE;
543 break;
544 case _MD_EXECUTEONLY:
545 stmt.segment.attr |= _MDS_EXECUTEONLY;
546 break;
547 case _MD_EXECUTEREAD:
548 stmt.segment.attr |= _MDS_EXECUTEREAD;
549 break;
550 case _MD_FIXED:
551 stmt.segment.attr |= _MDS_FIXED;
552 break;
553 case _MD_INVALID:
554 stmt.segment.attr |= _MDS_INVALID;
555 break;
556 case _MD_IOPL:
557 stmt.segment.attr |= _MDS_IOPL;
558 break;
559 case _MD_LOADONCALL:
560 stmt.segment.attr |= _MDS_LOADONCALL;
561 break;
562 case _MD_MIXED1632:
563 stmt.segment.attr |= _MDS_MIXED1632;
564 break;
565 case _MD_MOVEABLE:
566 stmt.segment.attr |= _MDS_MOVEABLE;
567 break;
568 case _MD_NOIOPL:
569 stmt.segment.attr |= _MDS_NOIOPL;
570 break;
571 case _MD_NONCONFORMING:
572 stmt.segment.attr |= _MDS_NONCONFORMING;
573 break;
574 case _MD_NONDISCARDABLE:
575 stmt.segment.attr |= _MDS_NONDISCARDABLE;
576 break;
577 case _MD_NONSHARED:
578 case _MD_IMPURE:
579 stmt.segment.attr |= _MDS_NONSHARED;
580 break;
581 case _MD_PRELOAD:
582 stmt.segment.attr |= _MDS_PRELOAD;
583 break;
584 case _MD_READONLY:
585 stmt.segment.attr |= _MDS_READONLY;
586 break;
587 case _MD_READWRITE:
588 stmt.segment.attr |= _MDS_READWRITE;
589 break;
590 case _MD_SHARED:
591 case _MD_PURE:
592 stmt.segment.attr |= _MDS_SHARED;
593 break;
594 default:
595 ok = FALSE;
596 break;
597 }
598 if (ok)
599 token = _md_next_token (md);
600 }
601 CALLBACK;
602 }
603 break;
604
605 case _MD_STACKSIZE:
606 token = _md_next_token (md);
607 if (token != _MD_number)
608 ERROR (_MDE_NUMBER_EXPECTED);
609 stmt.stacksize.size = _md_get_number (md);
610 token = _md_next_token (md);
611 CALLBACK;
612 break;
613
614 case _MD_STUB:
615 token = _md_next_token (md);
616 if (token == _MD_quote)
617 {
618 _strncpy (stmt.stub.name, _md_get_string (md),
619 sizeof (stmt.stub.name));
620 stmt.stub.none = FALSE;
621 }
622 else if (token == _MD_NONE)
623 {
624 stmt.stub.name[0] = 0;
625 stmt.stub.none = TRUE;
626 }
627 else
628 ERROR (_MDE_STRING_EXPECTED);
629 token = _md_next_token (md);
630 CALLBACK;
631 break;
632
633 case _MD_ioerror:
634 ERROR (_MDE_IO_ERROR);
635 break;
636
637 case _MD_missingquote:
638 ERROR (_MDE_MISSING_QUOTE);
639 break;
640
641 default:
642 ERROR (_MDE_INVALID_STMT);
643 }
644 }
645 return 0;
646}
Note: See TracBrowser for help on using the repository browser.