config_parser: Split up sections

We can't always combine sections together in network files as sections
like

[Address]
Address=::1/128
Peer=fe80::1
[Address]
Address=::2/128
Peer=fe80::2

Require that they are grouped accordingly. Rewrite the storage logic of
the config parser to support this logical organization.

Change-Id: I34ae1523202f8770fe3dcac010fb6226dd28b9ec
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/config_parser.cpp b/src/config_parser.cpp
index 27a7b15..80f71e7 100644
--- a/src/config_parser.cpp
+++ b/src/config_parser.cpp
@@ -8,6 +8,7 @@
 #include <stdplus/exception.hpp>
 #include <stdplus/fd/create.hpp>
 #include <stdplus/fd/line.hpp>
+#include <string>
 #include <utility>
 
 namespace phosphor
@@ -50,30 +51,39 @@
     return dir / fmt::format(FMT_COMPILE("{}.netdev"), intf);
 }
 
+const std::string*
+    SectionMap::getLastValueString(std::string_view section,
+                                   std::string_view key) const noexcept
+{
+    auto sit = find(section);
+    if (sit == end())
+    {
+        return nullptr;
+    }
+    for (auto it = sit->second.rbegin(); it != sit->second.rend(); ++it)
+    {
+        auto kit = it->find(key);
+        if (kit == it->end() || kit->second.empty())
+        {
+            continue;
+        }
+        return &kit->second.back();
+    }
+    return nullptr;
+}
+
+std::vector<std::string> SectionMap::getValueStrings(std::string_view section,
+                                                     std::string_view key) const
+{
+    return getValues(section, key,
+                     [](const Value& v) { return std::string(v); });
+}
+
 Parser::Parser(const fs::path& filename)
 {
     setFile(filename);
 }
 
-const ValueList& Parser::getValues(std::string_view section,
-                                   std::string_view key) const noexcept
-{
-    static const ValueList empty;
-    auto sit = sections.find(section);
-    if (sit == sections.end())
-    {
-        return empty;
-    }
-
-    auto kit = sit->second.find(key);
-    if (kit == sit->second.end())
-    {
-        return empty;
-    }
-
-    return kit->second;
-}
-
 inline bool isspace(char c) noexcept
 {
     return c == ' ' || c == '\t';
@@ -136,9 +146,9 @@
         if (it == sections.end())
         {
             std::tie(it, std::ignore) =
-                sections.emplace(Section(s), KeyValuesMap{});
+                sections.emplace(Section(s), KeyValuesMapList{});
         }
-        section = &it->second;
+        section = &it->second.emplace_back();
     }
 
     void pumpKV(std::string_view line)