sdbus++: Generate includes for enum references

It is common for enums to be shared across different dbus definitions.
This change adds the functionality to automatically generate the correct
includes for the server.hpp files.

Change-Id: Ic5b8df55b58479d18dd4aee20ead9c05b867b968
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/tools/sdbusplus/interface.py b/tools/sdbusplus/interface.py
index b9def8d..29f41e4 100644
--- a/tools/sdbusplus/interface.py
+++ b/tools/sdbusplus/interface.py
@@ -32,6 +32,26 @@
 
         super(Interface, self).__init__(**kwargs)
 
+    def enum_includes(self, l):
+        includes = []
+        for e in l:
+            es = e.enum_namespace(self.name).split('::')
+            # Skip empty, non-enum values and self references like '::'
+            if len(es) < 2:
+                continue
+            # All elements will be formatted (x::)+
+            # If the requested enum is xyz.openbmc_project.Network.IP.Protocol
+            # for a server_* configuration, the enum_namespace will be
+            # xyz::openbmc_project::Network::server::IP:: and we need to
+            # convert to xyz/openbmc_project/Network/IP/server.hpp
+            es.pop()  # Remove trailing empty element
+            e_class = es.pop() # Remove class name
+            e_type = es.pop()  # Remove injected type namespace
+            es.append(e_class)
+            es.append(e_type)
+            includes.append('/'.join(es) + '.hpp')
+        return includes
+
     def markdown(self, loader):
         return self.render(loader, "interface.mako.md", interface=self)
 
diff --git a/tools/sdbusplus/templates/method.mako.prototype.hpp.in b/tools/sdbusplus/templates/method.mako.prototype.hpp.in
index 2053b1c..fa88e30 100644
--- a/tools/sdbusplus/templates/method.mako.prototype.hpp.in
+++ b/tools/sdbusplus/templates/method.mako.prototype.hpp.in
@@ -199,4 +199,8 @@
         % for e in method.errors:
 #include <${error_include(e)}>
         % endfor
+    % elif ptype == 'callback-hpp-includes':
+        % for i in interface.enum_includes(method.returns + method.parameters):
+#include <${i}>
+        % endfor
     % endif
diff --git a/tools/sdbusplus/templates/property.mako.prototype.hpp.in b/tools/sdbusplus/templates/property.mako.prototype.hpp.in
index 4e280f6..4d9a56e 100644
--- a/tools/sdbusplus/templates/property.mako.prototype.hpp.in
+++ b/tools/sdbusplus/templates/property.mako.prototype.hpp.in
@@ -143,4 +143,8 @@
         % for e in property.errors:
 #include <${error_include(e)}>
         % endfor
+% elif ptype == 'callback-hpp-includes':
+        % for i in interface.enum_includes([property]):
+#include <${i}>
+        % endfor
 % endif
diff --git a/tools/sdbusplus/templates/signal.mako.prototype.hpp b/tools/sdbusplus/templates/signal.mako.prototype.hpp
index e547310..048eedb 100644
--- a/tools/sdbusplus/templates/signal.mako.prototype.hpp
+++ b/tools/sdbusplus/templates/signal.mako.prototype.hpp
@@ -78,4 +78,8 @@
     % endif
 }
 }
+    % elif ptype == 'callback-hpp-includes':
+        % for i in interface.enum_includes(signal.properties):
+#include <${i}>
+        % endfor
     % endif