record-btrace: add record goto target methods
[deliverable/binutils-gdb.git] / ld / deffilep.y
CommitLineData
252b5132
RH
1%{ /* deffilep.y - parser for .def files */
2
aa820537
AM
3/* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 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
f96b4a7b 10 the Free Software Foundation; either version 3 of the License, or
a35bc64f 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
f96b4a7b
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
3db64b00 23#include "sysdep.h"
252b5132 24#include "libiberty.h"
3882b010 25#include "safe-ctype.h"
252b5132 26#include "bfd.h"
252b5132
RH
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
e4492aa0
L
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
252b5132
RH
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
bdca0ea1
KT
81typedef struct def_pool_str {
82 struct def_pool_str *next;
83 char data[1];
84} def_pool_str;
85
86static def_pool_str *pool_strs = NULL;
87
88static char *def_pool_alloc (size_t sz);
89static char *def_pool_strdup (const char *str);
90static void def_pool_free (void);
91
1579bae1 92static void def_description (const char *);
7fcab871 93static void def_exports (const char *, const char *, int, int, const char *);
1579bae1
AM
94static void def_heapsize (int, int);
95static void def_import (const char *, const char *, const char *, const char *,
7fcab871 96 int, const char *);
0a4e6638 97static void def_image_name (const char *, bfd_vma, int);
1579bae1
AM
98static void def_section (const char *, int);
99static void def_section_alt (const char *, const char *);
100static void def_stacksize (int, int);
101static void def_version (int, int);
102static void def_directive (char *);
c1711530 103static void def_aligncomm (char *str, int align);
1579bae1
AM
104static int def_parse (void);
105static int def_error (const char *);
106static int def_lex (void);
252b5132
RH
107
108static int lex_forced_token = 0;
109static const char *lex_parse_string = 0;
110static const char *lex_parse_string_end = 0;
111
112%}
113
114%union {
115 char *id;
aa83d1ec 116 const char *id_const;
252b5132 117 int number;
0a4e6638 118 bfd_vma vma;
05056a8d 119 char *digits;
252b5132
RH
120};
121
8e58566f 122%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
655f76a2 123%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
c1711530 124%token PRIVATEU PRIVATEL ALIGNCOMM
7fcab871 125%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
252b5132 126%token <id> ID
05056a8d
DK
127%token <digits> DIGITS
128%type <number> NUMBER
0a4e6638 129%type <vma> VMA opt_base
05056a8d 130%type <digits> opt_digits
0a4e6638 131%type <number> opt_ordinal
252b5132 132%type <number> attr attr_list opt_number exp_opt_list exp_opt
aa83d1ec 133%type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
7fcab871 134%type <id> opt_equalequal_name
aa83d1ec 135%type <id_const> keyword_as_name
252b5132
RH
136
137%%
138
139start: start command
140 | command
141 ;
142
e4492aa0 143command:
a880c748
DS
144 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
145 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
252b5132 146 | DESCRIPTION ID { def_description ($2);}
8e58566f 147 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
252b5132
RH
148 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
149 | CODE attr_list { def_section ("CODE", $2);}
7c9e78f8 150 | DATAU attr_list { def_section ("DATA", $2);}
252b5132 151 | SECTIONS seclist
e4492aa0 152 | EXPORTS explist
252b5132
RH
153 | IMPORTS implist
154 | VERSIONK NUMBER { def_version ($2, 0);}
155 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
156 | DIRECTIVE ID { def_directive ($2);}
05056a8d 157 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
252b5132
RH
158 ;
159
160
161explist:
162 /* EMPTY */
163 | expline
164 | explist expline
165 ;
166
167expline:
7c9e78f8
DD
168 /* The opt_comma is necessary to support both the usual
169 DEF file syntax as well as .drectve syntax which
170 mandates <expsym>,<expoptlist>. */
aa83d1ec 171 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
7fcab871 172 { def_exports ($1, $2, $3, $5, $7); }
252b5132
RH
173 ;
174exp_opt_list:
7c9e78f8
DD
175 /* The opt_comma is necessary to support both the usual
176 DEF file syntax as well as .drectve syntax which
177 allows for comma separated opt list. */
178 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
252b5132
RH
179 | { $$ = 0; }
180 ;
181exp_opt:
7c9e78f8
DD
182 NONAMEU { $$ = 1; }
183 | NONAMEL { $$ = 1; }
184 | CONSTANTU { $$ = 2; }
185 | CONSTANTL { $$ = 2; }
186 | DATAU { $$ = 4; }
187 | DATAL { $$ = 4; }
188 | PRIVATEU { $$ = 8; }
189 | PRIVATEL { $$ = 8; }
252b5132 190 ;
e4492aa0 191implist:
252b5132
RH
192 implist impline
193 | impline
194 ;
195
196impline:
7fcab871
KT
197 ID '=' ID '.' ID '.' ID opt_equalequal_name
198 { def_import ($1, $3, $5, $7, -1, $8); }
199 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
200 { def_import ($1, $3, $5, 0, $7, $8); }
201 | ID '=' ID '.' ID opt_equalequal_name
202 { def_import ($1, $3, 0, $5, -1, $6); }
203 | ID '=' ID '.' NUMBER opt_equalequal_name
204 { def_import ($1, $3, 0, 0, $5, $6); }
205 | ID '.' ID '.' ID opt_equalequal_name
206 { def_import( 0, $1, $3, $5, -1, $6); }
207 | ID '.' ID opt_equalequal_name
208 { def_import ( 0, $1, 0, $3, -1, $4); }
252b5132
RH
209;
210
211seclist:
212 seclist secline
213 | secline
214 ;
215
216secline:
217 ID attr_list { def_section ($1, $2);}
218 | ID ID { def_section_alt ($1, $2);}
219 ;
220
221attr_list:
222 attr_list opt_comma attr { $$ = $1 | $3; }
223 | attr { $$ = $1; }
224 ;
225
226opt_comma:
227 ','
e4492aa0 228 |
252b5132
RH
229 ;
230opt_number: ',' NUMBER { $$=$2;}
231 | { $$=-1;}
232 ;
e4492aa0 233
252b5132
RH
234attr:
235 READ { $$ = 1;}
e4492aa0 236 | WRITE { $$ = 2;}
252b5132
RH
237 | EXECUTE { $$=4;}
238 | SHARED { $$=8;}
239 ;
240
aa83d1ec
KT
241
242keyword_as_name: BASE { $$ = "BASE"; }
243 | CODE { $$ = "CODE"; }
244 | CONSTANTU { $$ = "CONSTANT"; }
245 | CONSTANTL { $$ = "constant"; }
246 | DATAU { $$ = "DATA"; }
247 | DATAL { $$ = "data"; }
248 | DESCRIPTION { $$ = "DESCRIPTION"; }
249 | DIRECTIVE { $$ = "DIRECTIVE"; }
250 | EXECUTE { $$ = "EXECUTE"; }
251 | EXPORTS { $$ = "EXPORTS"; }
252 | HEAPSIZE { $$ = "HEAPSIZE"; }
253 | IMPORTS { $$ = "IMPORTS"; }
5b3d386e
KT
254/* Disable LIBRARY keyword as valid symbol-name. This is necessary
255 for libtool, which places this command after EXPORTS command.
256 This behavior is illegal by specification, but sadly required by
257 by compatibility reasons.
258 See PR binutils/13710
259 | LIBRARY { $$ = "LIBRARY"; } */
aa83d1ec
KT
260 | NAME { $$ = "NAME"; }
261 | NONAMEU { $$ = "NONAME"; }
262 | NONAMEL { $$ = "noname"; }
263 | PRIVATEU { $$ = "PRIVATE"; }
264 | PRIVATEL { $$ = "private"; }
265 | READ { $$ = "READ"; }
266 | SHARED { $$ = "SHARED"; }
267 | STACKSIZE_K { $$ = "STACKSIZE"; }
268 | VERSIONK { $$ = "VERSION"; }
269 | WRITE { $$ = "WRITE"; }
270 ;
271
272opt_name2: ID { $$ = $1; }
273 | '.' keyword_as_name
770c040b 274 {
aa83d1ec
KT
275 char *name = xmalloc (strlen ($2) + 2);
276 sprintf (name, ".%s", $2);
277 $$ = name;
278 }
279 | '.' opt_name2
e4492aa0 280 {
bdca0ea1 281 char *name = def_pool_alloc (strlen ($2) + 2);
770c040b
KT
282 sprintf (name, ".%s", $2);
283 $$ = name;
284 }
aa83d1ec 285 | keyword_as_name '.' opt_name2
e4492aa0 286 {
bdca0ea1 287 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
5aaace27
NC
288 sprintf (name, "%s.%s", $1, $3);
289 $$ = name;
290 }
aa83d1ec 291 | ID '.' opt_name2
e4492aa0 292 {
aa83d1ec
KT
293 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
294 sprintf (name, "%s.%s", $1, $3);
295 $$ = name;
296 }
297 ;
298
299opt_name: opt_name2 { $$ = $1; }
5aaace27 300 | { $$ = ""; }
252b5132
RH
301 ;
302
7fcab871
KT
303opt_equalequal_name: EQUAL ID { $$ = $2; }
304 | { $$ = 0; }
305 ;
306
e4492aa0 307opt_ordinal:
252b5132
RH
308 '@' NUMBER { $$ = $2;}
309 | { $$ = -1;}
310 ;
311
312opt_equal_name:
aa83d1ec 313 '=' opt_name2 { $$ = $2; }
e4492aa0 314 | { $$ = 0; }
252b5132
RH
315 ;
316
0a4e6638
KT
317opt_base: BASE '=' VMA { $$ = $3;}
318 | { $$ = (bfd_vma) -1;}
252b5132
RH
319 ;
320
05056a8d 321anylang_id: ID { $$ = $1; }
770c040b
KT
322 | '.' ID
323 {
bdca0ea1 324 char *id = def_pool_alloc (strlen ($2) + 2);
770c040b
KT
325 sprintf (id, ".%s", $2);
326 $$ = id;
327 }
05056a8d
DK
328 | anylang_id '.' opt_digits opt_id
329 {
bdca0ea1 330 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
05056a8d
DK
331 sprintf (id, "%s.%s%s", $1, $3, $4);
332 $$ = id;
333 }
334 ;
335
336opt_digits: DIGITS { $$ = $1; }
337 | { $$ = ""; }
338 ;
339
340opt_id: ID { $$ = $1; }
341 | { $$ = ""; }
342 ;
343
344NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
0a4e6638
KT
345 ;
346VMA: DIGITS { $$ = (bfd_vma) strtoull ($1, 0, 0); }
252b5132
RH
347
348%%
349
350/*****************************************************************************
351 API
352 *****************************************************************************/
353
354static FILE *the_file;
355static const char *def_filename;
356static int linenumber;
357static def_file *def;
358static int saw_newline;
359
360struct directive
361 {
362 struct directive *next;
363 char *name;
364 int len;
365 };
366
367static struct directive *directives = 0;
368
369def_file *
1579bae1 370def_file_empty (void)
252b5132 371{
1579bae1 372 def_file *rv = xmalloc (sizeof (def_file));
252b5132
RH
373 memset (rv, 0, sizeof (def_file));
374 rv->is_dll = -1;
1579bae1 375 rv->base_address = (bfd_vma) -1;
252b5132
RH
376 rv->stack_reserve = rv->stack_commit = -1;
377 rv->heap_reserve = rv->heap_commit = -1;
378 rv->version_major = rv->version_minor = -1;
379 return rv;
380}
381
382def_file *
1579bae1 383def_file_parse (const char *filename, def_file *add_to)
252b5132
RH
384{
385 struct directive *d;
386
387 the_file = fopen (filename, "r");
388 def_filename = filename;
389 linenumber = 1;
390 if (!the_file)
391 {
392 perror (filename);
393 return 0;
394 }
395 if (add_to)
396 {
397 def = add_to;
398 }
399 else
400 {
401 def = def_file_empty ();
402 }
403
404 saw_newline = 1;
405 if (def_parse ())
406 {
407 def_file_free (def);
408 fclose (the_file);
bdca0ea1 409 def_pool_free ();
252b5132
RH
410 return 0;
411 }
412
413 fclose (the_file);
414
bdca0ea1 415 while ((d = directives) != NULL)
252b5132
RH
416 {
417#if TRACE
418 printf ("Adding directive %08x `%s'\n", d->name, d->name);
419#endif
420 def_file_add_directive (def, d->name, d->len);
bdca0ea1
KT
421 directives = d->next;
422 free (d->name);
423 free (d);
252b5132 424 }
bdca0ea1 425 def_pool_free ();
252b5132
RH
426
427 return def;
428}
429
430void
91d6fa6a 431def_file_free (def_file *fdef)
252b5132
RH
432{
433 int i;
a35bc64f 434
91d6fa6a 435 if (!fdef)
252b5132 436 return;
91d6fa6a
NC
437 if (fdef->name)
438 free (fdef->name);
439 if (fdef->description)
440 free (fdef->description);
252b5132 441
91d6fa6a 442 if (fdef->section_defs)
252b5132 443 {
91d6fa6a 444 for (i = 0; i < fdef->num_section_defs; i++)
252b5132 445 {
91d6fa6a
NC
446 if (fdef->section_defs[i].name)
447 free (fdef->section_defs[i].name);
448 if (fdef->section_defs[i].class)
449 free (fdef->section_defs[i].class);
252b5132 450 }
91d6fa6a 451 free (fdef->section_defs);
252b5132
RH
452 }
453
91d6fa6a 454 if (fdef->exports)
252b5132 455 {
b41d91a7 456 for (i = 0; i < fdef->num_exports; i++)
252b5132 457 {
91d6fa6a
NC
458 if (fdef->exports[i].internal_name
459 && fdef->exports[i].internal_name != fdef->exports[i].name)
460 free (fdef->exports[i].internal_name);
461 if (fdef->exports[i].name)
462 free (fdef->exports[i].name);
463 if (fdef->exports[i].its_name)
464 free (fdef->exports[i].its_name);
252b5132 465 }
91d6fa6a 466 free (fdef->exports);
252b5132
RH
467 }
468
91d6fa6a 469 if (fdef->imports)
252b5132 470 {
91d6fa6a 471 for (i = 0; i < fdef->num_imports; i++)
252b5132 472 {
91d6fa6a
NC
473 if (fdef->imports[i].internal_name
474 && fdef->imports[i].internal_name != fdef->imports[i].name)
475 free (fdef->imports[i].internal_name);
476 if (fdef->imports[i].name)
477 free (fdef->imports[i].name);
478 if (fdef->imports[i].its_name)
479 free (fdef->imports[i].its_name);
252b5132 480 }
91d6fa6a 481 free (fdef->imports);
252b5132
RH
482 }
483
91d6fa6a 484 while (fdef->modules)
252b5132 485 {
91d6fa6a
NC
486 def_file_module *m = fdef->modules;
487
488 fdef->modules = fdef->modules->next;
252b5132
RH
489 free (m);
490 }
491
91d6fa6a 492 while (fdef->aligncomms)
c1711530 493 {
91d6fa6a
NC
494 def_file_aligncomm *c = fdef->aligncomms;
495
496 fdef->aligncomms = fdef->aligncomms->next;
c1711530
DK
497 free (c->symbol_name);
498 free (c);
499 }
500
91d6fa6a 501 free (fdef);
252b5132
RH
502}
503
504#ifdef DEF_FILE_PRINT
505void
91d6fa6a 506def_file_print (FILE *file, def_file *fdef)
252b5132
RH
507{
508 int i;
a35bc64f 509
91d6fa6a
NC
510 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
511 if (fdef->name)
512 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
513 if (fdef->is_dll != -1)
514 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
515 if (fdef->base_address != (bfd_vma) -1)
0a4e6638
KT
516 {
517 fprintf (file, " base address: 0x");
518 fprintf_vma (file, fdef->base_address);
519 fprintf (file, "\n");
520 }
91d6fa6a
NC
521 if (fdef->description)
522 fprintf (file, " description: `%s'\n", fdef->description);
523 if (fdef->stack_reserve != -1)
524 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
525 if (fdef->stack_commit != -1)
526 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
527 if (fdef->heap_reserve != -1)
528 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
529 if (fdef->heap_commit != -1)
530 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
531
532 if (fdef->num_section_defs > 0)
252b5132
RH
533 {
534 fprintf (file, " section defs:\n");
a35bc64f 535
91d6fa6a 536 for (i = 0; i < fdef->num_section_defs; i++)
252b5132
RH
537 {
538 fprintf (file, " name: `%s', class: `%s', flags:",
91d6fa6a
NC
539 fdef->section_defs[i].name, fdef->section_defs[i].class);
540 if (fdef->section_defs[i].flag_read)
252b5132 541 fprintf (file, " R");
91d6fa6a 542 if (fdef->section_defs[i].flag_write)
252b5132 543 fprintf (file, " W");
91d6fa6a 544 if (fdef->section_defs[i].flag_execute)
252b5132 545 fprintf (file, " X");
91d6fa6a 546 if (fdef->section_defs[i].flag_shared)
252b5132
RH
547 fprintf (file, " S");
548 fprintf (file, "\n");
549 }
550 }
551
91d6fa6a 552 if (fdef->num_exports > 0)
252b5132
RH
553 {
554 fprintf (file, " exports:\n");
a35bc64f 555
91d6fa6a 556 for (i = 0; i < fdef->num_exports; i++)
252b5132
RH
557 {
558 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
91d6fa6a
NC
559 fdef->exports[i].name, fdef->exports[i].internal_name,
560 fdef->exports[i].ordinal);
561 if (fdef->exports[i].flag_private)
252b5132 562 fprintf (file, " P");
91d6fa6a 563 if (fdef->exports[i].flag_constant)
252b5132 564 fprintf (file, " C");
91d6fa6a 565 if (fdef->exports[i].flag_noname)
252b5132 566 fprintf (file, " N");
91d6fa6a 567 if (fdef->exports[i].flag_data)
252b5132
RH
568 fprintf (file, " D");
569 fprintf (file, "\n");
570 }
571 }
572
91d6fa6a 573 if (fdef->num_imports > 0)
252b5132
RH
574 {
575 fprintf (file, " imports:\n");
a35bc64f 576
91d6fa6a 577 for (i = 0; i < fdef->num_imports; i++)
252b5132
RH
578 {
579 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
91d6fa6a
NC
580 fdef->imports[i].internal_name,
581 fdef->imports[i].module,
582 fdef->imports[i].name,
583 fdef->imports[i].ordinal);
252b5132
RH
584 }
585 }
a35bc64f 586
91d6fa6a
NC
587 if (fdef->version_major != -1)
588 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
a35bc64f 589
b41d91a7 590 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
252b5132
RH
591}
592#endif
593
db17156e
KT
594/* Helper routine to check for identity of string pointers,
595 which might be NULL. */
596
597static int
598are_names_equal (const char *s1, const char *s2)
599{
600 if (!s1 && !s2)
601 return 0;
602 if (!s1 || !s2)
603 return (!s1 ? -1 : 1);
604 return strcmp (s1, s2);
605}
606
607static int
608cmp_export_elem (const def_file_export *e, const char *ex_name,
609 const char *in_name, const char *its_name,
610 int ord)
611{
612 int r;
613
614 if ((r = are_names_equal (ex_name, e->name)) != 0)
615 return r;
616 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
617 return r;
618 if ((r = are_names_equal (its_name, e->its_name)) != 0)
619 return r;
620 return (ord - e->ordinal);
621}
622
623/* Search the position of the identical element, or returns the position
624 of the next higher element. If last valid element is smaller, then MAX
625 is returned. */
626
627static int
628find_export_in_list (def_file_export *b, int max,
629 const char *ex_name, const char *in_name,
630 const char *its_name, int ord, int *is_ident)
631{
632 int e, l, r, p;
633
634 *is_ident = 0;
635 if (!max)
636 return 0;
637 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
d0ac6938
KT
638 {
639 if (!e)
640 *is_ident = 1;
641 return 0;
642 }
db17156e
KT
643 if (max == 1)
644 return 1;
645 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
646 return max;
647 else if (!e || max == 2)
d0ac6938
KT
648 {
649 if (!e)
650 *is_ident = 1;
651 return max - 1;
652 }
db17156e
KT
653 l = 0; r = max - 1;
654 while (l < r)
655 {
656 p = (l + r) / 2;
657 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
658 if (!e)
659 {
660 *is_ident = 1;
661 return p;
662 }
663 else if (e < 0)
664 r = p - 1;
665 else if (e > 0)
666 l = p + 1;
667 }
668 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
669 ++l;
670 else if (!e)
671 *is_ident = 1;
672 return l;
673}
674
252b5132 675def_file_export *
91d6fa6a 676def_file_add_export (def_file *fdef,
1579bae1
AM
677 const char *external_name,
678 const char *internal_name,
7fcab871 679 int ordinal,
db17156e
KT
680 const char *its_name,
681 int *is_dup)
252b5132
RH
682{
683 def_file_export *e;
db17156e 684 int pos;
91d6fa6a 685 int max_exports = ROUND_UP(fdef->num_exports, 32);
a35bc64f 686
db17156e
KT
687 if (internal_name && !external_name)
688 external_name = internal_name;
689 if (external_name && !internal_name)
690 internal_name = external_name;
691
692 /* We need to avoid duplicates. */
693 *is_dup = 0;
694 pos = find_export_in_list (fdef->exports, fdef->num_exports,
695 external_name, internal_name,
696 its_name, ordinal, is_dup);
697
698 if (*is_dup != 0)
699 return (fdef->exports + pos);
700
91d6fa6a 701 if (fdef->num_exports >= max_exports)
252b5132 702 {
91d6fa6a
NC
703 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
704 if (fdef->exports)
705 fdef->exports = xrealloc (fdef->exports,
1579bae1 706 max_exports * sizeof (def_file_export));
252b5132 707 else
91d6fa6a 708 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
252b5132 709 }
db17156e
KT
710
711 e = fdef->exports + pos;
712 if (pos != fdef->num_exports)
713 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
252b5132 714 memset (e, 0, sizeof (def_file_export));
252b5132
RH
715 e->name = xstrdup (external_name);
716 e->internal_name = xstrdup (internal_name);
7fcab871 717 e->its_name = (its_name ? xstrdup (its_name) : NULL);
252b5132 718 e->ordinal = ordinal;
91d6fa6a 719 fdef->num_exports++;
252b5132
RH
720 return e;
721}
722
a35bc64f 723def_file_module *
91d6fa6a 724def_get_module (def_file *fdef, const char *name)
a35bc64f
NC
725{
726 def_file_module *s;
727
91d6fa6a 728 for (s = fdef->modules; s; s = s->next)
a35bc64f
NC
729 if (strcmp (s->name, name) == 0)
730 return s;
731
1579bae1 732 return NULL;
a35bc64f
NC
733}
734
252b5132 735static def_file_module *
91d6fa6a 736def_stash_module (def_file *fdef, const char *name)
252b5132
RH
737{
738 def_file_module *s;
a35bc64f 739
91d6fa6a 740 if ((s = def_get_module (fdef, name)) != NULL)
252b5132 741 return s;
1579bae1 742 s = xmalloc (sizeof (def_file_module) + strlen (name));
b41d91a7 743 s->next = fdef->modules;
91d6fa6a 744 fdef->modules = s;
252b5132
RH
745 s->user_data = 0;
746 strcpy (s->name, name);
747 return s;
748}
749
db17156e
KT
750static int
751cmp_import_elem (const def_file_import *e, const char *ex_name,
752 const char *in_name, const char *module,
753 int ord)
754{
755 int r;
756
6e230cc2
KT
757 if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
758 return r;
db17156e
KT
759 if ((r = are_names_equal (ex_name, e->name)) != 0)
760 return r;
761 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
762 return r;
763 if (ord != e->ordinal)
764 return (ord < e->ordinal ? -1 : 1);
6e230cc2 765 return 0;
db17156e
KT
766}
767
768/* Search the position of the identical element, or returns the position
769 of the next higher element. If last valid element is smaller, then MAX
770 is returned. */
771
772static int
773find_import_in_list (def_file_import *b, int max,
774 const char *ex_name, const char *in_name,
775 const char *module, int ord, int *is_ident)
776{
777 int e, l, r, p;
778
779 *is_ident = 0;
780 if (!max)
781 return 0;
782 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
d0ac6938
KT
783 {
784 if (!e)
785 *is_ident = 1;
786 return 0;
787 }
db17156e
KT
788 if (max == 1)
789 return 1;
790 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
791 return max;
792 else if (!e || max == 2)
d0ac6938
KT
793 {
794 if (!e)
795 *is_ident = 1;
796 return max - 1;
797 }
db17156e
KT
798 l = 0; r = max - 1;
799 while (l < r)
800 {
801 p = (l + r) / 2;
802 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
803 if (!e)
804 {
805 *is_ident = 1;
806 return p;
807 }
808 else if (e < 0)
809 r = p - 1;
810 else if (e > 0)
811 l = p + 1;
812 }
813 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
814 ++l;
815 else if (!e)
816 *is_ident = 1;
817 return l;
818}
819
252b5132 820def_file_import *
91d6fa6a 821def_file_add_import (def_file *fdef,
1579bae1
AM
822 const char *name,
823 const char *module,
824 int ordinal,
7fcab871 825 const char *internal_name,
db17156e
KT
826 const char *its_name,
827 int *is_dup)
252b5132
RH
828{
829 def_file_import *i;
db17156e 830 int pos;
91d6fa6a 831 int max_imports = ROUND_UP (fdef->num_imports, 16);
a35bc64f 832
db17156e
KT
833 /* We need to avoid here duplicates. */
834 *is_dup = 0;
835 pos = find_import_in_list (fdef->imports, fdef->num_imports,
836 name,
837 (!internal_name ? name : internal_name),
838 module, ordinal, is_dup);
839 if (*is_dup != 0)
840 return fdef->imports + pos;
841
91d6fa6a 842 if (fdef->num_imports >= max_imports)
252b5132 843 {
91d6fa6a 844 max_imports = ROUND_UP (fdef->num_imports+1, 16);
a35bc64f 845
91d6fa6a
NC
846 if (fdef->imports)
847 fdef->imports = xrealloc (fdef->imports,
1579bae1 848 max_imports * sizeof (def_file_import));
252b5132 849 else
91d6fa6a 850 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
252b5132 851 }
db17156e
KT
852 i = fdef->imports + pos;
853 if (pos != fdef->num_imports)
854 memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
252b5132
RH
855 memset (i, 0, sizeof (def_file_import));
856 if (name)
857 i->name = xstrdup (name);
858 if (module)
b41d91a7 859 i->module = def_stash_module (fdef, module);
252b5132
RH
860 i->ordinal = ordinal;
861 if (internal_name)
862 i->internal_name = xstrdup (internal_name);
863 else
864 i->internal_name = i->name;
7fcab871 865 i->its_name = (its_name ? xstrdup (its_name) : NULL);
91d6fa6a 866 fdef->num_imports++;
a35bc64f 867
252b5132
RH
868 return i;
869}
870
871struct
872{
873 char *param;
874 int token;
875}
876diropts[] =
877{
878 { "-heap", HEAPSIZE },
8e58566f 879 { "-stack", STACKSIZE_K },
252b5132
RH
880 { "-attr", SECTIONS },
881 { "-export", EXPORTS },
c1711530 882 { "-aligncomm", ALIGNCOMM },
252b5132
RH
883 { 0, 0 }
884};
885
886void
1579bae1 887def_file_add_directive (def_file *my_def, const char *param, int len)
252b5132
RH
888{
889 def_file *save_def = def;
890 const char *pend = param + len;
dc17f155 891 char * tend = (char *) param;
252b5132
RH
892 int i;
893
894 def = my_def;
895
896 while (param < pend)
897 {
1579bae1
AM
898 while (param < pend
899 && (ISSPACE (*param) || *param == '\n' || *param == 0))
252b5132 900 param++;
a35bc64f 901
dc17f155
NC
902 if (param == pend)
903 break;
904
905 /* Scan forward until we encounter any of:
906 - the end of the buffer
907 - the start of a new option
908 - a newline seperating options
909 - a NUL seperating options. */
910 for (tend = (char *) (param + 1);
1579bae1
AM
911 (tend < pend
912 && !(ISSPACE (tend[-1]) && *tend == '-')
913 && *tend != '\n' && *tend != 0);
a35bc64f
NC
914 tend++)
915 ;
252b5132
RH
916
917 for (i = 0; diropts[i].param; i++)
918 {
91d6fa6a 919 len = strlen (diropts[i].param);
a35bc64f 920
252b5132
RH
921 if (tend - param >= len
922 && strncmp (param, diropts[i].param, len) == 0
923 && (param[len] == ':' || param[len] == ' '))
924 {
925 lex_parse_string_end = tend;
926 lex_parse_string = param + len + 1;
927 lex_forced_token = diropts[i].token;
928 saw_newline = 0;
dc17f155
NC
929 if (def_parse ())
930 continue;
252b5132
RH
931 break;
932 }
933 }
934
935 if (!diropts[i].param)
dc17f155 936 {
3d4a522e
NC
937 if (tend < pend)
938 {
939 char saved;
dc17f155 940
3d4a522e
NC
941 saved = * tend;
942 * tend = 0;
943 /* xgettext:c-format */
944 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
945 * tend = saved;
946 }
947 else
948 {
949 einfo (_("Warning: corrupt .drectve at end of def file\n"));
950 }
dc17f155 951 }
a35bc64f 952
252b5132
RH
953 lex_parse_string = 0;
954 param = tend;
955 }
956
957 def = save_def;
bdca0ea1 958 def_pool_free ();
252b5132
RH
959}
960
a35bc64f 961/* Parser Callbacks. */
252b5132
RH
962
963static void
0a4e6638 964def_image_name (const char *name, bfd_vma base, int is_dll)
252b5132 965{
a2877985
DS
966 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
967 to do here. We retain the output filename specified on command line. */
968 if (*name)
969 {
970 const char* image_name = lbasename (name);
91d6fa6a 971
a2877985
DS
972 if (image_name != name)
973 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
974 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
975 name);
976 if (def->name)
977 free (def->name);
e4492aa0 978 /* Append the default suffix, if none specified. */
a2877985
DS
979 if (strchr (image_name, '.') == 0)
980 {
981 const char * suffix = is_dll ? ".dll" : ".exe";
982
983 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
984 sprintf (def->name, "%s%s", image_name, suffix);
985 }
986 else
987 def->name = xstrdup (image_name);
988 }
989
990 /* Honor a BASE address statement, even if LIBRARY string is empty. */
252b5132 991 def->base_address = base;
a880c748 992 def->is_dll = is_dll;
252b5132
RH
993}
994
995static void
1579bae1 996def_description (const char *text)
252b5132
RH
997{
998 int len = def->description ? strlen (def->description) : 0;
a35bc64f 999
252b5132
RH
1000 len += strlen (text) + 1;
1001 if (def->description)
1002 {
1579bae1 1003 def->description = xrealloc (def->description, len);
252b5132
RH
1004 strcat (def->description, text);
1005 }
1006 else
1007 {
1579bae1 1008 def->description = xmalloc (len);
252b5132
RH
1009 strcpy (def->description, text);
1010 }
1011}
1012
1013static void
1579bae1 1014def_stacksize (int reserve, int commit)
252b5132
RH
1015{
1016 def->stack_reserve = reserve;
1017 def->stack_commit = commit;
1018}
1019
1020static void
1579bae1 1021def_heapsize (int reserve, int commit)
252b5132
RH
1022{
1023 def->heap_reserve = reserve;
1024 def->heap_commit = commit;
1025}
1026
1027static void
1579bae1 1028def_section (const char *name, int attr)
252b5132
RH
1029{
1030 def_file_section *s;
1579bae1 1031 int max_sections = ROUND_UP (def->num_section_defs, 4);
a35bc64f 1032
252b5132
RH
1033 if (def->num_section_defs >= max_sections)
1034 {
1579bae1 1035 max_sections = ROUND_UP (def->num_section_defs+1, 4);
a35bc64f 1036
252b5132 1037 if (def->section_defs)
1579bae1
AM
1038 def->section_defs = xrealloc (def->section_defs,
1039 max_sections * sizeof (def_file_import));
252b5132 1040 else
1579bae1 1041 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
252b5132
RH
1042 }
1043 s = def->section_defs + def->num_section_defs;
1044 memset (s, 0, sizeof (def_file_section));
1045 s->name = xstrdup (name);
1046 if (attr & 1)
1047 s->flag_read = 1;
1048 if (attr & 2)
1049 s->flag_write = 1;
1050 if (attr & 4)
1051 s->flag_execute = 1;
1052 if (attr & 8)
1053 s->flag_shared = 1;
1054
1055 def->num_section_defs++;
1056}
1057
1058static void
1579bae1 1059def_section_alt (const char *name, const char *attr)
252b5132
RH
1060{
1061 int aval = 0;
a35bc64f 1062
252b5132
RH
1063 for (; *attr; attr++)
1064 {
1065 switch (*attr)
1066 {
1067 case 'R':
1068 case 'r':
1069 aval |= 1;
1070 break;
1071 case 'W':
1072 case 'w':
1073 aval |= 2;
1074 break;
1075 case 'X':
1076 case 'x':
1077 aval |= 4;
1078 break;
1079 case 'S':
1080 case 's':
1081 aval |= 8;
1082 break;
1083 }
1084 }
1085 def_section (name, aval);
1086}
1087
1088static void
1579bae1
AM
1089def_exports (const char *external_name,
1090 const char *internal_name,
1091 int ordinal,
7fcab871
KT
1092 int flags,
1093 const char *its_name)
252b5132
RH
1094{
1095 def_file_export *dfe;
db17156e 1096 int is_dup = 0;
252b5132
RH
1097
1098 if (!internal_name && external_name)
1099 internal_name = external_name;
1100#if TRACE
1101 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1102#endif
1103
7fcab871 1104 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
db17156e
KT
1105 its_name, &is_dup);
1106
1107 /* We might check here for flag redefinition and warn. For now we
1108 ignore duplicates silently. */
1109 if (is_dup)
1110 return;
1111
252b5132
RH
1112 if (flags & 1)
1113 dfe->flag_noname = 1;
1114 if (flags & 2)
1115 dfe->flag_constant = 1;
1116 if (flags & 4)
1117 dfe->flag_data = 1;
1118 if (flags & 8)
1119 dfe->flag_private = 1;
1120}
1121
1122static void
1579bae1
AM
1123def_import (const char *internal_name,
1124 const char *module,
1125 const char *dllext,
1126 const char *name,
7fcab871
KT
1127 int ordinal,
1128 const char *its_name)
252b5132
RH
1129{
1130 char *buf = 0;
db17156e
KT
1131 const char *ext = dllext ? dllext : "dll";
1132 int is_dup = 0;
e4492aa0 1133
1579bae1 1134 buf = xmalloc (strlen (module) + strlen (ext) + 2);
053c44e1
DS
1135 sprintf (buf, "%s.%s", module, ext);
1136 module = buf;
252b5132 1137
db17156e
KT
1138 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1139 &is_dup);
1140 free (buf);
252b5132
RH
1141}
1142
1143static void
1579bae1 1144def_version (int major, int minor)
252b5132
RH
1145{
1146 def->version_major = major;
1147 def->version_minor = minor;
1148}
1149
1150static void
1579bae1 1151def_directive (char *str)
252b5132 1152{
1579bae1 1153 struct directive *d = xmalloc (sizeof (struct directive));
a35bc64f 1154
252b5132
RH
1155 d->next = directives;
1156 directives = d;
1157 d->name = xstrdup (str);
1158 d->len = strlen (str);
1159}
1160
c1711530
DK
1161static void
1162def_aligncomm (char *str, int align)
1163{
dc204beb 1164 def_file_aligncomm *c, *p;
e4492aa0 1165
dc204beb
KT
1166 p = NULL;
1167 c = def->aligncomms;
1168 while (c != NULL)
1169 {
1170 int e = strcmp (c->symbol_name, str);
1171 if (!e)
1172 {
1173 /* Not sure if we want to allow here duplicates with
1174 different alignments, but for now we keep them. */
1175 e = (int) c->alignment - align;
1176 if (!e)
1177 return;
1178 }
1179 if (e > 0)
1180 break;
1181 c = (p = c)->next;
1182 }
c1711530 1183
dc204beb 1184 c = xmalloc (sizeof (def_file_aligncomm));
c1711530
DK
1185 c->symbol_name = xstrdup (str);
1186 c->alignment = (unsigned int) align;
dc204beb
KT
1187 if (!p)
1188 {
1189 c->next = def->aligncomms;
1190 def->aligncomms = c;
1191 }
1192 else
1193 {
1194 c->next = p->next;
1195 p->next = c;
1196 }
c1711530
DK
1197}
1198
252b5132 1199static int
1579bae1 1200def_error (const char *err)
252b5132 1201{
1579bae1
AM
1202 einfo ("%P: %s:%d: %s\n",
1203 def_filename ? def_filename : "<unknown-file>", linenumber, err);
252b5132
RH
1204 return 0;
1205}
1206
1207
a35bc64f 1208/* Lexical Scanner. */
252b5132
RH
1209
1210#undef TRACE
1211#define TRACE 0
1212
a35bc64f 1213/* Never freed, but always reused as needed, so no real leak. */
252b5132
RH
1214static char *buffer = 0;
1215static int buflen = 0;
1216static int bufptr = 0;
1217
1218static void
1579bae1 1219put_buf (char c)
252b5132
RH
1220{
1221 if (bufptr == buflen)
1222 {
a35bc64f 1223 buflen += 50; /* overly reasonable, eh? */
252b5132 1224 if (buffer)
1579bae1 1225 buffer = xrealloc (buffer, buflen + 1);
252b5132 1226 else
1579bae1 1227 buffer = xmalloc (buflen + 1);
252b5132
RH
1228 }
1229 buffer[bufptr++] = c;
a35bc64f 1230 buffer[bufptr] = 0; /* not optimal, but very convenient. */
252b5132
RH
1231}
1232
1233static struct
1234{
1235 char *name;
1236 int token;
1237}
1238tokens[] =
1239{
1240 { "BASE", BASE },
1241 { "CODE", CODE },
7c9e78f8
DD
1242 { "CONSTANT", CONSTANTU },
1243 { "constant", CONSTANTL },
1244 { "DATA", DATAU },
1245 { "data", DATAL },
252b5132
RH
1246 { "DESCRIPTION", DESCRIPTION },
1247 { "DIRECTIVE", DIRECTIVE },
1248 { "EXECUTE", EXECUTE },
1249 { "EXPORTS", EXPORTS },
1250 { "HEAPSIZE", HEAPSIZE },
1251 { "IMPORTS", IMPORTS },
1252 { "LIBRARY", LIBRARY },
1253 { "NAME", NAME },
7c9e78f8
DD
1254 { "NONAME", NONAMEU },
1255 { "noname", NONAMEL },
1256 { "PRIVATE", PRIVATEU },
1257 { "private", PRIVATEL },
252b5132
RH
1258 { "READ", READ },
1259 { "SECTIONS", SECTIONS },
1260 { "SEGMENTS", SECTIONS },
1261 { "SHARED", SHARED },
8e58566f 1262 { "STACKSIZE", STACKSIZE_K },
252b5132
RH
1263 { "VERSION", VERSIONK },
1264 { "WRITE", WRITE },
1265 { 0, 0 }
1266};
1267
1268static int
1579bae1 1269def_getc (void)
252b5132
RH
1270{
1271 int rv;
a35bc64f 1272
252b5132
RH
1273 if (lex_parse_string)
1274 {
1275 if (lex_parse_string >= lex_parse_string_end)
1276 rv = EOF;
1277 else
1278 rv = *lex_parse_string++;
1279 }
1280 else
1281 {
1282 rv = fgetc (the_file);
1283 }
1284 if (rv == '\n')
1285 saw_newline = 1;
1286 return rv;
1287}
1288
1289static int
1579bae1 1290def_ungetc (int c)
252b5132
RH
1291{
1292 if (lex_parse_string)
1293 {
1294 lex_parse_string--;
1295 return c;
1296 }
1297 else
1298 return ungetc (c, the_file);
1299}
1300
1301static int
1579bae1 1302def_lex (void)
252b5132
RH
1303{
1304 int c, i, q;
1305
1306 if (lex_forced_token)
1307 {
1308 i = lex_forced_token;
1309 lex_forced_token = 0;
1310#if TRACE
1311 printf ("lex: forcing token %d\n", i);
1312#endif
1313 return i;
1314 }
1315
1316 c = def_getc ();
1317
a35bc64f 1318 /* Trim leading whitespace. */
252b5132
RH
1319 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1320 c = def_getc ();
1321
1322 if (c == EOF)
1323 {
1324#if TRACE
1325 printf ("lex: EOF\n");
1326#endif
1327 return 0;
1328 }
1329
1330 if (saw_newline && c == ';')
1331 {
1332 do
1333 {
1334 c = def_getc ();
1335 }
1336 while (c != EOF && c != '\n');
1337 if (c == '\n')
1338 return def_lex ();
1339 return 0;
1340 }
a35bc64f
NC
1341
1342 /* Must be something else. */
252b5132
RH
1343 saw_newline = 0;
1344
3882b010 1345 if (ISDIGIT (c))
252b5132
RH
1346 {
1347 bufptr = 0;
3882b010 1348 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
252b5132
RH
1349 {
1350 put_buf (c);
1351 c = def_getc ();
1352 }
1353 if (c != EOF)
1354 def_ungetc (c);
bdca0ea1 1355 yylval.digits = def_pool_strdup (buffer);
252b5132 1356#if TRACE
05056a8d 1357 printf ("lex: `%s' returns DIGITS\n", buffer);
252b5132 1358#endif
05056a8d 1359 return DIGITS;
252b5132
RH
1360 }
1361
c9e38879 1362 if (ISALPHA (c) || strchr ("$:-_?@", c))
252b5132
RH
1363 {
1364 bufptr = 0;
c9e38879
NC
1365 q = c;
1366 put_buf (c);
1367 c = def_getc ();
1368
1369 if (q == '@')
1370 {
1371 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1372 return (q);
1373 else if (ISDIGIT (c)) /* '@' followed by digit. */
1374 {
1375 def_ungetc (c);
1376 return (q);
1377 }
1378#if TRACE
1379 printf ("lex: @ returns itself\n");
1380#endif
1381 }
1382
424908eb 1383 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
252b5132
RH
1384 {
1385 put_buf (c);
1386 c = def_getc ();
1387 }
1388 if (c != EOF)
1389 def_ungetc (c);
c9e38879
NC
1390 if (ISALPHA (q)) /* Check for tokens. */
1391 {
1392 for (i = 0; tokens[i].name; i++)
1393 if (strcmp (tokens[i].name, buffer) == 0)
1394 {
252b5132 1395#if TRACE
c9e38879 1396 printf ("lex: `%s' is a string token\n", buffer);
252b5132 1397#endif
c9e38879
NC
1398 return tokens[i].token;
1399 }
1400 }
252b5132
RH
1401#if TRACE
1402 printf ("lex: `%s' returns ID\n", buffer);
1403#endif
bdca0ea1 1404 yylval.id = def_pool_strdup (buffer);
252b5132
RH
1405 return ID;
1406 }
1407
1408 if (c == '\'' || c == '"')
1409 {
1410 q = c;
1411 c = def_getc ();
1412 bufptr = 0;
a35bc64f 1413
252b5132
RH
1414 while (c != EOF && c != q)
1415 {
1416 put_buf (c);
1417 c = def_getc ();
1418 }
bdca0ea1 1419 yylval.id = def_pool_strdup (buffer);
252b5132
RH
1420#if TRACE
1421 printf ("lex: `%s' returns ID\n", buffer);
1422#endif
1423 return ID;
1424 }
1425
7fcab871
KT
1426 if ( c == '=')
1427 {
1428 c = def_getc ();
1429 if (c == '=')
1430 {
1431#if TRACE
1432 printf ("lex: `==' returns EQUAL\n");
1433#endif
1434 return EQUAL;
1435 }
1436 def_ungetc (c);
1437#if TRACE
1438 printf ("lex: `=' returns itself\n");
1439#endif
1440 return '=';
1441 }
1442 if (c == '.' || c == ',')
252b5132
RH
1443 {
1444#if TRACE
1445 printf ("lex: `%c' returns itself\n", c);
1446#endif
1447 return c;
1448 }
1449
1450 if (c == '\n')
1451 {
1452 linenumber++;
1453 saw_newline = 1;
1454 }
1455
1456 /*printf ("lex: 0x%02x ignored\n", c); */
1457 return def_lex ();
1458}
bdca0ea1
KT
1459
1460static char *
1461def_pool_alloc (size_t sz)
1462{
1463 def_pool_str *e;
1464
1465 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1466 e->next = pool_strs;
1467 pool_strs = e;
1468 return e->data;
1469}
1470
1471static char *
1472def_pool_strdup (const char *str)
1473{
1474 char *s;
1475 size_t len;
1476 if (!str)
1477 return NULL;
1478 len = strlen (str) + 1;
1479 s = def_pool_alloc (len);
1480 memcpy (s, str, len);
1481 return s;
1482}
1483
1484static void
1485def_pool_free (void)
1486{
1487 def_pool_str *p;
1488 while ((p = pool_strs) != NULL)
1489 {
1490 pool_strs = p->next;
1491 free (p);
1492 }
1493}
This page took 0.640743 seconds and 4 git commands to generate.