X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fliboconfig%2Fscanner.l;h=9f0cd8e3cc51da8838661ab62904b20975017337;hb=07be522384e753b7921213a0dc96a50336c79a66;hp=aa111a2933b7fef756ec40dd96707e9d62d7471c;hpb=6360474f4aa35dd1a587b6148ff88a23e6155132;p=collectd.git diff --git a/src/liboconfig/scanner.l b/src/liboconfig/scanner.l index aa111a29..9f0cd8e3 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,9 +22,30 @@ #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] +EOL (\r\n|\n) +QUOTED_STRING ([^\\"]+|\\.)* UNQUOTED_STRING [0-9A-Za-z_]+ HEX_NUMBER 0[xX][0-9a-fA-F]+ OCT_NUMBER 0[0-7]+ @@ -41,17 +63,75 @@ IPV4_ADDR {IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}(:{PORT})? {WHITE_SPACE} | {COMMENT} {/* ignore */} -\n {return (EOL);} +\\{EOL} {/* continue line */} + +{EOL} {return (EOL);} "/" {return (SLASH);} "<" {return (OPENBRAC);} ">" {return (CLOSEBRAC);} -{BOOL_TRUE} {yylval.boolean = 1; return (TRUE);} -{BOOL_FALSE} {yylval.boolean = 0; return (FALSE);} +{BOOL_TRUE} {yylval.boolean = 1; return (BTRUE);} +{BOOL_FALSE} {yylval.boolean = 0; return (BFALSE);} {IPV4_ADDR} {yylval.string = yytext; return (UNQUOTED_STRING);} {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}\\{EOL} { + int len = strlen (yytext); + + ml_pos = 0; + + /* remove "\\" */ + if ('\r' == yytext[len - 2]) + len -= 3; + else + len -= 2; + yytext[len] = '\0'; + + ml_append (yytext); + BEGIN (ML); +} +^{WHITE_SPACE}+ {/* remove leading white-space */} +{NON_WHITE_SPACE}{QUOTED_STRING}\\{EOL} { + int len = strlen (yytext); + + /* remove "\\" */ + if ('\r' == yytext[len - 2]) + len -= 3; + else + len -= 2; + yytext[len] = '\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 */ +