Generate arbitrary files from C/C++ header files using CppHeaderParser to read the input files and Jinja2 templates to generate the outputs.
This grew out of a desire to generate pybind11 wrapping code from C++ header files. pybind11gen was created, but then I wanted to generate more things...
There are still rough edges, and the documentation is mostly nonexistent, but pull requests with fixes/improvements are very welcome!
As of 0.3.0, h2w requires Python 3.3+
pip install header2whatever
First, you need to create a jinja2 template that represents whatever you want to generate from the header file. For example, maybe you want to describe the functions in yaml:
---
{% for header in headers %}
{% for fn in header.functions %}
{{ fn.name }}:
returns: {{ fn.returns }}
params:
{% for param in fn.parameters %}
- { name: {{ param.name }}, type: "{{ param.type }}" }
{% endfor %}
{% endfor %}
{% endfor %}
And let's say you have the following header file foo.h:
void some_fn(int i); int returns_int(int p1, char* p2);
You can execute the following:
h2w foo.h -o foo.yml
And you'll get the following output:
---
returns_int:
returns: int
params:
- { name: p1, type: "int" }
- { name: p2, type: "char *" }
some_fn:
returns: void
params:
- { name: i, type: "int" }
As you can see, while this is a silly example, this approach is very flexible and fairly powerful.
Currently, the data structure passed to the template isn't documented -- but it's a filtered version of whatever CppHeaderParser outputs when it parses a header.
See the examples folder for more examples.
If you need to process multiple files, or just want to record the parameters for autogenerating a file without writing a shell script, batch mode is useful. You pass two parameters: a yaml file with the configuration, and an output directory to write the files to.
Sometimes you want to mix in data that CppHeaderParser can't give you. If you
pass the --yaml option, it will load the yaml into a dictionary and make it
available to the template as the 'data' variable.
You can also pass key=value parameters via the --param option, and
the specified keys will be available to the template.
When you need to do more complex logic that a jinja2 template just isn't appropriate for, you can specify a python file to load custom hooks from.
See [the default hooks](header2whatever/default_hooks.py) for documentation.
Apache 2
Dustin Spicuzza (dustin@virtualroadside.com)