settings: Support CRLF in settings parser
This commit is contained in:
@@ -56,8 +56,8 @@ static void include_files(parser_helper_t *ctx);
|
|||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
[\t ]*#[^\n]* /* eat comments */
|
[\t ]*#[^\r\n]* /* eat comments */
|
||||||
[\t ]+ /* eat whitespace */
|
[\t\r ]+ /* eat whitespace */
|
||||||
\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 */
|
||||||
|
|
||||||
"{" |
|
"{" |
|
||||||
@@ -74,12 +74,13 @@ static void include_files(parser_helper_t *ctx);
|
|||||||
yy_push_state(str, yyscanner);
|
yy_push_state(str, yyscanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
[^#{}="\n\t ]+ {
|
[^#{}="\r\n\t ]+ {
|
||||||
yylval->s = strdup(yytext);
|
yylval->s = strdup(yytext);
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
<inc>{
|
<inc>{
|
||||||
|
\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 */
|
||||||
<<EOF>> |
|
<<EOF>> |
|
||||||
[#}\n\t ] {
|
[#}\n\t ] {
|
||||||
@@ -111,12 +112,13 @@ static void include_files(parser_helper_t *ctx);
|
|||||||
\\["#} ] {
|
\\["#} ] {
|
||||||
yyextra->string_add(yyextra, yytext+1);
|
yyextra->string_add(yyextra, yytext+1);
|
||||||
}
|
}
|
||||||
[^"\\#}\n\t ]+ {
|
[^"\\#}\r\n\t ]+ {
|
||||||
yyextra->string_add(yyextra, yytext);
|
yyextra->string_add(yyextra, yytext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<str>{
|
<str>{
|
||||||
|
\r /* just ignore these */
|
||||||
"\"" |
|
"\"" |
|
||||||
<<EOF>> |
|
<<EOF>> |
|
||||||
\\ {
|
\\ {
|
||||||
@@ -138,12 +140,13 @@ static void include_files(parser_helper_t *ctx);
|
|||||||
return STRING;
|
return STRING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
\\n yyextra->string_add(yyextra, "\n");
|
\\n yyextra->string_add(yyextra, "\n");
|
||||||
\\r yyextra->string_add(yyextra, "\r");
|
\\r yyextra->string_add(yyextra, "\r");
|
||||||
\\t yyextra->string_add(yyextra, "\t");
|
\\t yyextra->string_add(yyextra, "\t");
|
||||||
\\\r?\n /* merge lines that end with EOL characters */
|
\\\r?\n /* merge lines that end with escaped EOL characters */
|
||||||
\\. yyextra->string_add(yyextra, yytext+1);
|
\\. yyextra->string_add(yyextra, yytext+1);
|
||||||
[^\\"]+ {
|
[^\\\r"]+ {
|
||||||
yyextra->string_add(yyextra, yytext);
|
yyextra->string_add(yyextra, yytext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1154,6 +1154,104 @@ START_TEST(test_invalid)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_SETUP(setup_crlf_config)
|
||||||
|
{
|
||||||
|
chunk_t inc1 = chunk_from_str(
|
||||||
|
"main {\r\n"
|
||||||
|
" key1 = n1\r\n"
|
||||||
|
" key2 = n2\n"
|
||||||
|
" key3 = val3\n"
|
||||||
|
" none = \n"
|
||||||
|
" sub1 {\n"
|
||||||
|
" key3 = value\n"
|
||||||
|
" }\n"
|
||||||
|
" sub2 {\n"
|
||||||
|
" sub3 = val3\n"
|
||||||
|
" }\n"
|
||||||
|
" include " include2 "\n"
|
||||||
|
"}");
|
||||||
|
chunk_t inc2 = chunk_from_str(
|
||||||
|
"key2 = v2\n"
|
||||||
|
"sub1 {\n"
|
||||||
|
" key = val\n"
|
||||||
|
"}");
|
||||||
|
ck_assert(chunk_write(inc1, include1, 0022, TRUE));
|
||||||
|
ck_assert(chunk_write(inc2, include2, 0022, TRUE));
|
||||||
|
}
|
||||||
|
END_SETUP
|
||||||
|
|
||||||
|
START_TEST(test_crlf)
|
||||||
|
{
|
||||||
|
chunk_t contents = chunk_from_str(
|
||||||
|
"main {\r\n"
|
||||||
|
" key1 = val1\r\n"
|
||||||
|
" none =\r\n"
|
||||||
|
" sub1 {\r\n"
|
||||||
|
" key2 = v2\r\n"
|
||||||
|
" # key2 = v3\r\n"
|
||||||
|
" sub1 {\r\n"
|
||||||
|
" key = val\r\n"
|
||||||
|
" }\r\n"
|
||||||
|
" }\r\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
create_settings(contents);
|
||||||
|
|
||||||
|
verify_string("val1", "main.key1");
|
||||||
|
verify_string("v2", "main.sub1.key2");
|
||||||
|
verify_string("val", "main.sub1.sub1.key");
|
||||||
|
verify_null("main.none");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_crlf_string)
|
||||||
|
{
|
||||||
|
chunk_t contents = chunk_from_str(
|
||||||
|
"main {\r\n"
|
||||||
|
" key1 = \"new\r\nline\"\r\n"
|
||||||
|
" key2 = \"joi\\\r\nned\"\r\n"
|
||||||
|
" none =\r\n"
|
||||||
|
" sub1 {\r\n"
|
||||||
|
" key2 = v2\r\n"
|
||||||
|
" sub1 {\r\n"
|
||||||
|
" key = val\r\n"
|
||||||
|
" }\r\n"
|
||||||
|
" }\r\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
create_settings(contents);
|
||||||
|
|
||||||
|
verify_string("new\nline", "main.key1");
|
||||||
|
verify_string("joined", "main.key2");
|
||||||
|
verify_string("v2", "main.sub1.key2");
|
||||||
|
verify_string("val", "main.sub1.sub1.key");
|
||||||
|
verify_null("main.none");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_crlf_include)
|
||||||
|
{
|
||||||
|
chunk_t contents = chunk_from_str(
|
||||||
|
"main {\r\n"
|
||||||
|
" key1 = val1\r\n"
|
||||||
|
" none =\r\n"
|
||||||
|
" sub1 {\r\n"
|
||||||
|
" key2 = v2\r\n"
|
||||||
|
" sub1 {\r\n"
|
||||||
|
" key = val\r\n"
|
||||||
|
" }\r\n"
|
||||||
|
" }\r\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
create_settings(contents);
|
||||||
|
|
||||||
|
verify_string("val1", "main.key1");
|
||||||
|
verify_string("v2", "main.sub1.key2");
|
||||||
|
verify_string("val", "main.sub1.sub1.key");
|
||||||
|
verify_null("main.none");
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
Suite *settings_suite_create()
|
Suite *settings_suite_create()
|
||||||
{
|
{
|
||||||
Suite *s;
|
Suite *s;
|
||||||
@@ -1241,5 +1339,12 @@ Suite *settings_suite_create()
|
|||||||
tcase_add_test(tc, test_invalid);
|
tcase_add_test(tc, test_invalid);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
tc = tcase_create("crlf");
|
||||||
|
tcase_add_checked_fixture(tc, setup_crlf_config, teardown_include_config);
|
||||||
|
tcase_add_test(tc, test_crlf);
|
||||||
|
tcase_add_test(tc, test_crlf_string);
|
||||||
|
tcase_add_test(tc, test_crlf_include);
|
||||||
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user