lib/generators.toPretty: escape strings properly

This commit is contained in:
Naïm Favier 2022-11-07 13:01:13 +01:00 committed by pennae
parent 0fa7b1b004
commit 0b661ce32a
2 changed files with 21 additions and 19 deletions

View File

@ -297,17 +297,19 @@ rec {
else if isFloat v then "~${toString v}" else if isFloat v then "~${toString v}"
else if isString v then else if isString v then
let let
# Separate a string into its lines lines = filter (v: ! isList v) (builtins.split "\n" v);
newlineSplits = filter (v: ! isList v) (builtins.split "\n" v); escapeSingleline = libStr.escape [ "\\" "\"" "\${" ];
# For a '' string terminated by a \n, which happens when the closing '' is on a new line escapeMultiline = libStr.replaceStrings [ "\${" "''" ] [ "''\${" "'''" ];
multilineResult = "''" + introSpace + concatStringsSep introSpace (lib.init newlineSplits) + outroSpace + "''"; singlelineResult = "\"" + concatStringsSep "\\n" (map escapeSingleline lines) + "\"";
# For a '' string not terminated by a \n, which happens when the closing '' is not on a new line multilineResult = let
multilineResult' = "''" + introSpace + concatStringsSep introSpace newlineSplits + "''"; escapedLines = map escapeMultiline lines;
# For single lines, replace all newlines with their escaped representation # The last line gets a special treatment: if it's empty, '' is on its own line at the "outer"
singlelineResult = "\"" + libStr.escape [ "\"" ] (concatStringsSep "\\n" newlineSplits) + "\""; # indentation level. Otherwise, '' is appended to the last line.
in if multiline && length newlineSplits > 1 then lastLine = lib.last escapedLines;
if lib.last newlineSplits == "" then multilineResult else multilineResult' in "''" + introSpace + concatStringsSep introSpace (lib.init escapedLines)
else singlelineResult + (if lastLine == "" then outroSpace else introSpace + lastLine) + "''";
in
if multiline && length lines > 1 then multilineResult else singlelineResult
else if true == v then "true" else if true == v then "true"
else if false == v then "false" else if false == v then "false"
else if null == v then "null" else if null == v then "null"

View File

@ -727,7 +727,7 @@ runTests {
float = 0.1337; float = 0.1337;
bool = true; bool = true;
emptystring = ""; emptystring = "";
string = ''fno"rd''; string = "fn\${o}\"r\\d";
newlinestring = "\n"; newlinestring = "\n";
path = /. + "/foo"; path = /. + "/foo";
null_ = null; null_ = null;
@ -735,7 +735,7 @@ runTests {
functionArgs = { arg ? 4, foo }: arg; functionArgs = { arg ? 4, foo }: arg;
list = [ 3 4 function [ false ] ]; list = [ 3 4 function [ false ] ];
emptylist = []; emptylist = [];
attrs = { foo = null; "foo bar" = "baz"; }; attrs = { foo = null; "foo b/ar" = "baz"; };
emptyattrs = {}; emptyattrs = {};
drv = deriv; drv = deriv;
}; };
@ -744,7 +744,7 @@ runTests {
float = "~0.133700"; float = "~0.133700";
bool = "true"; bool = "true";
emptystring = ''""''; emptystring = ''""'';
string = ''"fno\"rd"''; string = ''"fn\''${o}\"r\\d"'';
newlinestring = "\"\\n\""; newlinestring = "\"\\n\"";
path = "/foo"; path = "/foo";
null_ = "null"; null_ = "null";
@ -752,7 +752,7 @@ runTests {
functionArgs = "<function, args: {arg?, foo}>"; functionArgs = "<function, args: {arg?, foo}>";
list = "[ 3 4 ${function} [ false ] ]"; list = "[ 3 4 ${function} [ false ] ]";
emptylist = "[ ]"; emptylist = "[ ]";
attrs = "{ foo = null; \"foo bar\" = \"baz\"; }"; attrs = "{ foo = null; \"foo b/ar\" = \"baz\"; }";
emptyattrs = "{ }"; emptyattrs = "{ }";
drv = "<derivation ${deriv.name}>"; drv = "<derivation ${deriv.name}>";
}; };
@ -799,8 +799,8 @@ runTests {
newlinestring = "\n"; newlinestring = "\n";
multilinestring = '' multilinestring = ''
hello hello
there ''${there}
test te'''st
''; '';
multilinestring' = '' multilinestring' = ''
hello hello
@ -827,8 +827,8 @@ runTests {
multilinestring = '' multilinestring = ''
''' '''
hello hello
there '''''${there}
test te''''st
'''''; ''''';
multilinestring' = '' multilinestring' = ''
''' '''