Yet more diffs due to my incompetence.
[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 extern 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 "MAP",MAP,
78 "SIZEOF",SIZEOF,
79 "TARGET",TARGET_K,
80 "SEARCH_DIR",SEARCH_DIR,
81 "OUTPUT",OUTPUT,
82 "INPUT",INPUT,
83 "DEFINED",DEFINED,
84 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
85 "FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
86 "SECTIONS",SECTIONS,
87 "FILL",FILL,
88 "STARTUP",STARTUP,
89 "OUTPUT_FORMAT",OUTPUT_FORMAT,
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 eft */
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 ENDSCRIPT; }
273 "\ -defsym\ " { return OPTION_defsym; }
274 "\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
275 "\ -format\ " { return OPTION_format; }
276 "\ -n\ "                { return OPTION_n; }
277 "\ -r\ "                { return OPTION_r; }
278 "\ -Ur\ "               { return OPTION_Ur; }
279 "\ -o\ "                { return OPTION_o; }
280 "\ -g\ "                { return OPTION_g; }
281 "\ -e\ "                { return OPTION_e; }
282 "\ -b\ "                { return OPTION_b; }
283 "\ -dc\ "               { return OPTION_dc; }
284 "\ -dp\ "               { return OPTION_dp; }
285 "\ -d\ "                { return OPTION_d; }
286 "\ -v\ "                { return OPTION_v; }
287 "\ -M\ "                { return OPTION_M; }
288 "\ -t\ "                { return OPTION_t; }
289 "\ -X\ "                { return OPTION_X; }
290 "\ -x\ "                { return OPTION_x; }
291 "\ -c\ "                { return OPTION_c; }
292 "\ -R\ "                { return OPTION_R; }
293 "\ -u\ "                { return OPTION_u; }
294 "\ -s\ "            { return OPTION_s; }
295 "\ -S\ "            { return OPTION_S; }
296 "\ -l"{FILENAME} {
297                 yylval.name = buystring(yytext+3);
298                 return OPTION_l; 
299         }
300
301 "\ -L"{FILENAME}        { 
302                 yylval.name = buystring(yytext+3);
303                 return OPTION_L; 
304          }
305 "\ -Ttext\ "  {
306                  yylval.name = ".text";
307                  return OPTION_Texp;
308                }
309 "\ -Tdata\ "  {
310                  yylval.name = ".data";
311                  return OPTION_Texp;
312                }
313 "\ -Tbss\ "  {
314                  yylval.name = ".bss";
315                  return OPTION_Texp;
316                }
317
318 "\ -T"{FILENAME}  {
319                  yylval.name = buystring(yytext+3);
320                  return OPTION_Tfile;
321                }
322 "\ -T\ "          {
323                  return OPTION_T;
324                }
325
326 "\ -F"{FILENAME}  {
327                  return OPTION_F;
328                }
329 "\ -F\ "          {
330                  return OPTION_F;
331                }
332
333 "\ -A"{FILENAME} {
334                  yylval.name = buystring(yytext+3);
335                  return OPTION_Aarch;
336                }
337
338 " "             { if (ldgram_had_equals == true) ldgram_in_defsym = false; }
339 "<<="           { RTOKEN(LSHIFTEQ);}
340 ">>="           { RTOKEN(RSHIFTEQ);}
341 "||"            { RTOKEN(OROR);}
342 "=="            { RTOKEN(EQ);}
343 "!="            { RTOKEN(NE);}
344 ">="            { RTOKEN(GE);}
345 "<="            { RTOKEN(LE);}
346 "<<"            { RTOKEN(LSHIFT);}
347 ">>"            { RTOKEN(RSHIFT);}
348 "+="            { RTOKEN(PLUSEQ);}
349 "-="            { RTOKEN(MINUSEQ);}
350 "*="            { RTOKEN(MULTEQ);}
351 "/="            { RTOKEN(DIVEQ);}
352 "&="            { RTOKEN(ANDEQ);}
353 "|="            { RTOKEN(OREQ);}
354 "&&"            { RTOKEN(ANDAND);}
355 ">"             { RTOKEN('>');}
356 ","             { RTOKEN(',');}
357 "&"             { RTOKEN('&');}
358 "|"             { RTOKEN('|');}
359 "~"             { RTOKEN('~');}
360 "!"             { RTOKEN('!');}
361 "?"             { RTOKEN('?');}
362 "*"             { RTOKEN('*');}
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
376
377
378 "/*"            { 
379   while (1) {
380     int ch;
381     ch = input();
382     while (ch != '*') {
383       ch = input();
384     }
385
386
387
388     if (input() == '/') {
389       break;
390     }
391     unput(yytext[yyleng-1]);
392   }
393 }
394
395 "\""[^\"]*"\"" {
396
397   yylval.name = buystring(yytext+1);
398   yylval.name[yyleng-2] = 0; /* Fry final quote */
399   return NAME;
400 }
401
402 {FILENAMECHAR} {
403
404   boolean loop = false;
405   int ch;
406   keyword_type *k;
407
408   /* If we're in hex mode (only after a -T) then all we can see are numbers
409      hex digit we see will be a number. */
410
411   if (hex_mode) {       
412     return number(16, 16);
413   }
414
415   /* If we're in a defsym then all things starting with a digit are in
416      hex */
417
418   if (isdigit(yytext[0]) && ldgram_in_defsym) {
419     return number(16,16);
420   }
421
422
423   /* Otherwise if we're in a script we will parse the numbers
424      normally */
425
426   if (ldgram_in_script == true && isdigit(yytext[0])) {
427     return number(8,10);
428   }
429
430   /* Anywhere not in a script or defsym, an opertor is part of a
431      filename, except / and, which is an operator when on its own */
432   if (ldgram_in_script == true|| ldgram_in_defsym == true) {
433
434     switch (yytext[0]) {
435       case '*': RTOKEN('*');
436
437       case '=': {
438         ldgram_had_equals = true;
439         RTOKEN('=');
440       }
441         break;
442      case '/': {
443        if (ldgram_in_defsym) RTOKEN('/');
444      }
445         break;
446       case '+': RTOKEN('+');
447       case '-': RTOKEN('-');
448       case '!': RTOKEN('!');
449       case '~': RTOKEN('~');
450       }
451     }
452
453
454 /* Otherwise this must be a file or a symbol name, and it will continue to be a
455    filename until we get to something strange. In scripts operator looking
456    things  are taken to be operators, except /, which will be left
457  */
458   ch = input();
459   while (true)
460       {
461         if (ldgram_in_defsym == true) {
462           switch (ch) {
463           case '*': 
464           case '=': 
465           case '+': 
466           case '/': 
467           case '-': 
468           case '!': 
469           case '~': 
470             goto quit;
471           }
472           
473         }
474         
475         if (isalpha(ch) || isdigit(ch) || ch == '.'  || ch == '_'  ||
476             ch == '/' || ch == '.' || ch == '+' || ch == '-' || ch =='=') {
477           yytext[yyleng++] = ch;
478         }
479         else 
480           break;
481         ch = input();
482       }
483  quit:;
484   yytext[yyleng] = 0;
485   unput(ch);
486
487   for(k = keywords; k ->name != (char *)NULL; k++) {
488     if (strcmp(k->name, yytext)==0) {
489       yylval.token = k->value;
490       return k->value;
491     }
492   }
493   yylval.name = buystring(yytext);
494   return NAME;
495 }
496
497
498
499
500
501 %%