ENH: Add regular string replace (not regex), and relative path command. Also add tests
This commit is contained in:
parent
33ac18891f
commit
6e5cdd6de7
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue