From 56322d3b2ef2502ec52bf3633c6e808b2299b805 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sat, 12 Jul 2008 11:33:27 +0200 Subject: [PATCH] liboconfig/scanner.l: Added support for wrapping lines. Lines may now be wrapped by using "\" as the last character before the newline. This allows long lines to be split into multiple lines. This also applies to quoted strings, which are, however, treated special in that whitespace at the beginning of the following lines will be ignored. This allows for nicely indenting the wrapped lines. The following example: Foo a very very very long list of options \ that does not fit on one line Bar "a very very very long string \ which does not fit on one line" ... is equivalent to: Foo a very very very long list of options that does not fit on one line Bar "a very very very long string which does not fit on one line" Signed-off-by: Sebastian Harl Signed-off-by: Florian Forster --- src/liboconfig/scanner.l | 69 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/src/liboconfig/scanner.l b/src/liboconfig/scanner.l index 4d9fc3de..0f146ca4 100644 --- a/src/liboconfig/scanner.l +++ b/src/liboconfig/scanner.l @@ -1,6 +1,7 @@ /** * oconfig - src/scanner.l * Copyright (C) 2007 Florian octo Forster + * Copyright (C) 2008 Sebastian tokkee Harl * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -21,11 +22,29 @@ #include "oconfig.h" #include "aux_types.h" #include "parser.h" + +/* multiline string buffer */ +static char *ml_buffer = NULL; +static int ml_pos = 0; +static int ml_len = 0; + +#define ml_free (ml_len - ml_pos) + +static void ml_append (char *); + +#ifdef yyterminate +# undef yyterminate +#endif +#define yyterminate() \ + do { free (ml_buffer); ml_buffer = NULL; ml_pos = 0; ml_len = 0; \ + return YY_NULL; } while (0) %} %option yylineno %option noyywrap +%x ML WHITE_SPACE [\ \t\b] -QUOTED_STRING \"([^\\"]+|\\.)*\" +NON_WHITE_SPACE [^\ \t\b] +QUOTED_STRING ([^\\"]+|\\.)* UNQUOTED_STRING [0-9A-Za-z_]+ HEX_NUMBER 0[xX][0-9a-fA-F]+ OCT_NUMBER 0[0-7]+ @@ -43,6 +62,8 @@ IPV4_ADDR {IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}(:{PORT})? {WHITE_SPACE} | {COMMENT} {/* ignore */} +\\\n {/* continue line */} + \n {return (EOL);} "/" {return (SLASH);} "<" {return (OPENBRAC);} @@ -54,6 +75,50 @@ IPV4_ADDR {IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}(:{PORT})? {NUMBER} {yylval.number = strtod (yytext, NULL); return (NUMBER);} -{QUOTED_STRING} {yylval.string = yytext; return (QUOTED_STRING);} +\"{QUOTED_STRING}\" {yylval.string = yytext; return (QUOTED_STRING);} {UNQUOTED_STRING} {yylval.string = yytext; return (UNQUOTED_STRING);} + +\"{QUOTED_STRING}\\\n { + ml_pos = 0; + + /* remove "\\\n" */ + yytext[strlen (yytext) - 2] = '\0'; + + ml_append (yytext); + BEGIN (ML); +} +^{WHITE_SPACE}+ {/* remove leading white-space */} +{NON_WHITE_SPACE}{QUOTED_STRING}\\\n { + /* remove "\\\n" */ + yytext[strlen (yytext) - 2] = '\0'; + + ml_append(yytext); +} +{NON_WHITE_SPACE}{QUOTED_STRING}\" { + ml_append(yytext); + yylval.string = ml_buffer; + + BEGIN (INITIAL); + return (QUOTED_STRING); +} %% +static void ml_append (char *string) +{ + int len = strlen (string); + int s; + + if (ml_free <= len) { + ml_len += len - ml_free + 1; + ml_buffer = (char *)realloc (ml_buffer, ml_len); + if (NULL == ml_buffer) + YY_FATAL_ERROR ("out of dynamic memory in ml_append"); + } + + s = snprintf (ml_buffer + ml_pos, ml_free, "%s", string); + if ((0 > s) || (ml_free <= s)) + YY_FATAL_ERROR ("failed to write to multiline buffer"); + + ml_pos += s; + return; +} /* ml_append */ + -- 2.11.0