2 /* Copyright (C) 1991 Free Software Foundation, Inc.
4 This file is part of GLD, the Gnu Linker.
6 GLD is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GLD is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GLD; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
40 #include "ldgram.tab.h"
45 #define input lex_input
46 #define unput lex_unput
50 static boolean ldgram_in_defsym;
51 static boolean ldgram_had_equals;
52 extern boolean ldgram_in_script;
53 static char *command_line;
62 #define RTOKEN(x) { yylval.token = x; return x; }
63 keyword_type keywords[] =
71 "SUBSECTION_ALIGN",SUBSECTION_ALIGN,
75 "ENDSCRIPT", ENDSCRIPT,
77 "sizeof_headers",SIZEOF_HEADERS,
78 "SIZEOF_HEADERS",SIZEOF_HEADERS,
82 "SEARCH_DIR",SEARCH_DIR,
86 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
87 "FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
91 "OUTPUT_FORMAT",OUTPUT_FORMAT,
92 "OUTPUT_ARCH", OUTPUT_ARCH,
106 extern boolean hex_mode;
107 FILE *ldlex_input_stack;
108 static unsigned int have_pushback;
111 int pushback[NPUSHBACK];
113 extern char *ldfile_input_filename;
118 if (have_pushback > 0)
121 return thischar = pushback[have_pushback];
123 if (ldlex_input_stack) {
124 thischar = fgetc(ldlex_input_stack);
126 if (thischar == EOF) {
127 fclose(ldlex_input_stack);
128 ldlex_input_stack = (FILE *)NULL;
129 ldfile_input_filename = (char *)NULL;
130 /* First char after script eof is a @ so that we can tell the grammer
136 else if (command_line && *command_line) {
137 thischar = *(command_line++);
142 if(thischar == '\t') thischar = ' ';
143 if (thischar == '\n') { thischar = ' '; lineno++; }
151 if (have_pushback > NPUSHBACK) {
152 info("%F%P Too many pushbacks\n");
155 pushback[have_pushback] = c;
169 fprintf(yyout,"%d",x);
176 fprintf(yyout,"%s",x);
201 for (i= 1; i < ac; i++) {
202 size += strlen(av[i]) + 2;
204 dst = p = (char *)ldmalloc(size + 2);
205 /* Put a space arount each option */
208 for (i =1; i < ac; i++) {
210 unsigned int s = strlen(av[i]);
212 memcpy(dst, av[i], s);
225 DEFUN(number,(default_if_zero,base),
226 int default_if_zero AND
232 base = default_if_zero;
247 case '0': case '1': case '2': case '3': case '4':
248 case '5': case '6': case '7': case '8': case '9':
249 l = l * base + ch - '0';
251 case 'a': case 'b': case 'c' : case 'd' : case 'e': case 'f':
252 l =l *base + ch - 'a' + 10;
254 case 'A': case 'B': case 'C' : case 'D' : case 'E': case 'F':
255 l =l *base + ch - 'A' + 10;
269 FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=]
270 FILENAME {FILENAMECHAR}+
276 "\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; }
277 "\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
278 "\ -sort_common\ " { return OPTION_sort_common;}
279 "\ -format\ " { return OPTION_format; }
280 "\ -n\ " { return OPTION_n; }
281 "\ -r\ " { return OPTION_r; }
282 "\ -i\ " { return OPTION_r; }
283 "\ -Ur\ " { return OPTION_Ur; }
284 "\ -o\ " { return OPTION_o; }
285 "\ -g\ " { return OPTION_g; }
286 "\ -e\ " { return OPTION_e; }
287 "\ -b\ " { return OPTION_b; }
288 "\ -dc\ " { return OPTION_dc; }
289 "\ -dp\ " { return OPTION_dp; }
290 "\ -d\ " { return OPTION_d; }
291 "\ -v\ " { return OPTION_v; }
292 "\ -M\ " { return OPTION_M; }
293 "\ -t\ " { return OPTION_t; }
294 "\ -X\ " { return OPTION_X; }
295 "\ -x\ " { return OPTION_x; }
296 "\ -c\ " { return OPTION_c; }
297 "\ -R\ " { return OPTION_R; }
298 "\ -u\ " { return OPTION_u; }
299 "\ -s\ " { return OPTION_s; }
300 "\ -S\ " { return OPTION_S; }
301 "\ -B{FILENAME}\ " { /* Ignored */ }
303 yylval.name = buystring(yytext+3);
308 yylval.name = buystring(yytext+3);
312 yylval.name = ".text";
316 yylval.name = ".data";
320 yylval.name = ".bss";
325 yylval.name = buystring(yytext+3);
340 yylval.name = buystring(yytext+3);
345 if (ldgram_had_equals == true) {
346 ldgram_in_defsym = false;
347 ldgram_had_equals = false;
350 "<<=" { RTOKEN(LSHIFTEQ);}
351 ">>=" { RTOKEN(RSHIFTEQ);}
352 "||" { RTOKEN(OROR);}
357 "<<" { RTOKEN(LSHIFT);}
358 ">>" { RTOKEN(RSHIFT);}
359 "+=" { RTOKEN(PLUSEQ);}
360 "-=" { RTOKEN(MINUSEQ);}
361 "*=" { RTOKEN(MULTEQ);}
362 "/=" { RTOKEN(DIVEQ);}
363 "&=" { RTOKEN(ANDEQ);}
364 "|=" { RTOKEN(OREQ);}
365 "&&" { RTOKEN(ANDAND);}
377 "}" { RTOKEN('}') ; }
399 if (input() == '/') {
402 unput(yytext[yyleng-1]);
408 yylval.name = buystring(yytext+1);
409 yylval.name[yyleng-2] = 0; /* Fry final quote */
415 boolean loop = false;
419 /* If we're in hex mode (only after a -T) then all we can see are numbers
420 hex digit we see will be a number. */
423 return number(16, 16);
426 /* If we're in a defsym then all things starting with a digit are in
429 if (isdigit(yytext[0]) && ldgram_in_defsym) {
430 return number(16,16);
434 /* Otherwise if we're in a script we will parse the numbers
437 if (ldgram_in_script == true && isdigit(yytext[0])) {
441 /* Anywhere not in a script or defsym, an opertor is part of a
442 filename, except / and, which is an operator when on its own */
443 if (ldgram_in_script == true|| ldgram_in_defsym == true) {
446 case '*': RTOKEN('*');
449 ldgram_had_equals = true;
454 if (ldgram_in_defsym) RTOKEN('/');
457 case '+': RTOKEN('+');
458 case '-': RTOKEN('-');
459 case '!': RTOKEN('!');
460 case '~': RTOKEN('~');
465 /* Otherwise this must be a file or a symbol name, and it will continue to be a
466 filename until we get to something strange. In scripts operator looking
467 things are taken to be operators, except /, which will be left
472 if (ldgram_in_defsym == true) {
485 if(ldgram_in_script == true) {
497 if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ||
498 ch == '/' || ch == '.' || ch == '+' || ch == '-' || ch =='=') {
499 yytext[yyleng++] = ch;
509 for(k = keywords; k ->name != (char *)NULL; k++) {
510 if (strcmp(k->name, yytext)==0) {
511 yylval.token = k->value;
515 yylval.name = buystring(yytext);