Browse Source

ENH: Add command to generate random strings

Ken Martin 18 năm trước cách đây
mục cha
commit
c4fc2c19c7
2 tập tin đã thay đổi với 79 bổ sung1 xóa
  1. 72 0
      Source/cmStringCommand.cxx
  2. 7 1
      Source/cmStringCommand.h

+ 72 - 0
Source/cmStringCommand.cxx

@@ -66,6 +66,10 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& args)
     {
     return this->HandleSubstringCommand(args);
     }
+  else if(subCommand == "RANDOM")
+    {
+    return this->HandleRandomCommand(args);
+    }
   
   std::string e = "does not recognize sub-command "+subCommand;
   this->SetError(e.c_str());
@@ -606,3 +610,71 @@ bool cmStringCommand
   this->Makefile->AddDefinition(variableName.c_str(), buffer);
   return true;
 }
+
+//----------------------------------------------------------------------------
+bool cmStringCommand
+::HandleRandomCommand(std::vector<std::string> const& args)
+{
+  if(args.size() < 2 || args.size() == 3 || args.size() == 5)
+    {
+    this->SetError("sub-command RANDOM requires at least one argument.");
+    return false;
+    }
+
+  int length = 5;
+  const char cmStringCommandDefaultAlphabet[] = "qwertyuiopasdfghjklzxcvbnm"
+    "QWERTYUIOPASDFGHJKLZXCVBNM"
+    "0123456789";
+  std::string alphabet;
+
+  if ( args.size() > 3 )
+    {
+    size_t i = 1;
+    size_t stopAt = args.size() - 2;
+
+    for ( ; i < stopAt; ++i )
+      {
+      if ( args[i] == "LENGTH" )
+        {
+        ++i;
+        length = atoi(args[i].c_str());
+        }
+      else if ( args[i] == "ALPHABET" )
+        {
+        ++i;
+        alphabet = args[i];
+        }
+      }
+    }
+  if ( !alphabet.size() )
+    {
+    alphabet = cmStringCommandDefaultAlphabet;
+    }
+
+  double sizeofAlphabet = alphabet.size();
+  if ( sizeofAlphabet < 1 )
+    {
+    this->SetError("sub-command RANDOM invoked with bad alphabet.");
+    return false;
+    }
+  if ( length < 1 )
+    {
+    this->SetError("sub-command RANDOM invoked with bad length.");
+    return false;
+    }
+  const std::string& variableName = args[args.size()-1];
+
+  std::vector<char> result;
+  srand((int)time(NULL));
+  const char* alphaPtr = alphabet.c_str();
+  int cc;
+  for ( cc = 0; cc < length; cc ++ )
+    {
+    int idx=(int) (sizeofAlphabet* rand()/(RAND_MAX+1.0));
+    result.push_back(*(alphaPtr + idx));
+    }
+  result.push_back(0);
+
+  this->Makefile->AddDefinition(variableName.c_str(), &*result.begin());
+  return true;
+}

+ 7 - 1
Source/cmStringCommand.h

@@ -85,6 +85,7 @@ public:
       "  STRING(TOLOWER <string1> <output variable>)\n"
       "  STRING(LENGTH <string> <output variable>)\n"
       "  STRING(SUBSTRING <string> <begin> <length> <output variable>)\n"
+      "  STRING(RANDOM [LENGTH <length>] [ALPHABET <alphabet>] <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 "
@@ -108,7 +109,11 @@ public:
       "a file.\n"
       "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.";
+      "SUBSTRING will return a substring of a given string.\n"
+      "RANDOM will return a random string of given length consisting of "
+      "characters from the given alphabet. Default length is 5 "
+      "characters and default alphabet is all numbers and upper and "
+      "lower case letters.";
     }
   
   cmTypeMacro(cmStringCommand, cmCommand);
@@ -125,6 +130,7 @@ protected:
   bool HandleReplaceCommand(std::vector<std::string> const& args);
   bool HandleLengthCommand(std::vector<std::string> const& args);
   bool HandleSubstringCommand(std::vector<std::string> const& args);
+  bool HandleRandomCommand(std::vector<std::string> const& args);
   
   class RegexReplacement
   {