/* rclex.c -- lexer for Windows rc files parser */
-/* Copyright 1997, 1998, 1999, 2001, 2002, 2003, 2005, 2006, 2007
- Free Software Foundation, Inc.
+/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
Written by Kai Tietz, Onevision.
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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
+
/* This is a lexer used by the Windows rc file parser. It basically
just recognized a bunch of keywords. */
static int rcdata_mode;
-/* Whether we are supressing lines from cpp (including windows.h or
+/* Whether we are suppressing 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
const char *s = rclex_tok;
int line;
char *send, *fn;
+ size_t len, mlen;
++s;
while (ISSPACE (*s))
++s;
-
+
+ /* Check for #pragma code_page ( DEFAULT | <nr>). */
+ len = strlen (s);
+ mlen = strlen ("pragma");
+ if (len > mlen && memcmp (s, "pragma", mlen) == 0 && ISSPACE (s[mlen]))
+ {
+ const char *end;
+
+ s += mlen + 1;
+ while (ISSPACE (*s))
+ ++s;
+ len = strlen (s);
+ mlen = strlen ("code_page");
+ if (len <= mlen || memcmp (s, "code_page", mlen) != 0)
+ /* FIXME: We ought to issue a warning message about an unrecognised pragma. */
+ return;
+ s += mlen;
+ while (ISSPACE (*s))
+ ++s;
+ if (*s != '(')
+ /* FIXME: We ought to issue an error message about a malformed pragma. */
+ return;
+ ++s;
+ while (ISSPACE (*s))
+ ++s;
+ if (*s == 0 || (end = strchr (s, ')')) == NULL)
+ /* FIXME: We ought to issue an error message about a malformed pragma. */
+ return;
+ len = (size_t) (end - s);
+ fn = xmalloc (len + 1);
+ if (len)
+ memcpy (fn, s, len);
+ fn[len] = 0;
+ while (len > 0 && (fn[len - 1] > 0 && fn[len - 1] <= 0x20))
+ fn[--len] = 0;
+ if (! len || (len == strlen ("DEFAULT") && strcasecmp (fn, "DEFAULT") == 0))
+ wind_current_codepage = wind_default_codepage;
+ else if (len > 0)
+ {
+ rc_uint_type ncp;
+
+ if (fn[0] == '0' && (fn[1] == 'x' || fn[1] == 'X'))
+ ncp = (rc_uint_type) strtol (fn + 2, NULL, 16);
+ else
+ ncp = (rc_uint_type) strtol (fn, NULL, 10);
+ if (ncp == CP_UTF16 || ! unicode_is_valid_codepage (ncp))
+ fatal (_("invalid value specified for pragma code_page.\n"));
+ wind_current_codepage = ncp;
+ }
+ free (fn);
+ return;
+ }
+
line = strtol (s, &send, 0);
if (*send != '\0' && ! ISSPACE (*send))
return;
}
else
{
- rcparse_warning ("unexpected character after '\"'");
++t;
- assert (ISSPACE (*t));
+ if (! ISSPACE (*t))
+ rcparse_warning ("unexpected character after '\"'");
while (ISSPACE (*t))
{
if ((*t) == '\n')
rclex_string (void)
{
int c;
-
+
while ((c = rclex_peekch ()) != -1)
{
if (c == '\n')
}
else if (rclex_readch () == '"')
{
+ /* PR 6714
+ Skip any whitespace after the end of the double quotes. */
+ do
+ {
+ c = rclex_peekch ();
+ if (ISSPACE (c))
+ rclex_readch ();
+ else
+ c = -1;
+ }
+ while (c != -1);
+
if (rclex_peekch () == '"')
rclex_readch ();
else
/* Clear token. */
rclex_tok_pos = 0;
rclex_tok[0] = 0;
-
+
if ((ch = rclex_readch ()) == -1)
return -1;
if (ch == '\n')
cpp_line ();
ch = IGNORED_TOKEN;
break;
-
+
case '{':
ch = IGNORE_CPP (BEG);
break;
-
+
case '}':
ch = IGNORE_CPP (END);
break;
-
+
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
yylval.i.val = read_digit (ch);
default:
if (ISIDST (ch) || ch=='$')
{
- while ((ch = rclex_peekch ()) != -1 && (ISIDNUM (ch) || ch == '$' || ch == '.'))
+ while ((ch = rclex_peekch ()) != -1
+ && (ISIDNUM (ch) || ch == '$' || ch == '.'
+ || ch == ':' || ch == '\\' || ch == '/'
+ || ch == '_' || ch == '-')
+ )
rclex_readch ();
ch = IGNORE_CPP (rclex_translatekeyword (rclex_tok));
if (ch == STRING)