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;
52 static char *command_line;
61 #define RTOKEN(x) { yylval.token = x; return x; }
62 keyword_type keywords[] =
69 "SUBSECTION_ALIGN",SUBSECTION_ALIGN,
76 "SEARCH_DIR",SEARCH_DIR,
80 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
97 extern boolean hex_mode;
98 FILE *ldlex_input_stack;
99 static unsigned int have_pushback;
101 int pushback[NPUSHBACK];
103 extern char *ldfile_input_filename;
110 if (have_pushback > 0)
113 return thischar = pushback[have_pushback];
115 if (ldlex_input_stack) {
116 thischar = fgetc(ldlex_input_stack);
118 if (thischar == EOF) {
119 fclose(ldlex_input_stack);
120 ldlex_input_stack = (FILE *)NULL;
121 ldfile_input_filename = (char *)NULL;
122 thischar = lex_input();
126 else if (command_line && *command_line) {
127 thischar = *(command_line++);
130 if(thischar == '\t') thischar = ' ';
131 if (thischar == '\n') { thischar = ' '; lineno++; }
139 if (have_pushback > NPUSHBACK) {
140 info("%F%P Too many pushbacks\n");
143 pushback[have_pushback] = c;
157 fprintf(yyout,"%d",x);
164 fprintf(yyout,"%s",x);
189 for (i= 1; i < ac; i++) {
190 size += strlen(av[i]) + 2;
192 dst = p = (char *)ldmalloc(size + 2);
193 /* Put a space arount each option */
196 for (i =1; i < ac; i++) {
198 unsigned int s = strlen(av[i]);
200 memcpy(dst, av[i], s);
212 long number(text, base)
218 for (p = text; *p != 0; p++) {
230 else if (islower(*p)) {
244 FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+]
245 FILENAME {FILENAMECHAR}+
253 "\ -defsym" { return OPTION_defsym; }
254 "\ -noinhibit_exec" { return OPTION_noinhibit_exec; }
255 "\ -format" { return OPTION_format; }
256 "\ -n" { return OPTION_n; }
257 "\ -r" { return OPTION_r; }
258 "\ -Ur" { return OPTION_Ur; }
259 "\ -o" { return OPTION_o; }
260 "\ -g" { return OPTION_g; }
261 "\ -e" { return OPTION_e; }
262 "\ -b" { return OPTION_b; }
263 "\ -dc" { return OPTION_dc; }
264 "\ -dp" { return OPTION_dp; }
265 "\ -d" { return OPTION_d; }
266 "\ -v" { return OPTION_v; }
267 "\ -M" { return OPTION_M; }
268 "\ -t" { return OPTION_t; }
269 "\ -X" { return OPTION_X; }
270 "\ -x" { return OPTION_x; }
271 "\ -c" { return OPTION_c; }
272 "\ -s" { return OPTION_s; }
273 "\ -S" { return OPTION_S; }
275 yylval.name = buystring(yytext+3);
280 yylval.name = buystring(yytext+3);
284 yylval.name = ".text";
288 yylval.name = ".data";
292 yylval.name = ".bss";
297 yylval.name = buystring(yytext+3);
312 yylval.name = buystring(yytext+3);
316 "<<=" { RTOKEN(LSHIFTEQ);}
317 ">>=" { RTOKEN(RSHIFTEQ);}
318 "||" { RTOKEN(OROR);}
323 "<<" { RTOKEN(LSHIFT);}
324 ">>" { RTOKEN(RSHIFT);}
325 "+=" { RTOKEN(PLUSEQ);}
326 "-=" { RTOKEN(MINUSEQ);}
327 "*=" { RTOKEN(MULTEQ);}
328 "/=" { RTOKEN(DIVEQ);}
329 "&=" { RTOKEN(ANDEQ);}
330 "|=" { RTOKEN(OREQ);}
332 "&&" { RTOKEN(ANDAND);}
345 "}" { RTOKEN('}') ; }
367 if (input() == '/') {
370 unput(yytext[yyleng-1]);
376 yylval.name = buystring(yytext+1);
377 yylval.name[yyleng-2] = 0; /* Fry final quote */
382 yylval.integer = number(yytext+1, 8);
387 if (hex_mode == true) {
388 yylval.integer = number(yytext, 16);
391 yylval.integer = number(yytext, 10);
396 0[Xx][0-9a-fA-FKM]+ {
398 yylval.integer = number(yytext+2,16);
402 "\#"{WHITE}*{FILENAMECHAR}+ {
404 while(*p ==' ' || *p == '\t') p++;
405 yylval.name = buystring(p);
410 boolean loop = false;
412 Tokenize a name, this is really pain, since a name can be a
413 filename or a symbol name. filenames have slashes and stuff whist
414 in an expression those things are seperate tokens. We hack this by
415 setting lang_in_expression when we are expecting a symbol, so that
416 [/+-] get taken to be seperate tokens. An extra gotcha is
417 expressions after defsyms, we only allow +s and -s in a defsym
418 expression, so -defsym foo=bar+9 /file.o is parsed ok.
423 if (ldgram_in_expression) {
424 if (yytext[0] != '/' || ldgram_in_defsym == false) {
426 case '/': RTOKEN('/');
427 case '+': RTOKEN('+');
428 case '-': RTOKEN('-');
436 if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_') {
437 yytext[yyleng++] = ch;
439 else if (ch == '+' || ch == '-' || ch == '/') {
440 if (ldgram_in_expression) break;
441 yytext[yyleng++] = ch;
451 for(k = keywords; k ->name != (char *)NULL; k++) {
453 if (strcmp(k->name, yytext)==0) {
454 yylval.token = k->value;
458 yylval.name = buystring(yytext);