mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
76 lines
2.9 KiB
Markdown
76 lines
2.9 KiB
Markdown
|
|
# inject_pydoc.py
|
|
|
|
This tool is in charge extracting information from the C++ SDK
|
|
headers, and inject it into IDAPython's documentation.
|
|
|
|
## Extracting the C++ SDK information/documentation
|
|
|
|
The IDAPython build system will run `doxygen` against the SDK headers,
|
|
asking it to output all the information it could extract, as `XML`
|
|
format for later use - by `inject_pydoc.py`, but not only…
|
|
|
|
## Applying the documentation
|
|
|
|
Then, we run `tools/inject_pydoc.py`, to process that `XML`
|
|
content and extract documentation about the functions, classes,
|
|
methods, variables, etc… that are present in the corresponding
|
|
IDAPython module.
|
|
|
|
## Fixing the input parameters
|
|
|
|
We cannot blindly apply the SDK documentation, however: some C++
|
|
function parameters will turn into output values when converted to
|
|
Python, and thus it makes no sense to have those parameters as part of
|
|
the IDAPython function documentation. For example, when wrapping
|
|
|
|
inline void get_registered_actions(qstrvec_t *out)
|
|
|
|
into `ida_kernwin.get_registered_actions`, the `out` parameter will
|
|
turn into a `list(str)`, so it makes no sense to see the corresponding
|
|
C++ header's documentation:
|
|
|
|
/// \param out the list of actions to be filled
|
|
|
|
into the IDAPython documentation.
|
|
|
|
Fortunately, we can rely on SWiG's help to do that, because even
|
|
though SWiG doesn't know how to import C++ header's documentation, it
|
|
*will* tell us what parameters are present in the wrapped prototype.
|
|
|
|
Therefore, we collect the SWiG-generated list of parameters from the
|
|
prototype, and simply remove the non-relevant bits from the C++
|
|
header's documentation before injecting that into IDAPython.
|
|
|
|
## Fixing the return values
|
|
|
|
Because all of that was too easy, IDAPython adds another layer of
|
|
complexity (craziness?) for fixing the return values.
|
|
|
|
When it comes to the input parameters, it's actually _fairly_ easy to
|
|
drop the irrelevant bits from the C++ SDK header's documentation: we
|
|
know what parameters SWiG will keep & wrap.
|
|
|
|
But for the return values, it's another story entirely: SWiG doesn't
|
|
know (and cannot always reliably know) what type a return value will
|
|
have.
|
|
In particular when it comes to custom code in `pywraps/` that returns
|
|
a `PyObject *`.
|
|
|
|
Therefore, we have put a mechanism into place, that lets us put a
|
|
"wrapper" around _all_ IDAPython functions/class methods, that will
|
|
trace/keep track of the types of the values that were passed in, and
|
|
the types of the values that were spit out by those functions.
|
|
|
|
We can then use that wrapper when running tests, collect information
|
|
from the tests that were run, process that information, and save it
|
|
into `tools/collected_traces.txt`, which will then be used by
|
|
`inject_pydoc.py`.
|
|
|
|
It's worth pointing out that that information is not, and could not
|
|
possibly, be generated at build-time: it must be done at another time
|
|
(e.g., after running tests), which is very different than the
|
|
mechanism used for fixing the parameters (that "simply" relies on the
|
|
`doxygen`-parsed `XML`-formatted documentation.)
|
|
|