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