Add -Wshadow to the gcc command line options used when compiling the binutils.
[deliverable/binutils-gdb.git] / ld / deffilep.y
1 %{ /* deffilep.y - parser for .def files */
2
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 Free Software Foundation, Inc.
5
6 This file is part of GNU Binutils.
7
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 3 of the License, or
11 (at your option) any later version.
12
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.
17
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., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 #include "sysdep.h"
24 #include "libiberty.h"
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "ld.h"
28 #include "ldmisc.h"
29 #include "deffile.h"
30
31 #define TRACE 0
32
33 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34
35 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
36 as well as gratuitiously global symbol names, so we can have multiple
37 yacc generated parsers in ld. Note that these are only the variables
38 produced by yacc. If other parser generators (bison, byacc, etc) produce
39 additional global names that conflict at link time, then those parser
40 generators need to be fixed instead of adding those names to this list. */
41
42 #define yymaxdepth def_maxdepth
43 #define yyparse def_parse
44 #define yylex def_lex
45 #define yyerror def_error
46 #define yylval def_lval
47 #define yychar def_char
48 #define yydebug def_debug
49 #define yypact def_pact
50 #define yyr1 def_r1
51 #define yyr2 def_r2
52 #define yydef def_def
53 #define yychk def_chk
54 #define yypgo def_pgo
55 #define yyact def_act
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
59 #define yyps def_ps
60 #define yypv def_pv
61 #define yys def_s
62 #define yy_yys def_yys
63 #define yystate def_state
64 #define yytmp def_tmp
65 #define yyv def_v
66 #define yy_yyv def_yyv
67 #define yyval def_val
68 #define yylloc def_lloc
69 #define yyreds def_reds /* With YYDEBUG defined. */
70 #define yytoks def_toks /* With YYDEBUG defined. */
71 #define yylhs def_yylhs
72 #define yylen def_yylen
73 #define yydefred def_yydefred
74 #define yydgoto def_yydgoto
75 #define yysindex def_yysindex
76 #define yyrindex def_yyrindex
77 #define yygindex def_yygindex
78 #define yytable def_yytable
79 #define yycheck def_yycheck
80
81 static void def_description (const char *);
82 static void def_exports (const char *, const char *, int, int, const char *);
83 static void def_heapsize (int, int);
84 static void def_import (const char *, const char *, const char *, const char *,
85 int, const char *);
86 static void def_image_name (const char *, int, int);
87 static void def_section (const char *, int);
88 static void def_section_alt (const char *, const char *);
89 static void def_stacksize (int, int);
90 static void def_version (int, int);
91 static void def_directive (char *);
92 static void def_aligncomm (char *str, int align);
93 static int def_parse (void);
94 static int def_error (const char *);
95 static int def_lex (void);
96
97 static int lex_forced_token = 0;
98 static const char *lex_parse_string = 0;
99 static const char *lex_parse_string_end = 0;
100
101 %}
102
103 %union {
104 char *id;
105 int number;
106 char *digits;
107 };
108
109 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
110 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
111 %token PRIVATEU PRIVATEL ALIGNCOMM
112 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
113 %token <id> ID
114 %token <digits> DIGITS
115 %type <number> NUMBER
116 %type <digits> opt_digits
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 dot_name anylang_id opt_id
120 %type <id> opt_equalequal_name
121
122 %%
123
124 start: start command
125 | command
126 ;
127
128 command:
129 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
130 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
131 | DESCRIPTION ID { def_description ($2);}
132 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
133 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
134 | CODE attr_list { def_section ("CODE", $2);}
135 | DATAU attr_list { def_section ("DATA", $2);}
136 | SECTIONS seclist
137 | EXPORTS explist
138 | IMPORTS implist
139 | VERSIONK NUMBER { def_version ($2, 0);}
140 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
141 | DIRECTIVE ID { def_directive ($2);}
142 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
143 ;
144
145
146 explist:
147 /* EMPTY */
148 | expline
149 | explist expline
150 ;
151
152 expline:
153 /* The opt_comma is necessary to support both the usual
154 DEF file syntax as well as .drectve syntax which
155 mandates <expsym>,<expoptlist>. */
156 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
157 { def_exports ($1, $2, $3, $5, $7); }
158 ;
159 exp_opt_list:
160 /* The opt_comma is necessary to support both the usual
161 DEF file syntax as well as .drectve syntax which
162 allows for comma separated opt list. */
163 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
164 | { $$ = 0; }
165 ;
166 exp_opt:
167 NONAMEU { $$ = 1; }
168 | NONAMEL { $$ = 1; }
169 | CONSTANTU { $$ = 2; }
170 | CONSTANTL { $$ = 2; }
171 | DATAU { $$ = 4; }
172 | DATAL { $$ = 4; }
173 | PRIVATEU { $$ = 8; }
174 | PRIVATEL { $$ = 8; }
175 ;
176 implist:
177 implist impline
178 | impline
179 ;
180
181 impline:
182 ID '=' ID '.' ID '.' ID opt_equalequal_name
183 { def_import ($1, $3, $5, $7, -1, $8); }
184 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
185 { def_import ($1, $3, $5, 0, $7, $8); }
186 | ID '=' ID '.' ID opt_equalequal_name
187 { def_import ($1, $3, 0, $5, -1, $6); }
188 | ID '=' ID '.' NUMBER opt_equalequal_name
189 { def_import ($1, $3, 0, 0, $5, $6); }
190 | ID '.' ID '.' ID opt_equalequal_name
191 { def_import( 0, $1, $3, $5, -1, $6); }
192 | ID '.' ID opt_equalequal_name
193 { def_import ( 0, $1, 0, $3, -1, $4); }
194 ;
195
196 seclist:
197 seclist secline
198 | secline
199 ;
200
201 secline:
202 ID attr_list { def_section ($1, $2);}
203 | ID ID { def_section_alt ($1, $2);}
204 ;
205
206 attr_list:
207 attr_list opt_comma attr { $$ = $1 | $3; }
208 | attr { $$ = $1; }
209 ;
210
211 opt_comma:
212 ','
213 |
214 ;
215 opt_number: ',' NUMBER { $$=$2;}
216 | { $$=-1;}
217 ;
218
219 attr:
220 READ { $$ = 1;}
221 | WRITE { $$ = 2;}
222 | EXECUTE { $$=4;}
223 | SHARED { $$=8;}
224 ;
225
226 opt_name: ID { $$ = $1; }
227 | ID '.' ID
228 {
229 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
230 sprintf (name, "%s.%s", $1, $3);
231 $$ = name;
232 }
233 | { $$ = ""; }
234 ;
235
236 opt_equalequal_name: EQUAL ID { $$ = $2; }
237 | { $$ = 0; }
238 ;
239
240 opt_ordinal:
241 '@' NUMBER { $$ = $2;}
242 | { $$ = -1;}
243 ;
244
245 opt_equal_name:
246 '=' dot_name { $$ = $2; }
247 | { $$ = 0; }
248 ;
249
250 opt_base: BASE '=' NUMBER { $$ = $3;}
251 | { $$ = -1;}
252 ;
253
254 dot_name: ID { $$ = $1; }
255 | dot_name '.' ID
256 {
257 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
258 sprintf (name, "%s.%s", $1, $3);
259 $$ = name;
260 }
261 ;
262
263 anylang_id: ID { $$ = $1; }
264 | anylang_id '.' opt_digits opt_id
265 {
266 char *id = xmalloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
267 sprintf (id, "%s.%s%s", $1, $3, $4);
268 $$ = id;
269 }
270 ;
271
272 opt_digits: DIGITS { $$ = $1; }
273 | { $$ = ""; }
274 ;
275
276 opt_id: ID { $$ = $1; }
277 | { $$ = ""; }
278 ;
279
280 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
281
282 %%
283
284 /*****************************************************************************
285 API
286 *****************************************************************************/
287
288 static FILE *the_file;
289 static const char *def_filename;
290 static int linenumber;
291 static def_file *def;
292 static int saw_newline;
293
294 struct directive
295 {
296 struct directive *next;
297 char *name;
298 int len;
299 };
300
301 static struct directive *directives = 0;
302
303 def_file *
304 def_file_empty (void)
305 {
306 def_file *rv = xmalloc (sizeof (def_file));
307 memset (rv, 0, sizeof (def_file));
308 rv->is_dll = -1;
309 rv->base_address = (bfd_vma) -1;
310 rv->stack_reserve = rv->stack_commit = -1;
311 rv->heap_reserve = rv->heap_commit = -1;
312 rv->version_major = rv->version_minor = -1;
313 return rv;
314 }
315
316 def_file *
317 def_file_parse (const char *filename, def_file *add_to)
318 {
319 struct directive *d;
320
321 the_file = fopen (filename, "r");
322 def_filename = filename;
323 linenumber = 1;
324 if (!the_file)
325 {
326 perror (filename);
327 return 0;
328 }
329 if (add_to)
330 {
331 def = add_to;
332 }
333 else
334 {
335 def = def_file_empty ();
336 }
337
338 saw_newline = 1;
339 if (def_parse ())
340 {
341 def_file_free (def);
342 fclose (the_file);
343 return 0;
344 }
345
346 fclose (the_file);
347
348 for (d = directives; d; d = d->next)
349 {
350 #if TRACE
351 printf ("Adding directive %08x `%s'\n", d->name, d->name);
352 #endif
353 def_file_add_directive (def, d->name, d->len);
354 }
355
356 return def;
357 }
358
359 void
360 def_file_free (def_file *fdef)
361 {
362 int i;
363
364 if (!fdef)
365 return;
366 if (fdef->name)
367 free (fdef->name);
368 if (fdef->description)
369 free (fdef->description);
370
371 if (fdef->section_defs)
372 {
373 for (i = 0; i < fdef->num_section_defs; i++)
374 {
375 if (fdef->section_defs[i].name)
376 free (fdef->section_defs[i].name);
377 if (fdef->section_defs[i].class)
378 free (fdef->section_defs[i].class);
379 }
380 free (fdef->section_defs);
381 }
382
383 if (fdef->exports)
384 {
385 for (i = 0; i < def->num_exports; i++)
386 {
387 if (fdef->exports[i].internal_name
388 && fdef->exports[i].internal_name != fdef->exports[i].name)
389 free (fdef->exports[i].internal_name);
390 if (fdef->exports[i].name)
391 free (fdef->exports[i].name);
392 if (fdef->exports[i].its_name)
393 free (fdef->exports[i].its_name);
394 }
395 free (fdef->exports);
396 }
397
398 if (fdef->imports)
399 {
400 for (i = 0; i < fdef->num_imports; i++)
401 {
402 if (fdef->imports[i].internal_name
403 && fdef->imports[i].internal_name != fdef->imports[i].name)
404 free (fdef->imports[i].internal_name);
405 if (fdef->imports[i].name)
406 free (fdef->imports[i].name);
407 if (fdef->imports[i].its_name)
408 free (fdef->imports[i].its_name);
409 }
410 free (fdef->imports);
411 }
412
413 while (fdef->modules)
414 {
415 def_file_module *m = fdef->modules;
416
417 fdef->modules = fdef->modules->next;
418 free (m);
419 }
420
421 while (fdef->aligncomms)
422 {
423 def_file_aligncomm *c = fdef->aligncomms;
424
425 fdef->aligncomms = fdef->aligncomms->next;
426 free (c->symbol_name);
427 free (c);
428 }
429
430 free (fdef);
431 }
432
433 #ifdef DEF_FILE_PRINT
434 void
435 def_file_print (FILE *file, def_file *fdef)
436 {
437 int i;
438
439 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
440 if (fdef->name)
441 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
442 if (fdef->is_dll != -1)
443 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
444 if (fdef->base_address != (bfd_vma) -1)
445 fprintf (file, " base address: 0x%08x\n", fdef->base_address);
446 if (fdef->description)
447 fprintf (file, " description: `%s'\n", fdef->description);
448 if (fdef->stack_reserve != -1)
449 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
450 if (fdef->stack_commit != -1)
451 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
452 if (fdef->heap_reserve != -1)
453 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
454 if (fdef->heap_commit != -1)
455 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
456
457 if (fdef->num_section_defs > 0)
458 {
459 fprintf (file, " section defs:\n");
460
461 for (i = 0; i < fdef->num_section_defs; i++)
462 {
463 fprintf (file, " name: `%s', class: `%s', flags:",
464 fdef->section_defs[i].name, fdef->section_defs[i].class);
465 if (fdef->section_defs[i].flag_read)
466 fprintf (file, " R");
467 if (fdef->section_defs[i].flag_write)
468 fprintf (file, " W");
469 if (fdef->section_defs[i].flag_execute)
470 fprintf (file, " X");
471 if (fdef->section_defs[i].flag_shared)
472 fprintf (file, " S");
473 fprintf (file, "\n");
474 }
475 }
476
477 if (fdef->num_exports > 0)
478 {
479 fprintf (file, " exports:\n");
480
481 for (i = 0; i < fdef->num_exports; i++)
482 {
483 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
484 fdef->exports[i].name, fdef->exports[i].internal_name,
485 fdef->exports[i].ordinal);
486 if (fdef->exports[i].flag_private)
487 fprintf (file, " P");
488 if (fdef->exports[i].flag_constant)
489 fprintf (file, " C");
490 if (fdef->exports[i].flag_noname)
491 fprintf (file, " N");
492 if (fdef->exports[i].flag_data)
493 fprintf (file, " D");
494 fprintf (file, "\n");
495 }
496 }
497
498 if (fdef->num_imports > 0)
499 {
500 fprintf (file, " imports:\n");
501
502 for (i = 0; i < fdef->num_imports; i++)
503 {
504 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
505 fdef->imports[i].internal_name,
506 fdef->imports[i].module,
507 fdef->imports[i].name,
508 fdef->imports[i].ordinal);
509 }
510 }
511
512 if (fdef->version_major != -1)
513 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
514
515 fprintf (file, "<<<< def_file at 0x%08x\n", def);
516 }
517 #endif
518
519 def_file_export *
520 def_file_add_export (def_file *fdef,
521 const char *external_name,
522 const char *internal_name,
523 int ordinal,
524 const char *its_name)
525 {
526 def_file_export *e;
527 int max_exports = ROUND_UP(fdef->num_exports, 32);
528
529 if (fdef->num_exports >= max_exports)
530 {
531 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
532 if (fdef->exports)
533 fdef->exports = xrealloc (fdef->exports,
534 max_exports * sizeof (def_file_export));
535 else
536 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
537 }
538 e = fdef->exports + fdef->num_exports;
539 memset (e, 0, sizeof (def_file_export));
540 if (internal_name && !external_name)
541 external_name = internal_name;
542 if (external_name && !internal_name)
543 internal_name = external_name;
544 e->name = xstrdup (external_name);
545 e->internal_name = xstrdup (internal_name);
546 e->its_name = (its_name ? xstrdup (its_name) : NULL);
547 e->ordinal = ordinal;
548 fdef->num_exports++;
549 return e;
550 }
551
552 def_file_module *
553 def_get_module (def_file *fdef, const char *name)
554 {
555 def_file_module *s;
556
557 for (s = fdef->modules; s; s = s->next)
558 if (strcmp (s->name, name) == 0)
559 return s;
560
561 return NULL;
562 }
563
564 static def_file_module *
565 def_stash_module (def_file *fdef, const char *name)
566 {
567 def_file_module *s;
568
569 if ((s = def_get_module (fdef, name)) != NULL)
570 return s;
571 s = xmalloc (sizeof (def_file_module) + strlen (name));
572 s->next = def->modules;
573 fdef->modules = s;
574 s->user_data = 0;
575 strcpy (s->name, name);
576 return s;
577 }
578
579 def_file_import *
580 def_file_add_import (def_file *fdef,
581 const char *name,
582 const char *module,
583 int ordinal,
584 const char *internal_name,
585 const char *its_name)
586 {
587 def_file_import *i;
588 int max_imports = ROUND_UP (fdef->num_imports, 16);
589
590 if (fdef->num_imports >= max_imports)
591 {
592 max_imports = ROUND_UP (fdef->num_imports+1, 16);
593
594 if (fdef->imports)
595 fdef->imports = xrealloc (fdef->imports,
596 max_imports * sizeof (def_file_import));
597 else
598 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
599 }
600 i = fdef->imports + fdef->num_imports;
601 memset (i, 0, sizeof (def_file_import));
602 if (name)
603 i->name = xstrdup (name);
604 if (module)
605 i->module = def_stash_module (def, module);
606 i->ordinal = ordinal;
607 if (internal_name)
608 i->internal_name = xstrdup (internal_name);
609 else
610 i->internal_name = i->name;
611 i->its_name = (its_name ? xstrdup (its_name) : NULL);
612 fdef->num_imports++;
613
614 return i;
615 }
616
617 struct
618 {
619 char *param;
620 int token;
621 }
622 diropts[] =
623 {
624 { "-heap", HEAPSIZE },
625 { "-stack", STACKSIZE_K },
626 { "-attr", SECTIONS },
627 { "-export", EXPORTS },
628 { "-aligncomm", ALIGNCOMM },
629 { 0, 0 }
630 };
631
632 void
633 def_file_add_directive (def_file *my_def, const char *param, int len)
634 {
635 def_file *save_def = def;
636 const char *pend = param + len;
637 char * tend = (char *) param;
638 int i;
639
640 def = my_def;
641
642 while (param < pend)
643 {
644 while (param < pend
645 && (ISSPACE (*param) || *param == '\n' || *param == 0))
646 param++;
647
648 if (param == pend)
649 break;
650
651 /* Scan forward until we encounter any of:
652 - the end of the buffer
653 - the start of a new option
654 - a newline seperating options
655 - a NUL seperating options. */
656 for (tend = (char *) (param + 1);
657 (tend < pend
658 && !(ISSPACE (tend[-1]) && *tend == '-')
659 && *tend != '\n' && *tend != 0);
660 tend++)
661 ;
662
663 for (i = 0; diropts[i].param; i++)
664 {
665 len = strlen (diropts[i].param);
666
667 if (tend - param >= len
668 && strncmp (param, diropts[i].param, len) == 0
669 && (param[len] == ':' || param[len] == ' '))
670 {
671 lex_parse_string_end = tend;
672 lex_parse_string = param + len + 1;
673 lex_forced_token = diropts[i].token;
674 saw_newline = 0;
675 if (def_parse ())
676 continue;
677 break;
678 }
679 }
680
681 if (!diropts[i].param)
682 {
683 char saved;
684
685 saved = * tend;
686 * tend = 0;
687 /* xgettext:c-format */
688 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
689 * tend = saved;
690 }
691
692 lex_parse_string = 0;
693 param = tend;
694 }
695
696 def = save_def;
697 }
698
699 /* Parser Callbacks. */
700
701 static void
702 def_image_name (const char *name, int base, int is_dll)
703 {
704 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
705 to do here. We retain the output filename specified on command line. */
706 if (*name)
707 {
708 const char* image_name = lbasename (name);
709
710 if (image_name != name)
711 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
712 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
713 name);
714 if (def->name)
715 free (def->name);
716 /* Append the default suffix, if none specified. */
717 if (strchr (image_name, '.') == 0)
718 {
719 const char * suffix = is_dll ? ".dll" : ".exe";
720
721 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
722 sprintf (def->name, "%s%s", image_name, suffix);
723 }
724 else
725 def->name = xstrdup (image_name);
726 }
727
728 /* Honor a BASE address statement, even if LIBRARY string is empty. */
729 def->base_address = base;
730 def->is_dll = is_dll;
731 }
732
733 static void
734 def_description (const char *text)
735 {
736 int len = def->description ? strlen (def->description) : 0;
737
738 len += strlen (text) + 1;
739 if (def->description)
740 {
741 def->description = xrealloc (def->description, len);
742 strcat (def->description, text);
743 }
744 else
745 {
746 def->description = xmalloc (len);
747 strcpy (def->description, text);
748 }
749 }
750
751 static void
752 def_stacksize (int reserve, int commit)
753 {
754 def->stack_reserve = reserve;
755 def->stack_commit = commit;
756 }
757
758 static void
759 def_heapsize (int reserve, int commit)
760 {
761 def->heap_reserve = reserve;
762 def->heap_commit = commit;
763 }
764
765 static void
766 def_section (const char *name, int attr)
767 {
768 def_file_section *s;
769 int max_sections = ROUND_UP (def->num_section_defs, 4);
770
771 if (def->num_section_defs >= max_sections)
772 {
773 max_sections = ROUND_UP (def->num_section_defs+1, 4);
774
775 if (def->section_defs)
776 def->section_defs = xrealloc (def->section_defs,
777 max_sections * sizeof (def_file_import));
778 else
779 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
780 }
781 s = def->section_defs + def->num_section_defs;
782 memset (s, 0, sizeof (def_file_section));
783 s->name = xstrdup (name);
784 if (attr & 1)
785 s->flag_read = 1;
786 if (attr & 2)
787 s->flag_write = 1;
788 if (attr & 4)
789 s->flag_execute = 1;
790 if (attr & 8)
791 s->flag_shared = 1;
792
793 def->num_section_defs++;
794 }
795
796 static void
797 def_section_alt (const char *name, const char *attr)
798 {
799 int aval = 0;
800
801 for (; *attr; attr++)
802 {
803 switch (*attr)
804 {
805 case 'R':
806 case 'r':
807 aval |= 1;
808 break;
809 case 'W':
810 case 'w':
811 aval |= 2;
812 break;
813 case 'X':
814 case 'x':
815 aval |= 4;
816 break;
817 case 'S':
818 case 's':
819 aval |= 8;
820 break;
821 }
822 }
823 def_section (name, aval);
824 }
825
826 static void
827 def_exports (const char *external_name,
828 const char *internal_name,
829 int ordinal,
830 int flags,
831 const char *its_name)
832 {
833 def_file_export *dfe;
834
835 if (!internal_name && external_name)
836 internal_name = external_name;
837 #if TRACE
838 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
839 #endif
840
841 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
842 its_name);
843 if (flags & 1)
844 dfe->flag_noname = 1;
845 if (flags & 2)
846 dfe->flag_constant = 1;
847 if (flags & 4)
848 dfe->flag_data = 1;
849 if (flags & 8)
850 dfe->flag_private = 1;
851 }
852
853 static void
854 def_import (const char *internal_name,
855 const char *module,
856 const char *dllext,
857 const char *name,
858 int ordinal,
859 const char *its_name)
860 {
861 char *buf = 0;
862 const char *ext = dllext ? dllext : "dll";
863
864 buf = xmalloc (strlen (module) + strlen (ext) + 2);
865 sprintf (buf, "%s.%s", module, ext);
866 module = buf;
867
868 def_file_add_import (def, name, module, ordinal, internal_name, its_name);
869 if (buf)
870 free (buf);
871 }
872
873 static void
874 def_version (int major, int minor)
875 {
876 def->version_major = major;
877 def->version_minor = minor;
878 }
879
880 static void
881 def_directive (char *str)
882 {
883 struct directive *d = xmalloc (sizeof (struct directive));
884
885 d->next = directives;
886 directives = d;
887 d->name = xstrdup (str);
888 d->len = strlen (str);
889 }
890
891 static void
892 def_aligncomm (char *str, int align)
893 {
894 def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
895
896 c->symbol_name = xstrdup (str);
897 c->alignment = (unsigned int) align;
898
899 c->next = def->aligncomms;
900 def->aligncomms = c;
901 }
902
903 static int
904 def_error (const char *err)
905 {
906 einfo ("%P: %s:%d: %s\n",
907 def_filename ? def_filename : "<unknown-file>", linenumber, err);
908 return 0;
909 }
910
911
912 /* Lexical Scanner. */
913
914 #undef TRACE
915 #define TRACE 0
916
917 /* Never freed, but always reused as needed, so no real leak. */
918 static char *buffer = 0;
919 static int buflen = 0;
920 static int bufptr = 0;
921
922 static void
923 put_buf (char c)
924 {
925 if (bufptr == buflen)
926 {
927 buflen += 50; /* overly reasonable, eh? */
928 if (buffer)
929 buffer = xrealloc (buffer, buflen + 1);
930 else
931 buffer = xmalloc (buflen + 1);
932 }
933 buffer[bufptr++] = c;
934 buffer[bufptr] = 0; /* not optimal, but very convenient. */
935 }
936
937 static struct
938 {
939 char *name;
940 int token;
941 }
942 tokens[] =
943 {
944 { "BASE", BASE },
945 { "CODE", CODE },
946 { "CONSTANT", CONSTANTU },
947 { "constant", CONSTANTL },
948 { "DATA", DATAU },
949 { "data", DATAL },
950 { "DESCRIPTION", DESCRIPTION },
951 { "DIRECTIVE", DIRECTIVE },
952 { "EXECUTE", EXECUTE },
953 { "EXPORTS", EXPORTS },
954 { "HEAPSIZE", HEAPSIZE },
955 { "IMPORTS", IMPORTS },
956 { "LIBRARY", LIBRARY },
957 { "NAME", NAME },
958 { "NONAME", NONAMEU },
959 { "noname", NONAMEL },
960 { "PRIVATE", PRIVATEU },
961 { "private", PRIVATEL },
962 { "READ", READ },
963 { "SECTIONS", SECTIONS },
964 { "SEGMENTS", SECTIONS },
965 { "SHARED", SHARED },
966 { "STACKSIZE", STACKSIZE_K },
967 { "VERSION", VERSIONK },
968 { "WRITE", WRITE },
969 { 0, 0 }
970 };
971
972 static int
973 def_getc (void)
974 {
975 int rv;
976
977 if (lex_parse_string)
978 {
979 if (lex_parse_string >= lex_parse_string_end)
980 rv = EOF;
981 else
982 rv = *lex_parse_string++;
983 }
984 else
985 {
986 rv = fgetc (the_file);
987 }
988 if (rv == '\n')
989 saw_newline = 1;
990 return rv;
991 }
992
993 static int
994 def_ungetc (int c)
995 {
996 if (lex_parse_string)
997 {
998 lex_parse_string--;
999 return c;
1000 }
1001 else
1002 return ungetc (c, the_file);
1003 }
1004
1005 static int
1006 def_lex (void)
1007 {
1008 int c, i, q;
1009
1010 if (lex_forced_token)
1011 {
1012 i = lex_forced_token;
1013 lex_forced_token = 0;
1014 #if TRACE
1015 printf ("lex: forcing token %d\n", i);
1016 #endif
1017 return i;
1018 }
1019
1020 c = def_getc ();
1021
1022 /* Trim leading whitespace. */
1023 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1024 c = def_getc ();
1025
1026 if (c == EOF)
1027 {
1028 #if TRACE
1029 printf ("lex: EOF\n");
1030 #endif
1031 return 0;
1032 }
1033
1034 if (saw_newline && c == ';')
1035 {
1036 do
1037 {
1038 c = def_getc ();
1039 }
1040 while (c != EOF && c != '\n');
1041 if (c == '\n')
1042 return def_lex ();
1043 return 0;
1044 }
1045
1046 /* Must be something else. */
1047 saw_newline = 0;
1048
1049 if (ISDIGIT (c))
1050 {
1051 bufptr = 0;
1052 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1053 {
1054 put_buf (c);
1055 c = def_getc ();
1056 }
1057 if (c != EOF)
1058 def_ungetc (c);
1059 yylval.digits = xstrdup (buffer);
1060 #if TRACE
1061 printf ("lex: `%s' returns DIGITS\n", buffer);
1062 #endif
1063 return DIGITS;
1064 }
1065
1066 if (ISALPHA (c) || strchr ("$:-_?@", c))
1067 {
1068 bufptr = 0;
1069 q = c;
1070 put_buf (c);
1071 c = def_getc ();
1072
1073 if (q == '@')
1074 {
1075 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1076 return (q);
1077 else if (ISDIGIT (c)) /* '@' followed by digit. */
1078 {
1079 def_ungetc (c);
1080 return (q);
1081 }
1082 #if TRACE
1083 printf ("lex: @ returns itself\n");
1084 #endif
1085 }
1086
1087 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1088 {
1089 put_buf (c);
1090 c = def_getc ();
1091 }
1092 if (c != EOF)
1093 def_ungetc (c);
1094 if (ISALPHA (q)) /* Check for tokens. */
1095 {
1096 for (i = 0; tokens[i].name; i++)
1097 if (strcmp (tokens[i].name, buffer) == 0)
1098 {
1099 #if TRACE
1100 printf ("lex: `%s' is a string token\n", buffer);
1101 #endif
1102 return tokens[i].token;
1103 }
1104 }
1105 #if TRACE
1106 printf ("lex: `%s' returns ID\n", buffer);
1107 #endif
1108 yylval.id = xstrdup (buffer);
1109 return ID;
1110 }
1111
1112 if (c == '\'' || c == '"')
1113 {
1114 q = c;
1115 c = def_getc ();
1116 bufptr = 0;
1117
1118 while (c != EOF && c != q)
1119 {
1120 put_buf (c);
1121 c = def_getc ();
1122 }
1123 yylval.id = xstrdup (buffer);
1124 #if TRACE
1125 printf ("lex: `%s' returns ID\n", buffer);
1126 #endif
1127 return ID;
1128 }
1129
1130 if ( c == '=')
1131 {
1132 c = def_getc ();
1133 if (c == '=')
1134 {
1135 #if TRACE
1136 printf ("lex: `==' returns EQUAL\n");
1137 #endif
1138 return EQUAL;
1139 }
1140 def_ungetc (c);
1141 #if TRACE
1142 printf ("lex: `=' returns itself\n");
1143 #endif
1144 return '=';
1145 }
1146 if (c == '.' || c == ',')
1147 {
1148 #if TRACE
1149 printf ("lex: `%c' returns itself\n", c);
1150 #endif
1151 return c;
1152 }
1153
1154 if (c == '\n')
1155 {
1156 linenumber++;
1157 saw_newline = 1;
1158 }
1159
1160 /*printf ("lex: 0x%02x ignored\n", c); */
1161 return def_lex ();
1162 }
This page took 0.054532 seconds and 4 git commands to generate.