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