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