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
49 extern boolean ldgram_in_expression;
50 extern boolean ldgram_in_defsym;
51 extern boolean ldgram_in_script;
52 static char *command_line;
61 #define RTOKEN(x) { yylval.token = x; return x; }
62 keyword_type keywords[] =
69 "SUBSECTION_ALIGN",SUBSECTION_ALIGN,
73 "ENDSCRIPT", ENDSCRIPT,
78 "SEARCH_DIR",SEARCH_DIR,
82 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
83 "FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
87 "OUTPUT_FORMAT",OUTPUT_FORMAT,
101 extern boolean hex_mode;
102 FILE *ldlex_input_stack;
103 static unsigned int have_pushback;
105 int pushback[NPUSHBACK];
107 extern char *ldfile_input_filename;
112 if (have_pushback > 0)
115 return thischar = pushback[have_pushback];
117 if (ldlex_input_stack) {
118 thischar = fgetc(ldlex_input_stack);
120 if (thischar == EOF) {
121 fclose(ldlex_input_stack);
122 ldlex_input_stack = (FILE *)NULL;
123 ldfile_input_filename = (char *)NULL;
124 /* First char after script eof is a @ so that we can tell the grammer
130 else if (command_line && *command_line) {
131 thischar = *(command_line++);
136 if(thischar == '\t') thischar = ' ';
137 if (thischar == '\n') { thischar = ' '; lineno++; }
145 if (have_pushback > NPUSHBACK) {
146 info("%F%P Too many pushbacks\n");
149 pushback[have_pushback] = c;
163 fprintf(yyout,"%d",x);
170 fprintf(yyout,"%s",x);
195 for (i= 1; i < ac; i++) {
196 size += strlen(av[i]) + 2;
198 dst = p = (char *)ldmalloc(size + 2);
199 /* Put a space arount each option */
202 for (i =1; i < ac; i++) {
204 unsigned int s = strlen(av[i]);
206 memcpy(dst, av[i], s);
218 long number(text, base)
224 for (p = text; *p != 0; p++) {
236 else if (islower(*p)) {
250 FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=]
251 FILENAME {FILENAMECHAR}+
258 "@" { return ENDSCRIPT; }
259 "\ -defsym\ " { return OPTION_defsym; }
260 "\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
261 "\ -format\ " { return OPTION_format; }
262 "\ -n\ " { return OPTION_n; }
263 "\ -r\ " { return OPTION_r; }
264 "\ -Ur\ " { return OPTION_Ur; }
265 "\ -o\ " { return OPTION_o; }
266 "\ -g\ " { return OPTION_g; }
267 "\ -e\ " { return OPTION_e; }
268 "\ -b\ " { return OPTION_b; }
269 "\ -dc\ " { return OPTION_dc; }
270 "\ -dp\ " { return OPTION_dp; }
271 "\ -d\ " { return OPTION_d; }
272 "\ -v\ " { return OPTION_v; }
273 "\ -M\ " { return OPTION_M; }
274 "\ -t\ " { return OPTION_t; }
275 "\ -X\ " { return OPTION_X; }
276 "\ -x\ " { return OPTION_x; }
277 "\ -c\ " { return OPTION_c; }
278 "\ -R\ " { return OPTION_R; }
279 "\ -u\ " { return OPTION_u; }
280 "\ -s\ " { return OPTION_s; }
281 "\ -S\ " { return OPTION_S; }
283 yylval.name = buystring(yytext+3);
288 yylval.name = buystring(yytext+3);
292 yylval.name = ".text";
296 yylval.name = ".data";
300 yylval.name = ".bss";
305 yylval.name = buystring(yytext+3);
320 yylval.name = buystring(yytext+3);
324 "<<=" { RTOKEN(LSHIFTEQ);}
325 ">>=" { RTOKEN(RSHIFTEQ);}
326 "||" { RTOKEN(OROR);}
331 "<<" { RTOKEN(LSHIFT);}
332 ">>" { RTOKEN(RSHIFT);}
333 "+=" { RTOKEN(PLUSEQ);}
334 "-=" { RTOKEN(MINUSEQ);}
335 "*=" { RTOKEN(MULTEQ);}
336 "/=" { RTOKEN(DIVEQ);}
337 "&=" { RTOKEN(ANDEQ);}
338 "|=" { RTOKEN(OREQ);}
339 "&&" { RTOKEN(ANDAND);}
351 "}" { RTOKEN('}') ; }
373 if (input() == '/') {
376 unput(yytext[yyleng-1]);
382 yylval.name = buystring(yytext+1);
383 yylval.name[yyleng-2] = 0; /* Fry final quote */
387 "\#"{WHITE}*{FILENAMECHAR}+ {
389 while(*p ==' ' || *p == '\t') p++;
390 yylval.name = buystring(p);
395 boolean loop = false;
397 Tokenize a name, this is really pain, since a name can be a
398 filename or a symbol name. filenames have slashes and stuff whist
399 in an expression those things are seperate tokens. We hack this by
400 setting ldlang_in_script when we are expecting a symbol, so that
401 [/+-] get taken to be seperate tokens. An extra gotcha is
402 expressions after defsyms, we only allow +s and -s in a defsym
403 expression, so -defsym foo=bar+9 /file.o is parsed ok.
405 The more I think about this the more I hate it. I've got a problem
406 now with the = sign, what should I do ? imagine:
408 You'd think that was pretty unambiguous wouldn't you. Well it's
409 not since __start=. is (at the moment) a perfectly valid
410 filename. And in some cases we don't know what's going on. I'm
411 going to have to hack this. If we see a '/' before the = sign then
412 we say we've got an = in a filename, otherwise it's an operator.
414 That's it, I've had enough. From now on, an =s on a command line
415 will be taken to be part of a file name unless its in a defsym,
416 and an = in a file will be taken to be an operator.
421 if ((hex_mode && isxdigit(yytext[0]))
423 (isdigit(yytext[0]) && (ldgram_in_expression == true || ldgram_in_script == true))) {
424 char *start = yytext;
425 unsigned int base = 10;
426 if (hex_mode == true) base = 16;
427 if (yytext[0] == '0') {
437 if (ch == 'x' || ch == 'X') {
439 start = yytext + yyleng;
442 yytext[yyleng++] = ch;
448 yylval.integer = number(start, base);
452 if (ldfile_input_filename) {
453 /* We're inside a file */
454 if (yytext[0]== '=') {
461 /* Otherwise we only notice special things if were in an
464 if (ldgram_in_expression) {
465 if (yytext[0] != '/' || ldgram_in_defsym == false) {
467 case '/': RTOKEN('/');
468 case '=': RTOKEN('=');
469 case '+': RTOKEN('+');
470 case '-': RTOKEN('-');
478 if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ) {
479 yytext[yyleng++] = ch;
481 else if (ch == '=' && ldgram_in_script) {
482 /* An = within a script is always taken to be an operator */
485 else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') {
486 if (ldgram_in_expression) break;
487 yytext[yyleng++] = ch;
496 /* Filenames of just =signs are tokens */
497 if (yyleng == 1 && yytext[0] == '=') {
500 for(k = keywords; k ->name != (char *)NULL; k++) {
502 if (strcmp(k->name, yytext)==0) {
503 yylval.token = k->value;
507 yylval.name = buystring(yytext);