about summary refs log tree commit diff
path: root/src/libexpr/lexer.l
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2007-11-30T16·48+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2007-11-30T16·48+0000
commit6d6c68c0d29310b6eca35f58b1e68f495d6cd33a (patch)
treeeec6c3c138951f1f0cb3f9b4b1f3b3c177c31afb /src/libexpr/lexer.l
parent633518628f48fb9c06bfd570eeca6f62696aba05 (diff)
* 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.


Diffstat (limited to 'src/libexpr/lexer.l')
-rw-r--r--src/libexpr/lexer.l15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l
index 9f0f0b335f..23a14324f3 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; }
 <STRING>\"  { BEGIN(INITIAL); return '"'; }
 <STRING>.   return yytext[0]; /* just in case: shouldn't be reached */
 
+\'\'(\ *\n)?     { BEGIN(IND_STRING); return IND_STRING_OPEN; }
+<IND_STRING>([^\$\']|\$[^\{\']|\'[^\'])+ {
+                   yylval->t = makeIndStr(toATerm(yytext));
+                   return IND_STR;
+                 }
+<IND_STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
+<IND_STRING>\'\' { BEGIN(INITIAL); return IND_STRING_CLOSE; }
+<IND_STRING>.    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);
+}
+
 }