* ar.c (full_pathname): New static variable.
[binutils.git] / ld / deffilep.y
blob70e517c486d92700d09d2e4fa7c855e67274f4d7
1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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"
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 int def_lex ();
82 static void def_description PARAMS ((const char *));
83 static void def_exports PARAMS ((const char *, const char *, int, int));
84 static void def_heapsize PARAMS ((int, int));
85 static void def_import
86 PARAMS ((const char *, const char *, const char *, const char *, int));
87 static void def_library PARAMS ((const char *, int));
88 static void def_name PARAMS ((const char *, int));
89 static void def_section PARAMS ((const char *, int));
90 static void def_section_alt PARAMS ((const char *, const char *));
91 static void def_stacksize PARAMS ((int, int));
92 static void def_version PARAMS ((int, int));
93 static void def_directive PARAMS ((char *));
94 static int def_parse PARAMS ((void));
95 static int def_error PARAMS ((const char *));
96 static int def_lex PARAMS ((void));
98 static int lex_forced_token = 0;
99 static const char *lex_parse_string = 0;
100 static const char *lex_parse_string_end = 0;
104 %union {
105 char *id;
106 int number;
109 %token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATA
110 %token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANT, PRIVATE
111 %token READ WRITE EXECUTE SHARED NONAME DIRECTIVE
112 %token <id> ID
113 %token <number> NUMBER
114 %type <number> opt_base opt_ordinal
115 %type <number> attr attr_list opt_number exp_opt_list exp_opt
116 %type <id> opt_name opt_equal_name
120 start: start command
121 | command
124 command:
125 NAME opt_name opt_base { def_name ($2, $3); }
126 | LIBRARY opt_name opt_base { def_library ($2, $3); }
127 | DESCRIPTION ID { def_description ($2);}
128 | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
129 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
130 | CODE attr_list { def_section ("CODE", $2);}
131 | DATA attr_list { def_section ("DATA", $2);}
132 | SECTIONS seclist
133 | EXPORTS explist
134 | IMPORTS implist
135 | VERSIONK NUMBER { def_version ($2, 0);}
136 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
137 | DIRECTIVE ID { def_directive ($2);}
141 explist:
142 /* EMPTY */
143 | expline
144 | explist expline
147 expline:
148 ID opt_equal_name opt_ordinal exp_opt_list
149 { def_exports ($1, $2, $3, $4); }
151 exp_opt_list:
152 exp_opt exp_opt_list { $$ = $1 | $2; }
153 | { $$ = 0; }
155 exp_opt:
156 NONAME { $$ = 1; }
157 | CONSTANT { $$ = 2; }
158 | DATA { $$ = 4; }
159 | PRIVATE { $$ = 8; }
161 implist:
162 implist impline
163 | impline
166 impline:
167 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
168 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
169 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
170 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
171 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
172 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
175 seclist:
176 seclist secline
177 | secline
180 secline:
181 ID attr_list { def_section ($1, $2);}
182 | ID ID { def_section_alt ($1, $2);}
185 attr_list:
186 attr_list opt_comma attr { $$ = $1 | $3; }
187 | attr { $$ = $1; }
190 opt_comma:
194 opt_number: ',' NUMBER { $$=$2;}
195 | { $$=-1;}
198 attr:
199 READ { $$ = 1;}
200 | WRITE { $$ = 2;}
201 | EXECUTE { $$=4;}
202 | SHARED { $$=8;}
205 opt_name: ID { $$ = $1; }
206 | { $$ = 0; }
209 opt_ordinal:
210 '@' NUMBER { $$ = $2;}
211 | { $$ = -1;}
214 opt_equal_name:
215 '=' ID { $$ = $2; }
216 | { $$ = 0; }
219 opt_base: BASE '=' NUMBER { $$ = $3;}
220 | { $$ = 0;}
227 /*****************************************************************************
229 *****************************************************************************/
231 static FILE *the_file;
232 static const char *def_filename;
233 static int linenumber;
234 static def_file *def;
235 static int saw_newline;
237 struct directive
239 struct directive *next;
240 char *name;
241 int len;
244 static struct directive *directives = 0;
246 def_file *
247 def_file_empty ()
249 def_file *rv = (def_file *) xmalloc (sizeof (def_file));
250 memset (rv, 0, sizeof (def_file));
251 rv->is_dll = -1;
252 rv->base_address = (bfd_vma) (-1);
253 rv->stack_reserve = rv->stack_commit = -1;
254 rv->heap_reserve = rv->heap_commit = -1;
255 rv->version_major = rv->version_minor = -1;
256 return rv;
259 def_file *
260 def_file_parse (filename, add_to)
261 const char *filename;
262 def_file *add_to;
264 struct directive *d;
266 the_file = fopen (filename, "r");
267 def_filename = filename;
268 linenumber = 1;
269 if (!the_file)
271 perror (filename);
272 return 0;
274 if (add_to)
276 def = add_to;
278 else
280 def = def_file_empty ();
283 saw_newline = 1;
284 if (def_parse ())
286 def_file_free (def);
287 fclose (the_file);
288 return 0;
291 fclose (the_file);
293 for (d = directives; d; d = d->next)
295 #if TRACE
296 printf ("Adding directive %08x `%s'\n", d->name, d->name);
297 #endif
298 def_file_add_directive (def, d->name, d->len);
301 return def;
304 void
305 def_file_free (def)
306 def_file *def;
308 int i;
309 if (!def)
310 return;
311 if (def->name)
312 free (def->name);
313 if (def->description)
314 free (def->description);
316 if (def->section_defs)
318 for (i = 0; i < def->num_section_defs; i++)
320 if (def->section_defs[i].name)
321 free (def->section_defs[i].name);
322 if (def->section_defs[i].class)
323 free (def->section_defs[i].class);
325 free (def->section_defs);
328 if (def->exports)
330 for (i = 0; i < def->num_exports; i++)
332 if (def->exports[i].internal_name
333 && def->exports[i].internal_name != def->exports[i].name)
334 free (def->exports[i].internal_name);
335 if (def->exports[i].name)
336 free (def->exports[i].name);
338 free (def->exports);
341 if (def->imports)
343 for (i = 0; i < def->num_imports; i++)
345 if (def->imports[i].internal_name
346 && def->imports[i].internal_name != def->imports[i].name)
347 free (def->imports[i].internal_name);
348 if (def->imports[i].name)
349 free (def->imports[i].name);
351 free (def->imports);
354 while (def->modules)
356 def_file_module *m = def->modules;
357 def->modules = def->modules->next;
358 free (m);
361 free (def);
364 #ifdef DEF_FILE_PRINT
365 void
366 def_file_print (file, def)
367 FILE *file;
368 def_file *def;
370 int i;
371 fprintf (file, ">>>> def_file at 0x%08x\n", def);
372 if (def->name)
373 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
374 if (def->is_dll != -1)
375 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
376 if (def->base_address != (bfd_vma) (-1))
377 fprintf (file, " base address: 0x%08x\n", def->base_address);
378 if (def->description)
379 fprintf (file, " description: `%s'\n", def->description);
380 if (def->stack_reserve != -1)
381 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
382 if (def->stack_commit != -1)
383 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
384 if (def->heap_reserve != -1)
385 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
386 if (def->heap_commit != -1)
387 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
389 if (def->num_section_defs > 0)
391 fprintf (file, " section defs:\n");
392 for (i = 0; i < def->num_section_defs; i++)
394 fprintf (file, " name: `%s', class: `%s', flags:",
395 def->section_defs[i].name, def->section_defs[i].class);
396 if (def->section_defs[i].flag_read)
397 fprintf (file, " R");
398 if (def->section_defs[i].flag_write)
399 fprintf (file, " W");
400 if (def->section_defs[i].flag_execute)
401 fprintf (file, " X");
402 if (def->section_defs[i].flag_shared)
403 fprintf (file, " S");
404 fprintf (file, "\n");
408 if (def->num_exports > 0)
410 fprintf (file, " exports:\n");
411 for (i = 0; i < def->num_exports; i++)
413 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
414 def->exports[i].name, def->exports[i].internal_name,
415 def->exports[i].ordinal);
416 if (def->exports[i].flag_private)
417 fprintf (file, " P");
418 if (def->exports[i].flag_constant)
419 fprintf (file, " C");
420 if (def->exports[i].flag_noname)
421 fprintf (file, " N");
422 if (def->exports[i].flag_data)
423 fprintf (file, " D");
424 fprintf (file, "\n");
428 if (def->num_imports > 0)
430 fprintf (file, " imports:\n");
431 for (i = 0; i < def->num_imports; i++)
433 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
434 def->imports[i].internal_name,
435 def->imports[i].module,
436 def->imports[i].name,
437 def->imports[i].ordinal);
440 if (def->version_major != -1)
441 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
442 fprintf (file, "<<<< def_file at 0x%08x\n", def);
444 #endif
446 def_file_export *
447 def_file_add_export (def, external_name, internal_name, ordinal)
448 def_file *def;
449 const char *external_name;
450 const char *internal_name;
451 int ordinal;
453 def_file_export *e;
454 int max_exports = ROUND_UP(def->num_exports, 32);
455 if (def->num_exports >= max_exports)
457 max_exports = ROUND_UP(def->num_exports+1, 32);
458 if (def->exports)
459 def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export));
460 else
461 def->exports = (def_file_export *) xmalloc (max_exports * sizeof (def_file_export));
463 e = def->exports + def->num_exports;
464 memset (e, 0, sizeof (def_file_export));
465 if (internal_name && !external_name)
466 external_name = internal_name;
467 if (external_name && !internal_name)
468 internal_name = external_name;
469 e->name = xstrdup (external_name);
470 e->internal_name = xstrdup (internal_name);
471 e->ordinal = ordinal;
472 def->num_exports++;
473 return e;
476 static def_file_module *
477 def_stash_module (def, name)
478 def_file *def;
479 char *name;
481 def_file_module *s;
482 for (s=def->modules; s; s=s->next)
483 if (strcmp (s->name, name) == 0)
484 return s;
485 s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name));
486 s->next = def->modules;
487 def->modules = s;
488 s->user_data = 0;
489 strcpy (s->name, name);
490 return s;
493 def_file_import *
494 def_file_add_import (def, name, module, ordinal, internal_name)
495 def_file *def;
496 const char *name;
497 const char *module;
498 int ordinal;
499 const char *internal_name;
501 def_file_import *i;
502 int max_imports = ROUND_UP(def->num_imports, 16);
503 if (def->num_imports >= max_imports)
505 max_imports = ROUND_UP(def->num_imports+1, 16);
506 if (def->imports)
507 def->imports = (def_file_import *) xrealloc (def->imports, max_imports * sizeof (def_file_import));
508 else
509 def->imports = (def_file_import *) xmalloc (max_imports * sizeof (def_file_import));
511 i = def->imports + def->num_imports;
512 memset (i, 0, sizeof (def_file_import));
513 if (name)
514 i->name = xstrdup (name);
515 if (module)
516 i->module = def_stash_module(def, module);
517 i->ordinal = ordinal;
518 if (internal_name)
519 i->internal_name = xstrdup (internal_name);
520 else
521 i->internal_name = i->name;
522 def->num_imports++;
523 return i;
526 struct
528 char *param;
529 int token;
531 diropts[] =
533 { "-heap", HEAPSIZE },
534 { "-stack", STACKSIZE },
535 { "-attr", SECTIONS },
536 { "-export", EXPORTS },
537 { 0, 0 }
540 void
541 def_file_add_directive (my_def, param, len)
542 def_file *my_def;
543 const char *param;
544 int len;
546 def_file *save_def = def;
547 const char *pend = param + len;
548 const char *tend = param;
549 int i;
551 def = my_def;
553 while (param < pend)
555 while (param < pend && isspace (*param))
556 param++;
557 for (tend = param + 1;
558 tend < pend && !(isspace (tend[-1]) && *tend == '-');
559 tend++);
561 for (i = 0; diropts[i].param; i++)
563 int len = strlen (diropts[i].param);
564 if (tend - param >= len
565 && strncmp (param, diropts[i].param, len) == 0
566 && (param[len] == ':' || param[len] == ' '))
568 lex_parse_string_end = tend;
569 lex_parse_string = param + len + 1;
570 lex_forced_token = diropts[i].token;
571 saw_newline = 0;
572 def_parse ();
573 break;
577 if (!diropts[i].param)
579 /* xgettext:c-format */
580 einfo (_("Warning: .drectve `%.*s' unrecognized\n"),
581 tend - param, param);
583 lex_parse_string = 0;
584 param = tend;
587 def = save_def;
590 /*****************************************************************************
591 Parser Callbacks
592 *****************************************************************************/
594 static void
595 def_name (name, base)
596 const char *name;
597 int base;
599 if (def->name)
600 free (def->name);
601 def->name = xstrdup (name);
602 def->base_address = base;
603 def->is_dll = 0;
606 static void
607 def_library (name, base)
608 const char *name;
609 int base;
611 if (def->name)
612 free (def->name);
613 def->name = xstrdup (name);
614 def->base_address = base;
615 def->is_dll = 1;
618 static void
619 def_description (text)
620 const char *text;
622 int len = def->description ? strlen (def->description) : 0;
623 len += strlen (text) + 1;
624 if (def->description)
626 def->description = (char *) xrealloc (def->description, len);
627 strcat (def->description, text);
629 else
631 def->description = (char *) xmalloc (len);
632 strcpy (def->description, text);
636 static void
637 def_stacksize (reserve, commit)
638 int reserve;
639 int commit;
641 def->stack_reserve = reserve;
642 def->stack_commit = commit;
645 static void
646 def_heapsize (reserve, commit)
647 int reserve;
648 int commit;
650 def->heap_reserve = reserve;
651 def->heap_commit = commit;
654 static void
655 def_section (name, attr)
656 const char *name;
657 int attr;
659 def_file_section *s;
660 int max_sections = ROUND_UP(def->num_section_defs, 4);
661 if (def->num_section_defs >= max_sections)
663 max_sections = ROUND_UP(def->num_section_defs+1, 4);
664 if (def->section_defs)
665 def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
666 else
667 def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import));
669 s = def->section_defs + def->num_section_defs;
670 memset (s, 0, sizeof (def_file_section));
671 s->name = xstrdup (name);
672 if (attr & 1)
673 s->flag_read = 1;
674 if (attr & 2)
675 s->flag_write = 1;
676 if (attr & 4)
677 s->flag_execute = 1;
678 if (attr & 8)
679 s->flag_shared = 1;
681 def->num_section_defs++;
684 static void
685 def_section_alt (name, attr)
686 const char *name;
687 const char *attr;
689 int aval = 0;
690 for (; *attr; attr++)
692 switch (*attr)
694 case 'R':
695 case 'r':
696 aval |= 1;
697 break;
698 case 'W':
699 case 'w':
700 aval |= 2;
701 break;
702 case 'X':
703 case 'x':
704 aval |= 4;
705 break;
706 case 'S':
707 case 's':
708 aval |= 8;
709 break;
712 def_section (name, aval);
715 static void
716 def_exports (external_name, internal_name, ordinal, flags)
717 const char *external_name;
718 const char *internal_name;
719 int ordinal;
720 int flags;
722 def_file_export *dfe;
724 if (!internal_name && external_name)
725 internal_name = external_name;
726 #if TRACE
727 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
728 #endif
730 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
731 if (flags & 1)
732 dfe->flag_noname = 1;
733 if (flags & 2)
734 dfe->flag_constant = 1;
735 if (flags & 4)
736 dfe->flag_data = 1;
737 if (flags & 8)
738 dfe->flag_private = 1;
741 static void
742 def_import (internal_name, module, dllext, name, ordinal)
743 const char *internal_name;
744 const char *module;
745 const char *dllext;
746 const char *name;
747 int ordinal;
749 char *buf = 0;
751 if (dllext != NULL)
753 buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2);
754 sprintf (buf, "%s.%s", module, dllext);
755 module = buf;
758 def_file_add_import (def, name, module, ordinal, internal_name);
759 if (buf)
760 free (buf);
763 static void
764 def_version (major, minor)
765 int major;
766 int minor;
768 def->version_major = major;
769 def->version_minor = minor;
772 static void
773 def_directive (str)
774 char *str;
776 struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
777 d->next = directives;
778 directives = d;
779 d->name = xstrdup (str);
780 d->len = strlen (str);
783 static int
784 def_error (err)
785 const char *err;
787 einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err);
789 return 0;
793 /*****************************************************************************
794 Lexical Scanner
795 *****************************************************************************/
797 #undef TRACE
798 #define TRACE 0
800 /* Never freed, but always reused as needed, so no real leak */
801 static char *buffer = 0;
802 static int buflen = 0;
803 static int bufptr = 0;
805 static void
806 put_buf (c)
807 char c;
809 if (bufptr == buflen)
811 buflen += 50; /* overly reasonable, eh? */
812 if (buffer)
813 buffer = (char *) xrealloc (buffer, buflen + 1);
814 else
815 buffer = (char *) xmalloc (buflen + 1);
817 buffer[bufptr++] = c;
818 buffer[bufptr] = 0; /* not optimal, but very convenient */
821 static struct
823 char *name;
824 int token;
826 tokens[] =
828 { "BASE", BASE },
829 { "CODE", CODE },
830 { "CONSTANT", CONSTANT },
831 { "DATA", DATA },
832 { "DESCRIPTION", DESCRIPTION },
833 { "DIRECTIVE", DIRECTIVE },
834 { "EXECUTE", EXECUTE },
835 { "EXPORTS", EXPORTS },
836 { "HEAPSIZE", HEAPSIZE },
837 { "IMPORTS", IMPORTS },
838 { "LIBRARY", LIBRARY },
839 { "NAME", NAME },
840 { "NONAME", NONAME },
841 { "PRIVATE", PRIVATE },
842 { "READ", READ },
843 { "SECTIONS", SECTIONS },
844 { "SEGMENTS", SECTIONS },
845 { "SHARED", SHARED },
846 { "STACKSIZE", STACKSIZE },
847 { "VERSION", VERSIONK },
848 { "WRITE", WRITE },
849 { 0, 0 }
852 static int
853 def_getc ()
855 int rv;
856 if (lex_parse_string)
858 if (lex_parse_string >= lex_parse_string_end)
859 rv = EOF;
860 else
861 rv = *lex_parse_string++;
863 else
865 rv = fgetc (the_file);
867 if (rv == '\n')
868 saw_newline = 1;
869 return rv;
872 static int
873 def_ungetc (c)
874 int c;
876 if (lex_parse_string)
878 lex_parse_string--;
879 return c;
881 else
882 return ungetc (c, the_file);
885 static int
886 def_lex ()
888 int c, i, q;
890 if (lex_forced_token)
892 i = lex_forced_token;
893 lex_forced_token = 0;
894 #if TRACE
895 printf ("lex: forcing token %d\n", i);
896 #endif
897 return i;
900 c = def_getc ();
902 /* trim leading whitespace */
903 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
904 c = def_getc ();
906 if (c == EOF)
908 #if TRACE
909 printf ("lex: EOF\n");
910 #endif
911 return 0;
914 if (saw_newline && c == ';')
918 c = def_getc ();
920 while (c != EOF && c != '\n');
921 if (c == '\n')
922 return def_lex ();
923 return 0;
925 /* must be something else */
926 saw_newline = 0;
928 if (isdigit (c))
930 bufptr = 0;
931 while (c != EOF && (isxdigit (c) || (c == 'x')))
933 put_buf (c);
934 c = def_getc ();
936 if (c != EOF)
937 def_ungetc (c);
938 yylval.number = strtoul (buffer, 0, 0);
939 #if TRACE
940 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
941 #endif
942 return NUMBER;
945 if (isalpha (c) || strchr ("$:-_?", c))
947 bufptr = 0;
948 while (c != EOF && (isalnum (c) || strchr ("$:-_?/@", c)))
950 put_buf (c);
951 c = def_getc ();
953 if (c != EOF)
954 def_ungetc (c);
955 for (i = 0; tokens[i].name; i++)
956 if (strcmp (tokens[i].name, buffer) == 0)
958 #if TRACE
959 printf ("lex: `%s' is a string token\n", buffer);
960 #endif
961 return tokens[i].token;
963 #if TRACE
964 printf ("lex: `%s' returns ID\n", buffer);
965 #endif
966 yylval.id = xstrdup (buffer);
967 return ID;
970 if (c == '\'' || c == '"')
972 q = c;
973 c = def_getc ();
974 bufptr = 0;
975 while (c != EOF && c != q)
977 put_buf (c);
978 c = def_getc ();
980 yylval.id = xstrdup (buffer);
981 #if TRACE
982 printf ("lex: `%s' returns ID\n", buffer);
983 #endif
984 return ID;
987 if (c == '=' || c == '.' || c == '@' || c == ',')
989 #if TRACE
990 printf ("lex: `%c' returns itself\n", c);
991 #endif
992 return c;
995 if (c == '\n')
997 linenumber++;
998 saw_newline = 1;
1001 /*printf ("lex: 0x%02x ignored\n", c); */
1002 return def_lex ();