regex-instance: HalInterface stores regex instances.

Parse <regex-instance> regular expression patterns using
Extended Regular Expression syntax, and store it in
HalInterface object.

Bug: 73738616
Test: libvintf_test
Test: vintf_object_test
Test: vts_treble_vintf_test

Change-Id: If0b8e3bc053a6c2ecd9048092071f52f7896bba0
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 3d67e1c..27f31c9 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -25,6 +25,7 @@
 
 #include <tinyxml2.h>
 
+#include "Regex.h"
 #include "constants.h"
 #include "parse_string.h"
 
@@ -475,11 +476,14 @@
     void mutateNode(const HalInterface &intf, NodeType *root, DocType *d) const override {
         appendTextElement(root, "name", intf.name(), d);
         appendTextElements(root, "instance", intf.mInstances, d);
+        appendTextElements(root, "regex-instance", intf.mRegexes, d);
     }
     bool buildObject(HalInterface* intf, NodeType* root, std::string* error) const override {
         std::vector<std::string> instances;
+        std::vector<std::string> regexes;
         if (!parseTextElement(root, "name", &intf->mName, error) ||
-            !parseTextElements(root, "instance", &instances, error)) {
+            !parseTextElements(root, "instance", &instances, error) ||
+            !parseTextElements(root, "regex-instance", &regexes, error)) {
             return false;
         }
         bool success = true;
@@ -490,6 +494,19 @@
                 success = false;
             }
         }
+        for (const auto& e : regexes) {
+            details::Regex regex;
+            if (!regex.compile(e)) {
+                if (!error->empty()) *error += "\n";
+                *error += "Invalid regular expression '" + e + "' in " + intf->name();
+                success = false;
+            }
+            if (!intf->insertInstance(e, true /* isRegex */)) {
+                if (!error->empty()) *error += "\n";
+                *error += "Duplicated regex-instance '" + e + "' in " + intf->name();
+                success = false;
+            }
+        }
         return success;
     }
 };