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