%{ /* rclex.l -- lexer for Windows rc files parser */
-/* Copyright 1997 Free Software Foundation, Inc.
+/* Copyright 1997, 1998 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GNU Binutils.
#include <ctype.h>
#include <assert.h>
+/* Whether we are in rcdata mode, in which we returns the lengths of
+ strings. */
+
+static int rcdata_mode;
+
+/* List of allocated strings. */
+
+struct alloc_string
+{
+ struct alloc_string *next;
+ char *s;
+};
+
+static struct alloc_string *strings;
+
+/* Local functions. */
+
static void cpp_line PARAMS ((const char *));
-static char *handle_quotes PARAMS ((const char *));
+static char *handle_quotes PARAMS ((const char *, unsigned long *));
+static char *get_string PARAMS ((int));
%}
%%
"BEGIN" { return BEG; }
+"{" { return BEG; }
"END" { return END; }
+"}" { return END; }
"ACCELERATORS" { return ACCELERATORS; }
"VIRTKEY" { return VIRTKEY; }
"ASCII" { return ASCII; }
"ICON" { return ICON; }
"LANGUAGE" { return LANGUAGE; }
"CHARACTERISTICS" { return CHARACTERISTICS; }
-"VERSION" { return VERSION; }
+"VERSION" { return VERSIONK; }
"MENU" { return MENU; }
"MENUEX" { return MENUEX; }
"MENUITEM" { return MENUITEM; }
return BLOCKVARFILEINFO;
else
{
- yylval.s = (char *) xmalloc (send - s + 1);
- strncpy (yylval.s, s, send - s);
- yylval.s[send - s] = '\0';
+ char *r;
+
+ r = get_string (send - s + 1);
+ strncpy (r, s, send - s);
+ r[send - s] = '\0';
+ yylval.s = r;
return BLOCK;
}
}
}
("\""[^\"\n]*"\""[ \t]*)+ {
- yylval.s = handle_quotes (yytext);
- return QUOTEDSTRING;
+ char *s;
+ unsigned long length;
+
+ s = handle_quotes (yytext, &length);
+ if (! rcdata_mode)
+ {
+ yylval.s = s;
+ return QUOTEDSTRING;
+ }
+ else
+ {
+ yylval.ss.length = length;
+ yylval.ss.s = s;
+ return SIZEDSTRING;
+ }
}
-[A-Za-z][^ \t\r\n]* {
- yylval.s = xstrdup (yytext);
+[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;
return STRING;
}
merged separated by whitespace are merged, as in C. */
static char *
-handle_quotes (input)
+handle_quotes (input, len)
const char *input;
+ unsigned long *len;
{
char *ret, *s;
const char *t;
int ch;
- ret = (char *) xmalloc (strlen (input) + 1);
+ ret = get_string (strlen (input) + 1);
s = ret;
t = input;
rcparse_warning ("use \"\" to put \" in a string");
break;
+ case 'a':
+ *s++ = ESCAPE_A;
+ ++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;
}
*s++ = ch;
break;
+
+ default:
+ rcparse_warning ("unrecognized escape sequence");
+ *s++ = '\\';
+ *s++ = *t++;
+ break;
}
}
else if (*t != '"')
*s = '\0';
+ *len = s - ret;
+
return ret;
}
+
+/* Allocate a string of a given length. */
+
+static char *
+get_string (len)
+ int len;
+{
+ struct alloc_string *as;
+
+ as = (struct alloc_string *) xmalloc (sizeof *as);
+ as->s = xmalloc (len);
+
+ as->next = strings;
+ strings = as->next;
+
+ return as->s;
+}
+
+/* Discard all the strings we have allocated. The parser calls this
+ when it no longer needs them. */
+
+void
+rcparse_discard_strings ()
+{
+ 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 ()
+{
+ rcdata_mode = 1;
+}
+
+/* Go back to normal mode from rcdata mode. */
+
+void
+rcparse_normal ()
+{
+ rcdata_mode = 0;
+}