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