ENH: Add String length and substring

This commit is contained in:
Andy Cedilnik 2005-10-17 09:56:42 -04:00
parent 6e5cdd6de7
commit 12ef4edf64
4 changed files with 80 additions and 1 deletions

View File

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

View File

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

View File

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

View File

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