2007-06-14 Paolo Bonzini <bonzini@gnu.org>
[binutils.git] / ld / deffilep.y
blob80efb789f02afbaa9a72658ffd8c8d48f30a8d59
1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
22 #include "sysdep.h"
23 #include "libiberty.h"
24 #include "safe-ctype.h"
25 #include "bfd.h"
26 #include "ld.h"
27 #include "ldmisc.h"
28 #include "deffile.h"
30 #define TRACE 0
32 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
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. */
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
80 static void def_description (const char *);
81 static void def_exports (const char *, const char *, int, int);
82 static void def_heapsize (int, int);
83 static void def_import (const char *, const char *, const char *, const char *,
84 int);
85 static void def_image_name (const char *, int, int);
86 static void def_section (const char *, int);
87 static void def_section_alt (const char *, const char *);
88 static void def_stacksize (int, int);
89 static void def_version (int, int);
90 static void def_directive (char *);
91 static int def_parse (void);
92 static int def_error (const char *);
93 static int def_lex (void);
95 static int lex_forced_token = 0;
96 static const char *lex_parse_string = 0;
97 static const char *lex_parse_string_end = 0;
101 %union {
102 char *id;
103 int number;
106 %token NAME LIBRARY DESCRIPTION STACKSIZE HEAPSIZE CODE DATAU DATAL
107 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
108 %token PRIVATEU PRIVATEL
109 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
110 %token <id> ID
111 %token <number> NUMBER
112 %type <number> opt_base opt_ordinal
113 %type <number> attr attr_list opt_number exp_opt_list exp_opt
114 %type <id> opt_name opt_equal_name dot_name
118 start: start command
119 | command
122 command:
123 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
124 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
125 | DESCRIPTION ID { def_description ($2);}
126 | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
127 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
128 | CODE attr_list { def_section ("CODE", $2);}
129 | DATAU attr_list { def_section ("DATA", $2);}
130 | SECTIONS seclist
131 | EXPORTS explist
132 | IMPORTS implist
133 | VERSIONK NUMBER { def_version ($2, 0);}
134 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
135 | DIRECTIVE ID { def_directive ($2);}
139 explist:
140 /* EMPTY */
141 | expline
142 | explist expline
145 expline:
146 /* The opt_comma is necessary to support both the usual
147 DEF file syntax as well as .drectve syntax which
148 mandates <expsym>,<expoptlist>. */
149 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
150 { def_exports ($1, $2, $3, $5); }
152 exp_opt_list:
153 /* The opt_comma is necessary to support both the usual
154 DEF file syntax as well as .drectve syntax which
155 allows for comma separated opt list. */
156 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
157 | { $$ = 0; }
159 exp_opt:
160 NONAMEU { $$ = 1; }
161 | NONAMEL { $$ = 1; }
162 | CONSTANTU { $$ = 2; }
163 | CONSTANTL { $$ = 2; }
164 | DATAU { $$ = 4; }
165 | DATAL { $$ = 4; }
166 | PRIVATEU { $$ = 8; }
167 | PRIVATEL { $$ = 8; }
169 implist:
170 implist impline
171 | impline
174 impline:
175 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
176 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
177 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
178 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
179 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
180 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
183 seclist:
184 seclist secline
185 | secline
188 secline:
189 ID attr_list { def_section ($1, $2);}
190 | ID ID { def_section_alt ($1, $2);}
193 attr_list:
194 attr_list opt_comma attr { $$ = $1 | $3; }
195 | attr { $$ = $1; }
198 opt_comma:
202 opt_number: ',' NUMBER { $$=$2;}
203 | { $$=-1;}
206 attr:
207 READ { $$ = 1;}
208 | WRITE { $$ = 2;}
209 | EXECUTE { $$=4;}
210 | SHARED { $$=8;}
213 opt_name: ID { $$ = $1; }
214 | ID '.' ID
216 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
217 sprintf (name, "%s.%s", $1, $3);
218 $$ = name;
220 | { $$ = ""; }
223 opt_ordinal:
224 '@' NUMBER { $$ = $2;}
225 | { $$ = -1;}
228 opt_equal_name:
229 '=' dot_name { $$ = $2; }
230 | { $$ = 0; }
233 opt_base: BASE '=' NUMBER { $$ = $3;}
234 | { $$ = -1;}
237 dot_name: ID { $$ = $1; }
238 | dot_name '.' ID
240 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
241 sprintf (name, "%s.%s", $1, $3);
242 $$ = name;
249 /*****************************************************************************
251 *****************************************************************************/
253 static FILE *the_file;
254 static const char *def_filename;
255 static int linenumber;
256 static def_file *def;
257 static int saw_newline;
259 struct directive
261 struct directive *next;
262 char *name;
263 int len;
266 static struct directive *directives = 0;
268 def_file *
269 def_file_empty (void)
271 def_file *rv = xmalloc (sizeof (def_file));
272 memset (rv, 0, sizeof (def_file));
273 rv->is_dll = -1;
274 rv->base_address = (bfd_vma) -1;
275 rv->stack_reserve = rv->stack_commit = -1;
276 rv->heap_reserve = rv->heap_commit = -1;
277 rv->version_major = rv->version_minor = -1;
278 return rv;
281 def_file *
282 def_file_parse (const char *filename, def_file *add_to)
284 struct directive *d;
286 the_file = fopen (filename, "r");
287 def_filename = filename;
288 linenumber = 1;
289 if (!the_file)
291 perror (filename);
292 return 0;
294 if (add_to)
296 def = add_to;
298 else
300 def = def_file_empty ();
303 saw_newline = 1;
304 if (def_parse ())
306 def_file_free (def);
307 fclose (the_file);
308 return 0;
311 fclose (the_file);
313 for (d = directives; d; d = d->next)
315 #if TRACE
316 printf ("Adding directive %08x `%s'\n", d->name, d->name);
317 #endif
318 def_file_add_directive (def, d->name, d->len);
321 return def;
324 void
325 def_file_free (def_file *def)
327 int i;
329 if (!def)
330 return;
331 if (def->name)
332 free (def->name);
333 if (def->description)
334 free (def->description);
336 if (def->section_defs)
338 for (i = 0; i < def->num_section_defs; i++)
340 if (def->section_defs[i].name)
341 free (def->section_defs[i].name);
342 if (def->section_defs[i].class)
343 free (def->section_defs[i].class);
345 free (def->section_defs);
348 if (def->exports)
350 for (i = 0; i < def->num_exports; i++)
352 if (def->exports[i].internal_name
353 && def->exports[i].internal_name != def->exports[i].name)
354 free (def->exports[i].internal_name);
355 if (def->exports[i].name)
356 free (def->exports[i].name);
358 free (def->exports);
361 if (def->imports)
363 for (i = 0; i < def->num_imports; i++)
365 if (def->imports[i].internal_name
366 && def->imports[i].internal_name != def->imports[i].name)
367 free (def->imports[i].internal_name);
368 if (def->imports[i].name)
369 free (def->imports[i].name);
371 free (def->imports);
374 while (def->modules)
376 def_file_module *m = def->modules;
377 def->modules = def->modules->next;
378 free (m);
381 free (def);
384 #ifdef DEF_FILE_PRINT
385 void
386 def_file_print (FILE *file, def_file *def)
388 int i;
390 fprintf (file, ">>>> def_file at 0x%08x\n", def);
391 if (def->name)
392 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
393 if (def->is_dll != -1)
394 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
395 if (def->base_address != (bfd_vma) -1)
396 fprintf (file, " base address: 0x%08x\n", def->base_address);
397 if (def->description)
398 fprintf (file, " description: `%s'\n", def->description);
399 if (def->stack_reserve != -1)
400 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
401 if (def->stack_commit != -1)
402 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
403 if (def->heap_reserve != -1)
404 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
405 if (def->heap_commit != -1)
406 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
408 if (def->num_section_defs > 0)
410 fprintf (file, " section defs:\n");
412 for (i = 0; i < def->num_section_defs; i++)
414 fprintf (file, " name: `%s', class: `%s', flags:",
415 def->section_defs[i].name, def->section_defs[i].class);
416 if (def->section_defs[i].flag_read)
417 fprintf (file, " R");
418 if (def->section_defs[i].flag_write)
419 fprintf (file, " W");
420 if (def->section_defs[i].flag_execute)
421 fprintf (file, " X");
422 if (def->section_defs[i].flag_shared)
423 fprintf (file, " S");
424 fprintf (file, "\n");
428 if (def->num_exports > 0)
430 fprintf (file, " exports:\n");
432 for (i = 0; i < def->num_exports; i++)
434 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
435 def->exports[i].name, def->exports[i].internal_name,
436 def->exports[i].ordinal);
437 if (def->exports[i].flag_private)
438 fprintf (file, " P");
439 if (def->exports[i].flag_constant)
440 fprintf (file, " C");
441 if (def->exports[i].flag_noname)
442 fprintf (file, " N");
443 if (def->exports[i].flag_data)
444 fprintf (file, " D");
445 fprintf (file, "\n");
449 if (def->num_imports > 0)
451 fprintf (file, " imports:\n");
453 for (i = 0; i < def->num_imports; i++)
455 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
456 def->imports[i].internal_name,
457 def->imports[i].module,
458 def->imports[i].name,
459 def->imports[i].ordinal);
463 if (def->version_major != -1)
464 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
466 fprintf (file, "<<<< def_file at 0x%08x\n", def);
468 #endif
470 def_file_export *
471 def_file_add_export (def_file *def,
472 const char *external_name,
473 const char *internal_name,
474 int ordinal)
476 def_file_export *e;
477 int max_exports = ROUND_UP(def->num_exports, 32);
479 if (def->num_exports >= max_exports)
481 max_exports = ROUND_UP(def->num_exports + 1, 32);
482 if (def->exports)
483 def->exports = xrealloc (def->exports,
484 max_exports * sizeof (def_file_export));
485 else
486 def->exports = xmalloc (max_exports * sizeof (def_file_export));
488 e = def->exports + def->num_exports;
489 memset (e, 0, sizeof (def_file_export));
490 if (internal_name && !external_name)
491 external_name = internal_name;
492 if (external_name && !internal_name)
493 internal_name = external_name;
494 e->name = xstrdup (external_name);
495 e->internal_name = xstrdup (internal_name);
496 e->ordinal = ordinal;
497 def->num_exports++;
498 return e;
501 def_file_module *
502 def_get_module (def_file *def, const char *name)
504 def_file_module *s;
506 for (s = def->modules; s; s = s->next)
507 if (strcmp (s->name, name) == 0)
508 return s;
510 return NULL;
513 static def_file_module *
514 def_stash_module (def_file *def, const char *name)
516 def_file_module *s;
518 if ((s = def_get_module (def, name)) != NULL)
519 return s;
520 s = xmalloc (sizeof (def_file_module) + strlen (name));
521 s->next = def->modules;
522 def->modules = s;
523 s->user_data = 0;
524 strcpy (s->name, name);
525 return s;
528 def_file_import *
529 def_file_add_import (def_file *def,
530 const char *name,
531 const char *module,
532 int ordinal,
533 const char *internal_name)
535 def_file_import *i;
536 int max_imports = ROUND_UP (def->num_imports, 16);
538 if (def->num_imports >= max_imports)
540 max_imports = ROUND_UP (def->num_imports+1, 16);
542 if (def->imports)
543 def->imports = xrealloc (def->imports,
544 max_imports * sizeof (def_file_import));
545 else
546 def->imports = xmalloc (max_imports * sizeof (def_file_import));
548 i = def->imports + def->num_imports;
549 memset (i, 0, sizeof (def_file_import));
550 if (name)
551 i->name = xstrdup (name);
552 if (module)
553 i->module = def_stash_module (def, module);
554 i->ordinal = ordinal;
555 if (internal_name)
556 i->internal_name = xstrdup (internal_name);
557 else
558 i->internal_name = i->name;
559 def->num_imports++;
561 return i;
564 struct
566 char *param;
567 int token;
569 diropts[] =
571 { "-heap", HEAPSIZE },
572 { "-stack", STACKSIZE },
573 { "-attr", SECTIONS },
574 { "-export", EXPORTS },
575 { 0, 0 }
578 void
579 def_file_add_directive (def_file *my_def, const char *param, int len)
581 def_file *save_def = def;
582 const char *pend = param + len;
583 char * tend = (char *) param;
584 int i;
586 def = my_def;
588 while (param < pend)
590 while (param < pend
591 && (ISSPACE (*param) || *param == '\n' || *param == 0))
592 param++;
594 if (param == pend)
595 break;
597 /* Scan forward until we encounter any of:
598 - the end of the buffer
599 - the start of a new option
600 - a newline seperating options
601 - a NUL seperating options. */
602 for (tend = (char *) (param + 1);
603 (tend < pend
604 && !(ISSPACE (tend[-1]) && *tend == '-')
605 && *tend != '\n' && *tend != 0);
606 tend++)
609 for (i = 0; diropts[i].param; i++)
611 int len = strlen (diropts[i].param);
613 if (tend - param >= len
614 && strncmp (param, diropts[i].param, len) == 0
615 && (param[len] == ':' || param[len] == ' '))
617 lex_parse_string_end = tend;
618 lex_parse_string = param + len + 1;
619 lex_forced_token = diropts[i].token;
620 saw_newline = 0;
621 if (def_parse ())
622 continue;
623 break;
627 if (!diropts[i].param)
629 char saved;
631 saved = * tend;
632 * tend = 0;
633 /* xgettext:c-format */
634 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
635 * tend = saved;
638 lex_parse_string = 0;
639 param = tend;
642 def = save_def;
645 /* Parser Callbacks. */
647 static void
648 def_image_name (const char *name, int base, int is_dll)
650 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
651 to do here. We retain the output filename specified on command line. */
652 if (*name)
654 const char* image_name = lbasename (name);
655 if (image_name != name)
656 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
657 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
658 name);
659 if (def->name)
660 free (def->name);
661 /* Append the default suffix, if none specified. */
662 if (strchr (image_name, '.') == 0)
664 const char * suffix = is_dll ? ".dll" : ".exe";
666 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
667 sprintf (def->name, "%s%s", image_name, suffix);
669 else
670 def->name = xstrdup (image_name);
673 /* Honor a BASE address statement, even if LIBRARY string is empty. */
674 def->base_address = base;
675 def->is_dll = is_dll;
678 static void
679 def_description (const char *text)
681 int len = def->description ? strlen (def->description) : 0;
683 len += strlen (text) + 1;
684 if (def->description)
686 def->description = xrealloc (def->description, len);
687 strcat (def->description, text);
689 else
691 def->description = xmalloc (len);
692 strcpy (def->description, text);
696 static void
697 def_stacksize (int reserve, int commit)
699 def->stack_reserve = reserve;
700 def->stack_commit = commit;
703 static void
704 def_heapsize (int reserve, int commit)
706 def->heap_reserve = reserve;
707 def->heap_commit = commit;
710 static void
711 def_section (const char *name, int attr)
713 def_file_section *s;
714 int max_sections = ROUND_UP (def->num_section_defs, 4);
716 if (def->num_section_defs >= max_sections)
718 max_sections = ROUND_UP (def->num_section_defs+1, 4);
720 if (def->section_defs)
721 def->section_defs = xrealloc (def->section_defs,
722 max_sections * sizeof (def_file_import));
723 else
724 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
726 s = def->section_defs + def->num_section_defs;
727 memset (s, 0, sizeof (def_file_section));
728 s->name = xstrdup (name);
729 if (attr & 1)
730 s->flag_read = 1;
731 if (attr & 2)
732 s->flag_write = 1;
733 if (attr & 4)
734 s->flag_execute = 1;
735 if (attr & 8)
736 s->flag_shared = 1;
738 def->num_section_defs++;
741 static void
742 def_section_alt (const char *name, const char *attr)
744 int aval = 0;
746 for (; *attr; attr++)
748 switch (*attr)
750 case 'R':
751 case 'r':
752 aval |= 1;
753 break;
754 case 'W':
755 case 'w':
756 aval |= 2;
757 break;
758 case 'X':
759 case 'x':
760 aval |= 4;
761 break;
762 case 'S':
763 case 's':
764 aval |= 8;
765 break;
768 def_section (name, aval);
771 static void
772 def_exports (const char *external_name,
773 const char *internal_name,
774 int ordinal,
775 int flags)
777 def_file_export *dfe;
779 if (!internal_name && external_name)
780 internal_name = external_name;
781 #if TRACE
782 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
783 #endif
785 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
786 if (flags & 1)
787 dfe->flag_noname = 1;
788 if (flags & 2)
789 dfe->flag_constant = 1;
790 if (flags & 4)
791 dfe->flag_data = 1;
792 if (flags & 8)
793 dfe->flag_private = 1;
796 static void
797 def_import (const char *internal_name,
798 const char *module,
799 const char *dllext,
800 const char *name,
801 int ordinal)
803 char *buf = 0;
804 const char *ext = dllext ? dllext : "dll";
806 buf = xmalloc (strlen (module) + strlen (ext) + 2);
807 sprintf (buf, "%s.%s", module, ext);
808 module = buf;
810 def_file_add_import (def, name, module, ordinal, internal_name);
811 if (buf)
812 free (buf);
815 static void
816 def_version (int major, int minor)
818 def->version_major = major;
819 def->version_minor = minor;
822 static void
823 def_directive (char *str)
825 struct directive *d = xmalloc (sizeof (struct directive));
827 d->next = directives;
828 directives = d;
829 d->name = xstrdup (str);
830 d->len = strlen (str);
833 static int
834 def_error (const char *err)
836 einfo ("%P: %s:%d: %s\n",
837 def_filename ? def_filename : "<unknown-file>", linenumber, err);
838 return 0;
842 /* Lexical Scanner. */
844 #undef TRACE
845 #define TRACE 0
847 /* Never freed, but always reused as needed, so no real leak. */
848 static char *buffer = 0;
849 static int buflen = 0;
850 static int bufptr = 0;
852 static void
853 put_buf (char c)
855 if (bufptr == buflen)
857 buflen += 50; /* overly reasonable, eh? */
858 if (buffer)
859 buffer = xrealloc (buffer, buflen + 1);
860 else
861 buffer = xmalloc (buflen + 1);
863 buffer[bufptr++] = c;
864 buffer[bufptr] = 0; /* not optimal, but very convenient. */
867 static struct
869 char *name;
870 int token;
872 tokens[] =
874 { "BASE", BASE },
875 { "CODE", CODE },
876 { "CONSTANT", CONSTANTU },
877 { "constant", CONSTANTL },
878 { "DATA", DATAU },
879 { "data", DATAL },
880 { "DESCRIPTION", DESCRIPTION },
881 { "DIRECTIVE", DIRECTIVE },
882 { "EXECUTE", EXECUTE },
883 { "EXPORTS", EXPORTS },
884 { "HEAPSIZE", HEAPSIZE },
885 { "IMPORTS", IMPORTS },
886 { "LIBRARY", LIBRARY },
887 { "NAME", NAME },
888 { "NONAME", NONAMEU },
889 { "noname", NONAMEL },
890 { "PRIVATE", PRIVATEU },
891 { "private", PRIVATEL },
892 { "READ", READ },
893 { "SECTIONS", SECTIONS },
894 { "SEGMENTS", SECTIONS },
895 { "SHARED", SHARED },
896 { "STACKSIZE", STACKSIZE },
897 { "VERSION", VERSIONK },
898 { "WRITE", WRITE },
899 { 0, 0 }
902 static int
903 def_getc (void)
905 int rv;
907 if (lex_parse_string)
909 if (lex_parse_string >= lex_parse_string_end)
910 rv = EOF;
911 else
912 rv = *lex_parse_string++;
914 else
916 rv = fgetc (the_file);
918 if (rv == '\n')
919 saw_newline = 1;
920 return rv;
923 static int
924 def_ungetc (int c)
926 if (lex_parse_string)
928 lex_parse_string--;
929 return c;
931 else
932 return ungetc (c, the_file);
935 static int
936 def_lex (void)
938 int c, i, q;
940 if (lex_forced_token)
942 i = lex_forced_token;
943 lex_forced_token = 0;
944 #if TRACE
945 printf ("lex: forcing token %d\n", i);
946 #endif
947 return i;
950 c = def_getc ();
952 /* Trim leading whitespace. */
953 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
954 c = def_getc ();
956 if (c == EOF)
958 #if TRACE
959 printf ("lex: EOF\n");
960 #endif
961 return 0;
964 if (saw_newline && c == ';')
968 c = def_getc ();
970 while (c != EOF && c != '\n');
971 if (c == '\n')
972 return def_lex ();
973 return 0;
976 /* Must be something else. */
977 saw_newline = 0;
979 if (ISDIGIT (c))
981 bufptr = 0;
982 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
984 put_buf (c);
985 c = def_getc ();
987 if (c != EOF)
988 def_ungetc (c);
989 yylval.number = strtoul (buffer, 0, 0);
990 #if TRACE
991 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
992 #endif
993 return NUMBER;
996 if (ISALPHA (c) || strchr ("$:-_?@", c))
998 bufptr = 0;
999 q = c;
1000 put_buf (c);
1001 c = def_getc ();
1003 if (q == '@')
1005 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1006 return (q);
1007 else if (ISDIGIT (c)) /* '@' followed by digit. */
1009 def_ungetc (c);
1010 return (q);
1012 #if TRACE
1013 printf ("lex: @ returns itself\n");
1014 #endif
1017 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
1019 put_buf (c);
1020 c = def_getc ();
1022 if (c != EOF)
1023 def_ungetc (c);
1024 if (ISALPHA (q)) /* Check for tokens. */
1026 for (i = 0; tokens[i].name; i++)
1027 if (strcmp (tokens[i].name, buffer) == 0)
1029 #if TRACE
1030 printf ("lex: `%s' is a string token\n", buffer);
1031 #endif
1032 return tokens[i].token;
1035 #if TRACE
1036 printf ("lex: `%s' returns ID\n", buffer);
1037 #endif
1038 yylval.id = xstrdup (buffer);
1039 return ID;
1042 if (c == '\'' || c == '"')
1044 q = c;
1045 c = def_getc ();
1046 bufptr = 0;
1048 while (c != EOF && c != q)
1050 put_buf (c);
1051 c = def_getc ();
1053 yylval.id = xstrdup (buffer);
1054 #if TRACE
1055 printf ("lex: `%s' returns ID\n", buffer);
1056 #endif
1057 return ID;
1060 if (c == '=' || c == '.' || c == ',')
1062 #if TRACE
1063 printf ("lex: `%c' returns itself\n", c);
1064 #endif
1065 return c;
1068 if (c == '\n')
1070 linenumber++;
1071 saw_newline = 1;
1074 /*printf ("lex: 0x%02x ignored\n", c); */
1075 return def_lex ();