* pe-dll.h: New file.
[deliverable/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_lex PARAMS ((void));
97
98 static int lex_forced_token = 0;
99 static const char *lex_parse_string = 0;
100 static const char *lex_parse_string_end = 0;
101
102 %}
103
104 %union {
105 char *id;
106 int number;
107 };
108
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
117
118 %%
119
120 start: start command
121 | command
122 ;
123
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);}
138 ;
139
140
141 explist:
142 /* EMPTY */
143 | expline
144 | explist expline
145 ;
146
147 expline:
148 ID opt_equal_name opt_ordinal exp_opt_list
149 { def_exports ($1, $2, $3, $4); }
150 ;
151 exp_opt_list:
152 exp_opt exp_opt_list { $$ = $1 | $2; }
153 | { $$ = 0; }
154 ;
155 exp_opt:
156 NONAME { $$ = 1; }
157 | CONSTANT { $$ = 2; }
158 | DATA { $$ = 4; }
159 | PRIVATE { $$ = 8; }
160 ;
161 implist:
162 implist impline
163 | impline
164 ;
165
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); }
173 ;
174
175 seclist:
176 seclist secline
177 | secline
178 ;
179
180 secline:
181 ID attr_list { def_section ($1, $2);}
182 | ID ID { def_section_alt ($1, $2);}
183 ;
184
185 attr_list:
186 attr_list opt_comma attr { $$ = $1 | $3; }
187 | attr { $$ = $1; }
188 ;
189
190 opt_comma:
191 ','
192 |
193 ;
194 opt_number: ',' NUMBER { $$=$2;}
195 | { $$=-1;}
196 ;
197
198 attr:
199 READ { $$ = 1;}
200 | WRITE { $$ = 2;}
201 | EXECUTE { $$=4;}
202 | SHARED { $$=8;}
203 ;
204
205 opt_name: ID { $$ = $1; }
206 | { $$ = 0; }
207 ;
208
209 opt_ordinal:
210 '@' NUMBER { $$ = $2;}
211 | { $$ = -1;}
212 ;
213
214 opt_equal_name:
215 '=' ID { $$ = $2; }
216 | { $$ = 0; }
217 ;
218
219 opt_base: BASE '=' NUMBER { $$ = $3;}
220 | { $$ = 0;}
221 ;
222
223
224
225 %%
226
227 /*****************************************************************************
228 API
229 *****************************************************************************/
230
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;
236
237 struct directive
238 {
239 struct directive *next;
240 char *name;
241 int len;
242 };
243
244 static struct directive *directives = 0;
245
246 def_file *
247 def_file_empty ()
248 {
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;
257 }
258
259 def_file *
260 def_file_parse (filename, add_to)
261 const char *filename;
262 def_file *add_to;
263 {
264 struct directive *d;
265
266 the_file = fopen (filename, "r");
267 def_filename = filename;
268 linenumber = 1;
269 if (!the_file)
270 {
271 perror (filename);
272 return 0;
273 }
274 if (add_to)
275 {
276 def = add_to;
277 }
278 else
279 {
280 def = def_file_empty ();
281 }
282
283 saw_newline = 1;
284 if (def_parse ())
285 {
286 def_file_free (def);
287 fclose (the_file);
288 return 0;
289 }
290
291 fclose (the_file);
292
293 for (d = directives; d; d = d->next)
294 {
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);
299 }
300
301 return def;
302 }
303
304 void
305 def_file_free (def)
306 def_file *def;
307 {
308 int i;
309 if (!def)
310 return;
311 if (def->name)
312 free (def->name);
313 if (def->description)
314 free (def->description);
315
316 if (def->section_defs)
317 {
318 for (i = 0; i < def->num_section_defs; i++)
319 {
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);
324 }
325 free (def->section_defs);
326 }
327
328 if (def->exports)
329 {
330 for (i = 0; i < def->num_exports; i++)
331 {
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);
337 }
338 free (def->exports);
339 }
340
341 if (def->imports)
342 {
343 for (i = 0; i < def->num_imports; i++)
344 {
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);
350 }
351 free (def->imports);
352 }
353
354 while (def->modules)
355 {
356 def_file_module *m = def->modules;
357 def->modules = def->modules->next;
358 free (m);
359 }
360
361 free (def);
362 }
363
364 #ifdef DEF_FILE_PRINT
365 void
366 def_file_print (file, def)
367 FILE *file;
368 def_file *def;
369 {
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);
388
389 if (def->num_section_defs > 0)
390 {
391 fprintf (file, " section defs:\n");
392 for (i = 0; i < def->num_section_defs; i++)
393 {
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");
405 }
406 }
407
408 if (def->num_exports > 0)
409 {
410 fprintf (file, " exports:\n");
411 for (i = 0; i < def->num_exports; i++)
412 {
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");
425 }
426 }
427
428 if (def->num_imports > 0)
429 {
430 fprintf (file, " imports:\n");
431 for (i = 0; i < def->num_imports; i++)
432 {
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);
438 }
439 }
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);
443 }
444 #endif
445
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;
452 {
453 def_file_export *e;
454 int max_exports = ROUND_UP(def->num_exports, 32);
455 if (def->num_exports >= max_exports)
456 {
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));
462 }
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;
474 }
475
476 static def_file_module *
477 def_stash_module (def, name)
478 def_file *def;
479 char *name;
480 {
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;
491 }
492
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;
500 {
501 def_file_import *i;
502 int max_imports = ROUND_UP(def->num_imports, 16);
503 if (def->num_imports >= max_imports)
504 {
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));
510 }
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;
524 }
525
526 struct
527 {
528 char *param;
529 int token;
530 }
531 diropts[] =
532 {
533 { "-heap", HEAPSIZE },
534 { "-stack", STACKSIZE },
535 { "-attr", SECTIONS },
536 { "-export", EXPORTS },
537 { 0, 0 }
538 };
539
540 void
541 def_file_add_directive (my_def, param, len)
542 def_file *my_def;
543 const char *param;
544 int len;
545 {
546 def_file *save_def = def;
547 const char *pend = param + len;
548 const char *tend = param;
549 int i;
550
551 def = my_def;
552
553 while (param < pend)
554 {
555 while (param < pend && isspace (*param))
556 param++;
557 for (tend = param + 1;
558 tend < pend && !(isspace (tend[-1]) && *tend == '-');
559 tend++);
560
561 for (i = 0; diropts[i].param; i++)
562 {
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] == ' '))
567 {
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;
574 }
575 }
576
577 if (!diropts[i].param)
578 {
579 /* xgettext:c-format */
580 einfo (_("Warning: .drectve `%.*s' unrecognized\n"),
581 tend - param, param);
582 }
583 lex_parse_string = 0;
584 param = tend;
585 }
586
587 def = save_def;
588 }
589
590 /*****************************************************************************
591 Parser Callbacks
592 *****************************************************************************/
593
594 static void
595 def_name (name, base)
596 const char *name;
597 int base;
598 {
599 if (def->name)
600 free (def->name);
601 def->name = xstrdup (name);
602 def->base_address = base;
603 def->is_dll = 0;
604 }
605
606 static void
607 def_library (name, base)
608 const char *name;
609 int base;
610 {
611 if (def->name)
612 free (def->name);
613 def->name = xstrdup (name);
614 def->base_address = base;
615 def->is_dll = 1;
616 }
617
618 static void
619 def_description (text)
620 const char *text;
621 {
622 int len = def->description ? strlen (def->description) : 0;
623 len += strlen (text) + 1;
624 if (def->description)
625 {
626 def->description = (char *) xrealloc (def->description, len);
627 strcat (def->description, text);
628 }
629 else
630 {
631 def->description = (char *) xmalloc (len);
632 strcpy (def->description, text);
633 }
634 }
635
636 static void
637 def_stacksize (reserve, commit)
638 int reserve;
639 int commit;
640 {
641 def->stack_reserve = reserve;
642 def->stack_commit = commit;
643 }
644
645 static void
646 def_heapsize (reserve, commit)
647 int reserve;
648 int commit;
649 {
650 def->heap_reserve = reserve;
651 def->heap_commit = commit;
652 }
653
654 static void
655 def_section (name, attr)
656 const char *name;
657 int attr;
658 {
659 def_file_section *s;
660 int max_sections = ROUND_UP(def->num_section_defs, 4);
661 if (def->num_section_defs >= max_sections)
662 {
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));
668 }
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;
680
681 def->num_section_defs++;
682 }
683
684 static void
685 def_section_alt (name, attr)
686 const char *name;
687 const char *attr;
688 {
689 int aval = 0;
690 for (; *attr; attr++)
691 {
692 switch (*attr)
693 {
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;
710 }
711 }
712 def_section (name, aval);
713 }
714
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;
721 {
722 def_file_export *dfe;
723
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
729
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;
739 }
740
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;
748 {
749 char *buf = 0;
750
751 if (dllext != NULL)
752 {
753 buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2);
754 sprintf (buf, "%s.%s", module, dllext);
755 module = buf;
756 }
757
758 def_file_add_import (def, name, module, ordinal, internal_name);
759 if (buf)
760 free (buf);
761 }
762
763 static void
764 def_version (major, minor)
765 int major;
766 int minor;
767 {
768 def->version_major = major;
769 def->version_minor = minor;
770 }
771
772 static void
773 def_directive (str)
774 char *str;
775 {
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);
781 }
782
783 static int
784 def_error (err)
785 const char *err;
786 {
787 einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err);
788
789 return 0;
790 }
791
792
793 /*****************************************************************************
794 Lexical Scanner
795 *****************************************************************************/
796
797 #undef TRACE
798 #define TRACE 0
799
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;
804
805 static void
806 put_buf (c)
807 char c;
808 {
809 if (bufptr == buflen)
810 {
811 buflen += 50; /* overly reasonable, eh? */
812 if (buffer)
813 buffer = (char *) xrealloc (buffer, buflen + 1);
814 else
815 buffer = (char *) xmalloc (buflen + 1);
816 }
817 buffer[bufptr++] = c;
818 buffer[bufptr] = 0; /* not optimal, but very convenient */
819 }
820
821 static struct
822 {
823 char *name;
824 int token;
825 }
826 tokens[] =
827 {
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 }
850 };
851
852 static int
853 def_getc ()
854 {
855 int rv;
856 if (lex_parse_string)
857 {
858 if (lex_parse_string >= lex_parse_string_end)
859 rv = EOF;
860 else
861 rv = *lex_parse_string++;
862 }
863 else
864 {
865 rv = fgetc (the_file);
866 }
867 if (rv == '\n')
868 saw_newline = 1;
869 return rv;
870 }
871
872 static int
873 def_ungetc (c)
874 int c;
875 {
876 if (lex_parse_string)
877 {
878 lex_parse_string--;
879 return c;
880 }
881 else
882 return ungetc (c, the_file);
883 }
884
885 static int
886 def_lex ()
887 {
888 int c, i, q;
889
890 if (lex_forced_token)
891 {
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;
898 }
899
900 c = def_getc ();
901
902 /* trim leading whitespace */
903 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
904 c = def_getc ();
905
906 if (c == EOF)
907 {
908 #if TRACE
909 printf ("lex: EOF\n");
910 #endif
911 return 0;
912 }
913
914 if (saw_newline && c == ';')
915 {
916 do
917 {
918 c = def_getc ();
919 }
920 while (c != EOF && c != '\n');
921 if (c == '\n')
922 return def_lex ();
923 return 0;
924 }
925 /* must be something else */
926 saw_newline = 0;
927
928 if (isdigit (c))
929 {
930 bufptr = 0;
931 while (c != EOF && (isxdigit (c) || (c == 'x')))
932 {
933 put_buf (c);
934 c = def_getc ();
935 }
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;
943 }
944
945 if (isalpha (c) || strchr ("$:-_?", c))
946 {
947 bufptr = 0;
948 while (c != EOF && (isalnum (c) || strchr ("$:-_?/@", c)))
949 {
950 put_buf (c);
951 c = def_getc ();
952 }
953 if (c != EOF)
954 def_ungetc (c);
955 for (i = 0; tokens[i].name; i++)
956 if (strcmp (tokens[i].name, buffer) == 0)
957 {
958 #if TRACE
959 printf ("lex: `%s' is a string token\n", buffer);
960 #endif
961 return tokens[i].token;
962 }
963 #if TRACE
964 printf ("lex: `%s' returns ID\n", buffer);
965 #endif
966 yylval.id = xstrdup (buffer);
967 return ID;
968 }
969
970 if (c == '\'' || c == '"')
971 {
972 q = c;
973 c = def_getc ();
974 bufptr = 0;
975 while (c != EOF && c != q)
976 {
977 put_buf (c);
978 c = def_getc ();
979 }
980 yylval.id = xstrdup (buffer);
981 #if TRACE
982 printf ("lex: `%s' returns ID\n", buffer);
983 #endif
984 return ID;
985 }
986
987 if (c == '=' || c == '.' || c == '@' || c == ',')
988 {
989 #if TRACE
990 printf ("lex: `%c' returns itself\n", c);
991 #endif
992 return c;
993 }
994
995 if (c == '\n')
996 {
997 linenumber++;
998 saw_newline = 1;
999 }
1000
1001 /*printf ("lex: 0x%02x ignored\n", c); */
1002 return def_lex ();
1003 }
This page took 0.048631 seconds and 5 git commands to generate.