X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Frclex.c;h=37d4309f48dd67ab55dce08271619ae61ad8cac0;hb=229a22cfd2fd3c82a1b57d4af104f361cb0b0a33;hp=edcf2cece6b30cbdca2348accc23293103b22fe5;hpb=4a594fce16683232bbb2e239d3e3ebcfcde16d1a;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/rclex.c b/binutils/rclex.c index edcf2cece6..37d4309f48 100644 --- a/binutils/rclex.c +++ b/binutils/rclex.c @@ -1,7 +1,6 @@ /* 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-2019 Free Software Foundation, Inc. Written by Kai Tietz, Onevision. @@ -9,7 +8,7 @@ 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, @@ -22,6 +21,7 @@ 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. */ @@ -40,7 +40,7 @@ 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 @@ -142,11 +142,64 @@ cpp_line (void) 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 | ). */ + 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; @@ -336,9 +389,9 @@ handle_quotes (rc_uint_type *len) } else { - rcparse_warning ("unexpected character after '\"'"); ++t; - assert (ISSPACE (*t)); + if (! ISSPACE (*t)) + rcparse_warning ("unexpected character after '\"'"); while (ISSPACE (*t)) { if ((*t) == '\n') @@ -625,7 +678,7 @@ static void rclex_string (void) { int c; - + while ((c = rclex_peekch ()) != -1) { if (c == '\n') @@ -639,6 +692,18 @@ rclex_string (void) } 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 @@ -716,7 +781,7 @@ yylex (void) /* Clear token. */ rclex_tok_pos = 0; rclex_tok[0] = 0; - + if ((ch = rclex_readch ()) == -1) return -1; if (ch == '\n') @@ -732,15 +797,15 @@ yylex (void) 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); @@ -790,7 +855,11 @@ yylex (void) 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)