functions: Add runtime entries to bios attr string

Enhance the parsing of the JSON file to add runtime entries to the bios
attribute string. Currently, if the JSON contains a A.P10 and a
A.P10.iplTime entry, it will only add the iplTime entry to the bios
attribute string.
Instead of skipping the A.P10 entries when an iplTime entry exists, add
them as a runtime file (suffix _RT) to the bios attribute string for
hostboot to consume.

Tested: New _RT entries were created:
root@p10bmc:~# pldmtool bios GetBIOSAttributeCurrentValueByHandle -a
hb_lid_ids
{
    "CurrentValue":
"ATTR_PERM=81e00663,ATTR_TMP=81e00664,BMC_INV=81e0066e,BOOTKERNEL=81e00658,DEVTREE=81e00672,EECACHE=81e00679,GUARD=81e00667,HBB=81e0065a,HBBL=81e0065b,HBD=81e0068d,HBD_RT=81e00630,HBD_RW=81e00676,HBEL=81e00668,HBI=81e0065d,HBRT=81e0068e,HBRT_RT=81e00300,HB_VOLATILE=81e0066f,HCODE=81e00696,HCODE_LID=81e0067b,HCODE_LID_RT=81e00671,HCODE_RT=81e00602,HDAT=81e00669,IMA_CATALOG=81e0065e,NVRAM=81e0066b,OCC=81e00688,OCC_RT=81e00430,OCMBFW=81e0067a,PART=81e00670,PAYLOAD=81e00660,RINGOVD=81e00620,SBE=81e00661,SBKT=81e0066c,SECBOOT=81e0066d,UVISOR=81e00678,VERSION=81e00662,WOFDATA=81e00692,WOFDATA_RT=81e00440,pnor.toc=NA"
}

Change-Id: Id72106e859040f6054907adb51dd974f856d3796
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/functions.cpp b/functions.cpp
index 746a2a8..38ebeca 100644
--- a/functions.cpp
+++ b/functions.cpp
@@ -305,11 +305,15 @@
         }
 
         // The elements with the ipl extension have higher priority. Therefore
-        // Use operator[] to overwrite value if an entry for it already exists.
-        // Ex: if the JSON contains an entry A.P10 followed by A.P10.iplTime,
-        // the lid value for the latter one will be overwrite the value of the
-        // first one.
+        // Use operator[] to overwrite value if an entry for it already exists,
+        // and create a second entry with key name element_RT to specify it as
+        // a runtime element.
+        // Ex: if the JSON contains an entry A.P10 with lid name X, it'll create
+        // and try A=X. If the JSON also contained an entry A.P10.iplTime with
+        // lid name Y, the A entry would be overwritten to be A=Y and a second
+        // entry A_RT=X would be created.
         constexpr auto iplExtension = ".iplTime";
+        constexpr auto runtimeSuffix = "_RT";
         std::filesystem::path path(name);
         if (path.extension() == iplExtension)
         {
@@ -329,7 +333,16 @@
             // since stem() returns the base name if no periods are found.
             // Therefore both "element.P10" and "element.P10.iplTime" would
             // become "element".
-            attr[path.stem().stem()] = lid;
+            auto keyName = path.stem().stem();
+            auto attrIt = attr.find(keyName);
+            if (attrIt != attr.end())
+            {
+                // Copy the existing entry to a runtime entry
+                auto runtimeKeyName = keyName.string() + runtimeSuffix;
+                attr.insert({runtimeKeyName, attrIt->second});
+            }
+            // Overwrite the exsiting element with the ipl entry
+            attr[keyName] = lid;
             continue;
         }
 
@@ -340,7 +353,19 @@
         if (std::find(extensions.begin(), extensions.end(), path.extension()) !=
             extensions.end())
         {
-            attr.insert({path.stem(), lid});
+            auto keyName = path.stem();
+            auto attrIt = attr.find(keyName);
+            if (attrIt != attr.end())
+            {
+                // The existing entry is an ipl entry, therefore create this
+                // entry as a runtime one.
+                auto runtimeKeyName = keyName.string() + runtimeSuffix;
+                attr.insert({runtimeKeyName, lid});
+            }
+            else
+            {
+                attr.insert({path.stem(), lid});
+            }
         }
     }
     for (const auto& a : attr)