refactor(3p/nix/libutil): Replace string2Int & trim functions

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.
This commit is contained in:
Vincent Ambo 2020-05-25 01:19:02 +01:00
parent b371821db5
commit 98299da0fd
19 changed files with 84 additions and 72 deletions

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}
}
}
}

View file

@ -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&) {
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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") {

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);

View file

@ -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);
}
}

View file

@ -47,7 +47,7 @@ libutil_dep_list = [
openssl_dep,
pthread_dep,
libsodium_dep,
]
] + absl_deps
libutil_link_list = []
libutil_link_args = []

View file

@ -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()) {

View file

@ -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) {

View file

@ -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);