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