From 1bbccc5bef5c195e9fae2d3d5ab350b386fe45cc Mon Sep 17 00:00:00 2001 From: Andy Cedilnik Date: Fri, 17 Jun 2005 15:50:08 -0400 Subject: ENH: Improve handling of escaped characters --- Source/cmCommandArgumentLexer.cxx | 29 +++++++++++------- Source/cmCommandArgumentLexer.in.l | 10 ++++++- Source/cmCommandArgumentParserHelper.cxx | 51 +++++++++++++++++++++++++++++++- Source/cmCommandArgumentParserHelper.h | 3 ++ Source/cmListFileCache.cxx | 4 +-- Source/cmMakefile.cxx | 10 ++++--- Source/cmMakefile.h | 1 + 7 files changed, 90 insertions(+), 18 deletions(-) diff --git a/Source/cmCommandArgumentLexer.cxx b/Source/cmCommandArgumentLexer.cxx index 2c761e1..682ac74 100644 --- a/Source/cmCommandArgumentLexer.cxx +++ b/Source/cmCommandArgumentLexer.cxx @@ -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) diff --git a/Source/cmCommandArgumentLexer.in.l b/Source/cmCommandArgumentLexer.in.l index e2fdb72..80afa03 100644 --- a/Source/cmCommandArgumentLexer.in.l +++ b/Source/cmCommandArgumentLexer.in.l @@ -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; diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index 6038f66..85741b0 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -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) diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h index 3ecde79..dcbe5ef 100644 --- a/Source/cmCommandArgumentParserHelper.h +++ b/Source/cmCommandArgumentParserHelper.h @@ -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 diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 203696b..cf3e148 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -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); } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 3f286d5..2248ec4 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1361,17 +1361,18 @@ std::vector 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); } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index e8b159c..73c63aa 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -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, -- cgit v0.12