ENH: Improve handling of escaped characters
This commit is contained in:
parent
b7a2d11f2d
commit
1bbccc5bef
|
@ -341,8 +341,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
|
|||
*yy_cp = '\0'; \
|
||||
yyg->yy_c_buf_p = yy_cp;
|
||||
|
||||
#define YY_NUM_RULES 11
|
||||
#define YY_END_OF_BUFFER 12
|
||||
#define YY_NUM_RULES 12
|
||||
#define YY_END_OF_BUFFER 13
|
||||
/* This struct is not used in this scanner,
|
||||
but its presence is necessary. */
|
||||
struct yy_trans_info
|
||||
|
@ -352,8 +352,8 @@ struct yy_trans_info
|
|||
};
|
||||
static yyconst flex_int16_t yy_accept[20] =
|
||||
{ 0,
|
||||
0, 0, 12, 7, 8, 6, 5, 10, 9, 4,
|
||||
7, 0, 3, 6, 0, 7, 1, 2, 0
|
||||
0, 0, 13, 8, 9, 6, 5, 11, 10, 4,
|
||||
8, 0, 3, 6, 0, 7, 1, 2, 0
|
||||
} ;
|
||||
|
||||
static yyconst flex_int32_t yy_ec[256] =
|
||||
|
@ -859,7 +859,17 @@ YY_RULE_SETUP
|
|||
return cal_NAME;
|
||||
}
|
||||
case 7:
|
||||
/* rule 7 can match eol */
|
||||
YY_RULE_SETUP
|
||||
|
||||
{
|
||||
if ( !yyextra->HandleEscapeSymbol(yylvalp, *(yytext+1)) )
|
||||
{
|
||||
return cal_ERROR;
|
||||
}
|
||||
return cal_SYMBOL;
|
||||
}
|
||||
case 8:
|
||||
/* rule 8 can match eol */
|
||||
YY_RULE_SETUP
|
||||
|
||||
{
|
||||
|
@ -867,7 +877,7 @@ YY_RULE_SETUP
|
|||
yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
|
||||
return cal_SYMBOL;
|
||||
}
|
||||
case 8:
|
||||
case 9:
|
||||
YY_RULE_SETUP
|
||||
|
||||
{
|
||||
|
@ -875,7 +885,7 @@ YY_RULE_SETUP
|
|||
yylvalp->str = yyextra->m_DOLLARVariable;
|
||||
return cal_DOLLAR;
|
||||
}
|
||||
case 9:
|
||||
case 10:
|
||||
YY_RULE_SETUP
|
||||
|
||||
{
|
||||
|
@ -883,7 +893,7 @@ YY_RULE_SETUP
|
|||
yylvalp->str = yyextra->m_LCURLYVariable;
|
||||
return cal_LCURLY;
|
||||
}
|
||||
case 10:
|
||||
case 11:
|
||||
YY_RULE_SETUP
|
||||
|
||||
{
|
||||
|
@ -891,7 +901,7 @@ YY_RULE_SETUP
|
|||
yylvalp->str = yyextra->m_BSLASHVariable;
|
||||
return cal_BSLASH;
|
||||
}
|
||||
case 11:
|
||||
case 12:
|
||||
YY_RULE_SETUP
|
||||
|
||||
ECHO;
|
||||
|
@ -1220,7 +1230,6 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
|||
return yy_is_jam ? 0 : yy_current_state;
|
||||
}
|
||||
|
||||
|
||||
#ifndef YY_NO_INPUT
|
||||
#ifdef __cplusplus
|
||||
static int yyinput (yyscan_t yyscanner)
|
||||
|
|
|
@ -124,7 +124,15 @@ Modify cmCommandArgumentLexer.h:
|
|||
return cal_NAME;
|
||||
}
|
||||
|
||||
[^\${}\\@]+|\\. {
|
||||
\\. {
|
||||
if ( !yyextra->HandleEscapeSymbol(yylvalp, *(yytext+1)) )
|
||||
{
|
||||
return cal_ERROR;
|
||||
}
|
||||
return cal_SYMBOL;
|
||||
}
|
||||
|
||||
[^\${}\\@]+ {
|
||||
//std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
|
||||
yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
|
||||
return cal_SYMBOL;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "cmMakefile.h"
|
||||
|
||||
int cmCommandArgument_yyparse( yyscan_t yyscanner );
|
||||
|
||||
//
|
||||
cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
|
||||
{
|
||||
m_FileLine = -1;
|
||||
|
@ -35,6 +35,8 @@ cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
|
|||
strcpy(m_DOLLARVariable, "$");
|
||||
strcpy(m_LCURLYVariable, "{");
|
||||
strcpy(m_BSLASHVariable, "\\");
|
||||
|
||||
m_NoEscapeMode = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,6 +147,53 @@ void cmCommandArgumentParserHelper::AllocateParserType(cmCommandArgumentParserHe
|
|||
// std::cout << (void*) pt->str << " " << pt->str << " JPAllocateParserType" << std::endl;
|
||||
}
|
||||
|
||||
bool cmCommandArgumentParserHelper::HandleEscapeSymbol(cmCommandArgumentParserHelper::ParserType* pt, char symbol)
|
||||
{
|
||||
if ( m_NoEscapeMode )
|
||||
{
|
||||
char buffer[3];
|
||||
buffer[0] = '\\';
|
||||
buffer[1] = symbol;
|
||||
buffer[2] = 0;
|
||||
this->AllocateParserType(pt, buffer, 2);
|
||||
return true;
|
||||
}
|
||||
switch ( symbol )
|
||||
{
|
||||
case '\\':
|
||||
case '"':
|
||||
case ' ':
|
||||
case '#':
|
||||
case '(':
|
||||
case ')':
|
||||
case '$':
|
||||
case '^':
|
||||
case ';':
|
||||
this->AllocateParserType(pt, &symbol, 1);
|
||||
break;
|
||||
case 't':
|
||||
this->AllocateParserType(pt, "\t", 1);
|
||||
break;
|
||||
case 'n':
|
||||
this->AllocateParserType(pt, "\n", 1);
|
||||
break;
|
||||
case 'r':
|
||||
this->AllocateParserType(pt, "\r", 1);
|
||||
break;
|
||||
case '0':
|
||||
this->AllocateParserType(pt, "\0", 1);
|
||||
break;
|
||||
default:
|
||||
char buffer[2];
|
||||
buffer[0] = symbol;
|
||||
buffer[1] = 0;
|
||||
cmSystemTools::Error("Invalid escape sequence \\", buffer);
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int cmCommandArgumentParserHelper::ParseString(const char* str, int verb)
|
||||
{
|
||||
if ( !str)
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
// For the lexer:
|
||||
void AllocateParserType(cmCommandArgumentParserHelper::ParserType* pt,
|
||||
const char* str, int len = 0);
|
||||
bool HandleEscapeSymbol(cmCommandArgumentParserHelper::ParserType* pt, char symbol);
|
||||
|
||||
int LexInput(char* buf, int maxlen);
|
||||
void Error(const char* str);
|
||||
|
@ -64,6 +65,7 @@ public:
|
|||
|
||||
void SetLineFile(long line, const char* file);
|
||||
void SetEscapeQuotes(bool b) { m_EscapeQuotes = b; }
|
||||
void SetNoEscapeMode(bool b) { m_NoEscapeMode = b; }
|
||||
|
||||
const char* GetError() { return m_Error.c_str(); }
|
||||
|
||||
|
@ -97,6 +99,7 @@ private:
|
|||
long m_FileLine;
|
||||
bool m_EscapeQuotes;
|
||||
std::string m_Error;
|
||||
bool m_NoEscapeMode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -247,13 +247,13 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
|
|||
else if(token->type == cmListFileLexer_Token_Identifier ||
|
||||
token->type == cmListFileLexer_Token_ArgumentUnquoted)
|
||||
{
|
||||
cmListFileArgument a(cmSystemTools::RemoveEscapes(token->text),
|
||||
cmListFileArgument a(token->text,
|
||||
false, filename, token->line);
|
||||
function.m_Arguments.push_back(a);
|
||||
}
|
||||
else if(token->type == cmListFileLexer_Token_ArgumentQuoted)
|
||||
{
|
||||
cmListFileArgument a(cmSystemTools::RemoveEscapes(token->text),
|
||||
cmListFileArgument a(token->text,
|
||||
true, filename, token->line);
|
||||
function.m_Arguments.push_back(a);
|
||||
}
|
||||
|
|
|
@ -1361,17 +1361,18 @@ std::vector<std::string> cmMakefile::GetDefinitions(int cacheonly /* = 0 */) con
|
|||
|
||||
const char *cmMakefile::ExpandVariablesInString(std::string& source) const
|
||||
{
|
||||
return this->ExpandVariablesInString(source, false);
|
||||
return this->ExpandVariablesInString(source, false, false);
|
||||
}
|
||||
|
||||
const char *cmMakefile::ExpandVariablesInString(std::string& source,
|
||||
bool escapeQuotes,
|
||||
bool noEscapes,
|
||||
bool atOnly,
|
||||
const char* filename,
|
||||
long line,
|
||||
bool removeEmpty) const
|
||||
{
|
||||
if ( source.empty() || source.find_first_of("$@") == source.npos)
|
||||
if ( source.empty() || source.find_first_of("$@\\") == source.npos)
|
||||
{
|
||||
return source.c_str();
|
||||
}
|
||||
|
@ -1387,6 +1388,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
|
|||
parser.SetMakefile(this);
|
||||
parser.SetLineFile(line, filename);
|
||||
parser.SetEscapeQuotes(escapeQuotes);
|
||||
parser.SetNoEscapeMode(noEscapes);
|
||||
int res = parser.ParseString(source.c_str(), 0);
|
||||
if ( res )
|
||||
{
|
||||
|
@ -1703,7 +1705,7 @@ void cmMakefile::ExpandArguments(
|
|||
{
|
||||
// Expand the variables in the argument.
|
||||
value = i->Value;
|
||||
this->ExpandVariablesInString(value, false, false, i->FilePath, i->Line);
|
||||
this->ExpandVariablesInString(value, false, false, false, i->FilePath, i->Line);
|
||||
|
||||
// If the argument is quoted, it should be one argument.
|
||||
// Otherwise, it may be a list of arguments.
|
||||
|
@ -2353,7 +2355,7 @@ void cmMakefile::ConfigureString(const std::string& input,
|
|||
}
|
||||
|
||||
// Perform variable replacements.
|
||||
this->ExpandVariablesInString(output, escapeQuotes, atOnly, 0, -1, true);
|
||||
this->ExpandVariablesInString(output, escapeQuotes, true, atOnly, 0, -1, true);
|
||||
// this->RemoveVariablesInString(output, atOnly);
|
||||
}
|
||||
|
||||
|
|
|
@ -543,6 +543,7 @@ public:
|
|||
*/
|
||||
const char *ExpandVariablesInString(std::string& source) const;
|
||||
const char *ExpandVariablesInString(std::string& source, bool escapeQuotes,
|
||||
bool noEscapes,
|
||||
bool atOnly = false,
|
||||
const char* filename = 0,
|
||||
long line = -1,
|
||||
|
|
Loading…
Reference in New Issue