From afadbbbb04749314266202e9cb7a6d181a90746a Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 11 Apr 2018 11:38:00 +0200 Subject: [PATCH] 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 --- repos/os/run/rom_filter.run | 38 ++++++++------ repos/os/src/server/rom_filter/README | 17 ++++--- .../server/rom_filter/input_rom_registry.h | 49 ++++++++++++++++++- 3 files changed, 80 insertions(+), 24 deletions(-) diff --git a/repos/os/run/rom_filter.run b/repos/os/run/rom_filter.run index 2d25e48879..a8b2d5cbef 100644 --- a/repos/os/run/rom_filter.run +++ b/repos/os/run/rom_filter.run @@ -53,7 +53,12 @@ append config { - + +
+ + +
+
@@ -70,22 +75,23 @@ append config { + + + + + + + + + - + - + - - - - - - - - - + @@ -130,10 +136,10 @@ compare_output_to { [init -> rom_logger] ROM 'generated': [init -> rom_logger] [init -> rom_logger] ROM 'generated': -[init -> rom_logger] -[init -> rom_logger] ROM 'generated': -[init -> rom_logger] -[init -> rom_logger] ROM 'generated': [init -> rom_logger] +[init -> rom_logger] ROM 'generated': +[init -> rom_logger] +[init -> rom_logger] ROM 'generated': +[init -> rom_logger] } diff --git a/repos/os/src/server/rom_filter/README b/repos/os/src/server/rom_filter/README index 07fbe10aa3..db4d559657 100644 --- a/repos/os/src/server/rom_filter/README +++ b/repos/os/src/server/rom_filter/README @@ -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 '' 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 '' 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 '' node may contain a hierarchy of '' 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 '' node. The type of the top-level XML node must be specified via the 'node' attribute. diff --git a/repos/os/src/server/rom_filter/input_rom_registry.h b/repos/os/src/server/rom_filter/input_rom_registry.h index a3c89832f3..43eb0cc1d9 100644 --- a/repos/os/src/server/rom_filter/input_rom_registry.h +++ b/repos/os/src/server/rom_filter/input_rom_registry.h @@ -88,6 +88,47 @@ class Rom_filter::Input_rom_registry Genode::Signal_handler _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; }