sdbus++: generate error cpp

Change-Id: I63ea5ea07ab4efb0da21ee10de7fe9db429c1ffd
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/tools/sdbus++ b/tools/sdbus++
index db96b1f..28c2858 100755
--- a/tools/sdbus++
+++ b/tools/sdbus++
@@ -14,7 +14,8 @@
     valid_processes = {'markdown': "markdown",
                        'server-header': "server_header",
                        'server-cpp': "server_cpp",
-                       'exception-header': "exception_header"}
+                       'exception-header': "exception_header",
+                       'exception-cpp': "exception_cpp"}
 
     parser = argparse.ArgumentParser(description='Process sdbus++ YAML files.')
 
diff --git a/tools/sdbusplus/error.py b/tools/sdbusplus/error.py
index c67eee0..55f5e6a 100644
--- a/tools/sdbusplus/error.py
+++ b/tools/sdbusplus/error.py
@@ -25,3 +25,6 @@
 
     def exception_header(self, loader):
         return self.render(loader, "error.mako.hpp", error=self)
+
+    def exception_cpp(self, loader):
+        return self.render(loader, "error.mako.cpp", error=self)
diff --git a/tools/sdbusplus/templates/error.mako.cpp b/tools/sdbusplus/templates/error.mako.cpp
new file mode 100644
index 0000000..933ddcb
--- /dev/null
+++ b/tools/sdbusplus/templates/error.mako.cpp
@@ -0,0 +1,22 @@
+#include <${ '/'.join(error.name.split('.')) }/error.hpp>
+<% namespaces = error.name.split('.') %>
+namespace sdbusplus
+{
+    % for s in namespaces:
+namespace ${s}
+{
+    % endfor
+namespace common
+{
+    % for e in error.errors:
+const char* ${e.name}::what() const noexcept
+{
+    return name;
+}
+    % endfor
+
+} // namespace common
+    % for s in reversed(namespaces):
+} // namespace ${s}
+    % endfor
+} // namespace sdbusplus