Fix an issue with $index

the $index replacement for names wasn't working correctly.  This commit
refactors the code to make it work correctly in 3 cases.

1. Where the template is the entire string "$index" replaces it with the
given type.
2. Where the template is a portion of the string "index=$index" in which
case it replaces just the parameter with the stringified version.
3. Where the template starts with 0x, which replaces it with the hex
equivalent.

Tested By:
Observed PCIe retimer device is called "retimer 0" instead of "retimer
_"

Change-Id: I37a22f1c5502057754eb0d89c467502eb054d73b
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
diff --git a/configurations/A2UX8X4RISER.json b/configurations/A2UX8X4RISER.json
new file mode 100644
index 0000000..e960f87
--- /dev/null
+++ b/configurations/A2UX8X4RISER.json
@@ -0,0 +1,53 @@
+[
+    {
+        "Exposes": [
+            {
+                "Address": "0x4E",
+                "Bus": "$bus",
+                "Name": "Riser 3 Temp",
+                "Thresholds": [
+                    {
+                        "Direction": "greater than",
+                        "Name": "upper critical",
+                        "Severity": 1,
+                        "Value": 80
+                    },
+                    {
+                        "Direction": "greater than",
+                        "Name": "upper non critical",
+                        "Severity": 0,
+                        "Value": 75
+                    },
+                    {
+                        "Direction": "less than",
+                        "Name": "lower non critical",
+                        "Severity": 0,
+                        "Value": 5
+                    },
+                    {
+                        "Direction": "less than",
+                        "Name": "lower critical",
+                        "Severity": 1,
+                        "Value": 0
+                    }
+                ],
+                "Type": "TMP75"
+            },
+            {
+                "Address": "$address",
+                "Bus": "$bus",
+                "Name": "Riser 3 Fru",
+                "Type": "EEPROM"
+            }
+        ],
+        "Name": "2Ux8 Riser 3",
+        "Type": "Board",
+        "Probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'A2UX8X4RISER'})",
+        "xyz.openbmc_project.Inventory.Decorator.Asset": {
+            "Manufacturer": "$BOARD_MANUFACTURER",
+            "Model": "$BOARD_PRODUCT_NAME",
+            "PartNumber": "$BOARD_PART_NUMBER",
+            "SerialNumber": "$BOARD_SERIAL_NUMBER"
+        }
+    }
+]
\ No newline at end of file
diff --git a/src/EntityManager.cpp b/src/EntityManager.cpp
index 14b6fb6..94708b8 100644
--- a/src/EntityManager.cpp
+++ b/src/EntityManager.cpp
@@ -1080,51 +1080,48 @@
         }
         return;
     }
-    else if (keyPair.value().type() != nlohmann::json::value_t::string)
+
+    std::string* strPtr = keyPair.value().get_ptr<std::string*>();
+    if (strPtr == nullptr)
     {
         return;
     }
 
-    std::string value = keyPair.value();
-    if (value.find(TEMPLATE_CHAR) != std::string::npos)
+    boost::replace_all(*strPtr, "$index", std::to_string(foundDeviceIdx));
+
+    std::size_t templateIndex = 0;
+
+    for (auto& foundDevicePair : foundDevice)
     {
-        std::string templateValue = value;
-
-        templateValue.erase(0, 1); // remove template character
-
-        // special case index
-        if ("index" == templateValue)
+        std::string templateName = "$" + foundDevicePair.first;
+        if (boost::iequals(*strPtr, templateName))
         {
-            keyPair.value() = foundDeviceIdx;
+            std::visit([&](auto&& val) { keyPair.value() = val; },
+                       foundDevicePair.second);
+            // We probably just invalidated the pointer above, so set it to null
+            strPtr = nullptr;
+            break;
         }
-        else
-        {
-            bool found = false;
-            for (auto& foundDevicePair : foundDevice)
-            {
-                if (boost::iequals(foundDevicePair.first, templateValue))
-                {
-                    std::visit([&](auto&& val) { keyPair.value() = val; },
-                               foundDevicePair.second);
-                    found = true;
-                    break;
-                }
-            }
-            if (!found)
-            {
-                std::cerr << "could not find symbol " << templateValue << "\n";
-            }
-        }
+
+        std::string probeValue =
+            std::visit(VariantToStringVisitor(), foundDevicePair.second);
+        boost::replace_all(*strPtr, templateName, probeValue);
+    }
+
+    strPtr = keyPair.value().get_ptr<std::string*>();
+    if (strPtr == nullptr)
+    {
+        return;
     }
 
     // convert hex numbers to ints
-    else if (boost::starts_with(value, "0x"))
+    if (boost::starts_with(*strPtr, "0x"))
     {
         try
         {
             size_t pos = 0;
-            int64_t temp = std::stoul(value, &pos, 0);
-            if (pos == value.size())
+            int64_t temp = std::stoul(*strPtr, &pos, 0);
+            if (pos == strPtr->size())
             {
                 keyPair.value() = static_cast<uint64_t>(temp);
             }