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