aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/print.cc
diff options
context:
space:
mode:
authorRobert Hensing <roberth@users.noreply.github.com>2023-04-17 11:19:40 +0200
committerGitHub <noreply@github.com>2023-04-17 11:19:40 +0200
commit9af9c260fc0aff9e20a1c2e965249a20394ca22a (patch)
tree354d2c88676aa29f3a5fd18d4479e97655391c02 /src/libexpr/print.cc
parent36a473c5e80957fc0f2fd398cb75053f635e4524 (diff)
parentb6125772d7d5f82d48873fc93a7f261832154b14 (diff)
Merge pull request #8193 from hercules-ci/dry-strings
Deduplicate string literal rendering, fix 4909
Diffstat (limited to 'src/libexpr/print.cc')
-rw-r--r--src/libexpr/print.cc78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/libexpr/print.cc b/src/libexpr/print.cc
new file mode 100644
index 000000000..d08672cfc
--- /dev/null
+++ b/src/libexpr/print.cc
@@ -0,0 +1,78 @@
+#include "print.hh"
+
+namespace nix {
+
+std::ostream &
+printLiteralString(std::ostream & str, const std::string_view string)
+{
+ str << "\"";
+ for (auto i = string.begin(); i != string.end(); ++i) {
+ if (*i == '\"' || *i == '\\') str << "\\" << *i;
+ else if (*i == '\n') str << "\\n";
+ else if (*i == '\r') str << "\\r";
+ else if (*i == '\t') str << "\\t";
+ else if (*i == '$' && *(i+1) == '{') str << "\\" << *i;
+ else str << *i;
+ }
+ str << "\"";
+ return str;
+}
+
+std::ostream &
+printLiteralBool(std::ostream & str, bool boolean)
+{
+ str << (boolean ? "true" : "false");
+ return str;
+}
+
+std::ostream &
+printIdentifier(std::ostream & str, std::string_view s) {
+ if (s.empty())
+ str << "\"\"";
+ else if (s == "if") // FIXME: handle other keywords
+ str << '"' << s << '"';
+ else {
+ char c = s[0];
+ if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) {
+ printLiteralString(str, s);
+ return str;
+ }
+ for (auto c : s)
+ if (!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c == '_' || c == '\'' || c == '-')) {
+ printLiteralString(str, s);
+ return str;
+ }
+ str << s;
+ }
+ return str;
+}
+
+// FIXME: keywords
+static bool isVarName(std::string_view s)
+{
+ if (s.size() == 0) return false;
+ char c = s[0];
+ if ((c >= '0' && c <= '9') || c == '-' || c == '\'') return false;
+ for (auto & i : s)
+ if (!((i >= 'a' && i <= 'z') ||
+ (i >= 'A' && i <= 'Z') ||
+ (i >= '0' && i <= '9') ||
+ i == '_' || i == '-' || i == '\''))
+ return false;
+ return true;
+}
+
+std::ostream &
+printAttributeName(std::ostream & str, std::string_view name) {
+ if (isVarName(name))
+ str << name;
+ else
+ printLiteralString(str, name);
+ return str;
+}
+
+
+}