. , : { } = " # \\n \\t space
.EE
.PP
-In rare circumstances \fB.\fP characters may be used in section names (e.g. for
-log file names in a filelog section), but should generally be avoided.
-To use \fB:\fP characters in section names (e.g. for Windows log file paths)
-they may be written as \fB::\fP, which the parser replaces with a single
-\fB:\fP.
-
An example file in this format might look like this:
.PP
.EX
/**
* Recursively print a given section and all subsections/settings
- * FIXME: Doesn't work properly if any of the keys contain dots
*/
static void print_settings_section(settings_t *settings, char *section,
int level)
/* type of our extra data */
%option extra-type="parser_helper_t*"
-/* state used to scan names */
-%x nam
+/* state used to scan references */
+%x ref
/* state used to scan values */
%x val
/* state used to scan include file patterns */
%x str
/* pattern for section/key names */
-NAME [^#{}:,="\r\n\t ]
+NAME [^#{}:.,="\r\n\t ]
%%
\n|#.*\n /* eat newlines and comments at the end of a line */
"{" |
-"}" |
-"," return yytext[0];
+"}" return yytext[0];
-":" return REFS;
+"." return DOT;
+"," return COMMA;
+
+":" {
+ yy_push_state(ref, yyscanner);
+ return COLON;
+}
"=" {
yy_push_state(val, yyscanner);
return STRING_ERROR;
}
-{NAME} {
- yyextra->string_init(yyextra);
- yyextra->string_add(yyextra, yytext);
- yy_push_state(nam, yyscanner);
+{NAME}+ {
+ yylval->s = strdup(yytext);
+ return NAME;
}
-<nam>{
- "::" {
- yyextra->string_add(yyextra, yytext+1);
- }
+<ref>{
+ [\t ]*#[^\r\n]* /* eat comments */
+ [\t\r ]+ /* eat whitespace */
+ \n|#.*\n /* eat newlines and comments at the end of a line */
- {NAME}+ {
- yyextra->string_add(yyextra, yytext);
+ "," return COMMA;
+
+ {NAME}+(\.{NAME}+)* {
+ yylval->s = strdup(yytext);
+ return NAME;
}
- <<EOF>> |
- .|[\r\n] {
- if (*yytext)
- {
- switch (yytext[0])
- {
- case '\n':
- /* put the newline back to fix the line numbers */
- unput('\n');
- yy_set_bol(0);
- break;
- default:
- /* these are parsed outside of this start condition */
- unput(yytext[0]);
- break;
- }
- }
+ . {
+ unput(yytext[0]);
yy_pop_state(yyscanner);
- yylval->s = yyextra->string_get(yyextra);
- return NAME;
}
}
array_t *refs;
}
%token <s> NAME STRING
-%token REFS ":"
+%token DOT "."
+%token COMMA ","
+%token COLON ":"
%token NEWLINE STRING_ERROR
/* ...and other symbols */
$$ = array_create(0, 0);
array_insert($$, ARRAY_TAIL, $1);
}
- | references ',' NAME
+ | references "," NAME
{
array_insert($1, ARRAY_TAIL, $3);
$$ = $1;
ck_assert(settings->load_files(settings, path, FALSE));
verify_string("value", "valid.key");
verify_string("value1", "valid.key1");
-
- contents = chunk_from_str(
- "c::\\Logfiles\\charon.log { dmn = 1 }");
- ck_assert(chunk_write(contents, path, 0022, TRUE));
- ck_assert(settings->load_files(settings, path, FALSE));
- verify_string("1", "%s.dmn", "c:\\Logfiles\\charon.log");
-
- contents = chunk_from_str(
- "section { c::\\Logfiles\\charon.log = 1 }");
- ck_assert(chunk_write(contents, path, 0022, TRUE));
- ck_assert(settings->load_files(settings, path, FALSE));
- verify_string("1", "section.%s", "c:\\Logfiles\\charon.log");
}
END_TEST
"incorrect :: ref {}");
ck_assert(chunk_write(contents, path, 0022, TRUE));
ck_assert(!settings->load_files(settings, path, FALSE));
+
+ contents = chunk_from_str(
+ "/var/log/daemon.log { dmn = 1 }");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(!settings->load_files(settings, path, FALSE));
+
+ contents = chunk_from_str(
+ "filelog { /var/log/daemon.log = 1 }");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(!settings->load_files(settings, path, FALSE));
}
END_TEST