Bladeren bron

Fix issue #9851 - only seed the random number generator on the first call to STRING(RANDOM or if given the new RANDOM_SEED argument. Add test and documentation of new argument.

David Cole 16 jaren geleden
bovenliggende
commit
d6fe0438c1
3 gewijzigde bestanden met toevoegingen van 27 en 3 verwijderingen
  1. 16 1
      Source/cmStringCommand.cxx
  2. 3 2
      Source/cmStringCommand.h
  3. 8 0
      Tests/CMakeTests/StringTestScript.cmake

+ 16 - 1
Source/cmStringCommand.cxx

@@ -700,6 +700,9 @@ bool cmStringCommand
     return false;
     }
 
+  static bool seeded = false;
+  bool force_seed = false;
+  int seed = (int) time(NULL);
   int length = 5;
   const char cmStringCommandDefaultAlphabet[] = "qwertyuiopasdfghjklzxcvbnm"
     "QWERTYUIOPASDFGHJKLZXCVBNM"
@@ -723,6 +726,12 @@ bool cmStringCommand
         ++i;
         alphabet = args[i];
         }
+      else if ( args[i] == "RANDOM_SEED" )
+        {
+        ++i;
+        seed = atoi(args[i].c_str());
+        force_seed = true;
+        }
       }
     }
   if ( !alphabet.size() )
@@ -744,7 +753,13 @@ bool cmStringCommand
   const std::string& variableName = args[args.size()-1];
 
   std::vector<char> result;
-  srand((int)time(NULL));
+
+  if (!seeded || force_seed)
+    {
+    seeded = true;
+    srand(seed);
+    }
+
   const char* alphaPtr = alphabet.c_str();
   int cc;
   for ( cc = 0; cc < length; cc ++ )

+ 3 - 2
Source/cmStringCommand.h

@@ -89,7 +89,7 @@ public:
       "  string(SUBSTRING <string> <begin> <length> <output variable>)\n"
       "  string(STRIP <string> <output variable>)\n"
       "  string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]\n"
-      "         <output variable>)\n"
+      "         [RANDOM_SEED <seed>] <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 "
@@ -115,7 +115,8 @@ public:
       "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.\n"
+      "lower case letters.  If an integer RANDOM_SEED is given, its "
+      "value will be used to seed the random number generator.\n"
       "The following characters have special meaning in regular expressions:\n"
       "   ^         Matches at beginning of a line\n"
       "   $         Matches at end of a line\n"

+ 8 - 0
Tests/CMakeTests/StringTestScript.cmake

@@ -182,6 +182,14 @@ elseif(testname STREQUAL random_with_various_alphabets) # pass
   string(RANDOM LENGTH 1 ALPHABET "Q" v)
   message(STATUS "v='${v}'")
 
+  # seed values -- 2 same, then 1 different
+  string(RANDOM LENGTH 32 ALPHABET "ACGT" RANDOM_SEED 987654 v)
+  message(STATUS "v='${v}'")
+  string(RANDOM LENGTH 32 ALPHABET "ACGT" RANDOM_SEED 987654 v)
+  message(STATUS "v='${v}'")
+  string(RANDOM LENGTH 32 ALPHABET "ACGT" RANDOM_SEED 876543 v)
+  message(STATUS "v='${v}'")
+
   # alphabet of many colors - use all the crazy keyboard characters
   string(RANDOM LENGTH 78 ALPHABET "~`!@#$%^&*()_-+={}[]\\|:\\;'\",.<>/?" v)
   message(STATUS "v='${v}'")