7d50ccdfa03a623a856d21a3ef3b4b1d16178be5
[deliverable/binutils-gdb.git] / ld / ldlex.l
1 %{
2 /* Copyright (C) 1991 Free Software Foundation, Inc.
3
4 This file is part of GLD, the Gnu Linker.
5
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)
9 any later version.
10
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.
15
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. */
19
20 /*
21 * $Id$
22
23 *
24 */
25
26
27
28 /*SUPPRESS 529*/
29 /*SUPPRESS 26*/
30 /*SUPPRESS 29*/
31 #define LEXDEBUG 0
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
47 int debug;
48
49
50 static boolean ldgram_in_defsym;
51 static boolean ldgram_had_equals;
52 extern boolean ldgram_in_script;
53 static char *command_line;
54
55 extern int fgetc();
56 extern int yyparse();
57
58 typedef struct {
59 char *name;
60 int value;
61 } keyword_type;
62 #define RTOKEN(x) { yylval.token = x; return x; }
63 keyword_type keywords[] =
64 {
65 "/", '/',
66 "MEMORY",MEMORY,
67 "ORIGIN",ORIGIN,
68 "BLOCK",BLOCK,
69 "LENGTH",LENGTH,
70 "ALIGN",ALIGN_K,
71 "ADDR",ADDR,
72 "ENTRY",ENTRY,
73 "NEXT",NEXT,
74 "sizeof_headers",SIZEOF_HEADERS,
75 "SIZEOF_HEADERS",SIZEOF_HEADERS,
76 "MAP",MAP,
77 "SIZEOF",SIZEOF,
78 "TARGET",TARGET_K,
79 "SEARCH_DIR",SEARCH_DIR,
80 "OUTPUT",OUTPUT,
81 "INPUT",INPUT,
82 "DEFINED",DEFINED,
83 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
84 "FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
85 "SECTIONS",SECTIONS,
86 "FILL",FILL,
87 "STARTUP",STARTUP,
88 "OUTPUT_FORMAT",OUTPUT_FORMAT,
89 "OUTPUT_ARCH", OUTPUT_ARCH,
90 "HLL",HLL,
91 "SYSLIB",SYSLIB,
92 "FLOAT",FLOAT,
93 "LONG", LONG,
94 "SHORT", SHORT,
95 "BYTE", BYTE,
96 "NOFLOAT",NOFLOAT,
97 "o",ORIGIN,
98 "org",ORIGIN,
99 "l", LENGTH,
100 "len", LENGTH,
101 0,0};
102 unsigned int lineno;
103 extern boolean hex_mode;
104 FILE *ldlex_input_stack;
105 static unsigned int have_pushback;
106
107 #define NPUSHBACK 10
108 int pushback[NPUSHBACK];
109 int thischar;
110 extern char *ldfile_input_filename;
111 int donehash = 0;
112 int
113 lex_input()
114 {
115 if (have_pushback > 0)
116 {
117 have_pushback --;
118 return thischar = pushback[have_pushback];
119 }
120 if (ldlex_input_stack) {
121 thischar = fgetc(ldlex_input_stack);
122
123 if (thischar == EOF) {
124 fclose(ldlex_input_stack);
125 ldlex_input_stack = (FILE *)NULL;
126 ldfile_input_filename = (char *)NULL;
127 /* First char after script eof is a @ so that we can tell the grammer
128 that we've left */
129 thischar = '@';
130
131 }
132 }
133 else if (command_line && *command_line) {
134 thischar = *(command_line++);
135 }
136 else {
137 thischar = 0;
138 }
139 if(thischar == '\t') thischar = ' ';
140 if (thischar == '\n') { thischar = ' '; lineno++; }
141 return thischar ;
142 }
143
144 void
145 lex_unput(c)
146 int c;
147 {
148 if (have_pushback > NPUSHBACK) {
149 info("%F%P Too many pushbacks\n");
150 }
151
152 pushback[have_pushback] = c;
153 have_pushback ++;
154 }
155
156
157 int
158 yywrap()
159 { return 1; }
160 /*VARARGS*/
161
162 void
163 allprint(x)
164 int x;
165 {
166 fprintf(yyout,"%d",x);
167 }
168
169 void
170 sprint(x)
171 char *x;
172 {
173 fprintf(yyout,"%s",x);
174 }
175
176 int thischar;
177
178 void parse_line(arg)
179 char *arg;
180 {
181 command_line = arg;
182 have_pushback = 0;
183 yyparse();
184 }
185
186
187
188 void
189 parse_args(ac, av)
190 int ac;
191 char **av;
192 {
193 char *p;
194 int i;
195 size_t size = 0;
196 char *dst;
197 debug = 1;
198 for (i= 1; i < ac; i++) {
199 size += strlen(av[i]) + 2;
200 }
201 dst = p = (char *)ldmalloc(size + 2);
202 /* Put a space arount each option */
203
204
205 for (i =1; i < ac; i++) {
206
207 unsigned int s = strlen(av[i]);
208 *dst++ = ' ';
209 memcpy(dst, av[i], s);
210 dst[s] = ' ';
211 dst += s + 1;
212 }
213 *dst = 0;
214 parse_line(p);
215
216 free(p);
217
218
219 }
220
221 static long
222 DEFUN(number,(default_if_zero,base),
223 int default_if_zero AND
224 int base)
225 {
226 unsigned long l = 0;
227 int ch = yytext[0];
228 if (ch == 0) {
229 base = default_if_zero;
230 }
231 while (1) {
232 switch (ch) {
233 case 'x':
234 base = 16;
235 break;
236 case 'k':
237 case 'K':
238 l =l * 1024;
239 break;
240 case 'm':
241 case 'M':
242 l =l * 1024 * 1024;
243 break;
244 case '0': case '1': case '2': case '3': case '4':
245 case '5': case '6': case '7': case '8': case '9':
246 l = l * base + ch - '0';
247 break;
248 case 'a': case 'b': case 'c' : case 'd' : case 'e': case 'f':
249 l =l *base + ch - 'a' + 10;
250 break;
251 case 'A': case 'B': case 'C' : case 'D' : case 'E': case 'F':
252 l =l *base + ch - 'A' + 10;
253 break;
254 default:
255 unput(ch);
256 yylval.integer = l;
257 return INT;
258 }
259 ch = input();
260 }
261 }
262 %}
263
264 %a 4000
265 %o 5000
266 FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=]
267 FILENAME {FILENAMECHAR}+
268 WHITE [ \t]+
269
270 %%
271
272 "@" { return '}'; }
273 "\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; }
274 "\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
275 "\ -sort_common\ " { return OPTION_sort_common;}
276 "\ -format\ " { return OPTION_format; }
277 "\ -n\ " { return OPTION_n; }
278 "\ -r\ " { return OPTION_r; }
279 "\ -i\ " { return OPTION_r; }
280 "\ -Ur\ " { return OPTION_Ur; }
281 "\ -o\ " { return OPTION_o; }
282 "\ -g\ " { return OPTION_g; }
283 "\ -e\ " { return OPTION_e; }
284 "\ -b\ " { return OPTION_b; }
285 "\ -dc\ " { return OPTION_dc; }
286 "\ -dp\ " { return OPTION_dp; }
287 "\ -d\ " { return OPTION_d; }
288 "\ -v\ " { return OPTION_v; }
289 "\ -M\ " { return OPTION_M; }
290 "\ -t\ " { return OPTION_t; }
291 "\ -X\ " { return OPTION_X; }
292 "\ -x\ " { return OPTION_x; }
293 "\ -c\ " { return OPTION_c; }
294 "\ -R\ " { return OPTION_R; }
295 "\ -u\ " { return OPTION_u; }
296 "\ -s\ " { return OPTION_s; }
297 "\ -S\ " { return OPTION_S; }
298 "\ -B{FILENAME}\ " { /* Ignored */ }
299 "\ -l"{FILENAME} {
300 yylval.name = buystring(yytext+3);
301 return OPTION_l;
302 }
303
304 "\ -L"{FILENAME} {
305 yylval.name = buystring(yytext+3);
306 return OPTION_L;
307 }
308 "\ -Ttext\ " {
309 yylval.name = ".text";
310 return OPTION_Texp;
311 }
312 "\ -Tdata\ " {
313 yylval.name = ".data";
314 return OPTION_Texp;
315 }
316 "\ -Tbss\ " {
317 yylval.name = ".bss";
318 return OPTION_Texp;
319 }
320
321 "\ -T"{FILENAME} {
322 yylval.name = buystring(yytext+3);
323 return OPTION_Tfile;
324 }
325 "\ -T\ " {
326 return OPTION_T;
327 }
328
329 "\ -F"{FILENAME} {
330 return OPTION_F;
331 }
332 "\ -F\ " {
333 return OPTION_F;
334 }
335
336 "\ -A"{FILENAME} {
337 yylval.name = buystring(yytext+3);
338 return OPTION_Aarch;
339 }
340
341 " " {
342 if (ldgram_had_equals == true) {
343 ldgram_in_defsym = false;
344 ldgram_had_equals = false;
345 }
346 }
347 "<<=" { RTOKEN(LSHIFTEQ);}
348 ">>=" { RTOKEN(RSHIFTEQ);}
349 "||" { RTOKEN(OROR);}
350 "==" { RTOKEN(EQ);}
351 "!=" { RTOKEN(NE);}
352 ">=" { RTOKEN(GE);}
353 "<=" { RTOKEN(LE);}
354 "<<" { RTOKEN(LSHIFT);}
355 ">>" { RTOKEN(RSHIFT);}
356 "+=" { RTOKEN(PLUSEQ);}
357 "-=" { RTOKEN(MINUSEQ);}
358 "*=" { RTOKEN(MULTEQ);}
359 "/=" { RTOKEN(DIVEQ);}
360 "&=" { RTOKEN(ANDEQ);}
361 "|=" { RTOKEN(OREQ);}
362 "&&" { RTOKEN(ANDAND);}
363 ">" { RTOKEN('>');}
364 "," { RTOKEN(',');}
365 "&" { RTOKEN('&');}
366 "|" { RTOKEN('|');}
367 "~" { RTOKEN('~');}
368 "!" { RTOKEN('!');}
369 "?" { RTOKEN('?');}
370 "*" { RTOKEN('*');}
371 "%" { RTOKEN('%');}
372 "<" { RTOKEN('<');}
373 ">" { RTOKEN('>');}
374 "}" { RTOKEN('}') ; }
375 "{" { RTOKEN('{'); }
376 ")" { RTOKEN(')');}
377 "(" { RTOKEN('(');}
378 "]" { RTOKEN(']');}
379 "[" { RTOKEN('[');}
380 ":" { RTOKEN(':'); }
381 ";" { RTOKEN('\;');}
382 "-" { RTOKEN('-');}
383
384
385
386 "/*" {
387 while (1) {
388 int ch;
389 ch = input();
390 while (ch != '*') {
391 ch = input();
392 }
393
394
395
396 if (input() == '/') {
397 break;
398 }
399 unput(yytext[yyleng-1]);
400 }
401 }
402
403 "\""[^\"]*"\"" {
404
405 yylval.name = buystring(yytext+1);
406 yylval.name[yyleng-2] = 0; /* Fry final quote */
407 return NAME;
408 }
409
410 {FILENAMECHAR} {
411
412 boolean loop = false;
413 int ch;
414 keyword_type *k;
415
416 /* If we're in hex mode (only after a -T) then all we can see are numbers
417 hex digit we see will be a number. */
418
419 if (hex_mode) {
420 return number(16, 16);
421 }
422
423 /* If we're in a defsym then all things starting with a digit are in
424 hex */
425
426 if (isdigit(yytext[0]) && ldgram_in_defsym) {
427 return number(16,16);
428 }
429
430
431 /* Otherwise if we're in a script we will parse the numbers
432 normally */
433
434 if (ldgram_in_script == true && isdigit(yytext[0])) {
435 return number(8,10);
436 }
437
438 /* Anywhere not in a script or defsym, an opertor is part of a
439 filename, except / and, which is an operator when on its own */
440 if (ldgram_in_script == true|| ldgram_in_defsym == true) {
441
442 switch (yytext[0]) {
443 case '*': RTOKEN('*');
444
445 case '=': {
446 ldgram_had_equals = true;
447 RTOKEN('=');
448 }
449 break;
450 case '/': {
451 if (ldgram_in_defsym) RTOKEN('/');
452 }
453 break;
454 case '+': RTOKEN('+');
455 case '-': RTOKEN('-');
456 case '!': RTOKEN('!');
457 case '~': RTOKEN('~');
458 }
459 }
460
461
462 /* Otherwise this must be a file or a symbol name, and it will continue to be a
463 filename until we get to something strange. In scripts operator looking
464 things are taken to be operators, except /, which will be left
465 */
466 ch = input();
467 while (true)
468 {
469 if (ldgram_in_defsym == true) {
470 switch (ch) {
471 case '*':
472 case '=':
473 case '+':
474 case '/':
475 case '-':
476 case '!':
477 case '~':
478 goto quit;
479 }
480
481 }
482 if(ldgram_in_script == true) {
483 switch (ch) {
484 case '*':
485 case '=':
486 case '+':
487 case '-':
488 case '!':
489 case '~':
490 goto quit;
491 }
492 }
493
494 if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ||
495 ch == '/' || ch == '.' || ch == '+' || ch == '-' || ch =='=') {
496 yytext[yyleng++] = ch;
497 }
498 else
499 break;
500 ch = input();
501 }
502 quit:;
503 yytext[yyleng] = 0;
504 unput(ch);
505
506 for(k = keywords; k ->name != (char *)NULL; k++) {
507 if (strcmp(k->name, yytext)==0) {
508 yylval.token = k->value;
509 return k->value;
510 }
511 }
512 yylval.name = buystring(yytext);
513 return NAME;
514 }
515
516
517
518
519
520 %%
This page took 0.039396 seconds and 4 git commands to generate.