aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-04-02 16:21:38 -0400
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-04-02 16:21:38 -0400
commitb2c9315bf2ddda4d4c5ea5a49471114553ddff87 (patch)
tree8ec57641ed5253da2bd4f18d70bead6b080f8505 /src/libutil
parentd1d1ae7a3b97059af09dd5a5dde2e37ada0fddac (diff)
parent2ef99cd10489929a755831251c3fad8f3df2faeb (diff)
Merge remote-tracking branch 'upstream/master' into list-experimental-features
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/abstract-setting-to-json.hh1
-rw-r--r--src/libutil/ansicolor.hh1
-rw-r--r--src/libutil/archive.hh108
-rw-r--r--src/libutil/args.hh56
-rw-r--r--src/libutil/callback.hh9
-rw-r--r--src/libutil/canon-path.cc26
-rw-r--r--src/libutil/canon-path.hh99
-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.hh4
-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.hh19
-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.cc13
-rw-r--r--src/libutil/hash.hh109
-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.hh8
-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.hh146
-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.hh1
-rw-r--r--src/libutil/xml-writer.hh1
45 files changed, 707 insertions, 375 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..54721649c 100644
--- a/src/libutil/ansicolor.hh
+++ b/src/libutil/ansicolor.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
namespace nix {
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index e42dea540..60e33dd40 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,71 @@
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 +86,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 +117,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.hh b/src/libutil/args.hh
index 2969806dd..07d0d8eae 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,14 +217,19 @@ 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;
@@ -221,8 +241,10 @@ struct Command : virtual public Args
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 +252,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..76e48c4f2 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,42 @@ 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..2b5424b3d 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.
*
* ```
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 59a766034..a001056f7 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..eafc6a540 100644
--- a/src/libutil/error.hh
+++ b/src/libutil/error.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "suggestions.hh"
#include "ref.hh"
@@ -54,20 +55,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 +111,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 1f1852705..7c2f872c5 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 and documentation in the corresponding `.cc` file as well.
- **/
+ */
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.cc b/src/libutil/hash.cc
index d2fd0c15a..5735e4715 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -71,12 +71,13 @@ const std::string base16Chars = "0123456789abcdef";
static std::string printHash16(const Hash & hash)
{
- char buf[hash.hashSize * 2];
+ std::string buf;
+ buf.reserve(hash.hashSize * 2);
for (unsigned int i = 0; i < hash.hashSize; i++) {
- buf[i * 2] = base16Chars[hash.hash[i] >> 4];
- buf[i * 2 + 1] = base16Chars[hash.hash[i] & 0x0f];
+ buf.push_back(base16Chars[hash.hash[i] >> 4]);
+ buf.push_back(base16Chars[hash.hash[i] & 0x0f]);
}
- return std::string(buf, hash.hashSize * 2);
+ return buf;
}
@@ -130,7 +131,7 @@ std::string Hash::to_string(Base base, bool includeType) const
break;
case Base64:
case SRI:
- s += base64Encode(std::string((const char *) hash, hashSize));
+ s += base64Encode(std::string_view((const char *) hash, hashSize));
break;
}
return s;
@@ -403,7 +404,7 @@ HashType parseHashType(std::string_view s)
throw UsageError("unknown hash algorithm '%1%'", s);
}
-std::string printHashType(HashType ht)
+std::string_view printHashType(HashType ht)
{
switch (ht) {
case htMD5: return "md5";
diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh
index 00f70a572..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,36 +129,54 @@ 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. */
-std::string printHashType(HashType ht);
+/**
+ * And the reverse.
+ */
+std::string_view printHashType(HashType ht);
union Ctx;
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.hh b/src/libutil/logging.hh
index 59a707eef..576068c22 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; }
@@ -214,7 +218,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.hh b/src/libutil/serialise.hh
index 7da5b07fd..2cf527023 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,17 +534,20 @@ 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;
};
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..14b32279c 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 d5e6a2736..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..6c2706cc1 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "types.hh"
#include "error.hh"
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>