sdbus++: create script to generate all files from a dir

Meson doesn't handle generating code in the style that sdbus++
has, so we're going to need a script of some part as a helper.
Create a script that can generate all sdbus++ parts by looking
at a directory for YAML files.

phosphor-dbus-interfaces has similar scripts already that generate
autotools makefiles[1] and gnome has scripts like this to workaround
meson limitations[2].  Having sdbusplus provide this will hopefully
reduce duplication for other repositories.

1. https://github.com/openbmc/phosphor-dbus-interfaces/blob/5fd7574b59acfce023b892a995e0c87b13c5ab4c/generate_makefile.sh
2. https://github.com/gtkd-developers/GlibD/blob/b09fb1411378b98c3c035038863c5def6a4a0774/meson.build#L32

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ifd3cc04a10937c06dc20fe3d447a54e6f45b672a
diff --git a/tools/sdbus++-gendir b/tools/sdbus++-gendir
new file mode 100755
index 0000000..bc60ca0
--- /dev/null
+++ b/tools/sdbus++-gendir
@@ -0,0 +1,126 @@
+#!/usr/bin/env bash
+
+set -e
+
+function show_usage {
+    echo "Usage: $0 [options] <dirs>+"
+    echo
+    echo "Generate the sdbus++ sources from a directory path."
+    echo
+    echo "Options:"
+    echo "    --tool <path>    - path to processing tool (default 'sdbus++')."
+    echo "    --output <path>  - directory to place output files (default '.')."
+    echo "    --list-all       - include all generated files in stdout list."
+    echo "    <dirs>+          - any number of subdirectories to generate."
+    echo
+    echo "The output on stdout is a list of generated files, which is intended"
+    echo "to be consumed by build systems, such as Meson."
+    echo
+    echo "This tool, by default, generates all files that are able to be"
+    echo "created by sdbus++.  The output is a list of compilable sources that"
+    echo "were generated by the tool.  The tool may generate outputs which are"
+    echo "not able to be compiled, such as documentation, but it does not put"
+    echo "them into stdout unless --list-all is given."
+}
+
+sdbuspp="sdbus++"
+outputdir="."
+listall="no"
+
+options="$(getopt -o ho:t: --long help,list-all,output:,tool: -- "$@")"
+eval set -- "$options"
+
+while true; do
+    case "$1" in
+        -h | --help)
+            show_usage
+            exit
+            ;;
+
+        --list-all)
+            listall="yes"
+            shift
+            ;;
+
+        -o | --output)
+            shift
+            outputdir="$1";
+            shift
+            ;;
+
+        -t | --tool)
+            shift
+            sdbuspp="$1";
+            shift
+            ;;
+
+        --)
+            shift
+            break
+            ;;
+
+        *)
+            break
+            ;;
+    esac
+done
+
+if [ "x" == "x$@" ];
+then
+    show_usage
+    exit 1
+fi
+
+for d in $@;
+do
+    interfaces="$(find $d -name '*.interface.yaml')"
+
+    for i in $interfaces;
+    do
+        path="${i%.interface.yaml}"
+        iface="${path//\//.}"
+
+        mkdir -p $outputdir/$path
+
+        $sdbuspp interface server-header $iface > $outputdir/$path/server.hpp
+        echo $outputdir/$path/server.hpp
+
+        $sdbuspp interface server-cpp $iface > $outputdir/$path/server.cpp
+        echo $outputdir/$path/server.cpp
+
+        $sdbuspp interface client-header $iface > $outputdir/$path/client.hpp
+        echo $outputdir/$path/client.hpp
+
+        $sdbuspp interface markdown $iface > $outputdir/$path.md
+        # markdown files aren't recognized as source files by meson, so don't
+        # emit them by default.
+        if [ "xyes" == "x$listall" ];
+        then
+            echo $outputdir/$path.md
+        fi
+    done
+
+    errors="$(find $d -name '*.errors.yaml')"
+
+    for e in $errors;
+    do
+        path="${e%.errors.yaml}"
+        iface="${path//\//.}"
+
+        mkdir -p $outputdir/$path
+
+        $sdbuspp error exception-header $iface > $outputdir/$path/error.hpp
+        echo $outputdir/$path/error.hpp
+
+        $sdbuspp error exception-cpp $iface > $outputdir/$path/error.cpp
+        echo $outputdir/$path/error.cpp
+
+        $sdbuspp error markdown $iface >> $outputdir/$path.md
+        # markdown files aren't recognized as source files by meson, so don't
+        # emit them by default.
+        if [ "xyes" == "x$listall" ];
+        then
+            echo $outputdir/$path.md
+        fi
+    done
+done
diff --git a/tools/setup.py b/tools/setup.py
index 6e5357d..5404d7b 100755
--- a/tools/setup.py
+++ b/tools/setup.py
@@ -6,7 +6,7 @@
     version="1.0",
     packages=find_packages(),
     install_requires=["inflection", "mako", "pyyaml"],
-    scripts=["sdbus++"],
+    scripts=["sdbus++", "sdbus++-gendir"],
     package_data={"sdbusplus": ["templates/*.mako.*"]},
     url="http://github.com/openbmc/sdbusplus",
     classifiers=["License :: OSI Approved :: Apache Software License"],