Fixed an include
[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,
fd846434 83"FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
2fa0b342
DHW
84"SECTIONS",SECTIONS,
85"FILL",FILL,
86"STARTUP",STARTUP,
fd846434 87"OUTPUT_FORMAT",OUTPUT_FORMAT,
2fa0b342
DHW
88"HLL",HLL,
89"SYSLIB",SYSLIB,
90"FLOAT",FLOAT,
91"LONG", LONG,
92"SHORT", SHORT,
93"BYTE", BYTE,
94"NOFLOAT",NOFLOAT,
95"o",ORIGIN,
96"org",ORIGIN,
97"l", LENGTH,
98"len", LENGTH,
990,0};
100unsigned int lineno;
101extern boolean hex_mode;
102FILE *ldlex_input_stack;
103static unsigned int have_pushback;
104#define NPUSHBACK 10
105int pushback[NPUSHBACK];
106int thischar;
107extern char *ldfile_input_filename;
1418c83b 108int donehash = 0;
2fa0b342
DHW
109int
110lex_input()
111{
2fa0b342 112 if (have_pushback > 0)
1418c83b
SC
113 {
114 have_pushback --;
115 return thischar = pushback[have_pushback];
116 }
2fa0b342
DHW
117 if (ldlex_input_stack) {
118 thischar = fgetc(ldlex_input_stack);
119
120 if (thischar == EOF) {
121 fclose(ldlex_input_stack);
122 ldlex_input_stack = (FILE *)NULL;
123 ldfile_input_filename = (char *)NULL;
1418c83b
SC
124 /* First char after script eof is a @ so that we can tell the grammer
125 that we've eft */
126 thischar = '@';
2fa0b342
DHW
127
128 }
129 }
130 else if (command_line && *command_line) {
131 thischar = *(command_line++);
132 }
1418c83b
SC
133 else {
134 thischar = 0;
135 }
2fa0b342 136 if(thischar == '\t') thischar = ' ';
7ca04d28 137 if (thischar == '\n') { thischar = ' '; lineno++; }
2fa0b342
DHW
138 return thischar ;
139}
140
141void
142lex_unput(c)
143int c;
144{
145 if (have_pushback > NPUSHBACK) {
146 info("%F%P Too many pushbacks\n");
147 }
148
149 pushback[have_pushback] = c;
150 have_pushback ++;
151}
152
153
154 int
155yywrap()
156 { return 1; }
157/*VARARGS*/
158
159void
160allprint(x)
161int x;
162{
163fprintf(yyout,"%d",x);
164}
165
166void
167sprint(x)
168char *x;
169{
170fprintf(yyout,"%s",x);
171}
172
173int thischar;
174
175void parse_line(arg)
176char *arg;
177{
178 command_line = arg;
179 have_pushback = 0;
180 yyparse();
181}
182
183
184
185void
186parse_args(ac, av)
187int ac;
188char **av;
189{
190 char *p;
191 int i;
192 size_t size = 0;
193 char *dst;
194 debug = 1;
195 for (i= 1; i < ac; i++) {
196 size += strlen(av[i]) + 2;
197 }
198 dst = p = (char *)ldmalloc(size + 2);
199/* Put a space arount each option */
200
201
202 for (i =1; i < ac; i++) {
203
204 unsigned int s = strlen(av[i]);
205 *dst++ = ' ';
206 memcpy(dst, av[i], s);
207 dst[s] = ' ';
208 dst += s + 1;
209 }
210 *dst = 0;
211 parse_line(p);
212
213 free(p);
214
215
216}
217
218long number(text, base)
219char *text;
220int base;
221{
1418c83b 222 unsigned long l = 0;
2fa0b342
DHW
223 char *p;
224 for (p = text; *p != 0; p++) {
225 if (*p == 'K') {
226 l =l * 1024;
227 }
228 else if(*p== 'M') {
229 l =l * 1024 * 1024;
230 }
231 else {
232 l =l * base;
233 if (isdigit(*p)) {
234 l += *p - '0';
235 }
236 else if (islower(*p)) {
237 l += *p - 'a' + 10;
238 }
239 else {
240 l += *p - 'A' + 10;
241 }
242 }
243 }
244 return l;
245}
246%}
247
248%a 4000
249%o 5000
1418c83b 250FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=]
2fa0b342
DHW
251FILENAME {FILENAMECHAR}+
252
253
254WHITE [ \t]+
255
256%%
2fa0b342 257
1418c83b
SC
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; }
2fa0b342
DHW
282"\ -l"{FILENAME} {
283 yylval.name = buystring(yytext+3);
284 return OPTION_l;
285 }
286
287"\ -L"{FILENAME} {
288 yylval.name = buystring(yytext+3);
289 return OPTION_L;
290 }
1418c83b 291"\ -Ttext\ " {
2fa0b342
DHW
292 yylval.name = ".text";
293 return OPTION_Texp;
294 }
1418c83b 295"\ -Tdata\ " {
2fa0b342
DHW
296 yylval.name = ".data";
297 return OPTION_Texp;
298 }
1418c83b 299"\ -Tbss\ " {
2fa0b342
DHW
300 yylval.name = ".bss";
301 return OPTION_Texp;
302 }
303
304"\ -T"{FILENAME} {
305 yylval.name = buystring(yytext+3);
306 return OPTION_Tfile;
307 }
1418c83b 308"\ -T\ " {
2fa0b342
DHW
309 return OPTION_T;
310 }
311
7ca04d28
SC
312"\ -F"{FILENAME} {
313 return OPTION_F;
314 }
1418c83b 315"\ -F\ " {
7ca04d28
SC
316 return OPTION_F;
317 }
318
2fa0b342
DHW
319"\ -A"{FILENAME} {
320 yylval.name = buystring(yytext+3);
321 return OPTION_Aarch;
322 }
323" " { }
324"<<=" { RTOKEN(LSHIFTEQ);}
325">>=" { RTOKEN(RSHIFTEQ);}
326"||" { RTOKEN(OROR);}
327"==" { RTOKEN(EQ);}
328"!=" { RTOKEN(NE);}
329">=" { RTOKEN(GE);}
330"<=" { RTOKEN(LE);}
331"<<" { RTOKEN(LSHIFT);}
332">>" { RTOKEN(RSHIFT);}
333"+=" { RTOKEN(PLUSEQ);}
334"-=" { RTOKEN(MINUSEQ);}
335"*=" { RTOKEN(MULTEQ);}
336"/=" { RTOKEN(DIVEQ);}
337"&=" { RTOKEN(ANDEQ);}
338"|=" { RTOKEN(OREQ);}
2fa0b342
DHW
339"&&" { RTOKEN(ANDAND);}
340">" { RTOKEN('>');}
341"," { RTOKEN(',');}
342"&" { RTOKEN('&');}
343"|" { RTOKEN('|');}
344"~" { RTOKEN('~');}
345"!" { RTOKEN('!');}
346"?" { RTOKEN('?');}
347"*" { RTOKEN('*');}
348"%" { RTOKEN('%');}
349"<" { RTOKEN('<');}
2fa0b342
DHW
350">" { RTOKEN('>');}
351"}" { RTOKEN('}') ; }
352"{" { RTOKEN('{'); }
353")" { RTOKEN(')');}
354"(" { RTOKEN('(');}
355"]" { RTOKEN(']');}
356"[" { RTOKEN('[');}
357":" { RTOKEN(':'); }
fd846434 358";" { RTOKEN('\;');}
2fa0b342 359"-" { RTOKEN('-');}
1418c83b 360
2fa0b342
DHW
361
362
363"/*" {
364 while (1) {
365 int ch;
366 ch = input();
367 while (ch != '*') {
2fa0b342
DHW
368 ch = input();
369 }
370
371
372
373 if (input() == '/') {
374 break;
375 }
376 unput(yytext[yyleng-1]);
377 }
378}
379
380"\""[^\"]*"\"" {
381
382 yylval.name = buystring(yytext+1);
383 yylval.name[yyleng-2] = 0; /* Fry final quote */
384 return NAME;
385}
2fa0b342
DHW
386
387"\#"{WHITE}*{FILENAMECHAR}+ {
388 char *p = yytext+1;
389 while(*p ==' ' || *p == '\t') p++;
390 yylval.name = buystring(p);
391 return NAME;
392}
7ca04d28 393{FILENAMECHAR} {
2fa0b342 394
7ca04d28
SC
395 boolean loop = false;
396 /*
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
1418c83b 400 setting ldlang_in_script when we are expecting a symbol, so that
7ca04d28
SC
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.
404
1418c83b
SC
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:
407 __start=.;
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.
413 (later)
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.
7ca04d28
SC
417 */
418 int ch;
2fa0b342 419 keyword_type *k;
1418c83b 420
ac004870
SC
421 if ((hex_mode && isxdigit(yytext[0]))
422 ||
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') {
428 base = 8;
1418c83b 429 }
ac004870
SC
430 ch = input();
431 while (isxdigit(ch)
432 || ch == 'x'
433 || ch == 'X'
434 || ch == 'M'
435 )
436 {
437 if (ch == 'x' || ch == 'X') {
438 base = 16;
439 start = yytext + yyleng;
440 }
441 else {
442 yytext[yyleng++] = ch;
443 }
444 ch = input();
445 }
1418c83b
SC
446 yytext[yyleng] = 0;
447 unput(ch);
ac004870 448 yylval.integer = number(start, base);
1418c83b
SC
449 return INT;
450 }
451
452 if (ldfile_input_filename) {
453 /* We're inside a file */
454 if (yytext[0]== '=') {
455 RTOKEN('=');
456 }
457 }
458
459
460
ac004870
SC
461 /* Otherwise we only notice special things if were in an
462 expression */
1418c83b 463
7ca04d28
SC
464 if (ldgram_in_expression) {
465 if (yytext[0] != '/' || ldgram_in_defsym == false) {
466 switch (yytext[0]) {
467 case '/': RTOKEN('/');
1418c83b 468 case '=': RTOKEN('=');
7ca04d28
SC
469 case '+': RTOKEN('+');
470 case '-': RTOKEN('-');
471 }
2fa0b342 472 }
2fa0b342
DHW
473 }
474
7ca04d28
SC
475 ch = input();
476 while (true)
477 {
1418c83b 478 if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ) {
7ca04d28
SC
479 yytext[yyleng++] = ch;
480 }
ac004870
SC
481 else if (ch == '=' && ldgram_in_script) {
482 /* An = within a script is always taken to be an operator */
483 break;
484 }
1418c83b 485 else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') {
7ca04d28
SC
486 if (ldgram_in_expression) break;
487 yytext[yyleng++] = ch;
488 }
489 else
490 break;
491 ch = input();
492 }
493
2fa0b342
DHW
494 yytext[yyleng] = 0;
495 unput(ch);
1418c83b
SC
496 /* Filenames of just =signs are tokens */
497 if (yyleng == 1 && yytext[0] == '=') {
498 RTOKEN('=');
499 }
2fa0b342
DHW
500 for(k = keywords; k ->name != (char *)NULL; k++) {
501
502 if (strcmp(k->name, yytext)==0) {
503 yylval.token = k->value;
504 return k->value;
505 }
506 }
507 yylval.name = buystring(yytext);
508 return NAME;
509}
510
511
512
513
514
515%%
This page took 0.044703 seconds and 4 git commands to generate.