ENH: Add regular string replace (not regex), and relative path command. Also add tests

This commit is contained in:
Andy Cedilnik 2005-10-17 09:10:20 -04:00
parent 33ac18891f
commit 6e5cdd6de7
6 changed files with 90 additions and 1 deletions

View File

@ -58,6 +58,10 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args)
{ {
return this->HandleInstallCommand(args); return this->HandleInstallCommand(args);
} }
else if ( subCommand == "RELATIVE_PATH" )
{
return this->HandleRelativePathCommand(args);
}
std::string e = "does not recognize sub-command "+subCommand; std::string e = "does not recognize sub-command "+subCommand;
this->SetError(e.c_str()); this->SetError(e.c_str());
@ -696,3 +700,38 @@ bool cmFileCommand::HandleInstallCommand(
return true; return true;
} }
//----------------------------------------------------------------------------
bool cmFileCommand::HandleRelativePathCommand(
std::vector<std::string> const& args)
{
if(args.size() != 4 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
const std::string& outVar = args[1];
const std::string& directoryName = args[2];
const std::string& fileName = args[3];
if(!cmSystemTools::FileIsFullPath(directoryName.c_str()))
{
std::string errstring = "RelativePath must be passed a full path to the directory: " + directoryName;
this->SetError(errstring.c_str());
return false;
}
if(!cmSystemTools::FileIsFullPath(fileName.c_str()))
{
std::string errstring = "RelativePath must be passed a full path to the directory: " + directoryName;
this->SetError(errstring.c_str());
return false;
}
std::string res = cmSystemTools::RelativePath(directoryName.c_str(), fileName.c_str());
m_Makefile->AddDefinition(outVar.c_str(),
res.c_str());
return true;
}

View File

@ -70,6 +70,7 @@ public:
" FILE(GLOB variable [globbing expressions]...)\n" " FILE(GLOB variable [globbing expressions]...)\n"
" FILE(GLOB_RECURSE variable [globbing expressions]...)\n" " FILE(GLOB_RECURSE variable [globbing expressions]...)\n"
" FILE(MAKE_DIRECTORY [directory]...)\n" " FILE(MAKE_DIRECTORY [directory]...)\n"
" FILE(RELATIVE_PATH variable directory file)\n"
"WRITE will write a message into a file called 'filename'. It " "WRITE will write a message into a file called 'filename'. It "
"overwrites the file if it already exists, and creates the file " "overwrites the file if it already exists, and creates the file "
"if it does not exists.\n" "if it does not exists.\n"
@ -93,7 +94,8 @@ public:
"match the files.\n" "match the files.\n"
"Example of recursive globbing:\n" "Example of recursive globbing:\n"
" /dir/*.py - match all python files /dir and subdirectories\n" " /dir/*.py - match all python files /dir and subdirectories\n"
"MAKE_DIRECTORY will create a directory at the specified location"; "MAKE_DIRECTORY will create a directory at the specified location\n"
"RELATIVE_PATH will determine relative path from directory to the given file";
} }
cmTypeMacro(cmFileCommand, cmCommand); cmTypeMacro(cmFileCommand, cmCommand);
@ -104,6 +106,7 @@ protected:
bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse); bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse);
bool HandleMakeDirectoryCommand(std::vector<std::string> const& args); bool HandleMakeDirectoryCommand(std::vector<std::string> const& args);
bool HandleInstallCommand(std::vector<std::string> const& args); bool HandleInstallCommand(std::vector<std::string> const& args);
bool HandleRelativePathCommand(std::vector<std::string> const& args);
}; };

View File

@ -16,6 +16,7 @@
=========================================================================*/ =========================================================================*/
#include "cmStringCommand.h" #include "cmStringCommand.h"
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
#include <cmsys/SystemTools.hxx>
#include <stdlib.h> // required for atoi #include <stdlib.h> // required for atoi
#include <ctype.h> #include <ctype.h>
@ -33,6 +34,10 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& args)
{ {
return this->HandleRegexCommand(args); return this->HandleRegexCommand(args);
} }
else if(subCommand == "REPLACE")
{
return this->HandleReplaceCommand(args);
}
else if(subCommand == "TOLOWER") else if(subCommand == "TOLOWER")
{ {
return this->HandleToUpperLowerCommand(args, false); return this->HandleToUpperLowerCommand(args, false);
@ -492,3 +497,28 @@ bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const& args)
this->SetError(e.c_str()); this->SetError(e.c_str());
return false; return false;
} }
//----------------------------------------------------------------------------
bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const& args)
{
if(args.size() < 5)
{
this->SetError("sub-command REPLACE requires four arguments.");
return false;
}
const std::string& matchExpression = args[1];
const std::string& replaceExpression = args[2];
const std::string& variableName = args[3];
std::string input = args[4];
for(unsigned int i=5; i < args.size(); ++i)
{
input += args[i];
}
cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(), replaceExpression.c_str());
m_Makefile->AddDefinition(variableName.c_str(), input.c_str());
return true;
}

View File

@ -71,6 +71,9 @@ public:
" STRING(REGEX REPLACE <regular_expression>\n" " STRING(REGEX REPLACE <regular_expression>\n"
" <replace_expression> <output variable>\n" " <replace_expression> <output variable>\n"
" <input> [<input>...])\n" " <input> [<input>...])\n"
" STRING(REPLACE <match_expression>\n"
" <replace_expression> <output variable>\n"
" <input> [<input>...])\n"
" STRING(COMPARE EQUAL <string1> <string2> <output variable>)\n" " STRING(COMPARE EQUAL <string1> <string2> <output variable>)\n"
" STRING(COMPARE NOTEQUAL <string1> <string2> <output variable>)\n" " STRING(COMPARE NOTEQUAL <string1> <string2> <output variable>)\n"
" STRING(COMPARE LESS <string1> <string2> <output variable>)\n" " STRING(COMPARE LESS <string1> <string2> <output variable>)\n"
@ -90,6 +93,12 @@ public:
"subexpressions of the match using \\1, \\2, ..., \\9. Note that " "subexpressions of the match using \\1, \\2, ..., \\9. Note that "
"two backslashes (\\\\1) are required in CMake code to get a " "two backslashes (\\\\1) are required in CMake code to get a "
"backslash through argument parsing.\n" "backslash through argument parsing.\n"
"REPLACE will match the given expression "
"and substitute the replacement expression for the match "
"in the output. The replace expression may refer to paren-delimited "
"subexpressions of the match using \\1, \\2, ..., \\9. Note that "
"two backslashes (\\\\1) are required in CMake code to get a "
"backslash through argument parsing.\n"
"COMPARE EQUAL/NOTEQUAL/LESS/GREATER will compare the strings and " "COMPARE EQUAL/NOTEQUAL/LESS/GREATER will compare the strings and "
"store true or false in the output variable.\n" "store true or false in the output variable.\n"
"ASCII will convert all numbers into corresponding ASCII characters.\n" "ASCII will convert all numbers into corresponding ASCII characters.\n"
@ -108,6 +117,7 @@ protected:
bool RegexReplace(std::vector<std::string> const& args); bool RegexReplace(std::vector<std::string> const& args);
bool HandleToUpperLowerCommand(std::vector<std::string> const& args, bool toUpper); bool HandleToUpperLowerCommand(std::vector<std::string> const& args, bool toUpper);
bool HandleCompareCommand(std::vector<std::string> const& args); bool HandleCompareCommand(std::vector<std::string> const& args);
bool HandleReplaceCommand(std::vector<std::string> const& args);
class RegexReplacement class RegexReplacement
{ {

View File

@ -20,6 +20,9 @@ STRING(COMPARE GREATER "max" "min" ncgvar)
STRING(ASCII 67 109 97 107 101 savar) STRING(ASCII 67 109 97 107 101 savar)
STRING(TOUPPER "CMake" tuvar) STRING(TOUPPER "CMake" tuvar)
STRING(TOLOWER "CMake" tlvar) STRING(TOLOWER "CMake" tlvar)
STRING(REPLACE "Autoconf" "CMake" repvar "People should use Autoconf")
FILE(RELATIVE_PATH relpath "/usr/local/bin" "/usr/X11R6/bin/xnest")
# Escaping test # Escaping test
SET(var "\\ \" \ \t \n \r \# \( \) \0") SET(var "\\ \" \ \t \n \r \# \( \) \0")
@ -49,6 +52,8 @@ FOREACH(var
rmvar rmvar
rmallvar rmallvar
rrepvar rrepvar
repvar
relpath
nceqvar nceqvar
ceqvar ceqvar
cneqvar cneqvar

View File

@ -9,6 +9,7 @@ int main(int, char*[])
res += CheckMethod(rmvar, "CMake"); res += CheckMethod(rmvar, "CMake");
res += CheckMethod(rmallvar, "CMake;cmake;CMake"); res += CheckMethod(rmallvar, "CMake;cmake;CMake");
res += CheckMethod(rrepvar, "People should use CMake and CMake"); res += CheckMethod(rrepvar, "People should use CMake and CMake");
res += CheckMethod(repvar, "People should use CMake");
res += CheckMethod(nceqvar, "0"); res += CheckMethod(nceqvar, "0");
res += CheckMethod(ceqvar, "1"); res += CheckMethod(ceqvar, "1");
res += CheckMethod(cneqvar, "1"); res += CheckMethod(cneqvar, "1");
@ -20,6 +21,7 @@ int main(int, char*[])
res += CheckMethod(savar, "Cmake"); res += CheckMethod(savar, "Cmake");
res += CheckMethod(tuvar, "CMAKE"); res += CheckMethod(tuvar, "CMAKE");
res += CheckMethod(tlvar, "cmake"); res += CheckMethod(tlvar, "cmake");
res += CheckMethod(relpath, "../../X11R6/bin/xnest");
return res; return res;
} }