Add new devices x1122 x1132 emulation.
[deliverable/binutils-gdb.git] / ld / deffilep.y
CommitLineData
252b5132
RH
1%{ /* deffilep.y - parser for .def files */
2
a35bc64f 3/* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
db09f25b 4 Free Software Foundation, Inc.
252b5132 5
a35bc64f 6 This file is part of GNU Binutils.
252b5132 7
a35bc64f
NC
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.
252b5132 12
a35bc64f
NC
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.
252b5132 17
a35bc64f
NC
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. */
252b5132
RH
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
a35bc64f 40 generators need to be fixed instead of adding those names to this list. */
252b5132
RH
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
a35bc64f
NC
69#define yyreds def_reds /* With YYDEBUG defined. */
70#define yytoks def_toks /* With YYDEBUG defined. */
252b5132
RH
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));
a35bc64f 84static void def_import PARAMS ((const char *, const char *, const char *, const char *, int));
252b5132 85static void def_library PARAMS ((const char *, int));
db09f25b 86static def_file_module *def_stash_module PARAMS ((def_file *, const char *));
252b5132
RH
87static void def_name PARAMS ((const char *, int));
88static void def_section PARAMS ((const char *, int));
89static void def_section_alt PARAMS ((const char *, const char *));
90static void def_stacksize PARAMS ((int, int));
91static void def_version PARAMS ((int, int));
92static void def_directive PARAMS ((char *));
93static int def_parse PARAMS ((void));
94static int def_error PARAMS ((const char *));
948f9114
AJ
95static void put_buf PARAMS ((char));
96static int def_getc PARAMS ((void));
97static int def_ungetc PARAMS ((int));
252b5132
RH
98static int def_lex PARAMS ((void));
99
100static int lex_forced_token = 0;
101static const char *lex_parse_string = 0;
102static const char *lex_parse_string_end = 0;
103
104%}
105
106%union {
107 char *id;
108 int number;
109};
110
7c9e78f8
DD
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
252b5132
RH
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
123start: start command
124 | command
125 ;
126
127command:
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);}
7c9e78f8 134 | DATAU attr_list { def_section ("DATA", $2);}
252b5132
RH
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
144explist:
145 /* EMPTY */
146 | expline
147 | explist expline
148 ;
149
150expline:
7c9e78f8
DD
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); }
252b5132
RH
156 ;
157exp_opt_list:
7c9e78f8
DD
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; }
252b5132
RH
162 | { $$ = 0; }
163 ;
164exp_opt:
7c9e78f8
DD
165 NONAMEU { $$ = 1; }
166 | NONAMEL { $$ = 1; }
167 | CONSTANTU { $$ = 2; }
168 | CONSTANTL { $$ = 2; }
169 | DATAU { $$ = 4; }
170 | DATAL { $$ = 4; }
171 | PRIVATEU { $$ = 8; }
172 | PRIVATEL { $$ = 8; }
252b5132
RH
173 ;
174implist:
175 implist impline
176 | impline
177 ;
178
179impline:
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
188seclist:
189 seclist secline
190 | secline
191 ;
192
193secline:
194 ID attr_list { def_section ($1, $2);}
195 | ID ID { def_section_alt ($1, $2);}
196 ;
197
198attr_list:
199 attr_list opt_comma attr { $$ = $1 | $3; }
200 | attr { $$ = $1; }
201 ;
202
203opt_comma:
204 ','
205 |
206 ;
207opt_number: ',' NUMBER { $$=$2;}
208 | { $$=-1;}
209 ;
210
211attr:
212 READ { $$ = 1;}
213 | WRITE { $$ = 2;}
214 | EXECUTE { $$=4;}
215 | SHARED { $$=8;}
216 ;
217
218opt_name: ID { $$ = $1; }
5aaace27
NC
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 | { $$ = ""; }
252b5132
RH
226 ;
227
228opt_ordinal:
229 '@' NUMBER { $$ = $2;}
230 | { $$ = -1;}
231 ;
232
233opt_equal_name:
234 '=' ID { $$ = $2; }
235 | { $$ = 0; }
236 ;
237
238opt_base: BASE '=' NUMBER { $$ = $3;}
239 | { $$ = 0;}
240 ;
241
242
243
244%%
245
246/*****************************************************************************
247 API
248 *****************************************************************************/
249
250static FILE *the_file;
251static const char *def_filename;
252static int linenumber;
253static def_file *def;
254static int saw_newline;
255
256struct directive
257 {
258 struct directive *next;
259 char *name;
260 int len;
261 };
262
263static struct directive *directives = 0;
264
265def_file *
266def_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
278def_file *
279def_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
323void
324def_file_free (def)
325 def_file *def;
326{
327 int i;
a35bc64f 328
252b5132
RH
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;
a35bc64f 391
252b5132
RH
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");
a35bc64f 413
252b5132
RH
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");
a35bc64f 433
252b5132
RH
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");
a35bc64f 454
252b5132
RH
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 }
a35bc64f 464
252b5132
RH
465 if (def->version_major != -1)
466 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
a35bc64f 467
252b5132
RH
468 fprintf (file, "<<<< def_file at 0x%08x\n", def);
469}
470#endif
471
472def_file_export *
473def_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);
a35bc64f 481
252b5132
RH
482 if (def->num_exports >= max_exports)
483 {
a35bc64f 484 max_exports = ROUND_UP(def->num_exports + 1, 32);
252b5132 485 if (def->exports)
a35bc64f
NC
486 def->exports = (def_file_export *)
487 xrealloc (def->exports, max_exports * sizeof (def_file_export));
252b5132 488 else
a35bc64f
NC
489 def->exports = (def_file_export *)
490 xmalloc (max_exports * sizeof (def_file_export));
252b5132
RH
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
a35bc64f
NC
505def_file_module *
506def_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
252b5132
RH
519static def_file_module *
520def_stash_module (def, name)
521 def_file *def;
db09f25b 522 const char *name;
252b5132
RH
523{
524 def_file_module *s;
a35bc64f
NC
525
526 if ((s = def_get_module (def, name)) != (def_file_module *) 0)
252b5132
RH
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
536def_file_import *
537def_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);
a35bc64f 546
252b5132
RH
547 if (def->num_imports >= max_imports)
548 {
549 max_imports = ROUND_UP(def->num_imports+1, 16);
a35bc64f 550
252b5132 551 if (def->imports)
a35bc64f
NC
552 def->imports = (def_file_import *)
553 xrealloc (def->imports, max_imports * sizeof (def_file_import));
252b5132 554 else
a35bc64f
NC
555 def->imports = (def_file_import *)
556 xmalloc (max_imports * sizeof (def_file_import));
252b5132
RH
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)
db09f25b 563 i->module = def_stash_module (def, module);
252b5132
RH
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++;
a35bc64f 570
252b5132
RH
571 return i;
572}
573
574struct
575{
576 char *param;
577 int token;
578}
579diropts[] =
580{
581 { "-heap", HEAPSIZE },
582 { "-stack", STACKSIZE },
583 { "-attr", SECTIONS },
584 { "-export", EXPORTS },
585 { 0, 0 }
586};
587
588void
589def_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 {
3882b010 603 while (param < pend && ISSPACE (*param))
252b5132 604 param++;
a35bc64f 605
252b5132 606 for (tend = param + 1;
3882b010 607 tend < pend && !(ISSPACE (tend[-1]) && *tend == '-');
a35bc64f
NC
608 tend++)
609 ;
252b5132
RH
610
611 for (i = 0; diropts[i].param; i++)
612 {
613 int len = strlen (diropts[i].param);
a35bc64f 614
252b5132
RH
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)
a35bc64f
NC
629 /* xgettext:c-format */
630 einfo (_("Warning: .drectve `%.*s' unrecognized\n"),
631 tend - param, param);
632
252b5132
RH
633 lex_parse_string = 0;
634 param = tend;
635 }
636
637 def = save_def;
638}
639
a35bc64f 640/* Parser Callbacks. */
252b5132
RH
641
642static void
643def_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
654static void
655def_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
666static void
667def_description (text)
668 const char *text;
669{
670 int len = def->description ? strlen (def->description) : 0;
a35bc64f 671
252b5132
RH
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
685static void
686def_stacksize (reserve, commit)
687 int reserve;
688 int commit;
689{
690 def->stack_reserve = reserve;
691 def->stack_commit = commit;
692}
693
694static void
695def_heapsize (reserve, commit)
696 int reserve;
697 int commit;
698{
699 def->heap_reserve = reserve;
700 def->heap_commit = commit;
701}
702
703static void
704def_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);
a35bc64f 710
252b5132
RH
711 if (def->num_section_defs >= max_sections)
712 {
713 max_sections = ROUND_UP(def->num_section_defs+1, 4);
a35bc64f 714
252b5132
RH
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
735static void
736def_section_alt (name, attr)
737 const char *name;
738 const char *attr;
739{
740 int aval = 0;
a35bc64f 741
252b5132
RH
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
767static void
768def_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
793static void
794def_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
815static void
816def_version (major, minor)
817 int major;
818 int minor;
819{
820 def->version_major = major;
821 def->version_minor = minor;
822}
823
824static void
825def_directive (str)
826 char *str;
827{
828 struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
a35bc64f 829
252b5132
RH
830 d->next = directives;
831 directives = d;
832 d->name = xstrdup (str);
833 d->len = strlen (str);
834}
835
836static int
837def_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
a35bc64f 846/* Lexical Scanner. */
252b5132
RH
847
848#undef TRACE
849#define TRACE 0
850
a35bc64f 851/* Never freed, but always reused as needed, so no real leak. */
252b5132
RH
852static char *buffer = 0;
853static int buflen = 0;
854static int bufptr = 0;
855
856static void
857put_buf (c)
858 char c;
859{
860 if (bufptr == buflen)
861 {
a35bc64f 862 buflen += 50; /* overly reasonable, eh? */
252b5132
RH
863 if (buffer)
864 buffer = (char *) xrealloc (buffer, buflen + 1);
865 else
866 buffer = (char *) xmalloc (buflen + 1);
867 }
868 buffer[bufptr++] = c;
a35bc64f 869 buffer[bufptr] = 0; /* not optimal, but very convenient. */
252b5132
RH
870}
871
872static struct
873{
874 char *name;
875 int token;
876}
877tokens[] =
878{
879 { "BASE", BASE },
880 { "CODE", CODE },
7c9e78f8
DD
881 { "CONSTANT", CONSTANTU },
882 { "constant", CONSTANTL },
883 { "DATA", DATAU },
884 { "data", DATAL },
252b5132
RH
885 { "DESCRIPTION", DESCRIPTION },
886 { "DIRECTIVE", DIRECTIVE },
887 { "EXECUTE", EXECUTE },
888 { "EXPORTS", EXPORTS },
889 { "HEAPSIZE", HEAPSIZE },
890 { "IMPORTS", IMPORTS },
891 { "LIBRARY", LIBRARY },
892 { "NAME", NAME },
7c9e78f8
DD
893 { "NONAME", NONAMEU },
894 { "noname", NONAMEL },
895 { "PRIVATE", PRIVATEU },
896 { "private", PRIVATEL },
252b5132
RH
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
907static int
908def_getc ()
909{
910 int rv;
a35bc64f 911
252b5132
RH
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
928static int
929def_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
941static int
942def_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
a35bc64f 958 /* Trim leading whitespace. */
252b5132
RH
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 }
a35bc64f
NC
981
982 /* Must be something else. */
252b5132
RH
983 saw_newline = 0;
984
3882b010 985 if (ISDIGIT (c))
252b5132
RH
986 {
987 bufptr = 0;
3882b010 988 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
252b5132
RH
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
c9e38879 1002 if (ISALPHA (c) || strchr ("$:-_?@", c))
252b5132
RH
1003 {
1004 bufptr = 0;
c9e38879
NC
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
3882b010 1023 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
252b5132
RH
1024 {
1025 put_buf (c);
1026 c = def_getc ();
1027 }
1028 if (c != EOF)
1029 def_ungetc (c);
c9e38879
NC
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 {
252b5132 1035#if TRACE
c9e38879 1036 printf ("lex: `%s' is a string token\n", buffer);
252b5132 1037#endif
c9e38879
NC
1038 return tokens[i].token;
1039 }
1040 }
252b5132
RH
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;
a35bc64f 1053
252b5132
RH
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
c9e38879 1066 if (c == '=' || c == '.' || c == ',')
252b5132
RH
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.218111 seconds and 4 git commands to generate.