]> git.ipfire.org Git - pakfire.git/commitdiff
parser: Handle lines continued with backslash
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 1 Mar 2021 12:23:39 +0000 (12:23 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 1 Mar 2021 12:23:39 +0000 (12:23 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/parser/scanner.l
tests/data/parser/test-declarations.txt

index 73fc2ca429f13b20039b8c7075a3cfa320aeac33..4f964d39fb6f54759fcc7be32871c713d6f5f285 100644 (file)
@@ -73,6 +73,56 @@ COPY:
 
 #define unput_string(s) for (int i = strlen(s) - 1; i >= 0; i--) unput(s[i])
 
+static char* copy_string(const char* s) {
+       if (!s)
+               return NULL;
+
+       // Remove any leading whitespace
+       while (*s && isspace(*s))
+               s++;
+
+       // Remove any trailing whitespace
+       const char* e = s + strlen(s);
+       while (*e && isspace(*s))
+               e--;
+
+       // Determine the length of the string
+       const size_t l = strlen(s);
+
+       // Allocate a working buffer
+       char* buffer = malloc(l + 1);
+
+       // Copy input string to buffer
+       memcpy(buffer, s, l + 1);
+
+       // Pointer to the start of the string
+       char* p = buffer;
+
+       char* linebreak = strstr(p, "\\\n");
+       while (linebreak) {
+               // Move p to the beginning of the linebreak
+               p = linebreak;
+
+               // Skip \\\n
+               linebreak += strlen("\\\n");
+
+               // Find any whitespace after the linebreak
+               while (*linebreak && isspace(*linebreak))
+                       linebreak++;
+
+               if (!linebreak)
+                       break;
+
+               // Splice together
+               memmove(p, linebreak, buffer + l - linebreak + 1);
+
+               // Find another linebreak
+               linebreak = strstr(p, "\\\n");
+       }
+
+       return buffer;
+}
+
 %}
 
 %x INDENT
@@ -206,12 +256,17 @@ scriptlet                         script(let)?
                                                        yy_push_state(NOKEYWORD);
                                                }
 
+<READLINE>.*\\\n               {
+                                                       // Continue if a line ends with a "\"
+                                                       yymore();
+                                               }
+
 <READLINE>.*$                  {
                                                        // Return to caller
                                                        yy_pop_state();
 
                                                        // Copy the entire string
-                                                       yylval.string = pakfire_lstrip(yytext);
+                                                       yylval.string = copy_string(yytext);
 
                                                        return T_STRING;
                                                }
index 75b12dc6fa04c9409d81bb260b0e7db5ed4be519..115f7dbae11b1b2cc923e9cbf302287b34715974 100644 (file)
@@ -11,3 +11,8 @@ lines
        line 1
        line 2
 end
+
+# Continued line
+e = A \
+       B \
+       C