rom_filter: add attribute matching for input nodes

The new 'attribute' and 'value' attributes of input nodes
can be used to select input sub nodes that match the presence and value
of the specified attribute.

Issue #2691
This commit is contained in:
Norman Feske 2018-04-11 11:38:00 +02:00 committed by Christian Helmuth
parent 4b4760ce8e
commit afadbbbb04
3 changed files with 80 additions and 24 deletions

View File

@ -53,7 +53,12 @@ append config {
</inline>
<sleep milliseconds="1000" />
<inline description="leave X-ray mode undefined">
<xray/> <!-- undefined -->
<xray> <!-- undefined -->
<details>
<message reason="error"/> <!-- not selected -->
<message reason="no access" text="system locked"/>
</details>
</xray>
</inline>
<sleep milliseconds="1000" />
<inline description="finished"/>
@ -70,22 +75,23 @@ append config {
<attribute name="enabled" />
</input>
<input name="diagnostic_message" rom="xray" node="xray">
<node type="details">
<node type="message" attribute="reason" value="no access">
<attribute name="text" />
</node>
</node>
</input>
<output node="config">
<attribute name="message" input="diagnostic_message"/>
<if>
<has_value input="xray_enabled" value="no" />
<has_value input="xray_enabled" value="yes" />
<then>
<inline><!-- .. flat window decorations ... --></inline>
<inline><!-- xray enabled --></inline>
</then>
<else>
<if>
<has_value input="xray_enabled" value="yes" />
<then>
<inline><!-- ... colored window decorations ... --></inline>
</then>
<else>
<inline><!-- ... fallback ... --></inline>
</else>
</if>
<inline><!-- ... fallback ... --></inline>
</else>
</if>
</output>
@ -130,10 +136,10 @@ compare_output_to {
[init -> rom_logger] ROM 'generated':
[init -> rom_logger] <config><!-- ... fallback ... --></config>
[init -> rom_logger] ROM 'generated':
[init -> rom_logger] <config><!-- .. flat window decorations ... --></config>
[init -> rom_logger] ROM 'generated':
[init -> rom_logger] <config><!-- ... colored window decorations ... --></config>
[init -> rom_logger] ROM 'generated':
[init -> rom_logger] <config><!-- ... fallback ... --></config>
[init -> rom_logger] ROM 'generated':
[init -> rom_logger] <config><!-- xray enabled --></config>
[init -> rom_logger] ROM 'generated':
[init -> rom_logger] <config message="system locked"><!-- ... fallback ... --></config>
}

View File

@ -10,12 +10,17 @@ Configuration
The configuration consists of two parts. The first part is the declaration of
input values that are taken into the account. The input values are obtained
from ROM modules that contain XML-formatted data. Each input value is
represented by an '<input>' node with a unique 'name' attribute. The 'rom'
attribute specifies the ROM module to take the input from. If not specified,
the 'name' is used as the ROM name. The type of the top-level XML node can be
specified via the 'node' attribute. If not present, the top-level XML node is
expected to correspond to the 'name' attribute.
from ROM modules that contain XML-formatted data.
Each input value is represented by an '<input>' node with a unique 'name'
attribute. The 'rom' attribute specifies the ROM module to take the input
from. If not specified, the 'name' is used as the ROM name. The type of the
top-level XML node can be specified via the 'node' attribute. If not present,
the top-level XML node is expected to correspond to the 'name' attribute.
The '<input>' node may contain a hierarchy of '<node type="type">' nodes that
denote a path within the XML input. If specified, the optional attributes
'attribute' and 'value' constrain the selection of the input depending of the
presence and the value of the specified attribute.
The second part of the configuration defines the output via an '<output>' node.
The type of the top-level XML node must be specified via the 'node' attribute.

View File

@ -88,6 +88,47 @@ class Rom_filter::Input_rom_registry
Genode::Signal_handler<Entry> _rom_changed_handler =
{ _env.ep(), *this, &Entry::_handle_rom_changed };
/**
* Return sub node of 'content' according to the constraints
* given by 'path'
*
* \throw Xml_node::Nonexistent_sub_node
*/
static Xml_node _matching_sub_node(Node_type_name type,
Xml_node const &path,
Xml_node const &content)
{
typedef Input_value Attribute_value;
Xml_node sub_node = content.sub_node(type.string());
Attribute_name const expected_attr =
path.attribute_value("attribute", Attribute_name());
Attribute_value const expected_value =
path.attribute_value("value", Attribute_value());
for (;; sub_node = sub_node.next(type.string())) {
/* attribute remains unspecified -> match */
if (!expected_attr.valid())
return sub_node;
/* value remains unspecified -> match */
if (!expected_value.valid())
return sub_node;
Attribute_value const present_value =
sub_node.attribute_value(expected_attr.string(),
Attribute_value());
if (present_value == expected_value)
return sub_node;
}
throw Xml_node::Nonexistent_sub_node();
}
/**
* Query value from XML-structured ROM content
*
@ -122,8 +163,12 @@ class Rom_filter::Input_rom_registry
Node_type_name const sub_node_type =
path.attribute_value("type", Node_type_name(""));
content = content.sub_node(sub_node_type.string());
path = path.sub_node();
try {
content = _matching_sub_node(sub_node_type, path, content);
path = path.sub_node();
}
catch (Xml_node::Nonexistent_sub_node) {
throw Nonexistent_input_value(); }
continue;
}