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