3 * Copyright (C) 2013-2014 Tobias Brunner
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include <utils/parser_helper.h>
18 #include <parser/conf_parser.h>
22 bool conf_parser_open_next_file(parser_helper_t *ctx);
24 static void include_files(parser_helper_t *ctx);
30 /* use start conditions stack */
33 /* do not declare unneded functions */
34 %option noinput noyywrap
36 /* don't use global variables, and interact properly with bison */
37 %option reentrant bison-bridge
39 /* maintain the line number */
42 /* don't generate a default rule */
45 /* prefix function/variable declarations */
46 %option prefix="conf_parser_"
47 /* don't change the name of the output file otherwise autotools has issues */
48 %option outfile="lex.yy.c"
50 /* type of our extra data */
51 %option extra-type="parser_helper_t*"
53 /* state used to scan include file patterns */
55 /* state used to scan quoted strings */
60 ^[\t ]*"version"[^\n]*$ /* eat legacy version delcaration */
61 ^[\t ]+ return SPACES;
62 [\t ]+ /* eat other whitespace */
63 [\t ]*#[^\n]* /* eat comments */
68 ^"config setup" return CONFIG_SETUP;
72 "include"[\t ]+/[^=] {
73 yyextra->string_init(yyextra);
74 yy_push_state(inc, yyscanner);
78 yyextra->string_init(yyextra);
79 yy_push_state(str, yyscanner);
83 yylval->s = strdup(yytext);
88 /* we allow all characters except # and spaces, they can be escaped */
96 /* put the newline back to fix the line numbers */
101 /* comments are parsed outside of this start condition */
106 include_files(yyextra);
107 yy_pop_state(yyscanner);
109 "\"" { /* string include */
110 yy_push_state(str, yyscanner);
113 yyextra->string_add(yyextra, yytext);
116 yyextra->string_add(yyextra, yytext+1);
119 yyextra->string_add(yyextra, yytext);
128 if (!streq(yytext, "\""))
130 if (streq(yytext, "\n"))
131 { /* put the newline back to fix the line numbers */
135 PARSER_DBG1(yyextra, "unterminated string detected");
137 if (yy_top_state(yyscanner) == inc)
138 { /* string include */
139 include_files(yyextra);
140 yy_pop_state(yyscanner);
141 yy_pop_state(yyscanner);
145 yy_pop_state(yyscanner);
146 yylval->s = yyextra->string_get(yyextra);
150 \\n yyextra->string_add(yyextra, "\n");
151 \\r yyextra->string_add(yyextra, "\r");
152 \\t yyextra->string_add(yyextra, "\t");
153 \\b yyextra->string_add(yyextra, "\b");
154 \\f yyextra->string_add(yyextra, "\f");
156 yyextra->string_add(yyextra, yytext+1);
159 yyextra->string_add(yyextra, yytext);
164 conf_parser_pop_buffer_state(yyscanner);
165 if (!conf_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
174 * Open the next file, if any is queued and readable, otherwise returns FALSE.
176 bool conf_parser_open_next_file(parser_helper_t *ctx)
180 file = ctx->file_next(ctx);
186 conf_parser_set_in(file, ctx->scanner);
187 conf_parser_push_buffer_state(
188 conf_parser__create_buffer(file, YY_BUF_SIZE,
189 ctx->scanner), ctx->scanner);
194 * Assumes that the file pattern to include is currently stored as string on
197 static void include_files(parser_helper_t *ctx)
199 char *pattern = ctx->string_get(ctx);
201 ctx->file_include(ctx, pattern);
204 conf_parser_open_next_file(ctx);