commit
bb6312484af93a83a9ec8716f3887a43566a775a upstream.
Implement this as a special "type" property value which is an object
with sole property "typeof". The latter's value is the JSON
representation of the expression in set->key, so for concatenated
typeofs it is a concat expression.
All this is a bit clumsy right now but it works and it should be
possible to tear it down a bit for more user-friendliness in a
compatible way by either replacing the concat expression by the array it
contains or even the whole "typeof" object - the parser would just
assume any object (or objects in an array) in the "type" property value
are expressions to extract a type from.
Signed-off-by: Phil Sutter <phil@nwl.cc>
"auto-merge":* 'BOOLEAN'
*}}*
-'SET_TYPE' := 'STRING' | *[* 'SET_TYPE_LIST' *]*
+'SET_TYPE' := 'STRING' | *[* 'SET_TYPE_LIST' *]* | *{ "typeof":* 'EXPRESSION' *}*
'SET_TYPE_LIST' := 'STRING' [*,* 'SET_TYPE_LIST' ]
'SET_POLICY' := *"performance"* | *"memory"*
'SET_FLAG_LIST' := 'SET_FLAG' [*,* 'SET_FLAG_LIST' ]
Automatic merging of adjacent/overlapping set elements in interval sets.
==== TYPE
-The set type might be a string, such as *"ipv4_addr"* or an array
-consisting of strings (for concatenated types).
+The set type might be a string, such as *"ipv4_addr"*, an array
+consisting of strings (for concatenated types) or a *typeof* object containing
+an expression to extract the type from.
==== ELEM
A single set element might be given as string, integer or boolean value for
return root;
}
+static json_t *set_key_dtype_json(const struct set *set,
+ struct output_ctx *octx)
+{
+ bool use_typeof = set->key_typeof_valid;
+
+ if (!use_typeof)
+ return set_dtype_json(set->key);
+
+ return json_pack("{s:o}", "typeof", expr_print_json(set->key, octx));
+}
+
static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
{
char buf[1024];
"family", family2str(set->handle.family),
"name", set->handle.set.name,
"table", set->handle.table.name,
- "type", set_dtype_json(set->key),
+ "type", set_key_dtype_json(set, octx),
"handle", set->handle.handle.id);
if (set->comment)
compound_expr_add(expr, i);
}
return expr;
+ } else if (json_is_object(root)) {
+ const char *key;
+ json_t *val;
+
+ if (!json_unpack_stmt(ctx, root, &key, &val) &&
+ !strcmp(key, "typeof")) {
+ return json_parse_expr(ctx, val);
+ }
}
+
json_error(ctx, "Invalid set datatype.");
return NULL;
}