From 6d6c68c0d29310b6eca35f58b1e68f495d6cd33a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 30 Nov 2007 16:48:45 +0000 Subject: * Added a new kind of multi-line string literal delimited by two single quotes. Example (from NixOS): job = '' start on network-interfaces start script rm -f /var/run/opengl-driver ${if videoDriver == "nvidia" then "ln -sf ${nvidiaDrivers} /var/run/opengl-driver" else if cfg.driSupport then "ln -sf ${mesa} /var/run/opengl-driver" else "" } rm -f /var/log/slim.log end script ''; This style has two big advantages: - \, ' and " aren't special, only '' and ${. So you get a lot less escaping in shell scripts / configuration files in Nixpkgs/NixOS. The delimiter '' is rare in scripts (and can usually be written as ""). ${ is also fairly rare. Other delimiters such as <<...>>, {{...}} and <|...|> were also considered but this one appears to have the fewest drawbacks (thanks Martin). - Indentation is intelligently stripped so that multi-line strings can follow the nesting structure of the containing Nix expression. E.g. in the example above 6 spaces are stripped from the start of each line. This prevents unnecessary indentation in generated files (which sometimes even breaks things). See tests/lang/eval-okay-ind-string.nix for some examples. --- src/libexpr/lexer.l | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/libexpr/lexer.l') diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index 9f0f0b335f57..23a14324f32c 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -4,6 +4,7 @@ %x STRING +%x IND_STRING %{ @@ -122,6 +123,14 @@ inherit { return INHERIT; } \" { BEGIN(INITIAL); return '"'; } . return yytext[0]; /* just in case: shouldn't be reached */ +\'\'(\ *\n)? { BEGIN(IND_STRING); return IND_STRING_OPEN; } +([^\$\']|\$[^\{\']|\'[^\'])+ { + yylval->t = makeIndStr(toATerm(yytext)); + return IND_STR; + } +\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; } +\'\' { BEGIN(INITIAL); return IND_STRING_CLOSE; } +. return yytext[0]; /* just in case: shouldn't be reached */ {PATH} { yylval->t = toATerm(yytext); return PATH; /* !!! alloc */ } {URI} { yylval->t = toATerm(yytext); return URI; /* !!! alloc */ } @@ -148,4 +157,10 @@ void backToString(yyscan_t scanner) BEGIN(STRING); } +void backToIndString(yyscan_t scanner) +{ + struct yyguts_t * yyg = (struct yyguts_t *) scanner; + BEGIN(IND_STRING); +} + } -- cgit 1.4.1