Now handles multiple host and targets.
[deliverable/binutils-gdb.git] / ld / ldlex.l
CommitLineData
2fa0b342
DHW
1%{
2/* Copyright (C) 1991 Free Software Foundation, Inc.
3
4This file is part of GLD, the Gnu Linker.
5
6GLD is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GLD is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GLD; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/*
21 * $Id$
7ca04d28 22
2fa0b342
DHW
23 *
24*/
25
26
27
28/*SUPPRESS 529*/
29/*SUPPRESS 26*/
30/*SUPPRESS 29*/
1418c83b 31#define LEXDEBUG 0
2fa0b342
DHW
32#include "sysdep.h"
33#include "bfd.h"
34
35#include <ctype.h>
36#include "ldlex.h"
37
38#include "ld.h"
39#include "ldexp.h"
40#include "ldgram.tab.h"
41#include "ldmisc.h"
42
43#undef input
44#undef unput
45#define input lex_input
46#define unput lex_unput
47int debug;
7ca04d28
SC
48
49extern boolean ldgram_in_expression;
50extern boolean ldgram_in_defsym;
1418c83b 51extern boolean ldgram_in_script;
2fa0b342
DHW
52static char *command_line;
53
54extern int fgetc();
55extern int yyparse();
56
57typedef struct {
58 char *name;
59int value;
60} keyword_type;
61#define RTOKEN(x) { yylval.token = x; return x; }
62keyword_type keywords[] =
63{
64"MEMORY",MEMORY,
65"ORIGIN",ORIGIN,
66"BLOCK",BLOCK,
67"LENGTH",LENGTH,
68"ALIGN",ALIGN_K,
69"SUBSECTION_ALIGN",SUBSECTION_ALIGN,
70"ADDR",ADDR,
71"ENTRY",ENTRY,
1418c83b
SC
72"SCRIPT", SCRIPT,
73"ENDSCRIPT", ENDSCRIPT,
2fa0b342
DHW
74"NEXT",NEXT,
75"MAP",MAP,
76"SIZEOF",SIZEOF,
77"TARGET",TARGET_K,
78"SEARCH_DIR",SEARCH_DIR,
79"OUTPUT",OUTPUT,
80"INPUT",INPUT,
81"DEFINED",DEFINED,
82"CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
83"SECTIONS",SECTIONS,
84"FILL",FILL,
85"STARTUP",STARTUP,
86"HLL",HLL,
87"SYSLIB",SYSLIB,
88"FLOAT",FLOAT,
89"LONG", LONG,
90"SHORT", SHORT,
91"BYTE", BYTE,
92"NOFLOAT",NOFLOAT,
93"o",ORIGIN,
94"org",ORIGIN,
95"l", LENGTH,
96"len", LENGTH,
970,0};
98unsigned int lineno;
99extern boolean hex_mode;
100FILE *ldlex_input_stack;
101static unsigned int have_pushback;
102#define NPUSHBACK 10
103int pushback[NPUSHBACK];
104int thischar;
105extern char *ldfile_input_filename;
1418c83b 106int donehash = 0;
2fa0b342
DHW
107int
108lex_input()
109{
2fa0b342 110 if (have_pushback > 0)
1418c83b
SC
111 {
112 have_pushback --;
113 return thischar = pushback[have_pushback];
114 }
2fa0b342
DHW
115 if (ldlex_input_stack) {
116 thischar = fgetc(ldlex_input_stack);
117
118 if (thischar == EOF) {
119 fclose(ldlex_input_stack);
120 ldlex_input_stack = (FILE *)NULL;
121 ldfile_input_filename = (char *)NULL;
1418c83b
SC
122 /* First char after script eof is a @ so that we can tell the grammer
123 that we've eft */
124 thischar = '@';
2fa0b342
DHW
125
126 }
127 }
128 else if (command_line && *command_line) {
129 thischar = *(command_line++);
130 }
1418c83b
SC
131 else {
132 thischar = 0;
133 }
2fa0b342 134 if(thischar == '\t') thischar = ' ';
7ca04d28 135 if (thischar == '\n') { thischar = ' '; lineno++; }
2fa0b342
DHW
136 return thischar ;
137}
138
139void
140lex_unput(c)
141int c;
142{
143 if (have_pushback > NPUSHBACK) {
144 info("%F%P Too many pushbacks\n");
145 }
146
147 pushback[have_pushback] = c;
148 have_pushback ++;
149}
150
151
152 int
153yywrap()
154 { return 1; }
155/*VARARGS*/
156
157void
158allprint(x)
159int x;
160{
161fprintf(yyout,"%d",x);
162}
163
164void
165sprint(x)
166char *x;
167{
168fprintf(yyout,"%s",x);
169}
170
171int thischar;
172
173void parse_line(arg)
174char *arg;
175{
176 command_line = arg;
177 have_pushback = 0;
178 yyparse();
179}
180
181
182
183void
184parse_args(ac, av)
185int ac;
186char **av;
187{
188 char *p;
189 int i;
190 size_t size = 0;
191 char *dst;
192 debug = 1;
193 for (i= 1; i < ac; i++) {
194 size += strlen(av[i]) + 2;
195 }
196 dst = p = (char *)ldmalloc(size + 2);
197/* Put a space arount each option */
198
199
200 for (i =1; i < ac; i++) {
201
202 unsigned int s = strlen(av[i]);
203 *dst++ = ' ';
204 memcpy(dst, av[i], s);
205 dst[s] = ' ';
206 dst += s + 1;
207 }
208 *dst = 0;
209 parse_line(p);
210
211 free(p);
212
213
214}
215
216long number(text, base)
217char *text;
218int base;
219{
1418c83b 220 unsigned long l = 0;
2fa0b342
DHW
221 char *p;
222 for (p = text; *p != 0; p++) {
223 if (*p == 'K') {
224 l =l * 1024;
225 }
226 else if(*p== 'M') {
227 l =l * 1024 * 1024;
228 }
229 else {
230 l =l * base;
231 if (isdigit(*p)) {
232 l += *p - '0';
233 }
234 else if (islower(*p)) {
235 l += *p - 'a' + 10;
236 }
237 else {
238 l += *p - 'A' + 10;
239 }
240 }
241 }
242 return l;
243}
244%}
245
246%a 4000
247%o 5000
1418c83b 248FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=]
2fa0b342
DHW
249FILENAME {FILENAMECHAR}+
250
251
252WHITE [ \t]+
253
254%%
2fa0b342 255
1418c83b
SC
256"@" { return ENDSCRIPT; }
257"\ -defsym\ " { return OPTION_defsym; }
258"\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
259"\ -format\ " { return OPTION_format; }
260"\ -n\ " { return OPTION_n; }
261"\ -r\ " { return OPTION_r; }
262"\ -Ur\ " { return OPTION_Ur; }
263"\ -o\ " { return OPTION_o; }
264"\ -g\ " { return OPTION_g; }
265"\ -e\ " { return OPTION_e; }
266"\ -b\ " { return OPTION_b; }
267"\ -dc\ " { return OPTION_dc; }
268"\ -dp\ " { return OPTION_dp; }
269"\ -d\ " { return OPTION_d; }
270"\ -v\ " { return OPTION_v; }
271"\ -M\ " { return OPTION_M; }
272"\ -t\ " { return OPTION_t; }
273"\ -X\ " { return OPTION_X; }
274"\ -x\ " { return OPTION_x; }
275"\ -c\ " { return OPTION_c; }
276"\ -R\ " { return OPTION_R; }
277"\ -u\ " { return OPTION_u; }
278"\ -s\ " { return OPTION_s; }
279"\ -S\ " { return OPTION_S; }
2fa0b342
DHW
280"\ -l"{FILENAME} {
281 yylval.name = buystring(yytext+3);
282 return OPTION_l;
283 }
284
285"\ -L"{FILENAME} {
286 yylval.name = buystring(yytext+3);
287 return OPTION_L;
288 }
1418c83b 289"\ -Ttext\ " {
2fa0b342
DHW
290 yylval.name = ".text";
291 return OPTION_Texp;
292 }
1418c83b 293"\ -Tdata\ " {
2fa0b342
DHW
294 yylval.name = ".data";
295 return OPTION_Texp;
296 }
1418c83b 297"\ -Tbss\ " {
2fa0b342
DHW
298 yylval.name = ".bss";
299 return OPTION_Texp;
300 }
301
302"\ -T"{FILENAME} {
303 yylval.name = buystring(yytext+3);
304 return OPTION_Tfile;
305 }
1418c83b 306"\ -T\ " {
2fa0b342
DHW
307 return OPTION_T;
308 }
309
7ca04d28
SC
310"\ -F"{FILENAME} {
311 return OPTION_F;
312 }
1418c83b 313"\ -F\ " {
7ca04d28
SC
314 return OPTION_F;
315 }
316
2fa0b342
DHW
317"\ -A"{FILENAME} {
318 yylval.name = buystring(yytext+3);
319 return OPTION_Aarch;
320 }
321" " { }
322"<<=" { RTOKEN(LSHIFTEQ);}
323">>=" { RTOKEN(RSHIFTEQ);}
324"||" { RTOKEN(OROR);}
325"==" { RTOKEN(EQ);}
326"!=" { RTOKEN(NE);}
327">=" { RTOKEN(GE);}
328"<=" { RTOKEN(LE);}
329"<<" { RTOKEN(LSHIFT);}
330">>" { RTOKEN(RSHIFT);}
331"+=" { RTOKEN(PLUSEQ);}
332"-=" { RTOKEN(MINUSEQ);}
333"*=" { RTOKEN(MULTEQ);}
334"/=" { RTOKEN(DIVEQ);}
335"&=" { RTOKEN(ANDEQ);}
336"|=" { RTOKEN(OREQ);}
2fa0b342
DHW
337"&&" { RTOKEN(ANDAND);}
338">" { RTOKEN('>');}
339"," { RTOKEN(',');}
340"&" { RTOKEN('&');}
341"|" { RTOKEN('|');}
342"~" { RTOKEN('~');}
343"!" { RTOKEN('!');}
344"?" { RTOKEN('?');}
345"*" { RTOKEN('*');}
346"%" { RTOKEN('%');}
347"<" { RTOKEN('<');}
2fa0b342
DHW
348">" { RTOKEN('>');}
349"}" { RTOKEN('}') ; }
350"{" { RTOKEN('{'); }
351")" { RTOKEN(')');}
352"(" { RTOKEN('(');}
353"]" { RTOKEN(']');}
354"[" { RTOKEN('[');}
355":" { RTOKEN(':'); }
356";" { RTOKEN(';');}
357"-" { RTOKEN('-');}
1418c83b 358
2fa0b342
DHW
359
360
361"/*" {
362 while (1) {
363 int ch;
364 ch = input();
365 while (ch != '*') {
2fa0b342
DHW
366 ch = input();
367 }
368
369
370
371 if (input() == '/') {
372 break;
373 }
374 unput(yytext[yyleng-1]);
375 }
376}
377
378"\""[^\"]*"\"" {
379
380 yylval.name = buystring(yytext+1);
381 yylval.name[yyleng-2] = 0; /* Fry final quote */
382 return NAME;
383}
384[0][0-7KM]* {
385
386 yylval.integer = number(yytext+1, 8);
387 return INT;
388}
389
390[0-9]+[KM]? {
391 if (hex_mode == true) {
392 yylval.integer = number(yytext, 16);
393 }
394 else {
395 yylval.integer = number(yytext, 10);
396 }
397 return INT;
398}
399
4000[Xx][0-9a-fA-FKM]+ {
401
402 yylval.integer = number(yytext+2,16);
403 return INT;
404}
405
406"\#"{WHITE}*{FILENAMECHAR}+ {
407 char *p = yytext+1;
408 while(*p ==' ' || *p == '\t') p++;
409 yylval.name = buystring(p);
410 return NAME;
411}
7ca04d28 412{FILENAMECHAR} {
2fa0b342 413
7ca04d28
SC
414 boolean loop = false;
415 /*
416 Tokenize a name, this is really pain, since a name can be a
417 filename or a symbol name. filenames have slashes and stuff whist
418 in an expression those things are seperate tokens. We hack this by
1418c83b 419 setting ldlang_in_script when we are expecting a symbol, so that
7ca04d28
SC
420 [/+-] get taken to be seperate tokens. An extra gotcha is
421 expressions after defsyms, we only allow +s and -s in a defsym
422 expression, so -defsym foo=bar+9 /file.o is parsed ok.
423
1418c83b
SC
424 The more I think about this the more I hate it. I've got a problem
425 now with the = sign, what should I do ? imagine:
426 __start=.;
427 You'd think that was pretty unambiguous wouldn't you. Well it's
428 not since __start=. is (at the moment) a perfectly valid
429 filename. And in some cases we don't know what's going on. I'm
430 going to have to hack this. If we see a '/' before the = sign then
431 we say we've got an = in a filename, otherwise it's an operator.
432 (later)
433 That's it, I've had enough. From now on, an =s on a command line
434 will be taken to be part of a file name unless its in a defsym,
435 and an = in a file will be taken to be an operator.
7ca04d28
SC
436 */
437 int ch;
2fa0b342 438 keyword_type *k;
1418c83b
SC
439
440 if (hex_mode) {
441 ch = yytext[0];
442 /* Then always read a number */
443 while (isxdigit(ch)) {
444 yytext[yyleng++] = ch;
445 ch = input();
446 }
447 yytext[yyleng] = 0;
448 unput(ch);
449
450 yylval.integer = number(yytext,16);
451 return INT;
452 }
453
454 if (ldfile_input_filename) {
455 /* We're inside a file */
456 if (yytext[0]== '=') {
457 RTOKEN('=');
458 }
459 }
460
461
462
463 /* Otherwise we only notice special things if were in an
464 expression */
465
7ca04d28
SC
466 if (ldgram_in_expression) {
467 if (yytext[0] != '/' || ldgram_in_defsym == false) {
468 switch (yytext[0]) {
469 case '/': RTOKEN('/');
1418c83b 470 case '=': RTOKEN('=');
7ca04d28
SC
471 case '+': RTOKEN('+');
472 case '-': RTOKEN('-');
473 }
2fa0b342 474 }
2fa0b342
DHW
475 }
476
7ca04d28
SC
477 ch = input();
478 while (true)
479 {
1418c83b 480 if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ) {
7ca04d28
SC
481 yytext[yyleng++] = ch;
482 }
1418c83b
SC
483else if (ch == '=' && ldgram_in_script) {
484/* An = within a script is always taken to be an operator */
485break;
486}
487 else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') {
7ca04d28
SC
488 if (ldgram_in_expression) break;
489 yytext[yyleng++] = ch;
490 }
491 else
492 break;
493 ch = input();
494 }
495
2fa0b342
DHW
496 yytext[yyleng] = 0;
497 unput(ch);
1418c83b
SC
498 /* Filenames of just =signs are tokens */
499 if (yyleng == 1 && yytext[0] == '=') {
500 RTOKEN('=');
501 }
2fa0b342
DHW
502 for(k = keywords; k ->name != (char *)NULL; k++) {
503
504 if (strcmp(k->name, yytext)==0) {
505 yylval.token = k->value;
506 return k->value;
507 }
508 }
509 yylval.name = buystring(yytext);
510 return NAME;
511}
512
513
514
515
516
517%%
This page took 0.067829 seconds and 4 git commands to generate.