ENH: Improve handling of escaped characters

This commit is contained in:
Andy Cedilnik 2005-06-17 15:50:08 -04:00
parent b7a2d11f2d
commit 1bbccc5bef
7 changed files with 90 additions and 18 deletions

View File

@ -341,8 +341,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
*yy_cp = '\0'; \ *yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp; yyg->yy_c_buf_p = yy_cp;
#define YY_NUM_RULES 11 #define YY_NUM_RULES 12
#define YY_END_OF_BUFFER 12 #define YY_END_OF_BUFFER 13
/* This struct is not used in this scanner, /* This struct is not used in this scanner,
but its presence is necessary. */ but its presence is necessary. */
struct yy_trans_info struct yy_trans_info
@ -352,8 +352,8 @@ struct yy_trans_info
}; };
static yyconst flex_int16_t yy_accept[20] = static yyconst flex_int16_t yy_accept[20] =
{ 0, { 0,
0, 0, 12, 7, 8, 6, 5, 10, 9, 4, 0, 0, 13, 8, 9, 6, 5, 11, 10, 4,
7, 0, 3, 6, 0, 7, 1, 2, 0 8, 0, 3, 6, 0, 7, 1, 2, 0
} ; } ;
static yyconst flex_int32_t yy_ec[256] = static yyconst flex_int32_t yy_ec[256] =
@ -859,7 +859,17 @@ YY_RULE_SETUP
return cal_NAME; return cal_NAME;
} }
case 7: 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 YY_RULE_SETUP
{ {
@ -867,7 +877,7 @@ YY_RULE_SETUP
yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
return cal_SYMBOL; return cal_SYMBOL;
} }
case 8: case 9:
YY_RULE_SETUP YY_RULE_SETUP
{ {
@ -875,7 +885,7 @@ YY_RULE_SETUP
yylvalp->str = yyextra->m_DOLLARVariable; yylvalp->str = yyextra->m_DOLLARVariable;
return cal_DOLLAR; return cal_DOLLAR;
} }
case 9: case 10:
YY_RULE_SETUP YY_RULE_SETUP
{ {
@ -883,7 +893,7 @@ YY_RULE_SETUP
yylvalp->str = yyextra->m_LCURLYVariable; yylvalp->str = yyextra->m_LCURLYVariable;
return cal_LCURLY; return cal_LCURLY;
} }
case 10: case 11:
YY_RULE_SETUP YY_RULE_SETUP
{ {
@ -891,7 +901,7 @@ YY_RULE_SETUP
yylvalp->str = yyextra->m_BSLASHVariable; yylvalp->str = yyextra->m_BSLASHVariable;
return cal_BSLASH; return cal_BSLASH;
} }
case 11: case 12:
YY_RULE_SETUP YY_RULE_SETUP
ECHO; ECHO;
@ -1220,7 +1230,6 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
return yy_is_jam ? 0 : yy_current_state; return yy_is_jam ? 0 : yy_current_state;
} }
#ifndef YY_NO_INPUT #ifndef YY_NO_INPUT
#ifdef __cplusplus #ifdef __cplusplus
static int yyinput (yyscan_t yyscanner) static int yyinput (yyscan_t yyscanner)

View File

@ -124,7 +124,15 @@ Modify cmCommandArgumentLexer.h:
return cal_NAME; return cal_NAME;
} }
[^\${}\\@]+|\\. { \\. {
if ( !yyextra->HandleEscapeSymbol(yylvalp, *(yytext+1)) )
{
return cal_ERROR;
}
return cal_SYMBOL;
}
[^\${}\\@]+ {
//std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
return cal_SYMBOL; return cal_SYMBOL;

View File

@ -22,7 +22,7 @@
#include "cmMakefile.h" #include "cmMakefile.h"
int cmCommandArgument_yyparse( yyscan_t yyscanner ); int cmCommandArgument_yyparse( yyscan_t yyscanner );
//
cmCommandArgumentParserHelper::cmCommandArgumentParserHelper() cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
{ {
m_FileLine = -1; m_FileLine = -1;
@ -35,6 +35,8 @@ cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
strcpy(m_DOLLARVariable, "$"); strcpy(m_DOLLARVariable, "$");
strcpy(m_LCURLYVariable, "{"); strcpy(m_LCURLYVariable, "{");
strcpy(m_BSLASHVariable, "\\"); strcpy(m_BSLASHVariable, "\\");
m_NoEscapeMode = false;
} }
@ -145,6 +147,53 @@ void cmCommandArgumentParserHelper::AllocateParserType(cmCommandArgumentParserHe
// std::cout << (void*) pt->str << " " << pt->str << " JPAllocateParserType" << std::endl; // 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) int cmCommandArgumentParserHelper::ParseString(const char* str, int verb)
{ {
if ( !str) if ( !str)

View File

@ -47,6 +47,7 @@ public:
// For the lexer: // For the lexer:
void AllocateParserType(cmCommandArgumentParserHelper::ParserType* pt, void AllocateParserType(cmCommandArgumentParserHelper::ParserType* pt,
const char* str, int len = 0); const char* str, int len = 0);
bool HandleEscapeSymbol(cmCommandArgumentParserHelper::ParserType* pt, char symbol);
int LexInput(char* buf, int maxlen); int LexInput(char* buf, int maxlen);
void Error(const char* str); void Error(const char* str);
@ -64,6 +65,7 @@ public:
void SetLineFile(long line, const char* file); void SetLineFile(long line, const char* file);
void SetEscapeQuotes(bool b) { m_EscapeQuotes = b; } void SetEscapeQuotes(bool b) { m_EscapeQuotes = b; }
void SetNoEscapeMode(bool b) { m_NoEscapeMode = b; }
const char* GetError() { return m_Error.c_str(); } const char* GetError() { return m_Error.c_str(); }
@ -97,6 +99,7 @@ private:
long m_FileLine; long m_FileLine;
bool m_EscapeQuotes; bool m_EscapeQuotes;
std::string m_Error; std::string m_Error;
bool m_NoEscapeMode;
}; };
#endif #endif

View File

@ -247,13 +247,13 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
else if(token->type == cmListFileLexer_Token_Identifier || else if(token->type == cmListFileLexer_Token_Identifier ||
token->type == cmListFileLexer_Token_ArgumentUnquoted) token->type == cmListFileLexer_Token_ArgumentUnquoted)
{ {
cmListFileArgument a(cmSystemTools::RemoveEscapes(token->text), cmListFileArgument a(token->text,
false, filename, token->line); false, filename, token->line);
function.m_Arguments.push_back(a); function.m_Arguments.push_back(a);
} }
else if(token->type == cmListFileLexer_Token_ArgumentQuoted) else if(token->type == cmListFileLexer_Token_ArgumentQuoted)
{ {
cmListFileArgument a(cmSystemTools::RemoveEscapes(token->text), cmListFileArgument a(token->text,
true, filename, token->line); true, filename, token->line);
function.m_Arguments.push_back(a); function.m_Arguments.push_back(a);
} }

View File

@ -1361,17 +1361,18 @@ std::vector<std::string> cmMakefile::GetDefinitions(int cacheonly /* = 0 */) con
const char *cmMakefile::ExpandVariablesInString(std::string& source) const 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, const char *cmMakefile::ExpandVariablesInString(std::string& source,
bool escapeQuotes, bool escapeQuotes,
bool noEscapes,
bool atOnly, bool atOnly,
const char* filename, const char* filename,
long line, long line,
bool removeEmpty) const 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(); return source.c_str();
} }
@ -1387,6 +1388,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
parser.SetMakefile(this); parser.SetMakefile(this);
parser.SetLineFile(line, filename); parser.SetLineFile(line, filename);
parser.SetEscapeQuotes(escapeQuotes); parser.SetEscapeQuotes(escapeQuotes);
parser.SetNoEscapeMode(noEscapes);
int res = parser.ParseString(source.c_str(), 0); int res = parser.ParseString(source.c_str(), 0);
if ( res ) if ( res )
{ {
@ -1703,7 +1705,7 @@ void cmMakefile::ExpandArguments(
{ {
// Expand the variables in the argument. // Expand the variables in the argument.
value = i->Value; 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. // If the argument is quoted, it should be one argument.
// Otherwise, it may be a list of arguments. // Otherwise, it may be a list of arguments.
@ -2353,7 +2355,7 @@ void cmMakefile::ConfigureString(const std::string& input,
} }
// Perform variable replacements. // Perform variable replacements.
this->ExpandVariablesInString(output, escapeQuotes, atOnly, 0, -1, true); this->ExpandVariablesInString(output, escapeQuotes, true, atOnly, 0, -1, true);
// this->RemoveVariablesInString(output, atOnly); // this->RemoveVariablesInString(output, atOnly);
} }

View File

@ -543,6 +543,7 @@ public:
*/ */
const char *ExpandVariablesInString(std::string& source) const; const char *ExpandVariablesInString(std::string& source) const;
const char *ExpandVariablesInString(std::string& source, bool escapeQuotes, const char *ExpandVariablesInString(std::string& source, bool escapeQuotes,
bool noEscapes,
bool atOnly = false, bool atOnly = false,
const char* filename = 0, const char* filename = 0,
long line = -1, long line = -1,