Refactor getting children name, value and type access
[deliverable/binutils-gdb.git] / binutils / rclex.l
index 06a66077f287aba5c74ce3f43a7b803473cca438..92b1ec738526786bed9088739bed5e69bd682f10 100644 (file)
@@ -1,5 +1,6 @@
 %{ /* rclex.l -- lexer for Windows rc files parser  */
-/* Copyright 1997, 1998 Free Software Foundation, Inc.
+/* 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.
@@ -16,8 +17,8 @@
 
    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., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   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
 #include "bfd.h"
 #include "bucomm.h"
 #include "libiberty.h"
+#include "safe-ctype.h"
 #include "windres.h"
 #include "rcparse.h"
 
-#include <ctype.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
@@ -49,90 +69,90 @@ static struct alloc_string *strings;
 
 /* Local functions.  */
 
-static void cpp_line PARAMS ((const char *));
-static char *handle_quotes PARAMS ((const char *, unsigned long *));
-static char *get_string PARAMS ((int));
+static void cpp_line (const char *);
+static char *handle_quotes (const char *, unsigned long *);
+static char *get_string (int);
 
 %}
 
 %%
 
-"BEGIN"                        { return BEG; }
-"{"                    { return BEG; }
-"END"                  { return END; }
-"}"                    { return END; }
-"ACCELERATORS"         { return ACCELERATORS; }
-"VIRTKEY"              { return VIRTKEY; }
-"ASCII"                        { return ASCII; }
-"NOINVERT"             { return NOINVERT; }
-"SHIFT"                        { return SHIFT; }
-"CONTROL"              { return CONTROL; }
-"ALT"                  { return ALT; }
-"BITMAP"               { return BITMAP; }
-"CURSOR"               { return CURSOR; }
-"DIALOG"               { return DIALOG; }
-"DIALOGEX"             { return DIALOGEX; }
-"EXSTYLE"              { return EXSTYLE; }
-"CAPTION"              { return CAPTION; }
-"CLASS"                        { return CLASS; }
-"STYLE"                        { return STYLE; }
-"AUTO3STATE"           { return AUTO3STATE; }
-"AUTOCHECKBOX"         { return AUTOCHECKBOX; }
-"AUTORADIOBUTTON"      { return AUTORADIOBUTTON; }
-"CHECKBOX"             { return CHECKBOX; }
-"COMBOBOX"             { return COMBOBOX; }
-"CTEXT"                        { return CTEXT; }
-"DEFPUSHBUTTON"                { return DEFPUSHBUTTON; }
-"EDITTEXT"             { return EDITTEXT; }
-"GROUPBOX"             { return GROUPBOX; }
-"LISTBOX"              { return LISTBOX; }
-"LTEXT"                        { return LTEXT; }
-"PUSHBOX"              { return PUSHBOX; }
-"PUSHBUTTON"           { return PUSHBUTTON; }
-"RADIOBUTTON"          { return RADIOBUTTON; }
-"RTEXT"                        { return RTEXT; }
-"SCROLLBAR"            { return SCROLLBAR; }
-"STATE3"               { return STATE3; }
-"USERBUTTON"           { return USERBUTTON; }
-"BEDIT"                        { return BEDIT; }
-"HEDIT"                        { return HEDIT; }
-"IEDIT"                        { return IEDIT; }
-"FONT"                 { return FONT; }
-"ICON"                 { return ICON; }
-"LANGUAGE"             { return LANGUAGE; }
-"CHARACTERISTICS"      { return CHARACTERISTICS; }
-"VERSION"              { return VERSIONK; }
-"MENU"                 { return MENU; }
-"MENUEX"               { return MENUEX; }
-"MENUITEM"             { return MENUITEM; }
-"SEPARATOR"            { return SEPARATOR; }
-"POPUP"                        { return POPUP; }
-"CHECKED"              { return CHECKED; }
-"GRAYED"               { return GRAYED; }
-"HELP"                 { return HELP; }
-"INACTIVE"             { return INACTIVE; }
-"MENUBARBREAK"         { return MENUBARBREAK; }
-"MENUBREAK"            { return MENUBREAK; }
-"MESSAGETABLE"         { return MESSAGETABLE; }
-"RCDATA"               { return RCDATA; }
-"STRINGTABLE"          { return STRINGTABLE; }
-"VERSIONINFO"          { return VERSIONINFO; }
-"FILEVERSION"          { return FILEVERSION; }
-"PRODUCTVERSION"       { return PRODUCTVERSION; }
-"FILEFLAGSMASK"                { return FILEFLAGSMASK; }
-"FILEFLAGS"            { return FILEFLAGS; }
-"FILEOS"               { return FILEOS; }
-"FILETYPE"             { return FILETYPE; }
-"FILESUBTYPE"          { return FILESUBTYPE; }
-"VALUE"                        { return VALUE; }
-"MOVEABLE"             { return MOVEABLE; }
-"FIXED"                        { return FIXED; }
-"PURE"                 { return PURE; }
-"IMPURE"               { return IMPURE; }
-"PRELOAD"              { return PRELOAD; }
-"LOADONCALL"           { return LOADONCALL; }
-"DISCARDABLE"          { return DISCARDABLE; }
-"NOT"                  { return NOT; }
+"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;
@@ -146,11 +166,11 @@ static char *get_string PARAMS ((int));
                          if (strncmp (s, "StringFileInfo",
                                       sizeof "StringFileInfo" - 1) == 0
                              && s + sizeof "StringFileInfo" - 1 == send)
-                           return BLOCKSTRINGFILEINFO;
+                           MAYBE_RETURN (BLOCKSTRINGFILEINFO);
                          else if (strncmp (s, "VarFileInfo",
                                            sizeof "VarFileInfo" - 1) == 0
                                   && s + sizeof "VarFileInfo" - 1 == send)
-                           return BLOCKVARFILEINFO;
+                           MAYBE_RETURN (BLOCKVARFILEINFO);
                          else
                            {
                              char *r;
@@ -159,7 +179,7 @@ static char *get_string PARAMS ((int));
                              strncpy (r, s, send - s);
                              r[send - s] = '\0';
                              yylval.s = r;
-                             return BLOCK;
+                             MAYBE_RETURN (BLOCK);
                            }
                        }
 
@@ -170,16 +190,16 @@ static char *get_string PARAMS ((int));
 [0-9][x0-9A-Fa-f]*L    {
                          yylval.i.val = strtoul (yytext, 0, 0);
                          yylval.i.dword = 1;
-                         return NUMBER;
+                         MAYBE_RETURN (NUMBER);
                        }
 
 [0-9][x0-9A-Fa-f]*     {
                          yylval.i.val = strtoul (yytext, 0, 0);
                          yylval.i.dword = 0;
-                         return NUMBER;
+                         MAYBE_RETURN (NUMBER);
                        }
 
-("\""[^\"\n]*"\""[ \t]*)+ {
+("\""[^\"\n]*"\""[ \t\n]*)+ {
                          char *s;
                          unsigned long length;
 
@@ -187,13 +207,13 @@ static char *get_string PARAMS ((int));
                          if (! rcdata_mode)
                            {
                              yylval.s = s;
-                             return QUOTEDSTRING;
+                             MAYBE_RETURN (QUOTEDSTRING);
                            }
                          else
                            {
                              yylval.ss.length = length;
                              yylval.ss.s = s;
-                             return SIZEDSTRING;
+                             MAYBE_RETURN (SIZEDSTRING);
                            }
                        }
 
@@ -209,17 +229,17 @@ static char *get_string PARAMS ((int));
                          s = get_string (strlen (yytext) + 1);
                          strcpy (s, yytext);
                          yylval.s = s;
-                         return STRING;
+                         MAYBE_RETURN (STRING);
                        }
 
 [\n]                   { ++rc_lineno; }
 [ \t\r]+               { /* ignore whitespace */ }
-.                      { return *yytext; }
+.                      { MAYBE_RETURN (*yytext); }
 
 %%
 #ifndef yywrap
 /* This is needed for some versions of lex.  */
-int yywrap ()
+int yywrap (void)
 {
   return 1;
 }
@@ -228,25 +248,24 @@ int yywrap ()
 /* Handle a C preprocessor line.  */
 
 static void
-cpp_line (s)
-     const char *s;
+cpp_line (const char *s)
 {
   int line;
   char *send, *fn;
 
   ++s;
-  while (isspace ((unsigned char) *s))
+  while (ISSPACE (*s))
     ++s;
   
   line = strtol (s, &send, 0);
-  if (*send != '\0' && ! isspace ((unsigned char) *send))
+  if (*send != '\0' && ! ISSPACE (*send))
     return;
 
   /* Subtract 1 because we are about to count the newline.  */
   rc_lineno = line - 1;
 
   s = send;
-  while (isspace ((unsigned char) *s))
+  while (ISSPACE (*s))
     ++s;
 
   if (*s != '"')
@@ -263,6 +282,20 @@ cpp_line (s)
 
   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
@@ -270,13 +303,12 @@ cpp_line (s)
    merged separated by whitespace are merged, as in C.  */
 
 static char *
-handle_quotes (input, len)
-     const char *input;
-     unsigned long *len;
+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);
 
@@ -300,7 +332,7 @@ handle_quotes (input, len)
              break;
 
            case 'a':
-             *s++ = ESCAPE_A;
+             *s++ = ESCAPE_B; /* Strange, but true...  */
              ++t;
              break;
 
@@ -358,14 +390,18 @@ handle_quotes (input, len)
            case 'x':
              ++t;
              ch = 0;
-             while (1)
+             /* 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');
+                   ch = (ch << 4) | (*t - 'a' + 10);
                  else if (*t >= 'A' && *t <= 'F')
-                   ch = (ch << 4) | (*t - 'A');
+                   ch = (ch << 4) | (*t - 'A' + 10);
                  else
                    break;
                  ++t;
@@ -392,9 +428,13 @@ handle_quotes (input, len)
       else
        {
          ++t;
-         assert (isspace ((unsigned char) *t));
-         while (isspace ((unsigned char) *t))
-           ++t;
+         assert (ISSPACE (*t));
+         while (ISSPACE (*t))
+           {
+             if ((*t) == '\n')
+               ++rc_lineno;
+             ++t;
+           }
          if (*t == '\0')
            break;
          assert (*t == '"');
@@ -412,8 +452,7 @@ handle_quotes (input, len)
 /* Allocate a string of a given length.  */
 
 static char *
-get_string (len)
-     int len;
+get_string (int len)
 {
   struct alloc_string *as;
 
@@ -421,7 +460,7 @@ get_string (len)
   as->s = xmalloc (len);
 
   as->next = strings;
-  strings = as->next;
+  strings = as;
 
   return as->s;
 }
@@ -430,7 +469,7 @@ get_string (len)
    when it no longer needs them.  */
 
 void
-rcparse_discard_strings ()
+rcparse_discard_strings (void)
 {
   struct alloc_string *as;
 
@@ -451,7 +490,7 @@ rcparse_discard_strings ()
 /* Enter rcdata mode.  */
 
 void
-rcparse_rcdata ()
+rcparse_rcdata (void)
 {
   rcdata_mode = 1;
 }
@@ -459,7 +498,7 @@ rcparse_rcdata ()
 /* Go back to normal mode from rcdata mode.  */
 
 void
-rcparse_normal ()
+rcparse_normal (void)
 {
   rcdata_mode = 0;
 }
This page took 0.031778 seconds and 4 git commands to generate.