1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#!/usr/bin/env python
def find_names_in_modules(modules):
names = set()
for module in modules:
try:
mod = __import__(module)
except:
pass
else:
names.union(dir(module))
return names
import optparse
import sys
import ctypesgencore
from ctypesgencore import messages as msgs
def option_callback_W(option, opt, value, parser):
# Options preceded by a "-Wl," are simply treated as though the "-Wl,"
# is not there? I don't understand the purpose of this code...
if len(value) < 4 or value[0:3] != 'l,-':
raise optparse.BadOptionError("not in '-Wl,<opt>' form: %s%s"
% (opt, value))
opt = value[2:]
if opt not in ['-L', '-R', '--rpath']:
raise optparse.BadOptionError("-Wl option must be -L, -R"
" or --rpath, not " + value[2:])
# Push the linker option onto the list for further parsing.
parser.rargs.insert(0, value)
def option_callback_libdir(option, opt, value, parser):
# There are two sets of linker search paths: those for use at compile time
# and those for use at runtime. Search paths specified with -L, -R, or
# --rpath are added to both sets.
parser.values.compile_libdirs.append(value)
parser.values.runtime_libdirs.append(value)
if __name__ == "__main__":
usage = 'usage: %prog [options] /path/to/header.h ...'
op = optparse.OptionParser(usage=usage)
# Parameters
op.add_option('-o', '--output', dest='output', metavar='FILE',
help='write wrapper to FILE')
op.add_option('-l', '--library', dest='libraries', action='append',
default=[], metavar='LIBRARY', help='link to LIBRARY')
op.add_option('', '--include', dest='other_headers', action='append',
default=[], metavar='HEADER',
help='include system header HEADER (e.g. stdio.h or stdlib.h)')
op.add_option('-m', '--module', '--link-module', action='append',
dest='modules', metavar='MODULE', default=[],
help='use symbols from Python module MODULE')
op.add_option('-I', '--includedir', dest='include_search_paths',
action='append', default=[], metavar='INCLUDEDIR',
help='add INCLUDEDIR as a directory to search for headers')
op.add_option('-W', action="callback", callback=option_callback_W,
metavar="l,OPTION", type="str",
help="where OPTION is -L, -R, or --rpath")
op.add_option("-L", "-R", "--rpath", "--libdir", action="callback",
callback=option_callback_libdir, metavar="LIBDIR", type="str",
help="Add LIBDIR to the search path (both compile-time and run-time)")
op.add_option('', "--compile-libdir", action="append",
dest="compile_libdirs", metavar="LIBDIR", default=[],
help="Add LIBDIR to the compile-time library search path.")
op.add_option('', "--runtime-libdir", action="append",
dest="runtime_libdirs", metavar="LIBDIR", default=[],
help="Add LIBDIR to the run-time library search path.")
# Parser options
op.add_option('', '--cpp', dest='cpp', default='gcc -E',
help='The command to invoke the c preprocessor, including any '
'necessary options (default: gcc -E)')
op.add_option('', '--save-preprocessed-headers', metavar='FILENAME',
dest='save_preprocessed_headers', default=None,
help='Save the preprocessed headers to the specified FILENAME')
# Processor options
op.add_option('-a', '--all-headers', action='store_true',
dest='all_headers', default=False,
help='include symbols from all headers, including system headers')
op.add_option('', '--builtin-symbols', action='store_true',
dest='builtin_symbols', default=False,
help='include symbols automatically generated by the preprocessor')
op.add_option('', '--no-macros', action='store_false', dest='include_macros',
default=True, help="Don't output macros.")
op.add_option('-i', '--include-symbols', dest='include_symbols',
default=None, help='regular expression for symbols to always include')
op.add_option('-x', '--exclude-symbols', dest='exclude_symbols',
default=None, help='regular expression for symbols to exclude')
# Printer options
op.add_option('', '--header-template', dest='header_template', default=None,
metavar='TEMPLATE',
help='Use TEMPLATE as the header template in the output file.')
op.add_option('', '--strip-build-path', dest='strip_build_path',
default=None, metavar='BUILD_PATH',
help='Strip build path from header paths in the wrapper file.')
op.add_option('', '--insert-file', dest='inserted_files', default=[],
action='append', metavar='FILENAME',
help='Add the contents of FILENAME to the end of the wrapper file.')
# Error options
op.add_option('', "--all-errors", action="store_true", default=False,
dest="show_all_errors", help="Display all warnings and errors even "
"if they would not affect output.")
op.add_option('', "--show-long-errors", action="store_true", default=False,
dest="show_long_errors", help="Display long error messages "
"instead of abbreviating error messages.")
op.add_option('', "--no-macro-warnings", action="store_false", default=True,
dest="show_macro_warnings", help="Do not print macro warnings.")
op.set_defaults(**ctypesgencore.options.default_values)
(options, args) = op.parse_args(list(sys.argv[1:]))
options.headers = args
# Figure out what names will be defined by imported Python modules
options.other_known_names = find_names_in_modules(options.modules)
# Required parameters
if len(args) < 1:
msgs.error_message('No header files specified', cls='usage')
sys.exit(1)
if options.output is None:
msgs.error_message('No output file specified', cls='usage')
sys.exit(1)
if len(options.libraries) == 0:
msgs.warning_message('No libraries specified', cls='usage')
# Step 1: Parse
descriptions = ctypesgencore.parser.parse(options.headers, options)
# Step 2: Process
ctypesgencore.processor.process(descriptions, options)
# Step 3: Print
ctypesgencore.printer.WrapperPrinter(options.output, options, descriptions)
msgs.status_message("Wrapping complete.")
# Correct what may be a common mistake
if descriptions.all == []:
if not options.all_headers:
msgs.warning_message("There wasn't anything of use in the "
"specified header file(s). Perhaps you meant to run with "
"--all-headers to include objects from included sub-headers? ",
cls='usage')
|