diff --git a/src/ctypesgen/__main__.py b/src/ctypesgen/__main__.py index facfa93..ae49ae3 100644 --- a/src/ctypesgen/__main__.py +++ b/src/ctypesgen/__main__.py @@ -22,12 +22,51 @@ def main(given_argv=sys.argv[1:]): args = get_parser().parse_args(given_argv) - api_main(args, given_argv) + main_impl(args, given_argv) -# -- Pure API entry point -- +# -- API entrypoint with defaults -- -def api_main(args, given_argv=[]): +# This function is experimental and not officially supported. Use at own risk. +# API callers should preferably go through argparse-based main() where possible. + +def api_main(args): + + parser = get_parser() + + required_args = _get_parser_requires(parser) + defaults = _get_parser_defaults(parser) + print(required_args, defaults, args, sep="\n", file=sys.stderr) + + assert all(r in args for r in required_args), f"Must provide all required arguments: {required_args}" + + real_args = defaults.copy() + real_args.update(args) + real_args = argparse.Namespace(**real_args) + + return main_impl(real_args, given_argv=[]) + + +# Adapted from https://stackoverflow.com/a/59395868/15547292 + +def _get_parser_defaults(parser): + defaults = {} + for action in parser._actions: + if not action.required and action.dest != "help": + defaults[action.dest] = action.default + return defaults + +def _get_parser_requires(parser): + required = [] + for action in parser._actions: + if action.required: + required.append(action.dest) + return required + + +# -- Main implementation -- + +def main_impl(args, given_argv): assert args.headers or args.system_headers, "Either --headers or --system-headers required." @@ -70,7 +109,7 @@ def api_main(args, given_argv=[]): msgs.status_message("Wrapping complete.") -# -- Helper functions for api_main() -- +# -- Helper functions for main_impl() -- def find_symbols_in_modules(modnames, outpath, anchor):