diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2011-04-24 20:14:55 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2011-04-24 20:14:55 +0000 |
commit | 917667791cb7410d22e23fdfd33147d2774974e1 (patch) | |
tree | 9bfba1b94a0818f8291398dd16027c3a35f1f07c /gnu/usr.bin/binutils-2.17/binutils/rclex.l | |
parent | ccf01298eb370933be2f6386e5502f7f812047bc (diff) |
Here comes the easter bunnytils 2.17 (the last version released against a
licence mere mortals can understand the terms of); will be connected to the
build on an arch-by-arch basis.
Testsuites and generated files have been intentionnaly omitted from this import.
Peer pressure and ok from at least drahn@ pirofti@ deraadt@
Diffstat (limited to 'gnu/usr.bin/binutils-2.17/binutils/rclex.l')
-rw-r--r-- | gnu/usr.bin/binutils-2.17/binutils/rclex.l | 504 |
1 files changed, 504 insertions, 0 deletions
diff --git a/gnu/usr.bin/binutils-2.17/binutils/rclex.l b/gnu/usr.bin/binutils-2.17/binutils/rclex.l new file mode 100644 index 00000000000..92b1ec73852 --- /dev/null +++ b/gnu/usr.bin/binutils-2.17/binutils/rclex.l @@ -0,0 +1,504 @@ +%{ /* rclex.l -- lexer for Windows rc files parser */ +/* Copyright 1997, 1998, 1999, 2001, 2002, 2003, 2005 + Free Software Foundation, Inc. + Written by Ian Lance Taylor, Cygnus Support. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* This is a lex input file which generates a lexer used by the + Windows rc file parser. It basically just recognized a bunch of + keywords. */ + +#include "bfd.h" +#include "bucomm.h" +#include "libiberty.h" +#include "safe-ctype.h" +#include "windres.h" +#include "rcparse.h" + +#include <assert.h> + +#define YY_NO_UNPUT + +/* Whether we are in rcdata mode, in which we returns the lengths of + strings. */ + +static int rcdata_mode; + +/* Whether we are supressing lines from cpp (including windows.h or + headers from your C sources may bring in externs and typedefs). + When active, we return IGNORED_TOKEN, which lets us ignore these + outside of resource constructs. Thus, it isn't required to protect + all the non-preprocessor lines in your header files with #ifdef + RC_INVOKED. It also means your RC file can't include other RC + files if they're named "*.h". Sorry. Name them *.rch or whatever. */ + +static int suppress_cpp_data; + +#define MAYBE_RETURN(x) return suppress_cpp_data ? IGNORED_TOKEN : (x) + +/* The first filename we detect in the cpp output. We use this to + tell included files from the original file. */ + +static char *initial_fn; + +/* List of allocated strings. */ + +struct alloc_string +{ + struct alloc_string *next; + char *s; +}; + +static struct alloc_string *strings; + +/* Local functions. */ + +static void cpp_line (const char *); +static char *handle_quotes (const char *, unsigned long *); +static char *get_string (int); + +%} + +%% + +"BEGIN" { MAYBE_RETURN (BEG); } +"{" { MAYBE_RETURN (BEG); } +"END" { MAYBE_RETURN (END); } +"}" { MAYBE_RETURN (END); } +"ACCELERATORS" { MAYBE_RETURN (ACCELERATORS); } +"VIRTKEY" { MAYBE_RETURN (VIRTKEY); } +"ASCII" { MAYBE_RETURN (ASCII); } +"NOINVERT" { MAYBE_RETURN (NOINVERT); } +"SHIFT" { MAYBE_RETURN (SHIFT); } +"CONTROL" { MAYBE_RETURN (CONTROL); } +"ALT" { MAYBE_RETURN (ALT); } +"BITMAP" { MAYBE_RETURN (BITMAP); } +"CURSOR" { MAYBE_RETURN (CURSOR); } +"DIALOG" { MAYBE_RETURN (DIALOG); } +"DIALOGEX" { MAYBE_RETURN (DIALOGEX); } +"EXSTYLE" { MAYBE_RETURN (EXSTYLE); } +"CAPTION" { MAYBE_RETURN (CAPTION); } +"CLASS" { MAYBE_RETURN (CLASS); } +"STYLE" { MAYBE_RETURN (STYLE); } +"AUTO3STATE" { MAYBE_RETURN (AUTO3STATE); } +"AUTOCHECKBOX" { MAYBE_RETURN (AUTOCHECKBOX); } +"AUTORADIOBUTTON" { MAYBE_RETURN (AUTORADIOBUTTON); } +"CHECKBOX" { MAYBE_RETURN (CHECKBOX); } +"COMBOBOX" { MAYBE_RETURN (COMBOBOX); } +"CTEXT" { MAYBE_RETURN (CTEXT); } +"DEFPUSHBUTTON" { MAYBE_RETURN (DEFPUSHBUTTON); } +"EDITTEXT" { MAYBE_RETURN (EDITTEXT); } +"GROUPBOX" { MAYBE_RETURN (GROUPBOX); } +"LISTBOX" { MAYBE_RETURN (LISTBOX); } +"LTEXT" { MAYBE_RETURN (LTEXT); } +"PUSHBOX" { MAYBE_RETURN (PUSHBOX); } +"PUSHBUTTON" { MAYBE_RETURN (PUSHBUTTON); } +"RADIOBUTTON" { MAYBE_RETURN (RADIOBUTTON); } +"RTEXT" { MAYBE_RETURN (RTEXT); } +"SCROLLBAR" { MAYBE_RETURN (SCROLLBAR); } +"STATE3" { MAYBE_RETURN (STATE3); } +"USERBUTTON" { MAYBE_RETURN (USERBUTTON); } +"BEDIT" { MAYBE_RETURN (BEDIT); } +"HEDIT" { MAYBE_RETURN (HEDIT); } +"IEDIT" { MAYBE_RETURN (IEDIT); } +"FONT" { MAYBE_RETURN (FONT); } +"ICON" { MAYBE_RETURN (ICON); } +"LANGUAGE" { MAYBE_RETURN (LANGUAGE); } +"CHARACTERISTICS" { MAYBE_RETURN (CHARACTERISTICS); } +"VERSION" { MAYBE_RETURN (VERSIONK); } +"MENU" { MAYBE_RETURN (MENU); } +"MENUEX" { MAYBE_RETURN (MENUEX); } +"MENUITEM" { MAYBE_RETURN (MENUITEM); } +"SEPARATOR" { MAYBE_RETURN (SEPARATOR); } +"POPUP" { MAYBE_RETURN (POPUP); } +"CHECKED" { MAYBE_RETURN (CHECKED); } +"GRAYED" { MAYBE_RETURN (GRAYED); } +"HELP" { MAYBE_RETURN (HELP); } +"INACTIVE" { MAYBE_RETURN (INACTIVE); } +"MENUBARBREAK" { MAYBE_RETURN (MENUBARBREAK); } +"MENUBREAK" { MAYBE_RETURN (MENUBREAK); } +"MESSAGETABLE" { MAYBE_RETURN (MESSAGETABLE); } +"RCDATA" { MAYBE_RETURN (RCDATA); } +"STRINGTABLE" { MAYBE_RETURN (STRINGTABLE); } +"VERSIONINFO" { MAYBE_RETURN (VERSIONINFO); } +"FILEVERSION" { MAYBE_RETURN (FILEVERSION); } +"PRODUCTVERSION" { MAYBE_RETURN (PRODUCTVERSION); } +"FILEFLAGSMASK" { MAYBE_RETURN (FILEFLAGSMASK); } +"FILEFLAGS" { MAYBE_RETURN (FILEFLAGS); } +"FILEOS" { MAYBE_RETURN (FILEOS); } +"FILETYPE" { MAYBE_RETURN (FILETYPE); } +"FILESUBTYPE" { MAYBE_RETURN (FILESUBTYPE); } +"VALUE" { MAYBE_RETURN (VALUE); } +"MOVEABLE" { MAYBE_RETURN (MOVEABLE); } +"FIXED" { MAYBE_RETURN (FIXED); } +"PURE" { MAYBE_RETURN (PURE); } +"IMPURE" { MAYBE_RETURN (IMPURE); } +"PRELOAD" { MAYBE_RETURN (PRELOAD); } +"LOADONCALL" { MAYBE_RETURN (LOADONCALL); } +"DISCARDABLE" { MAYBE_RETURN (DISCARDABLE); } +"NOT" { MAYBE_RETURN (NOT); } + +"BLOCK"[ \t\n]*"\""[^\#\n]*"\"" { + char *s, *send; + + /* This is a hack to let us parse version + information easily. */ + + s = strchr (yytext, '"'); + ++s; + send = strchr (s, '"'); + if (strncmp (s, "StringFileInfo", + sizeof "StringFileInfo" - 1) == 0 + && s + sizeof "StringFileInfo" - 1 == send) + MAYBE_RETURN (BLOCKSTRINGFILEINFO); + else if (strncmp (s, "VarFileInfo", + sizeof "VarFileInfo" - 1) == 0 + && s + sizeof "VarFileInfo" - 1 == send) + MAYBE_RETURN (BLOCKVARFILEINFO); + else + { + char *r; + + r = get_string (send - s + 1); + strncpy (r, s, send - s); + r[send - s] = '\0'; + yylval.s = r; + MAYBE_RETURN (BLOCK); + } + } + +"#"[^\n]* { + cpp_line (yytext); + } + +[0-9][x0-9A-Fa-f]*L { + yylval.i.val = strtoul (yytext, 0, 0); + yylval.i.dword = 1; + MAYBE_RETURN (NUMBER); + } + +[0-9][x0-9A-Fa-f]* { + yylval.i.val = strtoul (yytext, 0, 0); + yylval.i.dword = 0; + MAYBE_RETURN (NUMBER); + } + +("\""[^\"\n]*"\""[ \t\n]*)+ { + char *s; + unsigned long length; + + s = handle_quotes (yytext, &length); + if (! rcdata_mode) + { + yylval.s = s; + MAYBE_RETURN (QUOTEDSTRING); + } + else + { + yylval.ss.length = length; + yylval.ss.s = s; + MAYBE_RETURN (SIZEDSTRING); + } + } + +[A-Za-z][^ ,\t\r\n]* { + char *s; + + /* I rejected comma in a string in order to + handle VIRTKEY, CONTROL in an accelerator + resource. This means that an unquoted + file name can not contain a comma. I + don't know what rc permits. */ + + s = get_string (strlen (yytext) + 1); + strcpy (s, yytext); + yylval.s = s; + MAYBE_RETURN (STRING); + } + +[\n] { ++rc_lineno; } +[ \t\r]+ { /* ignore whitespace */ } +. { MAYBE_RETURN (*yytext); } + +%% +#ifndef yywrap +/* This is needed for some versions of lex. */ +int yywrap (void) +{ + return 1; +} +#endif + +/* Handle a C preprocessor line. */ + +static void +cpp_line (const char *s) +{ + int line; + char *send, *fn; + + ++s; + while (ISSPACE (*s)) + ++s; + + line = strtol (s, &send, 0); + if (*send != '\0' && ! ISSPACE (*send)) + return; + + /* Subtract 1 because we are about to count the newline. */ + rc_lineno = line - 1; + + s = send; + while (ISSPACE (*s)) + ++s; + + if (*s != '"') + return; + + ++s; + send = strchr (s, '"'); + if (send == NULL) + return; + + fn = (char *) xmalloc (send - s + 1); + strncpy (fn, s, send - s); + fn[send - s] = '\0'; + + free (rc_filename); + rc_filename = fn; + + if (!initial_fn) + { + initial_fn = xmalloc (strlen (fn) + 1); + strcpy (initial_fn, fn); + } + + /* Allow the initial file, regardless of name. Suppress all other + files if they end in ".h" (this allows included "*.rc"). */ + if (strcmp (initial_fn, fn) == 0 + || strcmp (fn + strlen (fn) - 2, ".h") != 0) + suppress_cpp_data = 0; + else + suppress_cpp_data = 1; +} + +/* Handle a quoted string. The quotes are stripped. A pair of quotes + in a string are turned into a single quote. Adjacent strings are + merged separated by whitespace are merged, as in C. */ + +static char * +handle_quotes (const char *input, unsigned long *len) +{ + char *ret, *s; + const char *t; + int ch; + int num_xdigits; + + ret = get_string (strlen (input) + 1); + + s = ret; + t = input; + if (*t == '"') + ++t; + while (*t != '\0') + { + if (*t == '\\') + { + ++t; + switch (*t) + { + case '\0': + rcparse_warning ("backslash at end of string"); + break; + + case '\"': + rcparse_warning ("use \"\" to put \" in a string"); + break; + + case 'a': + *s++ = ESCAPE_B; /* Strange, but true... */ + ++t; + break; + + case 'b': + *s++ = ESCAPE_B; + ++t; + break; + + case 'f': + *s++ = ESCAPE_F; + ++t; + break; + + case 'n': + *s++ = ESCAPE_N; + ++t; + break; + + case 'r': + *s++ = ESCAPE_R; + ++t; + break; + + case 't': + *s++ = ESCAPE_T; + ++t; + break; + + case 'v': + *s++ = ESCAPE_V; + ++t; + break; + + case '\\': + *s++ = *t++; + break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + ch = *t - '0'; + ++t; + if (*t >= '0' && *t <= '7') + { + ch = (ch << 3) | (*t - '0'); + ++t; + if (*t >= '0' && *t <= '7') + { + ch = (ch << 3) | (*t - '0'); + ++t; + } + } + *s++ = ch; + break; + + case 'x': + ++t; + ch = 0; + /* We only handle single byte chars here. Make sure + we finish an escape sequence like "/xB0ABC" after + the first two digits. */ + num_xdigits = 2; + while (num_xdigits--) + { + if (*t >= '0' && *t <= '9') + ch = (ch << 4) | (*t - '0'); + else if (*t >= 'a' && *t <= 'f') + ch = (ch << 4) | (*t - 'a' + 10); + else if (*t >= 'A' && *t <= 'F') + ch = (ch << 4) | (*t - 'A' + 10); + else + break; + ++t; + } + *s++ = ch; + break; + + default: + rcparse_warning ("unrecognized escape sequence"); + *s++ = '\\'; + *s++ = *t++; + break; + } + } + else if (*t != '"') + *s++ = *t++; + else if (t[1] == '\0') + break; + else if (t[1] == '"') + { + *s++ = '"'; + t += 2; + } + else + { + ++t; + assert (ISSPACE (*t)); + while (ISSPACE (*t)) + { + if ((*t) == '\n') + ++rc_lineno; + ++t; + } + if (*t == '\0') + break; + assert (*t == '"'); + ++t; + } + } + + *s = '\0'; + + *len = s - ret; + + return ret; +} + +/* Allocate a string of a given length. */ + +static char * +get_string (int len) +{ + struct alloc_string *as; + + as = (struct alloc_string *) xmalloc (sizeof *as); + as->s = xmalloc (len); + + as->next = strings; + strings = as; + + return as->s; +} + +/* Discard all the strings we have allocated. The parser calls this + when it no longer needs them. */ + +void +rcparse_discard_strings (void) +{ + struct alloc_string *as; + + as = strings; + while (as != NULL) + { + struct alloc_string *n; + + free (as->s); + n = as->next; + free (as); + as = n; + } + + strings = NULL; +} + +/* Enter rcdata mode. */ + +void +rcparse_rcdata (void) +{ + rcdata_mode = 1; +} + +/* Go back to normal mode from rcdata mode. */ + +void +rcparse_normal (void) +{ + rcdata_mode = 0; +} |