Add support for Inventory.Decorator.Compatible

This adds support for the compatibility strings interface described in
https://github.com/openbmc/phosphor-dbus-interfaces/tree/master/yaml/xyz/openbmc_project/Software#compatibility.

The Version objects will now be created with the Inventory.Decorator.Compatible
interface with the compatibility names coming from the MANIFEST file.
e.g.
version=1.2.3
MachineName=foo
purpose=Other
ExtendedVersion=a.b.c
CompatibleName=foo.bar
CompatibleName=baz.bim

Tested:
$ busctl get-property xyz.openbmc_project.Software.Version \
    /xyz/openbmc_project/software/517751da \
    xyz.openbmc_project.Inventory.Decorator.Compatible Names
as 2 "foo.bar" "baz.bim"

Signed-off-by: Justin Ledford <justinledford@google.com>
Change-Id: I9ee36af2d3d1494d533a3b09c466a250c4fe786b
diff --git a/version.cpp b/version.cpp
index 250c221..f7fbd2b 100644
--- a/version.cpp
+++ b/version.cpp
@@ -30,6 +30,23 @@
 std::string Version::getValue(const std::string& manifestFilePath,
                               std::string key)
 {
+    std::vector<std::string> values = getRepeatedValues(manifestFilePath, key);
+    if (values.empty())
+    {
+        return std::string{};
+    }
+    if (values.size() > 1)
+    {
+        error("Multiple values found in MANIFEST file for key: {KEY}", "KEY",
+              key);
+    }
+    return values.at(0);
+}
+
+std::vector<std::string>
+    Version::getRepeatedValues(const std::string& manifestFilePath,
+                               std::string key)
+{
     key = key + "=";
     auto keySize = key.length();
 
@@ -41,11 +58,10 @@
             Argument::ARGUMENT_VALUE(manifestFilePath.c_str()));
     }
 
-    std::string value{};
+    std::vector<std::string> values{};
     std::ifstream efile;
     std::string line;
-    efile.exceptions(std::ifstream::failbit | std::ifstream::badbit |
-                     std::ifstream::eofbit);
+    efile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
 
     // Too many GCC bugs (53984, 66145) to do this the right way...
     try
@@ -61,19 +77,26 @@
             }
             if (line.compare(0, keySize, key) == 0)
             {
-                value = line.substr(keySize);
-                break;
+                values.push_back(line.substr(keySize));
             }
         }
         efile.close();
     }
     catch (const std::exception& e)
     {
-        error("Error occurred when reading MANIFEST file: {ERROR}", "KEY", key,
-              "ERROR", e);
+        if (!efile.eof())
+        {
+            error("Error occurred when reading MANIFEST file: {ERROR}", "KEY",
+                  key, "ERROR", e);
+        }
     }
 
-    return value;
+    if (values.empty())
+    {
+        error("No values found in MANIFEST file for key: {KEY}", "KEY", key);
+    }
+
+    return values;
 }
 
 using EVP_MD_CTX_Ptr =