Initial revision
[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  * $Log$
24  * Revision 1.1  1991/03/21 21:28:50  gumby
25  * Initial revision
26  *
27  * Revision 1.3  1991/03/16  22:27:24  rich
28  * fish
29  *
30  * Revision 1.2  1991/03/15  18:45:55  rich
31  * foo
32  *
33  * Revision 1.1  1991/03/13  00:48:27  chrisb
34  * Initial revision
35  *
36  * Revision 1.6  1991/03/10  09:31:32  rich
37  *  Modified Files:
38  *      Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c
39  *      ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h
40  *      ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c
41  *      ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c
42  *      ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h
43  *
44  * As of this round of changes, ld now builds on all hosts of (Intel960)
45  * interest and copy passes my copy test on big endian hosts again.
46  *
47  * Revision 1.5  1991/03/09  03:25:49  sac
48  * Can now parse the -Ur flag
49  *
50  * Revision 1.4  1991/03/06  02:26:04  sac
51  * Added support for constructor sections.
52  * Remove parsing ambiguity.
53  * Lint
54  *
55  * Revision 1.3  1991/02/22  17:15:14  sac
56  * Added RCS keywords and copyrights
57  *
58 */
59
60
61
62 /*SUPPRESS 529*/
63 /*SUPPRESS 26*/
64 /*SUPPRESS 29*/
65 #define LEXDEBUG
66 #include "sysdep.h"
67 #include "bfd.h"
68
69 #include <ctype.h>
70 #include "ldlex.h"
71
72 #include "ld.h"
73 #include "ldexp.h"
74 #include "ldgram.tab.h"
75 #include "ldmisc.h"
76
77 #undef input
78 #undef unput
79 #define input lex_input
80 #define unput lex_unput
81 int debug;
82 extern boolean ldgram_want_filename;
83 extern boolean ldgram_mustbe_filename;
84 extern boolean ldgram_mustbe_symbolname;
85 static char *command_line;
86
87 extern int fgetc();
88 extern int yyparse();
89
90 typedef struct {
91         char *name;     
92 int value;
93 } keyword_type;
94 #define RTOKEN(x)  {  yylval.token = x; return x; }
95 keyword_type keywords[] = 
96 {
97 "MEMORY",MEMORY,
98 "ORIGIN",ORIGIN,
99 "BLOCK",BLOCK,
100 "LENGTH",LENGTH,
101 "ALIGN",ALIGN_K,
102 "SUBSECTION_ALIGN",SUBSECTION_ALIGN,
103 "ADDR",ADDR,
104 "ENTRY",ENTRY,
105 "NEXT",NEXT,
106 "MAP",MAP,
107 "SIZEOF",SIZEOF,
108 "TARGET",TARGET_K,
109 "SEARCH_DIR",SEARCH_DIR,
110 "OUTPUT",OUTPUT,
111 "INPUT",INPUT,
112 "DEFINED",DEFINED,
113 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
114 "SECTIONS",SECTIONS,
115 "FILL",FILL,
116 "STARTUP",STARTUP,
117 "HLL",HLL,
118 "SYSLIB",SYSLIB,
119 "FLOAT",FLOAT,
120 "LONG", LONG,
121 "SHORT", SHORT,
122 "BYTE", BYTE,
123 "NOFLOAT",NOFLOAT,
124 "o",ORIGIN,
125 "org",ORIGIN,
126 "l", LENGTH,
127 "len", LENGTH,
128 0,0};
129 unsigned int lineno;
130 extern boolean hex_mode;
131 FILE *ldlex_input_stack;
132 static unsigned int have_pushback;
133 #define NPUSHBACK 10
134 int pushback[NPUSHBACK];
135 int thischar;
136 extern char *ldfile_input_filename;
137
138 int
139 lex_input()
140 {
141   /*
142      When we know that the next token must be a filename we force the 
143      input routine to return a '#' character, which will cause the special
144      filname regexp to match the following chars even if they don't look
145      much like a filename to any sane person.
146      */
147   if (ldgram_mustbe_filename) {
148     ldgram_mustbe_filename = false;
149     return '#';
150   }
151
152   if (have_pushback > 0) 
153     {
154       have_pushback --;
155       return thischar = pushback[have_pushback];
156     }
157   if (ldlex_input_stack) {
158     thischar = fgetc(ldlex_input_stack);
159
160     if (thischar == EOF)  {
161       fclose(ldlex_input_stack);
162       ldlex_input_stack = (FILE *)NULL;
163       ldfile_input_filename = (char *)NULL;
164       thischar = lex_input();
165
166     }
167   }
168   else if (command_line && *command_line)  {
169     thischar = *(command_line++);
170   }
171   else thischar = 0;
172   if(thischar == '\t') thischar = ' ';
173   return thischar ;
174 }
175
176 void
177 lex_unput(c)
178 int c;
179 {
180   if (have_pushback > NPUSHBACK) {
181     info("%F%P Too many pushbacks\n");
182   }
183
184   pushback[have_pushback] = c;
185   have_pushback ++;
186 }
187
188
189         int
190 yywrap()
191          { return 1; }
192 /*VARARGS*/
193
194 void
195 allprint(x) 
196 int x;
197 {
198 fprintf(yyout,"%d",x);
199 }
200
201 void
202 sprint(x) 
203 char *x;
204 {
205 fprintf(yyout,"%s",x);
206 }
207
208 int  thischar;
209
210 void parse_line(arg)
211 char *arg;
212 {
213   command_line = arg;
214   have_pushback = 0;
215   yyparse();
216 }
217
218
219
220 void
221 parse_args(ac, av)
222 int ac;
223 char **av;
224 {
225   char *p;
226   int i;
227   size_t size = 0;
228   char *dst;
229   debug = 1;
230   for (i= 1; i < ac; i++) {
231     size += strlen(av[i]) + 2; 
232   }
233   dst = p = (char *)ldmalloc(size + 2);
234 /* Put a space arount each option */
235
236
237   for (i =1; i < ac; i++) {
238
239     unsigned int s = strlen(av[i]);
240   *dst++ = ' ';
241     memcpy(dst, av[i], s);
242     dst[s] = ' ';
243     dst += s + 1;
244   }
245   *dst  = 0;
246   parse_line(p);
247
248   free(p);
249
250
251 }
252
253 long number(text, base)
254 char *text;
255 int base;
256 {
257 unsigned  long l = 0;
258   char *p;
259   for (p = text; *p != 0; p++) {
260     if (*p == 'K') {
261       l =l * 1024;
262     }
263     else if(*p== 'M') {
264       l =l * 1024 * 1024;
265     }
266     else {
267       l =l * base;
268       if (isdigit(*p))  {
269         l += *p - '0';
270       }
271       else if (islower(*p)) {
272         l += *p - 'a' + 10;
273       }
274       else {
275         l += *p - 'A' + 10;
276       }
277     }
278   }
279   return l;
280 }
281 %}
282
283 %a 4000
284 %o 5000
285 FILENAMECHAR    [a-zA-Z0-9\/\.\-\_\+]
286 FILENAME        {FILENAMECHAR}+
287
288
289 WHITE           [ \t]+
290
291 %%
292 "\n"            { lineno++; }
293
294
295 "\ -defsym" { return OPTION_defsym; }
296 "\ -noinhibit_exec" { return OPTION_noinhibit_exec; }
297 "\ -format" { return OPTION_format; }
298 "\ -n"          { return OPTION_n; }
299 "\ -r"          { return OPTION_r; }
300 "\ -Ur"         { return OPTION_Ur; }
301 "\ -o"          { return OPTION_o; }
302 "\ -g"          { return OPTION_g; }
303 "\ -e"          { return OPTION_e; }
304 "\ -b"          { return OPTION_b; }
305 "\ -dc"         { return OPTION_dc; }
306 "\ -dp"         { return OPTION_dp; }
307 "\ -d"          { return OPTION_d; }
308 "\ -v"          { return OPTION_v; }
309 "\ -M"          { return OPTION_M; }
310 "\ -t"          { return OPTION_t; }
311 "\ -X"          { return OPTION_X; }
312 "\ -x"          { return OPTION_x; }
313 "\ -c"          { return OPTION_c; }
314 "\ -s"            { return OPTION_s; }
315 "\ -S"            { return OPTION_S; }
316 "\ -l"{FILENAME} {
317                 yylval.name = buystring(yytext+3);
318                 return OPTION_l; 
319         }
320
321 "\ -L"{FILENAME}        { 
322                 yylval.name = buystring(yytext+3);
323                 return OPTION_L; 
324          }
325 "\ -Ttext"  {
326                  yylval.name = ".text";
327                  return OPTION_Texp;
328                }
329 "\ -Tdata"  {
330                  yylval.name = ".data";
331                  return OPTION_Texp;
332                }
333 "\ -Tbss"  {
334                  yylval.name = ".bss";
335                  return OPTION_Texp;
336                }
337
338 "\ -T"{FILENAME}  {
339                  yylval.name = buystring(yytext+3);
340                  return OPTION_Tfile;
341                }
342 "\ -T"          {
343                  return OPTION_T;
344                }
345
346 "\ -A"{FILENAME} {
347                  yylval.name = buystring(yytext+3);
348                  return OPTION_Aarch;
349                }
350 " " { }
351 "<<="           { RTOKEN(LSHIFTEQ);}
352 ">>="           { RTOKEN(RSHIFTEQ);}
353 "||"            { RTOKEN(OROR);}
354 "=="            { RTOKEN(EQ);}
355 "!="            { RTOKEN(NE);}
356 ">="            { RTOKEN(GE);}
357 "<="            { RTOKEN(LE);}
358 "<<"            { RTOKEN(LSHIFT);}
359 ">>"            { RTOKEN(RSHIFT);}
360 "+="            { RTOKEN(PLUSEQ);}
361 "-="            { RTOKEN(MINUSEQ);}
362 "*="            { RTOKEN(MULTEQ);}
363 "/="            { RTOKEN(DIVEQ);}
364 "&="            { RTOKEN(ANDEQ);}
365 "|="            { RTOKEN(OREQ);}
366
367 "&&"            { RTOKEN(ANDAND);}
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 ":"             { RTOKEN(':'); }
387 ";"             { RTOKEN(';');}
388 "-"             { RTOKEN('-');}
389 "="             { RTOKEN('=');}
390
391
392 "/*"            { 
393   while (1) {
394     int ch;
395     ch = input();
396     while (ch != '*') {
397       if (ch == '\n') {lineno++; }
398       ch = input();
399     }
400
401
402
403     if (input() == '/') {
404       break;
405     }
406     unput(yytext[yyleng-1]);
407   }
408 }
409
410 "\""[^\"]*"\"" {
411
412   yylval.name = buystring(yytext+1);
413   yylval.name[yyleng-2] = 0; /* Fry final quote */
414   return NAME;
415 }
416 [0][0-7KM]* {
417
418   yylval.integer = number(yytext+1, 8);
419  return INT;
420 }
421
422 [0-9]+[KM]? {
423   if (hex_mode == true) {
424     yylval.integer = number(yytext, 16);
425   }
426   else {
427     yylval.integer = number(yytext, 10);
428   }
429   return INT;
430 }
431
432 0[Xx][0-9a-fA-FKM]+ {
433  
434   yylval.integer = number(yytext+2,16); 
435   return INT;
436 }
437
438 "\#"{WHITE}*{FILENAMECHAR}+ {
439   char *p = yytext+1;
440   while(*p ==' ' || *p == '\t') p++;
441   yylval.name = buystring(p);
442   return NAME;
443 }
444
445
446 {FILENAMECHAR}  {
447
448 int ch;
449   keyword_type *k;
450   if (yytext[0] == '/' && ldgram_mustbe_symbolname) 
451     { RTOKEN('/');}
452    ch = input();
453   while (true) {
454     if (isalpha(ch) || isdigit(ch) || ch == '.'  || ch == '_') {
455       yytext[yyleng++] = ch;
456     }
457     else if (ch == '-' && ldgram_want_filename == true) {
458       yytext[yyleng++] = ch;
459     }
460     else if (ch == '+' && ldgram_want_filename == true) {
461       yytext[yyleng++] = ch;
462     }
463
464     else if (ch == '/' && ldgram_want_filename == true) {
465       yytext[yyleng++] = ch;
466     }
467
468     else break;
469     ch = input();
470   }
471
472   yytext[yyleng] = 0;
473   unput(ch);
474
475   for(k = keywords; k ->name != (char *)NULL; k++) {
476
477     if (strcmp(k->name, yytext)==0) {
478       yylval.token = k->value;
479       return k->value;
480     }
481   }
482   yylval.name = buystring(yytext);
483   return NAME;
484 }
485
486
487
488
489
490 %%