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