daily update
[binutils/dougsmingw.git] / ld / deffilep.y
blob1104c49cc80025b97c0498878d6093c810697604
1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 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, const char *);
83 static void def_heapsize (int, int);
84 static void def_import (const char *, const char *, const char *, const char *,
85 int, const char *);
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 EQUAL
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
120 %type <id> opt_equalequal_name
124 start: start command
125 | command
128 command:
129 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
130 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
131 | DESCRIPTION ID { def_description ($2);}
132 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
133 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
134 | CODE attr_list { def_section ("CODE", $2);}
135 | DATAU attr_list { def_section ("DATA", $2);}
136 | SECTIONS seclist
137 | EXPORTS explist
138 | IMPORTS implist
139 | VERSIONK NUMBER { def_version ($2, 0);}
140 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
141 | DIRECTIVE ID { def_directive ($2);}
142 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
146 explist:
147 /* EMPTY */
148 | expline
149 | explist expline
152 expline:
153 /* The opt_comma is necessary to support both the usual
154 DEF file syntax as well as .drectve syntax which
155 mandates <expsym>,<expoptlist>. */
156 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
157 { def_exports ($1, $2, $3, $5, $7); }
159 exp_opt_list:
160 /* The opt_comma is necessary to support both the usual
161 DEF file syntax as well as .drectve syntax which
162 allows for comma separated opt list. */
163 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
164 | { $$ = 0; }
166 exp_opt:
167 NONAMEU { $$ = 1; }
168 | NONAMEL { $$ = 1; }
169 | CONSTANTU { $$ = 2; }
170 | CONSTANTL { $$ = 2; }
171 | DATAU { $$ = 4; }
172 | DATAL { $$ = 4; }
173 | PRIVATEU { $$ = 8; }
174 | PRIVATEL { $$ = 8; }
176 implist:
177 implist impline
178 | impline
181 impline:
182 ID '=' ID '.' ID '.' ID opt_equalequal_name
183 { def_import ($1, $3, $5, $7, -1, $8); }
184 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
185 { def_import ($1, $3, $5, 0, $7, $8); }
186 | ID '=' ID '.' ID opt_equalequal_name
187 { def_import ($1, $3, 0, $5, -1, $6); }
188 | ID '=' ID '.' NUMBER opt_equalequal_name
189 { def_import ($1, $3, 0, 0, $5, $6); }
190 | ID '.' ID '.' ID opt_equalequal_name
191 { def_import( 0, $1, $3, $5, -1, $6); }
192 | ID '.' ID opt_equalequal_name
193 { def_import ( 0, $1, 0, $3, -1, $4); }
196 seclist:
197 seclist secline
198 | secline
201 secline:
202 ID attr_list { def_section ($1, $2);}
203 | ID ID { def_section_alt ($1, $2);}
206 attr_list:
207 attr_list opt_comma attr { $$ = $1 | $3; }
208 | attr { $$ = $1; }
211 opt_comma:
215 opt_number: ',' NUMBER { $$=$2;}
216 | { $$=-1;}
219 attr:
220 READ { $$ = 1;}
221 | WRITE { $$ = 2;}
222 | EXECUTE { $$=4;}
223 | SHARED { $$=8;}
226 opt_name: ID { $$ = $1; }
227 | ID '.' ID
229 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
230 sprintf (name, "%s.%s", $1, $3);
231 $$ = name;
233 | { $$ = ""; }
236 opt_equalequal_name: EQUAL ID { $$ = $2; }
237 | { $$ = 0; }
240 opt_ordinal:
241 '@' NUMBER { $$ = $2;}
242 | { $$ = -1;}
245 opt_equal_name:
246 '=' dot_name { $$ = $2; }
247 | { $$ = 0; }
250 opt_base: BASE '=' NUMBER { $$ = $3;}
251 | { $$ = -1;}
254 dot_name: ID { $$ = $1; }
255 | dot_name '.' ID
257 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
258 sprintf (name, "%s.%s", $1, $3);
259 $$ = name;
263 anylang_id: ID { $$ = $1; }
264 | anylang_id '.' opt_digits opt_id
266 char *id = xmalloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
267 sprintf (id, "%s.%s%s", $1, $3, $4);
268 $$ = id;
272 opt_digits: DIGITS { $$ = $1; }
273 | { $$ = ""; }
276 opt_id: ID { $$ = $1; }
277 | { $$ = ""; }
280 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
284 /*****************************************************************************
286 *****************************************************************************/
288 static FILE *the_file;
289 static const char *def_filename;
290 static int linenumber;
291 static def_file *def;
292 static int saw_newline;
294 struct directive
296 struct directive *next;
297 char *name;
298 int len;
301 static struct directive *directives = 0;
303 def_file *
304 def_file_empty (void)
306 def_file *rv = xmalloc (sizeof (def_file));
307 memset (rv, 0, sizeof (def_file));
308 rv->is_dll = -1;
309 rv->base_address = (bfd_vma) -1;
310 rv->stack_reserve = rv->stack_commit = -1;
311 rv->heap_reserve = rv->heap_commit = -1;
312 rv->version_major = rv->version_minor = -1;
313 return rv;
316 def_file *
317 def_file_parse (const char *filename, def_file *add_to)
319 struct directive *d;
321 the_file = fopen (filename, "r");
322 def_filename = filename;
323 linenumber = 1;
324 if (!the_file)
326 perror (filename);
327 return 0;
329 if (add_to)
331 def = add_to;
333 else
335 def = def_file_empty ();
338 saw_newline = 1;
339 if (def_parse ())
341 def_file_free (def);
342 fclose (the_file);
343 return 0;
346 fclose (the_file);
348 for (d = directives; d; d = d->next)
350 #if TRACE
351 printf ("Adding directive %08x `%s'\n", d->name, d->name);
352 #endif
353 def_file_add_directive (def, d->name, d->len);
356 return def;
359 void
360 def_file_free (def_file *fdef)
362 int i;
364 if (!fdef)
365 return;
366 if (fdef->name)
367 free (fdef->name);
368 if (fdef->description)
369 free (fdef->description);
371 if (fdef->section_defs)
373 for (i = 0; i < fdef->num_section_defs; i++)
375 if (fdef->section_defs[i].name)
376 free (fdef->section_defs[i].name);
377 if (fdef->section_defs[i].class)
378 free (fdef->section_defs[i].class);
380 free (fdef->section_defs);
383 if (fdef->exports)
385 for (i = 0; i < fdef->num_exports; i++)
387 if (fdef->exports[i].internal_name
388 && fdef->exports[i].internal_name != fdef->exports[i].name)
389 free (fdef->exports[i].internal_name);
390 if (fdef->exports[i].name)
391 free (fdef->exports[i].name);
392 if (fdef->exports[i].its_name)
393 free (fdef->exports[i].its_name);
395 free (fdef->exports);
398 if (fdef->imports)
400 for (i = 0; i < fdef->num_imports; i++)
402 if (fdef->imports[i].internal_name
403 && fdef->imports[i].internal_name != fdef->imports[i].name)
404 free (fdef->imports[i].internal_name);
405 if (fdef->imports[i].name)
406 free (fdef->imports[i].name);
407 if (fdef->imports[i].its_name)
408 free (fdef->imports[i].its_name);
410 free (fdef->imports);
413 while (fdef->modules)
415 def_file_module *m = fdef->modules;
417 fdef->modules = fdef->modules->next;
418 free (m);
421 while (fdef->aligncomms)
423 def_file_aligncomm *c = fdef->aligncomms;
425 fdef->aligncomms = fdef->aligncomms->next;
426 free (c->symbol_name);
427 free (c);
430 free (fdef);
433 #ifdef DEF_FILE_PRINT
434 void
435 def_file_print (FILE *file, def_file *fdef)
437 int i;
439 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
440 if (fdef->name)
441 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
442 if (fdef->is_dll != -1)
443 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
444 if (fdef->base_address != (bfd_vma) -1)
445 fprintf (file, " base address: 0x%08x\n", fdef->base_address);
446 if (fdef->description)
447 fprintf (file, " description: `%s'\n", fdef->description);
448 if (fdef->stack_reserve != -1)
449 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
450 if (fdef->stack_commit != -1)
451 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
452 if (fdef->heap_reserve != -1)
453 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
454 if (fdef->heap_commit != -1)
455 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
457 if (fdef->num_section_defs > 0)
459 fprintf (file, " section defs:\n");
461 for (i = 0; i < fdef->num_section_defs; i++)
463 fprintf (file, " name: `%s', class: `%s', flags:",
464 fdef->section_defs[i].name, fdef->section_defs[i].class);
465 if (fdef->section_defs[i].flag_read)
466 fprintf (file, " R");
467 if (fdef->section_defs[i].flag_write)
468 fprintf (file, " W");
469 if (fdef->section_defs[i].flag_execute)
470 fprintf (file, " X");
471 if (fdef->section_defs[i].flag_shared)
472 fprintf (file, " S");
473 fprintf (file, "\n");
477 if (fdef->num_exports > 0)
479 fprintf (file, " exports:\n");
481 for (i = 0; i < fdef->num_exports; i++)
483 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
484 fdef->exports[i].name, fdef->exports[i].internal_name,
485 fdef->exports[i].ordinal);
486 if (fdef->exports[i].flag_private)
487 fprintf (file, " P");
488 if (fdef->exports[i].flag_constant)
489 fprintf (file, " C");
490 if (fdef->exports[i].flag_noname)
491 fprintf (file, " N");
492 if (fdef->exports[i].flag_data)
493 fprintf (file, " D");
494 fprintf (file, "\n");
498 if (fdef->num_imports > 0)
500 fprintf (file, " imports:\n");
502 for (i = 0; i < fdef->num_imports; i++)
504 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
505 fdef->imports[i].internal_name,
506 fdef->imports[i].module,
507 fdef->imports[i].name,
508 fdef->imports[i].ordinal);
512 if (fdef->version_major != -1)
513 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
515 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
517 #endif
519 def_file_export *
520 def_file_add_export (def_file *fdef,
521 const char *external_name,
522 const char *internal_name,
523 int ordinal,
524 const char *its_name)
526 def_file_export *e;
527 int max_exports = ROUND_UP(fdef->num_exports, 32);
529 if (fdef->num_exports >= max_exports)
531 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
532 if (fdef->exports)
533 fdef->exports = xrealloc (fdef->exports,
534 max_exports * sizeof (def_file_export));
535 else
536 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
538 e = fdef->exports + fdef->num_exports;
539 memset (e, 0, sizeof (def_file_export));
540 if (internal_name && !external_name)
541 external_name = internal_name;
542 if (external_name && !internal_name)
543 internal_name = external_name;
544 e->name = xstrdup (external_name);
545 e->internal_name = xstrdup (internal_name);
546 e->its_name = (its_name ? xstrdup (its_name) : NULL);
547 e->ordinal = ordinal;
548 fdef->num_exports++;
549 return e;
552 def_file_module *
553 def_get_module (def_file *fdef, const char *name)
555 def_file_module *s;
557 for (s = fdef->modules; s; s = s->next)
558 if (strcmp (s->name, name) == 0)
559 return s;
561 return NULL;
564 static def_file_module *
565 def_stash_module (def_file *fdef, const char *name)
567 def_file_module *s;
569 if ((s = def_get_module (fdef, name)) != NULL)
570 return s;
571 s = xmalloc (sizeof (def_file_module) + strlen (name));
572 s->next = fdef->modules;
573 fdef->modules = s;
574 s->user_data = 0;
575 strcpy (s->name, name);
576 return s;
579 def_file_import *
580 def_file_add_import (def_file *fdef,
581 const char *name,
582 const char *module,
583 int ordinal,
584 const char *internal_name,
585 const char *its_name)
587 def_file_import *i;
588 int max_imports = ROUND_UP (fdef->num_imports, 16);
590 if (fdef->num_imports >= max_imports)
592 max_imports = ROUND_UP (fdef->num_imports+1, 16);
594 if (fdef->imports)
595 fdef->imports = xrealloc (fdef->imports,
596 max_imports * sizeof (def_file_import));
597 else
598 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
600 i = fdef->imports + fdef->num_imports;
601 memset (i, 0, sizeof (def_file_import));
602 if (name)
603 i->name = xstrdup (name);
604 if (module)
605 i->module = def_stash_module (fdef, module);
606 i->ordinal = ordinal;
607 if (internal_name)
608 i->internal_name = xstrdup (internal_name);
609 else
610 i->internal_name = i->name;
611 i->its_name = (its_name ? xstrdup (its_name) : NULL);
612 fdef->num_imports++;
614 return i;
617 struct
619 char *param;
620 int token;
622 diropts[] =
624 { "-heap", HEAPSIZE },
625 { "-stack", STACKSIZE_K },
626 { "-attr", SECTIONS },
627 { "-export", EXPORTS },
628 { "-aligncomm", ALIGNCOMM },
629 { 0, 0 }
632 void
633 def_file_add_directive (def_file *my_def, const char *param, int len)
635 def_file *save_def = def;
636 const char *pend = param + len;
637 char * tend = (char *) param;
638 int i;
640 def = my_def;
642 while (param < pend)
644 while (param < pend
645 && (ISSPACE (*param) || *param == '\n' || *param == 0))
646 param++;
648 if (param == pend)
649 break;
651 /* Scan forward until we encounter any of:
652 - the end of the buffer
653 - the start of a new option
654 - a newline seperating options
655 - a NUL seperating options. */
656 for (tend = (char *) (param + 1);
657 (tend < pend
658 && !(ISSPACE (tend[-1]) && *tend == '-')
659 && *tend != '\n' && *tend != 0);
660 tend++)
663 for (i = 0; diropts[i].param; i++)
665 len = strlen (diropts[i].param);
667 if (tend - param >= len
668 && strncmp (param, diropts[i].param, len) == 0
669 && (param[len] == ':' || param[len] == ' '))
671 lex_parse_string_end = tend;
672 lex_parse_string = param + len + 1;
673 lex_forced_token = diropts[i].token;
674 saw_newline = 0;
675 if (def_parse ())
676 continue;
677 break;
681 if (!diropts[i].param)
683 char saved;
685 saved = * tend;
686 * tend = 0;
687 /* xgettext:c-format */
688 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
689 * tend = saved;
692 lex_parse_string = 0;
693 param = tend;
696 def = save_def;
699 /* Parser Callbacks. */
701 static void
702 def_image_name (const char *name, int base, int is_dll)
704 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
705 to do here. We retain the output filename specified on command line. */
706 if (*name)
708 const char* image_name = lbasename (name);
710 if (image_name != name)
711 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
712 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
713 name);
714 if (def->name)
715 free (def->name);
716 /* Append the default suffix, if none specified. */
717 if (strchr (image_name, '.') == 0)
719 const char * suffix = is_dll ? ".dll" : ".exe";
721 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
722 sprintf (def->name, "%s%s", image_name, suffix);
724 else
725 def->name = xstrdup (image_name);
728 /* Honor a BASE address statement, even if LIBRARY string is empty. */
729 def->base_address = base;
730 def->is_dll = is_dll;
733 static void
734 def_description (const char *text)
736 int len = def->description ? strlen (def->description) : 0;
738 len += strlen (text) + 1;
739 if (def->description)
741 def->description = xrealloc (def->description, len);
742 strcat (def->description, text);
744 else
746 def->description = xmalloc (len);
747 strcpy (def->description, text);
751 static void
752 def_stacksize (int reserve, int commit)
754 def->stack_reserve = reserve;
755 def->stack_commit = commit;
758 static void
759 def_heapsize (int reserve, int commit)
761 def->heap_reserve = reserve;
762 def->heap_commit = commit;
765 static void
766 def_section (const char *name, int attr)
768 def_file_section *s;
769 int max_sections = ROUND_UP (def->num_section_defs, 4);
771 if (def->num_section_defs >= max_sections)
773 max_sections = ROUND_UP (def->num_section_defs+1, 4);
775 if (def->section_defs)
776 def->section_defs = xrealloc (def->section_defs,
777 max_sections * sizeof (def_file_import));
778 else
779 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
781 s = def->section_defs + def->num_section_defs;
782 memset (s, 0, sizeof (def_file_section));
783 s->name = xstrdup (name);
784 if (attr & 1)
785 s->flag_read = 1;
786 if (attr & 2)
787 s->flag_write = 1;
788 if (attr & 4)
789 s->flag_execute = 1;
790 if (attr & 8)
791 s->flag_shared = 1;
793 def->num_section_defs++;
796 static void
797 def_section_alt (const char *name, const char *attr)
799 int aval = 0;
801 for (; *attr; attr++)
803 switch (*attr)
805 case 'R':
806 case 'r':
807 aval |= 1;
808 break;
809 case 'W':
810 case 'w':
811 aval |= 2;
812 break;
813 case 'X':
814 case 'x':
815 aval |= 4;
816 break;
817 case 'S':
818 case 's':
819 aval |= 8;
820 break;
823 def_section (name, aval);
826 static void
827 def_exports (const char *external_name,
828 const char *internal_name,
829 int ordinal,
830 int flags,
831 const char *its_name)
833 def_file_export *dfe;
835 if (!internal_name && external_name)
836 internal_name = external_name;
837 #if TRACE
838 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
839 #endif
841 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
842 its_name);
843 if (flags & 1)
844 dfe->flag_noname = 1;
845 if (flags & 2)
846 dfe->flag_constant = 1;
847 if (flags & 4)
848 dfe->flag_data = 1;
849 if (flags & 8)
850 dfe->flag_private = 1;
853 static void
854 def_import (const char *internal_name,
855 const char *module,
856 const char *dllext,
857 const char *name,
858 int ordinal,
859 const char *its_name)
861 char *buf = 0;
862 const char *ext = dllext ? dllext : "dll";
864 buf = xmalloc (strlen (module) + strlen (ext) + 2);
865 sprintf (buf, "%s.%s", module, ext);
866 module = buf;
868 def_file_add_import (def, name, module, ordinal, internal_name, its_name);
869 if (buf)
870 free (buf);
873 static void
874 def_version (int major, int minor)
876 def->version_major = major;
877 def->version_minor = minor;
880 static void
881 def_directive (char *str)
883 struct directive *d = xmalloc (sizeof (struct directive));
885 d->next = directives;
886 directives = d;
887 d->name = xstrdup (str);
888 d->len = strlen (str);
891 static void
892 def_aligncomm (char *str, int align)
894 def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
896 c->symbol_name = xstrdup (str);
897 c->alignment = (unsigned int) align;
899 c->next = def->aligncomms;
900 def->aligncomms = c;
903 static int
904 def_error (const char *err)
906 einfo ("%P: %s:%d: %s\n",
907 def_filename ? def_filename : "<unknown-file>", linenumber, err);
908 return 0;
912 /* Lexical Scanner. */
914 #undef TRACE
915 #define TRACE 0
917 /* Never freed, but always reused as needed, so no real leak. */
918 static char *buffer = 0;
919 static int buflen = 0;
920 static int bufptr = 0;
922 static void
923 put_buf (char c)
925 if (bufptr == buflen)
927 buflen += 50; /* overly reasonable, eh? */
928 if (buffer)
929 buffer = xrealloc (buffer, buflen + 1);
930 else
931 buffer = xmalloc (buflen + 1);
933 buffer[bufptr++] = c;
934 buffer[bufptr] = 0; /* not optimal, but very convenient. */
937 static struct
939 char *name;
940 int token;
942 tokens[] =
944 { "BASE", BASE },
945 { "CODE", CODE },
946 { "CONSTANT", CONSTANTU },
947 { "constant", CONSTANTL },
948 { "DATA", DATAU },
949 { "data", DATAL },
950 { "DESCRIPTION", DESCRIPTION },
951 { "DIRECTIVE", DIRECTIVE },
952 { "EXECUTE", EXECUTE },
953 { "EXPORTS", EXPORTS },
954 { "HEAPSIZE", HEAPSIZE },
955 { "IMPORTS", IMPORTS },
956 { "LIBRARY", LIBRARY },
957 { "NAME", NAME },
958 { "NONAME", NONAMEU },
959 { "noname", NONAMEL },
960 { "PRIVATE", PRIVATEU },
961 { "private", PRIVATEL },
962 { "READ", READ },
963 { "SECTIONS", SECTIONS },
964 { "SEGMENTS", SECTIONS },
965 { "SHARED", SHARED },
966 { "STACKSIZE", STACKSIZE_K },
967 { "VERSION", VERSIONK },
968 { "WRITE", WRITE },
969 { 0, 0 }
972 static int
973 def_getc (void)
975 int rv;
977 if (lex_parse_string)
979 if (lex_parse_string >= lex_parse_string_end)
980 rv = EOF;
981 else
982 rv = *lex_parse_string++;
984 else
986 rv = fgetc (the_file);
988 if (rv == '\n')
989 saw_newline = 1;
990 return rv;
993 static int
994 def_ungetc (int c)
996 if (lex_parse_string)
998 lex_parse_string--;
999 return c;
1001 else
1002 return ungetc (c, the_file);
1005 static int
1006 def_lex (void)
1008 int c, i, q;
1010 if (lex_forced_token)
1012 i = lex_forced_token;
1013 lex_forced_token = 0;
1014 #if TRACE
1015 printf ("lex: forcing token %d\n", i);
1016 #endif
1017 return i;
1020 c = def_getc ();
1022 /* Trim leading whitespace. */
1023 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1024 c = def_getc ();
1026 if (c == EOF)
1028 #if TRACE
1029 printf ("lex: EOF\n");
1030 #endif
1031 return 0;
1034 if (saw_newline && c == ';')
1038 c = def_getc ();
1040 while (c != EOF && c != '\n');
1041 if (c == '\n')
1042 return def_lex ();
1043 return 0;
1046 /* Must be something else. */
1047 saw_newline = 0;
1049 if (ISDIGIT (c))
1051 bufptr = 0;
1052 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1054 put_buf (c);
1055 c = def_getc ();
1057 if (c != EOF)
1058 def_ungetc (c);
1059 yylval.digits = xstrdup (buffer);
1060 #if TRACE
1061 printf ("lex: `%s' returns DIGITS\n", buffer);
1062 #endif
1063 return DIGITS;
1066 if (ISALPHA (c) || strchr ("$:-_?@", c))
1068 bufptr = 0;
1069 q = c;
1070 put_buf (c);
1071 c = def_getc ();
1073 if (q == '@')
1075 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1076 return (q);
1077 else if (ISDIGIT (c)) /* '@' followed by digit. */
1079 def_ungetc (c);
1080 return (q);
1082 #if TRACE
1083 printf ("lex: @ returns itself\n");
1084 #endif
1087 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1089 put_buf (c);
1090 c = def_getc ();
1092 if (c != EOF)
1093 def_ungetc (c);
1094 if (ISALPHA (q)) /* Check for tokens. */
1096 for (i = 0; tokens[i].name; i++)
1097 if (strcmp (tokens[i].name, buffer) == 0)
1099 #if TRACE
1100 printf ("lex: `%s' is a string token\n", buffer);
1101 #endif
1102 return tokens[i].token;
1105 #if TRACE
1106 printf ("lex: `%s' returns ID\n", buffer);
1107 #endif
1108 yylval.id = xstrdup (buffer);
1109 return ID;
1112 if (c == '\'' || c == '"')
1114 q = c;
1115 c = def_getc ();
1116 bufptr = 0;
1118 while (c != EOF && c != q)
1120 put_buf (c);
1121 c = def_getc ();
1123 yylval.id = xstrdup (buffer);
1124 #if TRACE
1125 printf ("lex: `%s' returns ID\n", buffer);
1126 #endif
1127 return ID;
1130 if ( c == '=')
1132 c = def_getc ();
1133 if (c == '=')
1135 #if TRACE
1136 printf ("lex: `==' returns EQUAL\n");
1137 #endif
1138 return EQUAL;
1140 def_ungetc (c);
1141 #if TRACE
1142 printf ("lex: `=' returns itself\n");
1143 #endif
1144 return '=';
1146 if (c == '.' || c == ',')
1148 #if TRACE
1149 printf ("lex: `%c' returns itself\n", c);
1150 #endif
1151 return c;
1154 if (c == '\n')
1156 linenumber++;
1157 saw_newline = 1;
1160 /*printf ("lex: 0x%02x ignored\n", c); */
1161 return def_lex ();