* rcparse.y (res_text_field): New res_id variable.
[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
053c44e1 119%type <id> opt_name opt_equal_name dot_name
252b5132
RH
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>. */
053c44e1 154 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
7c9e78f8 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:
053c44e1 234 '=' dot_name { $$ = $2; }
252b5132
RH
235 | { $$ = 0; }
236 ;
237
238opt_base: BASE '=' NUMBER { $$ = $3;}
4064c856 239 | { $$ = -1;}
252b5132
RH
240 ;
241
053c44e1
DS
242dot_name: ID { $$ = $1; }
243 | dot_name '.' ID
244 {
245 char * name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
246 sprintf (name, "%s.%s", $1, $3);
247 $$ = name;
248 }
249 ;
252b5132
RH
250
251
252%%
253
254/*****************************************************************************
255 API
256 *****************************************************************************/
257
258static FILE *the_file;
259static const char *def_filename;
260static int linenumber;
261static def_file *def;
262static int saw_newline;
263
264struct directive
265 {
266 struct directive *next;
267 char *name;
268 int len;
269 };
270
271static struct directive *directives = 0;
272
273def_file *
274def_file_empty ()
275{
276 def_file *rv = (def_file *) xmalloc (sizeof (def_file));
277 memset (rv, 0, sizeof (def_file));
278 rv->is_dll = -1;
279 rv->base_address = (bfd_vma) (-1);
280 rv->stack_reserve = rv->stack_commit = -1;
281 rv->heap_reserve = rv->heap_commit = -1;
282 rv->version_major = rv->version_minor = -1;
283 return rv;
284}
285
286def_file *
287def_file_parse (filename, add_to)
288 const char *filename;
289 def_file *add_to;
290{
291 struct directive *d;
292
293 the_file = fopen (filename, "r");
294 def_filename = filename;
295 linenumber = 1;
296 if (!the_file)
297 {
298 perror (filename);
299 return 0;
300 }
301 if (add_to)
302 {
303 def = add_to;
304 }
305 else
306 {
307 def = def_file_empty ();
308 }
309
310 saw_newline = 1;
311 if (def_parse ())
312 {
313 def_file_free (def);
314 fclose (the_file);
315 return 0;
316 }
317
318 fclose (the_file);
319
320 for (d = directives; d; d = d->next)
321 {
322#if TRACE
323 printf ("Adding directive %08x `%s'\n", d->name, d->name);
324#endif
325 def_file_add_directive (def, d->name, d->len);
326 }
327
328 return def;
329}
330
331void
332def_file_free (def)
333 def_file *def;
334{
335 int i;
a35bc64f 336
252b5132
RH
337 if (!def)
338 return;
339 if (def->name)
340 free (def->name);
341 if (def->description)
342 free (def->description);
343
344 if (def->section_defs)
345 {
346 for (i = 0; i < def->num_section_defs; i++)
347 {
348 if (def->section_defs[i].name)
349 free (def->section_defs[i].name);
350 if (def->section_defs[i].class)
351 free (def->section_defs[i].class);
352 }
353 free (def->section_defs);
354 }
355
356 if (def->exports)
357 {
358 for (i = 0; i < def->num_exports; i++)
359 {
360 if (def->exports[i].internal_name
361 && def->exports[i].internal_name != def->exports[i].name)
362 free (def->exports[i].internal_name);
363 if (def->exports[i].name)
364 free (def->exports[i].name);
365 }
366 free (def->exports);
367 }
368
369 if (def->imports)
370 {
371 for (i = 0; i < def->num_imports; i++)
372 {
373 if (def->imports[i].internal_name
374 && def->imports[i].internal_name != def->imports[i].name)
375 free (def->imports[i].internal_name);
376 if (def->imports[i].name)
377 free (def->imports[i].name);
378 }
379 free (def->imports);
380 }
381
382 while (def->modules)
383 {
384 def_file_module *m = def->modules;
385 def->modules = def->modules->next;
386 free (m);
387 }
388
389 free (def);
390}
391
392#ifdef DEF_FILE_PRINT
393void
394def_file_print (file, def)
395 FILE *file;
396 def_file *def;
397{
398 int i;
a35bc64f 399
252b5132
RH
400 fprintf (file, ">>>> def_file at 0x%08x\n", def);
401 if (def->name)
402 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
403 if (def->is_dll != -1)
404 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
405 if (def->base_address != (bfd_vma) (-1))
406 fprintf (file, " base address: 0x%08x\n", def->base_address);
407 if (def->description)
408 fprintf (file, " description: `%s'\n", def->description);
409 if (def->stack_reserve != -1)
410 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
411 if (def->stack_commit != -1)
412 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
413 if (def->heap_reserve != -1)
414 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
415 if (def->heap_commit != -1)
416 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
417
418 if (def->num_section_defs > 0)
419 {
420 fprintf (file, " section defs:\n");
a35bc64f 421
252b5132
RH
422 for (i = 0; i < def->num_section_defs; i++)
423 {
424 fprintf (file, " name: `%s', class: `%s', flags:",
425 def->section_defs[i].name, def->section_defs[i].class);
426 if (def->section_defs[i].flag_read)
427 fprintf (file, " R");
428 if (def->section_defs[i].flag_write)
429 fprintf (file, " W");
430 if (def->section_defs[i].flag_execute)
431 fprintf (file, " X");
432 if (def->section_defs[i].flag_shared)
433 fprintf (file, " S");
434 fprintf (file, "\n");
435 }
436 }
437
438 if (def->num_exports > 0)
439 {
440 fprintf (file, " exports:\n");
a35bc64f 441
252b5132
RH
442 for (i = 0; i < def->num_exports; i++)
443 {
444 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
445 def->exports[i].name, def->exports[i].internal_name,
446 def->exports[i].ordinal);
447 if (def->exports[i].flag_private)
448 fprintf (file, " P");
449 if (def->exports[i].flag_constant)
450 fprintf (file, " C");
451 if (def->exports[i].flag_noname)
452 fprintf (file, " N");
453 if (def->exports[i].flag_data)
454 fprintf (file, " D");
455 fprintf (file, "\n");
456 }
457 }
458
459 if (def->num_imports > 0)
460 {
461 fprintf (file, " imports:\n");
a35bc64f 462
252b5132
RH
463 for (i = 0; i < def->num_imports; i++)
464 {
465 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
466 def->imports[i].internal_name,
467 def->imports[i].module,
468 def->imports[i].name,
469 def->imports[i].ordinal);
470 }
471 }
a35bc64f 472
252b5132
RH
473 if (def->version_major != -1)
474 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
a35bc64f 475
252b5132
RH
476 fprintf (file, "<<<< def_file at 0x%08x\n", def);
477}
478#endif
479
480def_file_export *
481def_file_add_export (def, external_name, internal_name, ordinal)
482 def_file *def;
483 const char *external_name;
484 const char *internal_name;
485 int ordinal;
486{
487 def_file_export *e;
488 int max_exports = ROUND_UP(def->num_exports, 32);
a35bc64f 489
252b5132
RH
490 if (def->num_exports >= max_exports)
491 {
a35bc64f 492 max_exports = ROUND_UP(def->num_exports + 1, 32);
252b5132 493 if (def->exports)
a35bc64f
NC
494 def->exports = (def_file_export *)
495 xrealloc (def->exports, max_exports * sizeof (def_file_export));
252b5132 496 else
a35bc64f
NC
497 def->exports = (def_file_export *)
498 xmalloc (max_exports * sizeof (def_file_export));
252b5132
RH
499 }
500 e = def->exports + def->num_exports;
501 memset (e, 0, sizeof (def_file_export));
502 if (internal_name && !external_name)
503 external_name = internal_name;
504 if (external_name && !internal_name)
505 internal_name = external_name;
506 e->name = xstrdup (external_name);
507 e->internal_name = xstrdup (internal_name);
508 e->ordinal = ordinal;
509 def->num_exports++;
510 return e;
511}
512
a35bc64f
NC
513def_file_module *
514def_get_module (def, name)
515 def_file *def;
516 const char *name;
517{
518 def_file_module *s;
519
520 for (s = def->modules; s; s = s->next)
521 if (strcmp (s->name, name) == 0)
522 return s;
523
524 return (def_file_module *) 0;
525}
526
252b5132
RH
527static def_file_module *
528def_stash_module (def, name)
529 def_file *def;
db09f25b 530 const char *name;
252b5132
RH
531{
532 def_file_module *s;
a35bc64f
NC
533
534 if ((s = def_get_module (def, name)) != (def_file_module *) 0)
252b5132
RH
535 return s;
536 s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name));
537 s->next = def->modules;
538 def->modules = s;
539 s->user_data = 0;
540 strcpy (s->name, name);
541 return s;
542}
543
544def_file_import *
545def_file_add_import (def, name, module, ordinal, internal_name)
546 def_file *def;
547 const char *name;
548 const char *module;
549 int ordinal;
550 const char *internal_name;
551{
552 def_file_import *i;
553 int max_imports = ROUND_UP(def->num_imports, 16);
a35bc64f 554
252b5132
RH
555 if (def->num_imports >= max_imports)
556 {
557 max_imports = ROUND_UP(def->num_imports+1, 16);
a35bc64f 558
252b5132 559 if (def->imports)
a35bc64f
NC
560 def->imports = (def_file_import *)
561 xrealloc (def->imports, max_imports * sizeof (def_file_import));
252b5132 562 else
a35bc64f
NC
563 def->imports = (def_file_import *)
564 xmalloc (max_imports * sizeof (def_file_import));
252b5132
RH
565 }
566 i = def->imports + def->num_imports;
567 memset (i, 0, sizeof (def_file_import));
568 if (name)
569 i->name = xstrdup (name);
570 if (module)
db09f25b 571 i->module = def_stash_module (def, module);
252b5132
RH
572 i->ordinal = ordinal;
573 if (internal_name)
574 i->internal_name = xstrdup (internal_name);
575 else
576 i->internal_name = i->name;
577 def->num_imports++;
a35bc64f 578
252b5132
RH
579 return i;
580}
581
582struct
583{
584 char *param;
585 int token;
586}
587diropts[] =
588{
589 { "-heap", HEAPSIZE },
590 { "-stack", STACKSIZE },
591 { "-attr", SECTIONS },
592 { "-export", EXPORTS },
593 { 0, 0 }
594};
595
596void
597def_file_add_directive (my_def, param, len)
598 def_file *my_def;
599 const char *param;
600 int len;
601{
602 def_file *save_def = def;
603 const char *pend = param + len;
dc17f155 604 char * tend = (char *) param;
252b5132
RH
605 int i;
606
607 def = my_def;
608
609 while (param < pend)
610 {
dc17f155 611 while (param < pend && (ISSPACE (*param) || * param == '\n' || * param == 0))
252b5132 612 param++;
a35bc64f 613
dc17f155
NC
614 if (param == pend)
615 break;
616
617 /* Scan forward until we encounter any of:
618 - the end of the buffer
619 - the start of a new option
620 - a newline seperating options
621 - a NUL seperating options. */
622 for (tend = (char *) (param + 1);
623 tend < pend && !(ISSPACE (tend[-1]) && *tend == '-') && (*tend != '\n') && (*tend != 0);
a35bc64f
NC
624 tend++)
625 ;
252b5132
RH
626
627 for (i = 0; diropts[i].param; i++)
628 {
629 int len = strlen (diropts[i].param);
a35bc64f 630
252b5132
RH
631 if (tend - param >= len
632 && strncmp (param, diropts[i].param, len) == 0
633 && (param[len] == ':' || param[len] == ' '))
634 {
635 lex_parse_string_end = tend;
636 lex_parse_string = param + len + 1;
637 lex_forced_token = diropts[i].token;
638 saw_newline = 0;
dc17f155
NC
639 if (def_parse ())
640 continue;
252b5132
RH
641 break;
642 }
643 }
644
645 if (!diropts[i].param)
dc17f155
NC
646 {
647 char saved;
648
649 saved = * tend;
650 * tend = 0;
651 /* xgettext:c-format */
652 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
653 * tend = saved;
654 }
a35bc64f 655
252b5132
RH
656 lex_parse_string = 0;
657 param = tend;
658 }
659
660 def = save_def;
661}
662
a35bc64f 663/* Parser Callbacks. */
252b5132
RH
664
665static void
666def_name (name, base)
667 const char *name;
668 int base;
669{
670 if (def->name)
671 free (def->name);
672 def->name = xstrdup (name);
673 def->base_address = base;
674 def->is_dll = 0;
675}
676
677static void
678def_library (name, base)
679 const char *name;
680 int base;
681{
682 if (def->name)
683 free (def->name);
684 def->name = xstrdup (name);
685 def->base_address = base;
686 def->is_dll = 1;
687}
688
689static void
690def_description (text)
691 const char *text;
692{
693 int len = def->description ? strlen (def->description) : 0;
a35bc64f 694
252b5132
RH
695 len += strlen (text) + 1;
696 if (def->description)
697 {
698 def->description = (char *) xrealloc (def->description, len);
699 strcat (def->description, text);
700 }
701 else
702 {
703 def->description = (char *) xmalloc (len);
704 strcpy (def->description, text);
705 }
706}
707
708static void
709def_stacksize (reserve, commit)
710 int reserve;
711 int commit;
712{
713 def->stack_reserve = reserve;
714 def->stack_commit = commit;
715}
716
717static void
718def_heapsize (reserve, commit)
719 int reserve;
720 int commit;
721{
722 def->heap_reserve = reserve;
723 def->heap_commit = commit;
724}
725
726static void
727def_section (name, attr)
728 const char *name;
729 int attr;
730{
731 def_file_section *s;
732 int max_sections = ROUND_UP(def->num_section_defs, 4);
a35bc64f 733
252b5132
RH
734 if (def->num_section_defs >= max_sections)
735 {
736 max_sections = ROUND_UP(def->num_section_defs+1, 4);
a35bc64f 737
252b5132
RH
738 if (def->section_defs)
739 def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
740 else
741 def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import));
742 }
743 s = def->section_defs + def->num_section_defs;
744 memset (s, 0, sizeof (def_file_section));
745 s->name = xstrdup (name);
746 if (attr & 1)
747 s->flag_read = 1;
748 if (attr & 2)
749 s->flag_write = 1;
750 if (attr & 4)
751 s->flag_execute = 1;
752 if (attr & 8)
753 s->flag_shared = 1;
754
755 def->num_section_defs++;
756}
757
758static void
759def_section_alt (name, attr)
760 const char *name;
761 const char *attr;
762{
763 int aval = 0;
a35bc64f 764
252b5132
RH
765 for (; *attr; attr++)
766 {
767 switch (*attr)
768 {
769 case 'R':
770 case 'r':
771 aval |= 1;
772 break;
773 case 'W':
774 case 'w':
775 aval |= 2;
776 break;
777 case 'X':
778 case 'x':
779 aval |= 4;
780 break;
781 case 'S':
782 case 's':
783 aval |= 8;
784 break;
785 }
786 }
787 def_section (name, aval);
788}
789
790static void
791def_exports (external_name, internal_name, ordinal, flags)
792 const char *external_name;
793 const char *internal_name;
794 int ordinal;
795 int flags;
796{
797 def_file_export *dfe;
798
799 if (!internal_name && external_name)
800 internal_name = external_name;
801#if TRACE
802 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
803#endif
804
805 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
806 if (flags & 1)
807 dfe->flag_noname = 1;
808 if (flags & 2)
809 dfe->flag_constant = 1;
810 if (flags & 4)
811 dfe->flag_data = 1;
812 if (flags & 8)
813 dfe->flag_private = 1;
814}
815
816static void
817def_import (internal_name, module, dllext, name, ordinal)
818 const char *internal_name;
819 const char *module;
820 const char *dllext;
821 const char *name;
822 int ordinal;
823{
824 char *buf = 0;
053c44e1
DS
825 const char *ext = dllext ? dllext : "dll";
826
827 buf = (char *) xmalloc (strlen (module) + strlen (ext) + 2);
828 sprintf (buf, "%s.%s", module, ext);
829 module = buf;
252b5132
RH
830
831 def_file_add_import (def, name, module, ordinal, internal_name);
832 if (buf)
833 free (buf);
834}
835
836static void
837def_version (major, minor)
838 int major;
839 int minor;
840{
841 def->version_major = major;
842 def->version_minor = minor;
843}
844
845static void
846def_directive (str)
847 char *str;
848{
849 struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
a35bc64f 850
252b5132
RH
851 d->next = directives;
852 directives = d;
853 d->name = xstrdup (str);
854 d->len = strlen (str);
855}
856
857static int
858def_error (err)
859 const char *err;
860{
dc17f155 861 einfo ("%P: %s:%d: %s\n", def_filename ? def_filename : "<unknown-file>", linenumber, err);
252b5132
RH
862
863 return 0;
864}
865
866
a35bc64f 867/* Lexical Scanner. */
252b5132
RH
868
869#undef TRACE
870#define TRACE 0
871
a35bc64f 872/* Never freed, but always reused as needed, so no real leak. */
252b5132
RH
873static char *buffer = 0;
874static int buflen = 0;
875static int bufptr = 0;
876
877static void
878put_buf (c)
879 char c;
880{
881 if (bufptr == buflen)
882 {
a35bc64f 883 buflen += 50; /* overly reasonable, eh? */
252b5132
RH
884 if (buffer)
885 buffer = (char *) xrealloc (buffer, buflen + 1);
886 else
887 buffer = (char *) xmalloc (buflen + 1);
888 }
889 buffer[bufptr++] = c;
a35bc64f 890 buffer[bufptr] = 0; /* not optimal, but very convenient. */
252b5132
RH
891}
892
893static struct
894{
895 char *name;
896 int token;
897}
898tokens[] =
899{
900 { "BASE", BASE },
901 { "CODE", CODE },
7c9e78f8
DD
902 { "CONSTANT", CONSTANTU },
903 { "constant", CONSTANTL },
904 { "DATA", DATAU },
905 { "data", DATAL },
252b5132
RH
906 { "DESCRIPTION", DESCRIPTION },
907 { "DIRECTIVE", DIRECTIVE },
908 { "EXECUTE", EXECUTE },
909 { "EXPORTS", EXPORTS },
910 { "HEAPSIZE", HEAPSIZE },
911 { "IMPORTS", IMPORTS },
912 { "LIBRARY", LIBRARY },
913 { "NAME", NAME },
7c9e78f8
DD
914 { "NONAME", NONAMEU },
915 { "noname", NONAMEL },
916 { "PRIVATE", PRIVATEU },
917 { "private", PRIVATEL },
252b5132
RH
918 { "READ", READ },
919 { "SECTIONS", SECTIONS },
920 { "SEGMENTS", SECTIONS },
921 { "SHARED", SHARED },
922 { "STACKSIZE", STACKSIZE },
923 { "VERSION", VERSIONK },
924 { "WRITE", WRITE },
925 { 0, 0 }
926};
927
928static int
929def_getc ()
930{
931 int rv;
a35bc64f 932
252b5132
RH
933 if (lex_parse_string)
934 {
935 if (lex_parse_string >= lex_parse_string_end)
936 rv = EOF;
937 else
938 rv = *lex_parse_string++;
939 }
940 else
941 {
942 rv = fgetc (the_file);
943 }
944 if (rv == '\n')
945 saw_newline = 1;
946 return rv;
947}
948
949static int
950def_ungetc (c)
951 int c;
952{
953 if (lex_parse_string)
954 {
955 lex_parse_string--;
956 return c;
957 }
958 else
959 return ungetc (c, the_file);
960}
961
962static int
963def_lex ()
964{
965 int c, i, q;
966
967 if (lex_forced_token)
968 {
969 i = lex_forced_token;
970 lex_forced_token = 0;
971#if TRACE
972 printf ("lex: forcing token %d\n", i);
973#endif
974 return i;
975 }
976
977 c = def_getc ();
978
a35bc64f 979 /* Trim leading whitespace. */
252b5132
RH
980 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
981 c = def_getc ();
982
983 if (c == EOF)
984 {
985#if TRACE
986 printf ("lex: EOF\n");
987#endif
988 return 0;
989 }
990
991 if (saw_newline && c == ';')
992 {
993 do
994 {
995 c = def_getc ();
996 }
997 while (c != EOF && c != '\n');
998 if (c == '\n')
999 return def_lex ();
1000 return 0;
1001 }
a35bc64f
NC
1002
1003 /* Must be something else. */
252b5132
RH
1004 saw_newline = 0;
1005
3882b010 1006 if (ISDIGIT (c))
252b5132
RH
1007 {
1008 bufptr = 0;
3882b010 1009 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
252b5132
RH
1010 {
1011 put_buf (c);
1012 c = def_getc ();
1013 }
1014 if (c != EOF)
1015 def_ungetc (c);
1016 yylval.number = strtoul (buffer, 0, 0);
1017#if TRACE
1018 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
1019#endif
1020 return NUMBER;
1021 }
1022
c9e38879 1023 if (ISALPHA (c) || strchr ("$:-_?@", c))
252b5132
RH
1024 {
1025 bufptr = 0;
c9e38879
NC
1026 q = c;
1027 put_buf (c);
1028 c = def_getc ();
1029
1030 if (q == '@')
1031 {
1032 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1033 return (q);
1034 else if (ISDIGIT (c)) /* '@' followed by digit. */
1035 {
1036 def_ungetc (c);
1037 return (q);
1038 }
1039#if TRACE
1040 printf ("lex: @ returns itself\n");
1041#endif
1042 }
1043
053c44e1 1044 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
252b5132
RH
1045 {
1046 put_buf (c);
1047 c = def_getc ();
1048 }
1049 if (c != EOF)
1050 def_ungetc (c);
c9e38879
NC
1051 if (ISALPHA (q)) /* Check for tokens. */
1052 {
1053 for (i = 0; tokens[i].name; i++)
1054 if (strcmp (tokens[i].name, buffer) == 0)
1055 {
252b5132 1056#if TRACE
c9e38879 1057 printf ("lex: `%s' is a string token\n", buffer);
252b5132 1058#endif
c9e38879
NC
1059 return tokens[i].token;
1060 }
1061 }
252b5132
RH
1062#if TRACE
1063 printf ("lex: `%s' returns ID\n", buffer);
1064#endif
1065 yylval.id = xstrdup (buffer);
1066 return ID;
1067 }
1068
1069 if (c == '\'' || c == '"')
1070 {
1071 q = c;
1072 c = def_getc ();
1073 bufptr = 0;
a35bc64f 1074
252b5132
RH
1075 while (c != EOF && c != q)
1076 {
1077 put_buf (c);
1078 c = def_getc ();
1079 }
1080 yylval.id = xstrdup (buffer);
1081#if TRACE
1082 printf ("lex: `%s' returns ID\n", buffer);
1083#endif
1084 return ID;
1085 }
1086
c9e38879 1087 if (c == '=' || c == '.' || c == ',')
252b5132
RH
1088 {
1089#if TRACE
1090 printf ("lex: `%c' returns itself\n", c);
1091#endif
1092 return c;
1093 }
1094
1095 if (c == '\n')
1096 {
1097 linenumber++;
1098 saw_newline = 1;
1099 }
1100
1101 /*printf ("lex: 0x%02x ignored\n", c); */
1102 return def_lex ();
1103}
This page took 0.207125 seconds and 4 git commands to generate.