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