aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
authorCarlo Nucera <carlo.nucera@protonmail.com>2020-07-15 17:58:30 -0400
committerCarlo Nucera <carlo.nucera@protonmail.com>2020-07-15 17:58:30 -0400
commit455bdee2056858b223b39aa86822fd83580038db (patch)
treecc9ddb46caf5f77d611152a2e95d9639d200c011 /src/libutil
parentf1c7746eb407258d77b2f7fffec0e5d4facf516a (diff)
parent36a124260361ba8dfa43bf43a067dcc48064c93f (diff)
Merge branch 'master' of github.com:NixOS/nix into derivation-header-include-order
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/ansicolor.hh4
-rw-r--r--src/libutil/archive.hh5
-rw-r--r--src/libutil/error.cc27
-rw-r--r--src/libutil/error.hh6
-rw-r--r--src/libutil/hash.cc1
-rw-r--r--src/libutil/istringstream_nocopy.hh92
-rw-r--r--src/libutil/logging.cc1
-rw-r--r--src/libutil/serialise.hh46
-rw-r--r--src/libutil/tests/logging.cc15
9 files changed, 70 insertions, 127 deletions
diff --git a/src/libutil/ansicolor.hh b/src/libutil/ansicolor.hh
index a38c2d798..ae741f867 100644
--- a/src/libutil/ansicolor.hh
+++ b/src/libutil/ansicolor.hh
@@ -11,7 +11,7 @@ namespace nix {
#define ANSI_GREEN "\e[32;1m"
#define ANSI_YELLOW "\e[33;1m"
#define ANSI_BLUE "\e[34;1m"
-#define ANSI_MAGENTA "\e[35m;1m"
-#define ANSI_CYAN "\e[36m;1m"
+#define ANSI_MAGENTA "\e[35;1m"
+#define ANSI_CYAN "\e[36;1m"
}
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index 768fe2536..302b1bb18 100644
--- a/src/libutil/archive.hh
+++ b/src/libutil/archive.hh
@@ -63,11 +63,12 @@ struct ParseSink
virtual void createSymlink(const Path & path, const string & target) { };
};
-struct TeeSink : ParseSink
+struct TeeParseSink : ParseSink
{
+ StringSink saved;
TeeSource source;
- TeeSink(Source & source) : source(source) { }
+ TeeParseSink(Source & source) : source(source, saved) { }
};
void parseDump(ParseSink & sink, Source & source);
diff --git a/src/libutil/error.cc b/src/libutil/error.cc
index a4ee7afc2..fd6f69b7f 100644
--- a/src/libutil/error.cc
+++ b/src/libutil/error.cc
@@ -355,26 +355,21 @@ std::ostream& showErrorInfo(std::ostream &out, const ErrorInfo &einfo, bool show
for (auto iter = einfo.traces.rbegin(); iter != einfo.traces.rend(); ++iter)
{
- try {
+ out << std::endl << prefix;
+ out << ANSI_BLUE << "trace: " << ANSI_NORMAL << iter->hint.str();
+
+ if (iter->pos.has_value() && (*iter->pos)) {
+ auto pos = iter->pos.value();
out << std::endl << prefix;
- out << ANSI_BLUE << "trace: " << ANSI_NORMAL << iter->hint.str();
+ printAtPos(prefix, pos, out);
- nl = true;
- if (*iter->pos) {
- auto pos = iter->pos.value();
+ auto loc = getCodeLines(pos);
+ if (loc.has_value())
+ {
+ out << std::endl << prefix;
+ printCodeLines(out, prefix, pos, *loc);
out << std::endl << prefix;
-
- printAtPos(prefix, pos, out);
- auto loc = getCodeLines(pos);
- if (loc.has_value())
- {
- out << std::endl << prefix;
- printCodeLines(out, prefix, pos, *loc);
- out << std::endl << prefix;
- }
}
- } catch(const std::bad_optional_access& e) {
- out << iter->hint.str() << std::endl;
}
}
}
diff --git a/src/libutil/error.hh b/src/libutil/error.hh
index 1b0fb43b8..f4b3f11bb 100644
--- a/src/libutil/error.hh
+++ b/src/libutil/error.hh
@@ -1,8 +1,8 @@
#pragma once
-
#include "ref.hh"
#include "types.hh"
+#include "fmt.hh"
#include <cstring>
#include <list>
@@ -10,7 +10,9 @@
#include <map>
#include <optional>
-#include "fmt.hh"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
/* Before 4.7, gcc's std::exception uses empty throw() specifiers for
* its (virtual) destructor and what() in c++11 mode, in violation of spec
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index 1a3e7c5d8..f0d7754d1 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -8,7 +8,6 @@
#include "hash.hh"
#include "archive.hh"
#include "util.hh"
-#include "istringstream_nocopy.hh"
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/src/libutil/istringstream_nocopy.hh b/src/libutil/istringstream_nocopy.hh
deleted file mode 100644
index f7beac578..000000000
--- a/src/libutil/istringstream_nocopy.hh
+++ /dev/null
@@ -1,92 +0,0 @@
-/* This file provides a variant of std::istringstream that doesn't
- copy its string argument. This is useful for large strings. The
- caller must ensure that the string object is not destroyed while
- it's referenced by this object. */
-
-#pragma once
-
-#include <string>
-#include <iostream>
-
-template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>>
-class basic_istringbuf_nocopy : public std::basic_streambuf<CharT, Traits>
-{
-public:
- typedef std::basic_string<CharT, Traits, Allocator> string_type;
-
- typedef typename std::basic_streambuf<CharT, Traits>::off_type off_type;
-
- typedef typename std::basic_streambuf<CharT, Traits>::pos_type pos_type;
-
- typedef typename std::basic_streambuf<CharT, Traits>::int_type int_type;
-
- typedef typename std::basic_streambuf<CharT, Traits>::traits_type traits_type;
-
-private:
- const string_type & s;
-
- off_type off;
-
-public:
- basic_istringbuf_nocopy(const string_type & s) : s{s}, off{0}
- {
- }
-
-private:
- pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which)
- {
- if (which & std::ios_base::in) {
- this->off = dir == std::ios_base::beg
- ? off
- : (dir == std::ios_base::end
- ? s.size() + off
- : this->off + off);
- }
- return pos_type(this->off);
- }
-
- pos_type seekpos(pos_type pos, std::ios_base::openmode which)
- {
- return seekoff(pos, std::ios_base::beg, which);
- }
-
- std::streamsize showmanyc()
- {
- return s.size() - off;
- }
-
- int_type underflow()
- {
- if (typename string_type::size_type(off) == s.size())
- return traits_type::eof();
- return traits_type::to_int_type(s[off]);
- }
-
- int_type uflow()
- {
- if (typename string_type::size_type(off) == s.size())
- return traits_type::eof();
- return traits_type::to_int_type(s[off++]);
- }
-
- int_type pbackfail(int_type ch)
- {
- if (off == 0 || (ch != traits_type::eof() && ch != s[off - 1]))
- return traits_type::eof();
-
- return traits_type::to_int_type(s[--off]);
- }
-
-};
-
-template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>>
-class basic_istringstream_nocopy : public std::basic_iostream<CharT, Traits>
-{
- typedef basic_istringbuf_nocopy<CharT, Traits, Allocator> buf_type;
- buf_type buf;
-public:
- basic_istringstream_nocopy(const typename buf_type::string_type & s) :
- std::basic_iostream<CharT, Traits>(&buf), buf(s) {};
-};
-
-typedef basic_istringstream_nocopy<char> istringstream_nocopy;
diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc
index 90c6afe81..832aee783 100644
--- a/src/libutil/logging.cc
+++ b/src/libutil/logging.cc
@@ -81,7 +81,6 @@ public:
log(ei.level, oss.str());
}
-
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
const std::string & s, const Fields & fields, ActivityId parent)
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index a04118512..8386a4991 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -166,17 +166,30 @@ struct StringSource : Source
};
-/* Adapter class of a Source that saves all data read to `s'. */
+/* A sink that writes all incoming data to two other sinks. */
+struct TeeSink : Sink
+{
+ Sink & sink1, & sink2;
+ TeeSink(Sink & sink1, Sink & sink2) : sink1(sink1), sink2(sink2) { }
+ virtual void operator () (const unsigned char * data, size_t len)
+ {
+ sink1(data, len);
+ sink2(data, len);
+ }
+};
+
+
+/* Adapter class of a Source that saves all data read to a sink. */
struct TeeSource : Source
{
Source & orig;
- ref<std::string> data;
- TeeSource(Source & orig)
- : orig(orig), data(make_ref<std::string>()) { }
+ Sink & sink;
+ TeeSource(Source & orig, Sink & sink)
+ : orig(orig), sink(sink) { }
size_t read(unsigned char * data, size_t len)
{
size_t n = orig.read(data, len);
- this->data->append((const char *) data, n);
+ sink(data, len);
return n;
}
};
@@ -336,4 +349,27 @@ Source & operator >> (Source & in, bool & b)
}
+/* An adapter that converts a std::basic_istream into a source. */
+struct StreamToSourceAdapter : Source
+{
+ std::shared_ptr<std::basic_istream<char>> istream;
+
+ StreamToSourceAdapter(std::shared_ptr<std::basic_istream<char>> istream)
+ : istream(istream)
+ { }
+
+ size_t read(unsigned char * data, size_t len) override
+ {
+ if (!istream->read((char *) data, len)) {
+ if (istream->eof()) {
+ if (istream->gcount() == 0)
+ throw EndOfFile("end of file");
+ } else
+ throw Error("I/O error in StreamToSourceAdapter");
+ }
+ return istream->gcount();
+ }
+};
+
+
}
diff --git a/src/libutil/tests/logging.cc b/src/libutil/tests/logging.cc
index ef22e9966..ad588055f 100644
--- a/src/libutil/tests/logging.cc
+++ b/src/libutil/tests/logging.cc
@@ -251,18 +251,19 @@ namespace nix {
TEST(addTrace, showTracesWithShowTrace) {
SymbolTable testTable;
auto problem_file = testTable.create(test_file);
-
auto oneliner_file = testTable.create(one_liner);
+ auto invalidfilename = testTable.create("invalid filename");
auto e = AssertionError(ErrorInfo {
.name = "wat",
- .description = "a well-known problem occurred",
+ .description = "show-traces",
.hint = hintfmt("it has been %1% days since our last error", "zero"),
.errPos = Pos(foString, problem_file, 2, 13),
});
e.addTrace(Pos(foStdin, oneliner_file, 1, 19), "while trying to compute %1%", 42);
e.addTrace(std::nullopt, "while doing something without a %1%", "pos");
+ e.addTrace(Pos(foFile, invalidfilename, 100, 1), "missing %s", "nix file");
testing::internal::CaptureStderr();
@@ -271,24 +272,25 @@ namespace nix {
logError(e.info());
auto str = testing::internal::GetCapturedStderr();
- ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- AssertionError --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from string\x1B[0m\n\na well-known problem occurred\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nit has been \x1B[33;1mzero\x1B[0m days since our last error\n\x1B[34;1m---- show-trace ----\x1B[0m\n\x1B[34;1mtrace: \x1B[0mwhile trying to compute \x1B[33;1m42\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(1:19)\x1B[34;1m from stdin\x1B[0m\n\n 1| this is the other problem line of code\n | \x1B[31;1m^\x1B[0m\n\n\x1B[34;1mtrace: \x1B[0mwhile doing something without a \x1B[33;1mpos\x1B[0m\n");
+ ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- SysError --- error-unit-test\x1B[0m\nopening file '\x1B[33;1minvalid filename\x1B[0m': \x1B[33;1mNo such file or directory\x1B[0m\n\x1B[31;1merror:\x1B[0m\x1B[34;1m --- AssertionError --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from string\x1B[0m\n\nshow-traces\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nit has been \x1B[33;1mzero\x1B[0m days since our last error\n\x1B[34;1m---- show-trace ----\x1B[0m\n\x1B[34;1mtrace: \x1B[0mwhile trying to compute \x1B[33;1m42\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(1:19)\x1B[34;1m from stdin\x1B[0m\n\n 1| this is the other problem line of code\n | \x1B[31;1m^\x1B[0m\n\n\x1B[34;1mtrace: \x1B[0mwhile doing something without a \x1B[33;1mpos\x1B[0m\n\x1B[34;1mtrace: \x1B[0mmissing \x1B[33;1mnix file\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(100:1)\x1B[34;1m in file: \x1B[0minvalid filename\n");
}
TEST(addTrace, hideTracesWithoutShowTrace) {
SymbolTable testTable;
auto problem_file = testTable.create(test_file);
-
auto oneliner_file = testTable.create(one_liner);
+ auto invalidfilename = testTable.create("invalid filename");
auto e = AssertionError(ErrorInfo {
.name = "wat",
- .description = "a well-known problem occurred",
+ .description = "hide traces",
.hint = hintfmt("it has been %1% days since our last error", "zero"),
.errPos = Pos(foString, problem_file, 2, 13),
});
e.addTrace(Pos(foStdin, oneliner_file, 1, 19), "while trying to compute %1%", 42);
e.addTrace(std::nullopt, "while doing something without a %1%", "pos");
+ e.addTrace(Pos(foFile, invalidfilename, 100, 1), "missing %s", "nix file");
testing::internal::CaptureStderr();
@@ -297,9 +299,10 @@ namespace nix {
logError(e.info());
auto str = testing::internal::GetCapturedStderr();
- ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- AssertionError --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from string\x1B[0m\n\na well-known problem occurred\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nit has been \x1B[33;1mzero\x1B[0m days since our last error\n");
+ ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- AssertionError --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from string\x1B[0m\n\nhide traces\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nit has been \x1B[33;1mzero\x1B[0m days since our last error\n");
}
+
/* ----------------------------------------------------------------------------
* hintfmt
* --------------------------------------------------------------------------*/