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. */
24 #include "libiberty.h"
25 #include "safe-ctype.h"
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
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
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
62 #define yy_yys def_yys
63 #define yystate def_state
66 #define yy_yyv def_yyv
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 *,
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;
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
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
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);}
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);}
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); }
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; }
168 | NONAMEL { $$ = 1; }
169 | CONSTANTU { $$ = 2; }
170 | CONSTANTL { $$ = 2; }
173 | PRIVATEU { $$ = 8; }
174 | PRIVATEL { $$ = 8; }
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); }
202 ID attr_list { def_section ($1, $2);}
203 | ID ID { def_section_alt ($1, $2);}
207 attr_list opt_comma attr { $$ = $1 | $3; }
215 opt_number: ',' NUMBER { $$=$2;}
226 opt_name: ID { $$ = $1; }
229 char *name = xmalloc (strlen ($2) + 2);
230 sprintf (name, ".%s", $2);
235 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
236 sprintf (name, "%s.%s", $1, $3);
242 opt_equalequal_name: EQUAL ID { $$ = $2; }
247 '@' NUMBER { $$ = $2;}
252 '=' dot_name { $$ = $2; }
256 opt_base: BASE '=' NUMBER { $$ = $3;}
260 dot_name: ID { $$ = $1; }
263 char *name = xmalloc (strlen ($2) + 2);
264 sprintf (name, ".%s", $2);
269 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
270 sprintf (name, "%s.%s", $1, $3);
275 anylang_id: ID { $$ = $1; }
278 char *id = xmalloc (strlen ($2) + 2);
279 sprintf (id, ".%s", $2);
282 | anylang_id '.' opt_digits opt_id
284 char *id = xmalloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
285 sprintf (id, "%s.%s%s", $1, $3, $4);
290 opt_digits: DIGITS { $$ = $1; }
294 opt_id: ID { $$ = $1; }
298 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
302 /*****************************************************************************
304 *****************************************************************************/
306 static FILE *the_file;
307 static const char *def_filename;
308 static int linenumber;
309 static def_file *def;
310 static int saw_newline;
314 struct directive *next;
319 static struct directive *directives = 0;
322 def_file_empty (void)
324 def_file *rv = xmalloc (sizeof (def_file));
325 memset (rv, 0, sizeof (def_file));
327 rv->base_address = (bfd_vma) -1;
328 rv->stack_reserve = rv->stack_commit = -1;
329 rv->heap_reserve = rv->heap_commit = -1;
330 rv->version_major = rv->version_minor = -1;
335 def_file_parse (const char *filename, def_file *add_to)
339 the_file = fopen (filename, "r");
340 def_filename = filename;
353 def = def_file_empty ();
366 for (d = directives; d; d = d->next)
369 printf ("Adding directive %08x `%s'\n", d->name, d->name);
371 def_file_add_directive (def, d->name, d->len);
378 def_file_free (def_file *fdef)
386 if (fdef->description)
387 free (fdef->description);
389 if (fdef->section_defs)
391 for (i = 0; i < fdef->num_section_defs; i++)
393 if (fdef->section_defs[i].name)
394 free (fdef->section_defs[i].name);
395 if (fdef->section_defs[i].class)
396 free (fdef->section_defs[i].class);
398 free (fdef->section_defs);
403 for (i = 0; i < fdef->num_exports; i++)
405 if (fdef->exports[i].internal_name
406 && fdef->exports[i].internal_name != fdef->exports[i].name)
407 free (fdef->exports[i].internal_name);
408 if (fdef->exports[i].name)
409 free (fdef->exports[i].name);
410 if (fdef->exports[i].its_name)
411 free (fdef->exports[i].its_name);
413 free (fdef->exports);
418 for (i = 0; i < fdef->num_imports; i++)
420 if (fdef->imports[i].internal_name
421 && fdef->imports[i].internal_name != fdef->imports[i].name)
422 free (fdef->imports[i].internal_name);
423 if (fdef->imports[i].name)
424 free (fdef->imports[i].name);
425 if (fdef->imports[i].its_name)
426 free (fdef->imports[i].its_name);
428 free (fdef->imports);
431 while (fdef->modules)
433 def_file_module *m = fdef->modules;
435 fdef->modules = fdef->modules->next;
439 while (fdef->aligncomms)
441 def_file_aligncomm *c = fdef->aligncomms;
443 fdef->aligncomms = fdef->aligncomms->next;
444 free (c->symbol_name);
451 #ifdef DEF_FILE_PRINT
453 def_file_print (FILE *file, def_file *fdef)
457 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
459 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
460 if (fdef->is_dll != -1)
461 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
462 if (fdef->base_address != (bfd_vma) -1)
463 fprintf (file, " base address: 0x%08x\n", fdef->base_address);
464 if (fdef->description)
465 fprintf (file, " description: `%s'\n", fdef->description);
466 if (fdef->stack_reserve != -1)
467 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
468 if (fdef->stack_commit != -1)
469 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
470 if (fdef->heap_reserve != -1)
471 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
472 if (fdef->heap_commit != -1)
473 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
475 if (fdef->num_section_defs > 0)
477 fprintf (file, " section defs:\n");
479 for (i = 0; i < fdef->num_section_defs; i++)
481 fprintf (file, " name: `%s', class: `%s', flags:",
482 fdef->section_defs[i].name, fdef->section_defs[i].class);
483 if (fdef->section_defs[i].flag_read)
484 fprintf (file, " R");
485 if (fdef->section_defs[i].flag_write)
486 fprintf (file, " W");
487 if (fdef->section_defs[i].flag_execute)
488 fprintf (file, " X");
489 if (fdef->section_defs[i].flag_shared)
490 fprintf (file, " S");
491 fprintf (file, "\n");
495 if (fdef->num_exports > 0)
497 fprintf (file, " exports:\n");
499 for (i = 0; i < fdef->num_exports; i++)
501 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
502 fdef->exports[i].name, fdef->exports[i].internal_name,
503 fdef->exports[i].ordinal);
504 if (fdef->exports[i].flag_private)
505 fprintf (file, " P");
506 if (fdef->exports[i].flag_constant)
507 fprintf (file, " C");
508 if (fdef->exports[i].flag_noname)
509 fprintf (file, " N");
510 if (fdef->exports[i].flag_data)
511 fprintf (file, " D");
512 fprintf (file, "\n");
516 if (fdef->num_imports > 0)
518 fprintf (file, " imports:\n");
520 for (i = 0; i < fdef->num_imports; i++)
522 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
523 fdef->imports[i].internal_name,
524 fdef->imports[i].module,
525 fdef->imports[i].name,
526 fdef->imports[i].ordinal);
530 if (fdef->version_major != -1)
531 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
533 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
537 /* Helper routine to check for identity of string pointers,
538 which might be NULL. */
541 are_names_equal (const char *s1, const char *s2)
546 return (!s1 ? -1 : 1);
547 return strcmp (s1, s2);
551 cmp_export_elem (const def_file_export *e, const char *ex_name,
552 const char *in_name, const char *its_name,
557 if ((r = are_names_equal (ex_name, e->name)) != 0)
559 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
561 if ((r = are_names_equal (its_name, e->its_name)) != 0)
563 return (ord - e->ordinal);
566 /* Search the position of the identical element, or returns the position
567 of the next higher element. If last valid element is smaller, then MAX
571 find_export_in_list (def_file_export *b, int max,
572 const char *ex_name, const char *in_name,
573 const char *its_name, int ord, int *is_ident)
580 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
584 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
586 else if (!e || max == 2)
592 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
603 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
611 def_file_add_export (def_file *fdef,
612 const char *external_name,
613 const char *internal_name,
615 const char *its_name,
620 int max_exports = ROUND_UP(fdef->num_exports, 32);
622 if (internal_name && !external_name)
623 external_name = internal_name;
624 if (external_name && !internal_name)
625 internal_name = external_name;
627 /* We need to avoid duplicates. */
629 pos = find_export_in_list (fdef->exports, fdef->num_exports,
630 external_name, internal_name,
631 its_name, ordinal, is_dup);
634 return (fdef->exports + pos);
636 if (fdef->num_exports >= max_exports)
638 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
640 fdef->exports = xrealloc (fdef->exports,
641 max_exports * sizeof (def_file_export));
643 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
646 e = fdef->exports + pos;
647 if (pos != fdef->num_exports)
648 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
649 memset (e, 0, sizeof (def_file_export));
650 e->name = xstrdup (external_name);
651 e->internal_name = xstrdup (internal_name);
652 e->its_name = (its_name ? xstrdup (its_name) : NULL);
653 e->ordinal = ordinal;
659 def_get_module (def_file *fdef, const char *name)
663 for (s = fdef->modules; s; s = s->next)
664 if (strcmp (s->name, name) == 0)
670 static def_file_module *
671 def_stash_module (def_file *fdef, const char *name)
675 if ((s = def_get_module (fdef, name)) != NULL)
677 s = xmalloc (sizeof (def_file_module) + strlen (name));
678 s->next = fdef->modules;
681 strcpy (s->name, name);
686 cmp_import_elem (const def_file_import *e, const char *ex_name,
687 const char *in_name, const char *module,
692 if ((r = are_names_equal (ex_name, e->name)) != 0)
694 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
696 if (ord != e->ordinal)
697 return (ord < e->ordinal ? -1 : 1);
698 return are_names_equal (module, (e->module ? e->module->name : NULL));
701 /* Search the position of the identical element, or returns the position
702 of the next higher element. If last valid element is smaller, then MAX
706 find_import_in_list (def_file_import *b, int max,
707 const char *ex_name, const char *in_name,
708 const char *module, int ord, int *is_ident)
715 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
719 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
721 else if (!e || max == 2)
727 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
738 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
746 def_file_add_import (def_file *fdef,
750 const char *internal_name,
751 const char *its_name,
756 int max_imports = ROUND_UP (fdef->num_imports, 16);
758 /* We need to avoid here duplicates. */
760 pos = find_import_in_list (fdef->imports, fdef->num_imports,
762 (!internal_name ? name : internal_name),
763 module, ordinal, is_dup);
765 return fdef->imports + pos;
767 if (fdef->num_imports >= max_imports)
769 max_imports = ROUND_UP (fdef->num_imports+1, 16);
772 fdef->imports = xrealloc (fdef->imports,
773 max_imports * sizeof (def_file_import));
775 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
777 i = fdef->imports + pos;
778 if (pos != fdef->num_imports)
779 memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
780 memset (i, 0, sizeof (def_file_import));
782 i->name = xstrdup (name);
784 i->module = def_stash_module (fdef, module);
785 i->ordinal = ordinal;
787 i->internal_name = xstrdup (internal_name);
789 i->internal_name = i->name;
790 i->its_name = (its_name ? xstrdup (its_name) : NULL);
803 { "-heap", HEAPSIZE },
804 { "-stack", STACKSIZE_K },
805 { "-attr", SECTIONS },
806 { "-export", EXPORTS },
807 { "-aligncomm", ALIGNCOMM },
812 def_file_add_directive (def_file *my_def, const char *param, int len)
814 def_file *save_def = def;
815 const char *pend = param + len;
816 char * tend = (char *) param;
824 && (ISSPACE (*param) || *param == '\n' || *param == 0))
830 /* Scan forward until we encounter any of:
831 - the end of the buffer
832 - the start of a new option
833 - a newline seperating options
834 - a NUL seperating options. */
835 for (tend = (char *) (param + 1);
837 && !(ISSPACE (tend[-1]) && *tend == '-')
838 && *tend != '\n' && *tend != 0);
842 for (i = 0; diropts[i].param; i++)
844 len = strlen (diropts[i].param);
846 if (tend - param >= len
847 && strncmp (param, diropts[i].param, len) == 0
848 && (param[len] == ':' || param[len] == ' '))
850 lex_parse_string_end = tend;
851 lex_parse_string = param + len + 1;
852 lex_forced_token = diropts[i].token;
860 if (!diropts[i].param)
866 /* xgettext:c-format */
867 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
871 lex_parse_string = 0;
878 /* Parser Callbacks. */
881 def_image_name (const char *name, int base, int is_dll)
883 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
884 to do here. We retain the output filename specified on command line. */
887 const char* image_name = lbasename (name);
889 if (image_name != name)
890 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
891 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
895 /* Append the default suffix, if none specified. */
896 if (strchr (image_name, '.') == 0)
898 const char * suffix = is_dll ? ".dll" : ".exe";
900 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
901 sprintf (def->name, "%s%s", image_name, suffix);
904 def->name = xstrdup (image_name);
907 /* Honor a BASE address statement, even if LIBRARY string is empty. */
908 def->base_address = base;
909 def->is_dll = is_dll;
913 def_description (const char *text)
915 int len = def->description ? strlen (def->description) : 0;
917 len += strlen (text) + 1;
918 if (def->description)
920 def->description = xrealloc (def->description, len);
921 strcat (def->description, text);
925 def->description = xmalloc (len);
926 strcpy (def->description, text);
931 def_stacksize (int reserve, int commit)
933 def->stack_reserve = reserve;
934 def->stack_commit = commit;
938 def_heapsize (int reserve, int commit)
940 def->heap_reserve = reserve;
941 def->heap_commit = commit;
945 def_section (const char *name, int attr)
948 int max_sections = ROUND_UP (def->num_section_defs, 4);
950 if (def->num_section_defs >= max_sections)
952 max_sections = ROUND_UP (def->num_section_defs+1, 4);
954 if (def->section_defs)
955 def->section_defs = xrealloc (def->section_defs,
956 max_sections * sizeof (def_file_import));
958 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
960 s = def->section_defs + def->num_section_defs;
961 memset (s, 0, sizeof (def_file_section));
962 s->name = xstrdup (name);
972 def->num_section_defs++;
976 def_section_alt (const char *name, const char *attr)
980 for (; *attr; attr++)
1002 def_section (name, aval);
1006 def_exports (const char *external_name,
1007 const char *internal_name,
1010 const char *its_name)
1012 def_file_export *dfe;
1015 if (!internal_name && external_name)
1016 internal_name = external_name;
1018 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1021 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1024 /* We might check here for flag redefinition and warn. For now we
1025 ignore duplicates silently. */
1030 dfe->flag_noname = 1;
1032 dfe->flag_constant = 1;
1036 dfe->flag_private = 1;
1040 def_import (const char *internal_name,
1045 const char *its_name)
1048 const char *ext = dllext ? dllext : "dll";
1051 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1052 sprintf (buf, "%s.%s", module, ext);
1055 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1061 def_version (int major, int minor)
1063 def->version_major = major;
1064 def->version_minor = minor;
1068 def_directive (char *str)
1070 struct directive *d = xmalloc (sizeof (struct directive));
1072 d->next = directives;
1074 d->name = xstrdup (str);
1075 d->len = strlen (str);
1079 def_aligncomm (char *str, int align)
1081 def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
1083 c->symbol_name = xstrdup (str);
1084 c->alignment = (unsigned int) align;
1086 c->next = def->aligncomms;
1087 def->aligncomms = c;
1091 def_error (const char *err)
1093 einfo ("%P: %s:%d: %s\n",
1094 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1099 /* Lexical Scanner. */
1104 /* Never freed, but always reused as needed, so no real leak. */
1105 static char *buffer = 0;
1106 static int buflen = 0;
1107 static int bufptr = 0;
1112 if (bufptr == buflen)
1114 buflen += 50; /* overly reasonable, eh? */
1116 buffer = xrealloc (buffer, buflen + 1);
1118 buffer = xmalloc (buflen + 1);
1120 buffer[bufptr++] = c;
1121 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1133 { "CONSTANT", CONSTANTU },
1134 { "constant", CONSTANTL },
1137 { "DESCRIPTION", DESCRIPTION },
1138 { "DIRECTIVE", DIRECTIVE },
1139 { "EXECUTE", EXECUTE },
1140 { "EXPORTS", EXPORTS },
1141 { "HEAPSIZE", HEAPSIZE },
1142 { "IMPORTS", IMPORTS },
1143 { "LIBRARY", LIBRARY },
1145 { "NONAME", NONAMEU },
1146 { "noname", NONAMEL },
1147 { "PRIVATE", PRIVATEU },
1148 { "private", PRIVATEL },
1150 { "SECTIONS", SECTIONS },
1151 { "SEGMENTS", SECTIONS },
1152 { "SHARED", SHARED },
1153 { "STACKSIZE", STACKSIZE_K },
1154 { "VERSION", VERSIONK },
1164 if (lex_parse_string)
1166 if (lex_parse_string >= lex_parse_string_end)
1169 rv = *lex_parse_string++;
1173 rv = fgetc (the_file);
1183 if (lex_parse_string)
1189 return ungetc (c, the_file);
1197 if (lex_forced_token)
1199 i = lex_forced_token;
1200 lex_forced_token = 0;
1202 printf ("lex: forcing token %d\n", i);
1209 /* Trim leading whitespace. */
1210 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1216 printf ("lex: EOF\n");
1221 if (saw_newline && c == ';')
1227 while (c != EOF && c != '\n');
1233 /* Must be something else. */
1239 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1246 yylval.digits = xstrdup (buffer);
1248 printf ("lex: `%s' returns DIGITS\n", buffer);
1253 if (ISALPHA (c) || strchr ("$:-_?@", c))
1262 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1264 else if (ISDIGIT (c)) /* '@' followed by digit. */
1270 printf ("lex: @ returns itself\n");
1274 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1281 if (ISALPHA (q)) /* Check for tokens. */
1283 for (i = 0; tokens[i].name; i++)
1284 if (strcmp (tokens[i].name, buffer) == 0)
1287 printf ("lex: `%s' is a string token\n", buffer);
1289 return tokens[i].token;
1293 printf ("lex: `%s' returns ID\n", buffer);
1295 yylval.id = xstrdup (buffer);
1299 if (c == '\'' || c == '"')
1305 while (c != EOF && c != q)
1310 yylval.id = xstrdup (buffer);
1312 printf ("lex: `%s' returns ID\n", buffer);
1323 printf ("lex: `==' returns EQUAL\n");
1329 printf ("lex: `=' returns itself\n");
1333 if (c == '.' || c == ',')
1336 printf ("lex: `%c' returns itself\n", c);
1347 /*printf ("lex: 0x%02x ignored\n", c); */