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