]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/ldlex.l
2.41 Release sources
[thirdparty/binutils-gdb.git] / ld / ldlex.l
CommitLineData
b0556316 1%option nounput noyywrap
cfdf38f2 2
252b5132
RH
3%{
4
d87bef3a 5/* Copyright (C) 1991-2023 Free Software Foundation, Inc.
f96b4a7b 6 Written by Steve Chamberlain of Cygnus Support.
252b5132 7
f96b4a7b 8 This file is part of the GNU Binutils.
252b5132 9
f96b4a7b 10 This program is free software; you can redistribute it and/or modify
3ec57632 11 it under the terms of the GNU General Public License as published by
f96b4a7b
NC
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
252b5132 14
f96b4a7b 15 This program is distributed in the hope that it will be useful,
3ec57632
NC
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
252b5132 19
3ec57632 20 You should have received a copy of the GNU General Public License
f96b4a7b
NC
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
252b5132 24
3db64b00 25#include "bfd.h"
3882b010 26#include "safe-ctype.h"
e3e942e9 27#include "bfdlink.h"
1ff6de03 28#include "ctf-api.h"
252b5132 29#include "ld.h"
252b5132
RH
30#include "ldmisc.h"
31#include "ldexp.h"
32#include "ldlang.h"
df2a7313 33#include <ldgram.h>
252b5132
RH
34#include "ldfile.h"
35#include "ldlex.h"
36#include "ldmain.h"
d1b2b2dc 37#include "libiberty.h"
252b5132
RH
38
39/* The type of top-level parser input.
40 yylex and yyparse (indirectly) both check this. */
41input_type parser_input;
42
1753ed68
JB
43/* Line number in the current input file. */
44unsigned int lineno;
252b5132
RH
45
46/* The string we are currently lexing, or NULL if we are reading a
47 file. */
48const char *lex_string = NULL;
49
50/* Support for flex reading from more than one input file (stream).
51 `include_stack' is flex's input state for each open file;
52 `file_name_stack' is the file names. `lineno_stack' is the current
53 line numbers.
54
55 If `include_stack_ptr' is 0, we haven't started reading anything yet.
56 Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid. */
57
58#undef YY_INPUT
d05c651b 59#define YY_INPUT(buf,result,max_size) result = yy_input (buf, max_size)
252b5132 60
5b806d27 61#ifndef YY_NO_UNPUT
297ba367 62#define YY_NO_UNPUT
5b806d27 63#endif
297ba367 64
252b5132
RH
65#define MAX_INCLUDE_DEPTH 10
66static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
67static const char *file_name_stack[MAX_INCLUDE_DEPTH];
68static unsigned int lineno_stack[MAX_INCLUDE_DEPTH];
f4a23d42 69static unsigned int sysrooted_stack[MAX_INCLUDE_DEPTH];
252b5132
RH
70static unsigned int include_stack_ptr = 0;
71static int vers_node_nesting = 0;
72
d05c651b 73static int yy_input (char *, int);
1579bae1
AM
74static void comment (void);
75static void lex_warn_invalid (char *where, char *what);
252b5132 76
1579bae1 77/* STATES
af29a8ab
AM
78 EXPRESSION in an expression
79 SCRIPT in a script
80 INPUTLIST in a script, a filename-list
6c19b93b 81 MRI in an MRI script
af29a8ab
AM
82 WILD inside the braces of an output section or overlay,
83 for input section wildcards
252b5132
RH
84 VERS_START starting a Sun style mapfile
85 VERS_SCRIPT a Sun style mapfile
86 VERS_NODE a node within a Sun style mapfile
87*/
88#define RTOKEN(x) { yylval.token = x; return x; }
89
252b5132
RH
90%}
91
92%a 4000
93%o 5000
94
092da96a
AM
95WILDCHAR [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]\,\=\?\*\^\!]
96FILENAMECHAR [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]\,\=]
97NOCFILENAMECHAR [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]]
98SYMBOLNAMECHAR [_a-zA-Z0-9\/\.\\\$\~]
99FILENAMECHAR1 [_a-zA-Z\/\.\\\$\~]
1c6aafe8 100SYMBOLNAMECHAR1 [_a-zA-Z\.\\\$]
1579bae1 101WHITE [ \t\n\r]+
252b5132 102
252b5132 103V_TAG [.$_a-zA-Z][._a-zA-Z0-9]*
5e35cbc2 104V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
252b5132
RH
105
106%s SCRIPT
eeed9cc7 107%s INPUTLIST
252b5132 108%s EXPRESSION
252b5132 109%s MRI
af29a8ab 110%s WILD
252b5132
RH
111%s VERS_START
112%s VERS_SCRIPT
113%s VERS_NODE
114%%
115
116 if (parser_input != input_selected)
117 {
118 /* The first token of the input determines the initial parser state. */
119 input_type t = parser_input;
120 parser_input = input_selected;
121 switch (t)
122 {
123 case input_script: return INPUT_SCRIPT; break;
124 case input_mri_script: return INPUT_MRI_SCRIPT; break;
125 case input_version_script: return INPUT_VERSION_SCRIPT; break;
55255dae 126 case input_dynamic_list: return INPUT_DYNAMIC_LIST; break;
252b5132
RH
127 case input_defsym: return INPUT_DEFSYM; break;
128 default: abort ();
129 }
130 }
131
af29a8ab
AM
132<SCRIPT,EXPRESSION,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"/*" {
133 comment (); }
252b5132 134
252b5132 135<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
6c19b93b 136 yylval.integer = bfd_scan_vma (yytext + 1, 0, 16);
1579bae1 137 yylval.bigint.str = NULL;
252b5132
RH
138 return INT;
139 }
140
141<MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) {
142 int ibase ;
1579bae1
AM
143 switch (yytext[yyleng - 1]) {
144 case 'X':
252b5132
RH
145 case 'x':
146 case 'H':
147 case 'h':
148 ibase = 16;
149 break;
150 case 'O':
151 case 'o':
152 ibase = 8;
153 break;
154 case 'B':
155 case 'b':
156 ibase = 2;
157 break;
158 default:
159 ibase = 10;
160 }
161 yylval.integer = bfd_scan_vma (yytext, 0,
162 ibase);
1579bae1 163 yylval.bigint.str = NULL;
252b5132
RH
164 return INT;
165 }
af29a8ab 166<SCRIPT,MRI,EXPRESSION>((("$"|0[xX])([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? {
252b5132 167 char *s = yytext;
2c382fb6 168 int ibase = 0;
252b5132
RH
169
170 if (*s == '$')
2c382fb6
AM
171 {
172 ++s;
173 ibase = 16;
174 }
175 yylval.integer = bfd_scan_vma (s, 0, ibase);
1579bae1
AM
176 yylval.bigint.str = NULL;
177 if (yytext[yyleng - 1] == 'M'
178 || yytext[yyleng - 1] == 'm')
2c382fb6
AM
179 {
180 yylval.integer *= 1024 * 1024;
181 }
1579bae1
AM
182 else if (yytext[yyleng - 1] == 'K'
183 || yytext[yyleng - 1]=='k')
2c382fb6
AM
184 {
185 yylval.integer *= 1024;
186 }
187 else if (yytext[0] == '0'
188 && (yytext[1] == 'x'
189 || yytext[1] == 'X'))
190 {
191 yylval.bigint.str = xstrdup (yytext + 2);
192 }
252b5132
RH
193 return INT;
194 }
f400c8d2
AM
195
196 /* Some tokens that only appear in expressions must be enabled for
197 states other than EXPRESSION, since parser lookahead means they
198 must be recognised before the parser switches the lexer out of
199 SCRIPT or WILD state into EXPRESSION state.
200
201 This sort of thing happens for example with NAME in ldgram.y
202 "section" rule, which is immediately followed by ldlex_expression.
203 However, if you follow the grammar from "sec_or_group_p1" you see
204 "assignment" appearing in "statement_anywhere". Now,
205 "assignment" also has NAME as its first token, just like
206 "section". So the parser can't know whether it is in the
207 "section" or the "assignment" rule until it has scanned the next
208 token to find an assignment operator. Thus the next token after
209 NAME in the "section" rule may be lexed before the lexer is
210 switched to EXPRESSION state, and there are quite a number of
211 optional components. The first token in all those components
212 must be able to be lexed in SCRIPT state, as well as the
213 assignment operators. In fact, due to "opt_exp_with_type",
214 anything that can appear on the left hand side of "exp" might
215 need to be lexed in SCRIPT state.
216
217 MRI mode tends to cover everything in MRI scripts.
218 */
219<MRI,WILD>"]" { RTOKEN(']'); }
220<MRI,WILD>"[" { RTOKEN('['); }
221<SCRIPT,EXPRESSION,MRI,WILD>"<<=" { RTOKEN(LSHIFTEQ); }
222<SCRIPT,EXPRESSION,MRI,WILD>">>=" { RTOKEN(RSHIFTEQ); }
223<EXPRESSION,MRI>"||" { RTOKEN(OROR); }
224<EXPRESSION,MRI>"==" { RTOKEN(EQ); }
225<EXPRESSION,MRI>"!=" { RTOKEN(NE); }
226<EXPRESSION,MRI>">=" { RTOKEN(GE); }
227<EXPRESSION,MRI>"<=" { RTOKEN(LE); }
228<EXPRESSION,MRI>"<<" { RTOKEN(LSHIFT); }
229<EXPRESSION,MRI>">>" { RTOKEN(RSHIFT); }
230<SCRIPT,EXPRESSION,MRI,WILD>"+=" { RTOKEN(PLUSEQ); }
231<SCRIPT,EXPRESSION,MRI,WILD>"-=" { RTOKEN(MINUSEQ); }
232<SCRIPT,EXPRESSION,MRI,WILD>"*=" { RTOKEN(MULTEQ); }
233<SCRIPT,EXPRESSION,MRI,WILD>"/=" { RTOKEN(DIVEQ); }
234<SCRIPT,EXPRESSION,MRI,WILD>"&=" { RTOKEN(ANDEQ); }
235<SCRIPT,EXPRESSION,MRI,WILD>"|=" { RTOKEN(OREQ); }
236<EXPRESSION,MRI>"&&" { RTOKEN(ANDAND); }
237<SCRIPT,EXPRESSION,MRI>">" { RTOKEN('>'); }
238<SCRIPT,EXPRESSION,MRI,INPUTLIST>"," { RTOKEN(','); }
239<EXPRESSION,MRI,WILD>"&" { RTOKEN('&'); }
240<EXPRESSION,MRI>"|" { RTOKEN('|'); }
241<SCRIPT,EXPRESSION,MRI>"~" { RTOKEN('~'); }
242<SCRIPT,EXPRESSION,MRI>"!" { RTOKEN('!'); }
243<EXPRESSION,MRI>"?" { RTOKEN('?'); }
244<EXPRESSION,MRI>"*" { RTOKEN('*'); }
245<SCRIPT,EXPRESSION,MRI>"+" { RTOKEN('+'); }
246<SCRIPT,EXPRESSION,MRI>"-" { RTOKEN('-'); }
247<EXPRESSION,MRI>"/" { RTOKEN('/'); }
248<EXPRESSION,MRI>"%" { RTOKEN('%'); }
249<EXPRESSION,MRI>"<" { RTOKEN('<'); }
250<SCRIPT,EXPRESSION,MRI,WILD>"=" { RTOKEN('='); }
af29a8ab
AM
251<SCRIPT,EXPRESSION,MRI,WILD>"}" { RTOKEN('}'); }
252<SCRIPT,EXPRESSION,MRI,WILD>"{" { RTOKEN('{'); }
f400c8d2
AM
253<SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>")" { RTOKEN(')'); }
254<SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>"(" { RTOKEN('('); }
af29a8ab 255<SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); }
f400c8d2
AM
256<SCRIPT,EXPRESSION,MRI,WILD>";" { RTOKEN(';'); }
257<SCRIPT>"MEMORY" { RTOKEN(MEMORY); }
258<SCRIPT>"REGION_ALIAS" { RTOKEN(REGION_ALIAS); }
259<SCRIPT>"LD_FEATURE" { RTOKEN(LD_FEATURE); }
260<SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN); }
261<SCRIPT>"VERSION" { RTOKEN(VERSIONK); }
262<SCRIPT,EXPRESSION>"BLOCK" { RTOKEN(BLOCK); }
263<SCRIPT,EXPRESSION>"BIND" { RTOKEN(BIND); }
264<SCRIPT,EXPRESSION>"LENGTH" { RTOKEN(LENGTH); }
265<SCRIPT,EXPRESSION>"ALIGN" { RTOKEN(ALIGN_K); }
266<SCRIPT,EXPRESSION>"DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN); }
267<SCRIPT,EXPRESSION>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END); }
268<SCRIPT,EXPRESSION>"DATA_SEGMENT_END" { RTOKEN(DATA_SEGMENT_END); }
269<SCRIPT,EXPRESSION>"ADDR" { RTOKEN(ADDR); }
270<SCRIPT,EXPRESSION>"LOADADDR" { RTOKEN(LOADADDR); }
af29a8ab 271<SCRIPT,EXPRESSION>"ALIGNOF" { RTOKEN(ALIGNOF); }
b325429b 272<SCRIPT,EXPRESSION>"ABSOLUTE" { RTOKEN(ABSOLUTE); }
f400c8d2
AM
273<SCRIPT,EXPRESSION>"MAX" { RTOKEN(MAX_K); }
274<SCRIPT,EXPRESSION>"MIN" { RTOKEN(MIN_K); }
275<SCRIPT,EXPRESSION>"LOG2CEIL" { RTOKEN(LOG2CEIL); }
af29a8ab 276<SCRIPT,EXPRESSION,WILD>"ASSERT" { RTOKEN(ASSERT_K); }
f400c8d2
AM
277<SCRIPT>"ENTRY" { RTOKEN(ENTRY); }
278<SCRIPT,MRI>"EXTERN" { RTOKEN(EXTERN); }
279<SCRIPT,EXPRESSION>"NEXT" { RTOKEN(NEXT); }
280<SCRIPT,EXPRESSION>"SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS); }
281<SCRIPT,EXPRESSION>"SEGMENT_START" { RTOKEN(SEGMENT_START); }
282<SCRIPT>"MAP" { RTOKEN(MAP); }
283<SCRIPT,EXPRESSION>"SIZEOF" { RTOKEN(SIZEOF); }
284<SCRIPT>"TARGET" { RTOKEN(TARGET_K); }
285<SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR); }
286<SCRIPT>"OUTPUT" { RTOKEN(OUTPUT); }
287<SCRIPT>"INPUT" { RTOKEN(INPUT); }
288<SCRIPT>"GROUP" { RTOKEN(GROUP); }
289<INPUTLIST>"AS_NEEDED" { RTOKEN(AS_NEEDED); }
290<SCRIPT,EXPRESSION>"DEFINED" { RTOKEN(DEFINED); }
291<WILD>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS); }
292<WILD>"CONSTRUCTORS" { RTOKEN(CONSTRUCTORS); }
293<SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION); }
294<SCRIPT>"FORCE_GROUP_ALLOCATION" { RTOKEN(FORCE_GROUP_ALLOCATION); }
295<SCRIPT>"INHIBIT_COMMON_ALLOCATION" { RTOKEN(INHIBIT_COMMON_ALLOCATION); }
296<SCRIPT>"SECTIONS" { RTOKEN(SECTIONS); }
297<SCRIPT>"INSERT" { RTOKEN(INSERT_K); }
298<SCRIPT>"AFTER" { RTOKEN(AFTER); }
299<SCRIPT>"BEFORE" { RTOKEN(BEFORE); }
300<WILD>"FILL" { RTOKEN(FILL); }
301<SCRIPT>"STARTUP" { RTOKEN(STARTUP); }
302<SCRIPT>"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT); }
303<SCRIPT>"OUTPUT_ARCH" { RTOKEN(OUTPUT_ARCH); }
304<SCRIPT>"HLL" { RTOKEN(HLL); }
305<SCRIPT>"SYSLIB" { RTOKEN(SYSLIB); }
306<SCRIPT>"FLOAT" { RTOKEN(FLOAT); }
307<WILD>"QUAD" { RTOKEN(QUAD); }
308<WILD>"SQUAD" { RTOKEN(SQUAD); }
309<WILD>"LONG" { RTOKEN(LONG); }
310<WILD>"SHORT" { RTOKEN(SHORT); }
311<WILD>"BYTE" { RTOKEN(BYTE); }
0d79a2a8 312<WILD>"ASCIZ" { RTOKEN(ASCIZ); }
2d5783fa 313<WILD>"LINKER_VERSION" { RTOKEN(LINKER_VERSION); }
f400c8d2
AM
314<SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT); }
315<SCRIPT,EXPRESSION>"NOCROSSREFS" { RTOKEN(NOCROSSREFS); }
316<SCRIPT,EXPRESSION>"NOCROSSREFS_TO" { RTOKEN(NOCROSSREFS_TO); }
317<SCRIPT,EXPRESSION>"OVERLAY" { RTOKEN(OVERLAY); }
318<WILD>"SORT_BY_NAME" { RTOKEN(SORT_BY_NAME); }
319<WILD>"SORT_BY_ALIGNMENT" { RTOKEN(SORT_BY_ALIGNMENT); }
320<WILD>"SORT" { RTOKEN(SORT_BY_NAME); }
321<WILD>"SORT_BY_INIT_PRIORITY" { RTOKEN(SORT_BY_INIT_PRIORITY); }
322<WILD>"SORT_NONE" { RTOKEN(SORT_NONE); }
323<EXPRESSION>"NOLOAD" { RTOKEN(NOLOAD); }
324<EXPRESSION>"READONLY" { RTOKEN(READONLY); }
325<EXPRESSION>"DSECT" { RTOKEN(DSECT); }
326<EXPRESSION>"COPY" { RTOKEN(COPY); }
327<EXPRESSION>"INFO" { RTOKEN(INFO); }
c212f39d 328<EXPRESSION>"TYPE" { RTOKEN(TYPE); }
f400c8d2
AM
329<SCRIPT,EXPRESSION>"ONLY_IF_RO" { RTOKEN(ONLY_IF_RO); }
330<SCRIPT,EXPRESSION>"ONLY_IF_RW" { RTOKEN(ONLY_IF_RW); }
331<SCRIPT,EXPRESSION>"SPECIAL" { RTOKEN(SPECIAL); }
332<SCRIPT>"o" { RTOKEN(ORIGIN); }
333<SCRIPT>"org" { RTOKEN(ORIGIN); }
334<SCRIPT>"l" { RTOKEN(LENGTH); }
335<SCRIPT>"len" { RTOKEN(LENGTH); }
336<WILD>"INPUT_SECTION_FLAGS" { RTOKEN(INPUT_SECTION_FLAGS); }
337<SCRIPT,EXPRESSION,WILD,MRI>"INCLUDE" { RTOKEN(INCLUDE);}
338<SCRIPT>"PHDRS" { RTOKEN(PHDRS); }
af29a8ab
AM
339<SCRIPT,EXPRESSION,WILD>"AT" { RTOKEN(AT);}
340<SCRIPT,EXPRESSION>"ALIGN_WITH_INPUT" { RTOKEN(ALIGN_WITH_INPUT);}
341<SCRIPT,EXPRESSION>"SUBALIGN" { RTOKEN(SUBALIGN);}
342<SCRIPT,EXPRESSION,WILD>"HIDDEN" { RTOKEN(HIDDEN); }
343<SCRIPT,EXPRESSION,WILD>"PROVIDE" { RTOKEN(PROVIDE); }
344<SCRIPT,EXPRESSION,WILD>"PROVIDE_HIDDEN" { RTOKEN(PROVIDE_HIDDEN); }
f400c8d2
AM
345<WILD>"KEEP" { RTOKEN(KEEP); }
346<WILD>"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); }
af29a8ab
AM
347<SCRIPT,EXPRESSION>"CONSTANT" { RTOKEN(CONSTANT);}
348
252b5132 349<MRI>"#".*\n? { ++ lineno; }
6c19b93b 350<MRI>"\n" { ++ lineno; RTOKEN(NEWLINE); }
252b5132
RH
351<MRI>"*".* { /* Mri comment line */ }
352<MRI>";".* { /* Mri comment line */ }
6c19b93b 353<MRI>"END" { RTOKEN(ENDWORD); }
b325429b 354<MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); }
3ec57632
NC
355<MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);}
356<MRI>"ALIGN" { RTOKEN(ALIGN_K);}
6c19b93b
AM
357<MRI>"CHIP" { RTOKEN(CHIP); }
358<MRI>"BASE" { RTOKEN(BASE); }
359<MRI>"ALIAS" { RTOKEN(ALIAS); }
360<MRI>"TRUNCATE" { RTOKEN(TRUNCATE); }
361<MRI>"LOAD" { RTOKEN(LOAD); }
362<MRI>"PUBLIC" { RTOKEN(PUBLIC); }
363<MRI>"ORDER" { RTOKEN(ORDER); }
364<MRI>"NAME" { RTOKEN(NAMEWORD); }
365<MRI>"FORMAT" { RTOKEN(FORMAT); }
366<MRI>"CASE" { RTOKEN(CASE); }
367<MRI>"START" { RTOKEN(START); }
368<MRI>"LIST".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
252b5132 369<MRI>"SECT" { RTOKEN(SECT); }
6c19b93b 370<MRI>"end" { RTOKEN(ENDWORD); }
b325429b 371<MRI>"absolute" { RTOKEN(ABSOLUTE); }
3ec57632
NC
372<MRI>"alignmod" { RTOKEN(ALIGNMOD);}
373<MRI>"align" { RTOKEN(ALIGN_K);}
6c19b93b
AM
374<MRI>"chip" { RTOKEN(CHIP); }
375<MRI>"base" { RTOKEN(BASE); }
376<MRI>"alias" { RTOKEN(ALIAS); }
377<MRI>"truncate" { RTOKEN(TRUNCATE); }
378<MRI>"load" { RTOKEN(LOAD); }
379<MRI>"public" { RTOKEN(PUBLIC); }
380<MRI>"order" { RTOKEN(ORDER); }
381<MRI>"name" { RTOKEN(NAMEWORD); }
382<MRI>"format" { RTOKEN(FORMAT); }
383<MRI>"case" { RTOKEN(CASE); }
384<MRI>"extern" { RTOKEN(EXTERN); }
385<MRI>"start" { RTOKEN(START); }
386<MRI>"list".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
252b5132 387<MRI>"sect" { RTOKEN(SECT); }
252b5132
RH
388
389<MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}* {
390/* Filename without commas, needed to parse mri stuff */
092da96a 391 yylval.name = xstrdup (yytext);
252b5132
RH
392 return NAME;
393 }
394
395
af29a8ab 396<SCRIPT,INPUTLIST>{FILENAMECHAR1}{FILENAMECHAR}* {
092da96a 397 yylval.name = xstrdup (yytext);
252b5132
RH
398 return NAME;
399 }
eeed9cc7 400<INPUTLIST>"="{FILENAMECHAR1}{FILENAMECHAR}* {
3aa2d05a 401/* Filename to be prefixed by --sysroot or when non-sysrooted, nothing. */
092da96a 402 yylval.name = xstrdup (yytext);
eeed9cc7
HPN
403 return NAME;
404 }
af29a8ab 405<INPUTLIST>"-l"{FILENAMECHAR}+ {
8545d1a9
NS
406 yylval.name = xstrdup (yytext + 2);
407 return LNAME;
408 }
40726f16 409<EXPRESSION>{SYMBOLNAMECHAR1}{SYMBOLNAMECHAR}* {
092da96a 410 yylval.name = xstrdup (yytext);
8545d1a9
NS
411 return NAME;
412 }
f400c8d2
AM
413 /* The following rule is to prevent a fill expression on the output
414 section before /DISCARD/ interpreting the '/' as a divide. */
1c6aafe8
AM
415<EXPRESSION>"/DISCARD/" {
416 yylval.name = xstrdup (yytext);
417 return NAME;
418 }
af29a8ab 419<WILD>{WILDCHAR}* {
252b5132
RH
420 /* Annoyingly, this pattern can match comments, and we have
421 longest match issues to consider. So if the first two
422 characters are a comment opening, put the input back and
423 try again. */
424 if (yytext[0] == '/' && yytext[1] == '*')
425 {
1579bae1 426 yyless (2);
252b5132
RH
427 comment ();
428 }
429 else
430 {
1579bae1 431 yylval.name = xstrdup (yytext);
252b5132
RH
432 return NAME;
433 }
434 }
435
af29a8ab 436<SCRIPT,EXPRESSION,WILD,VERS_NODE,INPUTLIST>"\""[^\"]*"\"" {
6ef4fa07
AM
437 /* No matter the state, quotes give what's inside. */
438 yylval.name = xmemdup (yytext + 1, yyleng - 2, yyleng - 1);
439 return NAME;
440 }
cc9faa98 441
af29a8ab 442<SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"\n" {
cc9faa98 443 lineno++; }
af29a8ab 444<MRI,SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>[ \t\r]+ {
cc9faa98 445 /* Eat up whitespace */ }
af29a8ab 446<SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT>#.* {
cc9faa98 447 /* Eat up comments */ }
252b5132
RH
448
449<VERS_NODE,VERS_SCRIPT>[:,;] { return *yytext; }
450
451<VERS_NODE>global { RTOKEN(GLOBAL); }
452
453<VERS_NODE>local { RTOKEN(LOCAL); }
454
455<VERS_NODE>extern { RTOKEN(EXTERN); }
456
d1b2b2dc 457<VERS_NODE>{V_IDENTIFIER} { yylval.name = xstrdup (yytext);
252b5132
RH
458 return VERS_IDENTIFIER; }
459
d1b2b2dc 460<VERS_SCRIPT>{V_TAG} { yylval.name = xstrdup (yytext);
252b5132
RH
461 return VERS_TAG; }
462
463<VERS_START>"{" { BEGIN(VERS_SCRIPT); return *yytext; }
464
1579bae1 465<VERS_SCRIPT>"{" { BEGIN(VERS_NODE);
252b5132
RH
466 vers_node_nesting = 0;
467 return *yytext;
468 }
469<VERS_SCRIPT>"}" { return *yytext; }
470<VERS_NODE>"{" { vers_node_nesting++; return *yytext; }
471<VERS_NODE>"}" { if (--vers_node_nesting < 0)
472 BEGIN(VERS_SCRIPT);
473 return *yytext;
474 }
475
252b5132
RH
476<<EOF>> {
477 include_stack_ptr--;
1579bae1 478 if (include_stack_ptr == 0)
1753ed68
JB
479 {
480 lineno = 0;
481 yyterminate ();
482 }
1579bae1 483 else
1579bae1 484 yy_switch_to_buffer (include_stack[include_stack_ptr]);
b47c4208 485
b47c4208 486 lineno = lineno_stack[include_stack_ptr];
f4a23d42 487 input_flags.sysrooted = sysrooted_stack[include_stack_ptr];
252b5132
RH
488
489 return END;
490}
491
02d44d76
JB
492<SCRIPT,WILD,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>. lex_warn_invalid (_(" in script"), yytext);
493<EXPRESSION>. lex_warn_invalid (_(" in expression"), yytext);
1579bae1 494
252b5132
RH
495%%
496\f
497
498/* Switch flex to reading script file NAME, open on FILE,
499 saving the current input info on the include stack. */
500
501void
f4a23d42 502lex_push_file (FILE *file, const char *name, unsigned int sysrooted)
252b5132 503{
1579bae1 504 if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
252b5132 505 {
d003af55 506 einfo (_("%F:includes nested too deeply\n"));
252b5132
RH
507 }
508 file_name_stack[include_stack_ptr] = name;
b47c4208 509 lineno_stack[include_stack_ptr] = lineno;
f4a23d42 510 sysrooted_stack[include_stack_ptr] = input_flags.sysrooted;
252b5132
RH
511 include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
512
513 include_stack_ptr++;
b47c4208 514 lineno = 1;
f4a23d42 515 input_flags.sysrooted = sysrooted;
252b5132 516 yyin = file;
1579bae1 517 yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE));
252b5132
RH
518}
519
520/* Return a newly created flex input buffer containing STRING,
521 which is SIZE bytes long. */
522
1579bae1
AM
523static YY_BUFFER_STATE
524yy_create_string_buffer (const char *string, size_t size)
252b5132
RH
525{
526 YY_BUFFER_STATE b;
527
ee44c2ac 528 b = xmalloc (sizeof (struct yy_buffer_state));
252b5132
RH
529 b->yy_input_file = 0;
530 b->yy_buf_size = size;
531
532 /* yy_ch_buf has to be 2 characters longer than the size given because
533 we need to put in 2 end-of-buffer characters. */
ee44c2ac 534 b->yy_ch_buf = xmalloc ((size_t) b->yy_buf_size + 3);
252b5132
RH
535
536 b->yy_ch_buf[0] = '\n';
537 strcpy (b->yy_ch_buf+1, string);
538 b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR;
539 b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR;
540 b->yy_n_chars = size+1;
541 b->yy_buf_pos = &b->yy_ch_buf[1];
542
dca7760f
AM
543 b->yy_is_our_buffer = 1;
544 b->yy_is_interactive = 0;
545 b->yy_at_bol = 1;
546 b->yy_fill_buffer = 0;
547
252b5132
RH
548 /* flex 2.4.7 changed the interface. FIXME: We should not be using
549 a flex internal interface in the first place! */
550#ifdef YY_BUFFER_NEW
551 b->yy_buffer_status = YY_BUFFER_NEW;
552#else
553 b->yy_eof_status = EOF_NOT_SEEN;
554#endif
555
556 return b;
557}
558
559/* Switch flex to reading from STRING, saving the current input info
560 on the include stack. */
561
562void
dab69f68 563lex_redirect (const char *string, const char *fake_filename, unsigned int count)
252b5132
RH
564{
565 YY_BUFFER_STATE tmp;
566
567 yy_init = 0;
1579bae1 568 if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
252b5132 569 {
d003af55 570 einfo (_("%F: macros nested too deeply\n"));
252b5132 571 }
dab69f68 572 file_name_stack[include_stack_ptr] = fake_filename;
b47c4208 573 lineno_stack[include_stack_ptr] = lineno;
252b5132
RH
574 include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
575 include_stack_ptr++;
dab69f68 576 lineno = count;
252b5132
RH
577 tmp = yy_create_string_buffer (string, strlen (string));
578 yy_switch_to_buffer (tmp);
252b5132
RH
579}
580\f
581/* Functions to switch to a different flex start condition,
582 saving the current start condition on `state_stack'. */
583
584static int state_stack[MAX_INCLUDE_DEPTH * 2];
585static int *state_stack_p = state_stack;
586
587void
1579bae1 588ldlex_script (void)
252b5132
RH
589{
590 *(state_stack_p)++ = yy_start;
591 BEGIN (SCRIPT);
592}
593
eeed9cc7
HPN
594void
595ldlex_inputlist (void)
596{
597 *(state_stack_p)++ = yy_start;
598 BEGIN (INPUTLIST);
599}
600
252b5132 601void
1579bae1 602ldlex_mri_script (void)
252b5132
RH
603{
604 *(state_stack_p)++ = yy_start;
605 BEGIN (MRI);
606}
607
608void
1579bae1 609ldlex_version_script (void)
252b5132
RH
610{
611 *(state_stack_p)++ = yy_start;
612 BEGIN (VERS_START);
613}
614
615void
1579bae1 616ldlex_version_file (void)
252b5132
RH
617{
618 *(state_stack_p)++ = yy_start;
619 BEGIN (VERS_SCRIPT);
620}
621
252b5132 622void
1579bae1 623ldlex_expression (void)
252b5132
RH
624{
625 *(state_stack_p)++ = yy_start;
626 BEGIN (EXPRESSION);
627}
628
629void
af29a8ab 630ldlex_wild (void)
252b5132
RH
631{
632 *(state_stack_p)++ = yy_start;
af29a8ab 633 BEGIN (WILD);
252b5132
RH
634}
635
636void
1579bae1 637ldlex_popstate (void)
252b5132
RH
638{
639 yy_start = *(--state_stack_p);
640}
dab69f68 641
40726f16
AM
642/* In cases where the parser needs to look ahead and the context
643 changes from expression to script or vice-versa, throw away a
644 NAME. What constitutes a NAME depends on context. */
645
646void
647ldlex_backup (void)
648{
649 yyless (0);
650}
651
dab69f68
AM
652/* Return the current file name, or the previous file if no file is
653 current. */
654
655const char*
656ldlex_filename (void)
657{
658 return file_name_stack[include_stack_ptr - (include_stack_ptr != 0)];
659}
252b5132
RH
660\f
661
d05c651b 662/* Place up to MAX_SIZE characters in BUF and return
252b5132
RH
663 either the number of characters read, or 0 to indicate EOF. */
664
d05c651b
AS
665static int
666yy_input (char *buf, int max_size)
252b5132 667{
d05c651b 668 int result = 0;
731e28d8 669 if (YY_CURRENT_BUFFER->yy_input_file)
252b5132
RH
670 {
671 if (yyin)
672 {
d05c651b
AS
673 result = fread (buf, 1, max_size, yyin);
674 if (result < max_size && ferror (yyin))
d003af55 675 einfo (_("%F%P: read in flex scanner failed\n"));
252b5132
RH
676 }
677 }
d05c651b 678 return result;
252b5132
RH
679}
680
681/* Eat the rest of a C-style comment. */
682
683static void
1579bae1 684comment (void)
252b5132
RH
685{
686 int c;
687
688 while (1)
252b5132 689 {
252b5132 690 c = input();
9ab3a744 691 while (c != '*' && c != 0)
d003af55
AM
692 {
693 if (c == '\n')
694 lineno++;
695 c = input();
696 }
252b5132 697
d003af55
AM
698 if (c == '*')
699 {
700 c = input();
701 while (c == '*')
702 c = input();
703 if (c == '/')
704 break; /* found the end */
705 }
252b5132 706
d003af55
AM
707 if (c == '\n')
708 lineno++;
252b5132 709
9ab3a744 710 if (c == 0)
d003af55
AM
711 {
712 einfo (_("%F%P: EOF in comment\n"));
713 break;
714 }
252b5132 715 }
252b5132
RH
716}
717
718/* Warn the user about a garbage character WHAT in the input
719 in context WHERE. */
720
721static void
1579bae1 722lex_warn_invalid (char *where, char *what)
252b5132
RH
723{
724 char buf[5];
725
726 /* If we have found an input file whose format we do not recognize,
727 and we are therefore treating it as a linker script, and we find
728 an invalid character, then most likely this is a real object file
729 of some different format. Treat it as such. */
730 if (ldfile_assumed_script)
731 {
732 bfd_set_error (bfd_error_file_not_recognized);
d003af55 733 einfo (_("%F%s: file not recognized: %E\n"), ldlex_filename ());
252b5132
RH
734 }
735
3882b010 736 if (! ISPRINT (*what))
252b5132 737 {
c3a7b120 738 sprintf (buf, "\\%03o", *(unsigned char *) what);
252b5132
RH
739 what = buf;
740 }
741
c1c8c1ef 742 einfo (_("%P:%pS: ignoring invalid character `%s'%s\n"), NULL, what, where);
252b5132 743}