diff --git a/doc/manual/src/SUMMARY.md.in b/doc/manual/src/SUMMARY.md.in
index 5df4e2d75..c8cb72fc0 100644
--- a/doc/manual/src/SUMMARY.md.in
+++ b/doc/manual/src/SUMMARY.md.in
@@ -34,7 +34,7 @@
- [Building and Testing](expressions/simple-building-testing.md)
- [Generic Builder Syntax](expressions/generic-builder.md)
- [Nix Expression Language](expressions/expression-language.md)
- - [Values](expressions/language-values.md)
+ - [Data Types](expressions/language-values.md)
- [Language Constructs](expressions/language-constructs.md)
- [Operators](expressions/language-operators.md)
- [Derivations](expressions/derivations.md)
diff --git a/doc/manual/src/advanced-topics/distributed-builds.md b/doc/manual/src/advanced-topics/distributed-builds.md
index b0d7fbf1a..fefd10100 100644
--- a/doc/manual/src/advanced-topics/distributed-builds.md
+++ b/doc/manual/src/advanced-topics/distributed-builds.md
@@ -12,14 +12,14 @@ machine is accessible via SSH and that it has Nix installed. You can
test whether connecting to the remote Nix instance works, e.g.
```console
-$ nix ping-store --store ssh://mac
+$ nix store ping --store ssh://mac
```
will try to connect to the machine named `mac`. It is possible to
specify an SSH identity file as part of the remote store URI, e.g.
```console
-$ nix ping-store --store ssh://mac?ssh-key=/home/alice/my-key
+$ nix store ping --store ssh://mac?ssh-key=/home/alice/my-key
```
Since builds should be non-interactive, the key should not have a
diff --git a/doc/manual/src/expressions/language-values.md b/doc/manual/src/expressions/language-values.md
index abbe1fd35..f09400d02 100644
--- a/doc/manual/src/expressions/language-values.md
+++ b/doc/manual/src/expressions/language-values.md
@@ -1,156 +1,164 @@
-# Values
+# Data Types
-## Simple Values
+## Primitives
-Nix has the following basic data types:
+- String
- - *Strings* can be written in three ways.
-
- The most common way is to enclose the string between double quotes,
- e.g., `"foo bar"`. Strings can span multiple lines. The special
- characters `"` and `\` and the character sequence `${` must be
- escaped by prefixing them with a backslash (`\`). Newlines, carriage
- returns and tabs can be written as `\n`, `\r` and `\t`,
- respectively.
-
- You can include the result of an expression into a string by
- enclosing it in `${...}`, a feature known as *antiquotation*. The
- enclosed expression must evaluate to something that can be coerced
- into a string (meaning that it must be a string, a path, or a
- derivation). For instance, rather than writing
-
- ```nix
- "--with-freetype2-library=" + freetype + "/lib"
- ```
-
- (where `freetype` is a derivation), you can instead write the more
- natural
-
- ```nix
- "--with-freetype2-library=${freetype}/lib"
- ```
-
- The latter is automatically translated to the former. A more
- complicated example (from the Nix expression for
- [Qt](http://www.trolltech.com/products/qt)):
-
- ```nix
- configureFlags = "
- -system-zlib -system-libpng -system-libjpeg
- ${if openglSupport then "-dlopen-opengl
- -L${mesa}/lib -I${mesa}/include
- -L${libXmu}/lib -I${libXmu}/include" else ""}
- ${if threadSupport then "-thread" else "-no-thread"}
- ";
- ```
-
- Note that Nix expressions and strings can be arbitrarily nested; in
- this case the outer string contains various antiquotations that
- themselves contain strings (e.g., `"-thread"`), some of which in
- turn contain expressions (e.g., `${mesa}`).
-
- The second way to write string literals is as an *indented string*,
- which is enclosed between pairs of *double single-quotes*, like so:
-
- ```nix
- ''
- This is the first line.
- This is the second line.
- This is the third line.
- ''
- ```
-
- This kind of string literal intelligently strips indentation from
- the start of each line. To be precise, it strips from each line a
- number of spaces equal to the minimal indentation of the string as a
- whole (disregarding the indentation of empty lines). For instance,
- the first and second line are indented two spaces, while the third
- line is indented four spaces. Thus, two spaces are stripped from
- each line, so the resulting string is
-
- ```nix
- "This is the first line.\nThis is the second line.\n This is the third line.\n"
- ```
-
- Note that the whitespace and newline following the opening `''` is
- ignored if there is no non-whitespace text on the initial line.
-
- Antiquotation (`${expr}`) is supported in indented strings.
-
- Since `${` and `''` have special meaning in indented strings, you
- need a way to quote them. `$` can be escaped by prefixing it with
- `''` (that is, two single quotes), i.e., `''$`. `''` can be escaped
- by prefixing it with `'`, i.e., `'''`. `$` removes any special
- meaning from the following `$`. Linefeed, carriage-return and tab
- characters can be written as `''\n`, `''\r`, `''\t`, and `''\`
- escapes any other character.
-
- Indented strings are primarily useful in that they allow multi-line
- string literals to follow the indentation of the enclosing Nix
- expression, and that less escaping is typically necessary for
- strings representing languages such as shell scripts and
- configuration files because `''` is much less common than `"`.
- Example:
-
- ```nix
- stdenv.mkDerivation {
- ...
- postInstall =
- ''
- mkdir $out/bin $out/etc
- cp foo $out/bin
- echo "Hello World" > $out/etc/foo.conf
- ${if enableBar then "cp bar $out/bin" else ""}
- '';
- ...
- }
- ```
-
- Finally, as a convenience, *URIs* as defined in appendix B of
- [RFC 2396](http://www.ietf.org/rfc/rfc2396.txt) can be written *as
- is*, without quotes. For instance, the string
- `"http://example.org/foo.tar.bz2"` can also be written as
- `http://example.org/foo.tar.bz2`.
+ *Strings* can be written in three ways.
- - Numbers, which can be *integers* (like `123`) or *floating point*
- (like `123.43` or `.27e13`).
-
- Numbers are type-compatible: pure integer operations will always
- return integers, whereas any operation involving at least one
- floating point number will have a floating point number as a result.
+ The most common way is to enclose the string between double quotes,
+ e.g., `"foo bar"`. Strings can span multiple lines. The special
+ characters `"` and `\` and the character sequence `${` must be
+ escaped by prefixing them with a backslash (`\`). Newlines, carriage
+ returns and tabs can be written as `\n`, `\r` and `\t`,
+ respectively.
- - *Paths*, e.g., `/bin/sh` or `./builder.sh`. A path must contain at
- least one slash to be recognised as such. For instance, `builder.sh`
- is not a path: it's parsed as an expression that selects the
- attribute `sh` from the variable `builder`. If the file name is
- relative, i.e., if it does not begin with a slash, it is made
- absolute at parse time relative to the directory of the Nix
- expression that contained it. For instance, if a Nix expression in
- `/foo/bar/bla.nix` refers to `../xyzzy/fnord.nix`, the absolute path
- is `/foo/xyzzy/fnord.nix`.
-
- If the first component of a path is a `~`, it is interpreted as if
- the rest of the path were relative to the user's home directory.
- e.g. `~/foo` would be equivalent to `/home/edolstra/foo` for a user
- whose home directory is `/home/edolstra`.
-
- Paths can also be specified between angle brackets, e.g.
- ``. This means that the directories listed in the
- environment variable `NIX_PATH` will be searched for the given file
- or directory name.
+ You can include the result of an expression into a string by
+ enclosing it in `${...}`, a feature known as *antiquotation*. The
+ enclosed expression must evaluate to something that can be coerced
+ into a string (meaning that it must be a string, a path, or a
+ derivation). For instance, rather than writing
- Antiquotation is supported in any paths except those in angle brackets.
- `./${foo}-${bar}.nix` is a more convenient way of writing
- `./. + "/" + foo + "-" + bar + ".nix"` or `./. + "/${foo}-${bar}.nix"`. At
- least one slash must appear *before* any antiquotations for this to be
- recognized as a path. `a.${foo}/b.${bar}` is a syntactically valid division
- operation. `./a.${foo}/b.${bar}` is a path.
+ ```nix
+ "--with-freetype2-library=" + freetype + "/lib"
+ ```
- - *Booleans* with values `true` and `false`.
+ (where `freetype` is a derivation), you can instead write the more
+ natural
- - The null value, denoted as `null`.
+ ```nix
+ "--with-freetype2-library=${freetype}/lib"
+ ```
-## Lists
+ The latter is automatically translated to the former. A more
+ complicated example (from the Nix expression for
+ [Qt](http://www.trolltech.com/products/qt)):
+
+ ```nix
+ configureFlags = "
+ -system-zlib -system-libpng -system-libjpeg
+ ${if openglSupport then "-dlopen-opengl
+ -L${mesa}/lib -I${mesa}/include
+ -L${libXmu}/lib -I${libXmu}/include" else ""}
+ ${if threadSupport then "-thread" else "-no-thread"}
+ ";
+ ```
+
+ Note that Nix expressions and strings can be arbitrarily nested; in
+ this case the outer string contains various antiquotations that
+ themselves contain strings (e.g., `"-thread"`), some of which in
+ turn contain expressions (e.g., `${mesa}`).
+
+ The second way to write string literals is as an *indented string*,
+ which is enclosed between pairs of *double single-quotes*, like so:
+
+ ```nix
+ ''
+ This is the first line.
+ This is the second line.
+ This is the third line.
+ ''
+ ```
+
+ This kind of string literal intelligently strips indentation from
+ the start of each line. To be precise, it strips from each line a
+ number of spaces equal to the minimal indentation of the string as a
+ whole (disregarding the indentation of empty lines). For instance,
+ the first and second line are indented two spaces, while the third
+ line is indented four spaces. Thus, two spaces are stripped from
+ each line, so the resulting string is
+
+ ```nix
+ "This is the first line.\nThis is the second line.\n This is the third line.\n"
+ ```
+
+ Note that the whitespace and newline following the opening `''` is
+ ignored if there is no non-whitespace text on the initial line.
+
+ Antiquotation (`${expr}`) is supported in indented strings.
+
+ Since `${` and `''` have special meaning in indented strings, you
+ need a way to quote them. `$` can be escaped by prefixing it with
+ `''` (that is, two single quotes), i.e., `''$`. `''` can be escaped
+ by prefixing it with `'`, i.e., `'''`. `$` removes any special
+ meaning from the following `$`. Linefeed, carriage-return and tab
+ characters can be written as `''\n`, `''\r`, `''\t`, and `''\`
+ escapes any other character.
+
+ Indented strings are primarily useful in that they allow multi-line
+ string literals to follow the indentation of the enclosing Nix
+ expression, and that less escaping is typically necessary for
+ strings representing languages such as shell scripts and
+ configuration files because `''` is much less common than `"`.
+ Example:
+
+ ```nix
+ stdenv.mkDerivation {
+ ...
+ postInstall =
+ ''
+ mkdir $out/bin $out/etc
+ cp foo $out/bin
+ echo "Hello World" > $out/etc/foo.conf
+ ${if enableBar then "cp bar $out/bin" else ""}
+ '';
+ ...
+ }
+ ```
+
+ Finally, as a convenience, *URIs* as defined in appendix B of
+ [RFC 2396](http://www.ietf.org/rfc/rfc2396.txt) can be written *as
+ is*, without quotes. For instance, the string
+ `"http://example.org/foo.tar.bz2"` can also be written as
+ `http://example.org/foo.tar.bz2`.
+
+- Number
+
+ Numbers, which can be *integers* (like `123`) or *floating point*
+ (like `123.43` or `.27e13`).
+
+ Numbers are type-compatible: pure integer operations will always
+ return integers, whereas any operation involving at least one
+ floating point number will have a floating point number as a result.
+
+- Path
+
+ *Paths*, e.g., `/bin/sh` or `./builder.sh`. A path must contain at
+ least one slash to be recognised as such. For instance, `builder.sh`
+ is not a path: it's parsed as an expression that selects the
+ attribute `sh` from the variable `builder`. If the file name is
+ relative, i.e., if it does not begin with a slash, it is made
+ absolute at parse time relative to the directory of the Nix
+ expression that contained it. For instance, if a Nix expression in
+ `/foo/bar/bla.nix` refers to `../xyzzy/fnord.nix`, the absolute path
+ is `/foo/xyzzy/fnord.nix`.
+
+ If the first component of a path is a `~`, it is interpreted as if
+ the rest of the path were relative to the user's home directory.
+ e.g. `~/foo` would be equivalent to `/home/edolstra/foo` for a user
+ whose home directory is `/home/edolstra`.
+
+ Paths can also be specified between angle brackets, e.g.
+ ``. This means that the directories listed in the
+ environment variable `NIX_PATH` will be searched for the given file
+ or directory name.
+
+ Antiquotation is supported in any paths except those in angle brackets.
+ `./${foo}-${bar}.nix` is a more convenient way of writing
+ `./. + "/" + foo + "-" + bar + ".nix"` or `./. + "/${foo}-${bar}.nix"`. At
+ least one slash must appear *before* any antiquotations for this to be
+ recognized as a path. `a.${foo}/b.${bar}` is a syntactically valid division
+ operation. `./a.${foo}/b.${bar}` is a path.
+
+- Boolean
+
+ *Booleans* with values `true` and `false`.
+
+- Null
+
+ The null value, denoted as `null`.
+
+## List
Lists are formed by enclosing a whitespace-separated list of values
between square brackets. For example,
@@ -172,9 +180,9 @@ function and the fifth being a set.
Note that lists are only lazy in values, and they are strict in length.
-## Attribute Sets
+## Attribute Set
-Attribute sets are collections of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`).
+An attribute set is a collection of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`).
Names and values are separated by an equal sign (`=`).
Each value is an arbitrary expression terminated by a semicolon (`;`).
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index f485e2fed..e3716f217 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -2501,18 +2501,18 @@ void EvalState::printStats()
}
{
auto list = topObj.list("functions");
- for (auto & i : functionCalls) {
+ for (auto & [fun, count] : functionCalls) {
auto obj = list.object();
- if (i.first->name)
- obj.attr("name", (const std::string &) i.first->name);
+ if (fun->name)
+ obj.attr("name", (std::string_view) symbols[fun->name]);
else
obj.attr("name", nullptr);
- if (auto pos = positions[i.first->pos]) {
- obj.attr("file", (const std::string &) pos.file);
+ if (auto pos = positions[fun->pos]) {
+ obj.attr("file", (std::string_view) pos.file);
obj.attr("line", pos.line);
obj.attr("column", pos.column);
}
- obj.attr("count", i.second);
+ obj.attr("count", count);
}
}
{
diff --git a/src/libutil/json.cc b/src/libutil/json.cc
index b0a5d7e75..abe0e6e74 100644
--- a/src/libutil/json.cc
+++ b/src/libutil/json.cc
@@ -6,7 +6,8 @@
namespace nix {
-void toJSON(std::ostream & str, const char * start, const char * end)
+template<>
+void toJSON(std::ostream & str, const std::string_view & s)
{
constexpr size_t BUF_SIZE = 4096;
char buf[BUF_SIZE + 7]; // BUF_SIZE + largest single sequence of puts
@@ -21,7 +22,7 @@ void toJSON(std::ostream & str, const char * start, const char * end)
};
put('"');
- for (auto i = start; i != end; i++) {
+ for (auto i = s.begin(); i != s.end(); i++) {
if (bufPos >= BUF_SIZE) flush();
if (*i == '\"' || *i == '\\') { put('\\'); put(*i); }
else if (*i == '\n') { put('\\'); put('n'); }
@@ -44,7 +45,7 @@ void toJSON(std::ostream & str, const char * start, const char * end)
void toJSON(std::ostream & str, const char * s)
{
- if (!s) str << "null"; else toJSON(str, s, s + strlen(s));
+ if (!s) str << "null"; else toJSON(str, std::string_view(s));
}
template<> void toJSON(std::ostream & str, const int & n) { str << n; }
@@ -55,11 +56,7 @@ template<> void toJSON(std::ostream & str, const long long & n) { str
template<> void toJSON(std::ostream & str, const unsigned long long & n) { str << n; }
template<> void toJSON(std::ostream & str, const float & n) { str << n; }
template<> void toJSON(std::ostream & str, const double & n) { str << n; }
-
-template<> void toJSON(std::ostream & str, const std::string & s)
-{
- toJSON(str, s.c_str(), s.c_str() + s.size());
-}
+template<> void toJSON(std::ostream & str, const std::string & s) { toJSON(str, (std::string_view) s); }
template<> void toJSON(std::ostream & str, const bool & b)
{
@@ -154,7 +151,7 @@ JSONObject::~JSONObject()
}
}
-void JSONObject::attr(const std::string & s)
+void JSONObject::attr(std::string_view s)
{
comma();
toJSON(state->str, s);
@@ -162,19 +159,19 @@ void JSONObject::attr(const std::string & s)
if (state->indent) state->str << ' ';
}
-JSONList JSONObject::list(const std::string & name)
+JSONList JSONObject::list(std::string_view name)
{
attr(name);
return JSONList(state);
}
-JSONObject JSONObject::object(const std::string & name)
+JSONObject JSONObject::object(std::string_view name)
{
attr(name);
return JSONObject(state);
}
-JSONPlaceholder JSONObject::placeholder(const std::string & name)
+JSONPlaceholder JSONObject::placeholder(std::string_view name)
{
attr(name);
return JSONPlaceholder(state);
diff --git a/src/libutil/json.hh b/src/libutil/json.hh
index 83213ca66..3790b1a2e 100644
--- a/src/libutil/json.hh
+++ b/src/libutil/json.hh
@@ -6,7 +6,6 @@
namespace nix {
-void toJSON(std::ostream & str, const char * start, const char * end);
void toJSON(std::ostream & str, const char * s);
template
@@ -107,7 +106,7 @@ private:
open();
}
- void attr(const std::string & s);
+ void attr(std::string_view s);
public:
@@ -128,18 +127,18 @@ public:
~JSONObject();
template
- JSONObject & attr(const std::string & name, const T & v)
+ JSONObject & attr(std::string_view name, const T & v)
{
attr(name);
toJSON(state->str, v);
return *this;
}
- JSONList list(const std::string & name);
+ JSONList list(std::string_view name);
- JSONObject object(const std::string & name);
+ JSONObject object(std::string_view name);
- JSONPlaceholder placeholder(const std::string & name);
+ JSONPlaceholder placeholder(std::string_view name);
};
class JSONPlaceholder : JSONWriter
diff --git a/src/libutil/tests/json.cc b/src/libutil/tests/json.cc
index dea73f53a..156286999 100644
--- a/src/libutil/tests/json.cc
+++ b/src/libutil/tests/json.cc
@@ -102,8 +102,8 @@ namespace nix {
TEST(toJSON, substringEscape) {
std::stringstream out;
- const char *s = "foo\t";
- toJSON(out, s+3, s + strlen(s));
+ std::string_view s = "foo\t";
+ toJSON(out, s.substr(3));
ASSERT_EQ(out.str(), "\"\\t\"");
}