The boot config syntax is a simple structured key-value. Each key consists
of dot-connected-words, and key and value are connected by ``=``. The value
-has to be terminated by semi-colon (``;``) or newline (``\n``).
-For array value, array entries are separated by comma (``,``). ::
-
- KEY[.WORD[...]] = VALUE[, VALUE2[...]][;]
-
-Unlike the kernel command line syntax, spaces are OK around the comma and ``=``.
+string has to be terminated by the following delimiters described below.
Each key word must contain only alphabets, numbers, dash (``-``) or underscore
(``_``). And each value only contains printable characters or spaces except
for delimiters such as semi-colon (``;``), new-line (``\n``), comma (``,``),
hash (``#``) and closing brace (``}``).
+If the ``=`` is followed by whitespace up to one of these delimiters, the
+key is assigned an empty value.
+
+For arrays, the array values are comma (``,``) separated, and comments and
+line breaks with newline (``\n``) are allowed between array values for
+readability. Thus the first entry of the array must be on the same line as
+the key.::
+
+ KEY[.WORD[...]] = VALUE[, VALUE2[...]][;]
+
+Unlike the kernel command line syntax, white spaces (including tabs) are
+ignored around the comma and ``=``.
+
If you want to use those delimiters in a value, you can use either double-
quotes (``"VALUE"``) or single-quotes (``'VALUE'``) to quote it. Note that
you can not escape these quotes.
foo = value
bar = 1, 2, 3
-Note that you can not put a comment between value and delimiter(``,`` or
-``;``). This means following config has a syntax error ::
+Note that you can NOT put a comment or a newline between value and delimiter
+(``,`` or ``;``). This means following config has a syntax error ::
key = 1 # comment
,2
/*
* Return delimiter or error, no node added. As same as lib/cmdline.c,
* you can use " around spaces, but can't escape " for value.
+ * *@__v must point real value string. (not including spaces before value.)
*/
static int __init __xbc_parse_value(char **__v, char **__n)
{
char *p, *v = *__v;
int c, quotes = 0;
- v = skip_spaces(v);
- while (*v == '#') {
- v = skip_comment(v);
- v = skip_spaces(v);
- }
if (*v == '"' || *v == '\'') {
quotes = *v;
v++;
last_parent = xbc_node_get_child(last_parent);
do {
+ /* Search the next array value beyond comments and empty lines */
+ next = skip_spaces(*__v);
+ while (*next == '#') {
+ next = skip_comment(next);
+ next = skip_spaces(next);
+ }
+ *__v = next;
c = __xbc_parse_value(__v, &next);
if (c < 0)
return c;
if (ret)
return ret;
- c = __xbc_parse_value(&v, &next);
- if (c < 0)
- return c;
+ v = skip_spaces_until_newline(v);
+ /* If there is a comment, this has an empty value. */
+ if (*v == '#') {
+ next = skip_comment(v);
+ *v = '\0';
+ c = '\n';
+ } else {
+ c = __xbc_parse_value(&v, &next);
+ if (c < 0)
+ return c;
+ }
child = xbc_node_get_child(last_parent);
if (child && xbc_node_is_value(child)) {