From c4fc2c19c75df1d3fa9fe4be0f9c775723cb2038 Mon Sep 17 00:00:00 2001 From: Ken Martin Date: Mon, 23 Apr 2007 11:04:12 -0400 Subject: ENH: Add command to generate random strings --- Source/cmStringCommand.cxx | 72 ++++++++++++++++++++++++++++++++++++++++++++++ Source/cmStringCommand.h | 8 +++++- 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 24d034d..655bdfb 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -66,6 +66,10 @@ bool cmStringCommand::InitialPass(std::vector 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 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 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; +} diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 523162d..283c91a 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -85,6 +85,7 @@ public: " STRING(TOLOWER )\n" " STRING(LENGTH )\n" " STRING(SUBSTRING )\n" + " STRING(RANDOM [LENGTH ] [ALPHABET ] )\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 const& args); bool HandleLengthCommand(std::vector const& args); bool HandleSubstringCommand(std::vector const& args); + bool HandleRandomCommand(std::vector const& args); class RegexReplacement { -- cgit v0.12