3 * Copyright (C) 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>
19 #include "settings_parser.h"
21 bool settings_parser_open_next_file(parser_helper_t *ctx);
23 static void include_files(parser_helper_t *ctx);
31 /* use start conditions stack */
34 /* do not declare unneded functions */
35 %option noinput noyywrap
37 /* don't use global variables, and interact properly with bison */
38 %option reentrant bison-bridge
40 /* maintain the line number */
43 /* don't generate a default rule */
46 /* prefix function/variable declarations */
47 %option prefix="settings_parser_"
48 /* don't change the name of the output file otherwise autotools has issues */
49 %option outfile="lex.yy.c"
51 /* type of our extra data */
52 %option extra-type="parser_helper_t*"
54 /* state used to scan include file patterns */
56 /* state used to scan quoted strings */
61 [\t ]*#[^\n]* /* eat comments */
62 [\t ]+ /* eat whitespace */
63 \n|#.*\n return NEWLINE; /* also eats comments at the end of a line */
69 "include"[\t ]+/[^=] {
70 yyextra->string_init(yyextra);
71 yy_push_state(inc, yyscanner);
75 yyextra->string_init(yyextra);
76 yy_push_state(str, yyscanner);
80 yylval->s = strdup(yytext);
85 /* we allow all characters except #, } and spaces, they can be escaped */
89 if (*yytext && yytext[strlen(yytext) - 1] == '\n')
90 { /* put the newline back to fix the line numbers */
94 include_files(yyextra);
95 yy_pop_state(yyscanner);
97 "\"" { /* string include */
98 yy_push_state(str, yyscanner);
101 yyextra->string_add(yyextra, yytext);
104 yyextra->string_add(yyextra, yytext+1);
107 yyextra->string_add(yyextra, yytext);
116 if (!streq(yytext, "\""))
118 if (streq(yytext, "\n"))
119 { /* put the newline back to fix the line numbers */
123 PARSER_DBG1(yyextra, "unterminated string detected");
125 if (yy_top_state(yyscanner) == inc)
126 { /* string include */
127 include_files(yyextra);
128 yy_pop_state(yyscanner);
129 yy_pop_state(yyscanner);
133 yy_pop_state(yyscanner);
134 yylval->s = yyextra->string_get(yyextra);
138 \\n yyextra->string_add(yyextra, "\n");
139 \\r yyextra->string_add(yyextra, "\r");
140 \\t yyextra->string_add(yyextra, "\t");
141 \\b yyextra->string_add(yyextra, "\b");
142 \\f yyextra->string_add(yyextra, "\f");
144 yyextra->string_add(yyextra, yytext+1);
147 yyextra->string_add(yyextra, yytext);
152 settings_parser_pop_buffer_state(yyscanner);
153 if (!settings_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
162 * Open the next file, if any is queued and readable, otherwise returns FALSE.
164 bool settings_parser_open_next_file(parser_helper_t *ctx)
166 parser_helper_file_t *file;
168 file = ctx->file_next(ctx);
174 settings_parser_set_in(file->file, ctx->scanner);
175 settings_parser_push_buffer_state(
176 settings_parser__create_buffer(file->file, YY_BUF_SIZE,
177 ctx->scanner), ctx->scanner);
182 * Assumes that the file pattern to include is currently stored as string on
185 static void include_files(parser_helper_t *ctx)
187 char *pattern = ctx->string_get(ctx);
189 ctx->file_include(ctx, pattern);
192 settings_parser_open_next_file(ctx);