settings: Parse assigned values in a different context
This allows us to accept characters like = or { without having to use quoted strings. And we can also properly warn about unexpected quoted strings.
This commit is contained in:
parent
f8c20fb1c2
commit
740133b12d
|
@ -49,6 +49,8 @@ static void include_files(parser_helper_t *ctx);
|
||||||
/* type of our extra data */
|
/* type of our extra data */
|
||||||
%option extra-type="parser_helper_t*"
|
%option extra-type="parser_helper_t*"
|
||||||
|
|
||||||
|
/* state used to scan values */
|
||||||
|
%x val
|
||||||
/* state used to scan include file patterns */
|
/* state used to scan include file patterns */
|
||||||
%x inc
|
%x inc
|
||||||
/* state used to scan quoted strings */
|
/* state used to scan quoted strings */
|
||||||
|
@ -61,8 +63,12 @@ static void include_files(parser_helper_t *ctx);
|
||||||
\n|#.*\n return NEWLINE; /* also eats comments at the end of a line */
|
\n|#.*\n return NEWLINE; /* also eats comments at the end of a line */
|
||||||
|
|
||||||
"{" |
|
"{" |
|
||||||
"}" |
|
"}" return yytext[0];
|
||||||
"=" return yytext[0];
|
|
||||||
|
"=" {
|
||||||
|
yy_push_state(val, yyscanner);
|
||||||
|
return yytext[0];
|
||||||
|
}
|
||||||
|
|
||||||
"include"[\t ]+/[^=] {
|
"include"[\t ]+/[^=] {
|
||||||
yyextra->string_init(yyextra);
|
yyextra->string_init(yyextra);
|
||||||
|
@ -70,8 +76,8 @@ static void include_files(parser_helper_t *ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
"\"" {
|
"\"" {
|
||||||
yyextra->string_init(yyextra);
|
PARSER_DBG1(yyextra, "unexpected string detected");
|
||||||
yy_push_state(str, yyscanner);
|
return STRING_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
[^#{}="\r\n\t ]+ {
|
[^#{}="\r\n\t ]+ {
|
||||||
|
@ -79,6 +85,42 @@ static void include_files(parser_helper_t *ctx);
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<val>{
|
||||||
|
\r /* just ignore these */
|
||||||
|
[\t ]+
|
||||||
|
<<EOF>> |
|
||||||
|
[#}\n] {
|
||||||
|
if (*yytext)
|
||||||
|
{
|
||||||
|
switch (yytext[0])
|
||||||
|
{
|
||||||
|
case '\n':
|
||||||
|
/* put the newline back to fix the line numbers */
|
||||||
|
unput('\n');
|
||||||
|
yy_set_bol(0);
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
case '}':
|
||||||
|
/* these are parsed outside of this start condition */
|
||||||
|
unput(yytext[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yy_pop_state(yyscanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
"\"" {
|
||||||
|
yyextra->string_init(yyextra);
|
||||||
|
yy_push_state(str, yyscanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* same as above, but allow more characters */
|
||||||
|
[^#}"\r\n\t ]+ {
|
||||||
|
yylval->s = strdup(yytext);
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<inc>{
|
<inc>{
|
||||||
\r /* just ignore these */
|
\r /* just ignore these */
|
||||||
/* we allow all characters except #, } and spaces, they can be escaped */
|
/* we allow all characters except #, } and spaces, they can be escaped */
|
||||||
|
|
|
@ -1109,6 +1109,12 @@ START_TEST(test_valid)
|
||||||
"}\n");
|
"}\n");
|
||||||
ck_assert(chunk_write(contents, path, 0022, TRUE));
|
ck_assert(chunk_write(contents, path, 0022, TRUE));
|
||||||
ck_assert(settings->load_files(settings, path, FALSE));
|
ck_assert(settings->load_files(settings, path, FALSE));
|
||||||
|
|
||||||
|
contents = chunk_from_str(
|
||||||
|
"equals = a setting with = and { character");
|
||||||
|
ck_assert(chunk_write(contents, path, 0022, TRUE));
|
||||||
|
ck_assert(settings->load_files(settings, path, FALSE));
|
||||||
|
verify_string("a setting with = and { character", "equals");
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
@ -1148,7 +1154,7 @@ START_TEST(test_invalid)
|
||||||
ck_assert(!settings->load_files(settings, path, FALSE));
|
ck_assert(!settings->load_files(settings, path, FALSE));
|
||||||
|
|
||||||
contents = chunk_from_str(
|
contents = chunk_from_str(
|
||||||
"only = a single setting = per line");
|
"\"unexpected\" = string");
|
||||||
ck_assert(chunk_write(contents, path, 0022, TRUE));
|
ck_assert(chunk_write(contents, path, 0022, TRUE));
|
||||||
ck_assert(!settings->load_files(settings, path, FALSE));
|
ck_assert(!settings->load_files(settings, path, FALSE));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue