aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/util.cc
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2021-02-25 21:58:41 +0000
committerJohn Ericson <John.Ericson@Obsidian.Systems>2021-02-25 21:58:41 +0000
commit90d76fa399de4e207ea14ec4c0dd65434f60c152 (patch)
tree3c52e982cba5bcf7b91c99d1b63ba967b4ea8b92 /src/libutil/util.cc
parent4636cc9a1f6de70947abbfb17a0ad91981d1cad7 (diff)
parentca0994819d68aee26a2906c37a47ae609ac46c4c (diff)
Merge remote-tracking branch 'obsidian/path-info' into ca-drv-exotic
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r--src/libutil/util.cc65
1 files changed, 39 insertions, 26 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 53342b5cb..89f7b58f8 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -320,7 +320,7 @@ void readFile(const Path & path, Sink & sink)
}
-void writeFile(const Path & path, const string & s, mode_t mode)
+void writeFile(const Path & path, std::string_view s, mode_t mode)
{
AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode);
if (!fd)
@@ -340,13 +340,13 @@ void writeFile(const Path & path, Source & source, mode_t mode)
if (!fd)
throw SysError("opening file '%1%'", path);
- std::vector<unsigned char> buf(64 * 1024);
+ std::vector<char> buf(64 * 1024);
try {
while (true) {
try {
auto n = source.read(buf.data(), buf.size());
- writeFull(fd.get(), (unsigned char *) buf.data(), n);
+ writeFull(fd.get(), {buf.data(), n});
} catch (EndOfFile &) { break; }
}
} catch (Error & e) {
@@ -632,11 +632,11 @@ void replaceSymlink(const Path & target, const Path & link,
}
-void readFull(int fd, unsigned char * buf, size_t count)
+void readFull(int fd, char * buf, size_t count)
{
while (count) {
checkInterrupt();
- ssize_t res = read(fd, (char *) buf, count);
+ ssize_t res = read(fd, buf, count);
if (res == -1) {
if (errno == EINTR) continue;
throw SysError("reading from file");
@@ -648,27 +648,19 @@ void readFull(int fd, unsigned char * buf, size_t count)
}
-void writeFull(int fd, const unsigned char * buf, size_t count, bool allowInterrupts)
+void writeFull(int fd, std::string_view s, bool allowInterrupts)
{
- while (count) {
+ while (!s.empty()) {
if (allowInterrupts) checkInterrupt();
- ssize_t res = write(fd, (char *) buf, count);
+ ssize_t res = write(fd, s.data(), s.size());
if (res == -1 && errno != EINTR)
throw SysError("writing to file");
- if (res > 0) {
- count -= res;
- buf += res;
- }
+ if (res > 0)
+ s.remove_prefix(res);
}
}
-void writeFull(int fd, const string & s, bool allowInterrupts)
-{
- writeFull(fd, (const unsigned char *) s.data(), s.size(), allowInterrupts);
-}
-
-
string drainFD(int fd, bool block, const size_t reserveSize)
{
StringSink sink(reserveSize);
@@ -705,7 +697,7 @@ void drainFD(int fd, Sink & sink, bool block)
throw SysError("reading from file");
}
else if (rd == 0) break;
- else sink(buf.data(), rd);
+ else sink({(char *) buf.data(), (size_t) rd});
}
}
@@ -1145,7 +1137,7 @@ void runProgram2(const RunOptions & options)
in.readSide = -1;
writerThread = std::thread([&]() {
try {
- std::vector<unsigned char> buf(8 * 1024);
+ std::vector<char> buf(8 * 1024);
while (true) {
size_t n;
try {
@@ -1153,7 +1145,7 @@ void runProgram2(const RunOptions & options)
} catch (EndOfFile &) {
break;
}
- writeFull(in.writeSide.get(), buf.data(), n);
+ writeFull(in.writeSide.get(), {buf.data(), n});
}
promise.set_value();
} catch (...) {
@@ -1257,7 +1249,7 @@ template StringSet tokenizeString(std::string_view s, const string & separators)
template vector<string> tokenizeString(std::string_view s, const string & separators);
-string chomp(const string & s)
+string chomp(std::string_view s)
{
size_t i = s.find_last_not_of(" \n\r\t");
return i == string::npos ? "" : string(s, 0, i + 1);
@@ -1273,11 +1265,11 @@ string trim(const string & s, const string & whitespace)
}
-string replaceStrings(const std::string & s,
+string replaceStrings(std::string_view s,
const std::string & from, const std::string & to)
{
- if (from.empty()) return s;
- string res = s;
+ string res(s);
+ if (from.empty()) return res;
size_t pos = 0;
while ((pos = res.find(from, pos)) != std::string::npos) {
res.replace(pos, from.size(), to);
@@ -1409,7 +1401,28 @@ std::string filterANSIEscapes(const std::string & s, bool filterAll, unsigned in
i++;
else {
- t += *i++; w++;
+ w++;
+ // Copy one UTF-8 character.
+ if ((*i & 0xe0) == 0xc0) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
+ } else if ((*i & 0xf0) == 0xe0) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
+ }
+ } else if ((*i & 0xf8) == 0xf0) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) {
+ t += *i++;
+ if (i != s.end() && ((*i & 0xc0) == 0x80)) t += *i++;
+ }
+ }
+ } else
+ t += *i++;
}
}