Filtering header content¶
A C/C++ header can contains different zone, some of which are parts of the public API, and some of which may correspond to specific low-level options.
litgen (and srcmlcpp) can filter a header based on preprocessor #ifdef / #ifndef occurrences.
Let’s look at an example header: its code is defined in the cpp_code variable below.
cpp_code = """
#ifndef MY_HEADER_H // This is an inclusion guard, it should not be filtered out
void Foo() {}
#ifdef ARCANE_OPTION
// We are entering a zone that handle arcane options that should not be included in the bindings
void Foo2() {}
#else
// this should also not be included in the bindings
void Foo3() {}
#endif
#ifdef COMMON_OPTION
// We are entering a zone for which we would like to publish bindings
void Foo4();
#endif
#endif // #ifndef MY_HEADER_H
"""Let’s try to generate bindings for it:
import litgen
from litgen.demo import litgen_demo
options = litgen.LitgenOptions()
litgen_demo.demo(options, cpp_code)We see that elements inside #ifdef ARCANE_OPTION were not processed. However, elements inside #ifdef COMMON_OPTION were not processed. Let’s correct this by adjusting the options:
options = litgen.LitgenOptions()
# the default value for header_filter_acceptable__regex was
# "__cplusplus|_h_$|_h$|_H$|_H_$|hpp$|HPP$|hxx$|HXX$"
# (which includes support for common header guards)
# Let's add support for COMMON_OPTION
options.srcmlcpp_options.header_filter_acceptable__regex = "_H$|^COMMON_OPTION$"
litgen_demo.demo(options, cpp_code)API Prefixes¶
In a given header files, function can have an “API Prefix”, that denotes whether they should be published or not in a shared library.
cpp_code = """
// This function has an API marker and is exported in a shared library
MY_API int add(int, int b);
// This function does not have an API marker, and is probably private
int mul(int a, int b);
"""You can set the API marker in the options:
options = litgen.LitgenOptions()
options.srcmlcpp_options.functions_api_prefixes = "MY_API"
litgen_demo.demo(options, cpp_code)You can also decide to export non API function, with an optional comment.
options = litgen.LitgenOptions()
options.srcmlcpp_options.functions_api_prefixes = "MY_API"
options.fn_exclude_non_api = False
options.fn_non_api_comment = "Private API!"
litgen_demo.demo(options, cpp_code)Header preprocessing¶
If you need to preprocess header code before the generation, you can create a function that transforms the source code, and store it inside options.srcmlcpp_options.code_preprocess_function.
For example:
def preprocess_change_int(code: str) -> str:
return code.replace("int", "Int32") # This is a *very* dumb preprocessor
cpp_code = """
int add(int, int b);
"""
options = litgen.LitgenOptions()
options.srcmlcpp_options.code_preprocess_function = preprocess_change_int
generated_code = litgen.generate_code(options, cpp_code)
litgen_demo.show_cpp_code(generated_code.stub_code)