1 %
{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 #include "libiberty.h"
25 #include "safe-ctype.h"
33 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
35 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
36 as well as gratuitiously global symbol names, so we can have multiple
37 yacc generated parsers in ld. Note that these are only the variables
38 produced by yacc. If other parser generators (bison, byacc, etc) produce
39 additional global names that conflict at link time, then those parser
40 generators need to be fixed instead of adding those names to this list. */
42 #define yymaxdepth def_maxdepth
43 #define yyparse def_parse
45 #define yyerror def_error
46 #define yylval def_lval
47 #define yychar def_char
48 #define yydebug def_debug
49 #define yypact def_pact
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
62 #define yy_yys def_yys
63 #define yystate def_state
66 #define yy_yyv def_yyv
68 #define yylloc def_lloc
69 #define yyreds def_reds /* With YYDEBUG defined. */
70 #define yytoks def_toks /* With YYDEBUG defined. */
71 #define yylhs def_yylhs
72 #define yylen def_yylen
73 #define yydefred def_yydefred
74 #define yydgoto def_yydgoto
75 #define yysindex def_yysindex
76 #define yyrindex def_yyrindex
77 #define yygindex def_yygindex
78 #define yytable def_yytable
79 #define yycheck def_yycheck
81 static void def_description
(const char *);
82 static void def_exports
(const char *, const char *, int, int, const char *);
83 static void def_heapsize
(int, int);
84 static void def_import
(const char *, const char *, const char *, const char *,
86 static void def_image_name
(const char *, int, int);
87 static void def_section
(const char *, int);
88 static void def_section_alt
(const char *, const char *);
89 static void def_stacksize
(int, int);
90 static void def_version
(int, int);
91 static void def_directive
(char *);
92 static void def_aligncomm
(char *str
, int align
);
93 static int def_parse
(void);
94 static int def_error
(const char *);
95 static int def_lex
(void);
97 static int lex_forced_token
= 0;
98 static const char *lex_parse_string
= 0;
99 static const char *lex_parse_string_end
= 0;
109 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
110 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
111 %token PRIVATEU PRIVATEL ALIGNCOMM
112 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
114 %token
<digits
> DIGITS
115 %type
<number
> NUMBER
116 %type
<digits
> opt_digits
117 %type
<number
> opt_base opt_ordinal
118 %type
<number
> attr attr_list opt_number exp_opt_list exp_opt
119 %type
<id
> opt_name opt_equal_name dot_name anylang_id opt_id
120 %type
<id
> opt_equalequal_name
129 NAME opt_name opt_base
{ def_image_name
($2, $3, 0); }
130 | LIBRARY opt_name opt_base
{ def_image_name
($2, $3, 1); }
131 | DESCRIPTION ID
{ def_description
($2);}
132 | STACKSIZE_K NUMBER opt_number
{ def_stacksize
($2, $3);}
133 | HEAPSIZE NUMBER opt_number
{ def_heapsize
($2, $3);}
134 | CODE attr_list
{ def_section
("CODE", $2);}
135 | DATAU attr_list
{ def_section
("DATA", $2);}
139 | VERSIONK NUMBER
{ def_version
($2, 0);}
140 | VERSIONK NUMBER
'.' NUMBER
{ def_version
($2, $4);}
141 | DIRECTIVE ID
{ def_directive
($2);}
142 | ALIGNCOMM anylang_id
',' NUMBER
{ def_aligncomm
($2, $4);}
153 /* The opt_comma is necessary to support both the usual
154 DEF file syntax as well as .drectve syntax which
155 mandates <expsym>,<expoptlist>. */
156 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
157 { def_exports
($1, $2, $3, $5, $7); }
160 /* The opt_comma is necessary to support both the usual
161 DEF file syntax as well as .drectve syntax which
162 allows for comma separated opt list. */
163 exp_opt opt_comma exp_opt_list
{ $$
= $1 |
$3; }
168 | NONAMEL
{ $$
= 1; }
169 | CONSTANTU
{ $$
= 2; }
170 | CONSTANTL
{ $$
= 2; }
173 | PRIVATEU
{ $$
= 8; }
174 | PRIVATEL
{ $$
= 8; }
182 ID
'=' ID
'.' ID
'.' ID opt_equalequal_name
183 { def_import
($1, $3, $5, $7, -1, $8); }
184 | ID
'=' ID
'.' ID
'.' NUMBER opt_equalequal_name
185 { def_import
($1, $3, $5, 0, $7, $8); }
186 | ID
'=' ID
'.' ID opt_equalequal_name
187 { def_import
($1, $3, 0, $5, -1, $6); }
188 | ID
'=' ID
'.' NUMBER opt_equalequal_name
189 { def_import
($1, $3, 0, 0, $5, $6); }
190 | ID
'.' ID
'.' ID opt_equalequal_name
191 { def_import
( 0, $1, $3, $5, -1, $6); }
192 | ID
'.' ID opt_equalequal_name
193 { def_import
( 0, $1, 0, $3, -1, $4); }
202 ID attr_list
{ def_section
($1, $2);}
203 | ID ID
{ def_section_alt
($1, $2);}
207 attr_list opt_comma attr
{ $$
= $1 |
$3; }
215 opt_number: ',' NUMBER
{ $$
=$2;}
226 opt_name: ID
{ $$
= $1; }
229 char *name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
230 sprintf
(name
, "%s.%s", $1, $3);
236 opt_equalequal_name: EQUAL ID
{ $$
= $2; }
241 '@' NUMBER
{ $$
= $2;}
246 '=' dot_name
{ $$
= $2; }
250 opt_base: BASE
'=' NUMBER
{ $$
= $3;}
254 dot_name: ID
{ $$
= $1; }
257 char *name
= xmalloc
(strlen
($1) + 1 + strlen
($3) + 1);
258 sprintf
(name
, "%s.%s", $1, $3);
263 anylang_id: ID
{ $$
= $1; }
264 | anylang_id
'.' opt_digits opt_id
266 char *id
= xmalloc
(strlen
($1) + 1 + strlen
($3) + strlen
($4) + 1);
267 sprintf
(id
, "%s.%s%s", $1, $3, $4);
272 opt_digits: DIGITS
{ $$
= $1; }
276 opt_id: ID
{ $$
= $1; }
280 NUMBER: DIGITS
{ $$
= strtoul
($1, 0, 0); }
284 /*****************************************************************************
286 *****************************************************************************/
288 static FILE *the_file
;
289 static const char *def_filename
;
290 static int linenumber
;
291 static def_file
*def
;
292 static int saw_newline
;
296 struct directive
*next
;
301 static struct directive
*directives
= 0;
304 def_file_empty
(void)
306 def_file
*rv
= xmalloc
(sizeof
(def_file
));
307 memset
(rv
, 0, sizeof
(def_file
));
309 rv
->base_address
= (bfd_vma
) -1;
310 rv
->stack_reserve
= rv
->stack_commit
= -1;
311 rv
->heap_reserve
= rv
->heap_commit
= -1;
312 rv
->version_major
= rv
->version_minor
= -1;
317 def_file_parse
(const char *filename
, def_file
*add_to
)
321 the_file
= fopen
(filename
, "r");
322 def_filename
= filename
;
335 def
= def_file_empty
();
348 for
(d
= directives
; d
; d
= d
->next
)
351 printf
("Adding directive %08x `%s'\n", d
->name
, d
->name
);
353 def_file_add_directive
(def
, d
->name
, d
->len
);
360 def_file_free
(def_file
*fdef
)
368 if
(fdef
->description
)
369 free
(fdef
->description
);
371 if
(fdef
->section_defs
)
373 for
(i
= 0; i
< fdef
->num_section_defs
; i
++)
375 if
(fdef
->section_defs
[i
].name
)
376 free
(fdef
->section_defs
[i
].name
);
377 if
(fdef
->section_defs
[i
].class
)
378 free
(fdef
->section_defs
[i
].class
);
380 free
(fdef
->section_defs
);
385 for
(i
= 0; i
< fdef
->num_exports
; i
++)
387 if
(fdef
->exports
[i
].internal_name
388 && fdef
->exports
[i
].internal_name
!= fdef
->exports
[i
].name
)
389 free
(fdef
->exports
[i
].internal_name
);
390 if
(fdef
->exports
[i
].name
)
391 free
(fdef
->exports
[i
].name
);
392 if
(fdef
->exports
[i
].its_name
)
393 free
(fdef
->exports
[i
].its_name
);
395 free
(fdef
->exports
);
400 for
(i
= 0; i
< fdef
->num_imports
; i
++)
402 if
(fdef
->imports
[i
].internal_name
403 && fdef
->imports
[i
].internal_name
!= fdef
->imports
[i
].name
)
404 free
(fdef
->imports
[i
].internal_name
);
405 if
(fdef
->imports
[i
].name
)
406 free
(fdef
->imports
[i
].name
);
407 if
(fdef
->imports
[i
].its_name
)
408 free
(fdef
->imports
[i
].its_name
);
410 free
(fdef
->imports
);
413 while
(fdef
->modules
)
415 def_file_module
*m
= fdef
->modules
;
417 fdef
->modules
= fdef
->modules
->next
;
421 while
(fdef
->aligncomms
)
423 def_file_aligncomm
*c
= fdef
->aligncomms
;
425 fdef
->aligncomms
= fdef
->aligncomms
->next
;
426 free
(c
->symbol_name
);
433 #ifdef DEF_FILE_PRINT
435 def_file_print
(FILE *file
, def_file
*fdef
)
439 fprintf
(file
, ">>>> def_file at 0x%08x\n", fdef
);
441 fprintf
(file
, " name: %s\n", fdef
->name ? fdef
->name
: "(unspecified)");
442 if
(fdef
->is_dll
!= -1)
443 fprintf
(file
, " is dll: %s\n", fdef
->is_dll ?
"yes" : "no");
444 if
(fdef
->base_address
!= (bfd_vma
) -1)
445 fprintf
(file
, " base address: 0x%08x\n", fdef
->base_address
);
446 if
(fdef
->description
)
447 fprintf
(file
, " description: `%s'\n", fdef
->description
);
448 if
(fdef
->stack_reserve
!= -1)
449 fprintf
(file
, " stack reserve: 0x%08x\n", fdef
->stack_reserve
);
450 if
(fdef
->stack_commit
!= -1)
451 fprintf
(file
, " stack commit: 0x%08x\n", fdef
->stack_commit
);
452 if
(fdef
->heap_reserve
!= -1)
453 fprintf
(file
, " heap reserve: 0x%08x\n", fdef
->heap_reserve
);
454 if
(fdef
->heap_commit
!= -1)
455 fprintf
(file
, " heap commit: 0x%08x\n", fdef
->heap_commit
);
457 if
(fdef
->num_section_defs
> 0)
459 fprintf
(file
, " section defs:\n");
461 for
(i
= 0; i
< fdef
->num_section_defs
; i
++)
463 fprintf
(file
, " name: `%s', class: `%s', flags:",
464 fdef
->section_defs
[i
].name
, fdef
->section_defs
[i
].class
);
465 if
(fdef
->section_defs
[i
].flag_read
)
466 fprintf
(file
, " R");
467 if
(fdef
->section_defs
[i
].flag_write
)
468 fprintf
(file
, " W");
469 if
(fdef
->section_defs
[i
].flag_execute
)
470 fprintf
(file
, " X");
471 if
(fdef
->section_defs
[i
].flag_shared
)
472 fprintf
(file
, " S");
473 fprintf
(file
, "\n");
477 if
(fdef
->num_exports
> 0)
479 fprintf
(file
, " exports:\n");
481 for
(i
= 0; i
< fdef
->num_exports
; i
++)
483 fprintf
(file
, " name: `%s', int: `%s', ordinal: %d, flags:",
484 fdef
->exports
[i
].name
, fdef
->exports
[i
].internal_name
,
485 fdef
->exports
[i
].ordinal
);
486 if
(fdef
->exports
[i
].flag_private
)
487 fprintf
(file
, " P");
488 if
(fdef
->exports
[i
].flag_constant
)
489 fprintf
(file
, " C");
490 if
(fdef
->exports
[i
].flag_noname
)
491 fprintf
(file
, " N");
492 if
(fdef
->exports
[i
].flag_data
)
493 fprintf
(file
, " D");
494 fprintf
(file
, "\n");
498 if
(fdef
->num_imports
> 0)
500 fprintf
(file
, " imports:\n");
502 for
(i
= 0; i
< fdef
->num_imports
; i
++)
504 fprintf
(file
, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
505 fdef
->imports
[i
].internal_name
,
506 fdef
->imports
[i
].module
,
507 fdef
->imports
[i
].name
,
508 fdef
->imports
[i
].ordinal
);
512 if
(fdef
->version_major
!= -1)
513 fprintf
(file
, " version: %d.%d\n", fdef
->version_major
, fdef
->version_minor
);
515 fprintf
(file
, "<<<< def_file at 0x%08x\n", fdef
);
520 def_file_add_export
(def_file
*fdef
,
521 const char *external_name
,
522 const char *internal_name
,
524 const char *its_name
)
527 int max_exports
= ROUND_UP
(fdef
->num_exports
, 32);
529 if
(fdef
->num_exports
>= max_exports
)
531 max_exports
= ROUND_UP
(fdef
->num_exports
+ 1, 32);
533 fdef
->exports
= xrealloc
(fdef
->exports
,
534 max_exports
* sizeof
(def_file_export
));
536 fdef
->exports
= xmalloc
(max_exports
* sizeof
(def_file_export
));
538 e
= fdef
->exports
+ fdef
->num_exports
;
539 memset
(e
, 0, sizeof
(def_file_export
));
540 if
(internal_name
&& !external_name
)
541 external_name
= internal_name
;
542 if
(external_name
&& !internal_name
)
543 internal_name
= external_name
;
544 e
->name
= xstrdup
(external_name
);
545 e
->internal_name
= xstrdup
(internal_name
);
546 e
->its_name
= (its_name ? xstrdup
(its_name
) : NULL
);
547 e
->ordinal
= ordinal
;
553 def_get_module
(def_file
*fdef
, const char *name
)
557 for
(s
= fdef
->modules
; s
; s
= s
->next
)
558 if
(strcmp
(s
->name
, name
) == 0)
564 static def_file_module
*
565 def_stash_module
(def_file
*fdef
, const char *name
)
569 if
((s
= def_get_module
(fdef
, name
)) != NULL
)
571 s
= xmalloc
(sizeof
(def_file_module
) + strlen
(name
));
572 s
->next
= fdef
->modules
;
575 strcpy
(s
->name
, name
);
580 def_file_add_import
(def_file
*fdef
,
584 const char *internal_name
,
585 const char *its_name
)
588 int max_imports
= ROUND_UP
(fdef
->num_imports
, 16);
590 if
(fdef
->num_imports
>= max_imports
)
592 max_imports
= ROUND_UP
(fdef
->num_imports
+1, 16);
595 fdef
->imports
= xrealloc
(fdef
->imports
,
596 max_imports
* sizeof
(def_file_import
));
598 fdef
->imports
= xmalloc
(max_imports
* sizeof
(def_file_import
));
600 i
= fdef
->imports
+ fdef
->num_imports
;
601 memset
(i
, 0, sizeof
(def_file_import
));
603 i
->name
= xstrdup
(name
);
605 i
->module
= def_stash_module
(fdef
, module
);
606 i
->ordinal
= ordinal
;
608 i
->internal_name
= xstrdup
(internal_name
);
610 i
->internal_name
= i
->name
;
611 i
->its_name
= (its_name ? xstrdup
(its_name
) : NULL
);
624 { "-heap", HEAPSIZE
},
625 { "-stack", STACKSIZE_K
},
626 { "-attr", SECTIONS
},
627 { "-export", EXPORTS
},
628 { "-aligncomm", ALIGNCOMM
},
633 def_file_add_directive
(def_file
*my_def
, const char *param
, int len
)
635 def_file
*save_def
= def
;
636 const char *pend
= param
+ len
;
637 char * tend
= (char *) param
;
645 && (ISSPACE
(*param
) ||
*param
== '\n' ||
*param
== 0))
651 /* Scan forward until we encounter any of:
652 - the end of the buffer
653 - the start of a new option
654 - a newline seperating options
655 - a NUL seperating options. */
656 for
(tend
= (char *) (param
+ 1);
658 && !(ISSPACE
(tend
[-1]) && *tend
== '-')
659 && *tend
!= '\n' && *tend
!= 0);
663 for
(i
= 0; diropts
[i
].param
; i
++)
665 len
= strlen
(diropts
[i
].param
);
667 if
(tend
- param
>= len
668 && strncmp
(param
, diropts
[i
].param
, len
) == 0
669 && (param
[len
] == ':' || param
[len
] == ' '))
671 lex_parse_string_end
= tend
;
672 lex_parse_string
= param
+ len
+ 1;
673 lex_forced_token
= diropts
[i
].token
;
681 if
(!diropts
[i
].param
)
687 /* xgettext:c-format */
688 einfo
(_
("Warning: .drectve `%s' unrecognized\n"), param
);
692 lex_parse_string
= 0;
699 /* Parser Callbacks. */
702 def_image_name
(const char *name
, int base
, int is_dll
)
704 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
705 to do here. We retain the output filename specified on command line. */
708 const char* image_name
= lbasename
(name
);
710 if
(image_name
!= name
)
711 einfo
("%s:%d: Warning: path components stripped from %s, '%s'\n",
712 def_filename
, linenumber
, is_dll ?
"LIBRARY" : "NAME",
716 /* Append the default suffix, if none specified. */
717 if
(strchr
(image_name
, '.') == 0)
719 const char * suffix
= is_dll ?
".dll" : ".exe";
721 def
->name
= xmalloc
(strlen
(image_name
) + strlen
(suffix
) + 1);
722 sprintf
(def
->name
, "%s%s", image_name
, suffix
);
725 def
->name
= xstrdup
(image_name
);
728 /* Honor a BASE address statement, even if LIBRARY string is empty. */
729 def
->base_address
= base
;
730 def
->is_dll
= is_dll
;
734 def_description
(const char *text
)
736 int len
= def
->description ? strlen
(def
->description
) : 0;
738 len
+= strlen
(text
) + 1;
739 if
(def
->description
)
741 def
->description
= xrealloc
(def
->description
, len
);
742 strcat
(def
->description
, text
);
746 def
->description
= xmalloc
(len
);
747 strcpy
(def
->description
, text
);
752 def_stacksize
(int reserve
, int commit
)
754 def
->stack_reserve
= reserve
;
755 def
->stack_commit
= commit
;
759 def_heapsize
(int reserve
, int commit
)
761 def
->heap_reserve
= reserve
;
762 def
->heap_commit
= commit
;
766 def_section
(const char *name
, int attr
)
769 int max_sections
= ROUND_UP
(def
->num_section_defs
, 4);
771 if
(def
->num_section_defs
>= max_sections
)
773 max_sections
= ROUND_UP
(def
->num_section_defs
+1, 4);
775 if
(def
->section_defs
)
776 def
->section_defs
= xrealloc
(def
->section_defs
,
777 max_sections
* sizeof
(def_file_import
));
779 def
->section_defs
= xmalloc
(max_sections
* sizeof
(def_file_import
));
781 s
= def
->section_defs
+ def
->num_section_defs
;
782 memset
(s
, 0, sizeof
(def_file_section
));
783 s
->name
= xstrdup
(name
);
793 def
->num_section_defs
++;
797 def_section_alt
(const char *name
, const char *attr
)
801 for
(; *attr
; attr
++)
823 def_section
(name
, aval
);
827 def_exports
(const char *external_name
,
828 const char *internal_name
,
831 const char *its_name
)
833 def_file_export
*dfe
;
835 if
(!internal_name
&& external_name
)
836 internal_name
= external_name
;
838 printf
("def_exports, ext=%s int=%s\n", external_name
, internal_name
);
841 dfe
= def_file_add_export
(def
, external_name
, internal_name
, ordinal
,
844 dfe
->flag_noname
= 1;
846 dfe
->flag_constant
= 1;
850 dfe
->flag_private
= 1;
854 def_import
(const char *internal_name
,
859 const char *its_name
)
862 const char *ext
= dllext ? dllext
: "dll";
864 buf
= xmalloc
(strlen
(module
) + strlen
(ext
) + 2);
865 sprintf
(buf
, "%s.%s", module
, ext
);
868 def_file_add_import
(def
, name
, module
, ordinal
, internal_name
, its_name
);
874 def_version
(int major
, int minor
)
876 def
->version_major
= major
;
877 def
->version_minor
= minor
;
881 def_directive
(char *str
)
883 struct directive
*d
= xmalloc
(sizeof
(struct directive
));
885 d
->next
= directives
;
887 d
->name
= xstrdup
(str
);
888 d
->len
= strlen
(str
);
892 def_aligncomm
(char *str
, int align
)
894 def_file_aligncomm
*c
= xmalloc
(sizeof
(def_file_aligncomm
));
896 c
->symbol_name
= xstrdup
(str
);
897 c
->alignment
= (unsigned int) align
;
899 c
->next
= def
->aligncomms
;
904 def_error
(const char *err
)
906 einfo
("%P: %s:%d: %s\n",
907 def_filename ? def_filename
: "<unknown-file>", linenumber
, err
);
912 /* Lexical Scanner. */
917 /* Never freed, but always reused as needed, so no real leak. */
918 static char *buffer
= 0;
919 static int buflen
= 0;
920 static int bufptr
= 0;
925 if
(bufptr
== buflen
)
927 buflen
+= 50; /* overly reasonable, eh? */
929 buffer
= xrealloc
(buffer
, buflen
+ 1);
931 buffer
= xmalloc
(buflen
+ 1);
933 buffer
[bufptr
++] = c
;
934 buffer
[bufptr
] = 0; /* not optimal, but very convenient. */
946 { "CONSTANT", CONSTANTU
},
947 { "constant", CONSTANTL
},
950 { "DESCRIPTION", DESCRIPTION
},
951 { "DIRECTIVE", DIRECTIVE
},
952 { "EXECUTE", EXECUTE
},
953 { "EXPORTS", EXPORTS
},
954 { "HEAPSIZE", HEAPSIZE
},
955 { "IMPORTS", IMPORTS
},
956 { "LIBRARY", LIBRARY
},
958 { "NONAME", NONAMEU
},
959 { "noname", NONAMEL
},
960 { "PRIVATE", PRIVATEU
},
961 { "private", PRIVATEL
},
963 { "SECTIONS", SECTIONS
},
964 { "SEGMENTS", SECTIONS
},
965 { "SHARED", SHARED
},
966 { "STACKSIZE", STACKSIZE_K
},
967 { "VERSION", VERSIONK
},
977 if
(lex_parse_string
)
979 if
(lex_parse_string
>= lex_parse_string_end
)
982 rv
= *lex_parse_string
++;
986 rv
= fgetc
(the_file
);
996 if
(lex_parse_string
)
1002 return ungetc
(c
, the_file
);
1010 if
(lex_forced_token
)
1012 i
= lex_forced_token
;
1013 lex_forced_token
= 0;
1015 printf
("lex: forcing token %d\n", i
);
1022 /* Trim leading whitespace. */
1023 while
(c
!= EOF
&& (c
== ' ' || c
== '\t') && saw_newline
)
1029 printf
("lex: EOF\n");
1034 if
(saw_newline
&& c
== ';')
1040 while
(c
!= EOF
&& c
!= '\n');
1046 /* Must be something else. */
1052 while
(c
!= EOF
&& (ISXDIGIT
(c
) ||
(c
== 'x')))
1059 yylval.digits
= xstrdup
(buffer
);
1061 printf
("lex: `%s' returns DIGITS\n", buffer
);
1066 if
(ISALPHA
(c
) || strchr
("$:-_?@", c
))
1075 if
(ISBLANK
(c
) ) /* '@' followed by whitespace. */
1077 else if
(ISDIGIT
(c
)) /* '@' followed by digit. */
1083 printf
("lex: @ returns itself\n");
1087 while
(c
!= EOF
&& (ISALNUM
(c
) || strchr
("$:-_?/@<>", c
)))
1094 if
(ISALPHA
(q
)) /* Check for tokens. */
1096 for
(i
= 0; tokens
[i
].name
; i
++)
1097 if
(strcmp
(tokens
[i
].name
, buffer
) == 0)
1100 printf
("lex: `%s' is a string token\n", buffer
);
1102 return tokens
[i
].token
;
1106 printf
("lex: `%s' returns ID\n", buffer
);
1108 yylval.id
= xstrdup
(buffer
);
1112 if
(c
== '\'' || c
== '"')
1118 while
(c
!= EOF
&& c
!= q
)
1123 yylval.id
= xstrdup
(buffer
);
1125 printf
("lex: `%s' returns ID\n", buffer
);
1136 printf
("lex: `==' returns EQUAL\n");
1142 printf
("lex: `=' returns itself\n");
1146 if
(c
== '.' || c
== ',')
1149 printf
("lex: `%c' returns itself\n", c
);
1160 /*printf ("lex: 0x%02x ignored\n", c); */