*** empty log message ***
[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 "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 "OUTPUT_ARCH", OUTPUT_ARCH,
91 "HLL",HLL,
92 "SYSLIB",SYSLIB,
93 "FLOAT",FLOAT,
94 "LONG", LONG,
95 "SHORT", SHORT,
96 "BYTE", BYTE,
97 "NOFLOAT",NOFLOAT,
98 "o",ORIGIN,
99 "org",ORIGIN,
100 "l", LENGTH,
101 "len", LENGTH,
102 0,0};
103 unsigned int lineno;
104 extern boolean hex_mode;
105 FILE *ldlex_input_stack;
106 static unsigned int have_pushback;
107
108 #define NPUSHBACK 10
109 int pushback[NPUSHBACK];
110 int thischar;
111 extern char *ldfile_input_filename;
112 int donehash = 0;
113 int
114 lex_input()
115 {
116   if (have_pushback > 0) 
117       {
118         have_pushback --;
119         return thischar = pushback[have_pushback];
120       }
121   if (ldlex_input_stack) {
122     thischar = fgetc(ldlex_input_stack);
123
124     if (thischar == EOF)  {
125       fclose(ldlex_input_stack);
126       ldlex_input_stack = (FILE *)NULL;
127       ldfile_input_filename = (char *)NULL;
128       /* First char after script eof is a @ so that we can tell the grammer
129          that we've left */
130       thischar = '@';
131
132     }
133   }
134   else if (command_line && *command_line)  {
135     thischar = *(command_line++);
136   }
137   else {
138  thischar = 0;
139   }
140   if(thischar == '\t') thischar = ' ';
141   if (thischar == '\n') { thischar = ' '; lineno++; }
142   return thischar ;
143 }
144
145 void
146 lex_unput(c)
147 int c;
148 {
149   if (have_pushback > NPUSHBACK) {
150     info("%F%P Too many pushbacks\n");
151   }
152
153   pushback[have_pushback] = c;
154   have_pushback ++;
155 }
156
157
158         int
159 yywrap()
160          { return 1; }
161 /*VARARGS*/
162
163 void
164 allprint(x) 
165 int x;
166 {
167 fprintf(yyout,"%d",x);
168 }
169
170 void
171 sprint(x) 
172 char *x;
173 {
174 fprintf(yyout,"%s",x);
175 }
176
177 int  thischar;
178
179 void parse_line(arg)
180 char *arg;
181 {
182   command_line = arg;
183   have_pushback = 0;
184   yyparse();
185 }
186
187
188
189 void
190 parse_args(ac, av)
191 int ac;
192 char **av;
193 {
194   char *p;
195   int i;
196   size_t size = 0;
197   char *dst;
198   debug = 1;
199   for (i= 1; i < ac; i++) {
200     size += strlen(av[i]) + 2; 
201   }
202   dst = p = (char *)ldmalloc(size + 2);
203 /* Put a space arount each option */
204
205
206   for (i =1; i < ac; i++) {
207
208     unsigned int s = strlen(av[i]);
209   *dst++ = ' ';
210     memcpy(dst, av[i], s);
211     dst[s] = ' ';
212     dst += s + 1;
213   }
214   *dst  = 0;
215   parse_line(p);
216
217   free(p);
218
219
220 }
221
222 static long 
223 DEFUN(number,(default_if_zero,base),
224       int default_if_zero AND
225       int base)
226 {
227   unsigned  long l = 0;
228   int ch = yytext[0];
229   if (ch == 0) {
230     base = default_if_zero;
231   }
232   while (1) {
233     switch (ch) {
234     case 'x':
235       base = 16;
236       break;
237     case 'k':
238     case 'K':
239       l =l * 1024;
240       break;
241     case 'm':
242     case 'M':
243       l =l * 1024 * 1024;
244       break;
245     case '0': case '1': case '2': case '3': case '4':
246     case '5': case '6': case '7': case '8': case '9':
247       l = l * base + ch - '0';
248       break;
249     case 'a': case 'b': case 'c' : case 'd' : case 'e': case 'f':
250       l =l *base + ch - 'a' + 10;
251       break;
252     case 'A': case 'B': case 'C' : case 'D' : case 'E': case 'F':
253       l =l *base + ch - 'A' + 10;
254       break;
255     default:
256       unput(ch);
257       yylval.integer = l;
258       return INT;
259     }
260 ch = input();
261   }
262 }
263 %}
264
265 %a 4000
266 %o 5000
267 FILENAMECHAR    [a-zA-Z0-9\/\.\-\_\+\=]
268 FILENAME        {FILENAMECHAR}+
269 WHITE           [ \t]+ 
270
271 %%
272
273 "@" { return '}'; }
274 "\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; }
275 "\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
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 %%