diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2023-05-09 11:42:44 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-09 11:42:44 -0400 |
commit | aacde38d2c8a0cf159794e5ec87ef63dccf59e35 (patch) | |
tree | 814470ccd866eabdb4f2734abc16e31b6219e193 /src | |
parent | 4539ab530ad23a8558512f784bd72c4cd0e72f13 (diff) | |
parent | 82d1d74a85bc3d06ff3b17e735deedd98eb47b66 (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.cc | 1 | ||||
-rw-r--r-- | src/libexpr/print.cc | 20 | ||||
-rw-r--r-- | src/libexpr/print.hh | 6 |
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 |