2001-08-29 Joel Sherrill <joel@OARcorp.com>
[deliverable/binutils-gdb.git] / ld / deffilep.y
1 %{ /* deffilep.y - parser for .def files */
2
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include <stdio.h>
22 #include <ctype.h>
23 #include "libiberty.h"
24 #include "bfd.h"
25 #include "sysdep.h"
26 #include "ld.h"
27 #include "ldmisc.h"
28 #include "deffile.h"
29
30 #define TRACE 0
31
32 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
33
34 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
35 as well as gratuitiously global symbol names, so we can have multiple
36 yacc generated parsers in ld. Note that these are only the variables
37 produced by yacc. If other parser generators (bison, byacc, etc) produce
38 additional global names that conflict at link time, then those parser
39 generators need to be fixed instead of adding those names to this list. */
40
41 #define yymaxdepth def_maxdepth
42 #define yyparse def_parse
43 #define yylex def_lex
44 #define yyerror def_error
45 #define yylval def_lval
46 #define yychar def_char
47 #define yydebug def_debug
48 #define yypact def_pact
49 #define yyr1 def_r1
50 #define yyr2 def_r2
51 #define yydef def_def
52 #define yychk def_chk
53 #define yypgo def_pgo
54 #define yyact def_act
55 #define yyexca def_exca
56 #define yyerrflag def_errflag
57 #define yynerrs def_nerrs
58 #define yyps def_ps
59 #define yypv def_pv
60 #define yys def_s
61 #define yy_yys def_yys
62 #define yystate def_state
63 #define yytmp def_tmp
64 #define yyv def_v
65 #define yy_yyv def_yyv
66 #define yyval def_val
67 #define yylloc def_lloc
68 #define yyreds def_reds /* With YYDEBUG defined */
69 #define yytoks def_toks /* With YYDEBUG defined */
70 #define yylhs def_yylhs
71 #define yylen def_yylen
72 #define yydefred def_yydefred
73 #define yydgoto def_yydgoto
74 #define yysindex def_yysindex
75 #define yyrindex def_yyrindex
76 #define yygindex def_yygindex
77 #define yytable def_yytable
78 #define yycheck def_yycheck
79
80 static void def_description PARAMS ((const char *));
81 static void def_exports PARAMS ((const char *, const char *, int, int));
82 static void def_heapsize PARAMS ((int, int));
83 static void def_import
84 PARAMS ((const char *, const char *, const char *, const char *, int));
85 static void def_library PARAMS ((const char *, int));
86 static def_file_module *def_stash_module PARAMS ((def_file *, char *));
87 static void def_name PARAMS ((const char *, int));
88 static void def_section PARAMS ((const char *, int));
89 static void def_section_alt PARAMS ((const char *, const char *));
90 static void def_stacksize PARAMS ((int, int));
91 static void def_version PARAMS ((int, int));
92 static void def_directive PARAMS ((char *));
93 static int def_parse PARAMS ((void));
94 static int def_error PARAMS ((const char *));
95 static void put_buf PARAMS ((char));
96 static int def_getc PARAMS ((void));
97 static int def_ungetc PARAMS ((int));
98 static int def_lex PARAMS ((void));
99
100 static int lex_forced_token = 0;
101 static const char *lex_parse_string = 0;
102 static const char *lex_parse_string_end = 0;
103
104 %}
105
106 %union {
107 char *id;
108 int number;
109 };
110
111 %token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATAU, DATAL
112 %token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANTU, CONSTANTL
113 %token PRIVATEU, PRIVATEL
114 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
115 %token <id> ID
116 %token <number> NUMBER
117 %type <number> opt_base opt_ordinal
118 %type <number> attr attr_list opt_number exp_opt_list exp_opt
119 %type <id> opt_name opt_equal_name
120
121 %%
122
123 start: start command
124 | command
125 ;
126
127 command:
128 NAME opt_name opt_base { def_name ($2, $3); }
129 | LIBRARY opt_name opt_base { def_library ($2, $3); }
130 | DESCRIPTION ID { def_description ($2);}
131 | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
132 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
133 | CODE attr_list { def_section ("CODE", $2);}
134 | DATAU attr_list { def_section ("DATA", $2);}
135 | SECTIONS seclist
136 | EXPORTS explist
137 | IMPORTS implist
138 | VERSIONK NUMBER { def_version ($2, 0);}
139 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
140 | DIRECTIVE ID { def_directive ($2);}
141 ;
142
143
144 explist:
145 /* EMPTY */
146 | expline
147 | explist expline
148 ;
149
150 expline:
151 /* The opt_comma is necessary to support both the usual
152 DEF file syntax as well as .drectve syntax which
153 mandates <expsym>,<expoptlist>. */
154 ID opt_equal_name opt_ordinal opt_comma exp_opt_list
155 { def_exports ($1, $2, $3, $5); }
156 ;
157 exp_opt_list:
158 /* The opt_comma is necessary to support both the usual
159 DEF file syntax as well as .drectve syntax which
160 allows for comma separated opt list. */
161 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
162 | { $$ = 0; }
163 ;
164 exp_opt:
165 NONAMEU { $$ = 1; }
166 | NONAMEL { $$ = 1; }
167 | CONSTANTU { $$ = 2; }
168 | CONSTANTL { $$ = 2; }
169 | DATAU { $$ = 4; }
170 | DATAL { $$ = 4; }
171 | PRIVATEU { $$ = 8; }
172 | PRIVATEL { $$ = 8; }
173 ;
174 implist:
175 implist impline
176 | impline
177 ;
178
179 impline:
180 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
181 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
182 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
183 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
184 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
185 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
186 ;
187
188 seclist:
189 seclist secline
190 | secline
191 ;
192
193 secline:
194 ID attr_list { def_section ($1, $2);}
195 | ID ID { def_section_alt ($1, $2);}
196 ;
197
198 attr_list:
199 attr_list opt_comma attr { $$ = $1 | $3; }
200 | attr { $$ = $1; }
201 ;
202
203 opt_comma:
204 ','
205 |
206 ;
207 opt_number: ',' NUMBER { $$=$2;}
208 | { $$=-1;}
209 ;
210
211 attr:
212 READ { $$ = 1;}
213 | WRITE { $$ = 2;}
214 | EXECUTE { $$=4;}
215 | SHARED { $$=8;}
216 ;
217
218 opt_name: ID { $$ = $1; }
219 | ID '.' ID
220 {
221 char * name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
222 sprintf (name, "%s.%s", $1, $3);
223 $$ = name;
224 }
225 | { $$ = ""; }
226 ;
227
228 opt_ordinal:
229 '@' NUMBER { $$ = $2;}
230 | { $$ = -1;}
231 ;
232
233 opt_equal_name:
234 '=' ID { $$ = $2; }
235 | { $$ = 0; }
236 ;
237
238 opt_base: BASE '=' NUMBER { $$ = $3;}
239 | { $$ = 0;}
240 ;
241
242
243
244 %%
245
246 /*****************************************************************************
247 API
248 *****************************************************************************/
249
250 static FILE *the_file;
251 static const char *def_filename;
252 static int linenumber;
253 static def_file *def;
254 static int saw_newline;
255
256 struct directive
257 {
258 struct directive *next;
259 char *name;
260 int len;
261 };
262
263 static struct directive *directives = 0;
264
265 def_file *
266 def_file_empty ()
267 {
268 def_file *rv = (def_file *) xmalloc (sizeof (def_file));
269 memset (rv, 0, sizeof (def_file));
270 rv->is_dll = -1;
271 rv->base_address = (bfd_vma) (-1);
272 rv->stack_reserve = rv->stack_commit = -1;
273 rv->heap_reserve = rv->heap_commit = -1;
274 rv->version_major = rv->version_minor = -1;
275 return rv;
276 }
277
278 def_file *
279 def_file_parse (filename, add_to)
280 const char *filename;
281 def_file *add_to;
282 {
283 struct directive *d;
284
285 the_file = fopen (filename, "r");
286 def_filename = filename;
287 linenumber = 1;
288 if (!the_file)
289 {
290 perror (filename);
291 return 0;
292 }
293 if (add_to)
294 {
295 def = add_to;
296 }
297 else
298 {
299 def = def_file_empty ();
300 }
301
302 saw_newline = 1;
303 if (def_parse ())
304 {
305 def_file_free (def);
306 fclose (the_file);
307 return 0;
308 }
309
310 fclose (the_file);
311
312 for (d = directives; d; d = d->next)
313 {
314 #if TRACE
315 printf ("Adding directive %08x `%s'\n", d->name, d->name);
316 #endif
317 def_file_add_directive (def, d->name, d->len);
318 }
319
320 return def;
321 }
322
323 void
324 def_file_free (def)
325 def_file *def;
326 {
327 int i;
328 if (!def)
329 return;
330 if (def->name)
331 free (def->name);
332 if (def->description)
333 free (def->description);
334
335 if (def->section_defs)
336 {
337 for (i = 0; i < def->num_section_defs; i++)
338 {
339 if (def->section_defs[i].name)
340 free (def->section_defs[i].name);
341 if (def->section_defs[i].class)
342 free (def->section_defs[i].class);
343 }
344 free (def->section_defs);
345 }
346
347 if (def->exports)
348 {
349 for (i = 0; i < def->num_exports; i++)
350 {
351 if (def->exports[i].internal_name
352 && def->exports[i].internal_name != def->exports[i].name)
353 free (def->exports[i].internal_name);
354 if (def->exports[i].name)
355 free (def->exports[i].name);
356 }
357 free (def->exports);
358 }
359
360 if (def->imports)
361 {
362 for (i = 0; i < def->num_imports; i++)
363 {
364 if (def->imports[i].internal_name
365 && def->imports[i].internal_name != def->imports[i].name)
366 free (def->imports[i].internal_name);
367 if (def->imports[i].name)
368 free (def->imports[i].name);
369 }
370 free (def->imports);
371 }
372
373 while (def->modules)
374 {
375 def_file_module *m = def->modules;
376 def->modules = def->modules->next;
377 free (m);
378 }
379
380 free (def);
381 }
382
383 #ifdef DEF_FILE_PRINT
384 void
385 def_file_print (file, def)
386 FILE *file;
387 def_file *def;
388 {
389 int i;
390 fprintf (file, ">>>> def_file at 0x%08x\n", def);
391 if (def->name)
392 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
393 if (def->is_dll != -1)
394 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
395 if (def->base_address != (bfd_vma) (-1))
396 fprintf (file, " base address: 0x%08x\n", def->base_address);
397 if (def->description)
398 fprintf (file, " description: `%s'\n", def->description);
399 if (def->stack_reserve != -1)
400 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
401 if (def->stack_commit != -1)
402 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
403 if (def->heap_reserve != -1)
404 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
405 if (def->heap_commit != -1)
406 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
407
408 if (def->num_section_defs > 0)
409 {
410 fprintf (file, " section defs:\n");
411 for (i = 0; i < def->num_section_defs; i++)
412 {
413 fprintf (file, " name: `%s', class: `%s', flags:",
414 def->section_defs[i].name, def->section_defs[i].class);
415 if (def->section_defs[i].flag_read)
416 fprintf (file, " R");
417 if (def->section_defs[i].flag_write)
418 fprintf (file, " W");
419 if (def->section_defs[i].flag_execute)
420 fprintf (file, " X");
421 if (def->section_defs[i].flag_shared)
422 fprintf (file, " S");
423 fprintf (file, "\n");
424 }
425 }
426
427 if (def->num_exports > 0)
428 {
429 fprintf (file, " exports:\n");
430 for (i = 0; i < def->num_exports; i++)
431 {
432 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
433 def->exports[i].name, def->exports[i].internal_name,
434 def->exports[i].ordinal);
435 if (def->exports[i].flag_private)
436 fprintf (file, " P");
437 if (def->exports[i].flag_constant)
438 fprintf (file, " C");
439 if (def->exports[i].flag_noname)
440 fprintf (file, " N");
441 if (def->exports[i].flag_data)
442 fprintf (file, " D");
443 fprintf (file, "\n");
444 }
445 }
446
447 if (def->num_imports > 0)
448 {
449 fprintf (file, " imports:\n");
450 for (i = 0; i < def->num_imports; i++)
451 {
452 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
453 def->imports[i].internal_name,
454 def->imports[i].module,
455 def->imports[i].name,
456 def->imports[i].ordinal);
457 }
458 }
459 if (def->version_major != -1)
460 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
461 fprintf (file, "<<<< def_file at 0x%08x\n", def);
462 }
463 #endif
464
465 def_file_export *
466 def_file_add_export (def, external_name, internal_name, ordinal)
467 def_file *def;
468 const char *external_name;
469 const char *internal_name;
470 int ordinal;
471 {
472 def_file_export *e;
473 int max_exports = ROUND_UP(def->num_exports, 32);
474 if (def->num_exports >= max_exports)
475 {
476 max_exports = ROUND_UP(def->num_exports+1, 32);
477 if (def->exports)
478 def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export));
479 else
480 def->exports = (def_file_export *) xmalloc (max_exports * sizeof (def_file_export));
481 }
482 e = def->exports + def->num_exports;
483 memset (e, 0, sizeof (def_file_export));
484 if (internal_name && !external_name)
485 external_name = internal_name;
486 if (external_name && !internal_name)
487 internal_name = external_name;
488 e->name = xstrdup (external_name);
489 e->internal_name = xstrdup (internal_name);
490 e->ordinal = ordinal;
491 def->num_exports++;
492 return e;
493 }
494
495 static def_file_module *
496 def_stash_module (def, name)
497 def_file *def;
498 char *name;
499 {
500 def_file_module *s;
501 for (s=def->modules; s; s=s->next)
502 if (strcmp (s->name, name) == 0)
503 return s;
504 s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name));
505 s->next = def->modules;
506 def->modules = s;
507 s->user_data = 0;
508 strcpy (s->name, name);
509 return s;
510 }
511
512 def_file_import *
513 def_file_add_import (def, name, module, ordinal, internal_name)
514 def_file *def;
515 const char *name;
516 const char *module;
517 int ordinal;
518 const char *internal_name;
519 {
520 def_file_import *i;
521 int max_imports = ROUND_UP(def->num_imports, 16);
522 if (def->num_imports >= max_imports)
523 {
524 max_imports = ROUND_UP(def->num_imports+1, 16);
525 if (def->imports)
526 def->imports = (def_file_import *) xrealloc (def->imports, max_imports * sizeof (def_file_import));
527 else
528 def->imports = (def_file_import *) xmalloc (max_imports * sizeof (def_file_import));
529 }
530 i = def->imports + def->num_imports;
531 memset (i, 0, sizeof (def_file_import));
532 if (name)
533 i->name = xstrdup (name);
534 if (module)
535 i->module = def_stash_module(def, module);
536 i->ordinal = ordinal;
537 if (internal_name)
538 i->internal_name = xstrdup (internal_name);
539 else
540 i->internal_name = i->name;
541 def->num_imports++;
542 return i;
543 }
544
545 struct
546 {
547 char *param;
548 int token;
549 }
550 diropts[] =
551 {
552 { "-heap", HEAPSIZE },
553 { "-stack", STACKSIZE },
554 { "-attr", SECTIONS },
555 { "-export", EXPORTS },
556 { 0, 0 }
557 };
558
559 void
560 def_file_add_directive (my_def, param, len)
561 def_file *my_def;
562 const char *param;
563 int len;
564 {
565 def_file *save_def = def;
566 const char *pend = param + len;
567 const char *tend = param;
568 int i;
569
570 def = my_def;
571
572 while (param < pend)
573 {
574 while (param < pend && isspace (*param))
575 param++;
576 for (tend = param + 1;
577 tend < pend && !(isspace (tend[-1]) && *tend == '-');
578 tend++);
579
580 for (i = 0; diropts[i].param; i++)
581 {
582 int len = strlen (diropts[i].param);
583 if (tend - param >= len
584 && strncmp (param, diropts[i].param, len) == 0
585 && (param[len] == ':' || param[len] == ' '))
586 {
587 lex_parse_string_end = tend;
588 lex_parse_string = param + len + 1;
589 lex_forced_token = diropts[i].token;
590 saw_newline = 0;
591 def_parse ();
592 break;
593 }
594 }
595
596 if (!diropts[i].param)
597 {
598 /* xgettext:c-format */
599 einfo (_("Warning: .drectve `%.*s' unrecognized\n"),
600 tend - param, param);
601 }
602 lex_parse_string = 0;
603 param = tend;
604 }
605
606 def = save_def;
607 }
608
609 /*****************************************************************************
610 Parser Callbacks
611 *****************************************************************************/
612
613 static void
614 def_name (name, base)
615 const char *name;
616 int base;
617 {
618 if (def->name)
619 free (def->name);
620 def->name = xstrdup (name);
621 def->base_address = base;
622 def->is_dll = 0;
623 }
624
625 static void
626 def_library (name, base)
627 const char *name;
628 int base;
629 {
630 if (def->name)
631 free (def->name);
632 def->name = xstrdup (name);
633 def->base_address = base;
634 def->is_dll = 1;
635 }
636
637 static void
638 def_description (text)
639 const char *text;
640 {
641 int len = def->description ? strlen (def->description) : 0;
642 len += strlen (text) + 1;
643 if (def->description)
644 {
645 def->description = (char *) xrealloc (def->description, len);
646 strcat (def->description, text);
647 }
648 else
649 {
650 def->description = (char *) xmalloc (len);
651 strcpy (def->description, text);
652 }
653 }
654
655 static void
656 def_stacksize (reserve, commit)
657 int reserve;
658 int commit;
659 {
660 def->stack_reserve = reserve;
661 def->stack_commit = commit;
662 }
663
664 static void
665 def_heapsize (reserve, commit)
666 int reserve;
667 int commit;
668 {
669 def->heap_reserve = reserve;
670 def->heap_commit = commit;
671 }
672
673 static void
674 def_section (name, attr)
675 const char *name;
676 int attr;
677 {
678 def_file_section *s;
679 int max_sections = ROUND_UP(def->num_section_defs, 4);
680 if (def->num_section_defs >= max_sections)
681 {
682 max_sections = ROUND_UP(def->num_section_defs+1, 4);
683 if (def->section_defs)
684 def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
685 else
686 def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import));
687 }
688 s = def->section_defs + def->num_section_defs;
689 memset (s, 0, sizeof (def_file_section));
690 s->name = xstrdup (name);
691 if (attr & 1)
692 s->flag_read = 1;
693 if (attr & 2)
694 s->flag_write = 1;
695 if (attr & 4)
696 s->flag_execute = 1;
697 if (attr & 8)
698 s->flag_shared = 1;
699
700 def->num_section_defs++;
701 }
702
703 static void
704 def_section_alt (name, attr)
705 const char *name;
706 const char *attr;
707 {
708 int aval = 0;
709 for (; *attr; attr++)
710 {
711 switch (*attr)
712 {
713 case 'R':
714 case 'r':
715 aval |= 1;
716 break;
717 case 'W':
718 case 'w':
719 aval |= 2;
720 break;
721 case 'X':
722 case 'x':
723 aval |= 4;
724 break;
725 case 'S':
726 case 's':
727 aval |= 8;
728 break;
729 }
730 }
731 def_section (name, aval);
732 }
733
734 static void
735 def_exports (external_name, internal_name, ordinal, flags)
736 const char *external_name;
737 const char *internal_name;
738 int ordinal;
739 int flags;
740 {
741 def_file_export *dfe;
742
743 if (!internal_name && external_name)
744 internal_name = external_name;
745 #if TRACE
746 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
747 #endif
748
749 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
750 if (flags & 1)
751 dfe->flag_noname = 1;
752 if (flags & 2)
753 dfe->flag_constant = 1;
754 if (flags & 4)
755 dfe->flag_data = 1;
756 if (flags & 8)
757 dfe->flag_private = 1;
758 }
759
760 static void
761 def_import (internal_name, module, dllext, name, ordinal)
762 const char *internal_name;
763 const char *module;
764 const char *dllext;
765 const char *name;
766 int ordinal;
767 {
768 char *buf = 0;
769
770 if (dllext != NULL)
771 {
772 buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2);
773 sprintf (buf, "%s.%s", module, dllext);
774 module = buf;
775 }
776
777 def_file_add_import (def, name, module, ordinal, internal_name);
778 if (buf)
779 free (buf);
780 }
781
782 static void
783 def_version (major, minor)
784 int major;
785 int minor;
786 {
787 def->version_major = major;
788 def->version_minor = minor;
789 }
790
791 static void
792 def_directive (str)
793 char *str;
794 {
795 struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
796 d->next = directives;
797 directives = d;
798 d->name = xstrdup (str);
799 d->len = strlen (str);
800 }
801
802 static int
803 def_error (err)
804 const char *err;
805 {
806 einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err);
807
808 return 0;
809 }
810
811
812 /*****************************************************************************
813 Lexical Scanner
814 *****************************************************************************/
815
816 #undef TRACE
817 #define TRACE 0
818
819 /* Never freed, but always reused as needed, so no real leak */
820 static char *buffer = 0;
821 static int buflen = 0;
822 static int bufptr = 0;
823
824 static void
825 put_buf (c)
826 char c;
827 {
828 if (bufptr == buflen)
829 {
830 buflen += 50; /* overly reasonable, eh? */
831 if (buffer)
832 buffer = (char *) xrealloc (buffer, buflen + 1);
833 else
834 buffer = (char *) xmalloc (buflen + 1);
835 }
836 buffer[bufptr++] = c;
837 buffer[bufptr] = 0; /* not optimal, but very convenient */
838 }
839
840 static struct
841 {
842 char *name;
843 int token;
844 }
845 tokens[] =
846 {
847 { "BASE", BASE },
848 { "CODE", CODE },
849 { "CONSTANT", CONSTANTU },
850 { "constant", CONSTANTL },
851 { "DATA", DATAU },
852 { "data", DATAL },
853 { "DESCRIPTION", DESCRIPTION },
854 { "DIRECTIVE", DIRECTIVE },
855 { "EXECUTE", EXECUTE },
856 { "EXPORTS", EXPORTS },
857 { "HEAPSIZE", HEAPSIZE },
858 { "IMPORTS", IMPORTS },
859 { "LIBRARY", LIBRARY },
860 { "NAME", NAME },
861 { "NONAME", NONAMEU },
862 { "noname", NONAMEL },
863 { "PRIVATE", PRIVATEU },
864 { "private", PRIVATEL },
865 { "READ", READ },
866 { "SECTIONS", SECTIONS },
867 { "SEGMENTS", SECTIONS },
868 { "SHARED", SHARED },
869 { "STACKSIZE", STACKSIZE },
870 { "VERSION", VERSIONK },
871 { "WRITE", WRITE },
872 { 0, 0 }
873 };
874
875 static int
876 def_getc ()
877 {
878 int rv;
879 if (lex_parse_string)
880 {
881 if (lex_parse_string >= lex_parse_string_end)
882 rv = EOF;
883 else
884 rv = *lex_parse_string++;
885 }
886 else
887 {
888 rv = fgetc (the_file);
889 }
890 if (rv == '\n')
891 saw_newline = 1;
892 return rv;
893 }
894
895 static int
896 def_ungetc (c)
897 int c;
898 {
899 if (lex_parse_string)
900 {
901 lex_parse_string--;
902 return c;
903 }
904 else
905 return ungetc (c, the_file);
906 }
907
908 static int
909 def_lex ()
910 {
911 int c, i, q;
912
913 if (lex_forced_token)
914 {
915 i = lex_forced_token;
916 lex_forced_token = 0;
917 #if TRACE
918 printf ("lex: forcing token %d\n", i);
919 #endif
920 return i;
921 }
922
923 c = def_getc ();
924
925 /* trim leading whitespace */
926 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
927 c = def_getc ();
928
929 if (c == EOF)
930 {
931 #if TRACE
932 printf ("lex: EOF\n");
933 #endif
934 return 0;
935 }
936
937 if (saw_newline && c == ';')
938 {
939 do
940 {
941 c = def_getc ();
942 }
943 while (c != EOF && c != '\n');
944 if (c == '\n')
945 return def_lex ();
946 return 0;
947 }
948 /* must be something else */
949 saw_newline = 0;
950
951 if (isdigit (c))
952 {
953 bufptr = 0;
954 while (c != EOF && (isxdigit (c) || (c == 'x')))
955 {
956 put_buf (c);
957 c = def_getc ();
958 }
959 if (c != EOF)
960 def_ungetc (c);
961 yylval.number = strtoul (buffer, 0, 0);
962 #if TRACE
963 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
964 #endif
965 return NUMBER;
966 }
967
968 if (isalpha (c) || strchr ("$:-_?", c))
969 {
970 bufptr = 0;
971 while (c != EOF && (isalnum (c) || strchr ("$:-_?/@", c)))
972 {
973 put_buf (c);
974 c = def_getc ();
975 }
976 if (c != EOF)
977 def_ungetc (c);
978 for (i = 0; tokens[i].name; i++)
979 if (strcmp (tokens[i].name, buffer) == 0)
980 {
981 #if TRACE
982 printf ("lex: `%s' is a string token\n", buffer);
983 #endif
984 return tokens[i].token;
985 }
986 #if TRACE
987 printf ("lex: `%s' returns ID\n", buffer);
988 #endif
989 yylval.id = xstrdup (buffer);
990 return ID;
991 }
992
993 if (c == '\'' || c == '"')
994 {
995 q = c;
996 c = def_getc ();
997 bufptr = 0;
998 while (c != EOF && c != q)
999 {
1000 put_buf (c);
1001 c = def_getc ();
1002 }
1003 yylval.id = xstrdup (buffer);
1004 #if TRACE
1005 printf ("lex: `%s' returns ID\n", buffer);
1006 #endif
1007 return ID;
1008 }
1009
1010 if (c == '=' || c == '.' || c == '@' || c == ',')
1011 {
1012 #if TRACE
1013 printf ("lex: `%c' returns itself\n", c);
1014 #endif
1015 return c;
1016 }
1017
1018 if (c == '\n')
1019 {
1020 linenumber++;
1021 saw_newline = 1;
1022 }
1023
1024 /*printf ("lex: 0x%02x ignored\n", c); */
1025 return def_lex ();
1026 }
This page took 0.051489 seconds and 4 git commands to generate.