settings: Add support for multi-line strings

Unterminated strings are now an error.
This commit is contained in:
Tobias Brunner 2015-06-08 17:47:51 +02:00
parent d918410add
commit 764960e8b9
3 changed files with 20 additions and 16 deletions

View File

@ -119,16 +119,11 @@ static void include_files(parser_helper_t *ctx);
<str>{
"\"" |
<<EOF>> |
\n |
\\ {
if (!streq(yytext, "\""))
{
if (streq(yytext, "\n"))
{ /* put the newline back to fix the line numbers */
unput('\n');
yy_set_bol(0);
}
PARSER_DBG1(yyextra, "unterminated string detected");
return STRING_ERROR;
}
if (yy_top_state(yyscanner) == inc)
{ /* string include */
@ -148,7 +143,7 @@ static void include_files(parser_helper_t *ctx);
\\t yyextra->string_add(yyextra, "\t");
\\\r?\n /* merge lines that end with EOL characters */
\\. yyextra->string_add(yyextra, yytext+1);
[^\\\n"]+ {
[^\\"]+ {
yyextra->string_add(yyextra, yytext);
}
}

View File

@ -79,7 +79,7 @@ static int yylex(YYSTYPE *lvalp, parser_helper_t *ctx)
struct kv_t *kv;
}
%token <s> NAME STRING
%token NEWLINE
%token NEWLINE STRING_ERROR
/* ...and other symbols */
%type <s> value valuepart

View File

@ -58,6 +58,10 @@ START_SETUP(setup_base_config)
" }\n"
" key2 = with space\n"
" key3 = \"string with\\nnewline\"\n"
" key4 = \"multi line\n"
"string\"\n"
" key5 = \"escaped \\\n"
"newline\"\n"
"}\n"
"out = side\n"
"other {\n"
@ -88,6 +92,8 @@ START_TEST(test_get_str)
verify_string("", "main.empty");
verify_string("with space", "main.key2");
verify_string("string with\nnewline", "main.key3");
verify_string("multi line\nstring", "main.key4");
verify_string("escaped newline", "main.key5");
verify_string("value", "main.sub1.key");
verify_string("value2", "main.sub1.key2");
verify_string("bar", "main.sub1.subsub.foo");
@ -97,7 +103,7 @@ START_TEST(test_get_str)
verify_string("other val", "other.key1");
verify_null("main.none");
verify_null("main.key4");
verify_null("main.key6");
verify_null("other.sub");
}
END_TEST
@ -131,7 +137,7 @@ START_TEST(test_get_str_printf)
* probably document it at least */
verify_null("main.%s%u.key%d", "sub", 1, 2);
verify_null("%s.%s%d", "main", "key", 4);
verify_null("%s.%s%d", "main", "key", 6);
}
END_TEST
@ -906,9 +912,8 @@ START_SETUP(setup_string_config)
create_settings(chunk_from_str(
"string = \" with accurate\twhitespace\"\n"
"special = \"all { special } characters # can be used.\"\n"
"unterminated = \"is fine\n"
"but = produces a warning\n"
"newlines = \"can either be encoded\\nor \\\n"
"newlines = \"can be encoded explicitly\\nor implicitly\n"
"or \\\n"
"escaped\"\n"
"quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n"
"multiple = \"strings\" are \"combined\"\n"
@ -920,9 +925,7 @@ START_TEST(test_strings)
{
verify_string(" with accurate\twhitespace", "string");
verify_string("all { special } characters # can be used.", "special");
verify_string("is fine", "unterminated");
verify_string("produces a warning", "but");
verify_string("can either be encoded\nor escaped", "newlines");
verify_string("can be encoded explicitly\nor implicitly\nor escaped", "newlines");
verify_string("\"and\" slashes \\ can \\ be", "quotes");
verify_string("strings are combined", "multiple");
}
@ -989,6 +992,12 @@ START_TEST(test_invalid)
ck_assert(chunk_write(contents, path, 0022, TRUE));
ck_assert(!settings->load_files(settings, path, FALSE));
contents = chunk_from_str(
"unterminated {\n"
" strings = \"are invalid\n");
ck_assert(chunk_write(contents, path, 0022, TRUE));
ck_assert(!settings->load_files(settings, path, FALSE));
contents = chunk_from_str(
"spaces in name {}");
ck_assert(chunk_write(contents, path, 0022, TRUE));