aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-05-09 11:42:44 -0400
committerGitHub <noreply@github.com>2023-05-09 11:42:44 -0400
commitaacde38d2c8a0cf159794e5ec87ef63dccf59e35 (patch)
tree814470ccd866eabdb4f2734abc16e31b6219e193 /src
parent4539ab530ad23a8558512f784bd72c4cd0e72f13 (diff)
parent82d1d74a85bc3d06ff3b17e735deedd98eb47b66 (diff)
Merge pull request #8110 from aakropotkin/quote-reserved
Quote reserved keywords when printing expressions
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc1
-rw-r--r--src/libexpr/print.cc20
-rw-r--r--src/libexpr/print.hh6
3 files changed, 24 insertions, 3 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index e2b455b91..0b4243670 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -94,7 +94,6 @@ RootValue allocRootValue(Value * v)
#endif
}
-
void Value::print(const SymbolTable & symbols, std::ostream & str,
std::set<const void *> * seen) const
{
diff --git a/src/libexpr/print.cc b/src/libexpr/print.cc
index d08672cfc..53ba70bdd 100644
--- a/src/libexpr/print.cc
+++ b/src/libexpr/print.cc
@@ -1,4 +1,5 @@
#include "print.hh"
+#include <unordered_set>
namespace nix {
@@ -25,11 +26,26 @@ printLiteralBool(std::ostream & str, bool boolean)
return str;
}
+// Returns `true' is a string is a reserved keyword which requires quotation
+// when printing attribute set field names.
+//
+// This list should generally be kept in sync with `./lexer.l'.
+// You can test if a keyword needs to be added by running:
+// $ nix eval --expr '{ <KEYWORD> = 1; }'
+// For example `or' doesn't need to be quoted.
+bool isReservedKeyword(const std::string_view str)
+{
+ static const std::unordered_set<std::string_view> reservedKeywords = {
+ "if", "then", "else", "assert", "with", "let", "in", "rec", "inherit"
+ };
+ return reservedKeywords.contains(str);
+}
+
std::ostream &
printIdentifier(std::ostream & str, std::string_view s) {
if (s.empty())
str << "\"\"";
- else if (s == "if") // FIXME: handle other keywords
+ else if (isReservedKeyword(s))
str << '"' << s << '"';
else {
char c = s[0];
@@ -50,10 +66,10 @@ printIdentifier(std::ostream & str, std::string_view s) {
return str;
}
-// FIXME: keywords
static bool isVarName(std::string_view s)
{
if (s.size() == 0) return false;
+ if (isReservedKeyword(s)) return false;
char c = s[0];
if ((c >= '0' && c <= '9') || c == '-' || c == '\'') return false;
for (auto & i : s)
diff --git a/src/libexpr/print.hh b/src/libexpr/print.hh
index f9cfc3964..3b72ae201 100644
--- a/src/libexpr/print.hh
+++ b/src/libexpr/print.hh
@@ -36,6 +36,12 @@ namespace nix {
std::ostream & printAttributeName(std::ostream & o, std::string_view s);
/**
+ * Returns `true' is a string is a reserved keyword which requires quotation
+ * when printing attribute set field names.
+ */
+ bool isReservedKeyword(const std::string_view str);
+
+ /**
* Print a string as an identifier in the Nix expression language syntax.
*
* FIXME: "identifier" is ambiguous. Identifiers do not have a single