summaryrefslogtreecommitdiff
path: root/giscanner/scannermain.py
diff options
context:
space:
mode:
Diffstat (limited to 'giscanner/scannermain.py')
-rwxr-xr-xgiscanner/scannermain.py102
1 files changed, 78 insertions, 24 deletions
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index 794cede3..00dc30d6 100755
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -38,12 +38,30 @@ from giscanner.girparser import GIRParser
from giscanner.girwriter import GIRWriter
from giscanner.maintransformer import MainTransformer
from giscanner.shlibs import resolve_shlibs
-from giscanner.sourcescanner import SourceScanner
+from giscanner.sourcescanner import SourceScanner, ALL_EXTS
from giscanner.transformer import Transformer
from . import utils
+
+def process_cflags_begin(option, opt, value, parser):
+ cflags = getattr(parser.values, option.dest)
+ while len(parser.rargs) > 0 and parser.rargs[0] != '--cflags-end':
+ cflags.append(parser.rargs.pop(0))
+
+
+def process_cflags_end(option, opt, value, parser):
+ pass
+
+
def get_preprocessor_option_group(parser):
group = optparse.OptionGroup(parser, "Preprocessor options")
+ group.add_option("", "--cflags-begin",
+ help="Start preprocessor/compiler flags",
+ dest="cflags", default=[],
+ action="callback", callback=process_cflags_begin)
+ group.add_option("", "--cflags-end",
+ help="End preprocessor/compiler flags",
+ action="callback", callback=process_cflags_end)
group.add_option("-I", help="Pre-processor include file",
action="append", dest="cpp_includes",
default=[])
@@ -56,6 +74,7 @@ def get_preprocessor_option_group(parser):
group.add_option("-p", dest="", help="Ignored")
return group
+
def get_windows_option_group(parser):
group = optparse.OptionGroup(parser, "Machine Dependent Options")
group.add_option("-m", help="some machine dependent option",
@@ -64,13 +83,13 @@ def get_windows_option_group(parser):
return group
+
def _get_option_parser():
parser = optparse.OptionParser('%prog [options] sources')
parser.add_option('', "--quiet",
action="store_true", dest="quiet",
default=False,
- help="If passed, do not print details of normal" \
- + " operation")
+ help="If passed, do not print details of normal operation")
parser.add_option("", "--format",
action="store", dest="format",
default="gir",
@@ -158,6 +177,9 @@ match the namespace prefix.""")
parser.add_option("", "--c-include",
action="append", dest="c_includes", default=[],
help="headers which should be included in C programs")
+ parser.add_option("", "--filelist",
+ action="store", dest="filelist", default=[],
+ help="file containing headers and sources to be scanned")
group = get_preprocessor_option_group(parser)
parser.add_option_group(group)
@@ -186,17 +208,15 @@ match the namespace prefix.""")
def _error(msg):
raise SystemExit('ERROR: %s' % (msg, ))
+
def passthrough_gir(path, f):
parser = GIRParser()
parser.parse(path)
- writer = GIRWriter(parser.get_namespace(),
- parser.get_shared_libraries(),
- parser.get_includes(),
- parser.get_pkgconfig_packages(),
- parser.get_c_includes())
+ writer = GIRWriter(parser.get_namespace())
f.write(writer.get_xml())
+
def test_codegen(optstring):
(namespace, out_h_filename, out_c_filename) = optstring.split(',')
if namespace == 'Everything':
@@ -207,6 +227,7 @@ def test_codegen(optstring):
_error("Invaild namespace %r" % (namespace, ))
return 0
+
def process_options(output, allowed_flags):
for option in output.split():
for flag in allowed_flags:
@@ -215,6 +236,7 @@ def process_options(output, allowed_flags):
yield option
break
+
def process_packages(options, packages):
args = ['pkg-config', '--cflags']
args.extend(packages)
@@ -234,15 +256,13 @@ def process_packages(options, packages):
options.cpp_defines.extend(pkg_options.cpp_defines)
options.cpp_undefines.extend(pkg_options.cpp_undefines)
+
def extract_filenames(args):
filenames = []
for arg in args:
# We don't support real C++ parsing yet, but we should be able
# to understand C API implemented in C++ files.
- if (arg.endswith('.c') or arg.endswith('.cpp') or
- arg.endswith('.cc') or arg.endswith('.cxx') or
- arg.endswith('.h') or arg.endswith('.hpp') or
- arg.endswith('.hxx')):
+ if os.path.splitext(arg)[1] in ALL_EXTS:
if not os.path.exists(arg):
_error('%s: no such a file or directory' % (arg, ))
# Make absolute, because we do comparisons inside scannerparser.c
@@ -250,6 +270,29 @@ def extract_filenames(args):
filenames.append(os.path.abspath(arg))
return filenames
+
+def extract_filelist(options):
+ filenames = []
+ if not os.path.exists(options.filelist):
+ _error('%s: no such filelist file' % (options.filelist, ))
+ filelist_file = open(options.filelist, "r")
+ lines = filelist_file.readlines()
+ for line in lines:
+ # We don't support real C++ parsing yet, but we should be able
+ # to understand C API implemented in C++ files.
+ filename = line.strip()
+ if (filename.endswith('.c') or filename.endswith('.cpp')
+ or filename.endswith('.cc') or filename.endswith('.cxx')
+ or filename.endswith('.h') or filename.endswith('.hpp')
+ or filename.endswith('.hxx')):
+ if not os.path.exists(filename):
+ _error('%s: Invalid filelist entry-no such file or directory' % (line, ))
+ # Make absolute, because we do comparisons inside scannerparser.c
+ # against the absolute path that cpp will give us
+ filenames.append(os.path.abspath(filename))
+ return filenames
+
+
def create_namespace(options):
if options.strip_prefix:
print """g-ir-scanner: warning: Option --strip-prefix has been deprecated;
@@ -278,6 +321,7 @@ see --identifier-prefix and --symbol-prefix."""
identifier_prefixes=identifier_prefixes,
symbol_prefixes=symbol_prefixes)
+
def create_transformer(namespace, options):
transformer = Transformer(namespace,
accept_unprefixed=options.accept_unprefixed)
@@ -286,7 +330,6 @@ def create_transformer(namespace, options):
transformer.disable_cache()
transformer.set_passthrough_mode()
- shown_include_warning = False
for include in options.includes:
if os.sep in include:
_error("Invalid include path %r" % (include, ))
@@ -300,6 +343,7 @@ def create_transformer(namespace, options):
return transformer
+
def create_binary(transformer, options, args):
# Transform the C AST nodes into higher level
# GLib/GObject nodes
@@ -310,7 +354,7 @@ def create_binary(transformer, options, args):
gdump_parser.init_parse()
if options.program:
- args=[options.program]
+ args = [options.program]
args.extend(options.program_args)
binary = IntrospectionBinary(args)
else:
@@ -323,19 +367,25 @@ def create_binary(transformer, options, args):
gdump_parser.parse()
return shlibs
+
def create_source_scanner(options, args):
- filenames = extract_filenames(args)
+ if hasattr(options, 'filelist') and options.filelist:
+ filenames = extract_filelist(options)
+ else:
+ filenames = extract_filenames(args)
# Run the preprocessor, tokenize and construct simple
# objects representing the raw C symbols
ss = SourceScanner()
ss.set_cpp_options(options.cpp_includes,
options.cpp_defines,
- options.cpp_undefines)
+ options.cpp_undefines,
+ cflags=options.cflags)
ss.parse_files(filenames)
ss.parse_macros(filenames)
return ss
+
def write_output(data, options):
if options.output == "-":
output = sys.stdout
@@ -355,7 +405,7 @@ def write_output(data, options):
os.unlink(temp_f_name)
try:
shutil.move(main_f_name, options.output)
- except OSError, e:
+ except OSError as e:
if e.errno == errno.EPERM:
os.unlink(main_f_name)
return 0
@@ -364,14 +414,15 @@ def write_output(data, options):
else:
try:
output = open(options.output, "w")
- except IOError, e:
+ except IOError as e:
_error("opening output for writing: %s" % (e.strerror, ))
try:
output.write(data)
- except IOError, e:
+ except IOError as e:
_error("while writing output: %s" % (e.strerror, ))
+
def scanner_main(args):
parser = _get_option_parser()
(options, args) = parser.parse_args(args)
@@ -381,8 +432,9 @@ def scanner_main(args):
if options.test_codegen:
return test_codegen(options.test_codegen)
- if len(args) <= 1:
- _error('Need at least one filename')
+ if hasattr(options, 'filelist') and not options.filelist:
+ if len(args) <= 1:
+ _error('Need at least one filename')
if not options.namespace_name:
_error('Namespace name missing')
@@ -416,7 +468,6 @@ def scanner_main(args):
blocks = ap.parse(ss.get_comments())
# Transform the C symbols into AST nodes
- transformer.set_annotations(blocks)
transformer.parse(ss.get_symbols())
if not options.header_only:
@@ -424,6 +475,8 @@ def scanner_main(args):
else:
shlibs = []
+ transformer.namespace.shared_libraries = shlibs
+
main = MainTransformer(transformer, blocks)
main.transform()
@@ -446,8 +499,9 @@ def scanner_main(args):
else:
exported_packages = options.packages
- writer = Writer(transformer.namespace, shlibs, transformer.get_includes(),
- exported_packages, options.c_includes)
+ transformer.namespace.c_includes = options.c_includes
+ transformer.namespace.exported_packages = exported_packages
+ writer = Writer(transformer.namespace)
data = writer.get_xml()
write_output(data, options)