diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/splint/examples/ld/ldlexo.w |
Initial commit
Diffstat (limited to 'support/splint/examples/ld/ldlexo.w')
-rw-r--r-- | support/splint/examples/ld/ldlexo.w | 763 |
1 files changed, 763 insertions, 0 deletions
diff --git a/support/splint/examples/ld/ldlexo.w b/support/splint/examples/ld/ldlexo.w new file mode 100644 index 0000000000..6b62d2fd77 --- /dev/null +++ b/support/splint/examples/ld/ldlexo.w @@ -0,0 +1,763 @@ +@q Copyright 2015 Alexander Shibakov@> +@q Copyright 2002-2015 Free Software Foundation, Inc.@> +@q This file is part of SPLinT@> + +@q SPLinT is free software: you can redistribute it and/or modify@> +@q it under the terms of the GNU General Public License as published by@> +@q the Free Software Foundation, either version 3 of the License, or@> +@q (at your option) any later version.@> + +@q SPLinT is distributed in the hope that it will be useful,@> +@q but WITHOUT ANY WARRANTY; without even the implied warranty of@> +@q MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the@> +@q GNU General Public License for more details.@> + +@q You should have received a copy of the GNU General Public License@> +@q along with SPLinT. If not, see <http://www.gnu.org/licenses/>.@> + +@*1 The original lexer. {\it Note that the \ld\ lexer was designed to accomodate +the syntax of various \flex\ flavors, such as the original \lex. The +options \prodstyle{\%a} and \prodstyle{\%o} are ignored by \flex\ and +are a leftover from the archaic days of the original scanner generator.} + +@s input_type int + +@<Original \ld\ lexer@>= +@G + @> @<Original \ld\ macros@> @= +%{@>@<Original \ld\ preamble@> @=%} +%option nounput + @> @<Ignored options@> @= +%% + @> @<Original \ld\ regular expressions@> @= +%% +@g + +@ @<Original \ld\ preamble@>= +#include "bfd.h" +#include "safe-ctype.h" +#include "bfdlink.h" +#include "ld.h" +#include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" +#include <ldgram.h> +#include "ldfile.h" +#include "ldlex.h" +#include "ldmain.h" +#include "libiberty.h" + +input_type parser_input;/* The type of top-level parser input. + |yylex| and |yyparse| (indirectly) both check this. */ + +unsigned int lineno = 1;/* Line number in the current input file. */ + +const char *lex_string = NULL;/* The string we are currently lexing, or |NULL| if we are reading a + file. */ + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result = yy_input (buf, max_size) +/* Support for \flex\ reading from more than one input file (stream). + |include_stack| is \flex's input state for each open file; + |file_name_stack| is the file names. |lineno_stack| is the current + line numbers. + + If |include_stack_ptr| is 0, we haven't started reading anything yet. + Otherwise, stack elements 0 through |include_stack_ptr - 1| are valid. */ + + +#ifndef YY_NO_UNPUT +#define YY_NO_UNPUT +#endif + +#define MAX_INCLUDE_DEPTH 10 +static YY_BUFFER_STATE@, @[include_stack[MAX_INCLUDE_DEPTH]@]; +static const char *file_name_stack[MAX_INCLUDE_DEPTH]; +static unsigned int lineno_stack[MAX_INCLUDE_DEPTH]; +static unsigned int sysrooted_stack[MAX_INCLUDE_DEPTH]; +static unsigned int include_stack_ptr = 0; +static int vers_node_nesting = 0; + +static int yy_input (char *, int); +static void comment (void); +static void lex_warn_invalid (char *where, char *what); + +#define RTOKEN(x) { yylval.token = x; return x; } + +#ifndef yywrap +int yywrap (void) { return 1; }/* Some versions of \flex\ want this. */ +#endif + +@ @<Ignored options@>= +@G +%a 4000 +%o 5000 +@g + +@ {\it Some convenient abbreviations for regular expressions.}% +\ifbootstrapmode\else\yyskipparsetrue\fi@<Original \ld\ macros@>= +@G +CMDFILENAMECHAR [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\-\~] +CMDFILENAMECHAR1 [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\~] +FILENAMECHAR1 [_a-zA-Z\/\.\\\$\_\~] +SYMBOLCHARN [_a-zA-Z\/\.\\\$\_\~0-9] +FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~] +WILDCHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*\^\!] +WHITE [ \t\n\r]+ +NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] +V_TAG [.$_a-zA-Z][._a-zA-Z0-9]* +V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* +@g + +@ {% +\def\aterm{\item{\sqbullet}\ignorespaces}% +\setbox0=\hbox{\sqbullet\enspace}% +\parindent=0pt +\advance\parindent by \wd0 +States: +\aterm |EXPRESSION| definitely in an expression + +\aterm |SCRIPT| definitely in a script + +\aterm |BOTH| either |EXPRESSION| or |SCRIPT| + +\aterm |DEFSYMEXP| in an argument to \.{--defsym} + +\aterm |MRI| in an \MRI\ script + +\aterm |VERS_START| starting a Sun style mapfile + +\aterm |VERS_SCRIPT| a Sun style mapfile + +\aterm |VERS_NODE| a node within a Sun style mapfile + +}% +\ifbootstrapmode\else\yyskipparsefalse\fi +@<\ld\ states@>= +@G +%s SCRIPT +%s EXPRESSION +%s BOTH +%s DEFSYMEXP +%s MRI +%s VERS_START +%s VERS_SCRIPT +%s VERS_NODE +@g + +@ @<\ld\ postamble@>= + if (parser_input != input_selected) + { + /* The first token of the input determines the initial parser state. */ + input_type t = parser_input; + parser_input = input_selected; + switch (t) + { + case input_script: return INPUT_SCRIPT; break; + case input_mri_script: return INPUT_MRI_SCRIPT; break; + case input_version_script: return INPUT_VERSION_SCRIPT; break; + case input_dynamic_list: return INPUT_DYNAMIC_LIST; break; + case input_defsym: return INPUT_DEFSYM; break; + default: abort (); + } +} + +@ @<Original \ld\ regular expressions@>= +@=<BOTH,SCRIPT,EXPRESSION,VERS_START,VERS_NODE,VERS_SCRIPT>"/*" {@> comment ();@+@=}@>@; +@G +<DEFSYMEXP>"-" {@>@[RTOKEN('-');@]@=} +<DEFSYMEXP>"+" {@>@[RTOKEN('+');@]@=} +<DEFSYMEXP>{FILENAMECHAR1}{SYMBOLCHARN}* {@>@[yylval.name = xstrdup (yytext);@+return NAME;@]@=} +<DEFSYMEXP>"=" {@>@[RTOKEN('=');@]@=} + +<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ { +@O + yylval.integer = bfd_scan_vma (yytext + 1, 0, 16); + yylval.bigint.str = NULL; + return INT; +@o +} + +<MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) { +@O + int ibase ; + switch (yytext[yyleng - 1]) { + case 'X': + case 'x': + case 'H': + case 'h': + ibase = 16; + break; + case 'O': + case 'o': + ibase = 8; + break; + case 'B': + case 'b': + ibase = 2; + break; + default: + ibase = 10; + } + yylval.integer = bfd_scan_vma (yytext, 0, + ibase); + yylval.bigint.str = NULL; + return INT; +@o +} + +<SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>((("$"|0[xX])([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? { +@O + char *s = yytext; + int ibase = 0; + + if (*s == '$') + { + ++s; + ibase = 16; + } + yylval.integer = bfd_scan_vma (s, 0, ibase); + yylval.bigint.str = NULL; + if (yytext[yyleng - 1] == 'M' + || yytext[yyleng - 1] == 'm') + { + yylval.integer *= 1024 * 1024; + } + else if (yytext[yyleng - 1] == 'K' + || yytext[yyleng - 1]=='k') + { + yylval.integer *= 1024; + } + else if (yytext[0] == '0' + && (yytext[1] == 'x' + || yytext[1] == 'X')) + { + yylval.bigint.str = xstrdup (yytext + 2); + } + return INT; +@o +} + +<BOTH,SCRIPT,EXPRESSION,MRI>"]" {@>@[RTOKEN(']');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"[" {@>@[RTOKEN('[');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"<<=" {@>@[RTOKEN(LSHIFTEQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>">>=" {@>@[RTOKEN(RSHIFTEQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"||" {@>@[RTOKEN(OROR);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"==" {@>@[RTOKEN(EQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"!=" {@>@[RTOKEN(NE);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>">=" {@>@[RTOKEN(GE);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"<=" {@>@[RTOKEN(LE);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"<<" {@>@[RTOKEN(LSHIFT);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>">>" {@>@[RTOKEN(RSHIFT);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"+=" {@>@[RTOKEN(PLUSEQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"-=" {@>@[RTOKEN(MINUSEQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"*=" {@>@[RTOKEN(MULTEQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"/=" {@>@[RTOKEN(DIVEQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"&=" {@>@[RTOKEN(ANDEQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"|=" {@>@[RTOKEN(OREQ);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"&&" {@>@[RTOKEN(ANDAND);@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>">" {@>@[RTOKEN('>');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"," {@>@[RTOKEN(',');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"&" {@>@[RTOKEN('&');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"|" {@>@[RTOKEN('|');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"~" {@>@[RTOKEN('~');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"!" {@>@[RTOKEN('!');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"?" {@>@[RTOKEN('?');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"*" {@>@[RTOKEN('*');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"+" {@>@[RTOKEN('+');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"-" {@>@[RTOKEN('-');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"/" {@>@[RTOKEN('/');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"%" {@>@[RTOKEN('%');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"<" {@>@[RTOKEN('<');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"=" {@>@[RTOKEN('=');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"}" {@>@[RTOKEN('}') ; @]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"{" {@>@[RTOKEN('{'); @]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>")" {@>@[RTOKEN(')');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>"(" {@>@[RTOKEN('(');@]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>":" {@>@[RTOKEN(':'); @]@=} +<BOTH,SCRIPT,EXPRESSION,MRI>";" {@>@[RTOKEN(';');@]@=} +<BOTH,SCRIPT>"MEMORY" {@>@[RTOKEN(MEMORY);@]@=} +<BOTH,SCRIPT>"REGION_ALIAS" {@>@[RTOKEN(REGION_ALIAS);@]@=} +<BOTH,SCRIPT>"LD_FEATURE" {@>@[RTOKEN(LD_FEATURE);@]@=} +<BOTH,SCRIPT,EXPRESSION>"ORIGIN" {@>@[RTOKEN(ORIGIN);@]@=} +<BOTH,SCRIPT>"VERSION" {@>@[RTOKEN(VERSIONK);@]@=} +<EXPRESSION,BOTH,SCRIPT>"BLOCK" {@>@[RTOKEN(BLOCK);@]@=} +<EXPRESSION,BOTH,SCRIPT>"BIND" {@>@[RTOKEN(BIND);@]@=} +<BOTH,SCRIPT,EXPRESSION>"LENGTH" {@>@[RTOKEN(LENGTH);@]@=} +<EXPRESSION,BOTH,SCRIPT>"ALIGN" {@>@[RTOKEN(ALIGN_K);@]@=} +<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_ALIGN" {@>@[RTOKEN(DATA_SEGMENT_ALIGN);@]@=} +<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_RELRO_END" {@>@[RTOKEN(DATA_SEGMENT_RELRO_END);@]@=} +<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_END" {@>@[RTOKEN(DATA_SEGMENT_END);@]@=} +<EXPRESSION,BOTH,SCRIPT>"ADDR" {@>@[RTOKEN(ADDR);@]@=} +<EXPRESSION,BOTH,SCRIPT>"LOADADDR" {@>@[RTOKEN(LOADADDR);@]@=} +<EXPRESSION,BOTH,SCRIPT>"ALIGNOF" {@>@[RTOKEN(ALIGNOF); @]@=} +<EXPRESSION,BOTH>"MAX" {@>@[RTOKEN(MAX_K); @]@=} +<EXPRESSION,BOTH>"MIN" {@>@[RTOKEN(MIN_K); @]@=} +<EXPRESSION,BOTH>"LOG2CEIL" {@>@[RTOKEN(LOG2CEIL); @]@=} +<EXPRESSION,BOTH,SCRIPT>"ASSERT" {@>@[RTOKEN(ASSERT_K); @]@=} +<BOTH,SCRIPT>"ENTRY" {@>@[RTOKEN(ENTRY);@]@=} +<BOTH,SCRIPT,MRI>"EXTERN" {@>@[RTOKEN(EXTERN);@]@=} +<EXPRESSION,BOTH,SCRIPT>"NEXT" {@>@[RTOKEN(NEXT);@]@=} +<EXPRESSION,BOTH,SCRIPT>"sizeof_headers" {@>@[RTOKEN(SIZEOF_HEADERS);@]@=} +<EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS" {@>@[RTOKEN(SIZEOF_HEADERS);@]@=} +<EXPRESSION,BOTH,SCRIPT>"SEGMENT_START" {@>@[RTOKEN(SEGMENT_START);@]@=} +<BOTH,SCRIPT>"MAP" {@>@[RTOKEN(MAP);@]@=} +<EXPRESSION,BOTH,SCRIPT>"SIZEOF" {@>@[RTOKEN(SIZEOF);@]@=} +<BOTH,SCRIPT>"TARGET" {@>@[RTOKEN(TARGET_K);@]@=} +<BOTH,SCRIPT>"SEARCH_DIR" {@>@[RTOKEN(SEARCH_DIR);@]@=} +<BOTH,SCRIPT>"OUTPUT" {@>@[RTOKEN(OUTPUT);@]@=} +<BOTH,SCRIPT>"INPUT" {@>@[RTOKEN(INPUT);@]@=} +<EXPRESSION,BOTH,SCRIPT>"GROUP" {@>@[RTOKEN(GROUP);@]@=} +<EXPRESSION,BOTH,SCRIPT>"AS_NEEDED" {@>@[RTOKEN(AS_NEEDED);@]@=} +<EXPRESSION,BOTH,SCRIPT>"DEFINED" {@>@[RTOKEN(DEFINED);@]@=} +<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" {@>@[RTOKEN(CREATE_OBJECT_SYMBOLS);@]@=} +<BOTH,SCRIPT>"CONSTRUCTORS" {@>@[RTOKEN( CONSTRUCTORS);@]@=} +<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" {@>@[RTOKEN(FORCE_COMMON_ALLOCATION);@]@=} +<BOTH,SCRIPT>"INHIBIT_COMMON_ALLOCATION" {@>@[RTOKEN(INHIBIT_COMMON_ALLOCATION);@]@=} +<BOTH,SCRIPT>"SECTIONS" {@>@[RTOKEN(SECTIONS);@]@=} +<BOTH,SCRIPT>"INSERT" {@>@[RTOKEN(INSERT_K);@]@=} +<BOTH,SCRIPT>"AFTER" {@>@[RTOKEN(AFTER);@]@=} +<BOTH,SCRIPT>"BEFORE" {@>@[RTOKEN(BEFORE);@]@=} +<BOTH,SCRIPT>"FILL" {@>@[RTOKEN(FILL);@]@=} +<BOTH,SCRIPT>"STARTUP" {@>@[RTOKEN(STARTUP);@]@=} +<BOTH,SCRIPT>"OUTPUT_FORMAT" {@>@[RTOKEN(OUTPUT_FORMAT);@]@=} +<BOTH,SCRIPT>"OUTPUT_ARCH" {@>@[RTOKEN( OUTPUT_ARCH);@]@=} +<BOTH,SCRIPT>"HLL" {@>@[RTOKEN(HLL);@]@=} +<BOTH,SCRIPT>"SYSLIB" {@>@[RTOKEN(SYSLIB);@]@=} +<BOTH,SCRIPT>"FLOAT" {@>@[RTOKEN(FLOAT);@]@=} +<BOTH,SCRIPT>"QUAD" {@>@[RTOKEN( QUAD);@]@=} +<BOTH,SCRIPT>"SQUAD" {@>@[RTOKEN( SQUAD);@]@=} +<BOTH,SCRIPT>"LONG" {@>@[RTOKEN( LONG);@]@=} +<BOTH,SCRIPT>"SHORT" {@>@[RTOKEN( SHORT);@]@=} +<BOTH,SCRIPT>"BYTE" {@>@[RTOKEN( BYTE);@]@=} +<BOTH,SCRIPT>"NOFLOAT" {@>@[RTOKEN(NOFLOAT);@]@=} +<EXPRESSION,BOTH,SCRIPT>"NOCROSSREFS" {@>@[RTOKEN(NOCROSSREFS);@]@=} +<BOTH,SCRIPT>"OVERLAY" {@>@[RTOKEN(OVERLAY); @]@=} +<BOTH,SCRIPT>"SORT_BY_NAME" {@>@[RTOKEN(SORT_BY_NAME); @]@=} +<BOTH,SCRIPT>"SORT_BY_ALIGNMENT" {@>@[RTOKEN(SORT_BY_ALIGNMENT); @]@=} +<BOTH,SCRIPT>"SORT" {@>@[RTOKEN(SORT_BY_NAME); @]@=} +<BOTH,SCRIPT>"SORT_BY_INIT_PRIORITY" {@>@[RTOKEN(SORT_BY_INIT_PRIORITY); @]@=} +<BOTH,SCRIPT>"SORT_NONE" {@>@[RTOKEN(SORT_NONE); @]@=} +<EXPRESSION,BOTH,SCRIPT>"NOLOAD" {@>@[RTOKEN(NOLOAD);@]@=} +<EXPRESSION,BOTH,SCRIPT>"DSECT" {@>@[RTOKEN(DSECT);@]@=} +<EXPRESSION,BOTH,SCRIPT>"COPY" {@>@[RTOKEN(COPY);@]@=} +<EXPRESSION,BOTH,SCRIPT>"INFO" {@>@[RTOKEN(INFO);@]@=} +<EXPRESSION,BOTH,SCRIPT>"OVERLAY" {@>@[RTOKEN(OVERLAY);@]@=} +<EXPRESSION,BOTH,SCRIPT>"ONLY_IF_RO" {@>@[RTOKEN(ONLY_IF_RO); @]@=} +<EXPRESSION,BOTH,SCRIPT>"ONLY_IF_RW" {@>@[RTOKEN(ONLY_IF_RW); @]@=} +<EXPRESSION,BOTH,SCRIPT>"SPECIAL" {@>@[RTOKEN(SPECIAL); @]@=} +<BOTH,SCRIPT>"o" {@>@[RTOKEN(ORIGIN);@]@=} +<BOTH,SCRIPT>"org" {@>@[RTOKEN(ORIGIN);@]@=} +<BOTH,SCRIPT>"l" {@>@[RTOKEN( LENGTH);@]@=} +<BOTH,SCRIPT>"len" {@>@[RTOKEN( LENGTH);@]@=} +<EXPRESSION,BOTH,SCRIPT>"INPUT_SECTION_FLAGS" {@>@[RTOKEN(INPUT_SECTION_FLAGS); @]@=} +<EXPRESSION,BOTH,SCRIPT>"INCLUDE" {@>@[RTOKEN(INCLUDE);@]@=} +<BOTH,SCRIPT>"PHDRS" {@>@[RTOKEN (PHDRS); @]@=} +<EXPRESSION,BOTH,SCRIPT>"AT" {@>@[RTOKEN(AT);@]@=} +<EXPRESSION,BOTH,SCRIPT>"ALIGN_WITH_INPUT" {@>@[RTOKEN(ALIGN_WITH_INPUT);@]@=} +<EXPRESSION,BOTH,SCRIPT>"SUBALIGN" {@>@[RTOKEN(SUBALIGN);@]@=} +<EXPRESSION,BOTH,SCRIPT>"HIDDEN" {@>@[RTOKEN(HIDDEN); @]@=} +<EXPRESSION,BOTH,SCRIPT>"PROVIDE" {@>@[RTOKEN(PROVIDE); @]@=} +<EXPRESSION,BOTH,SCRIPT>"PROVIDE_HIDDEN" {@>@[RTOKEN(PROVIDE_HIDDEN); @]@=} +<EXPRESSION,BOTH,SCRIPT>"KEEP" {@>@[RTOKEN(KEEP); @]@=} +<EXPRESSION,BOTH,SCRIPT>"EXCLUDE_FILE" {@>@[RTOKEN(EXCLUDE_FILE); @]@=} +<EXPRESSION,BOTH,SCRIPT>"CONSTANT" {@>@[RTOKEN(CONSTANT);@]@=} +<MRI>"#".*\n? {@>@[++ lineno; @]@=} +<MRI>"\n" {@> @[++lineno;@+RTOKEN(NEWLINE);@]@=} +<MRI>"*".* {}/* \MRI\ comment line */ +<MRI>";".* {}/* \MRI\ comment line */ +<MRI>"END" {@>@[RTOKEN(ENDWORD); @]@=} +<MRI>"ALIGNMOD" {@>@[RTOKEN(ALIGNMOD);@]@=} +<MRI>"ALIGN" {@>@[RTOKEN(ALIGN_K);@]@=} +<MRI>"CHIP" {@>@[RTOKEN(CHIP); @]@=} +<MRI>"BASE" {@>@[RTOKEN(BASE); @]@=} +<MRI>"ALIAS" {@>@[RTOKEN(ALIAS); @]@=} +<MRI>"TRUNCATE" {@>@[RTOKEN(TRUNCATE); @]@=} +<MRI>"LOAD" {@>@[RTOKEN(LOAD); @]@=} +<MRI>"PUBLIC" {@>@[RTOKEN(PUBLIC); @]@=} +<MRI>"ORDER" {@>@[RTOKEN(ORDER); @]@=} +<MRI>"NAME" {@>@[RTOKEN(NAMEWORD); @]@=} +<MRI>"FORMAT" {@>@[RTOKEN(FORMAT); @]@=} +<MRI>"CASE" {@>@[RTOKEN(CASE); @]@=} +<MRI>"START" {@>@[RTOKEN(START); @]@=} +<MRI>"LIST".* {@>@[RTOKEN(LIST); @]@=}/* \prodstyle{LIST} and ignore to end of line */ +<MRI>"SECT" {@>@[RTOKEN(SECT); @]@=} +<EXPRESSION,BOTH,SCRIPT,MRI>"ABSOLUTE" {@>@[RTOKEN(ABSOLUTE); @]@=} +<MRI>"end" {@>@[RTOKEN(ENDWORD); @]@=} +<MRI>"alignmod" {@>@[RTOKEN(ALIGNMOD);@]@=} +<MRI>"align" {@>@[RTOKEN(ALIGN_K);@]@=} +<MRI>"chip" {@>@[RTOKEN(CHIP); @]@=} +<MRI>"base" {@>@[RTOKEN(BASE); @]@=} +<MRI>"alias" {@>@[RTOKEN(ALIAS); @]@=} +<MRI>"truncate" {@>@[RTOKEN(TRUNCATE); @]@=} +<MRI>"load" {@>@[RTOKEN(LOAD); @]@=} +<MRI>"public" {@>@[RTOKEN(PUBLIC); @]@=} +<MRI>"order" {@>@[RTOKEN(ORDER); @]@=} +<MRI>"name" {@>@[RTOKEN(NAMEWORD); @]@=} +<MRI>"format" {@>@[RTOKEN(FORMAT); @]@=} +<MRI>"case" {@>@[RTOKEN(CASE); @]@=} +<MRI>"extern" {@>@[RTOKEN(EXTERN); @]@=} +<MRI>"start" {@>@[RTOKEN(START); @]@=} +<MRI>"list".* {@>@[RTOKEN(LIST); @]@=}/* \prodstyle{LIST} and ignore to end of line */ +<MRI>"sect" {@>@[RTOKEN(SECT); @]@=} +<EXPRESSION,BOTH,SCRIPT,MRI>"absolute" {@>@[RTOKEN(ABSOLUTE); @]@=} + +<MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}* { +@O +/* Filename without commas, needed to parse \MRI\ stuff */ + yylval.name = xstrdup (yytext); + return NAME; +@o +} +<BOTH>{FILENAMECHAR1}{FILENAMECHAR}* { +@O + yylval.name = xstrdup (yytext); + return NAME; +@o +} +<BOTH>"-l"{FILENAMECHAR}+ { +@O + yylval.name = xstrdup (yytext + 2); + return LNAME; +@o +} +<EXPRESSION>{FILENAMECHAR1}{NOCFILENAMECHAR}* { +@O + yylval.name = xstrdup (yytext); + return NAME; +@o +} +<EXPRESSION>"-l"{NOCFILENAMECHAR}+ { +@O + yylval.name = xstrdup (yytext + 2); + return LNAME; +@o +} +<SCRIPT>{WILDCHAR}* { +@O + /* Annoyingly, this pattern can match comments, and we have + longest match issues to consider. So if the first two + characters are a comment opening, put the input back and + try again. */ + if (yytext[0] == '/' && yytext[1] == '*') + { + yyless (2); + comment (); + } + else + { + yylval.name = xstrdup (yytext); + return NAME; + } +@o +} + +<EXPRESSION,BOTH,SCRIPT,VERS_NODE>"\""[^\"]*"\"" { +@O + /* No matter the state, quotes + give what's inside */ + yylval.name = xstrdup (yytext + 1); + yylval.name[yyleng - 2] = 0; + return NAME; +@o +} + +<BOTH,SCRIPT,EXPRESSION>"\n" {@>@[lineno++;@]@=} +<MRI,BOTH,SCRIPT,EXPRESSION>[ \t\r]+ {} + +<VERS_NODE,VERS_SCRIPT>[:,;] {@>@[return *yytext; @]@=} +<VERS_NODE>global {@>@[RTOKEN(GLOBAL); @]@=} +<VERS_NODE>local {@>@[RTOKEN(LOCAL); @]@=} +<VERS_NODE>extern {@>@[RTOKEN(EXTERN); @]@=} + +<VERS_NODE>{V_IDENTIFIER} { +@O + yylval.name = xstrdup (yytext); + return VERS_IDENTIFIER; +@o +} + +<VERS_SCRIPT>{V_TAG} { +@O + yylval.name = xstrdup (yytext); + return VERS_TAG; +@o +} + +<VERS_START>"{" {@>@[BEGIN(VERS_SCRIPT);@+return *yytext;@]@=} + +<VERS_SCRIPT>"{" { +@O + BEGIN(VERS_NODE); + vers_node_nesting = 0; + return *yytext; +@o +} + +<VERS_SCRIPT>"}" {@>@[return *yytext;@]@=} +<VERS_NODE>"{" {@>@[vers_node_nesting++;@+return *yytext;@]@=} + +<VERS_NODE>"}" { +@O + if (--vers_node_nesting < 0) + BEGIN(VERS_SCRIPT); + return *yytext; +@o +} + +<VERS_START,VERS_NODE,VERS_SCRIPT>[\n] {@>@[lineno++;@]@=} +<VERS_START,VERS_NODE,VERS_SCRIPT>#.* {}/* Eat up comments */ +<VERS_START,VERS_NODE,VERS_SCRIPT>[ \t\r]+ {}/* Eat up whitespace */ + +<<EOF>> { +@O + include_stack_ptr--; + if (include_stack_ptr == 0) + yyterminate (); + else + yy_switch_to_buffer (include_stack[include_stack_ptr]); + + lineno = lineno_stack[include_stack_ptr]; + input_flags.sysrooted = sysrooted_stack[include_stack_ptr]; + + return END; +@o +} + +<SCRIPT,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>. @>@[lex_warn_invalid (" in script", yytext);@] +<EXPRESSION,DEFSYMEXP,BOTH>. @>@[lex_warn_invalid (" in expression", yytext);@] +@g + +@ Switch \flex\ to reading script file |name|, open on |file|, +saving the current input info on the include stack. +@<Supporting \Cee\ code@>= +void +lex_push_file (FILE *file, const char *name, unsigned int sysrooted) +{ + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + { + einfo ("%F:includes nested too deeply\n"); + } + file_name_stack[include_stack_ptr] = name; + lineno_stack[include_stack_ptr] = lineno; + sysrooted_stack[include_stack_ptr] = input_flags.sysrooted; + include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; + + include_stack_ptr++; + lineno = 1; + input_flags.sysrooted = sysrooted; + yyin = file; + yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE)); +} + +@ Return a newly created \flex\ input buffer containing |string|, +which is |size| bytes long. +@<Supporting \Cee\ code@>= +static YY_BUFFER_STATE +yy_create_string_buffer (const char *string, size_t size) +{ + YY_BUFFER_STATE b; + + b = malloc (sizeof (struct yy_buffer_state));/* Calls to |malloc| get turned by sed into |xmalloc|. */ + b->yy_input_file = 0; + b->yy_buf_size = size; + + b->yy_ch_buf = malloc ((unsigned) (b->yy_buf_size + 3)); + /* |yy_ch_buf| has to be 2 characters longer than the size given because + we need to put in 2 end-of-buffer characters. */ + + b->yy_ch_buf[0] = '\n'; + strcpy (b->yy_ch_buf+1, string); + b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR; + b->yy_n_chars = size+1; + b->yy_buf_pos = &b->yy_ch_buf[1]; + + b->yy_is_our_buffer = 1; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + +#ifdef YY_BUFFER_NEW + b->yy_buffer_status = YY_BUFFER_NEW; +#else + b->yy_eof_status = EOF_NOT_SEEN; +#endif + + return b; +} + +@ Switch \flex\ to reading from |string|, saving the current input info +on the include stack. +@<Supporting \Cee\ code@>= +void +lex_redirect (const char *string, const char *fake_filename, unsigned int count) +{ + YY_BUFFER_STATE tmp; + + yy_init = 0; + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + { + einfo("%F: macros nested too deeply\n"); + } + file_name_stack[include_stack_ptr] = fake_filename; + lineno_stack[include_stack_ptr] = lineno; + include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; + include_stack_ptr++; + lineno = count; + tmp = yy_create_string_buffer (string, strlen (string)); + yy_switch_to_buffer (tmp); +} + +@ Functions to switch to a different \flex\ start condition, +saving the current start condition on |state_stack|. +@<Supporting \Cee\ code@>= +static int state_stack[MAX_INCLUDE_DEPTH * 2]; +static int *state_stack_p = state_stack; + +void +ldlex_script (void) +{ + *(state_stack_p)++ = yy_start; + BEGIN (SCRIPT); +} + +void +ldlex_mri_script (void) +{ + *(state_stack_p)++ = yy_start; + BEGIN (MRI); +} + +void +ldlex_version_script (void) +{ + *(state_stack_p)++ = yy_start; + BEGIN (VERS_START); +} + +void +ldlex_version_file (void) +{ + *(state_stack_p)++ = yy_start; + BEGIN (VERS_SCRIPT); +} + +void +ldlex_defsym (void) +{ + *(state_stack_p)++ = yy_start; + BEGIN (DEFSYMEXP); +} + +void +ldlex_expression (void) +{ + *(state_stack_p)++ = yy_start; + BEGIN (EXPRESSION); +} + +void +ldlex_both (void) +{ + *(state_stack_p)++ = yy_start; + BEGIN (BOTH); +} + +void +ldlex_popstate (void) +{ + yy_start = *(--state_stack_p); +} + +@ Return the current file name, or the previous file if no file is +current. +@<Supporting \Cee\ code@>= +const char* +ldlex_filename (void) +{ + return file_name_stack[include_stack_ptr - (include_stack_ptr != 0)]; +} + +@ Place up to |max_size| characters in |buf| and return +either the number of characters read, or 0 to indicate |EOF|. +@<Supporting \Cee\ code@>= +static int +yy_input (char *buf, int max_size) +{ + int result = 0; + if (YY_CURRENT_BUFFER->yy_input_file) + { + if (yyin) + { + result = fread (buf, 1, max_size, yyin); + if (result < max_size && ferror (yyin)) + einfo ("%F%P: read in flex scanner failed\n"); + } + } + return result; +} + +@ Eat the rest of a \Cee-style comment. +@<Supporting \Cee\ code@>= +static void +comment (void) +{ + int c; + + while (1) + { + c = input(); + while (c != '*' && c != EOF) + { + if (c == '\n') + lineno++; + c = input(); + } + + if (c == '*') + { + c = input(); + while (c == '*') + c = input(); + if (c == '/') + break; /* found the end */ + } + + if (c == '\n') + lineno++; + + if (c == EOF) + { + einfo( "%F%P: EOF in comment\n"); + break; + } + } +} + +@ Warn the user about a garbage character |what| in the input +in context |where|. +@<Supporting \Cee\ code@>= +static void +lex_warn_invalid (char *where, char *what) +{ + char buf[5]; + + if (ldfile_assumed_script) + { /* If we have found an input file whose format we do not recognize, + and we are therefore treating it as a linker script, and we find + an invalid character, then most likely this is a real object file + of some different format. Treat it as such. */ + + bfd_set_error (bfd_error_file_not_recognized); + einfo ("%F%s: file not recognized: %E\n", ldlex_filename ()); + } + + if (! ISPRINT (*what)) + { + sprintf (buf, "\\%03o", *(unsigned char *) what); + what = buf; + } + + einfo ("%P:%S: ignoring invalid character `%s'%s\n", NULL, what, where); +} |