Include namespaces in the phosphor-logging exception name

Currently the phosphor-logging exception name is for example
Device for an error file located in xyz/openbmc_project/Error/Callout/.
It should instead be named xyz.openbmc_project.Error.Callout.Device
following the naming structure of the sdbusplus++ tool
to differentiate it from other Device error exceptions.
With the full name, the namespaces can be determined, so there's no
need to pass the namespace parameter to the template that generates
the elog-errors.hpp. As with the name, follow the namespace
structure of the sdbusplus exception object.

Closes openbmc/phosphor-logging#2

Change-Id: I960d759d90aa18fd43211034ebd6009859113ee7
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/logging_test.cpp b/logging_test.cpp
index 96d2a36..ad51823 100644
--- a/logging_test.cpp
+++ b/logging_test.cpp
@@ -74,27 +74,28 @@
     const char *test_string = "/tmp/test_string/";
     try
     {
-        elog<example::xyz::openbmc_project::Example::TestErrorOne>(
-                example::xyz::openbmc_project::Example::TestErrorOne::
-                    ERRNUM(number),
-                example::xyz::openbmc_project::Example::TestErrorOne::
-                    FILE_PATH(test_string),
-                example::xyz::openbmc_project::Example::TestErrorOne::
-                    FILE_NAME("elog_test_3.txt"),
-                example::xyz::openbmc_project::Example::TestErrorTwo::
-                    DEV_ADDR(0xDEADDEAD),
-                example::xyz::openbmc_project::Example::TestErrorTwo::
-                    DEV_ID(100),
-                example::xyz::openbmc_project::Example::TestErrorTwo::
-                    DEV_NAME("test case 3"));
+        elog<example::xyz::openbmc_project::Example::Elog::Error::TestErrorOne>(
+                example::xyz::openbmc_project::Example::Elog::Error::
+                    TestErrorOne::ERRNUM(number),
+                example::xyz::openbmc_project::Example::Elog::Error::
+                    TestErrorOne::FILE_PATH(test_string),
+                example::xyz::openbmc_project::Example::Elog::Error::
+                    TestErrorOne::FILE_NAME("elog_test_3.txt"),
+                example::xyz::openbmc_project::Example::Elog::Error::
+                    TestErrorTwo::DEV_ADDR(0xDEADDEAD),
+                example::xyz::openbmc_project::Example::Elog::Error::
+                    TestErrorTwo::DEV_ID(100),
+                example::xyz::openbmc_project::Example::Elog::Error::
+                    TestErrorTwo::DEV_NAME("test case 3"));
     }
-    catch (elogException<example::xyz::openbmc_project::Example::TestErrorOne>& e)
+    catch (elogException<example::xyz::openbmc_project::Example::Elog::Error::
+           TestErrorOne>& e)
     {
         std::cout << "elog exception caught: " << e.what() << std::endl;
     }
 
     // Reduce our error namespaces
-    using namespace example::xyz::openbmc_project::Example;
+    using namespace example::xyz::openbmc_project::Example::Elog::Error;
 
     // Now read back and verify our data made it into the journal
     std::stringstream stream;
@@ -192,5 +193,3 @@
 
     return 0;
 }
-
-
diff --git a/tools/elog-gen.py b/tools/elog-gen.py
index 360ae11..0452489 100755
--- a/tools/elog-gen.py
+++ b/tools/elog-gen.py
@@ -56,17 +56,23 @@
     return True
 
 
+# Return the yaml files with their directory structure plus the file name
+# without the yaml extension, which will be used to set the namespaces.
+# Ex: file xyz/openbmc_project/Error/Callout/Device.errors.yaml
+# will have namespce xyz/openbmc_project/Error/Callout/Device
 def get_error_yaml_files(i_yaml_dir, i_test_dir):
     yaml_files = dict()
     if i_yaml_dir != "None":
         for root, dirs, files in os.walk(i_yaml_dir):
             for files in filter(lambda file:
                                 file.endswith('.errors.yaml'), files):
-                splitdir = root.split(i_yaml_dir)[1]
+                splitdir = root.split(i_yaml_dir)[1] + "/" + files[:-12]
+                if splitdir.startswith("/"):
+                    splitdir = splitdir[1:]
                 yaml_files[(os.path.join(root, files))] = splitdir
     for root, dirs, files in os.walk(i_test_dir):
         for files in filter(lambda file: file.endswith('.errors.yaml'), files):
-            splitdir = root.split(i_test_dir)[1]
+            splitdir = root.split(i_test_dir)[1] + "/" + files[:-12]
             yaml_files[(os.path.join(root, files))] = splitdir
     return yaml_files
 
@@ -114,7 +120,6 @@
     meta = dict()  # The meta data names associated (ERRNO, FILE_NAME, ...)
     meta_data = dict()  # The meta data info (type, format)
     parents = dict()
-    namespace = dict()
 
     error_yamls = get_error_yaml_files(i_yaml_dir, i_test_dir)
 
@@ -145,8 +150,7 @@
                        error_lvl,
                        meta,
                        meta_data,
-                       parents,
-                       namespace))
+                       parents))
 
     if(not check_error_inheritance(errors, parents)):
         print("Error - failed to validate error inheritance")
@@ -162,7 +166,7 @@
     f.write(template.render(
             errors=errors, error_msg=error_msg,
             error_lvl=error_lvl, meta=meta,
-            meta_data=meta_data, error_namespace=namespace,
+            meta_data=meta_data,
             parents=parents))
     f.close()
 
@@ -181,8 +185,7 @@
     i_namespace                 namespace data
     o_elog_data                 error metadata
     """
-    errors, error_msg, error_lvl, meta, meta_data, parents, namespace = \
-        o_elog_data
+    errors, error_msg, error_lvl, meta, meta_data, parents = o_elog_data
     ifile = yaml.safe_load(open(i_elog_yaml))
     mfile = yaml.safe_load(open(i_elog_meta_yaml))
     for i in mfile:
@@ -196,19 +199,19 @@
             print("Error - Did not find meta data for " + i['name'])
             exit(1)
         # Grab the main error and it's info
-        errors.append(i['name'])
+        fullname = i_namespace.replace('/', '.') + ('.') + i['name']
+        errors.append(fullname)
         parent = None
         if('inherits' in i):
-            # xyz.openbmc.Foo, we need Foo
             # Get 0th inherited error (current support - single inheritance)
-            parent = i['inherits'][0].split(".").pop()
-        parents[i['name']] = parent
-        error_msg[i['name']] = match['description']
+            parent = i['inherits'][0]
+        parents[fullname] = parent
+        error_msg[fullname] = match['description']
         try:
-            error_lvl[i['name']] = i['level']
+            error_lvl[fullname] = i['level']
         except:
             print ("No level found for: " + i['name'] + ", using INFO")
-            error_lvl[i['name']] = "INFO"
+            error_lvl[fullname] = "INFO"
         tmp_meta = []
         # grab all the meta data fields and info
         for j in i['meta']:
@@ -218,8 +221,7 @@
             meta_data[str_short]['str'] = j['str']
             meta_data[str_short]['str_short'] = str_short
             meta_data[str_short]['type'] = get_cpp_type(j['type'])
-        meta[i['name']] = tmp_meta
-        namespace[i['name']] = i_namespace
+        meta[fullname] = tmp_meta
 
     # Debug
     # for i in errors:
diff --git a/tools/example/xyz/openbmc_project/Example/Bar.metadata.yaml b/tools/example/xyz/openbmc_project/Example/Bar.metadata.yaml
index bc7381a..c5c57ca 100644
--- a/tools/example/xyz/openbmc_project/Example/Bar.metadata.yaml
+++ b/tools/example/xyz/openbmc_project/Example/Bar.metadata.yaml
@@ -4,4 +4,4 @@
     - str: "BAR_DATA=%s"
       type: string
   inherits:
-    - Foo
+    - example.xyz.openbmc_project.Example.Foo.Foo
diff --git a/tools/example/xyz/openbmc_project/Example/Elog.metadata.yaml b/tools/example/xyz/openbmc_project/Example/Elog.metadata.yaml
index f0838e0..5b027e1 100644
--- a/tools/example/xyz/openbmc_project/Example/Elog.metadata.yaml
+++ b/tools/example/xyz/openbmc_project/Example/Elog.metadata.yaml
@@ -8,7 +8,7 @@
     - str: FILE_NAME=%s
       type: string
   inherits:
-    - TestErrorTwo
+    - example.xyz.openbmc_project.Example.Elog.TestErrorTwo
 
 - name: TestErrorTwo
   level: ERR
diff --git a/tools/example/xyz/openbmc_project/Example/Foo.metadata.yaml b/tools/example/xyz/openbmc_project/Example/Foo.metadata.yaml
index 02963aa..5fe2f13 100644
--- a/tools/example/xyz/openbmc_project/Example/Foo.metadata.yaml
+++ b/tools/example/xyz/openbmc_project/Example/Foo.metadata.yaml
@@ -4,4 +4,4 @@
     - str: "FOO_DATA=%s"
       type: string
   inherits:
-    - example.xyz.openbmc_project.Example.TestErrorOne
+    - example.xyz.openbmc_project.Example.Elog.TestErrorOne
diff --git a/tools/phosphor-logging/templates/elog-gen-template.mako.hpp b/tools/phosphor-logging/templates/elog-gen-template.mako.hpp
index 097b865..181d4bd 100644
--- a/tools/phosphor-logging/templates/elog-gen-template.mako.hpp
+++ b/tools/phosphor-logging/templates/elog-gen-template.mako.hpp
@@ -17,17 +17,19 @@
 
     % for index, name in enumerate(errors):
 <%
-    namespaces = error_namespace[name].split('/')
-    ## In case someone provided a error_namespace ending with '/', remove the
-    ## last split string, which would be an empty string.
-    if not namespaces[-1]:
-        namespaces = namespaces[:-1]
-    classname = name
+    ## Ex: name: xyz.openbmc_project.Error.Callout.Device
+    namespaces = name.split('.')
+    ## classname is the last name item (Device)
+    classname = namespaces[-1]
+    ## namespaces are all the name items except the last one
+    namespaces = namespaces[:-1]
 %>\
     % for s in namespaces:
 namespace ${s}
 {
     % endfor
+namespace Error
+{
 namespace _${classname}
 {
     % for b in meta[name]:
@@ -48,7 +50,13 @@
 
     parent = parents[name]
     while parent:
-        parent_meta += [parent + "::" + p for p in meta[parent]]
+        tmpparent = parent.split('.')
+        ## Name is the last item
+        parent_name = tmpparent[-1]
+        ## namespaces are all the name items except the last one
+        parent_namespace = '::'.join(tmpparent[:-1])
+        parent_meta += [parent_namespace + "::Error::" + parent_name + "::" +
+                        p for p in meta[parent]]
         parent_meta_short = ', '.join(meta[parent])
         meta_string = meta_string + ", " + parent_meta_short
         parent = parents[parent]
@@ -66,6 +74,8 @@
     % endfor
     using metadata_types = std::tuple<${meta_string}>;
 };
+
+} // namespace Error
 % for s in reversed(namespaces):
 } // namespace ${s}
 % endfor