ENH: Add String length and substring
This commit is contained in:
parent
6e5cdd6de7
commit
12ef4edf64
|
@ -58,6 +58,14 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& args)
|
||||||
{
|
{
|
||||||
return this->HandleConfigureCommand(args);
|
return this->HandleConfigureCommand(args);
|
||||||
}
|
}
|
||||||
|
else if(subCommand == "LENGTH")
|
||||||
|
{
|
||||||
|
return this->HandleLengthCommand(args);
|
||||||
|
}
|
||||||
|
else if(subCommand == "SUBSTRING")
|
||||||
|
{
|
||||||
|
return this->HandleSubstringCommand(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());
|
||||||
|
@ -522,3 +530,59 @@ bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const& args)
|
||||||
m_Makefile->AddDefinition(variableName.c_str(), input.c_str());
|
m_Makefile->AddDefinition(variableName.c_str(), input.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const& args)
|
||||||
|
{
|
||||||
|
if(args.size() != 5)
|
||||||
|
{
|
||||||
|
this->SetError("sub-command REPLACE requires four arguments.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& stringValue = args[1];
|
||||||
|
int begin = atoi(args[2].c_str());
|
||||||
|
int end = atoi(args[3].c_str());
|
||||||
|
const std::string& variableName = args[4];
|
||||||
|
|
||||||
|
size_t stringLength = stringValue.size();
|
||||||
|
int intStringLength = static_cast<int>(stringLength);
|
||||||
|
if ( begin < 0 || begin > intStringLength )
|
||||||
|
{
|
||||||
|
cmOStringStream ostr;
|
||||||
|
ostr << "begin index: " << begin << " is out of range 0 - " << stringLength;
|
||||||
|
this->SetError(ostr.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int leftOverLength = intStringLength - begin;
|
||||||
|
if ( end < 0 || end > intStringLength )
|
||||||
|
{
|
||||||
|
cmOStringStream ostr;
|
||||||
|
ostr << "end index: " << end << " is out of range " << 0 << " - " << leftOverLength;
|
||||||
|
this->SetError(ostr.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Makefile->AddDefinition(variableName.c_str(), stringValue.substr(begin, end).c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmStringCommand::HandleLengthCommand(std::vector<std::string> const& args)
|
||||||
|
{
|
||||||
|
if(args.size() != 3)
|
||||||
|
{
|
||||||
|
this->SetError("sub-command LENGTH requires two arguments.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& stringValue = args[1];
|
||||||
|
const std::string& variableName = args[2];
|
||||||
|
|
||||||
|
size_t length = stringValue.size();
|
||||||
|
char buffer[1024];
|
||||||
|
sprintf(buffer, "%d", length);
|
||||||
|
|
||||||
|
m_Makefile->AddDefinition(variableName.c_str(), buffer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -83,6 +83,8 @@ public:
|
||||||
" [@ONLY] [ESCAPE_QUOTES])\n"
|
" [@ONLY] [ESCAPE_QUOTES])\n"
|
||||||
" STRING(TOUPPER <string1> <output variable>)\n"
|
" STRING(TOUPPER <string1> <output variable>)\n"
|
||||||
" STRING(TOLOWER <string1> <output variable>)\n"
|
" STRING(TOLOWER <string1> <output variable>)\n"
|
||||||
|
" STRING(LENGTH <string> <output variable>)\n"
|
||||||
|
" STRING(SUBSTRING <string> <begin> <end> <output variable>)\n"
|
||||||
"REGEX MATCH will match the regular expression once and store the "
|
"REGEX MATCH will match the regular expression once and store the "
|
||||||
"match in the output variable.\n"
|
"match in the output variable.\n"
|
||||||
"REGEX MATCHALL will match the regular expression as many times as "
|
"REGEX MATCHALL will match the regular expression as many times as "
|
||||||
|
@ -104,7 +106,9 @@ public:
|
||||||
"ASCII will convert all numbers into corresponding ASCII characters.\n"
|
"ASCII will convert all numbers into corresponding ASCII characters.\n"
|
||||||
"CONFIGURE will transform a string like CONFIGURE_FILE transforms "
|
"CONFIGURE will transform a string like CONFIGURE_FILE transforms "
|
||||||
"a file.\n"
|
"a file.\n"
|
||||||
"TOUPPER/TOLOWER will convert string to upper/lower characters.";
|
"TOUPPER/TOLOWER will convert string to upper/lower characters.\n"
|
||||||
|
"LENGTH will return a given string's length.\n"
|
||||||
|
"SUBSTRING will return a substring of a given string.";
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTypeMacro(cmStringCommand, cmCommand);
|
cmTypeMacro(cmStringCommand, cmCommand);
|
||||||
|
@ -118,6 +122,8 @@ protected:
|
||||||
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);
|
bool HandleReplaceCommand(std::vector<std::string> const& args);
|
||||||
|
bool HandleLengthCommand(std::vector<std::string> const& args);
|
||||||
|
bool HandleSubstringCommand(std::vector<std::string> const& args);
|
||||||
|
|
||||||
class RegexReplacement
|
class RegexReplacement
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,11 @@ STRING(TOUPPER "CMake" tuvar)
|
||||||
STRING(TOLOWER "CMake" tlvar)
|
STRING(TOLOWER "CMake" tlvar)
|
||||||
STRING(REPLACE "Autoconf" "CMake" repvar "People should use Autoconf")
|
STRING(REPLACE "Autoconf" "CMake" repvar "People should use Autoconf")
|
||||||
|
|
||||||
|
STRING(SUBSTRING "People should use Autoconf" 7 10 substringres)
|
||||||
|
SET(substringres "Everybody ${substringres} CMake")
|
||||||
|
|
||||||
|
STRING(LENGTH ${substringres} lengthres)
|
||||||
|
|
||||||
FILE(RELATIVE_PATH relpath "/usr/local/bin" "/usr/X11R6/bin/xnest")
|
FILE(RELATIVE_PATH relpath "/usr/local/bin" "/usr/X11R6/bin/xnest")
|
||||||
|
|
||||||
# Escaping test
|
# Escaping test
|
||||||
|
@ -54,6 +59,8 @@ FOREACH(var
|
||||||
rrepvar
|
rrepvar
|
||||||
repvar
|
repvar
|
||||||
relpath
|
relpath
|
||||||
|
substringres
|
||||||
|
lengthres
|
||||||
nceqvar
|
nceqvar
|
||||||
ceqvar
|
ceqvar
|
||||||
cneqvar
|
cneqvar
|
||||||
|
|
|
@ -10,7 +10,9 @@ int main(int, char*[])
|
||||||
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(repvar, "People should use CMake");
|
||||||
|
res += CheckMethod(substringres, "Everybody should use CMake");
|
||||||
res += CheckMethod(nceqvar, "0");
|
res += CheckMethod(nceqvar, "0");
|
||||||
|
res += CheckMethod(lengthres, "26");
|
||||||
res += CheckMethod(ceqvar, "1");
|
res += CheckMethod(ceqvar, "1");
|
||||||
res += CheckMethod(cneqvar, "1");
|
res += CheckMethod(cneqvar, "1");
|
||||||
res += CheckMethod(ncneqvar, "0");
|
res += CheckMethod(ncneqvar, "0");
|
||||||
|
|
Loading…
Reference in New Issue