ld/ChangeLog
[binutils.git] / ld / deffilep.y
blob83872f5981be3fb4671a1fa9d74cd61ed1fd3181
1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 #include "sysdep.h"
24 #include "libiberty.h"
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "ld.h"
28 #include "ldmisc.h"
29 #include "deffile.h"
31 #define TRACE 0
33 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
35 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
36 as well as gratuitiously global symbol names, so we can have multiple
37 yacc generated parsers in ld. Note that these are only the variables
38 produced by yacc. If other parser generators (bison, byacc, etc) produce
39 additional global names that conflict at link time, then those parser
40 generators need to be fixed instead of adding those names to this list. */
42 #define yymaxdepth def_maxdepth
43 #define yyparse def_parse
44 #define yylex def_lex
45 #define yyerror def_error
46 #define yylval def_lval
47 #define yychar def_char
48 #define yydebug def_debug
49 #define yypact def_pact
50 #define yyr1 def_r1
51 #define yyr2 def_r2
52 #define yydef def_def
53 #define yychk def_chk
54 #define yypgo def_pgo
55 #define yyact def_act
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
59 #define yyps def_ps
60 #define yypv def_pv
61 #define yys def_s
62 #define yy_yys def_yys
63 #define yystate def_state
64 #define yytmp def_tmp
65 #define yyv def_v
66 #define yy_yyv def_yyv
67 #define yyval def_val
68 #define yylloc def_lloc
69 #define yyreds def_reds /* With YYDEBUG defined. */
70 #define yytoks def_toks /* With YYDEBUG defined. */
71 #define yylhs def_yylhs
72 #define yylen def_yylen
73 #define yydefred def_yydefred
74 #define yydgoto def_yydgoto
75 #define yysindex def_yysindex
76 #define yyrindex def_yyrindex
77 #define yygindex def_yygindex
78 #define yytable def_yytable
79 #define yycheck def_yycheck
81 static void def_description (const char *);
82 static void def_exports (const char *, const char *, int, int);
83 static void def_heapsize (int, int);
84 static void def_import (const char *, const char *, const char *, const char *,
85 int);
86 static void def_image_name (const char *, int, int);
87 static void def_section (const char *, int);
88 static void def_section_alt (const char *, const char *);
89 static void def_stacksize (int, int);
90 static void def_version (int, int);
91 static void def_directive (char *);
92 static void def_aligncomm (char *str, int align);
93 static int def_parse (void);
94 static int def_error (const char *);
95 static int def_lex (void);
97 static int lex_forced_token = 0;
98 static const char *lex_parse_string = 0;
99 static const char *lex_parse_string_end = 0;
103 %union {
104 char *id;
105 int number;
106 char *digits;
109 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
110 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
111 %token PRIVATEU PRIVATEL ALIGNCOMM
112 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
113 %token <id> ID
114 %token <digits> DIGITS
115 %type <number> NUMBER
116 %type <digits> opt_digits
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 dot_name anylang_id opt_id
123 start: start command
124 | command
127 command:
128 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
129 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
130 | DESCRIPTION ID { def_description ($2);}
131 | STACKSIZE_K 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 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
145 explist:
146 /* EMPTY */
147 | expline
148 | explist expline
151 expline:
152 /* The opt_comma is necessary to support both the usual
153 DEF file syntax as well as .drectve syntax which
154 mandates <expsym>,<expoptlist>. */
155 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
156 { def_exports ($1, $2, $3, $5); }
158 exp_opt_list:
159 /* The opt_comma is necessary to support both the usual
160 DEF file syntax as well as .drectve syntax which
161 allows for comma separated opt list. */
162 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
163 | { $$ = 0; }
165 exp_opt:
166 NONAMEU { $$ = 1; }
167 | NONAMEL { $$ = 1; }
168 | CONSTANTU { $$ = 2; }
169 | CONSTANTL { $$ = 2; }
170 | DATAU { $$ = 4; }
171 | DATAL { $$ = 4; }
172 | PRIVATEU { $$ = 8; }
173 | PRIVATEL { $$ = 8; }
175 implist:
176 implist impline
177 | impline
180 impline:
181 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
182 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
183 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
184 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
185 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
186 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
189 seclist:
190 seclist secline
191 | secline
194 secline:
195 ID attr_list { def_section ($1, $2);}
196 | ID ID { def_section_alt ($1, $2);}
199 attr_list:
200 attr_list opt_comma attr { $$ = $1 | $3; }
201 | attr { $$ = $1; }
204 opt_comma:
208 opt_number: ',' NUMBER { $$=$2;}
209 | { $$=-1;}
212 attr:
213 READ { $$ = 1;}
214 | WRITE { $$ = 2;}
215 | EXECUTE { $$=4;}
216 | SHARED { $$=8;}
219 opt_name: ID { $$ = $1; }
220 | ID '.' ID
222 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
223 sprintf (name, "%s.%s", $1, $3);
224 $$ = name;
226 | { $$ = ""; }
229 opt_ordinal:
230 '@' NUMBER { $$ = $2;}
231 | { $$ = -1;}
234 opt_equal_name:
235 '=' dot_name { $$ = $2; }
236 | { $$ = 0; }
239 opt_base: BASE '=' NUMBER { $$ = $3;}
240 | { $$ = -1;}
243 dot_name: ID { $$ = $1; }
244 | dot_name '.' ID
246 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
247 sprintf (name, "%s.%s", $1, $3);
248 $$ = name;
252 anylang_id: ID { $$ = $1; }
253 | anylang_id '.' opt_digits opt_id
255 char *id = xmalloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
256 sprintf (id, "%s.%s%s", $1, $3, $4);
257 $$ = id;
261 opt_digits: DIGITS { $$ = $1; }
262 | { $$ = ""; }
265 opt_id: ID { $$ = $1; }
266 | { $$ = ""; }
269 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
273 /*****************************************************************************
275 *****************************************************************************/
277 static FILE *the_file;
278 static const char *def_filename;
279 static int linenumber;
280 static def_file *def;
281 static int saw_newline;
283 struct directive
285 struct directive *next;
286 char *name;
287 int len;
290 static struct directive *directives = 0;
292 def_file *
293 def_file_empty (void)
295 def_file *rv = xmalloc (sizeof (def_file));
296 memset (rv, 0, sizeof (def_file));
297 rv->is_dll = -1;
298 rv->base_address = (bfd_vma) -1;
299 rv->stack_reserve = rv->stack_commit = -1;
300 rv->heap_reserve = rv->heap_commit = -1;
301 rv->version_major = rv->version_minor = -1;
302 return rv;
305 def_file *
306 def_file_parse (const char *filename, def_file *add_to)
308 struct directive *d;
310 the_file = fopen (filename, "r");
311 def_filename = filename;
312 linenumber = 1;
313 if (!the_file)
315 perror (filename);
316 return 0;
318 if (add_to)
320 def = add_to;
322 else
324 def = def_file_empty ();
327 saw_newline = 1;
328 if (def_parse ())
330 def_file_free (def);
331 fclose (the_file);
332 return 0;
335 fclose (the_file);
337 for (d = directives; d; d = d->next)
339 #if TRACE
340 printf ("Adding directive %08x `%s'\n", d->name, d->name);
341 #endif
342 def_file_add_directive (def, d->name, d->len);
345 return def;
348 void
349 def_file_free (def_file *def)
351 int i;
353 if (!def)
354 return;
355 if (def->name)
356 free (def->name);
357 if (def->description)
358 free (def->description);
360 if (def->section_defs)
362 for (i = 0; i < def->num_section_defs; i++)
364 if (def->section_defs[i].name)
365 free (def->section_defs[i].name);
366 if (def->section_defs[i].class)
367 free (def->section_defs[i].class);
369 free (def->section_defs);
372 if (def->exports)
374 for (i = 0; i < def->num_exports; i++)
376 if (def->exports[i].internal_name
377 && def->exports[i].internal_name != def->exports[i].name)
378 free (def->exports[i].internal_name);
379 if (def->exports[i].name)
380 free (def->exports[i].name);
382 free (def->exports);
385 if (def->imports)
387 for (i = 0; i < def->num_imports; i++)
389 if (def->imports[i].internal_name
390 && def->imports[i].internal_name != def->imports[i].name)
391 free (def->imports[i].internal_name);
392 if (def->imports[i].name)
393 free (def->imports[i].name);
395 free (def->imports);
398 while (def->modules)
400 def_file_module *m = def->modules;
401 def->modules = def->modules->next;
402 free (m);
405 while (def->aligncomms)
407 def_file_aligncomm *c = def->aligncomms;
408 def->aligncomms = def->aligncomms->next;
409 free (c->symbol_name);
410 free (c);
413 free (def);
416 #ifdef DEF_FILE_PRINT
417 void
418 def_file_print (FILE *file, def_file *def)
420 int i;
422 fprintf (file, ">>>> def_file at 0x%08x\n", def);
423 if (def->name)
424 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
425 if (def->is_dll != -1)
426 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
427 if (def->base_address != (bfd_vma) -1)
428 fprintf (file, " base address: 0x%08x\n", def->base_address);
429 if (def->description)
430 fprintf (file, " description: `%s'\n", def->description);
431 if (def->stack_reserve != -1)
432 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
433 if (def->stack_commit != -1)
434 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
435 if (def->heap_reserve != -1)
436 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
437 if (def->heap_commit != -1)
438 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
440 if (def->num_section_defs > 0)
442 fprintf (file, " section defs:\n");
444 for (i = 0; i < def->num_section_defs; i++)
446 fprintf (file, " name: `%s', class: `%s', flags:",
447 def->section_defs[i].name, def->section_defs[i].class);
448 if (def->section_defs[i].flag_read)
449 fprintf (file, " R");
450 if (def->section_defs[i].flag_write)
451 fprintf (file, " W");
452 if (def->section_defs[i].flag_execute)
453 fprintf (file, " X");
454 if (def->section_defs[i].flag_shared)
455 fprintf (file, " S");
456 fprintf (file, "\n");
460 if (def->num_exports > 0)
462 fprintf (file, " exports:\n");
464 for (i = 0; i < def->num_exports; i++)
466 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
467 def->exports[i].name, def->exports[i].internal_name,
468 def->exports[i].ordinal);
469 if (def->exports[i].flag_private)
470 fprintf (file, " P");
471 if (def->exports[i].flag_constant)
472 fprintf (file, " C");
473 if (def->exports[i].flag_noname)
474 fprintf (file, " N");
475 if (def->exports[i].flag_data)
476 fprintf (file, " D");
477 fprintf (file, "\n");
481 if (def->num_imports > 0)
483 fprintf (file, " imports:\n");
485 for (i = 0; i < def->num_imports; i++)
487 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
488 def->imports[i].internal_name,
489 def->imports[i].module,
490 def->imports[i].name,
491 def->imports[i].ordinal);
495 if (def->version_major != -1)
496 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
498 fprintf (file, "<<<< def_file at 0x%08x\n", def);
500 #endif
502 def_file_export *
503 def_file_add_export (def_file *def,
504 const char *external_name,
505 const char *internal_name,
506 int ordinal)
508 def_file_export *e;
509 int max_exports = ROUND_UP(def->num_exports, 32);
511 if (def->num_exports >= max_exports)
513 max_exports = ROUND_UP(def->num_exports + 1, 32);
514 if (def->exports)
515 def->exports = xrealloc (def->exports,
516 max_exports * sizeof (def_file_export));
517 else
518 def->exports = xmalloc (max_exports * sizeof (def_file_export));
520 e = def->exports + def->num_exports;
521 memset (e, 0, sizeof (def_file_export));
522 if (internal_name && !external_name)
523 external_name = internal_name;
524 if (external_name && !internal_name)
525 internal_name = external_name;
526 e->name = xstrdup (external_name);
527 e->internal_name = xstrdup (internal_name);
528 e->ordinal = ordinal;
529 def->num_exports++;
530 return e;
533 def_file_module *
534 def_get_module (def_file *def, const char *name)
536 def_file_module *s;
538 for (s = def->modules; s; s = s->next)
539 if (strcmp (s->name, name) == 0)
540 return s;
542 return NULL;
545 static def_file_module *
546 def_stash_module (def_file *def, const char *name)
548 def_file_module *s;
550 if ((s = def_get_module (def, name)) != NULL)
551 return s;
552 s = xmalloc (sizeof (def_file_module) + strlen (name));
553 s->next = def->modules;
554 def->modules = s;
555 s->user_data = 0;
556 strcpy (s->name, name);
557 return s;
560 def_file_import *
561 def_file_add_import (def_file *def,
562 const char *name,
563 const char *module,
564 int ordinal,
565 const char *internal_name)
567 def_file_import *i;
568 int max_imports = ROUND_UP (def->num_imports, 16);
570 if (def->num_imports >= max_imports)
572 max_imports = ROUND_UP (def->num_imports+1, 16);
574 if (def->imports)
575 def->imports = xrealloc (def->imports,
576 max_imports * sizeof (def_file_import));
577 else
578 def->imports = xmalloc (max_imports * sizeof (def_file_import));
580 i = def->imports + def->num_imports;
581 memset (i, 0, sizeof (def_file_import));
582 if (name)
583 i->name = xstrdup (name);
584 if (module)
585 i->module = def_stash_module (def, module);
586 i->ordinal = ordinal;
587 if (internal_name)
588 i->internal_name = xstrdup (internal_name);
589 else
590 i->internal_name = i->name;
591 def->num_imports++;
593 return i;
596 struct
598 char *param;
599 int token;
601 diropts[] =
603 { "-heap", HEAPSIZE },
604 { "-stack", STACKSIZE_K },
605 { "-attr", SECTIONS },
606 { "-export", EXPORTS },
607 { "-aligncomm", ALIGNCOMM },
608 { 0, 0 }
611 void
612 def_file_add_directive (def_file *my_def, const char *param, int len)
614 def_file *save_def = def;
615 const char *pend = param + len;
616 char * tend = (char *) param;
617 int i;
619 def = my_def;
621 while (param < pend)
623 while (param < pend
624 && (ISSPACE (*param) || *param == '\n' || *param == 0))
625 param++;
627 if (param == pend)
628 break;
630 /* Scan forward until we encounter any of:
631 - the end of the buffer
632 - the start of a new option
633 - a newline seperating options
634 - a NUL seperating options. */
635 for (tend = (char *) (param + 1);
636 (tend < pend
637 && !(ISSPACE (tend[-1]) && *tend == '-')
638 && *tend != '\n' && *tend != 0);
639 tend++)
642 for (i = 0; diropts[i].param; i++)
644 int len = strlen (diropts[i].param);
646 if (tend - param >= len
647 && strncmp (param, diropts[i].param, len) == 0
648 && (param[len] == ':' || param[len] == ' '))
650 lex_parse_string_end = tend;
651 lex_parse_string = param + len + 1;
652 lex_forced_token = diropts[i].token;
653 saw_newline = 0;
654 if (def_parse ())
655 continue;
656 break;
660 if (!diropts[i].param)
662 char saved;
664 saved = * tend;
665 * tend = 0;
666 /* xgettext:c-format */
667 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
668 * tend = saved;
671 lex_parse_string = 0;
672 param = tend;
675 def = save_def;
678 /* Parser Callbacks. */
680 static void
681 def_image_name (const char *name, int base, int is_dll)
683 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
684 to do here. We retain the output filename specified on command line. */
685 if (*name)
687 const char* image_name = lbasename (name);
688 if (image_name != name)
689 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
690 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
691 name);
692 if (def->name)
693 free (def->name);
694 /* Append the default suffix, if none specified. */
695 if (strchr (image_name, '.') == 0)
697 const char * suffix = is_dll ? ".dll" : ".exe";
699 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
700 sprintf (def->name, "%s%s", image_name, suffix);
702 else
703 def->name = xstrdup (image_name);
706 /* Honor a BASE address statement, even if LIBRARY string is empty. */
707 def->base_address = base;
708 def->is_dll = is_dll;
711 static void
712 def_description (const char *text)
714 int len = def->description ? strlen (def->description) : 0;
716 len += strlen (text) + 1;
717 if (def->description)
719 def->description = xrealloc (def->description, len);
720 strcat (def->description, text);
722 else
724 def->description = xmalloc (len);
725 strcpy (def->description, text);
729 static void
730 def_stacksize (int reserve, int commit)
732 def->stack_reserve = reserve;
733 def->stack_commit = commit;
736 static void
737 def_heapsize (int reserve, int commit)
739 def->heap_reserve = reserve;
740 def->heap_commit = commit;
743 static void
744 def_section (const char *name, int attr)
746 def_file_section *s;
747 int max_sections = ROUND_UP (def->num_section_defs, 4);
749 if (def->num_section_defs >= max_sections)
751 max_sections = ROUND_UP (def->num_section_defs+1, 4);
753 if (def->section_defs)
754 def->section_defs = xrealloc (def->section_defs,
755 max_sections * sizeof (def_file_import));
756 else
757 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
759 s = def->section_defs + def->num_section_defs;
760 memset (s, 0, sizeof (def_file_section));
761 s->name = xstrdup (name);
762 if (attr & 1)
763 s->flag_read = 1;
764 if (attr & 2)
765 s->flag_write = 1;
766 if (attr & 4)
767 s->flag_execute = 1;
768 if (attr & 8)
769 s->flag_shared = 1;
771 def->num_section_defs++;
774 static void
775 def_section_alt (const char *name, const char *attr)
777 int aval = 0;
779 for (; *attr; attr++)
781 switch (*attr)
783 case 'R':
784 case 'r':
785 aval |= 1;
786 break;
787 case 'W':
788 case 'w':
789 aval |= 2;
790 break;
791 case 'X':
792 case 'x':
793 aval |= 4;
794 break;
795 case 'S':
796 case 's':
797 aval |= 8;
798 break;
801 def_section (name, aval);
804 static void
805 def_exports (const char *external_name,
806 const char *internal_name,
807 int ordinal,
808 int flags)
810 def_file_export *dfe;
812 if (!internal_name && external_name)
813 internal_name = external_name;
814 #if TRACE
815 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
816 #endif
818 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
819 if (flags & 1)
820 dfe->flag_noname = 1;
821 if (flags & 2)
822 dfe->flag_constant = 1;
823 if (flags & 4)
824 dfe->flag_data = 1;
825 if (flags & 8)
826 dfe->flag_private = 1;
829 static void
830 def_import (const char *internal_name,
831 const char *module,
832 const char *dllext,
833 const char *name,
834 int ordinal)
836 char *buf = 0;
837 const char *ext = dllext ? dllext : "dll";
839 buf = xmalloc (strlen (module) + strlen (ext) + 2);
840 sprintf (buf, "%s.%s", module, ext);
841 module = buf;
843 def_file_add_import (def, name, module, ordinal, internal_name);
844 if (buf)
845 free (buf);
848 static void
849 def_version (int major, int minor)
851 def->version_major = major;
852 def->version_minor = minor;
855 static void
856 def_directive (char *str)
858 struct directive *d = xmalloc (sizeof (struct directive));
860 d->next = directives;
861 directives = d;
862 d->name = xstrdup (str);
863 d->len = strlen (str);
866 static void
867 def_aligncomm (char *str, int align)
869 def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
871 c->symbol_name = xstrdup (str);
872 c->alignment = (unsigned int) align;
874 c->next = def->aligncomms;
875 def->aligncomms = c;
878 static int
879 def_error (const char *err)
881 einfo ("%P: %s:%d: %s\n",
882 def_filename ? def_filename : "<unknown-file>", linenumber, err);
883 return 0;
887 /* Lexical Scanner. */
889 #undef TRACE
890 #define TRACE 0
892 /* Never freed, but always reused as needed, so no real leak. */
893 static char *buffer = 0;
894 static int buflen = 0;
895 static int bufptr = 0;
897 static void
898 put_buf (char c)
900 if (bufptr == buflen)
902 buflen += 50; /* overly reasonable, eh? */
903 if (buffer)
904 buffer = xrealloc (buffer, buflen + 1);
905 else
906 buffer = xmalloc (buflen + 1);
908 buffer[bufptr++] = c;
909 buffer[bufptr] = 0; /* not optimal, but very convenient. */
912 static struct
914 char *name;
915 int token;
917 tokens[] =
919 { "BASE", BASE },
920 { "CODE", CODE },
921 { "CONSTANT", CONSTANTU },
922 { "constant", CONSTANTL },
923 { "DATA", DATAU },
924 { "data", DATAL },
925 { "DESCRIPTION", DESCRIPTION },
926 { "DIRECTIVE", DIRECTIVE },
927 { "EXECUTE", EXECUTE },
928 { "EXPORTS", EXPORTS },
929 { "HEAPSIZE", HEAPSIZE },
930 { "IMPORTS", IMPORTS },
931 { "LIBRARY", LIBRARY },
932 { "NAME", NAME },
933 { "NONAME", NONAMEU },
934 { "noname", NONAMEL },
935 { "PRIVATE", PRIVATEU },
936 { "private", PRIVATEL },
937 { "READ", READ },
938 { "SECTIONS", SECTIONS },
939 { "SEGMENTS", SECTIONS },
940 { "SHARED", SHARED },
941 { "STACKSIZE", STACKSIZE_K },
942 { "VERSION", VERSIONK },
943 { "WRITE", WRITE },
944 { 0, 0 }
947 static int
948 def_getc (void)
950 int rv;
952 if (lex_parse_string)
954 if (lex_parse_string >= lex_parse_string_end)
955 rv = EOF;
956 else
957 rv = *lex_parse_string++;
959 else
961 rv = fgetc (the_file);
963 if (rv == '\n')
964 saw_newline = 1;
965 return rv;
968 static int
969 def_ungetc (int c)
971 if (lex_parse_string)
973 lex_parse_string--;
974 return c;
976 else
977 return ungetc (c, the_file);
980 static int
981 def_lex (void)
983 int c, i, q;
985 if (lex_forced_token)
987 i = lex_forced_token;
988 lex_forced_token = 0;
989 #if TRACE
990 printf ("lex: forcing token %d\n", i);
991 #endif
992 return i;
995 c = def_getc ();
997 /* Trim leading whitespace. */
998 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
999 c = def_getc ();
1001 if (c == EOF)
1003 #if TRACE
1004 printf ("lex: EOF\n");
1005 #endif
1006 return 0;
1009 if (saw_newline && c == ';')
1013 c = def_getc ();
1015 while (c != EOF && c != '\n');
1016 if (c == '\n')
1017 return def_lex ();
1018 return 0;
1021 /* Must be something else. */
1022 saw_newline = 0;
1024 if (ISDIGIT (c))
1026 bufptr = 0;
1027 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1029 put_buf (c);
1030 c = def_getc ();
1032 if (c != EOF)
1033 def_ungetc (c);
1034 yylval.digits = xstrdup (buffer);
1035 #if TRACE
1036 printf ("lex: `%s' returns DIGITS\n", buffer);
1037 #endif
1038 return DIGITS;
1041 if (ISALPHA (c) || strchr ("$:-_?@", c))
1043 bufptr = 0;
1044 q = c;
1045 put_buf (c);
1046 c = def_getc ();
1048 if (q == '@')
1050 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1051 return (q);
1052 else if (ISDIGIT (c)) /* '@' followed by digit. */
1054 def_ungetc (c);
1055 return (q);
1057 #if TRACE
1058 printf ("lex: @ returns itself\n");
1059 #endif
1062 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
1064 put_buf (c);
1065 c = def_getc ();
1067 if (c != EOF)
1068 def_ungetc (c);
1069 if (ISALPHA (q)) /* Check for tokens. */
1071 for (i = 0; tokens[i].name; i++)
1072 if (strcmp (tokens[i].name, buffer) == 0)
1074 #if TRACE
1075 printf ("lex: `%s' is a string token\n", buffer);
1076 #endif
1077 return tokens[i].token;
1080 #if TRACE
1081 printf ("lex: `%s' returns ID\n", buffer);
1082 #endif
1083 yylval.id = xstrdup (buffer);
1084 return ID;
1087 if (c == '\'' || c == '"')
1089 q = c;
1090 c = def_getc ();
1091 bufptr = 0;
1093 while (c != EOF && c != q)
1095 put_buf (c);
1096 c = def_getc ();
1098 yylval.id = xstrdup (buffer);
1099 #if TRACE
1100 printf ("lex: `%s' returns ID\n", buffer);
1101 #endif
1102 return ID;
1105 if (c == '=' || c == '.' || c == ',')
1107 #if TRACE
1108 printf ("lex: `%c' returns itself\n", c);
1109 #endif
1110 return c;
1113 if (c == '\n')
1115 linenumber++;
1116 saw_newline = 1;
1119 /*printf ("lex: 0x%02x ignored\n", c); */
1120 return def_lex ();