]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - ld/deffilep.y
19990502 sourceware import
[thirdparty/binutils-gdb.git] / ld / deffilep.y
1 %{ /* deffilep.y - parser for .def files */
2
3 /* Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
4
5 This file is part of GNU Binutils.
6
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.
11
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.
16
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. */
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
80 static int def_lex ();
81
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_debug;
97 static int def_lex PARAMS ((void));
98
99 static int lex_forced_token = 0;
100 static const char *lex_parse_string = 0;
101 static 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
121 start: start command
122 | command
123 ;
124
125 command:
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
142 explist:
143 /* EMPTY */
144 | expline
145 | explist expline
146 ;
147
148 expline:
149 ID opt_equal_name opt_ordinal exp_opt_list
150 { def_exports ($1, $2, $3, $4); }
151 ;
152 exp_opt_list:
153 exp_opt exp_opt_list { $$ = $1 | $2; }
154 | { $$ = 0; }
155 ;
156 exp_opt:
157 NONAME { $$ = 1; }
158 | CONSTANT { $$ = 2; }
159 | DATA { $$ = 4; }
160 | PRIVATE { $$ = 8; }
161 ;
162 implist:
163 implist impline
164 | impline
165 ;
166
167 impline:
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
176 seclist:
177 seclist secline
178 | secline
179 ;
180
181 secline:
182 ID attr_list { def_section ($1, $2);}
183 | ID ID { def_section_alt ($1, $2);}
184 ;
185
186 attr_list:
187 attr_list opt_comma attr { $$ = $1 | $3; }
188 | attr { $$ = $1; }
189 ;
190
191 opt_comma:
192 ','
193 |
194 ;
195 opt_number: ',' NUMBER { $$=$2;}
196 | { $$=-1;}
197 ;
198
199 attr:
200 READ { $$ = 1;}
201 | WRITE { $$ = 2;}
202 | EXECUTE { $$=4;}
203 | SHARED { $$=8;}
204 ;
205
206 opt_name: ID { $$ = $1; }
207 | { $$ = 0; }
208 ;
209
210 opt_ordinal:
211 '@' NUMBER { $$ = $2;}
212 | { $$ = -1;}
213 ;
214
215 opt_equal_name:
216 '=' ID { $$ = $2; }
217 | { $$ = 0; }
218 ;
219
220 opt_base: BASE '=' NUMBER { $$ = $3;}
221 | { $$ = 0;}
222 ;
223
224
225
226 %%
227
228 /*****************************************************************************
229 API
230 *****************************************************************************/
231
232 static FILE *the_file;
233 static const char *def_filename;
234 static int linenumber;
235 static def_file *def;
236 static int saw_newline;
237
238 struct directive
239 {
240 struct directive *next;
241 char *name;
242 int len;
243 };
244
245 static struct directive *directives = 0;
246
247 def_file *
248 def_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
260 def_file *
261 def_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
305 void
306 def_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
366 void
367 def_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
447 def_file_export *
448 def_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
477 static def_file_module *
478 def_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
494 def_file_import *
495 def_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
527 struct
528 {
529 char *param;
530 int token;
531 }
532 diropts[] =
533 {
534 { "-heap", HEAPSIZE },
535 { "-stack", STACKSIZE },
536 { "-attr", SECTIONS },
537 { "-export", EXPORTS },
538 { 0, 0 }
539 };
540
541 void
542 def_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
595 static void
596 def_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
607 static void
608 def_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
619 static void
620 def_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
637 static void
638 def_stacksize (reserve, commit)
639 int reserve;
640 int commit;
641 {
642 def->stack_reserve = reserve;
643 def->stack_commit = commit;
644 }
645
646 static void
647 def_heapsize (reserve, commit)
648 int reserve;
649 int commit;
650 {
651 def->heap_reserve = reserve;
652 def->heap_commit = commit;
653 }
654
655 static void
656 def_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
685 static void
686 def_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
716 static void
717 def_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
742 static void
743 def_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
764 static void
765 def_version (major, minor)
766 int major;
767 int minor;
768 {
769 def->version_major = major;
770 def->version_minor = minor;
771 }
772
773 static void
774 def_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
784 static int
785 def_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 */
802 static char *buffer = 0;
803 static int buflen = 0;
804 static int bufptr = 0;
805
806 static void
807 put_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
822 static struct
823 {
824 char *name;
825 int token;
826 }
827 tokens[] =
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
853 static int
854 def_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
873 static int
874 def_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
886 static int
887 def_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 }