diff options
author | Vincent Ambo <tazjin@google.com> | 2020-05-25T00·19+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-05-25T00·19+0100 |
commit | 98299da0fda612b42ab933c47f18163cfef5fa71 (patch) | |
tree | 78fc0f1127b5f2336d3e370f342f72f38d5a5ee2 | |
parent | b371821db59d33851d521d66ba1fb126d388c00f (diff) |
refactor(3p/nix/libutil): Replace string2Int & trim functions r/843
Replaces these functions with corresponding functions from Abseil, namely absl::StripAsciiWhitespace and absl::SimpleAtoi. In the course of doing this some minor things I encountered along the way were also refactored. This also changes the signatures of the various custom readFile functions to use absl::string_view types.
-rw-r--r-- | third_party/nix/src/libexpr/attr-path.cc | 4 | ||||
-rw-r--r-- | third_party/nix/src/libexpr/get-drvs.cc | 3 | ||||
-rw-r--r-- | third_party/nix/src/libexpr/names.cc | 6 | ||||
-rw-r--r-- | third_party/nix/src/libmain/shared.hh | 3 | ||||
-rw-r--r-- | third_party/nix/src/libstore/binary-cache-store.cc | 13 | ||||
-rw-r--r-- | third_party/nix/src/libstore/build.cc | 6 | ||||
-rw-r--r-- | third_party/nix/src/libstore/download.cc | 16 | ||||
-rw-r--r-- | third_party/nix/src/libstore/globals.cc | 3 | ||||
-rw-r--r-- | third_party/nix/src/libstore/local-store.cc | 3 | ||||
-rw-r--r-- | third_party/nix/src/libstore/machines.cc | 5 | ||||
-rw-r--r-- | third_party/nix/src/libstore/nar-info.cc | 6 | ||||
-rw-r--r-- | third_party/nix/src/libstore/profiles.cc | 29 | ||||
-rw-r--r-- | third_party/nix/src/libstore/store-api.cc | 5 | ||||
-rw-r--r-- | third_party/nix/src/libutil/args.hh | 4 | ||||
-rw-r--r-- | third_party/nix/src/libutil/config.cc | 3 | ||||
-rw-r--r-- | third_party/nix/src/libutil/meson.build | 2 | ||||
-rw-r--r-- | third_party/nix/src/libutil/util.cc | 19 | ||||
-rw-r--r-- | third_party/nix/src/libutil/util.hh | 19 | ||||
-rw-r--r-- | third_party/nix/src/nix-env/nix-env.cc | 7 |
19 files changed, 84 insertions, 72 deletions
diff --git a/third_party/nix/src/libexpr/attr-path.cc b/third_party/nix/src/libexpr/attr-path.cc index 628b58c1b1e3..5f14fca21493 100644 --- a/third_party/nix/src/libexpr/attr-path.cc +++ b/third_party/nix/src/libexpr/attr-path.cc @@ -1,5 +1,7 @@ #include "attr-path.hh" +#include <absl/strings/numbers.h> + #include "eval-inline.hh" #include "util.hh" @@ -50,7 +52,7 @@ Value* findAlongAttrPath(EvalState& state, const std::string& attrPath, /* Is i an index (integer) or a normal attribute name? */ enum { apAttr, apIndex } apType = apAttr; unsigned int attrIndex; - if (string2Int(attr, attrIndex)) { + if (absl::SimpleAtoi(attr, &attrIndex)) { apType = apIndex; } diff --git a/third_party/nix/src/libexpr/get-drvs.cc b/third_party/nix/src/libexpr/get-drvs.cc index bc40ec3fef6c..968108e78c51 100644 --- a/third_party/nix/src/libexpr/get-drvs.cc +++ b/third_party/nix/src/libexpr/get-drvs.cc @@ -4,6 +4,7 @@ #include <regex> #include <utility> +#include <absl/strings/numbers.h> #include <glog/logging.h> #include "derivations.hh" @@ -243,7 +244,7 @@ NixInt DrvInfo::queryMetaInt(const std::string& name, NixInt def) { /* Backwards compatibility with before we had support for integer meta fields. */ NixInt n; - if (string2Int(v->string.s, n)) { + if (absl::SimpleAtoi(v->string.s, &n)) { return n; } } diff --git a/third_party/nix/src/libexpr/names.cc b/third_party/nix/src/libexpr/names.cc index 20c326776cb7..769f9e99db29 100644 --- a/third_party/nix/src/libexpr/names.cc +++ b/third_party/nix/src/libexpr/names.cc @@ -2,6 +2,8 @@ #include <memory> +#include <absl/strings/numbers.h> + #include "util.hh" namespace nix { @@ -68,8 +70,8 @@ std::string nextComponent(std::string::const_iterator& p, static bool componentsLT(const std::string& c1, const std::string& c2) { int n1; int n2; - bool c1Num = string2Int(c1, n1); - bool c2Num = string2Int(c2, n2); + bool c1Num = absl::SimpleAtoi(c1, &n1); + bool c2Num = absl::SimpleAtoi(c2, &n2); if (c1Num && c2Num) { return n1 < n2; diff --git a/third_party/nix/src/libmain/shared.hh b/third_party/nix/src/libmain/shared.hh index edd0a5159a9d..60d7918931d7 100644 --- a/third_party/nix/src/libmain/shared.hh +++ b/third_party/nix/src/libmain/shared.hh @@ -2,6 +2,7 @@ #include <locale> +#include <absl/strings/numbers.h> #include <signal.h> #include "args.hh" @@ -78,7 +79,7 @@ N getIntArg(const std::string& opt, Strings::iterator& i, } } N n; - if (!string2Int(s, n)) + if (!absl::SimpleAtoi(s, &n)) throw UsageError(format("'%1%' requires an integer argument") % opt); return n * multiplier; } diff --git a/third_party/nix/src/libstore/binary-cache-store.cc b/third_party/nix/src/libstore/binary-cache-store.cc index 37d1c1a440a2..ea36078435ba 100644 --- a/third_party/nix/src/libstore/binary-cache-store.cc +++ b/third_party/nix/src/libstore/binary-cache-store.cc @@ -4,6 +4,9 @@ #include <future> #include <memory> +#include <absl/strings/ascii.h> +#include <absl/strings/numbers.h> + #include "archive.hh" #include "compression.hh" #include "derivations.hh" @@ -21,7 +24,8 @@ namespace nix { BinaryCacheStore::BinaryCacheStore(const Params& params) : Store(params) { if (secretKeyFile != "") { - secretKey = std::make_unique<SecretKey>(readFile(secretKeyFile)); + const std::string& secret_key_file = secretKeyFile; + secretKey = std::make_unique<SecretKey>(readFile(secret_key_file)); } StringSink sink; @@ -43,7 +47,8 @@ void BinaryCacheStore::init() { continue; } auto name = line.substr(0, colon); - auto value = trim(line.substr(colon + 1, std::string::npos)); + auto value = + absl::StripAsciiWhitespace(line.substr(colon + 1, std::string::npos)); if (name == "StoreDir") { if (value != storeDir) { throw Error(format("binary cache '%s' is for Nix stores with prefix " @@ -53,7 +58,9 @@ void BinaryCacheStore::init() { } else if (name == "WantMassQuery") { wantMassQuery_ = value == "1"; } else if (name == "Priority") { - string2Int(value, priority); + if (!absl::SimpleAtoi(value, &priority)) { + LOG(WARNING) << "Invalid 'Priority' value: " << value; + } } } } diff --git a/third_party/nix/src/libstore/build.cc b/third_party/nix/src/libstore/build.cc index 49204a72a8cd..c0fa0074d6ea 100644 --- a/third_party/nix/src/libstore/build.cc +++ b/third_party/nix/src/libstore/build.cc @@ -13,6 +13,7 @@ #include <thread> #include <absl/strings/ascii.h> +#include <absl/strings/numbers.h> #include <fcntl.h> #include <grp.h> #include <netdb.h> @@ -2412,7 +2413,7 @@ void DerivationGoal::startBuilder() { userNamespaceSync.readSide = -1; pid_t tmp; - if (!string2Int<pid_t>(readLine(builderOut.readSide.get()), tmp)) { + if (!absl::SimpleAtoi(readLine(builderOut.readSide.get()), &tmp)) { abort(); } pid = tmp; @@ -2805,7 +2806,8 @@ void DerivationGoal::runChild() { std::string netrcData; try { if (drv->isBuiltin() && drv->builder == "builtin:fetchurl") { - netrcData = readFile(settings.netrcFile); + const std::string& netrc_file = settings.netrcFile; + netrcData = readFile(netrc_file); } } catch (SysError&) { } diff --git a/third_party/nix/src/libstore/download.cc b/third_party/nix/src/libstore/download.cc index a83599715c1e..bebe0d1bf848 100644 --- a/third_party/nix/src/libstore/download.cc +++ b/third_party/nix/src/libstore/download.cc @@ -1,6 +1,7 @@ #include "download.hh" #include <absl/strings/ascii.h> +#include <absl/strings/numbers.h> #include "archive.hh" #include "compression.hh" @@ -174,7 +175,8 @@ struct CurlDownloader : public Downloader { size_t headerCallback(void* contents, size_t size, size_t nmemb) { size_t realSize = size * nmemb; std::string line((char*)contents, realSize); - DLOG(INFO) << "got header for '" << request.uri << "': " << trim(line); + DLOG(INFO) << "got header for '" << request.uri + << "': " << absl::StripAsciiWhitespace(line); if (line.compare(0, 5, "HTTP/") == 0) { // new response starts result.etag = ""; auto ss = tokenizeString<std::vector<std::string>>(line, " "); @@ -186,9 +188,10 @@ struct CurlDownloader : public Downloader { } else { auto i = line.find(':'); if (i != std::string::npos) { - std::string name = toLower(trim(std::string(line, 0, i))); + std::string name = absl::AsciiStrToLower( + absl::StripAsciiWhitespace(std::string(line, 0, i))); if (name == "etag") { - result.etag = trim(std::string(line, i + 1)); + result.etag = absl::StripAsciiWhitespace(std::string(line, i + 1)); /* Hack to work around a GitHub bug: it sends ETags, but ignores If-None-Match. So if we get the expected ETag on a 200 response, then shut @@ -200,9 +203,10 @@ struct CurlDownloader : public Downloader { return 0; } } else if (name == "content-encoding") { - encoding = trim(std::string(line, i + 1)); + encoding = absl::StripAsciiWhitespace(std::string(line, i + 1)); } else if (name == "accept-ranges" && - toLower(trim(std::string(line, i + 1))) == "bytes") { + absl::AsciiStrToLower(absl::StripAsciiWhitespace( + std::string(line, i + 1))) == "bytes") { acceptRanges = true; } } @@ -893,7 +897,7 @@ CachedDownloadResult Downloader::downloadCached( tokenizeString<std::vector<std::string>>(readFile(dataFile), "\n"); if (ss.size() >= 3 && ss[0] == url) { time_t lastChecked; - if (string2Int(ss[2], lastChecked) && + if (absl::SimpleAtoi(ss[2], &lastChecked) && (uint64_t)lastChecked + request.ttl >= (uint64_t)time(nullptr)) { skip = true; result.effectiveUri = request.uri; diff --git a/third_party/nix/src/libstore/globals.cc b/third_party/nix/src/libstore/globals.cc index 61293dffed50..7307f035275f 100644 --- a/third_party/nix/src/libstore/globals.cc +++ b/third_party/nix/src/libstore/globals.cc @@ -4,6 +4,7 @@ #include <map> #include <thread> +#include <absl/strings/numbers.h> #include <dlfcn.h> #include "archive.hh" @@ -163,7 +164,7 @@ void BaseSetting<SandboxMode>::convertToArg(Args& args, void MaxBuildJobsSetting::set(const std::string& str) { if (str == "auto") { value = std::max(1U, std::thread::hardware_concurrency()); - } else if (!string2Int(str, value)) { + } else if (!absl::SimpleAtoi(str, &value)) { throw UsageError( "configuration setting '%s' should be 'auto' or an integer", name); } diff --git a/third_party/nix/src/libstore/local-store.cc b/third_party/nix/src/libstore/local-store.cc index 84055740de2c..faea0fbce56a 100644 --- a/third_party/nix/src/libstore/local-store.cc +++ b/third_party/nix/src/libstore/local-store.cc @@ -7,6 +7,7 @@ #include <ctime> #include <iostream> +#include <absl/strings/numbers.h> #include <fcntl.h> #include <glog/logging.h> #include <grp.h> @@ -295,7 +296,7 @@ int LocalStore::getSchema() { int curSchema = 0; if (pathExists(schemaPath)) { std::string s = readFile(schemaPath); - if (!string2Int(s, curSchema)) { + if (!absl::SimpleAtoi(s, &curSchema)) { throw Error(format("'%1%' is corrupt") % schemaPath); } } diff --git a/third_party/nix/src/libstore/machines.cc b/third_party/nix/src/libstore/machines.cc index 2f1a7289bd84..6472e037d14c 100644 --- a/third_party/nix/src/libstore/machines.cc +++ b/third_party/nix/src/libstore/machines.cc @@ -2,6 +2,8 @@ #include <algorithm> +#include <absl/strings/ascii.h> +#include <absl/strings/string_view.h> #include <glog/logging.h> #include "globals.hh" @@ -48,14 +50,13 @@ bool Machine::mandatoryMet(const std::set<std::string>& features) const { void parseMachines(const std::string& s, Machines& machines) { for (auto line : tokenizeString<std::vector<std::string>>(s, "\n;")) { - trim(line); line.erase(std::find(line.begin(), line.end(), '#'), line.end()); if (line.empty()) { continue; } if (line[0] == '@') { - auto file = trim(std::string(line, 1)); + auto file = absl::StripAsciiWhitespace(std::string(line, 1)); try { parseMachines(readFile(file), machines); } catch (const SysError& e) { diff --git a/third_party/nix/src/libstore/nar-info.cc b/third_party/nix/src/libstore/nar-info.cc index 5a217d1b617d..9f4c53e19b59 100644 --- a/third_party/nix/src/libstore/nar-info.cc +++ b/third_party/nix/src/libstore/nar-info.cc @@ -1,5 +1,7 @@ #include "nar-info.hh" +#include <absl/strings/numbers.h> + #include "globals.hh" namespace nix { @@ -47,13 +49,13 @@ NarInfo::NarInfo(const Store& store, const std::string& s, } else if (name == "FileHash") { fileHash = parseHashField(value); } else if (name == "FileSize") { - if (!string2Int(value, fileSize)) { + if (!absl::SimpleAtoi(value, &fileSize)) { corrupt(); } } else if (name == "NarHash") { narHash = parseHashField(value); } else if (name == "NarSize") { - if (!string2Int(value, narSize)) { + if (!absl::SimpleAtoi(value, &narSize)) { corrupt(); } } else if (name == "References") { diff --git a/third_party/nix/src/libstore/profiles.cc b/third_party/nix/src/libstore/profiles.cc index 7c802d754935..3516954b50b7 100644 --- a/third_party/nix/src/libstore/profiles.cc +++ b/third_party/nix/src/libstore/profiles.cc @@ -3,6 +3,9 @@ #include <cerrno> #include <cstdio> +#include <absl/strings/numbers.h> +#include <absl/strings/string_view.h> +#include <absl/strings/strip.h> #include <glog/logging.h> #include <sys/stat.h> #include <sys/types.h> @@ -17,22 +20,22 @@ static bool cmpGensByNumber(const Generation& a, const Generation& b) { return a.number < b.number; } -/* Parse a generation name of the format - `<profilename>-<number>-link'. */ -static int parseName(const std::string& profileName, const std::string& name) { - if (std::string(name, 0, profileName.size() + 1) != profileName + "-") { - return -1; - } - std::string s = std::string(name, profileName.size() + 1); - std::string::size_type p = s.find("-link"); - if (p == std::string::npos) { +// Parse a generation out of the format +// `<profilename>-<generation>-link'. +static int parseName(absl::string_view profileName, absl::string_view name) { + // Consume the `<profilename>-' prefix and and `-link' suffix. + if (!(absl::ConsumePrefix(&name, profileName) && + absl::ConsumePrefix(&name, "-") && + absl::ConsumeSuffix(&name, "-link"))) { return -1; } + int n; - if (string2Int(std::string(s, 0, p), n) && n >= 0) { - return n; + if (!absl::SimpleAtoi(name, &n) && n < 0) { + return -1; } - return -1; + + return n; } Generations findGenerations(const Path& profile, int& curGen) { @@ -218,7 +221,7 @@ void deleteGenerationsOlderThan(const Path& profile, std::string strDays = std::string(timeSpec, 0, timeSpec.size() - 1); int days; - if (!string2Int(strDays, days) || days < 1) { + if (!absl::SimpleAtoi(strDays, &days) || days < 1) { throw Error(format("invalid number of days specifier '%1%'") % timeSpec); } diff --git a/third_party/nix/src/libstore/store-api.cc b/third_party/nix/src/libstore/store-api.cc index e6891395cdc5..54214e6f4e94 100644 --- a/third_party/nix/src/libstore/store-api.cc +++ b/third_party/nix/src/libstore/store-api.cc @@ -3,6 +3,7 @@ #include <future> #include <utility> +#include <absl/strings/numbers.h> #include <glog/logging.h> #include "crypto.hh" @@ -718,7 +719,7 @@ ValidPathInfo decodeValidPathInfo(std::istream& str, bool hashGiven) { getline(str, s); info.narHash = Hash(s, htSHA256); getline(str, s); - if (!string2Int(s, info.narSize)) { + if (!absl::SimpleAtoi(s, &info.narSize)) { throw Error("number expected"); } } @@ -726,7 +727,7 @@ ValidPathInfo decodeValidPathInfo(std::istream& str, bool hashGiven) { std::string s; int n; getline(str, s); - if (!string2Int(s, n)) { + if (!absl::SimpleAtoi(s, &n)) { throw Error("number expected"); } while ((n--) != 0) { diff --git a/third_party/nix/src/libutil/args.hh b/third_party/nix/src/libutil/args.hh index 20a6379fecba..2c352a04368c 100644 --- a/third_party/nix/src/libutil/args.hh +++ b/third_party/nix/src/libutil/args.hh @@ -4,6 +4,8 @@ #include <map> #include <memory> +#include <absl/strings/numbers.h> + #include "util.hh" namespace nix { @@ -179,7 +181,7 @@ class Args { .arity(1) .handler([=](std::vector<std::string> ss) { I n; - if (!string2Int(ss[0], n)) + if (!absl::SimpleAtoi(ss[0], &n)) throw UsageError("flag '--%s' requires a integer argument", longName); fun(n); diff --git a/third_party/nix/src/libutil/config.cc b/third_party/nix/src/libutil/config.cc index c7c952abf16f..bc81ce77ceb5 100644 --- a/third_party/nix/src/libutil/config.cc +++ b/third_party/nix/src/libutil/config.cc @@ -3,6 +3,7 @@ #include <utility> +#include <absl/strings/numbers.h> #include <glog/logging.h> #include "args.hh" @@ -214,7 +215,7 @@ std::string BaseSetting<std::string>::to_string() { template <typename T> void BaseSetting<T>::set(const std::string& str) { static_assert(std::is_integral<T>::value, "Integer required."); - if (!string2Int(str, value)) { + if (!absl::SimpleAtoi(str, &value)) { throw UsageError("setting '%s' has invalid value '%s'", name, str); } } diff --git a/third_party/nix/src/libutil/meson.build b/third_party/nix/src/libutil/meson.build index a6494e6eac7c..50043a8fad57 100644 --- a/third_party/nix/src/libutil/meson.build +++ b/third_party/nix/src/libutil/meson.build @@ -47,7 +47,7 @@ libutil_dep_list = [ openssl_dep, pthread_dep, libsodium_dep, -] +] + absl_deps libutil_link_list = [] libutil_link_args = [] diff --git a/third_party/nix/src/libutil/util.cc b/third_party/nix/src/libutil/util.cc index 696a8ff2365e..8dca97af98a0 100644 --- a/third_party/nix/src/libutil/util.cc +++ b/third_party/nix/src/libutil/util.cc @@ -12,6 +12,7 @@ #include <thread> #include <utility> +#include <absl/strings/string_view.h> #include <fcntl.h> #include <grp.h> #include <pwd.h> @@ -306,16 +307,17 @@ std::string readFile(int fd) { return std::string((char*)buf.data(), st.st_size); } -std::string readFile(const Path& path, bool drain) { - AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); +std::string readFile(absl::string_view path, bool drain) { + AutoCloseFD fd = open(std::string(path).c_str(), O_RDONLY | O_CLOEXEC); if (!fd) { throw SysError(format("opening file '%1%'") % path); } return drain ? drainFD(fd.get()) : readFile(fd.get()); } -void readFile(const Path& path, Sink& sink) { - AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); +void readFile(absl::string_view path, Sink& sink) { + // TODO(tazjin): use stdlib functions for this stuff + AutoCloseFD fd = open(std::string(path).c_str(), O_RDONLY | O_CLOEXEC); if (!fd) { throw SysError("opening file '%s'", path); } @@ -1213,15 +1215,6 @@ std::string concatStringsSep(const std::string& sep, const StringSet& ss) { return s; } -std::string trim(const std::string& s, const std::string& whitespace) { - auto i = s.find_first_not_of(whitespace); - if (i == std::string::npos) { - return ""; - } - auto j = s.find_last_not_of(whitespace); - return std::string(s, i, j == std::string::npos ? j : j - i + 1); -} - std::string replaceStrings(const std::string& s, const std::string& from, const std::string& to) { if (from.empty()) { diff --git a/third_party/nix/src/libutil/util.hh b/third_party/nix/src/libutil/util.hh index 7d10df50bf5b..0f3752dfde5a 100644 --- a/third_party/nix/src/libutil/util.hh +++ b/third_party/nix/src/libutil/util.hh @@ -8,6 +8,7 @@ #include <optional> #include <sstream> +#include <absl/strings/string_view.h> #include <dirent.h> #include <signal.h> #include <sys/stat.h> @@ -97,8 +98,8 @@ unsigned char getFileType(const Path& path); /* Read the contents of a file into a string. */ std::string readFile(int fd); -std::string readFile(const Path& path, bool drain = false); -void readFile(const Path& path, Sink& sink); +std::string readFile(absl::string_view path, bool drain = false); +void readFile(absl::string_view path, Sink& sink); /* Write a string to a file. */ void writeFile(const Path& path, const std::string& s, mode_t mode = 0666); @@ -325,10 +326,6 @@ C tokenizeString(const std::string& s, std::string concatStringsSep(const std::string& sep, const Strings& ss); std::string concatStringsSep(const std::string& sep, const StringSet& ss); -/* Remove whitespace from the start and end of a string. */ -std::string trim(const std::string& s, - const std::string& whitespace = " \n\r\t"); - /* Replace all occurrences of a string inside another string. */ std::string replaceStrings(const std::string& s, const std::string& from, const std::string& to); @@ -339,16 +336,6 @@ std::string statusToString(int status); bool statusOk(int status); -/* Parse a string into an integer. */ -template <class N> -bool string2Int(const std::string& s, N& n) { - if (std::string(s, 0, 1) == "-" && !std::numeric_limits<N>::is_signed) - return false; - std::istringstream str(s); - str >> n; - return str && str.get() == EOF; -} - /* Parse a string into a float. */ template <class N> bool string2Float(const std::string& s, N& n) { diff --git a/third_party/nix/src/nix-env/nix-env.cc b/third_party/nix/src/nix-env/nix-env.cc index e827f31e5df8..d17bde34f3cd 100644 --- a/third_party/nix/src/nix-env/nix-env.cc +++ b/third_party/nix/src/nix-env/nix-env.cc @@ -4,6 +4,7 @@ #include <iostream> #include <sstream> +#include <absl/strings/numbers.h> #include <glog/logging.h> #include <sys/stat.h> #include <sys/types.h> @@ -1303,7 +1304,7 @@ static void opSwitchGeneration(Globals& globals, Strings opFlags, } int dstGen; - if (!string2Int(opArgs.front(), dstGen)) { + if (!absl::SimpleAtoi(opArgs.front(), &dstGen)) { throw UsageError(format("expected a generation number")); } @@ -1369,7 +1370,7 @@ static void opDeleteGenerations(Globals& globals, Strings opFlags, } std::string str_max = std::string(opArgs.front(), 1, opArgs.front().size()); int max; - if (!string2Int(str_max, max) || max == 0) { + if (!absl::SimpleAtoi(str_max, &max) || max == 0) { throw Error(format("invalid number of generations to keep ‘%1%’") % opArgs.front()); } @@ -1378,7 +1379,7 @@ static void opDeleteGenerations(Globals& globals, Strings opFlags, std::set<unsigned int> gens; for (auto& i : opArgs) { unsigned int n; - if (!string2Int(i, n)) { + if (!absl::SimpleAtoi(i, &n)) { throw UsageError(format("invalid generation number '%1%'") % i); } gens.insert(n); |