aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-04-07 20:39:04 -0400
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-04-07 20:39:04 -0400
commitfd21f9d76e53228acbbbfc05726059d48243f6d2 (patch)
tree95b50f8613e33ba2b81954cbd8b986c1d9be473b /src/libutil
parent5d56e2daf70788fae532d1875edbd4e9bdb5afef (diff)
parent4411c7d7e0242c9f9f8ae3f4d0473c53df12edfb (diff)
Merge remote-tracking branch 'upstream/master' into path-info
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/abstract-setting-to-json.hh1
-rw-r--r--src/libutil/ansicolor.hh6
-rw-r--r--src/libutil/archive.hh110
-rw-r--r--src/libutil/args.cc17
-rw-r--r--src/libutil/args.hh58
-rw-r--r--src/libutil/callback.hh9
-rw-r--r--src/libutil/canon-path.cc26
-rw-r--r--src/libutil/canon-path.hh101
-rw-r--r--src/libutil/cgroup.hh11
-rw-r--r--src/libutil/chunked-vector.hh21
-rw-r--r--src/libutil/closure.hh3
-rw-r--r--src/libutil/comparator.hh14
-rw-r--r--src/libutil/compression.hh1
-rw-r--r--src/libutil/compute-levels.hh3
-rw-r--r--src/libutil/config.hh41
-rw-r--r--src/libutil/error.hh49
-rw-r--r--src/libutil/experimental-features.hh3
-rw-r--r--src/libutil/finally.hh5
-rw-r--r--src/libutil/fmt.hh22
-rw-r--r--src/libutil/git.hh33
-rw-r--r--src/libutil/hash.hh107
-rw-r--r--src/libutil/hilite.hh13
-rw-r--r--src/libutil/json-impls.hh1
-rw-r--r--src/libutil/json-utils.hh1
-rw-r--r--src/libutil/logging.cc5
-rw-r--r--src/libutil/logging.hh33
-rw-r--r--src/libutil/lru-cache.hh23
-rw-r--r--src/libutil/monitor-fd.hh1
-rw-r--r--src/libutil/namespaces.hh1
-rw-r--r--src/libutil/pool.hh45
-rw-r--r--src/libutil/ref.hh7
-rw-r--r--src/libutil/regex-combinators.hh1
-rw-r--r--src/libutil/serialise.cc39
-rw-r--r--src/libutil/serialise.hh152
-rw-r--r--src/libutil/split.hh11
-rw-r--r--src/libutil/suggestions.hh8
-rw-r--r--src/libutil/sync.hh33
-rw-r--r--src/libutil/tarfile.hh5
-rw-r--r--src/libutil/tests/canon-path.cc73
-rw-r--r--src/libutil/tests/hash.hh1
-rw-r--r--src/libutil/thread-pool.hh44
-rw-r--r--src/libutil/topo-sort.hh1
-rw-r--r--src/libutil/types.hh47
-rw-r--r--src/libutil/url-parts.hh16
-rw-r--r--src/libutil/url.hh6
-rw-r--r--src/libutil/util.hh479
-rw-r--r--src/libutil/xml-writer.hh1
47 files changed, 1136 insertions, 552 deletions
diff --git a/src/libutil/abstract-setting-to-json.hh b/src/libutil/abstract-setting-to-json.hh
index 2d82b54e7..7b6c3fcb5 100644
--- a/src/libutil/abstract-setting-to-json.hh
+++ b/src/libutil/abstract-setting-to-json.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <nlohmann/json.hpp>
#include "config.hh"
diff --git a/src/libutil/ansicolor.hh b/src/libutil/ansicolor.hh
index 38305e71c..86becafa6 100644
--- a/src/libutil/ansicolor.hh
+++ b/src/libutil/ansicolor.hh
@@ -1,8 +1,12 @@
#pragma once
+/**
+ * @file
+ *
+ * @brief Some ANSI escape sequences.
+ */
namespace nix {
-/* Some ANSI escape sequences. */
#define ANSI_NORMAL "\e[0m"
#define ANSI_BOLD "\e[1m"
#define ANSI_FAINT "\e[2m"
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index e42dea540..2cf164a41 100644
--- a/src/libutil/archive.hh
+++ b/src/libutil/archive.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "types.hh"
#include "serialise.hh"
@@ -7,54 +8,73 @@
namespace nix {
-/* dumpPath creates a Nix archive of the specified path. The format
- is as follows:
-
- IF path points to a REGULAR FILE:
- dump(path) = attrs(
- [ ("type", "regular")
- , ("contents", contents(path))
- ])
-
- IF path points to a DIRECTORY:
- dump(path) = attrs(
- [ ("type", "directory")
- , ("entries", concat(map(f, sort(entries(path)))))
- ])
- where f(fn) = attrs(
- [ ("name", fn)
- , ("file", dump(path + "/" + fn))
- ])
-
- where:
-
- attrs(as) = concat(map(attr, as)) + encN(0)
- attrs((a, b)) = encS(a) + encS(b)
-
- encS(s) = encN(len(s)) + s + (padding until next 64-bit boundary)
-
- encN(n) = 64-bit little-endian encoding of n.
-
- contents(path) = the contents of a regular file.
-
- sort(strings) = lexicographic sort by 8-bit value (strcmp).
-
- entries(path) = the entries of a directory, without `.' and
- `..'.
-
- `+' denotes string concatenation. */
-
-
+/**
+ * dumpPath creates a Nix archive of the specified path.
+ *
+ * @param path the file system data to dump. Dumping is recursive so if
+ * this is a directory we dump it and all its children.
+ *
+ * @param [out] sink The serialised archive is fed into this sink.
+ *
+ * @param filter Can be used to skip certain files.
+ *
+ * The format is as follows:
+ *
+ * ```
+ * IF path points to a REGULAR FILE:
+ * dump(path) = attrs(
+ * [ ("type", "regular")
+ * , ("contents", contents(path))
+ * ])
+ *
+ * IF path points to a DIRECTORY:
+ * dump(path) = attrs(
+ * [ ("type", "directory")
+ * , ("entries", concat(map(f, sort(entries(path)))))
+ * ])
+ * where f(fn) = attrs(
+ * [ ("name", fn)
+ * , ("file", dump(path + "/" + fn))
+ * ])
+ *
+ * where:
+ *
+ * attrs(as) = concat(map(attr, as)) + encN(0)
+ * attrs((a, b)) = encS(a) + encS(b)
+ *
+ * encS(s) = encN(len(s)) + s + (padding until next 64-bit boundary)
+ *
+ * encN(n) = 64-bit little-endian encoding of n.
+ *
+ * contents(path) = the contents of a regular file.
+ *
+ * sort(strings) = lexicographic sort by 8-bit value (strcmp).
+ *
+ * entries(path) = the entries of a directory, without `.` and
+ * `..`.
+ *
+ * `+` denotes string concatenation.
+ * ```
+ */
void dumpPath(const Path & path, Sink & sink,
PathFilter & filter = defaultPathFilter);
-/* Same as `void dumpPath()`, but returns the last modified date of the path */
+/**
+ * Same as dumpPath(), but returns the last modified date of the path.
+ */
time_t dumpPathAndGetMtime(const Path & path, Sink & sink,
PathFilter & filter = defaultPathFilter);
+/**
+ * Dump an archive with a single file with these contents.
+ *
+ * @param s Contents of the file.
+ */
void dumpString(std::string_view s, Sink & sink);
-/* FIXME: fix this API, it sucks. */
+/**
+ * \todo Fix this API, it sucks.
+ */
struct ParseSink
{
virtual void createDirectory(const Path & path) { };
@@ -68,8 +88,10 @@ struct ParseSink
virtual void createSymlink(const Path & path, const std::string & target) { };
};
-/* If the NAR archive contains a single file at top-level, then save
- the contents of the file to `s'. Otherwise barf. */
+/**
+ * If the NAR archive contains a single file at top-level, then save
+ * the contents of the file to `s`. Otherwise barf.
+ */
struct RetrieveRegularNARSink : ParseSink
{
bool regular = true;
@@ -97,7 +119,9 @@ void parseDump(ParseSink & sink, Source & source);
void restorePath(const Path & path, Source & source);
-/* Read a NAR from 'source' and write it to 'sink'. */
+/**
+ * Read a NAR from 'source' and write it to 'sink'.
+ */
void copyNAR(Source & source, Sink & sink);
void copyPath(const Path & from, const Path & to);
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index fc009592c..081dbeb28 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -236,8 +236,6 @@ nlohmann::json Args::toJSON()
auto flags = nlohmann::json::object();
for (auto & [name, flag] : longFlags) {
- /* Skip experimental flags when listing flags. */
- if (!experimentalFeatureSettings.isEnabled(flag->experimentalFeature)) continue;
auto j = nlohmann::json::object();
if (flag->aliases.count(name)) continue;
if (flag->shortName)
@@ -249,6 +247,11 @@ nlohmann::json Args::toJSON()
j["arity"] = flag->handler.arity;
if (!flag->labels.empty())
j["labels"] = flag->labels;
+ // TODO With C++23 use `std::optional::tranform`
+ if (auto & xp = flag->experimentalFeature)
+ j["experimental-feature"] = showExperimentalFeature(*xp);
+ else
+ j["experimental-feature"] = nullptr;
flags[name] = std::move(j);
}
@@ -345,6 +348,11 @@ Strings argvToStrings(int argc, char * * argv)
return args;
}
+std::optional<ExperimentalFeature> Command::experimentalFeature ()
+{
+ return { Xp::NixCommand };
+}
+
MultiCommand::MultiCommand(const Commands & commands_)
: commands(commands_)
{
@@ -408,6 +416,11 @@ nlohmann::json MultiCommand::toJSON()
cat["id"] = command->category();
cat["description"] = trim(categories[command->category()]);
j["category"] = std::move(cat);
+ // TODO With C++23 use `std::optional::tranform`
+ if (auto xp = command->experimentalFeature())
+ cat["experimental-feature"] = showExperimentalFeature(*xp);
+ else
+ cat["experimental-feature"] = nullptr;
cmds[name] = std::move(j);
}
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index 2969806dd..d90129796 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <iostream>
#include <map>
@@ -18,16 +19,22 @@ class Args
{
public:
- /* Parse the command line, throwing a UsageError if something goes
- wrong. */
+ /**
+ * Parse the command line, throwing a UsageError if something goes
+ * wrong.
+ */
void parseCmdline(const Strings & cmdline);
- /* Return a short one-line description of the command. */
+ /**
+ * Return a short one-line description of the command.
+ */
virtual std::string description() { return ""; }
virtual bool forceImpureByDefault() { return false; }
- /* Return documentation about this command, in Markdown format. */
+ /**
+ * Return documentation about this command, in Markdown format.
+ */
virtual std::string doc() { return ""; }
protected:
@@ -146,13 +153,17 @@ protected:
std::set<std::string> hiddenCategories;
- /* Called after all command line flags before the first non-flag
- argument (if any) have been processed. */
+ /**
+ * Called after all command line flags before the first non-flag
+ * argument (if any) have been processed.
+ */
virtual void initialFlagsProcessed() {}
- /* Called after the command line has been processed if we need to generate
- completions. Useful for commands that need to know the whole command line
- in order to know what completions to generate. */
+ /**
+ * Called after the command line has been processed if we need to generate
+ * completions. Useful for commands that need to know the whole command line
+ * in order to know what completions to generate.
+ */
virtual void completionHook() { }
public:
@@ -166,7 +177,9 @@ public:
expectedArgs.emplace_back(std::move(arg));
}
- /* Expect a string argument. */
+ /**
+ * Expect a string argument.
+ */
void expectArg(const std::string & label, std::string * dest, bool optional = false)
{
expectArgs({
@@ -176,7 +189,9 @@ public:
});
}
- /* Expect 0 or more arguments. */
+ /**
+ * Expect 0 or more arguments.
+ */
void expectArgs(const std::string & label, std::vector<std::string> * dest)
{
expectArgs({
@@ -202,27 +217,36 @@ private:
std::set<ExperimentalFeature> flagExperimentalFeatures;
};
-/* A command is an argument parser that can be executed by calling its
- run() method. */
+/**
+ * A command is an argument parser that can be executed by calling its
+ * run() method.
+ */
struct Command : virtual public Args
{
friend class MultiCommand;
virtual ~Command() { }
+ /**
+ * Entry point to the command
+ */
virtual void run() = 0;
typedef int Category;
static constexpr Category catDefault = 0;
+ virtual std::optional<ExperimentalFeature> experimentalFeature ();
+
virtual Category category() { return catDefault; }
};
typedef std::map<std::string, std::function<ref<Command>()>> Commands;
-/* An argument parser that supports multiple subcommands,
- i.e. ‘<command> <subcommand>’. */
+/**
+ * An argument parser that supports multiple subcommands,
+ * i.e. ‘<command> <subcommand>’.
+ */
class MultiCommand : virtual public Args
{
public:
@@ -230,7 +254,9 @@ public:
std::map<Command::Category, std::string> categories;
- // Selected command, if any.
+ /**
+ * Selected command, if any.
+ */
std::optional<std::pair<std::string, ref<Command>>> command;
MultiCommand(const Commands & commands);
diff --git a/src/libutil/callback.hh b/src/libutil/callback.hh
index ef31794be..3710d1239 100644
--- a/src/libutil/callback.hh
+++ b/src/libutil/callback.hh
@@ -1,13 +1,16 @@
#pragma once
+///@file
#include <future>
#include <functional>
namespace nix {
-/* A callback is a wrapper around a lambda that accepts a valid of
- type T or an exception. (We abuse std::future<T> to pass the value or
- exception.) */
+/**
+ * A callback is a wrapper around a lambda that accepts a valid of
+ * type T or an exception. (We abuse std::future<T> to pass the value or
+ * exception.)
+ */
template<typename T>
class Callback
{
diff --git a/src/libutil/canon-path.cc b/src/libutil/canon-path.cc
index b132b4262..ddf6db6d1 100644
--- a/src/libutil/canon-path.cc
+++ b/src/libutil/canon-path.cc
@@ -100,4 +100,30 @@ std::ostream & operator << (std::ostream & stream, const CanonPath & path)
return stream;
}
+std::string CanonPath::makeRelative(const CanonPath & path) const
+{
+ auto p1 = begin();
+ auto p2 = path.begin();
+
+ for (; p1 != end() && p2 != path.end() && *p1 == *p2; ++p1, ++p2) ;
+
+ if (p1 == end() && p2 == path.end())
+ return ".";
+ else if (p1 == end())
+ return std::string(p2.remaining);
+ else {
+ std::string res;
+ while (p1 != end()) {
+ ++p1;
+ if (!res.empty()) res += '/';
+ res += "..";
+ }
+ if (p2 != path.end()) {
+ if (!res.empty()) res += '/';
+ res += p2.remaining;
+ }
+ return res;
+ }
+}
+
}
diff --git a/src/libutil/canon-path.hh b/src/libutil/canon-path.hh
index 9d5984584..614883c06 100644
--- a/src/libutil/canon-path.hh
+++ b/src/libutil/canon-path.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <string>
#include <optional>
@@ -8,28 +9,31 @@
namespace nix {
-/* A canonical representation of a path. It ensures the following:
-
- - It always starts with a slash.
-
- - It never ends with a slash, except if the path is "/".
-
- - A slash is never followed by a slash (i.e. no empty components).
-
- - There are no components equal to '.' or '..'.
-
- Note that the path does not need to correspond to an actually
- existing path, and there is no guarantee that symlinks are
- resolved.
-*/
+/**
+ * A canonical representation of a path. It ensures the following:
+ *
+ * - It always starts with a slash.
+ *
+ * - It never ends with a slash, except if the path is "/".
+ *
+ * - A slash is never followed by a slash (i.e. no empty components).
+ *
+ * - There are no components equal to '.' or '..'.
+ *
+ * Note that the path does not need to correspond to an actually
+ * existing path, and there is no guarantee that symlinks are
+ * resolved.
+ */
class CanonPath
{
std::string path;
public:
- /* Construct a canon path from a non-canonical path. Any '.', '..'
- or empty components are removed. */
+ /**
+ * Construct a canon path from a non-canonical path. Any '.', '..'
+ * or empty components are removed.
+ */
CanonPath(std::string_view raw);
explicit CanonPath(const char * raw)
@@ -44,9 +48,11 @@ public:
static CanonPath root;
- /* If `raw` starts with a slash, return
- `CanonPath(raw)`. Otherwise return a `CanonPath` representing
- `root + "/" + raw`. */
+ /**
+ * If `raw` starts with a slash, return
+ * `CanonPath(raw)`. Otherwise return a `CanonPath` representing
+ * `root + "/" + raw`.
+ */
CanonPath(std::string_view raw, const CanonPath & root);
bool isRoot() const
@@ -58,8 +64,10 @@ public:
const std::string & abs() const
{ return path; }
- /* Like abs(), but return an empty string if this path is
- '/'. Thus the returned string never ends in a slash. */
+ /**
+ * Like abs(), but return an empty string if this path is
+ * '/'. Thus the returned string never ends in a slash.
+ */
const std::string & absOrEmpty() const
{
const static std::string epsilon;
@@ -85,6 +93,9 @@ public:
bool operator != (const Iterator & x) const
{ return remaining.data() != x.remaining.data(); }
+ bool operator == (const Iterator & x) const
+ { return !(*this != x); }
+
const std::string_view operator * () const
{ return remaining.substr(0, slash); }
@@ -104,7 +115,9 @@ public:
std::optional<CanonPath> parent() const;
- /* Remove the last component. Panics if this path is the root. */
+ /**
+ * Remove the last component. Panics if this path is the root.
+ */
void pop();
std::optional<std::string_view> dirOf() const
@@ -125,10 +138,12 @@ public:
bool operator != (const CanonPath & x) const
{ return path != x.path; }
- /* Compare paths lexicographically except that path separators
- are sorted before any other character. That is, in the sorted order
- a directory is always followed directly by its children. For
- instance, 'foo' < 'foo/bar' < 'foo!'. */
+ /**
+ * Compare paths lexicographically except that path separators
+ * are sorted before any other character. That is, in the sorted order
+ * a directory is always followed directly by its children. For
+ * instance, 'foo' < 'foo/bar' < 'foo!'.
+ */
bool operator < (const CanonPath & x) const
{
auto i = path.begin();
@@ -144,28 +159,44 @@ public:
return i == path.end() && j != x.path.end();
}
- /* Return true if `this` is equal to `parent` or a child of
- `parent`. */
+ /**
+ * Return true if `this` is equal to `parent` or a child of
+ * `parent`.
+ */
bool isWithin(const CanonPath & parent) const;
CanonPath removePrefix(const CanonPath & prefix) const;
- /* Append another path to this one. */
+ /**
+ * Append another path to this one.
+ */
void extend(const CanonPath & x);
- /* Concatenate two paths. */
+ /**
+ * Concatenate two paths.
+ */
CanonPath operator + (const CanonPath & x) const;
- /* Add a path component to this one. It must not contain any slashes. */
+ /**
+ * Add a path component to this one. It must not contain any slashes.
+ */
void push(std::string_view c);
CanonPath operator + (std::string_view c) const;
- /* Check whether access to this path is allowed, which is the case
- if 1) `this` is within any of the `allowed` paths; or 2) any of
- the `allowed` paths are within `this`. (The latter condition
- ensures access to the parents of allowed paths.) */
+ /**
+ * Check whether access to this path is allowed, which is the case
+ * if 1) `this` is within any of the `allowed` paths; or 2) any of
+ * the `allowed` paths are within `this`. (The latter condition
+ * ensures access to the parents of allowed paths.)
+ */
bool isAllowed(const std::set<CanonPath> & allowed) const;
+
+ /**
+ * Return a representation `x` of `path` relative to `this`, i.e.
+ * `CanonPath(this.makeRelative(x), this) == path`.
+ */
+ std::string makeRelative(const CanonPath & path) const;
};
std::ostream & operator << (std::ostream & stream, const CanonPath & path);
diff --git a/src/libutil/cgroup.hh b/src/libutil/cgroup.hh
index d08c8ad29..574ae8e5b 100644
--- a/src/libutil/cgroup.hh
+++ b/src/libutil/cgroup.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#if __linux__
@@ -18,10 +19,12 @@ struct CgroupStats
std::optional<std::chrono::microseconds> cpuUser, cpuSystem;
};
-/* Destroy the cgroup denoted by 'path'. The postcondition is that
- 'path' does not exist, and thus any processes in the cgroup have
- been killed. Also return statistics from the cgroup just before
- destruction. */
+/**
+ * Destroy the cgroup denoted by 'path'. The postcondition is that
+ * 'path' does not exist, and thus any processes in the cgroup have
+ * been killed. Also return statistics from the cgroup just before
+ * destruction.
+ */
CgroupStats destroyCgroup(const Path & cgroup);
}
diff --git a/src/libutil/chunked-vector.hh b/src/libutil/chunked-vector.hh
index 0a4f0b400..d914e2542 100644
--- a/src/libutil/chunked-vector.hh
+++ b/src/libutil/chunked-vector.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <cstdint>
#include <cstdlib>
@@ -7,20 +8,24 @@
namespace nix {
-/* Provides an indexable container like vector<> with memory overhead
- guarantees like list<> by allocating storage in chunks of ChunkSize
- elements instead of using a contiguous memory allocation like vector<>
- does. Not using a single vector that is resized reduces memory overhead
- on large data sets by on average (growth factor)/2, mostly
- eliminates copies within the vector during resizing, and provides stable
- references to its elements. */
+/**
+ * Provides an indexable container like vector<> with memory overhead
+ * guarantees like list<> by allocating storage in chunks of ChunkSize
+ * elements instead of using a contiguous memory allocation like vector<>
+ * does. Not using a single vector that is resized reduces memory overhead
+ * on large data sets by on average (growth factor)/2, mostly
+ * eliminates copies within the vector during resizing, and provides stable
+ * references to its elements.
+ */
template<typename T, size_t ChunkSize>
class ChunkedVector {
private:
uint32_t size_ = 0;
std::vector<std::vector<T>> chunks;
- /* keep this out of the ::add hot path */
+ /**
+ * Keep this out of the ::add hot path
+ */
[[gnu::noinline]]
auto & addChunk()
{
diff --git a/src/libutil/closure.hh b/src/libutil/closure.hh
index 779b9b2d5..16e3b93e4 100644
--- a/src/libutil/closure.hh
+++ b/src/libutil/closure.hh
@@ -1,3 +1,6 @@
+#pragma once
+///@file
+
#include <set>
#include <future>
#include "sync.hh"
diff --git a/src/libutil/comparator.hh b/src/libutil/comparator.hh
index eecd5b819..9f661c5c3 100644
--- a/src/libutil/comparator.hh
+++ b/src/libutil/comparator.hh
@@ -1,6 +1,8 @@
#pragma once
+///@file
-/* Awfull hacky generation of the comparison operators by doing a lexicographic
+/**
+ * Awful hacky generation of the comparison operators by doing a lexicographic
* comparison between the choosen fields.
*
* ```
@@ -15,12 +17,12 @@
* }
* ```
*/
-#define GENERATE_ONE_CMP(COMPARATOR, MY_TYPE, FIELDS...) \
+#define GENERATE_ONE_CMP(COMPARATOR, MY_TYPE, ...) \
bool operator COMPARATOR(const MY_TYPE& other) const { \
- const MY_TYPE* me = this; \
- auto fields1 = std::make_tuple( FIELDS ); \
- me = &other; \
- auto fields2 = std::make_tuple( FIELDS ); \
+ __VA_OPT__(const MY_TYPE* me = this;) \
+ auto fields1 = std::make_tuple( __VA_ARGS__ ); \
+ __VA_OPT__(me = &other;) \
+ auto fields2 = std::make_tuple( __VA_ARGS__ ); \
return fields1 COMPARATOR fields2; \
}
#define GENERATE_EQUAL(args...) GENERATE_ONE_CMP(==, args)
diff --git a/src/libutil/compression.hh b/src/libutil/compression.hh
index c470b82a5..3892831c2 100644
--- a/src/libutil/compression.hh
+++ b/src/libutil/compression.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "ref.hh"
#include "types.hh"
diff --git a/src/libutil/compute-levels.hh b/src/libutil/compute-levels.hh
index 8ded295f9..093e7a915 100644
--- a/src/libutil/compute-levels.hh
+++ b/src/libutil/compute-levels.hh
@@ -1,3 +1,6 @@
+#pragma once
+///@file
+
#include "types.hh"
namespace nix {
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index 748d6043b..3c1d70294 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <cassert>
#include <map>
@@ -124,21 +125,21 @@ public:
void reapplyUnknownSettings();
};
-/* A class to simplify providing configuration settings. The typical
- use is to inherit Config and add Setting<T> members:
-
- class MyClass : private Config
- {
- Setting<int> foo{this, 123, "foo", "the number of foos to use"};
- Setting<std::string> bar{this, "blabla", "bar", "the name of the bar"};
-
- MyClass() : Config(readConfigFile("/etc/my-app.conf"))
- {
- std::cout << foo << "\n"; // will print 123 unless overridden
- }
- };
-*/
-
+/**
+ * A class to simplify providing configuration settings. The typical
+ * use is to inherit Config and add Setting<T> members:
+ *
+ * class MyClass : private Config
+ * {
+ * Setting<int> foo{this, 123, "foo", "the number of foos to use"};
+ * Setting<std::string> bar{this, "blabla", "bar", "the name of the bar"};
+ *
+ * MyClass() : Config(readConfigFile("/etc/my-app.conf"))
+ * {
+ * std::cout << foo << "\n"; // will print 123 unless overridden
+ * }
+ * };
+ */
class Config : public AbstractConfig
{
friend class AbstractSetting;
@@ -228,7 +229,9 @@ protected:
bool isOverridden() const { return overridden; }
};
-/* A setting of type T. */
+/**
+ * A setting of type T.
+ */
template<typename T>
class BaseSetting : public AbstractSetting
{
@@ -311,8 +314,10 @@ public:
void operator =(const T & v) { this->assign(v); }
};
-/* A special setting for Paths. These are automatically canonicalised
- (e.g. "/foo//bar/" becomes "/foo/bar"). */
+/**
+ * A special setting for Paths. These are automatically canonicalised
+ * (e.g. "/foo//bar/" becomes "/foo/bar").
+ */
class PathSetting : public BaseSetting<Path>
{
bool allowEmpty;
diff --git a/src/libutil/error.hh b/src/libutil/error.hh
index 0ebeaba61..6a0923081 100644
--- a/src/libutil/error.hh
+++ b/src/libutil/error.hh
@@ -1,4 +1,19 @@
#pragma once
+/**
+ * @file
+ *
+ * @brief This file defines two main structs/classes used in nix error handling.
+ *
+ * ErrorInfo provides a standard payload of error information, with conversion to string
+ * happening in the logger rather than at the call site.
+ *
+ * BaseError is the ancestor of nix specific exceptions (and Interrupted), and contains
+ * an ErrorInfo.
+ *
+ * ErrorInfo structs are sent to the logger as part of an exception, or directly with the
+ * logError or logWarning macros.
+ * See libutil/tests/logging.cc for usage examples.
+ */
#include "suggestions.hh"
#include "ref.hh"
@@ -26,22 +41,6 @@
namespace nix {
-/*
-
- This file defines two main structs/classes used in nix error handling.
-
- ErrorInfo provides a standard payload of error information, with conversion to string
- happening in the logger rather than at the call site.
-
- BaseError is the ancestor of nix specific exceptions (and Interrupted), and contains
- an ErrorInfo.
-
- ErrorInfo structs are sent to the logger as part of an exception, or directly with the
- logError or logWarning macros.
-
- See libutil/tests/logging.cc for usage examples.
-
- */
typedef enum {
lvlError = 0,
@@ -54,20 +53,26 @@ typedef enum {
lvlVomit
} Verbosity;
-// the lines of code surrounding an error.
+/**
+ * The lines of code surrounding an error.
+ */
struct LinesOfCode {
std::optional<std::string> prevLineOfCode;
std::optional<std::string> errLineOfCode;
std::optional<std::string> nextLineOfCode;
};
-/* An abstract type that represents a location in a source file. */
+/**
+ * An abstract type that represents a location in a source file.
+ */
struct AbstractPos
{
uint32_t line = 0;
uint32_t column = 0;
- /* Return the contents of the source file. */
+ /**
+ * Return the contents of the source file.
+ */
virtual std::optional<std::string> getSource() const
{ return std::nullopt; };
@@ -104,8 +109,10 @@ struct ErrorInfo {
std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool showTrace);
-/* BaseError should generally not be caught, as it has Interrupted as
- a subclass. Catch Error instead. */
+/**
+ * BaseError should generally not be caught, as it has Interrupted as
+ * a subclass. Catch Error instead.
+ */
class BaseError : public std::exception
{
protected:
diff --git a/src/libutil/experimental-features.hh b/src/libutil/experimental-features.hh
index ac372e03e..5948ad7ad 100644
--- a/src/libutil/experimental-features.hh
+++ b/src/libutil/experimental-features.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "comparator.hh"
#include "error.hh"
@@ -12,7 +13,7 @@ namespace nix {
*
* If you update this, don’t forget to also change the map defining their
* string representation in the corresponding `.cc` file.
- **/
+ */
enum struct ExperimentalFeature
{
CaDerivations,
diff --git a/src/libutil/finally.hh b/src/libutil/finally.hh
index dee2e8d2f..db654301f 100644
--- a/src/libutil/finally.hh
+++ b/src/libutil/finally.hh
@@ -1,6 +1,9 @@
#pragma once
+///@file
-/* A trivial class to run a function at the end of a scope. */
+/**
+ * A trivial class to run a function at the end of a scope.
+ */
template<typename Fn>
class Finally
{
diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh
index e11426b88..727255b45 100644
--- a/src/libutil/fmt.hh
+++ b/src/libutil/fmt.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <boost/format.hpp>
#include <string>
@@ -8,20 +9,25 @@
namespace nix {
-/* Inherit some names from other namespaces for convenience. */
+/**
+ * Inherit some names from other namespaces for convenience.
+ */
using boost::format;
-/* A variadic template that does nothing. Useful to call a function
- for all variadic arguments but ignoring the result. */
+/**
+ * A variadic template that does nothing. Useful to call a function
+ * for all variadic arguments but ignoring the result.
+ */
struct nop { template<typename... T> nop(T...) {} };
-/* A helper for formatting strings. ‘fmt(format, a_0, ..., a_n)’ is
- equivalent to ‘boost::format(format) % a_0 % ... %
- ... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion
- takes place). */
-
+/**
+ * A helper for formatting strings. ‘fmt(format, a_0, ..., a_n)’ is
+ * equivalent to ‘boost::format(format) % a_0 % ... %
+ * ... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion
+ * takes place).
+ */
template<class F>
inline void formatHelper(F & f)
{
diff --git a/src/libutil/git.hh b/src/libutil/git.hh
index cb13ef0e5..bf2b9a286 100644
--- a/src/libutil/git.hh
+++ b/src/libutil/git.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <string>
#include <string_view>
@@ -8,21 +9,23 @@ namespace nix {
namespace git {
-// A line from the output of `git ls-remote --symref`.
-//
-// These can be of two kinds:
-//
-// - Symbolic references of the form
-//
-// ref: {target} {reference}
-//
-// where {target} is itself a reference and {reference} is optional
-//
-// - Object references of the form
-//
-// {target} {reference}
-//
-// where {target} is a commit id and {reference} is mandatory
+/**
+ * A line from the output of `git ls-remote --symref`.
+ *
+ * These can be of two kinds:
+ *
+ * - Symbolic references of the form
+ *
+ * ref: {target} {reference}
+ *
+ * where {target} is itself a reference and {reference} is optional
+ *
+ * - Object references of the form
+ *
+ * {target} {reference}
+ *
+ * where {target} is a commit id and {reference} is mandatory
+ */
struct LsRemoteRefLine {
enum struct Kind {
Symbolic,
diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh
index 38d09646e..be1fdba2a 100644
--- a/src/libutil/hash.hh
+++ b/src/libutil/hash.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "types.hh"
#include "serialise.hh"
@@ -33,62 +34,86 @@ struct Hash
HashType type;
- /* Create a zero-filled hash object. */
+ /**
+ * Create a zero-filled hash object.
+ */
Hash(HashType type);
- /* Parse the hash from a string representation in the format
- "[<type>:]<base16|base32|base64>" or "<type>-<base64>" (a
- Subresource Integrity hash expression). If the 'type' argument
- is not present, then the hash type must be specified in the
- string. */
+ /**
+ * Parse the hash from a string representation in the format
+ * "[<type>:]<base16|base32|base64>" or "<type>-<base64>" (a
+ * Subresource Integrity hash expression). If the 'type' argument
+ * is not present, then the hash type must be specified in the
+ * string.
+ */
static Hash parseAny(std::string_view s, std::optional<HashType> type);
- /* Parse a hash from a string representation like the above, except the
- type prefix is mandatory is there is no separate arguement. */
+ /**
+ * Parse a hash from a string representation like the above, except the
+ * type prefix is mandatory is there is no separate arguement.
+ */
static Hash parseAnyPrefixed(std::string_view s);
- /* Parse a plain hash that musst not have any prefix indicating the type.
- The type is passed in to disambiguate. */
+ /**
+ * Parse a plain hash that musst not have any prefix indicating the type.
+ * The type is passed in to disambiguate.
+ */
static Hash parseNonSRIUnprefixed(std::string_view s, HashType type);
static Hash parseSRI(std::string_view original);
private:
- /* The type must be provided, the string view must not include <type>
- prefix. `isSRI` helps disambigate the various base-* encodings. */
+ /**
+ * The type must be provided, the string view must not include <type>
+ * prefix. `isSRI` helps disambigate the various base-* encodings.
+ */
Hash(std::string_view s, HashType type, bool isSRI);
public:
- /* Check whether two hash are equal. */
+ /**
+ * Check whether two hash are equal.
+ */
bool operator == (const Hash & h2) const;
- /* Check whether two hash are not equal. */
+ /**
+ * Check whether two hash are not equal.
+ */
bool operator != (const Hash & h2) const;
- /* For sorting. */
+ /**
+ * For sorting.
+ */
bool operator < (const Hash & h) const;
- /* Returns the length of a base-16 representation of this hash. */
+ /**
+ * Returns the length of a base-16 representation of this hash.
+ */
size_t base16Len() const
{
return hashSize * 2;
}
- /* Returns the length of a base-32 representation of this hash. */
+ /**
+ * Returns the length of a base-32 representation of this hash.
+ */
size_t base32Len() const
{
return (hashSize * 8 - 1) / 5 + 1;
}
- /* Returns the length of a base-64 representation of this hash. */
+ /**
+ * Returns the length of a base-64 representation of this hash.
+ */
size_t base64Len() const
{
return ((4 * hashSize / 3) + 3) & ~3;
}
- /* Return a string representation of the hash, in base-16, base-32
- or base-64. By default, this is prefixed by the hash type
- (e.g. "sha256:"). */
+ /**
+ * Return a string representation of the hash, in base-16, base-32
+ * or base-64. By default, this is prefixed by the hash type
+ * (e.g. "sha256:").
+ */
std::string to_string(Base base, bool includeType) const;
std::string gitRev() const
@@ -104,35 +129,53 @@ public:
static Hash dummy;
};
-/* Helper that defaults empty hashes to the 0 hash. */
+/**
+ * Helper that defaults empty hashes to the 0 hash.
+ */
Hash newHashAllowEmpty(std::string_view hashStr, std::optional<HashType> ht);
-/* Print a hash in base-16 if it's MD5, or base-32 otherwise. */
+/**
+ * Print a hash in base-16 if it's MD5, or base-32 otherwise.
+ */
std::string printHash16or32(const Hash & hash);
-/* Compute the hash of the given string. */
+/**
+ * Compute the hash of the given string.
+ */
Hash hashString(HashType ht, std::string_view s);
-/* Compute the hash of the given file. */
+/**
+ * Compute the hash of the given file.
+ */
Hash hashFile(HashType ht, const Path & path);
-/* Compute the hash of the given path. The hash is defined as
- (essentially) hashString(ht, dumpPath(path)). */
+/**
+ * Compute the hash of the given path. The hash is defined as
+ * (essentially) hashString(ht, dumpPath(path)).
+ */
typedef std::pair<Hash, uint64_t> HashResult;
HashResult hashPath(HashType ht, const Path & path,
PathFilter & filter = defaultPathFilter);
-/* Compress a hash to the specified number of bytes by cyclically
- XORing bytes together. */
+/**
+ * Compress a hash to the specified number of bytes by cyclically
+ * XORing bytes together.
+ */
Hash compressHash(const Hash & hash, unsigned int newSize);
-/* Parse a string representing a hash type. */
+/**
+ * Parse a string representing a hash type.
+ */
HashType parseHashType(std::string_view s);
-/* Will return nothing on parse error */
+/**
+ * Will return nothing on parse error
+ */
std::optional<HashType> parseHashTypeOpt(std::string_view s);
-/* And the reverse. */
+/**
+ * And the reverse.
+ */
std::string_view printHashType(HashType ht);
diff --git a/src/libutil/hilite.hh b/src/libutil/hilite.hh
index f8bdbfc55..2d5cf7c6f 100644
--- a/src/libutil/hilite.hh
+++ b/src/libutil/hilite.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <regex>
#include <vector>
@@ -6,11 +7,13 @@
namespace nix {
-/* Highlight all the given matches in the given string `s` by wrapping
- them between `prefix` and `postfix`.
-
- If some matches overlap, then their union will be wrapped rather
- than the individual matches. */
+/**
+ * Highlight all the given matches in the given string `s` by wrapping
+ * them between `prefix` and `postfix`.
+ *
+ * If some matches overlap, then their union will be wrapped rather
+ * than the individual matches.
+ */
std::string hiliteMatches(
std::string_view s,
std::vector<std::smatch> matches,
diff --git a/src/libutil/json-impls.hh b/src/libutil/json-impls.hh
index bd75748ad..b26163a04 100644
--- a/src/libutil/json-impls.hh
+++ b/src/libutil/json-impls.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "nlohmann/json_fwd.hpp"
diff --git a/src/libutil/json-utils.hh b/src/libutil/json-utils.hh
index b8a031227..eb00e954f 100644
--- a/src/libutil/json-utils.hh
+++ b/src/libutil/json-utils.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <nlohmann/json.hpp>
diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc
index 7cac75ce1..5a2dd99af 100644
--- a/src/libutil/logging.cc
+++ b/src/libutil/logging.cc
@@ -65,9 +65,10 @@ public:
switch (lvl) {
case lvlError: c = '3'; break;
case lvlWarn: c = '4'; break;
- case lvlInfo: c = '5'; break;
+ case lvlNotice: case lvlInfo: c = '5'; break;
case lvlTalkative: case lvlChatty: c = '6'; break;
- default: c = '7';
+ case lvlDebug: case lvlVomit: c = '7';
+ default: c = '7'; break; // should not happen, and missing enum case is reported by -Werror=switch-enum
}
prefix = std::string("<") + c + ">";
}
diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh
index 59a707eef..5aa6bee95 100644
--- a/src/libutil/logging.hh
+++ b/src/libutil/logging.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "types.hh"
#include "error.hh"
@@ -72,6 +73,9 @@ public:
virtual void stop() { };
+ virtual void pause() { };
+ virtual void resume() { };
+
// Whether the logger prints the whole build log
virtual bool isVerbose() { return false; }
@@ -179,12 +183,17 @@ bool handleJSONLogMessage(const std::string & msg,
const Activity & act, std::map<ActivityId, Activity> & activities,
bool trusted);
-extern Verbosity verbosity; /* suppress msgs > this */
-
-/* Print a message with the standard ErrorInfo format.
- In general, use these 'log' macros for reporting problems that may require user
- intervention or that need more explanation. Use the 'print' macros for more
- lightweight status messages. */
+/**
+ * suppress msgs > this
+ */
+extern Verbosity verbosity;
+
+/**
+ * Print a message with the standard ErrorInfo format.
+ * In general, use these 'log' macros for reporting problems that may require user
+ * intervention or that need more explanation. Use the 'print' macros for more
+ * lightweight status messages.
+ */
#define logErrorInfo(level, errorInfo...) \
do { \
if ((level) <= nix::verbosity) { \
@@ -195,9 +204,11 @@ extern Verbosity verbosity; /* suppress msgs > this */
#define logError(errorInfo...) logErrorInfo(lvlError, errorInfo)
#define logWarning(errorInfo...) logErrorInfo(lvlWarn, errorInfo)
-/* Print a string message if the current log level is at least the specified
- level. Note that this has to be implemented as a macro to ensure that the
- arguments are evaluated lazily. */
+/**
+ * Print a string message if the current log level is at least the specified
+ * level. Note that this has to be implemented as a macro to ensure that the
+ * arguments are evaluated lazily.
+ */
#define printMsgUsing(loggerParam, level, args...) \
do { \
auto __lvl = level; \
@@ -214,7 +225,9 @@ extern Verbosity verbosity; /* suppress msgs > this */
#define debug(args...) printMsg(lvlDebug, args)
#define vomit(args...) printMsg(lvlVomit, args)
-/* if verbosity >= lvlWarn, print a message with a yellow 'warning:' prefix. */
+/**
+ * if verbosity >= lvlWarn, print a message with a yellow 'warning:' prefix.
+ */
template<typename... Args>
inline void warn(const std::string & fs, const Args & ... args)
{
diff --git a/src/libutil/lru-cache.hh b/src/libutil/lru-cache.hh
index 6ef4a3e06..0e19517ed 100644
--- a/src/libutil/lru-cache.hh
+++ b/src/libutil/lru-cache.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <cassert>
#include <map>
@@ -7,7 +8,9 @@
namespace nix {
-/* A simple least-recently used cache. Not thread-safe. */
+/**
+ * A simple least-recently used cache. Not thread-safe.
+ */
template<typename Key, typename Value>
class LRUCache
{
@@ -31,7 +34,9 @@ public:
LRUCache(size_t capacity) : capacity(capacity) { }
- /* Insert or upsert an item in the cache. */
+ /**
+ * Insert or upsert an item in the cache.
+ */
void upsert(const Key & key, const Value & value)
{
if (capacity == 0) return;
@@ -39,7 +44,9 @@ public:
erase(key);
if (data.size() >= capacity) {
- /* Retire the oldest item. */
+ /**
+ * Retire the oldest item.
+ */
auto oldest = lru.begin();
data.erase(*oldest);
lru.erase(oldest);
@@ -63,14 +70,18 @@ public:
return true;
}
- /* Look up an item in the cache. If it exists, it becomes the most
- recently used item. */
+ /**
+ * Look up an item in the cache. If it exists, it becomes the most
+ * recently used item.
+ * */
std::optional<Value> get(const Key & key)
{
auto i = data.find(key);
if (i == data.end()) return {};
- /* Move this item to the back of the LRU list. */
+ /**
+ * Move this item to the back of the LRU list.
+ */
lru.erase(i->second.first.it);
auto j = lru.insert(lru.end(), i);
i->second.first.it = j;
diff --git a/src/libutil/monitor-fd.hh b/src/libutil/monitor-fd.hh
index 9518cf8aa..86d0115fc 100644
--- a/src/libutil/monitor-fd.hh
+++ b/src/libutil/monitor-fd.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <thread>
#include <atomic>
diff --git a/src/libutil/namespaces.hh b/src/libutil/namespaces.hh
index e82379b9c..0b7eeb66c 100644
--- a/src/libutil/namespaces.hh
+++ b/src/libutil/namespaces.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
namespace nix {
diff --git a/src/libutil/pool.hh b/src/libutil/pool.hh
index d49067bb9..6247b6125 100644
--- a/src/libutil/pool.hh
+++ b/src/libutil/pool.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <functional>
#include <limits>
@@ -11,33 +12,37 @@
namespace nix {
-/* This template class implements a simple pool manager of resources
- of some type R, such as database connections. It is used as
- follows:
-
- class Connection { ... };
-
- Pool<Connection> pool;
-
- {
- auto conn(pool.get());
- conn->exec("select ...");
- }
-
- Here, the Connection object referenced by ‘conn’ is automatically
- returned to the pool when ‘conn’ goes out of scope.
-*/
-
+/**
+ * This template class implements a simple pool manager of resources
+ * of some type R, such as database connections. It is used as
+ * follows:
+ *
+ * class Connection { ... };
+ *
+ * Pool<Connection> pool;
+ *
+ * {
+ * auto conn(pool.get());
+ * conn->exec("select ...");
+ * }
+ *
+ * Here, the Connection object referenced by ‘conn’ is automatically
+ * returned to the pool when ‘conn’ goes out of scope.
+ */
template <class R>
class Pool
{
public:
- /* A function that produces new instances of R on demand. */
+ /**
+ * A function that produces new instances of R on demand.
+ */
typedef std::function<ref<R>()> Factory;
- /* A function that checks whether an instance of R is still
- usable. Unusable instances are removed from the pool. */
+ /**
+ * A function that checks whether an instance of R is still
+ * usable. Unusable instances are removed from the pool.
+ */
typedef std::function<bool(const ref<R> &)> Validator;
private:
diff --git a/src/libutil/ref.hh b/src/libutil/ref.hh
index 7d38b059c..af5f8304c 100644
--- a/src/libutil/ref.hh
+++ b/src/libutil/ref.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <memory>
#include <exception>
@@ -6,8 +7,10 @@
namespace nix {
-/* A simple non-nullable reference-counted pointer. Actually a wrapper
- around std::shared_ptr that prevents null constructions. */
+/**
+ * A simple non-nullable reference-counted pointer. Actually a wrapper
+ * around std::shared_ptr that prevents null constructions.
+ */
template<typename T>
class ref
{
diff --git a/src/libutil/regex-combinators.hh b/src/libutil/regex-combinators.hh
index 0b997b25a..87d6aa678 100644
--- a/src/libutil/regex-combinators.hh
+++ b/src/libutil/regex-combinators.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <string_view>
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc
index 7476e6f6c..6e53239f5 100644
--- a/src/libutil/serialise.cc
+++ b/src/libutil/serialise.cc
@@ -186,6 +186,22 @@ static DefaultStackAllocator defaultAllocatorSingleton;
StackAllocator *StackAllocator::defaultAllocator = &defaultAllocatorSingleton;
+std::shared_ptr<void> (*create_coro_gc_hook)() = []() -> std::shared_ptr<void> {
+ return {};
+};
+
+/* This class is used for entry and exit hooks on coroutines */
+class CoroutineContext {
+ /* Disable GC when entering the coroutine without the boehm patch,
+ * since it doesn't find the main thread stack in this case.
+ * std::shared_ptr<void> performs type-erasure, so it will call the right
+ * deleter. */
+ const std::shared_ptr<void> coro_gc_hook = create_coro_gc_hook();
+public:
+ CoroutineContext() {};
+ ~CoroutineContext() {};
+};
+
std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
{
struct SourceToSink : FinishSink
@@ -206,7 +222,8 @@ std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
if (in.empty()) return;
cur = in;
- if (!coro)
+ if (!coro) {
+ CoroutineContext ctx;
coro = coro_t::push_type(VirtualStackAllocator{}, [&](coro_t::pull_type & yield) {
LambdaSource source([&](char *out, size_t out_len) {
if (cur.empty()) {
@@ -223,17 +240,24 @@ std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
});
fun(source);
});
+ }
if (!*coro) { abort(); }
- if (!cur.empty()) (*coro)(false);
+ if (!cur.empty()) {
+ CoroutineContext ctx;
+ (*coro)(false);
+ }
}
void finish() override
{
if (!coro) return;
if (!*coro) abort();
- (*coro)(true);
+ {
+ CoroutineContext ctx;
+ (*coro)(true);
+ }
if (*coro) abort();
}
};
@@ -264,18 +288,23 @@ std::unique_ptr<Source> sinkToSource(
size_t read(char * data, size_t len) override
{
- if (!coro)
+ if (!coro) {
+ CoroutineContext ctx;
coro = coro_t::pull_type(VirtualStackAllocator{}, [&](coro_t::push_type & yield) {
LambdaSink sink([&](std::string_view data) {
if (!data.empty()) yield(std::string(data));
});
fun(sink);
});
+ }
if (!*coro) { eof(); abort(); }
if (pos == cur.size()) {
- if (!cur.empty()) (*coro)();
+ if (!cur.empty()) {
+ CoroutineContext ctx;
+ (*coro)();
+ }
cur = coro->get();
pos = 0;
}
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index 7da5b07fd..ba6dbf619 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <memory>
@@ -10,7 +11,9 @@ namespace boost::context { struct stack_context; }
namespace nix {
-/* Abstract destination of binary data. */
+/**
+ * Abstract destination of binary data.
+ */
struct Sink
{
virtual ~Sink() { }
@@ -18,7 +21,9 @@ struct Sink
virtual bool good() { return true; }
};
-/* Just throws away data. */
+/**
+ * Just throws away data.
+ */
struct NullSink : Sink
{
void operator () (std::string_view data) override
@@ -32,8 +37,10 @@ struct FinishSink : virtual Sink
};
-/* A buffered abstract sink. Warning: a BufferedSink should not be
- used from multiple threads concurrently. */
+/**
+ * A buffered abstract sink. Warning: a BufferedSink should not be
+ * used from multiple threads concurrently.
+ */
struct BufferedSink : virtual Sink
{
size_t bufSize, bufPos;
@@ -50,19 +57,25 @@ struct BufferedSink : virtual Sink
};
-/* Abstract source of binary data. */
+/**
+ * Abstract source of binary data.
+ */
struct Source
{
virtual ~Source() { }
- /* Store exactly ‘len’ bytes in the buffer pointed to by ‘data’.
- It blocks until all the requested data is available, or throws
- an error if it is not going to be available. */
+ /**
+ * Store exactly ‘len’ bytes in the buffer pointed to by ‘data’.
+ * It blocks until all the requested data is available, or throws
+ * an error if it is not going to be available.
+ */
void operator () (char * data, size_t len);
- /* Store up to ‘len’ in the buffer pointed to by ‘data’, and
- return the number of bytes stored. It blocks until at least
- one byte is available. */
+ /**
+ * Store up to ‘len’ in the buffer pointed to by ‘data’, and
+ * return the number of bytes stored. It blocks until at least
+ * one byte is available.
+ */
virtual size_t read(char * data, size_t len) = 0;
virtual bool good() { return true; }
@@ -73,8 +86,10 @@ struct Source
};
-/* A buffered abstract source. Warning: a BufferedSource should not be
- used from multiple threads concurrently. */
+/**
+ * A buffered abstract source. Warning: a BufferedSource should not be
+ * used from multiple threads concurrently.
+ */
struct BufferedSource : Source
{
size_t bufSize, bufPosIn, bufPosOut;
@@ -88,12 +103,16 @@ struct BufferedSource : Source
bool hasData();
protected:
- /* Underlying read call, to be overridden. */
+ /**
+ * Underlying read call, to be overridden.
+ */
virtual size_t readUnbuffered(char * data, size_t len) = 0;
};
-/* A sink that writes data to a file descriptor. */
+/**
+ * A sink that writes data to a file descriptor.
+ */
struct FdSink : BufferedSink
{
int fd;
@@ -123,7 +142,9 @@ private:
};
-/* A source that reads data from a file descriptor. */
+/**
+ * A source that reads data from a file descriptor.
+ */
struct FdSource : BufferedSource
{
int fd;
@@ -149,7 +170,9 @@ private:
};
-/* A sink that writes data to a string. */
+/**
+ * A sink that writes data to a string.
+ */
struct StringSink : Sink
{
std::string s;
@@ -163,7 +186,9 @@ struct StringSink : Sink
};
-/* A source that reads data from a string. */
+/**
+ * A source that reads data from a string.
+ */
struct StringSource : Source
{
std::string_view s;
@@ -173,7 +198,9 @@ struct StringSource : Source
};
-/* A sink that writes all incoming data to two other sinks. */
+/**
+ * A sink that writes all incoming data to two other sinks.
+ */
struct TeeSink : Sink
{
Sink & sink1, & sink2;
@@ -186,7 +213,9 @@ struct TeeSink : Sink
};
-/* Adapter class of a Source that saves all data read to a sink. */
+/**
+ * Adapter class of a Source that saves all data read to a sink.
+ */
struct TeeSource : Source
{
Source & orig;
@@ -201,7 +230,9 @@ struct TeeSource : Source
}
};
-/* A reader that consumes the original Source until 'size'. */
+/**
+ * A reader that consumes the original Source until 'size'.
+ */
struct SizedSource : Source
{
Source & orig;
@@ -219,7 +250,9 @@ struct SizedSource : Source
return n;
}
- /* Consume the original source until no remain data is left to consume. */
+ /**
+ * Consume the original source until no remain data is left to consume.
+ */
size_t drainAll()
{
std::vector<char> buf(8192);
@@ -232,7 +265,9 @@ struct SizedSource : Source
}
};
-/* A sink that that just counts the number of bytes given to it */
+/**
+ * A sink that that just counts the number of bytes given to it
+ */
struct LengthSink : Sink
{
uint64_t length = 0;
@@ -243,7 +278,9 @@ struct LengthSink : Sink
}
};
-/* Convert a function into a sink. */
+/**
+ * Convert a function into a sink.
+ */
struct LambdaSink : Sink
{
typedef std::function<void(std::string_view data)> lambda_t;
@@ -259,7 +296,9 @@ struct LambdaSink : Sink
};
-/* Convert a function into a source. */
+/**
+ * Convert a function into a source.
+ */
struct LambdaSource : Source
{
typedef std::function<size_t(char *, size_t)> lambda_t;
@@ -274,8 +313,10 @@ struct LambdaSource : Source
}
};
-/* Chain two sources together so after the first is exhausted, the second is
- used */
+/**
+ * Chain two sources together so after the first is exhausted, the second is
+ * used
+ */
struct ChainSource : Source
{
Source & source1, & source2;
@@ -289,8 +330,10 @@ struct ChainSource : Source
std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun);
-/* Convert a function that feeds data into a Sink into a Source. The
- Source executes the function as a coroutine. */
+/**
+ * Convert a function that feeds data into a Sink into a Source. The
+ * Source executes the function as a coroutine.
+ */
std::unique_ptr<Source> sinkToSource(
std::function<void(Sink &)> fun,
std::function<void()> eof = []() {
@@ -376,7 +419,9 @@ Source & operator >> (Source & in, bool & b)
Error readError(Source & source);
-/* An adapter that converts a std::basic_istream into a source. */
+/**
+ * An adapter that converts a std::basic_istream into a source.
+ */
struct StreamToSourceAdapter : Source
{
std::shared_ptr<std::basic_istream<char>> istream;
@@ -399,13 +444,14 @@ struct StreamToSourceAdapter : Source
};
-/* A source that reads a distinct format of concatenated chunks back into its
- logical form, in order to guarantee a known state to the original stream,
- even in the event of errors.
-
- Use with FramedSink, which also allows the logical stream to be terminated
- in the event of an exception.
-*/
+/**
+ * A source that reads a distinct format of concatenated chunks back into its
+ * logical form, in order to guarantee a known state to the original stream,
+ * even in the event of errors.
+ *
+ * Use with FramedSink, which also allows the logical stream to be terminated
+ * in the event of an exception.
+ */
struct FramedSource : Source
{
Source & from;
@@ -450,11 +496,12 @@ struct FramedSource : Source
}
};
-/* Write as chunks in the format expected by FramedSource.
-
- The exception_ptr reference can be used to terminate the stream when you
- detect that an error has occurred on the remote end.
-*/
+/**
+ * Write as chunks in the format expected by FramedSource.
+ *
+ * The exception_ptr reference can be used to terminate the stream when you
+ * detect that an error has occurred on the remote end.
+ */
struct FramedSink : nix::BufferedSink
{
BufferedSink & to;
@@ -487,18 +534,27 @@ struct FramedSink : nix::BufferedSink
};
};
-/* Stack allocation strategy for sinkToSource.
- Mutable to avoid a boehm gc dependency in libutil.
-
- boost::context doesn't provide a virtual class, so we define our own.
+/**
+ * Stack allocation strategy for sinkToSource.
+ * Mutable to avoid a boehm gc dependency in libutil.
+ *
+ * boost::context doesn't provide a virtual class, so we define our own.
*/
struct StackAllocator {
virtual boost::context::stack_context allocate() = 0;
virtual void deallocate(boost::context::stack_context sctx) = 0;
- /* The stack allocator to use in sinkToSource and potentially elsewhere.
- It is reassigned by the initGC() method in libexpr. */
+ /**
+ * The stack allocator to use in sinkToSource and potentially elsewhere.
+ * It is reassigned by the initGC() method in libexpr.
+ */
static StackAllocator *defaultAllocator;
};
+/* Disabling GC when entering a coroutine (without the boehm patch).
+ mutable to avoid boehm gc dependency in libutil.
+ */
+extern std::shared_ptr<void> (*create_coro_gc_hook)();
+
+
}
diff --git a/src/libutil/split.hh b/src/libutil/split.hh
index 87a23b13e..3b9b2b83b 100644
--- a/src/libutil/split.hh
+++ b/src/libutil/split.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <optional>
#include <string_view>
@@ -7,10 +8,12 @@
namespace nix {
-// If `separator` is found, we return the portion of the string before the
-// separator, and modify the string argument to contain only the part after the
-// separator. Otherwise, we return `std::nullopt`, and we leave the argument
-// string alone.
+/**
+ * If `separator` is found, we return the portion of the string before the
+ * separator, and modify the string argument to contain only the part after the
+ * separator. Otherwise, we return `std::nullopt`, and we leave the argument
+ * string alone.
+ */
static inline std::optional<std::string_view> splitPrefixTo(std::string_view & string, char separator) {
auto sepInstance = string.find(separator);
diff --git a/src/libutil/suggestions.hh b/src/libutil/suggestions.hh
index d54dd8e31..9abf5ee5f 100644
--- a/src/libutil/suggestions.hh
+++ b/src/libutil/suggestions.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "comparator.hh"
#include "types.hh"
@@ -13,7 +14,8 @@ int levenshteinDistance(std::string_view first, std::string_view second);
*/
class Suggestion {
public:
- int distance; // The smaller the better
+ /// The smaller the better
+ int distance;
std::string suggestion;
std::string to_string() const;
@@ -43,7 +45,9 @@ public:
std::ostream & operator<<(std::ostream & str, const Suggestion &);
std::ostream & operator<<(std::ostream & str, const Suggestions &);
-// Either a value of type `T`, or some suggestions
+/**
+ * Either a value of type `T`, or some suggestions
+ */
template<typename T>
class OrSuggestions {
public:
diff --git a/src/libutil/sync.hh b/src/libutil/sync.hh
index e1d591d77..47e4512b1 100644
--- a/src/libutil/sync.hh
+++ b/src/libutil/sync.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <cstdlib>
#include <mutex>
@@ -7,22 +8,22 @@
namespace nix {
-/* This template class ensures synchronized access to a value of type
- T. It is used as follows:
-
- struct Data { int x; ... };
-
- Sync<Data> data;
-
- {
- auto data_(data.lock());
- data_->x = 123;
- }
-
- Here, "data" is automatically unlocked when "data_" goes out of
- scope.
-*/
-
+/**
+ * This template class ensures synchronized access to a value of type
+ * T. It is used as follows:
+ *
+ * struct Data { int x; ... };
+ *
+ * Sync<Data> data;
+ *
+ * {
+ * auto data_(data.lock());
+ * data_->x = 123;
+ * }
+ *
+ * Here, "data" is automatically unlocked when "data_" goes out of
+ * scope.
+ */
template<class T, class M = std::mutex>
class Sync
{
diff --git a/src/libutil/tarfile.hh b/src/libutil/tarfile.hh
index 4d9141fd4..24afb710a 100644
--- a/src/libutil/tarfile.hh
+++ b/src/libutil/tarfile.hh
@@ -1,3 +1,6 @@
+#pragma once
+///@file
+
#include "serialise.hh"
#include <archive.h>
@@ -14,7 +17,7 @@ struct TarArchive {
TarArchive(const Path & path);
- // disable copy constructor
+ /// disable copy constructor
TarArchive(const TarArchive &) = delete;
void close();
diff --git a/src/libutil/tests/canon-path.cc b/src/libutil/tests/canon-path.cc
index c1c5adadf..fc94ccc3d 100644
--- a/src/libutil/tests/canon-path.cc
+++ b/src/libutil/tests/canon-path.cc
@@ -107,15 +107,13 @@ namespace nix {
}
TEST(CanonPath, within) {
- {
- ASSERT_TRUE(CanonPath("foo").isWithin(CanonPath("foo")));
- ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("bar")));
- ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("fo")));
- ASSERT_TRUE(CanonPath("foo/bar").isWithin(CanonPath("foo")));
- ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("foo/bar")));
- ASSERT_TRUE(CanonPath("/foo/bar/default.nix").isWithin(CanonPath("/")));
- ASSERT_TRUE(CanonPath("/").isWithin(CanonPath("/")));
- }
+ ASSERT_TRUE(CanonPath("foo").isWithin(CanonPath("foo")));
+ ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("bar")));
+ ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("fo")));
+ ASSERT_TRUE(CanonPath("foo/bar").isWithin(CanonPath("foo")));
+ ASSERT_FALSE(CanonPath("foo").isWithin(CanonPath("foo/bar")));
+ ASSERT_TRUE(CanonPath("/foo/bar/default.nix").isWithin(CanonPath("/")));
+ ASSERT_TRUE(CanonPath("/").isWithin(CanonPath("/")));
}
TEST(CanonPath, sort) {
@@ -127,29 +125,38 @@ namespace nix {
}
TEST(CanonPath, allowed) {
- {
- std::set<CanonPath> allowed {
- CanonPath("foo/bar"),
- CanonPath("foo!"),
- CanonPath("xyzzy"),
- CanonPath("a/b/c"),
- };
-
- ASSERT_TRUE (CanonPath("foo/bar").isAllowed(allowed));
- ASSERT_TRUE (CanonPath("foo/bar/bla").isAllowed(allowed));
- ASSERT_TRUE (CanonPath("foo").isAllowed(allowed));
- ASSERT_FALSE(CanonPath("bar").isAllowed(allowed));
- ASSERT_FALSE(CanonPath("bar/a").isAllowed(allowed));
- ASSERT_TRUE (CanonPath("a").isAllowed(allowed));
- ASSERT_TRUE (CanonPath("a/b").isAllowed(allowed));
- ASSERT_TRUE (CanonPath("a/b/c").isAllowed(allowed));
- ASSERT_TRUE (CanonPath("a/b/c/d").isAllowed(allowed));
- ASSERT_TRUE (CanonPath("a/b/c/d/e").isAllowed(allowed));
- ASSERT_FALSE(CanonPath("a/b/a").isAllowed(allowed));
- ASSERT_FALSE(CanonPath("a/b/d").isAllowed(allowed));
- ASSERT_FALSE(CanonPath("aaa").isAllowed(allowed));
- ASSERT_FALSE(CanonPath("zzz").isAllowed(allowed));
- ASSERT_TRUE (CanonPath("/").isAllowed(allowed));
- }
+ std::set<CanonPath> allowed {
+ CanonPath("foo/bar"),
+ CanonPath("foo!"),
+ CanonPath("xyzzy"),
+ CanonPath("a/b/c"),
+ };
+
+ ASSERT_TRUE (CanonPath("foo/bar").isAllowed(allowed));
+ ASSERT_TRUE (CanonPath("foo/bar/bla").isAllowed(allowed));
+ ASSERT_TRUE (CanonPath("foo").isAllowed(allowed));
+ ASSERT_FALSE(CanonPath("bar").isAllowed(allowed));
+ ASSERT_FALSE(CanonPath("bar/a").isAllowed(allowed));
+ ASSERT_TRUE (CanonPath("a").isAllowed(allowed));
+ ASSERT_TRUE (CanonPath("a/b").isAllowed(allowed));
+ ASSERT_TRUE (CanonPath("a/b/c").isAllowed(allowed));
+ ASSERT_TRUE (CanonPath("a/b/c/d").isAllowed(allowed));
+ ASSERT_TRUE (CanonPath("a/b/c/d/e").isAllowed(allowed));
+ ASSERT_FALSE(CanonPath("a/b/a").isAllowed(allowed));
+ ASSERT_FALSE(CanonPath("a/b/d").isAllowed(allowed));
+ ASSERT_FALSE(CanonPath("aaa").isAllowed(allowed));
+ ASSERT_FALSE(CanonPath("zzz").isAllowed(allowed));
+ ASSERT_TRUE (CanonPath("/").isAllowed(allowed));
+ }
+
+ TEST(CanonPath, makeRelative) {
+ CanonPath d("/foo/bar");
+ ASSERT_EQ(d.makeRelative(CanonPath("/foo/bar")), ".");
+ ASSERT_EQ(d.makeRelative(CanonPath("/foo")), "..");
+ ASSERT_EQ(d.makeRelative(CanonPath("/")), "../..");
+ ASSERT_EQ(d.makeRelative(CanonPath("/foo/bar/xyzzy")), "xyzzy");
+ ASSERT_EQ(d.makeRelative(CanonPath("/foo/bar/xyzzy/bla")), "xyzzy/bla");
+ ASSERT_EQ(d.makeRelative(CanonPath("/foo/xyzzy/bla")), "../xyzzy/bla");
+ ASSERT_EQ(d.makeRelative(CanonPath("/xyzzy/bla")), "../../xyzzy/bla");
}
}
diff --git a/src/libutil/tests/hash.hh b/src/libutil/tests/hash.hh
index 9e9650e6e..1f9fa59ae 100644
--- a/src/libutil/tests/hash.hh
+++ b/src/libutil/tests/hash.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <rapidcheck/gen/Arbitrary.h>
diff --git a/src/libutil/thread-pool.hh b/src/libutil/thread-pool.hh
index b22e0d162..0e09fae97 100644
--- a/src/libutil/thread-pool.hh
+++ b/src/libutil/thread-pool.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "sync.hh"
#include "util.hh"
@@ -13,8 +14,10 @@ namespace nix {
MakeError(ThreadPoolShutDown, Error);
-/* A simple thread pool that executes a queue of work items
- (lambdas). */
+/**
+ * A simple thread pool that executes a queue of work items
+ * (lambdas).
+ */
class ThreadPool
{
public:
@@ -23,19 +26,30 @@ public:
~ThreadPool();
- // FIXME: use std::packaged_task?
+ /**
+ * An individual work item.
+ *
+ * \todo use std::packaged_task?
+ */
typedef std::function<void()> work_t;
- /* Enqueue a function to be executed by the thread pool. */
+ /**
+ * Enqueue a function to be executed by the thread pool.
+ */
void enqueue(const work_t & t);
- /* Execute work items until the queue is empty. Note that work
- items are allowed to add new items to the queue; this is
- handled correctly. Queue processing stops prematurely if any
- work item throws an exception. This exception is propagated to
- the calling thread. If multiple work items throw an exception
- concurrently, only one item is propagated; the others are
- printed on stderr and otherwise ignored. */
+ /**
+ * Execute work items until the queue is empty.
+ *
+ * \note Note that work items are allowed to add new items to the
+ * queue; this is handled correctly.
+ *
+ * Queue processing stops prematurely if any work item throws an
+ * exception. This exception is propagated to the calling thread. If
+ * multiple work items throw an exception concurrently, only one
+ * item is propagated; the others are printed on stderr and
+ * otherwise ignored.
+ */
void process();
private:
@@ -62,9 +76,11 @@ private:
void shutdown();
};
-/* Process in parallel a set of items of type T that have a partial
- ordering between them. Thus, any item is only processed after all
- its dependencies have been processed. */
+/**
+ * Process in parallel a set of items of type T that have a partial
+ * ordering between them. Thus, any item is only processed after all
+ * its dependencies have been processed.
+ */
template<typename T>
void processGraph(
ThreadPool & pool,
diff --git a/src/libutil/topo-sort.hh b/src/libutil/topo-sort.hh
index 7418be5e0..a52811fbf 100644
--- a/src/libutil/topo-sort.hh
+++ b/src/libutil/topo-sort.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "error.hh"
diff --git a/src/libutil/types.hh b/src/libutil/types.hh
index 6bcbd7e1d..c86f52175 100644
--- a/src/libutil/types.hh
+++ b/src/libutil/types.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "ref.hh"
@@ -17,7 +18,9 @@ typedef std::set<std::string> StringSet;
typedef std::map<std::string, std::string> StringMap;
typedef std::map<std::string, std::string> StringPairs;
-/* Paths are just strings. */
+/**
+ * Paths are just strings.
+ */
typedef std::string Path;
typedef std::string_view PathView;
typedef std::list<Path> Paths;
@@ -25,15 +28,19 @@ typedef std::set<Path> PathSet;
typedef std::vector<std::pair<std::string, std::string>> Headers;
-/* Helper class to run code at startup. */
+/**
+ * Helper class to run code at startup.
+ */
template<typename T>
struct OnStartup
{
OnStartup(T && t) { t(); }
};
-/* Wrap bools to prevent string literals (i.e. 'char *') from being
- cast to a bool in Attr. */
+/**
+ * Wrap bools to prevent string literals (i.e. 'char *') from being
+ * cast to a bool in Attr.
+ */
template<typename T>
struct Explicit {
T t;
@@ -45,21 +52,25 @@ struct Explicit {
};
-/* This wants to be a little bit like rust's Cow type.
- Some parts of the evaluator benefit greatly from being able to reuse
- existing allocations for strings, but have to be able to also use
- newly allocated storage for values.
-
- We do not define implicit conversions, even with ref qualifiers,
- since those can easily become ambiguous to the reader and can degrade
- into copying behaviour we want to avoid. */
+/**
+ * This wants to be a little bit like rust's Cow type.
+ * Some parts of the evaluator benefit greatly from being able to reuse
+ * existing allocations for strings, but have to be able to also use
+ * newly allocated storage for values.
+ *
+ * We do not define implicit conversions, even with ref qualifiers,
+ * since those can easily become ambiguous to the reader and can degrade
+ * into copying behaviour we want to avoid.
+ */
class BackedStringView {
private:
std::variant<std::string, std::string_view> data;
- /* Needed to introduce a temporary since operator-> must return
- a pointer. Without this we'd need to store the view object
- even when we already own a string. */
+ /**
+ * Needed to introduce a temporary since operator-> must return
+ * a pointer. Without this we'd need to store the view object
+ * even when we already own a string.
+ */
class Ptr {
private:
std::string_view view;
@@ -77,8 +88,10 @@ public:
BackedStringView(const BackedStringView &) = delete;
BackedStringView & operator=(const BackedStringView &) = delete;
- /* We only want move operations defined since the sole purpose of
- this type is to avoid copies. */
+ /**
+ * We only want move operations defined since the sole purpose of
+ * this type is to avoid copies.
+ */
BackedStringView(BackedStringView && other) = default;
BackedStringView & operator=(BackedStringView && other) = default;
diff --git a/src/libutil/url-parts.hh b/src/libutil/url-parts.hh
index afc1df98a..98162b0f7 100644
--- a/src/libutil/url-parts.hh
+++ b/src/libutil/url-parts.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <string>
#include <regex>
@@ -22,21 +23,22 @@ const static std::string segmentRegex = "(?:" + pcharRegex + "*)";
const static std::string absPathRegex = "(?:(?:/" + segmentRegex + ")*/?)";
const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRegex + ")*/?)";
-// A Git ref (i.e. branch or tag name).
-const static std::string refRegexS = "[a-zA-Z0-9@][a-zA-Z0-9_.\\/@-]*"; // FIXME: check
+/// A Git ref (i.e. branch or tag name).
+/// \todo check that this is correct.
+const static std::string refRegexS = "[a-zA-Z0-9@][a-zA-Z0-9_.\\/@-]*";
extern std::regex refRegex;
-// Instead of defining what a good Git Ref is, we define what a bad Git Ref is
-// This is because of the definition of a ref in refs.c in https://github.com/git/git
-// See tests/fetchGitRefs.sh for the full definition
+/// Instead of defining what a good Git Ref is, we define what a bad Git Ref is
+/// This is because of the definition of a ref in refs.c in https://github.com/git/git
+/// See tests/fetchGitRefs.sh for the full definition
const static std::string badGitRefRegexS = "//|^[./]|/\\.|\\.\\.|[[:cntrl:][:space:]:?^~\[]|\\\\|\\*|\\.lock$|\\.lock/|@\\{|[/.]$|^@$|^$";
extern std::regex badGitRefRegex;
-// A Git revision (a SHA-1 commit hash).
+/// A Git revision (a SHA-1 commit hash).
const static std::string revRegexS = "[0-9a-fA-F]{40}";
extern std::regex revRegex;
-// A ref or revision, or a ref followed by a revision.
+/// A ref or revision, or a ref followed by a revision.
const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refRegexS + ")(?:/(" + revRegexS + "))?))";
const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*";
diff --git a/src/libutil/url.hh b/src/libutil/url.hh
index ddd673d65..d2413ec0e 100644
--- a/src/libutil/url.hh
+++ b/src/libutil/url.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "error.hh"
@@ -7,7 +8,8 @@ namespace nix {
struct ParsedURL
{
std::string url;
- std::string base; // URL without query/fragment
+ /// URL without query/fragment
+ std::string base;
std::string scheme;
std::optional<std::string> authority;
std::string path;
@@ -28,7 +30,7 @@ std::map<std::string, std::string> decodeQuery(const std::string & query);
ParsedURL parseURL(const std::string & url);
-/*
+/**
* Although that’s not really standardized anywhere, an number of tools
* use a scheme of the form 'x+y' in urls, where y is the “transport layer”
* scheme, and x is the “application layer” scheme.
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 5a3976d02..56160baaf 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "types.hh"
#include "error.hh"
@@ -32,77 +33,112 @@ struct Sink;
struct Source;
-/* The system for which Nix is compiled. */
+/**
+ * The system for which Nix is compiled.
+ */
extern const std::string nativeSystem;
-/* Return an environment variable. */
+/**
+ * @return an environment variable.
+ */
std::optional<std::string> getEnv(const std::string & key);
-/* Return a non empty environment variable. Returns nullopt if the env
-variable is set to "" */
+/**
+ * @return a non empty environment variable. Returns nullopt if the env
+ * variable is set to ""
+ */
std::optional<std::string> getEnvNonEmpty(const std::string & key);
-/* Get the entire environment. */
+/**
+ * Get the entire environment.
+ */
std::map<std::string, std::string> getEnv();
-/* Clear the environment. */
+/**
+ * Clear the environment.
+ */
void clearEnv();
-/* Return an absolutized path, resolving paths relative to the
- specified directory, or the current directory otherwise. The path
- is also canonicalised. */
+/**
+ * @return An absolutized path, resolving paths relative to the
+ * specified directory, or the current directory otherwise. The path
+ * is also canonicalised.
+ */
Path absPath(Path path,
std::optional<PathView> dir = {},
bool resolveSymlinks = false);
-/* Canonicalise a path by removing all `.' or `..' components and
- double or trailing slashes. Optionally resolves all symlink
- components such that each component of the resulting path is *not*
- a symbolic link. */
+/**
+ * Canonicalise a path by removing all `.` or `..` components and
+ * double or trailing slashes. Optionally resolves all symlink
+ * components such that each component of the resulting path is *not*
+ * a symbolic link.
+ */
Path canonPath(PathView path, bool resolveSymlinks = false);
-/* Return the directory part of the given canonical path, i.e.,
- everything before the final `/'. If the path is the root or an
- immediate child thereof (e.g., `/foo'), this means `/'
- is returned.*/
+/**
+ * @return The directory part of the given canonical path, i.e.,
+ * everything before the final `/`. If the path is the root or an
+ * immediate child thereof (e.g., `/foo`), this means `/`
+ * is returned.
+ */
Path dirOf(const PathView path);
-/* Return the base name of the given canonical path, i.e., everything
- following the final `/' (trailing slashes are removed). */
+/**
+ * @return the base name of the given canonical path, i.e., everything
+ * following the final `/` (trailing slashes are removed).
+ */
std::string_view baseNameOf(std::string_view path);
-/* Perform tilde expansion on a path. */
+/**
+ * Perform tilde expansion on a path.
+ */
std::string expandTilde(std::string_view path);
-/* Check whether 'path' is a descendant of 'dir'. Both paths must be
- canonicalized. */
+/**
+ * Check whether 'path' is a descendant of 'dir'. Both paths must be
+ * canonicalized.
+ */
bool isInDir(std::string_view path, std::string_view dir);
-/* Check whether 'path' is equal to 'dir' or a descendant of
- 'dir'. Both paths must be canonicalized. */
+/**
+ * Check whether 'path' is equal to 'dir' or a descendant of
+ * 'dir'. Both paths must be canonicalized.
+ */
bool isDirOrInDir(std::string_view path, std::string_view dir);
-/* Get status of `path'. */
+/**
+ * Get status of `path`.
+ */
struct stat stat(const Path & path);
struct stat lstat(const Path & path);
-/* Return true iff the given path exists. */
+/**
+ * @return true iff the given path exists.
+ */
bool pathExists(const Path & path);
-/* Read the contents (target) of a symbolic link. The result is not
- in any way canonicalised. */
+/**
+ * Read the contents (target) of a symbolic link. The result is not
+ * in any way canonicalised.
+ */
Path readLink(const Path & path);
bool isLink(const Path & path);
-/* Read the contents of a directory. The entries `.' and `..' are
- removed. */
+/**
+ * Read the contents of a directory. The entries `.` and `..` are
+ * removed.
+ */
struct DirEntry
{
std::string name;
ino_t ino;
- unsigned char type; // one of DT_*
+ /**
+ * one of DT_*
+ */
+ unsigned char type;
DirEntry(std::string name, ino_t ino, unsigned char type)
: name(std::move(name)), ino(ino), type(type) { }
};
@@ -113,74 +149,110 @@ DirEntries readDirectory(const Path & path);
unsigned char getFileType(const Path & path);
-/* Read the contents of a file into a string. */
+/**
+ * Read the contents of a file into a string.
+ */
std::string readFile(int fd);
std::string readFile(const Path & path);
void readFile(const Path & path, Sink & sink);
-/* Write a string to a file. */
+/**
+ * Write a string to a file.
+ */
void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
-/* Flush a file's parent directory to disk */
+/**
+ * Flush a file's parent directory to disk
+ */
void syncParent(const Path & path);
-/* Read a line from a file descriptor. */
+/**
+ * Read a line from a file descriptor.
+ */
std::string readLine(int fd);
-/* Write a line to a file descriptor. */
+/**
+ * Write a line to a file descriptor.
+ */
void writeLine(int fd, std::string s);
-/* Delete a path; i.e., in the case of a directory, it is deleted
- recursively. It's not an error if the path does not exist. The
- second variant returns the number of bytes and blocks freed. */
+/**
+ * Delete a path; i.e., in the case of a directory, it is deleted
+ * recursively. It's not an error if the path does not exist. The
+ * second variant returns the number of bytes and blocks freed.
+ */
void deletePath(const Path & path);
void deletePath(const Path & path, uint64_t & bytesFreed);
std::string getUserName();
-/* Return the given user's home directory from /etc/passwd. */
+/**
+ * @return the given user's home directory from /etc/passwd.
+ */
Path getHomeOf(uid_t userId);
-/* Return $HOME or the user's home directory from /etc/passwd. */
+/**
+ * @return $HOME or the user's home directory from /etc/passwd.
+ */
Path getHome();
-/* Return $XDG_CACHE_HOME or $HOME/.cache. */
+/**
+ * @return $XDG_CACHE_HOME or $HOME/.cache.
+ */
Path getCacheDir();
-/* Return $XDG_CONFIG_HOME or $HOME/.config. */
+/**
+ * @return $XDG_CONFIG_HOME or $HOME/.config.
+ */
Path getConfigDir();
-/* Return the directories to search for user configuration files */
+/**
+ * @return the directories to search for user configuration files
+ */
std::vector<Path> getConfigDirs();
-/* Return $XDG_DATA_HOME or $HOME/.local/share. */
+/**
+ * @return $XDG_DATA_HOME or $HOME/.local/share.
+ */
Path getDataDir();
-/* Return the path of the current executable. */
+/**
+ * @return the path of the current executable.
+ */
std::optional<Path> getSelfExe();
-/* Return $XDG_STATE_HOME or $HOME/.local/state. */
+/**
+ * @return $XDG_STATE_HOME or $HOME/.local/state.
+ */
Path getStateDir();
-/* Create the Nix state directory and return the path to it. */
+/**
+ * Create the Nix state directory and return the path to it.
+ */
Path createNixStateDir();
-/* Create a directory and all its parents, if necessary. Returns the
- list of created directories, in order of creation. */
+/**
+ * Create a directory and all its parents, if necessary. Returns the
+ * list of created directories, in order of creation.
+ */
Paths createDirs(const Path & path);
inline Paths createDirs(PathView path)
{
return createDirs(Path(path));
}
-/* Create a symlink. */
+/**
+ * Create a symlink.
+ */
void createSymlink(const Path & target, const Path & link,
std::optional<time_t> mtime = {});
-/* Atomically create or replace a symlink. */
+/**
+ * Atomically create or replace a symlink.
+ */
void replaceSymlink(const Path & target, const Path & link,
std::optional<time_t> mtime = {});
@@ -196,24 +268,32 @@ void renameFile(const Path & src, const Path & dst);
void moveFile(const Path & src, const Path & dst);
-/* Wrappers arount read()/write() that read/write exactly the
- requested number of bytes. */
+/**
+ * Wrappers arount read()/write() that read/write exactly the
+ * requested number of bytes.
+ */
void readFull(int fd, char * buf, size_t count);
void writeFull(int fd, std::string_view s, bool allowInterrupts = true);
MakeError(EndOfFile, Error);
-/* Read a file descriptor until EOF occurs. */
+/**
+ * Read a file descriptor until EOF occurs.
+ */
std::string drainFD(int fd, bool block = true, const size_t reserveSize=0);
void drainFD(int fd, Sink & sink, bool block = true);
-/* If cgroups are active, attempt to calculate the number of CPUs available.
- If cgroups are unavailable or if cpu.max is set to "max", return 0. */
+/**
+ * If cgroups are active, attempt to calculate the number of CPUs available.
+ * If cgroups are unavailable or if cpu.max is set to "max", return 0.
+ */
unsigned int getMaxCPU();
-/* Automatic cleanup of resources. */
+/**
+ * Automatic cleanup of resources.
+ */
class AutoDelete
@@ -251,11 +331,15 @@ public:
};
-/* Create a temporary directory. */
+/**
+ * Create a temporary directory.
+ */
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755);
-/* Create a temporary file, returning a file handle and its path. */
+/**
+ * Create a temporary file, returning a file handle and its path.
+ */
std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix = "nix");
@@ -298,27 +382,36 @@ public:
};
-/* Kill all processes running under the specified uid by sending them
- a SIGKILL. */
+/**
+ * Kill all processes running under the specified uid by sending them
+ * a SIGKILL.
+ */
void killUser(uid_t uid);
-/* Fork a process that runs the given function, and return the child
- pid to the caller. */
+/**
+ * Fork a process that runs the given function, and return the child
+ * pid to the caller.
+ */
struct ProcessOptions
{
std::string errorPrefix = "";
bool dieWithParent = true;
bool runExitHandlers = false;
bool allowVfork = false;
- int cloneFlags = 0; // use clone() with the specified flags (Linux only)
+ /**
+ * use clone() with the specified flags (Linux only)
+ */
+ int cloneFlags = 0;
};
pid_t startProcess(std::function<void()> fun, const ProcessOptions & options = ProcessOptions());
-/* Run a program and return its stdout in a string (i.e., like the
- shell backtick operator). */
+/**
+ * Run a program and return its stdout in a string (i.e., like the
+ * shell backtick operator).
+ */
std::string runProgram(Path program, bool searchPath = false,
const Strings & args = Strings(),
const std::optional<std::string> & input = {});
@@ -343,25 +436,35 @@ std::pair<int, std::string> runProgram(RunOptions && options);
void runProgram2(const RunOptions & options);
-/* Change the stack size. */
+/**
+ * Change the stack size.
+ */
void setStackSize(size_t stackSize);
-/* Restore the original inherited Unix process context (such as signal
- masks, stack size). */
+/**
+ * Restore the original inherited Unix process context (such as signal
+ * masks, stack size).
+ */
void restoreProcessContext(bool restoreMounts = true);
-/* Save the current mount namespace. Ignored if called more than
- once. */
+/**
+ * Save the current mount namespace. Ignored if called more than
+ * once.
+ */
void saveMountNamespace();
-/* Restore the mount namespace saved by saveMountNamespace(). Ignored
- if saveMountNamespace() was never called. */
+/**
+ * Restore the mount namespace saved by saveMountNamespace(). Ignored
+ * if saveMountNamespace() was never called.
+ */
void restoreMountNamespace();
-/* Cause this thread to not share any FS attributes with the main
- thread, because this causes setns() in restoreMountNamespace() to
- fail. */
+/**
+ * Cause this thread to not share any FS attributes with the main
+ * thread, because this causes setns() in restoreMountNamespace() to
+ * fail.
+ */
void unshareFilesystem();
@@ -376,16 +479,22 @@ public:
{ }
};
-/* Convert a list of strings to a null-terminated vector of char
- *'s. The result must not be accessed beyond the lifetime of the
- list of strings. */
+/**
+ * Convert a list of strings to a null-terminated vector of `char
+ * *`s. The result must not be accessed beyond the lifetime of the
+ * list of strings.
+ */
std::vector<char *> stringsToCharPtrs(const Strings & ss);
-/* Close all file descriptors except those listed in the given set.
- Good practice in child processes. */
+/**
+ * Close all file descriptors except those listed in the given set.
+ * Good practice in child processes.
+ */
void closeMostFDs(const std::set<int> & exceptions);
-/* Set the close-on-exec flag for the given file descriptor. */
+/**
+ * Set the close-on-exec flag for the given file descriptor.
+ */
void closeOnExec(int fd);
@@ -411,12 +520,16 @@ MakeError(Interrupted, BaseError);
MakeError(FormatError, Error);
-/* String tokenizer. */
+/**
+ * String tokenizer.
+ */
template<class C> C tokenizeString(std::string_view s, std::string_view separators = " \t\n\r");
-/* Concatenate the given strings with a separator between the
- elements. */
+/**
+ * Concatenate the given strings with a separator between the
+ * elements.
+ */
template<class C>
std::string concatStringsSep(const std::string_view sep, const C & ss)
{
@@ -441,7 +554,9 @@ auto concatStrings(Parts && ... parts)
}
-/* Add quotes around a collection of strings. */
+/**
+ * Add quotes around a collection of strings.
+ */
template<class C> Strings quoteStrings(const C & c)
{
Strings res;
@@ -450,16 +565,23 @@ template<class C> Strings quoteStrings(const C & c)
return res;
}
-/* Remove trailing whitespace from a string. FIXME: return
- std::string_view. */
+/**
+ * Remove trailing whitespace from a string.
+ *
+ * \todo return std::string_view.
+ */
std::string chomp(std::string_view s);
-/* Remove whitespace from the start and end of a string. */
+/**
+ * Remove whitespace from the start and end of a string.
+ */
std::string trim(std::string_view s, std::string_view whitespace = " \n\r\t");
-/* Replace all occurrences of a string inside another string. */
+/**
+ * Replace all occurrences of a string inside another string.
+ */
std::string replaceStrings(
std::string s,
std::string_view from,
@@ -469,14 +591,18 @@ std::string replaceStrings(
std::string rewriteStrings(std::string s, const StringMap & rewrites);
-/* Convert the exit status of a child as returned by wait() into an
- error string. */
+/**
+ * Convert the exit status of a child as returned by wait() into an
+ * error string.
+ */
std::string statusToString(int status);
bool statusOk(int status);
-/* Parse a string into an integer. */
+/**
+ * Parse a string into an integer.
+ */
template<class N>
std::optional<N> string2Int(const std::string_view s)
{
@@ -489,8 +615,10 @@ std::optional<N> string2Int(const std::string_view s)
}
}
-/* Like string2Int(), but support an optional suffix 'K', 'M', 'G' or
- 'T' denoting a binary unit prefix. */
+/**
+ * Like string2Int(), but support an optional suffix 'K', 'M', 'G' or
+ * 'T' denoting a binary unit prefix.
+ */
template<class N>
N string2IntWithUnitPrefix(std::string_view s)
{
@@ -511,7 +639,9 @@ N string2IntWithUnitPrefix(std::string_view s)
throw UsageError("'%s' is not an integer", s);
}
-/* Parse a string into a float. */
+/**
+ * Parse a string into a float.
+ */
template<class N>
std::optional<N> string2Float(const std::string_view s)
{
@@ -523,7 +653,9 @@ std::optional<N> string2Float(const std::string_view s)
}
-/* Convert a little-endian integer to host order. */
+/**
+ * Convert a little-endian integer to host order.
+ */
template<typename T>
T readLittleEndian(unsigned char * p)
{
@@ -535,66 +667,90 @@ T readLittleEndian(unsigned char * p)
}
-/* Return true iff `s' starts with `prefix'. */
+/**
+ * @return true iff `s` starts with `prefix`.
+ */
bool hasPrefix(std::string_view s, std::string_view prefix);
-/* Return true iff `s' ends in `suffix'. */
+/**
+ * @return true iff `s` ends in `suffix`.
+ */
bool hasSuffix(std::string_view s, std::string_view suffix);
-/* Convert a string to lower case. */
+/**
+ * Convert a string to lower case.
+ */
std::string toLower(const std::string & s);
-/* Escape a string as a shell word. */
+/**
+ * Escape a string as a shell word.
+ */
std::string shellEscape(const std::string_view s);
-/* Exception handling in destructors: print an error message, then
- ignore the exception. */
+/**
+ * Exception handling in destructors: print an error message, then
+ * ignore the exception.
+ */
void ignoreException(Verbosity lvl = lvlError);
-/* Tree formatting. */
+/**
+ * Tree formatting.
+ */
constexpr char treeConn[] = "├───";
constexpr char treeLast[] = "└───";
constexpr char treeLine[] = "│ ";
constexpr char treeNull[] = " ";
-/* Determine whether ANSI escape sequences are appropriate for the
- present output. */
+/**
+ * Determine whether ANSI escape sequences are appropriate for the
+ * present output.
+ */
bool shouldANSI();
-/* Truncate a string to 'width' printable characters. If 'filterAll'
- is true, all ANSI escape sequences are filtered out. Otherwise,
- some escape sequences (such as colour setting) are copied but not
- included in the character count. Also, tabs are expanded to
- spaces. */
+/**
+ * Truncate a string to 'width' printable characters. If 'filterAll'
+ * is true, all ANSI escape sequences are filtered out. Otherwise,
+ * some escape sequences (such as colour setting) are copied but not
+ * included in the character count. Also, tabs are expanded to
+ * spaces.
+ */
std::string filterANSIEscapes(std::string_view s,
bool filterAll = false,
unsigned int width = std::numeric_limits<unsigned int>::max());
-/* Base64 encoding/decoding. */
+/**
+ * Base64 encoding/decoding.
+ */
std::string base64Encode(std::string_view s);
std::string base64Decode(std::string_view s);
-/* Remove common leading whitespace from the lines in the string
- 's'. For example, if every line is indented by at least 3 spaces,
- then we remove 3 spaces from the start of every line. */
+/**
+ * Remove common leading whitespace from the lines in the string
+ * 's'. For example, if every line is indented by at least 3 spaces,
+ * then we remove 3 spaces from the start of every line.
+ */
std::string stripIndentation(std::string_view s);
-/* Get the prefix of 's' up to and excluding the next line break (LF
- optionally preceded by CR), and the remainder following the line
- break. */
+/**
+ * Get the prefix of 's' up to and excluding the next line break (LF
+ * optionally preceded by CR), and the remainder following the line
+ * break.
+ */
std::pair<std::string_view, std::string_view> getLine(std::string_view s);
-/* Get a value for the specified key from an associate container. */
+/**
+ * Get a value for the specified key from an associate container.
+ */
template <class T>
const typename T::mapped_type * get(const T & map, const typename T::key_type & key)
{
@@ -611,7 +767,9 @@ typename T::mapped_type * get(T & map, const typename T::key_type & key)
return &i->second;
}
-/* Get a value for the specified key from an associate container, or a default value if the key isn't present. */
+/**
+ * Get a value for the specified key from an associate container, or a default value if the key isn't present.
+ */
template <class T>
const typename T::mapped_type & getOr(T & map,
const typename T::key_type & key,
@@ -622,7 +780,9 @@ const typename T::mapped_type & getOr(T & map,
return i->second;
}
-/* Remove and return the first item from a container. */
+/**
+ * Remove and return the first item from a container.
+ */
template <class T>
std::optional<typename T::value_type> remove_begin(T & c)
{
@@ -634,7 +794,9 @@ std::optional<typename T::value_type> remove_begin(T & c)
}
-/* Remove and return the first item from a container. */
+/**
+ * Remove and return the first item from a container.
+ */
template <class T>
std::optional<typename T::value_type> pop(T & c)
{
@@ -649,8 +811,10 @@ template<typename T>
class Callback;
-/* Start a thread that handles various signals. Also block those signals
- on the current thread (and thus any threads created by it). */
+/**
+ * Start a thread that handles various signals. Also block those signals
+ * on the current thread (and thus any threads created by it).
+ */
void startSignalHandlerThread();
struct InterruptCallback
@@ -658,16 +822,20 @@ struct InterruptCallback
virtual ~InterruptCallback() { };
};
-/* Register a function that gets called on SIGINT (in a non-signal
- context). */
+/**
+ * Register a function that gets called on SIGINT (in a non-signal
+ * context).
+ */
std::unique_ptr<InterruptCallback> createInterruptCallback(
std::function<void()> callback);
void triggerInterrupt();
-/* A RAII class that causes the current thread to receive SIGUSR1 when
- the signal handler thread receives SIGINT. That is, this allows
- SIGINT to be multiplexed to multiple threads. */
+/**
+ * A RAII class that causes the current thread to receive SIGUSR1 when
+ * the signal handler thread receives SIGINT. That is, this allows
+ * SIGINT to be multiplexed to multiple threads.
+ */
struct ReceiveInterrupts
{
pthread_t target;
@@ -681,8 +849,10 @@ struct ReceiveInterrupts
-/* A RAII helper that increments a counter on construction and
- decrements it on destruction. */
+/**
+ * A RAII helper that increments a counter on construction and
+ * decrements it on destruction.
+ */
template<typename T>
struct MaintainCount
{
@@ -693,33 +863,50 @@ struct MaintainCount
};
-/* Return the number of rows and columns of the terminal. */
+/**
+ * @return the number of rows and columns of the terminal.
+ */
std::pair<unsigned short, unsigned short> getWindowSize();
-/* Used in various places. */
+/**
+ * Used in various places.
+ */
typedef std::function<bool(const Path & path)> PathFilter;
extern PathFilter defaultPathFilter;
-/* Common initialisation performed in child processes. */
+/**
+ * Common initialisation performed in child processes.
+ */
void commonChildInit();
-/* Create a Unix domain socket. */
+/**
+ * Create a Unix domain socket.
+ */
AutoCloseFD createUnixDomainSocket();
-/* Create a Unix domain socket in listen mode. */
+/**
+ * Create a Unix domain socket in listen mode.
+ */
AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode);
-/* Bind a Unix domain socket to a path. */
+/**
+ * Bind a Unix domain socket to a path.
+ */
void bind(int fd, const std::string & path);
-/* Connect to a Unix domain socket. */
+/**
+ * Connect to a Unix domain socket.
+ */
void connect(int fd, const std::string & path);
-// A Rust/Python-like enumerate() iterator adapter.
-// Borrowed from http://reedbeta.com/blog/python-like-enumerate-in-cpp17.
+/**
+ * A Rust/Python-like enumerate() iterator adapter.
+ *
+ * Borrowed from http://reedbeta.com/blog/python-like-enumerate-in-cpp17.
+ */
template <typename T,
typename TIter = decltype(std::begin(std::declval<T>())),
typename = decltype(std::end(std::declval<T>()))>
@@ -745,7 +932,9 @@ constexpr auto enumerate(T && iterable)
}
-// C++17 std::visit boilerplate
+/**
+ * C++17 std::visit boilerplate
+ */
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
@@ -753,8 +942,10 @@ template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
std::string showBytes(uint64_t bytes);
-/* Provide an addition operator between strings and string_views
- inexplicably omitted from the standard library. */
+/**
+ * Provide an addition operator between strings and string_views
+ * inexplicably omitted from the standard library.
+ */
inline std::string operator + (const std::string & s1, std::string_view s2)
{
auto s = s1;
diff --git a/src/libutil/xml-writer.hh b/src/libutil/xml-writer.hh
index 4c91adee6..74f53b7ca 100644
--- a/src/libutil/xml-writer.hh
+++ b/src/libutil/xml-writer.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include <iostream>
#include <string>