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'; \
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)

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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,