Skip to content

Commit 935fbe0

Browse files
author
Sebastian Holtermann
committed
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.
1 parent 32a7605 commit 935fbe0

20 files changed

+105
-74
lines changed

Source/CTest/cmCTestMultiProcessHandler.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "cmDuration.h"
1111
#include "cmListFileCache.h"
1212
#include "cmRange.h"
13+
#include "cmStringAlgorithms.h"
1314
#include "cmSystemTools.h"
1415
#include "cmWorkingDirectory.h"
1516

@@ -110,8 +111,7 @@ void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load)
110111
std::string fake_load_value;
111112
if (cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING",
112113
fake_load_value)) {
113-
if (!cmSystemTools::StringToULong(fake_load_value.c_str(),
114-
&this->FakeLoadForTesting)) {
114+
if (!cmStrToULong(fake_load_value, &this->FakeLoadForTesting)) {
115115
cmSystemTools::Error("Failed to parse fake load value: " +
116116
fake_load_value);
117117
}

Source/CTest/cmCTestSubmitHandler.cxx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
529529
auto retryDelay = std::chrono::seconds(0);
530530
if (!retryDelayString.empty()) {
531531
unsigned long retryDelayValue = 0;
532-
if (!cmSystemTools::StringToULong(retryDelayString.c_str(),
533-
&retryDelayValue)) {
532+
if (!cmStrToULong(retryDelayString, &retryDelayValue)) {
534533
cmCTestLog(this->CTest, WARNING,
535534
"Invalid value for 'RETRY_DELAY' : " << retryDelayString
536535
<< std::endl);
@@ -540,7 +539,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
540539
}
541540
unsigned long retryCount = 0;
542541
if (!retryCountString.empty()) {
543-
if (!cmSystemTools::StringToULong(retryCountString.c_str(), &retryCount)) {
542+
if (!cmStrToULong(retryCountString, &retryCount)) {
544543
cmCTestLog(this->CTest, WARNING,
545544
"Invalid value for 'RETRY_DELAY' : " << retryCountString
546545
<< std::endl);

Source/CTest/cmCTestTestCommand.cxx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "cmCTestTestHandler.h"
88
#include "cmDuration.h"
99
#include "cmMakefile.h"
10-
#include "cmSystemTools.h"
10+
#include "cmStringAlgorithms.h"
1111

1212
#include <chrono>
1313
#include <sstream>
@@ -110,15 +110,14 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
110110
unsigned long testLoad;
111111
const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
112112
if (this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD]) {
113-
if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD],
114-
&testLoad)) {
113+
if (!cmStrToULong(this->Values[ctt_TEST_LOAD], &testLoad)) {
115114
testLoad = 0;
116115
cmCTestLog(this->CTest, WARNING,
117116
"Invalid value for 'TEST_LOAD' : "
118117
<< this->Values[ctt_TEST_LOAD] << std::endl);
119118
}
120119
} else if (ctestTestLoad && *ctestTestLoad) {
121-
if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad)) {
120+
if (!cmStrToULong(ctestTestLoad, &testLoad)) {
122121
testLoad = 0;
123122
cmCTestLog(this->CTest, WARNING,
124123
"Invalid value for 'CTEST_TEST_LOAD' : " << ctestTestLoad

Source/CTest/cmCTestTestHandler.cxx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,8 +2193,7 @@ bool cmCTestTestHandler::SetTestsProperties(
21932193
cmListFileContext fc;
21942194
fc.FilePath = triples[i - 3];
21952195
long line = 0;
2196-
if (!cmSystemTools::StringToLong(triples[i - 2].c_str(),
2197-
&line)) {
2196+
if (!cmStrToLong(triples[i - 2], &line)) {
21982197
line = 0;
21992198
}
22002199
fc.Line = line;

Source/cmCTest.cxx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ bool cmCTest::UpdateCTestConfiguration()
754754
std::string const& testLoad = this->GetCTestConfiguration("TestLoad");
755755
if (!testLoad.empty()) {
756756
unsigned long load;
757-
if (cmSystemTools::StringToULong(testLoad.c_str(), &load)) {
757+
if (cmStrToULong(testLoad, &load)) {
758758
this->SetTestLoad(load);
759759
} else {
760760
cmCTestLog(this, WARNING,
@@ -1854,7 +1854,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
18541854
}
18551855
i++;
18561856
long repeat = 1;
1857-
if (!cmSystemTools::StringToLong(args[i].c_str(), &repeat)) {
1857+
if (!cmStrToLong(args[i], &repeat)) {
18581858
errormsg =
18591859
"'--repeat-until-fail' given non-integer value '" + args[i] + "'";
18601860
return false;
@@ -1868,7 +1868,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
18681868
if (this->CheckArgument(arg, "--test-load") && i < args.size() - 1) {
18691869
i++;
18701870
unsigned long load;
1871-
if (cmSystemTools::StringToULong(args[i].c_str(), &load)) {
1871+
if (cmStrToULong(args[i], &load)) {
18721872
this->SetTestLoad(load);
18731873
} else {
18741874
cmCTestLog(this, WARNING,
@@ -1942,7 +1942,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
19421942
i < args.size() - 1) {
19431943
i++;
19441944
long outputSize;
1945-
if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) {
1945+
if (cmStrToLong(args[i], &outputSize)) {
19461946
this->Impl->TestHandler.SetTestOutputSizePassed(int(outputSize));
19471947
} else {
19481948
cmCTestLog(this, WARNING,
@@ -1954,7 +1954,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
19541954
i < args.size() - 1) {
19551955
i++;
19561956
long outputSize;
1957-
if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) {
1957+
if (cmStrToLong(args[i], &outputSize)) {
19581958
this->Impl->TestHandler.SetTestOutputSizeFailed(int(outputSize));
19591959
} else {
19601960
cmCTestLog(this, WARNING,

Source/cmFileCommand.cxx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,8 +2357,7 @@ bool HandleLockCommand(std::vector<std::string> const& args,
23572357
return false;
23582358
}
23592359
long scanned;
2360-
if (!cmSystemTools::StringToLong(args[i].c_str(), &scanned) ||
2361-
scanned < 0) {
2360+
if (!cmStrToLong(args[i], &scanned) || scanned < 0) {
23622361
std::ostringstream e;
23632362
e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer.";
23642363
status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());

Source/cmGlobalNinjaGenerator.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
560560
if (pos != std::string::npos) {
561561
const char* fv = &this->NinjaVersion[pos + k_DYNDEP_.size()];
562562
unsigned long dyndep = 0;
563-
cmSystemTools::StringToULong(fv, &dyndep);
563+
cmStrToULong(fv, &dyndep);
564564
if (dyndep == 1) {
565565
this->NinjaSupportsDyndeps = true;
566566
}

Source/cmParseArgumentsCommand.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
131131
}
132132
parseFromArgV = true;
133133
argIter++; // move past PARSE_ARGV
134-
if (!cmSystemTools::StringToULong(argIter->c_str(), &argvStart)) {
134+
if (!cmStrToULong(*argIter, &argvStart)) {
135135
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
136136
"PARSE_ARGV index '" + *argIter +
137137
"' is not an unsigned integer");
@@ -185,7 +185,7 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
185185
// in the PARSE_ARGV move read the arguments from ARGC and ARGV#
186186
std::string argc = this->Makefile->GetSafeDefinition("ARGC");
187187
unsigned long count;
188-
if (!cmSystemTools::StringToULong(argc.c_str(), &count)) {
188+
if (!cmStrToULong(argc, &count)) {
189189
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
190190
"PARSE_ARGV called with ARGC='" + argc +
191191
"' that is not an unsigned integer");

Source/cmPolicies.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static bool stringToId(const char* input, cmPolicies::PolicyID& pid)
3434
}
3535
}
3636
long id;
37-
if (!cmSystemTools::StringToLong(input + 3, &id)) {
37+
if (!cmStrToLong(input + 3, &id)) {
3838
return false;
3939
}
4040
if (id >= cmPolicies::CMPCOUNT) {

Source/cmQtAutoGenInitializer.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
243243
this->Verbosity = makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE");
244244
if (!this->Verbosity.empty()) {
245245
unsigned long iVerb = 0;
246-
if (!cmSystemTools::StringToULong(this->Verbosity.c_str(), &iVerb)) {
246+
if (!cmStrToULong(this->Verbosity, &iVerb)) {
247247
// Non numeric verbosity
248248
this->Verbosity = cmSystemTools::IsOn(this->Verbosity) ? "1" : "0";
249249
}
@@ -1523,7 +1523,7 @@ void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
15231523
static unsigned int CharPtrToUInt(const char* const input)
15241524
{
15251525
unsigned long tmp = 0;
1526-
if (input != nullptr && cmSystemTools::StringToULong(input, &tmp)) {
1526+
if (input != nullptr && cmStrToULong(input, &tmp)) {
15271527
return static_cast<unsigned int>(tmp);
15281528
}
15291529
return 0;

Source/cmQtAutoGenerator.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ cmQtAutoGenerator::Logger::Logger()
2222
std::string verbose;
2323
if (cmSystemTools::GetEnv("VERBOSE", verbose) && !verbose.empty()) {
2424
unsigned long iVerbose = 0;
25-
if (cmSystemTools::StringToULong(verbose.c_str(), &iVerbose)) {
25+
if (cmStrToULong(verbose, &iVerbose)) {
2626
SetVerbosity(static_cast<unsigned int>(iVerbose));
2727
} else {
2828
// Non numeric verbosity
@@ -46,7 +46,7 @@ cmQtAutoGenerator::Logger::~Logger() = default;
4646
void cmQtAutoGenerator::Logger::RaiseVerbosity(std::string const& value)
4747
{
4848
unsigned long verbosity = 0;
49-
if (cmSystemTools::StringToULong(value.c_str(), &verbosity)) {
49+
if (cmStrToULong(value, &verbosity)) {
5050
if (this->Verbosity_ < verbosity) {
5151
this->Verbosity_ = static_cast<unsigned int>(verbosity);
5252
}

Source/cmQtAutoMocUic.cxx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,7 +1582,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
15821582
BaseConst_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG");
15831583
{
15841584
unsigned long num = 1;
1585-
if (cmSystemTools::StringToULong(InfoGet("AM_PARALLEL").c_str(), &num)) {
1585+
if (cmStrToULong(InfoGet("AM_PARALLEL"), &num)) {
15861586
num = std::max<unsigned long>(num, 1);
15871587
num = std::min<unsigned long>(num, ParallelMax);
15881588
}
@@ -1630,8 +1630,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
16301630
// - Qt environment
16311631
{
16321632
unsigned long qtv = BaseConst_.QtVersionMajor;
1633-
if (cmSystemTools::StringToULong(InfoGet("AM_QT_VERSION_MAJOR").c_str(),
1634-
&qtv)) {
1633+
if (cmStrToULong(InfoGet("AM_QT_VERSION_MAJOR"), &qtv)) {
16351634
BaseConst_.QtVersionMajor = static_cast<unsigned int>(qtv);
16361635
}
16371636
}

Source/cmStringAlgorithms.cxx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include <algorithm>
66
#include <cstdio>
7+
#include <errno.h>
8+
#include <stdlib.h>
79

810
std::string cmTrimWhitespace(cm::string_view str)
911
{
@@ -124,3 +126,35 @@ std::string cmCatViews(std::initializer_list<cm::string_view> views)
124126
}
125127
return result;
126128
}
129+
130+
bool cmStrToLong(const char* str, long* value)
131+
{
132+
errno = 0;
133+
char* endp;
134+
*value = strtol(str, &endp, 10);
135+
return (*endp == '\0') && (endp != str) && (errno == 0);
136+
}
137+
138+
bool cmStrToLong(std::string const& str, long* value)
139+
{
140+
return cmStrToLong(str.c_str(), value);
141+
}
142+
143+
bool cmStrToULong(const char* str, unsigned long* value)
144+
{
145+
errno = 0;
146+
char* endp;
147+
while (cmIsSpace(*str)) {
148+
++str;
149+
}
150+
if (*str == '-') {
151+
return false;
152+
}
153+
*value = strtoul(str, &endp, 10);
154+
return (*endp == '\0') && (endp != str) && (errno == 0);
155+
}
156+
157+
bool cmStrToULong(std::string const& str, unsigned long* value)
158+
{
159+
return cmStrToULong(str.c_str(), value);
160+
}

Source/cmStringAlgorithms.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,13 @@ inline void cmStripSuffixIfExists(std::string& str, cm::string_view suffix)
190190
}
191191
}
192192

193+
/** Converts a string to long. Expects that the whole string is an integer. */
194+
bool cmStrToLong(const char* str, long* value);
195+
bool cmStrToLong(std::string const& str, long* value);
196+
197+
/** Converts a string to unsigned long. Expects that the whole string is an
198+
* integer */
199+
bool cmStrToULong(const char* str, unsigned long* value);
200+
bool cmStrToULong(std::string const& str, unsigned long* value);
201+
193202
#endif

Source/cmStringCommand.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args)
736736
}
737737

738738
unsigned long times;
739-
if (!cmSystemTools::StringToULong(args[ArgPos::TIMES].c_str(), &times)) {
739+
if (!cmStrToULong(args[ArgPos::TIMES], &times)) {
740740
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
741741
"repeat count is not a positive number.");
742742
return true;

Source/cmSystemTools.cxx

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2848,28 +2848,6 @@ bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir)
28482848
return false;
28492849
}
28502850

2851-
bool cmSystemTools::StringToLong(const char* str, long* value)
2852-
{
2853-
errno = 0;
2854-
char* endp;
2855-
*value = strtol(str, &endp, 10);
2856-
return (*endp == '\0') && (endp != str) && (errno == 0);
2857-
}
2858-
2859-
bool cmSystemTools::StringToULong(const char* str, unsigned long* value)
2860-
{
2861-
errno = 0;
2862-
char* endp;
2863-
while (isspace(*str)) {
2864-
++str;
2865-
}
2866-
if (*str == '-') {
2867-
return false;
2868-
}
2869-
*value = strtoul(str, &endp, 10);
2870-
return (*endp == '\0') && (endp != str) && (errno == 0);
2871-
}
2872-
28732851
std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes)
28742852
{
28752853
std::string out;

Source/cmSystemTools.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,10 +500,6 @@ class cmSystemTools : public cmsys::SystemTools
500500
/** Remove a directory; repeat a few times in case of locked files. */
501501
static bool RepeatedRemoveDirectory(const std::string& dir);
502502

503-
/** Convert string to long. Expected that the whole string is an integer */
504-
static bool StringToLong(const char* str, long* value);
505-
static bool StringToULong(const char* str, unsigned long* value);
506-
507503
/** Encode a string as a URL. */
508504
static std::string EncodeURL(std::string const& in,
509505
bool escapeSlashes = true);

Source/cmakemain.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ int extract_job_number(int& index, char const* current, char const* next,
321321
unsigned long numJobs = 0;
322322
if (jobString.empty()) {
323323
jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL;
324-
} else if (cmSystemTools::StringToULong(jobString.c_str(), &numJobs)) {
324+
} else if (cmStrToULong(jobString, &numJobs)) {
325325
if (numJobs == 0) {
326326
std::cerr
327327
<< "The <jobs> value requires a positive integer argument.\n\n";
@@ -439,7 +439,7 @@ int do_build(int ac, char const* const* av)
439439
jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL;
440440
} else {
441441
unsigned long numJobs = 0;
442-
if (cmSystemTools::StringToULong(parallel.c_str(), &numJobs)) {
442+
if (cmStrToULong(parallel, &numJobs)) {
443443
if (numJobs == 0) {
444444
std::cerr << "The CMAKE_BUILD_PARALLEL_LEVEL environment variable "
445445
"requires a positive integer argument.\n\n";

Tests/CMakeLib/testStringAlgorithms.cxx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,5 +167,40 @@ int testStringAlgorithms(int /*unused*/, char* /*unused*/ [])
167167
assert_ok(!cmHasLiteralSuffix(str, "ab"), "cmHasLiteralPrefix string not");
168168
}
169169

170+
// ----------------------------------------------------------------------
171+
// Test cmStrToLong
172+
{
173+
long value;
174+
assert_ok(cmStrToLong("1", &value) && value == 1,
175+
"cmStrToLong parses a positive decimal integer.");
176+
assert_ok(cmStrToLong(" 1", &value) && value == 1,
177+
"cmStrToLong parses a decimal integer after whitespace.");
178+
179+
assert_ok(cmStrToLong("-1", &value) && value == -1,
180+
"cmStrToLong parses a negative decimal integer.");
181+
assert_ok(
182+
cmStrToLong(" -1", &value) && value == -1,
183+
"cmStrToLong parses a negative decimal integer after whitespace.");
184+
185+
assert_ok(!cmStrToLong("1x", &value),
186+
"cmStrToLong rejects trailing content.");
187+
}
188+
189+
// ----------------------------------------------------------------------
190+
// Test cmStrToULong
191+
{
192+
unsigned long value;
193+
assert_ok(cmStrToULong("1", &value) && value == 1,
194+
"cmStrToULong parses a decimal integer.");
195+
assert_ok(cmStrToULong(" 1", &value) && value == 1,
196+
"cmStrToULong parses a decimal integer after whitespace.");
197+
assert_ok(!cmStrToULong("-1", &value),
198+
"cmStrToULong rejects a negative number.");
199+
assert_ok(!cmStrToULong(" -1", &value),
200+
"cmStrToULong rejects a negative number after whitespace.");
201+
assert_ok(!cmStrToULong("1x", &value),
202+
"cmStrToULong rejects trailing content.");
203+
}
204+
170205
return failed;
171206
}

0 commit comments

Comments
 (0)