chiark / gitweb /
Allow trailing '@' to be left out of CGI expansions in specific
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 27 Apr 2008 19:43:35 +0000 (20:43 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 27 Apr 2008 19:43:35 +0000 (20:43 +0100)
circumstances.  This is such a common typo it seems better to accept
the result of user testing than cling to the original syntax.

doc/disorder_config.5.in
server/cgi.c

index e714a22549b0b5b76f700150cb9a76756f791bac..c9b20618a381435dce735b0c309b0e836024fcf7 100644 (file)
@@ -907,14 +907,20 @@ character reference, e.g. \fB&#253;\fR.
 Use \fB&#64;\fR to insert a literal \fB@\fR without falling foul of
 the expansion syntax.
 .SS "Expansion Syntax"
-Expansions are surrounded by at ("@") symbols take the form of a keyword
-followed by zero or more arguments.
-Arguments may either be quoted by curly brackets ("{" and "}") or separated
+An expansion starts with an at ("@") symbol and takes the form of an expansion
+name followed by zero or more arguments.
+.PP
+Arguments can be quoted by curly brackets ("{" and "}") or separated
 by colons (":").
 Both kinds may be mixed in a single expansion, though doing so seems
 likely to cause confusion.
 The descriptions below contain suggested forms for each expansion.
 .PP
+An expansion is terminated by another "@" symbol, but this is optional in the
+specific case that the last argument is quoted by curly brackets and it is
+followed by whitespace and then some character that is not "{" (since that
+could be interpreted as a further argument).
+.PP
 Leading and trailing whitespace in unquoted arguments is ignored, as is
 whitespace (including newlines) following a close bracket ("}").
 .PP
index 2017d1b5fdf4f31b48f1d00d440dc5da1aa5e93a..23d102055a7ec0c75fca6c3a1fd5aebbaf2e9d20 100644 (file)
@@ -389,6 +389,9 @@ void cgi_expand_string(const char *name,
     ++template;
     sline = line;
     while(*template != '@') {
+      /* Skip whitespace */
+      while(isspace((unsigned char)*template))
+       ++template;
       dynstr_init(&d);
       if(*template == '{') {
        /* bracketed arg */
@@ -403,14 +406,18 @@ void cgi_expand_string(const char *name,
        }
        if(!*template) fatal(0, "%s:%d: unterminated expansion", name, sline);
        ++template;
-       /* skip whitespace after closing bracket */
-       while(isspace((unsigned char)*template))
-         ++template;
+       if(isspace((unsigned char)*template)) {
+         /* We have @{...}<WHITESPACE><SOMETHING> */
+         for(p = template; isspace((unsigned char)*p); ++p)
+           ;
+         /* Now we are looking at <SOMETHING>.  If it's "{" then that
+          * must be the next argument.  Otherwise we infer that this
+          * is really the end of the expansion. */
+         if(*p != '{')
+           goto finished_expansion;
+       }
       } else {
        /* unbracketed arg */
-       /* leading whitespace is not significant in unquoted args */
-       while(isspace((unsigned char)*template))
-         ++template;
        while(*template
              && *template != '@' && *template != '{' && *template != ':') {
          if(*template == '\n') ++line;
@@ -427,6 +434,7 @@ void cgi_expand_string(const char *name,
       vector_append(&v, d.vec);
     }
     ++template;
+finished_expansion:
     vector_terminate(&v);
     /* @@ terminates this file */
     if(v.nvec == 0)