Browse Source

cmStringAlgorithms: Add cmStrToLong and cmStrToULong

This adds the following functions to cmStringAlgorithms:
- `cmStrToLong`: moved from `cmSystemTools::StringToLong`
- `cmStrToULong`: moved from `cmSystemTools::StringToULong`

Overloads of the given functions for `std::string` are added as well.
Sebastian Holtermann 6 years ago
parent
commit
935fbe0b04

+ 2 - 2
Source/CTest/cmCTestMultiProcessHandler.cxx

@@ -10,6 +10,7 @@
 #include "cmDuration.h"
 #include "cmListFileCache.h"
 #include "cmRange.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmWorkingDirectory.h"
 
@@ -110,8 +111,7 @@ void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load)
   std::string fake_load_value;
   if (cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING",
                             fake_load_value)) {
-    if (!cmSystemTools::StringToULong(fake_load_value.c_str(),
-                                      &this->FakeLoadForTesting)) {
+    if (!cmStrToULong(fake_load_value, &this->FakeLoadForTesting)) {
       cmSystemTools::Error("Failed to parse fake load value: " +
                            fake_load_value);
     }

+ 2 - 3
Source/CTest/cmCTestSubmitHandler.cxx

@@ -529,8 +529,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
   auto retryDelay = std::chrono::seconds(0);
   if (!retryDelayString.empty()) {
     unsigned long retryDelayValue = 0;
-    if (!cmSystemTools::StringToULong(retryDelayString.c_str(),
-                                      &retryDelayValue)) {
+    if (!cmStrToULong(retryDelayString, &retryDelayValue)) {
       cmCTestLog(this->CTest, WARNING,
                  "Invalid value for 'RETRY_DELAY' : " << retryDelayString
                                                       << std::endl);
@@ -540,7 +539,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
   }
   unsigned long retryCount = 0;
   if (!retryCountString.empty()) {
-    if (!cmSystemTools::StringToULong(retryCountString.c_str(), &retryCount)) {
+    if (!cmStrToULong(retryCountString, &retryCount)) {
       cmCTestLog(this->CTest, WARNING,
                  "Invalid value for 'RETRY_DELAY' : " << retryCountString
                                                       << std::endl);

+ 3 - 4
Source/CTest/cmCTestTestCommand.cxx

@@ -7,7 +7,7 @@
 #include "cmCTestTestHandler.h"
 #include "cmDuration.h"
 #include "cmMakefile.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
 
 #include <chrono>
 #include <sstream>
@@ -110,15 +110,14 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
   unsigned long testLoad;
   const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
   if (this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD]) {
-    if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD],
-                                      &testLoad)) {
+    if (!cmStrToULong(this->Values[ctt_TEST_LOAD], &testLoad)) {
       testLoad = 0;
       cmCTestLog(this->CTest, WARNING,
                  "Invalid value for 'TEST_LOAD' : "
                    << this->Values[ctt_TEST_LOAD] << std::endl);
     }
   } else if (ctestTestLoad && *ctestTestLoad) {
-    if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad)) {
+    if (!cmStrToULong(ctestTestLoad, &testLoad)) {
       testLoad = 0;
       cmCTestLog(this->CTest, WARNING,
                  "Invalid value for 'CTEST_TEST_LOAD' : " << ctestTestLoad

+ 1 - 2
Source/CTest/cmCTestTestHandler.cxx

@@ -2193,8 +2193,7 @@ bool cmCTestTestHandler::SetTestsProperties(
                 cmListFileContext fc;
                 fc.FilePath = triples[i - 3];
                 long line = 0;
-                if (!cmSystemTools::StringToLong(triples[i - 2].c_str(),
-                                                 &line)) {
+                if (!cmStrToLong(triples[i - 2], &line)) {
                   line = 0;
                 }
                 fc.Line = line;

+ 5 - 5
Source/cmCTest.cxx

@@ -754,7 +754,7 @@ bool cmCTest::UpdateCTestConfiguration()
   std::string const& testLoad = this->GetCTestConfiguration("TestLoad");
   if (!testLoad.empty()) {
     unsigned long load;
-    if (cmSystemTools::StringToULong(testLoad.c_str(), &load)) {
+    if (cmStrToULong(testLoad, &load)) {
       this->SetTestLoad(load);
     } else {
       cmCTestLog(this, WARNING,
@@ -1854,7 +1854,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
     }
     i++;
     long repeat = 1;
-    if (!cmSystemTools::StringToLong(args[i].c_str(), &repeat)) {
+    if (!cmStrToLong(args[i], &repeat)) {
       errormsg =
         "'--repeat-until-fail' given non-integer value '" + args[i] + "'";
       return false;
@@ -1868,7 +1868,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
   if (this->CheckArgument(arg, "--test-load") && i < args.size() - 1) {
     i++;
     unsigned long load;
-    if (cmSystemTools::StringToULong(args[i].c_str(), &load)) {
+    if (cmStrToULong(args[i], &load)) {
       this->SetTestLoad(load);
     } else {
       cmCTestLog(this, WARNING,
@@ -1942,7 +1942,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
       i < args.size() - 1) {
     i++;
     long outputSize;
-    if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) {
+    if (cmStrToLong(args[i], &outputSize)) {
       this->Impl->TestHandler.SetTestOutputSizePassed(int(outputSize));
     } else {
       cmCTestLog(this, WARNING,
@@ -1954,7 +1954,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
       i < args.size() - 1) {
     i++;
     long outputSize;
-    if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) {
+    if (cmStrToLong(args[i], &outputSize)) {
       this->Impl->TestHandler.SetTestOutputSizeFailed(int(outputSize));
     } else {
       cmCTestLog(this, WARNING,

+ 1 - 2
Source/cmFileCommand.cxx

@@ -2357,8 +2357,7 @@ bool HandleLockCommand(std::vector<std::string> const& args,
         return false;
       }
       long scanned;
-      if (!cmSystemTools::StringToLong(args[i].c_str(), &scanned) ||
-          scanned < 0) {
+      if (!cmStrToLong(args[i], &scanned) || scanned < 0) {
         std::ostringstream e;
         e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer.";
         status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());

+ 1 - 1
Source/cmGlobalNinjaGenerator.cxx

@@ -560,7 +560,7 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
     if (pos != std::string::npos) {
       const char* fv = &this->NinjaVersion[pos + k_DYNDEP_.size()];
       unsigned long dyndep = 0;
-      cmSystemTools::StringToULong(fv, &dyndep);
+      cmStrToULong(fv, &dyndep);
       if (dyndep == 1) {
         this->NinjaSupportsDyndeps = true;
       }

+ 2 - 2
Source/cmParseArgumentsCommand.cxx

@@ -131,7 +131,7 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
     }
     parseFromArgV = true;
     argIter++; // move past PARSE_ARGV
-    if (!cmSystemTools::StringToULong(argIter->c_str(), &argvStart)) {
+    if (!cmStrToULong(*argIter, &argvStart)) {
       this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                    "PARSE_ARGV index '" + *argIter +
                                      "' is not an unsigned integer");
@@ -185,7 +185,7 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
     // in the PARSE_ARGV move read the arguments from ARGC and ARGV#
     std::string argc = this->Makefile->GetSafeDefinition("ARGC");
     unsigned long count;
-    if (!cmSystemTools::StringToULong(argc.c_str(), &count)) {
+    if (!cmStrToULong(argc, &count)) {
       this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                    "PARSE_ARGV called with ARGC='" + argc +
                                      "' that is not an unsigned integer");

+ 1 - 1
Source/cmPolicies.cxx

@@ -34,7 +34,7 @@ static bool stringToId(const char* input, cmPolicies::PolicyID& pid)
     }
   }
   long id;
-  if (!cmSystemTools::StringToLong(input + 3, &id)) {
+  if (!cmStrToLong(input + 3, &id)) {
     return false;
   }
   if (id >= cmPolicies::CMPCOUNT) {

+ 2 - 2
Source/cmQtAutoGenInitializer.cxx

@@ -243,7 +243,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
   this->Verbosity = makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE");
   if (!this->Verbosity.empty()) {
     unsigned long iVerb = 0;
-    if (!cmSystemTools::StringToULong(this->Verbosity.c_str(), &iVerb)) {
+    if (!cmStrToULong(this->Verbosity, &iVerb)) {
       // Non numeric verbosity
       this->Verbosity = cmSystemTools::IsOn(this->Verbosity) ? "1" : "0";
     }
@@ -1523,7 +1523,7 @@ void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
 static unsigned int CharPtrToUInt(const char* const input)
 {
   unsigned long tmp = 0;
-  if (input != nullptr && cmSystemTools::StringToULong(input, &tmp)) {
+  if (input != nullptr && cmStrToULong(input, &tmp)) {
     return static_cast<unsigned int>(tmp);
   }
   return 0;

+ 2 - 2
Source/cmQtAutoGenerator.cxx

@@ -22,7 +22,7 @@ cmQtAutoGenerator::Logger::Logger()
     std::string verbose;
     if (cmSystemTools::GetEnv("VERBOSE", verbose) && !verbose.empty()) {
       unsigned long iVerbose = 0;
-      if (cmSystemTools::StringToULong(verbose.c_str(), &iVerbose)) {
+      if (cmStrToULong(verbose, &iVerbose)) {
         SetVerbosity(static_cast<unsigned int>(iVerbose));
       } else {
         // Non numeric verbosity
@@ -46,7 +46,7 @@ cmQtAutoGenerator::Logger::~Logger() = default;
 void cmQtAutoGenerator::Logger::RaiseVerbosity(std::string const& value)
 {
   unsigned long verbosity = 0;
-  if (cmSystemTools::StringToULong(value.c_str(), &verbosity)) {
+  if (cmStrToULong(value, &verbosity)) {
     if (this->Verbosity_ < verbosity) {
       this->Verbosity_ = static_cast<unsigned int>(verbosity);
     }

+ 2 - 3
Source/cmQtAutoMocUic.cxx

@@ -1582,7 +1582,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
   BaseConst_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG");
   {
     unsigned long num = 1;
-    if (cmSystemTools::StringToULong(InfoGet("AM_PARALLEL").c_str(), &num)) {
+    if (cmStrToULong(InfoGet("AM_PARALLEL"), &num)) {
       num = std::max<unsigned long>(num, 1);
       num = std::min<unsigned long>(num, ParallelMax);
     }
@@ -1630,8 +1630,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
   // - Qt environment
   {
     unsigned long qtv = BaseConst_.QtVersionMajor;
-    if (cmSystemTools::StringToULong(InfoGet("AM_QT_VERSION_MAJOR").c_str(),
-                                     &qtv)) {
+    if (cmStrToULong(InfoGet("AM_QT_VERSION_MAJOR"), &qtv)) {
       BaseConst_.QtVersionMajor = static_cast<unsigned int>(qtv);
     }
   }

+ 34 - 0
Source/cmStringAlgorithms.cxx

@@ -4,6 +4,8 @@
 
 #include <algorithm>
 #include <cstdio>
+#include <errno.h>
+#include <stdlib.h>
 
 std::string cmTrimWhitespace(cm::string_view str)
 {
@@ -124,3 +126,35 @@ std::string cmCatViews(std::initializer_list<cm::string_view> views)
   }
   return result;
 }
+
+bool cmStrToLong(const char* str, long* value)
+{
+  errno = 0;
+  char* endp;
+  *value = strtol(str, &endp, 10);
+  return (*endp == '\0') && (endp != str) && (errno == 0);
+}
+
+bool cmStrToLong(std::string const& str, long* value)
+{
+  return cmStrToLong(str.c_str(), value);
+}
+
+bool cmStrToULong(const char* str, unsigned long* value)
+{
+  errno = 0;
+  char* endp;
+  while (cmIsSpace(*str)) {
+    ++str;
+  }
+  if (*str == '-') {
+    return false;
+  }
+  *value = strtoul(str, &endp, 10);
+  return (*endp == '\0') && (endp != str) && (errno == 0);
+}
+
+bool cmStrToULong(std::string const& str, unsigned long* value)
+{
+  return cmStrToULong(str.c_str(), value);
+}

+ 9 - 0
Source/cmStringAlgorithms.h

@@ -190,4 +190,13 @@ inline void cmStripSuffixIfExists(std::string& str, cm::string_view suffix)
   }
 }
 
+/** Converts a string to long. Expects that the whole string is an integer.  */
+bool cmStrToLong(const char* str, long* value);
+bool cmStrToLong(std::string const& str, long* value);
+
+/** Converts a string to unsigned long. Expects that the whole string is an
+ * integer */
+bool cmStrToULong(const char* str, unsigned long* value);
+bool cmStrToULong(std::string const& str, unsigned long* value);
+
 #endif

+ 1 - 1
Source/cmStringCommand.cxx

@@ -736,7 +736,7 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args)
   }
 
   unsigned long times;
-  if (!cmSystemTools::StringToULong(args[ArgPos::TIMES].c_str(), &times)) {
+  if (!cmStrToULong(args[ArgPos::TIMES], &times)) {
     this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  "repeat count is not a positive number.");
     return true;

+ 0 - 22
Source/cmSystemTools.cxx

@@ -2848,28 +2848,6 @@ bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir)
   return false;
 }
 
-bool cmSystemTools::StringToLong(const char* str, long* value)
-{
-  errno = 0;
-  char* endp;
-  *value = strtol(str, &endp, 10);
-  return (*endp == '\0') && (endp != str) && (errno == 0);
-}
-
-bool cmSystemTools::StringToULong(const char* str, unsigned long* value)
-{
-  errno = 0;
-  char* endp;
-  while (isspace(*str)) {
-    ++str;
-  }
-  if (*str == '-') {
-    return false;
-  }
-  *value = strtoul(str, &endp, 10);
-  return (*endp == '\0') && (endp != str) && (errno == 0);
-}
-
 std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes)
 {
   std::string out;

+ 0 - 4
Source/cmSystemTools.h

@@ -500,10 +500,6 @@ public:
   /** Remove a directory; repeat a few times in case of locked files.  */
   static bool RepeatedRemoveDirectory(const std::string& dir);
 
-  /** Convert string to long. Expected that the whole string is an integer */
-  static bool StringToLong(const char* str, long* value);
-  static bool StringToULong(const char* str, unsigned long* value);
-
   /** Encode a string as a URL.  */
   static std::string EncodeURL(std::string const& in,
                                bool escapeSlashes = true);

+ 2 - 2
Source/cmakemain.cxx

@@ -321,7 +321,7 @@ int extract_job_number(int& index, char const* current, char const* next,
   unsigned long numJobs = 0;
   if (jobString.empty()) {
     jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL;
-  } else if (cmSystemTools::StringToULong(jobString.c_str(), &numJobs)) {
+  } else if (cmStrToULong(jobString, &numJobs)) {
     if (numJobs == 0) {
       std::cerr
         << "The <jobs> value requires a positive integer argument.\n\n";
@@ -439,7 +439,7 @@ int do_build(int ac, char const* const* av)
         jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL;
       } else {
         unsigned long numJobs = 0;
-        if (cmSystemTools::StringToULong(parallel.c_str(), &numJobs)) {
+        if (cmStrToULong(parallel, &numJobs)) {
           if (numJobs == 0) {
             std::cerr << "The CMAKE_BUILD_PARALLEL_LEVEL environment variable "
                          "requires a positive integer argument.\n\n";

+ 35 - 0
Tests/CMakeLib/testStringAlgorithms.cxx

@@ -167,5 +167,40 @@ int testStringAlgorithms(int /*unused*/, char* /*unused*/ [])
     assert_ok(!cmHasLiteralSuffix(str, "ab"), "cmHasLiteralPrefix string not");
   }
 
+  // ----------------------------------------------------------------------
+  // Test cmStrToLong
+  {
+    long value;
+    assert_ok(cmStrToLong("1", &value) && value == 1,
+              "cmStrToLong parses a positive decimal integer.");
+    assert_ok(cmStrToLong(" 1", &value) && value == 1,
+              "cmStrToLong parses a decimal integer after whitespace.");
+
+    assert_ok(cmStrToLong("-1", &value) && value == -1,
+              "cmStrToLong parses a negative decimal integer.");
+    assert_ok(
+      cmStrToLong(" -1", &value) && value == -1,
+      "cmStrToLong parses a negative decimal integer after whitespace.");
+
+    assert_ok(!cmStrToLong("1x", &value),
+              "cmStrToLong rejects trailing content.");
+  }
+
+  // ----------------------------------------------------------------------
+  // Test cmStrToULong
+  {
+    unsigned long value;
+    assert_ok(cmStrToULong("1", &value) && value == 1,
+              "cmStrToULong parses a decimal integer.");
+    assert_ok(cmStrToULong(" 1", &value) && value == 1,
+              "cmStrToULong parses a decimal integer after whitespace.");
+    assert_ok(!cmStrToULong("-1", &value),
+              "cmStrToULong rejects a negative number.");
+    assert_ok(!cmStrToULong(" -1", &value),
+              "cmStrToULong rejects a negative number after whitespace.");
+    assert_ok(!cmStrToULong("1x", &value),
+              "cmStrToULong rejects trailing content.");
+  }
+
   return failed;
 }

+ 0 - 16
Tests/CMakeLib/testSystemTools.cxx

@@ -94,21 +94,5 @@ int testSystemTools(int /*unused*/, char* /*unused*/ [])
     cmPassed("cmSystemTools::strverscmp working");
   }
 
-  // ----------------------------------------------------------------------
-  // Test cmSystemTools::StringToULong
-  {
-    unsigned long value;
-    cmAssert(cmSystemTools::StringToULong("1", &value) && value == 1,
-             "StringToULong parses a decimal integer.");
-    cmAssert(cmSystemTools::StringToULong(" 1", &value) && value == 1,
-             "StringToULong parses a decimal integer after whitespace.");
-    cmAssert(!cmSystemTools::StringToULong("-1", &value),
-             "StringToULong rejects a negative number.");
-    cmAssert(!cmSystemTools::StringToULong(" -1", &value),
-             "StringToULong rejects a negative number after whitespace.");
-    cmAssert(!cmSystemTools::StringToULong("1x", &value),
-             "StringToULong rejects trailing content.");
-  }
-
   return failed;
 }