This commit was generated by cvs2svn to track changes on a CVS vendor
[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
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 extern boolean ldgram_in_expression;
50 extern boolean ldgram_in_defsym;
51
52 static char *command_line;
53
54 extern int fgetc();
55 extern int yyparse();
56
57 typedef struct {
58         char *name;     
59 int value;
60 } keyword_type;
61 #define RTOKEN(x)  {  yylval.token = x; return x; }
62 keyword_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,
72 "NEXT",NEXT,
73 "MAP",MAP,
74 "SIZEOF",SIZEOF,
75 "TARGET",TARGET_K,
76 "SEARCH_DIR",SEARCH_DIR,
77 "OUTPUT",OUTPUT,
78 "INPUT",INPUT,
79 "DEFINED",DEFINED,
80 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
81 "SECTIONS",SECTIONS,
82 "FILL",FILL,
83 "STARTUP",STARTUP,
84 "HLL",HLL,
85 "SYSLIB",SYSLIB,
86 "FLOAT",FLOAT,
87 "LONG", LONG,
88 "SHORT", SHORT,
89 "BYTE", BYTE,
90 "NOFLOAT",NOFLOAT,
91 "o",ORIGIN,
92 "org",ORIGIN,
93 "l", LENGTH,
94 "len", LENGTH,
95 0,0};
96 unsigned int lineno;
97 extern boolean hex_mode;
98 FILE *ldlex_input_stack;
99 static unsigned int have_pushback;
100 #define NPUSHBACK 10
101 int pushback[NPUSHBACK];
102 int thischar;
103 extern char *ldfile_input_filename;
104
105 int
106 lex_input()
107 {
108
109
110   if (have_pushback > 0) 
111     {
112       have_pushback --;
113       return thischar = pushback[have_pushback];
114     }
115   if (ldlex_input_stack) {
116     thischar = fgetc(ldlex_input_stack);
117
118     if (thischar == EOF)  {
119       fclose(ldlex_input_stack);
120       ldlex_input_stack = (FILE *)NULL;
121       ldfile_input_filename = (char *)NULL;
122       thischar = lex_input();
123
124     }
125   }
126   else if (command_line && *command_line)  {
127     thischar = *(command_line++);
128   }
129   else thischar = 0;
130   if(thischar == '\t') thischar = ' ';
131   if (thischar == '\n') { thischar = ' '; lineno++; }
132   return thischar ;
133 }
134
135 void
136 lex_unput(c)
137 int c;
138 {
139   if (have_pushback > NPUSHBACK) {
140     info("%F%P Too many pushbacks\n");
141   }
142
143   pushback[have_pushback] = c;
144   have_pushback ++;
145 }
146
147
148         int
149 yywrap()
150          { return 1; }
151 /*VARARGS*/
152
153 void
154 allprint(x) 
155 int x;
156 {
157 fprintf(yyout,"%d",x);
158 }
159
160 void
161 sprint(x) 
162 char *x;
163 {
164 fprintf(yyout,"%s",x);
165 }
166
167 int  thischar;
168
169 void parse_line(arg)
170 char *arg;
171 {
172   command_line = arg;
173   have_pushback = 0;
174   yyparse();
175 }
176
177
178
179 void
180 parse_args(ac, av)
181 int ac;
182 char **av;
183 {
184   char *p;
185   int i;
186   size_t size = 0;
187   char *dst;
188   debug = 1;
189   for (i= 1; i < ac; i++) {
190     size += strlen(av[i]) + 2; 
191   }
192   dst = p = (char *)ldmalloc(size + 2);
193 /* Put a space arount each option */
194
195
196   for (i =1; i < ac; i++) {
197
198     unsigned int s = strlen(av[i]);
199   *dst++ = ' ';
200     memcpy(dst, av[i], s);
201     dst[s] = ' ';
202     dst += s + 1;
203   }
204   *dst  = 0;
205   parse_line(p);
206
207   free(p);
208
209
210 }
211
212 long number(text, base)
213 char *text;
214 int base;
215 {
216 unsigned  long l = 0;
217   char *p;
218   for (p = text; *p != 0; p++) {
219     if (*p == 'K') {
220       l =l * 1024;
221     }
222     else if(*p== 'M') {
223       l =l * 1024 * 1024;
224     }
225     else {
226       l =l * base;
227       if (isdigit(*p))  {
228         l += *p - '0';
229       }
230       else if (islower(*p)) {
231         l += *p - 'a' + 10;
232       }
233       else {
234         l += *p - 'A' + 10;
235       }
236     }
237   }
238   return l;
239 }
240 %}
241
242 %a 4000
243 %o 5000
244 FILENAMECHAR    [a-zA-Z0-9\/\.\-\_\+]
245 FILENAME        {FILENAMECHAR}+
246
247
248 WHITE           [ \t]+
249
250 %%
251
252
253 "\ -defsym" { return OPTION_defsym; }
254 "\ -noinhibit_exec" { return OPTION_noinhibit_exec; }
255 "\ -format" { return OPTION_format; }
256 "\ -n"          { return OPTION_n; }
257 "\ -r"          { return OPTION_r; }
258 "\ -Ur"         { return OPTION_Ur; }
259 "\ -o"          { return OPTION_o; }
260 "\ -g"          { return OPTION_g; }
261 "\ -e"          { return OPTION_e; }
262 "\ -b"          { return OPTION_b; }
263 "\ -dc"         { return OPTION_dc; }
264 "\ -dp"         { return OPTION_dp; }
265 "\ -d"          { return OPTION_d; }
266 "\ -v"          { return OPTION_v; }
267 "\ -M"          { return OPTION_M; }
268 "\ -t"          { return OPTION_t; }
269 "\ -X"          { return OPTION_X; }
270 "\ -x"          { return OPTION_x; }
271 "\ -c"          { return OPTION_c; }
272 "\ -s"            { return OPTION_s; }
273 "\ -S"            { return OPTION_S; }
274 "\ -l"{FILENAME} {
275                 yylval.name = buystring(yytext+3);
276                 return OPTION_l; 
277         }
278
279 "\ -L"{FILENAME}        { 
280                 yylval.name = buystring(yytext+3);
281                 return OPTION_L; 
282          }
283 "\ -Ttext"  {
284                  yylval.name = ".text";
285                  return OPTION_Texp;
286                }
287 "\ -Tdata"  {
288                  yylval.name = ".data";
289                  return OPTION_Texp;
290                }
291 "\ -Tbss"  {
292                  yylval.name = ".bss";
293                  return OPTION_Texp;
294                }
295
296 "\ -T"{FILENAME}  {
297                  yylval.name = buystring(yytext+3);
298                  return OPTION_Tfile;
299                }
300 "\ -T"          {
301                  return OPTION_T;
302                }
303
304 "\ -F"{FILENAME}  {
305                  return OPTION_F;
306                }
307 "\ -F"          {
308                  return OPTION_F;
309                }
310
311 "\ -A"{FILENAME} {
312                  yylval.name = buystring(yytext+3);
313                  return OPTION_Aarch;
314                }
315 " " { }
316 "<<="           { RTOKEN(LSHIFTEQ);}
317 ">>="           { RTOKEN(RSHIFTEQ);}
318 "||"            { RTOKEN(OROR);}
319 "=="            { RTOKEN(EQ);}
320 "!="            { RTOKEN(NE);}
321 ">="            { RTOKEN(GE);}
322 "<="            { RTOKEN(LE);}
323 "<<"            { RTOKEN(LSHIFT);}
324 ">>"            { RTOKEN(RSHIFT);}
325 "+="            { RTOKEN(PLUSEQ);}
326 "-="            { RTOKEN(MINUSEQ);}
327 "*="            { RTOKEN(MULTEQ);}
328 "/="            { RTOKEN(DIVEQ);}
329 "&="            { RTOKEN(ANDEQ);}
330 "|="            { RTOKEN(OREQ);}
331
332 "&&"            { RTOKEN(ANDAND);}
333 ">"             { RTOKEN('>');}
334 ","             { RTOKEN(',');}
335 "&"             { RTOKEN('&');}
336 "|"             { RTOKEN('|');}
337 "~"             { RTOKEN('~');}
338 "!"             { RTOKEN('!');}
339 "?"             { RTOKEN('?');}
340 "*"             { RTOKEN('*');}
341 "%"             { RTOKEN('%');}
342 "<"             { RTOKEN('<');}
343 "+"             { RTOKEN('+');}
344 ">"             { RTOKEN('>');}
345 "}"             { RTOKEN('}') ; }
346 "{"             { RTOKEN('{'); }
347 ")"             { RTOKEN(')');}
348 "("             { RTOKEN('(');}
349 "]"             { RTOKEN(']');}
350 "["             { RTOKEN('[');}
351 ":"             { RTOKEN(':'); }
352 ";"             { RTOKEN(';');}
353 "-"             { RTOKEN('-');}
354 "="             { RTOKEN('=');}
355
356
357 "/*"            { 
358   while (1) {
359     int ch;
360     ch = input();
361     while (ch != '*') {
362       ch = input();
363     }
364
365
366
367     if (input() == '/') {
368       break;
369     }
370     unput(yytext[yyleng-1]);
371   }
372 }
373
374 "\""[^\"]*"\"" {
375
376   yylval.name = buystring(yytext+1);
377   yylval.name[yyleng-2] = 0; /* Fry final quote */
378   return NAME;
379 }
380 [0][0-7KM]* {
381
382   yylval.integer = number(yytext+1, 8);
383  return INT;
384 }
385
386 [0-9]+[KM]? {
387   if (hex_mode == true) {
388     yylval.integer = number(yytext, 16);
389   }
390   else {
391     yylval.integer = number(yytext, 10);
392   }
393   return INT;
394 }
395
396 0[Xx][0-9a-fA-FKM]+ {
397  
398   yylval.integer = number(yytext+2,16); 
399   return INT;
400 }
401
402 "\#"{WHITE}*{FILENAMECHAR}+ {
403   char *p = yytext+1;
404   while(*p ==' ' || *p == '\t') p++;
405   yylval.name = buystring(p);
406   return NAME;
407 }
408 {FILENAMECHAR} {
409
410   boolean loop = false;
411   /*
412     Tokenize a name, this is really pain, since a name can be a
413     filename or a symbol name. filenames have slashes and stuff whist
414     in an expression those things are seperate tokens. We hack this by
415     setting lang_in_expression when we are expecting a symbol, so that
416     [/+-] get taken to be seperate tokens. An extra gotcha is
417     expressions after defsyms, we only allow +s and -s in a defsym
418     expression, so -defsym foo=bar+9 /file.o is parsed ok.
419     
420     */
421   int ch;
422   keyword_type *k;
423   if (ldgram_in_expression) {
424     if (yytext[0] != '/' ||  ldgram_in_defsym == false)  {
425       switch (yytext[0]) {
426       case '/': RTOKEN('/');
427       case '+': RTOKEN('+');
428       case '-': RTOKEN('-');
429       }
430     }
431   }
432
433   ch = input();
434   while (true)
435       {
436         if (isalpha(ch) || isdigit(ch) || ch == '.'  || ch == '_') {
437           yytext[yyleng++] = ch;
438         }
439         else if (ch == '+' || ch == '-' || ch == '/') {
440           if (ldgram_in_expression) break;
441           yytext[yyleng++] = ch;
442         }
443         else 
444           break;
445         ch = input();
446       }
447
448   yytext[yyleng] = 0;
449   unput(ch);
450
451   for(k = keywords; k ->name != (char *)NULL; k++) {
452
453     if (strcmp(k->name, yytext)==0) {
454       yylval.token = k->value;
455       return k->value;
456     }
457   }
458   yylval.name = buystring(yytext);
459   return NAME;
460 }
461
462
463
464
465
466 %%