varlink: parse comments too
This commit is contained in:
+79
-10
@@ -657,8 +657,10 @@ static int varlink_idl_subparse_token(
|
||||
static int varlink_idl_subparse_comment(
|
||||
const char **p,
|
||||
unsigned *line,
|
||||
unsigned *column) {
|
||||
unsigned *column,
|
||||
char **ret) {
|
||||
|
||||
_cleanup_free_ char *comment = NULL;
|
||||
size_t l;
|
||||
|
||||
assert(p);
|
||||
@@ -667,9 +669,30 @@ static int varlink_idl_subparse_comment(
|
||||
assert(column);
|
||||
|
||||
l = strcspn(*p, NEWLINE);
|
||||
|
||||
if (!utf8_is_valid_n(*p, l))
|
||||
return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Comment is not valid UTF-8.", *line, *column);
|
||||
|
||||
if (ret) {
|
||||
/* Remove a single space as prefix of a comment, if one is specified. This is because we
|
||||
* generally expect comments to be formatted as "# foobar" rather than "#foobar", and will
|
||||
* ourselves format them that way. We accept the comments without the space too however. We
|
||||
* will not strip more than one space, to allow indented comment blocks. */
|
||||
|
||||
if (**p == ' ')
|
||||
comment = strndup(*p + 1, l - 1);
|
||||
else
|
||||
comment = strndup(*p, l);
|
||||
if (!comment)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
advance_line_column(*p, l + 1, line, column);
|
||||
*p += l;
|
||||
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(comment);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -856,7 +879,7 @@ static int varlink_idl_subparse_struct_or_enum(
|
||||
return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Unexpected token '%s'.", *line, *column, token);
|
||||
|
||||
state = STATE_NAME;
|
||||
allowed_delimiters = ")";
|
||||
allowed_delimiters = ")#";
|
||||
allowed_chars = VALID_CHARS_IDENTIFIER;
|
||||
break;
|
||||
|
||||
@@ -865,7 +888,23 @@ static int varlink_idl_subparse_struct_or_enum(
|
||||
|
||||
if (!token)
|
||||
return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column);
|
||||
if (streq(token, ")"))
|
||||
else if (streq(token, "#")) {
|
||||
_cleanup_free_ char *comment = NULL;
|
||||
|
||||
r = varlink_idl_subparse_comment(p, line, column, &comment);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = varlink_symbol_realloc(symbol, *n_fields + 1);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
VarlinkField *field = (*symbol)->fields + (*n_fields)++;
|
||||
*field = (VarlinkField) {
|
||||
.name = TAKE_PTR(comment),
|
||||
.field_type = _VARLINK_FIELD_COMMENT,
|
||||
};
|
||||
} else if (streq(token, ")"))
|
||||
state = STATE_DONE;
|
||||
else {
|
||||
field_name = TAKE_PTR(token);
|
||||
@@ -929,7 +968,7 @@ static int varlink_idl_subparse_struct_or_enum(
|
||||
|
||||
if (streq(token, ",")) {
|
||||
state = STATE_NAME;
|
||||
allowed_delimiters = NULL;
|
||||
allowed_delimiters = "#";
|
||||
allowed_chars = VALID_CHARS_IDENTIFIER;
|
||||
} else {
|
||||
assert(streq(token, ")"));
|
||||
@@ -947,7 +986,7 @@ static int varlink_idl_subparse_struct_or_enum(
|
||||
return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column);
|
||||
if (streq(token, ",")) {
|
||||
state = STATE_NAME;
|
||||
allowed_delimiters = NULL;
|
||||
allowed_delimiters = "#";
|
||||
allowed_chars = VALID_CHARS_IDENTIFIER;
|
||||
} else if (streq(token, ")"))
|
||||
state = STATE_DONE;
|
||||
@@ -1062,9 +1101,24 @@ int varlink_idl_parse(
|
||||
if (!token)
|
||||
return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column);
|
||||
if (streq(token, "#")) {
|
||||
r = varlink_idl_subparse_comment(&text, line, column);
|
||||
_cleanup_free_ char *comment = NULL;
|
||||
|
||||
r = varlink_idl_subparse_comment(&text, line, column, &comment);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = varlink_interface_realloc(&interface, n_symbols + 1);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = varlink_symbol_realloc(&symbol, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
symbol->symbol_type = _VARLINK_INTERFACE_COMMENT;
|
||||
symbol->name = TAKE_PTR(comment);
|
||||
|
||||
interface->symbols[n_symbols++] = TAKE_PTR(symbol);
|
||||
} else if (streq(token, "interface")) {
|
||||
state = STATE_INTERFACE;
|
||||
allowed_delimiters = NULL;
|
||||
@@ -1074,9 +1128,6 @@ int varlink_idl_parse(
|
||||
break;
|
||||
|
||||
case STATE_INTERFACE:
|
||||
assert(!interface);
|
||||
assert(n_symbols == 0);
|
||||
|
||||
if (!token)
|
||||
return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column);
|
||||
|
||||
@@ -1084,7 +1135,9 @@ int varlink_idl_parse(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert(!interface->name);
|
||||
interface->name = TAKE_PTR(token);
|
||||
|
||||
state = STATE_PRE_SYMBOL;
|
||||
allowed_delimiters = "#";
|
||||
allowed_chars = VALID_CHARS_RESERVED;
|
||||
@@ -1097,9 +1150,25 @@ int varlink_idl_parse(
|
||||
}
|
||||
|
||||
if (streq(token, "#")) {
|
||||
r = varlink_idl_subparse_comment(&text, line, column);
|
||||
_cleanup_free_ char *comment = NULL;
|
||||
|
||||
r = varlink_idl_subparse_comment(&text, line, column, &comment);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = varlink_interface_realloc(&interface, n_symbols + 1);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert(!symbol);
|
||||
r = varlink_symbol_realloc(&symbol, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
symbol->symbol_type = _VARLINK_SYMBOL_COMMENT;
|
||||
symbol->name = TAKE_PTR(comment);
|
||||
|
||||
interface->symbols[n_symbols++] = TAKE_PTR(symbol);
|
||||
} else if (streq(token, "method")) {
|
||||
state = STATE_METHOD;
|
||||
allowed_chars = VALID_CHARS_IDENTIFIER;
|
||||
|
||||
@@ -123,6 +123,21 @@ static void test_parse_format_one(const VarlinkInterface *iface) {
|
||||
assert_se(varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
|
||||
assert_se(varlink_idl_consistent(parsed, LOG_ERR) >= 0);
|
||||
assert_se(varlink_idl_format(parsed, &text2) >= 0);
|
||||
|
||||
ASSERT_STREQ(text, text2);
|
||||
|
||||
text = mfree(text);
|
||||
text2 = mfree(text2);
|
||||
parsed = varlink_interface_free(parsed);
|
||||
|
||||
/* Do the same thing, but aggressively line break, and make sure this is roundtrippable as well */
|
||||
assert_se(varlink_idl_dump(stdout, /* use_colors=*/ true, 23, iface) >= 0);
|
||||
assert_se(varlink_idl_consistent(iface, LOG_ERR) >= 0);
|
||||
assert_se(varlink_idl_format_full(iface, 23, &text) >= 0);
|
||||
assert_se(varlink_idl_parse(text, NULL, NULL, &parsed) >= 0);
|
||||
assert_se(varlink_idl_consistent(parsed, LOG_ERR) >= 0);
|
||||
assert_se(varlink_idl_format_full(parsed, 23, &text2) >= 0);
|
||||
|
||||
ASSERT_STREQ(text, text2);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user