Kaynağa Gözat

ENH: Add String length and substring

Andy Cedilnik 20 yıl önce
ebeveyn
işleme
12ef4edf64

+ 64 - 0
Source/cmStringCommand.cxx

@@ -58,6 +58,14 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& 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;
   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());
   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;
+}

+ 7 - 1
Source/cmStringCommand.h

@@ -83,6 +83,8 @@ public:
       "         [@ONLY] [ESCAPE_QUOTES])\n"
       "  STRING(TOUPPER <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 "
       "match in the output variable.\n"
       "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"
       "CONFIGURE will transform a string like CONFIGURE_FILE transforms "
       "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);
@@ -118,6 +122,8 @@ protected:
   bool HandleToUpperLowerCommand(std::vector<std::string> const& args, bool toUpper);
   bool HandleCompareCommand(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
   {

+ 7 - 0
Tests/StringFileTest/CMakeLists.txt

@@ -22,6 +22,11 @@ STRING(TOUPPER "CMake" tuvar)
 STRING(TOLOWER "CMake" tlvar)
 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")
 
 # Escaping test
@@ -54,6 +59,8 @@ FOREACH(var
     rrepvar
     repvar
     relpath
+    substringres
+    lengthres
     nceqvar
     ceqvar
     cneqvar

+ 2 - 0
Tests/StringFileTest/StringFile.cxx

@@ -10,7 +10,9 @@ int main(int, char*[])
   res += CheckMethod(rmallvar, "CMake;cmake;CMake");
   res += CheckMethod(rrepvar, "People should use CMake and CMake");
   res += CheckMethod(repvar, "People should use CMake");
+  res += CheckMethod(substringres, "Everybody should use CMake");
   res += CheckMethod(nceqvar, "0");
+  res += CheckMethod(lengthres, "26");
   res += CheckMethod(ceqvar, "1");
   res += CheckMethod(cneqvar, "1");
   res += CheckMethod(ncneqvar, "0");