Locale changes from Bruno Haible <haible@clisp.cons.org>.
[deliverable/binutils-gdb.git] / ld / deffilep.y
CommitLineData
252b5132
RH
1%{ /* deffilep.y - parser for .def files */
2
db09f25b
AM
3/* Copyright 1995, 1997, 1998, 1999, 2000, 2001
4 Free Software Foundation, Inc.
252b5132
RH
5
6This file is part of GNU Binutils.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include <stdio.h>
252b5132 23#include "libiberty.h"
3882b010 24#include "safe-ctype.h"
252b5132
RH
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
252b5132
RH
81static void def_description PARAMS ((const char *));
82static void def_exports PARAMS ((const char *, const char *, int, int));
83static void def_heapsize PARAMS ((int, int));
84static void def_import
85 PARAMS ((const char *, const char *, const char *, const char *, int));
86static void def_library PARAMS ((const char *, int));
db09f25b 87static def_file_module *def_stash_module PARAMS ((def_file *, const char *));
252b5132
RH
88static void def_name PARAMS ((const char *, int));
89static void def_section PARAMS ((const char *, int));
90static void def_section_alt PARAMS ((const char *, const char *));
91static void def_stacksize PARAMS ((int, int));
92static void def_version PARAMS ((int, int));
93static void def_directive PARAMS ((char *));
94static int def_parse PARAMS ((void));
95static int def_error PARAMS ((const char *));
948f9114
AJ
96static void put_buf PARAMS ((char));
97static int def_getc PARAMS ((void));
98static int def_ungetc PARAMS ((int));
252b5132
RH
99static int def_lex PARAMS ((void));
100
101static int lex_forced_token = 0;
102static const char *lex_parse_string = 0;
103static const char *lex_parse_string_end = 0;
104
105%}
106
107%union {
108 char *id;
109 int number;
110};
111
7c9e78f8
DD
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
252b5132
RH
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
124start: start command
125 | command
126 ;
127
128command:
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);}
7c9e78f8 135 | DATAU attr_list { def_section ("DATA", $2);}
252b5132
RH
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
145explist:
146 /* EMPTY */
147 | expline
148 | explist expline
149 ;
150
151expline:
7c9e78f8
DD
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); }
252b5132
RH
157 ;
158exp_opt_list:
7c9e78f8
DD
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; }
252b5132
RH
163 | { $$ = 0; }
164 ;
165exp_opt:
7c9e78f8
DD
166 NONAMEU { $$ = 1; }
167 | NONAMEL { $$ = 1; }
168 | CONSTANTU { $$ = 2; }
169 | CONSTANTL { $$ = 2; }
170 | DATAU { $$ = 4; }
171 | DATAL { $$ = 4; }
172 | PRIVATEU { $$ = 8; }
173 | PRIVATEL { $$ = 8; }
252b5132
RH
174 ;
175implist:
176 implist impline
177 | impline
178 ;
179
180impline:
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
189seclist:
190 seclist secline
191 | secline
192 ;
193
194secline:
195 ID attr_list { def_section ($1, $2);}
196 | ID ID { def_section_alt ($1, $2);}
197 ;
198
199attr_list:
200 attr_list opt_comma attr { $$ = $1 | $3; }
201 | attr { $$ = $1; }
202 ;
203
204opt_comma:
205 ','
206 |
207 ;
208opt_number: ',' NUMBER { $$=$2;}
209 | { $$=-1;}
210 ;
211
212attr:
213 READ { $$ = 1;}
214 | WRITE { $$ = 2;}
215 | EXECUTE { $$=4;}
216 | SHARED { $$=8;}
217 ;
218
219opt_name: ID { $$ = $1; }
5aaace27
NC
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 | { $$ = ""; }
252b5132
RH
227 ;
228
229opt_ordinal:
230 '@' NUMBER { $$ = $2;}
231 | { $$ = -1;}
232 ;
233
234opt_equal_name:
235 '=' ID { $$ = $2; }
236 | { $$ = 0; }
237 ;
238
239opt_base: BASE '=' NUMBER { $$ = $3;}
240 | { $$ = 0;}
241 ;
242
243
244
245%%
246
247/*****************************************************************************
248 API
249 *****************************************************************************/
250
251static FILE *the_file;
252static const char *def_filename;
253static int linenumber;
254static def_file *def;
255static int saw_newline;
256
257struct directive
258 {
259 struct directive *next;
260 char *name;
261 int len;
262 };
263
264static struct directive *directives = 0;
265
266def_file *
267def_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
279def_file *
280def_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
324void
325def_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
385void
386def_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
466def_file_export *
467def_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
496static def_file_module *
497def_stash_module (def, name)
498 def_file *def;
db09f25b 499 const char *name;
252b5132
RH
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
513def_file_import *
514def_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)
db09f25b 536 i->module = def_stash_module (def, module);
252b5132
RH
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
546struct
547{
548 char *param;
549 int token;
550}
551diropts[] =
552{
553 { "-heap", HEAPSIZE },
554 { "-stack", STACKSIZE },
555 { "-attr", SECTIONS },
556 { "-export", EXPORTS },
557 { 0, 0 }
558};
559
560void
561def_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 {
3882b010 575 while (param < pend && ISSPACE (*param))
252b5132
RH
576 param++;
577 for (tend = param + 1;
3882b010 578 tend < pend && !(ISSPACE (tend[-1]) && *tend == '-');
252b5132
RH
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
614static void
615def_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
626static void
627def_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
638static void
639def_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
656static void
657def_stacksize (reserve, commit)
658 int reserve;
659 int commit;
660{
661 def->stack_reserve = reserve;
662 def->stack_commit = commit;
663}
664
665static void
666def_heapsize (reserve, commit)
667 int reserve;
668 int commit;
669{
670 def->heap_reserve = reserve;
671 def->heap_commit = commit;
672}
673
674static void
675def_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
704static void
705def_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
735static void
736def_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
761static void
762def_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
783static void
784def_version (major, minor)
785 int major;
786 int minor;
787{
788 def->version_major = major;
789 def->version_minor = minor;
790}
791
792static void
793def_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
803static int
804def_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 */
821static char *buffer = 0;
822static int buflen = 0;
823static int bufptr = 0;
824
825static void
826put_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
841static struct
842{
843 char *name;
844 int token;
845}
846tokens[] =
847{
848 { "BASE", BASE },
849 { "CODE", CODE },
7c9e78f8
DD
850 { "CONSTANT", CONSTANTU },
851 { "constant", CONSTANTL },
852 { "DATA", DATAU },
853 { "data", DATAL },
252b5132
RH
854 { "DESCRIPTION", DESCRIPTION },
855 { "DIRECTIVE", DIRECTIVE },
856 { "EXECUTE", EXECUTE },
857 { "EXPORTS", EXPORTS },
858 { "HEAPSIZE", HEAPSIZE },
859 { "IMPORTS", IMPORTS },
860 { "LIBRARY", LIBRARY },
861 { "NAME", NAME },
7c9e78f8
DD
862 { "NONAME", NONAMEU },
863 { "noname", NONAMEL },
864 { "PRIVATE", PRIVATEU },
865 { "private", PRIVATEL },
252b5132
RH
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
876static int
877def_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
896static int
897def_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
909static int
910def_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
3882b010 952 if (ISDIGIT (c))
252b5132
RH
953 {
954 bufptr = 0;
3882b010 955 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
252b5132
RH
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
3882b010 969 if (ISALPHA (c) || strchr ("$:-_?", c))
252b5132
RH
970 {
971 bufptr = 0;
3882b010 972 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
252b5132
RH
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.12044 seconds and 4 git commands to generate.