Add MATCH_ONE Probe Type

The demo systems only have riser 3 installed, so add
a MATCH_ONE probe that allows you to only return 1 device
in the case a regex finds multiple.

Change-Id: I5cb0b3519ccdd467b39795436a80d504a0c82f24
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/configurations/R1000 Chassis.json b/configurations/R1000 Chassis.json
index fdb5d27..692d403 100644
--- a/configurations/R1000 Chassis.json
+++ b/configurations/R1000 Chassis.json
@@ -245,6 +245,7 @@
     "probe": [
         "FOUND('WFP Baseboard')",
         "AND",
-        "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'F1UL16RISER1'})"
+        "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'F1UL16RISER\\d'})",
+        "MATCH_ONE"
     ]
 }
\ No newline at end of file
diff --git a/configurations/R2000 Chassis.json b/configurations/R2000 Chassis.json
index 7743b77..298b16f 100644
--- a/configurations/R2000 Chassis.json
+++ b/configurations/R2000 Chassis.json
@@ -125,6 +125,7 @@
     "probe": [
         "FOUND('WFP Baseboard')",
         "AND",
-        "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'A2UL16RISER1'})"
+        "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'A2UL16RISER\\d'})",
+        "MATCH_ONE"
     ]
 }
\ No newline at end of file
diff --git a/src/EntityManager.cpp b/src/EntityManager.cpp
index 45d18e9..7b91159 100644
--- a/src/EntityManager.cpp
+++ b/src/EntityManager.cpp
@@ -54,14 +54,16 @@
     TRUE_T,
     AND,
     OR,
-    FOUND
+    FOUND,
+    MATCH_ONE
 };
 const static boost::container::flat_map<const char *, probe_type_codes, cmp_str>
     PROBE_TYPES{{{"FALSE", probe_type_codes::FALSE_T},
                  {"TRUE", probe_type_codes::TRUE_T},
                  {"AND", probe_type_codes::AND},
                  {"OR", probe_type_codes::OR},
-                 {"FOUND", probe_type_codes::FOUND}}};
+                 {"FOUND", probe_type_codes::FOUND},
+                 {"MATCH_ONE", probe_type_codes::MATCH_ONE}}};
 
 using GetSubTreeType = std::vector<
     std::pair<std::string,
@@ -267,6 +269,7 @@
     const static std::regex command(R"(\((.*)\))");
     std::smatch match;
     bool ret = false;
+    bool matchOne = false;
     bool cur = true;
     probe_type_codes lastCommand = probe_type_codes::FALSE_T;
 
@@ -299,6 +302,14 @@
                 return true; // todo, actually evaluate?
                 break;
             }
+            case probe_type_codes::MATCH_ONE:
+            {
+                // set current value to last, this probe type shouldn't affect
+                // the outcome
+                cur = ret;
+                matchOne = true;
+                break;
+            }
             /*case probe_type_codes::AND:
               break;
             case probe_type_codes::OR:
@@ -384,6 +395,10 @@
         foundDevs.emplace_back(
             boost::container::flat_map<std::string, dbus::dbus_variant>());
     }
+    if (matchOne && foundDevs.size() > 1)
+    {
+        foundDevs.erase(foundDevs.begin() + 1, foundDevs.end());
+    }
     return ret;
 }