diff options
Diffstat (limited to 'tools/g-ir-scanner')
-rwxr-xr-x | tools/g-ir-scanner | 360 |
1 files changed, 0 insertions, 360 deletions
diff --git a/tools/g-ir-scanner b/tools/g-ir-scanner deleted file mode 100755 index 4b5b924c..00000000 --- a/tools/g-ir-scanner +++ /dev/null @@ -1,360 +0,0 @@ -#!/usr/bin/env python -# -*- Mode: Python -*- -# GObject-Introspection - a framework for introspecting GObject libraries -# Copyright (C) 2008 Johan Dahlin -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. -# - -import subprocess -import optparse -import os -import sys - -# This only works on unix systems -currentdir = os.path.dirname(os.path.abspath(sys.argv[0])) -basedir = os.path.abspath(os.path.join(currentdir, '..')) -if (os.path.exists(os.path.join(basedir, '.svn')) or - os.path.exists(os.path.join(basedir, '.git'))): - path = basedir -else: - libdir = 'lib' - for p in sys.path: - if 'lib64' in p: - libdir = 'lib64' - break - - path = os.path.join(basedir, libdir, 'python%d.%d' % sys.version_info[:2], - 'site-packages') -sys.path.insert(0, path) - -from giscanner.annotationparser import AnnotationParser, InvalidAnnotationError -from giscanner.ast import Include -from giscanner.cachestore import CacheStore -from giscanner.dumper import compile_introspection_binary -from giscanner.glibtransformer import GLibTransformer, IntrospectionBinary -from giscanner.minixpath import myxpath, xpath_assert -from giscanner.sourcescanner import SourceScanner -from giscanner.transformer import Transformer - -def _get_option_parser(): - parser = optparse.OptionParser('%prog [options] sources') - parser.add_option("", "--format", - action="store", dest="format", - default="gir", - help="format to use, one of gidl, gir") - parser.add_option("-i", "--include", - action="append", dest="includes", default=[], - help="include types for other gidls") - parser.add_option("", "--add-include-path", - action="append", dest="include_paths", default=[], - help="include paths for other GIR files") - parser.add_option("", "--program", - action="store", dest="program", default=None, - help="program to execute") - parser.add_option("", "--program-arg", - action="append", dest="program_args", default=[], - help="extra arguments to program") - parser.add_option("", "--libtool", - action="store", dest="libtool_path", default=None, - help="full path to libtool") - parser.add_option("", "--no-libtool", - action="store_true", dest="nolibtool", default=False, - help="use libtool") - parser.add_option("-l", "--library", - action="append", dest="libraries", default=[], - help="libraries of this unit") - parser.add_option("-L", "--library-path", - action="append", dest="library_paths", default=[], - help="directories to search for libraries") - parser.add_option("-n", "--namespace", - action="store", dest="namespace_name", - help=("name of namespace for this unit, also " - "used as --strip-prefix default")) - parser.add_option("", "--nsversion", - action="store", dest="namespace_version", - help="version of namespace for this unit") - parser.add_option("", "--strip-prefix", - action="store", dest="strip_prefix", default=None, - help="remove this prefix from objects and functions") - parser.add_option("-o", "--output", - action="store", dest="output", - help="output to writeout, defaults to stdout") - parser.add_option("", "--pkg", - action="append", dest="packages", default=[], - help="pkg-config packages to get cflags from") - parser.add_option("-v", "--verbose", - action="store_true", dest="verbose", - help="be verbose") - parser.add_option("", "--noclosure", - action="store_true", dest="noclosure", - help="do not delete unknown types") - parser.add_option("", "--typelib-xml", - action="store_true", dest="typelib_xml", - help="Just convert GIR to typelib XML") - parser.add_option("", "--inject", - action="store_true", dest="inject", - help="Inject additional components into GIR XML") - parser.add_option("", "--xpath-assertions", - action="store", dest="xpath_assertions", - help="Use given file to create assertions on GIR content") - parser.add_option("", "--c-include", - action="append", dest="c_includes", default=[], - help="headers which should be included in C programs") - - group = optparse.OptionGroup(parser, "Preprocessor options") - group.add_option("-I", help="Pre-processor include file", - action="append", dest="cpp_includes", - default=[]) - group.add_option("-D", help="Pre-processor define", - action="append", dest="cpp_defines", - default=[]) - group.add_option("-U", help="Pre-processor undefine", - action="append", dest="cpp_undefines", - default=[]) - group.add_option("-p", dest="", help="Ignored") - parser.add_option_group(group) - - return parser - - -def _error(msg): - raise SystemExit('ERROR: %s' % (msg, )) - -def typelib_xml_strip(path): - from giscanner.girparser import GIRParser - from giscanner.girwriter import GIRWriter - from giscanner.girparser import C_NS - from xml.etree.cElementTree import parse - - c_ns_key = '{%s}' % (C_NS, ) - - tree = parse(path) - root = tree.getroot() - for node in root.getiterator(): - for attrib in list(node.attrib): - if attrib.startswith(c_ns_key): - del node.attrib[attrib] - parser = GIRParser() - parser.parse_tree(tree) - - writer = GIRWriter(parser.get_namespace(), - parser.get_shared_libraries(), - parser.get_includes()) - sys.stdout.write(writer.get_xml()) - return 0 - -def inject(path, additions, outpath): - from giscanner.girparser import GIRParser - from giscanner.girwriter import GIRWriter - from xml.etree.cElementTree import parse - - tree = parse(path) - root = tree.getroot() - injectDoc = parse(open(additions)) - for node in injectDoc.getroot(): - injectPath = node.attrib['path'] - target = myxpath(root, injectPath) - if not target: - raise ValueError("Couldn't find path %r" % (injectPath, )) - for child in node: - target.append(child) - - parser = GIRParser() - parser.parse_tree(tree) - writer = GIRWriter(parser.get_namespace(), - parser.get_shared_libraries(), - parser.get_includes()) - outf = open(outpath, 'w') - outf.write(writer.get_xml()) - outf.close() - return 0 - -def validate(assertions, path): - from xml.etree.cElementTree import parse - doc = parse(open(path)) - root = doc.getroot() - f = open(assertions) - assertions_list = f.readlines() - for assertion in assertions_list: - assertion = assertion.strip() - xpath_assert(root, assertion) - f.close() - return 0 - -def process_options(output, allowed_flags): - for option in output.split(): - for flag in allowed_flags: - if not option.startswith(flag): - continue - yield option - break - -def process_packages(parser, options, packages): - args = ['pkg-config', '--cflags'] - args.extend(packages) - output = subprocess.Popen(args, - stdout=subprocess.PIPE).communicate()[0] - if output is None: - # the error output should have already appeared on our stderr, - # so we just exit - sys.exit(1) - # Some pkg-config files on Windows have options we don't understand, - # so we explicitly filter to only the ones we need. - options_whitelist = ['-I', '-D', '-U', '-l', '-L'] - filtered_output = list(process_options(output, options_whitelist)) - pkg_options, unused = parser.parse_args(filtered_output) - options.cpp_includes.extend(pkg_options.cpp_includes) - options.cpp_defines.extend(pkg_options.cpp_defines) - options.cpp_undefines.extend(pkg_options.cpp_undefines) - - args = ['pkg-config', '--libs-only-L'] - args.extend(packages) - output = subprocess.Popen(args, - stdout=subprocess.PIPE).communicate()[0] - if output is None: - sys.exit(1) - filtered_output = list(process_options(output, options_whitelist)) - pkg_options, unused = parser.parse_args(filtered_output) - options.library_paths.extend(pkg_options.library_paths) - -def main(args): - parser = _get_option_parser() - (options, args) = parser.parse_args(args) - - if len(args) <= 1: - _error('Need at least one filename') - - if options.typelib_xml: - return typelib_xml_strip(args[1]) - - if options.inject: - if len(args) != 4: - _error('Need three filenames; e.g. g-ir-scanner ' - '--inject Source.gir Additions.xml SourceOut.gir') - return inject(*args[1:4]) - - if options.xpath_assertions: - return validate(options.xpath_assertions, args[1]) - - if not options.namespace_name: - _error('Namespace name missing') - - if options.format == 'gir': - from giscanner.girwriter import GIRWriter as Writer - else: - _error("Unknown format: %s" % (options.format, )) - - if not (options.libraries or options.program): - _error("Must specify --program or --library") - libraries = options.libraries - - # FIXME: using LPATH is definitely not portable enough. Using Python's - # find_library for finding our shared libraries is not a portable enough - # anyway as it behaves differently depending on the OS - lpath = os.environ.get('LPATH') - library_path = ':'.join(options.library_paths) - - ld_library_path = os.environ.get('LD_LIBRARY_PATH') - if ld_library_path: - library_path = ':'.join([ld_library_path, library_path]) - - if lpath: - os.environ['LPATH'] = ':'.join([lpath, library_path]) - else: - os.environ['LPATH'] = library_path - filenames = [] - for arg in args: - if (arg.endswith('.c') or - arg.endswith('.h')): - if not os.path.exists(arg): - _error('%s: no such a file or directory' % (arg, )) - # Make absolute, because we do comparisons inside scannerparser.c - # against the absolute path that cpp will give us - filenames.append(os.path.abspath(arg)) - - cachestore = CacheStore() - transformer = Transformer(cachestore, - options.namespace_name, - options.namespace_version) - if options.strip_prefix: - transformer.set_strip_prefix(options.strip_prefix) - else: - transformer.set_strip_prefix(options.namespace_name) - transformer.set_include_paths(options.include_paths) - shown_include_warning = False - for include in options.includes: - if os.sep in include: - raise ValueError("Invalid include path %r" % (include, )) - include_obj = Include.from_string(include) - transformer.register_include(include_obj) - - packages = set(options.packages) - packages.update(transformer.get_pkgconfig_packages()) - process_packages(parser, options, packages) - - # 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) - ss.parse_files(filenames) - ss.parse_macros(filenames) - - # Transform the C symbols into AST nodes - transformer.set_source_ast(ss) - - # Transform the C AST nodes into higher level - # GLib/GObject nodes - glibtransformer = GLibTransformer(transformer, - noclosure=options.noclosure) - - # Do enough parsing that we have the get_type() functions to reference - # when creating the introspection binary - glibtransformer.init_parse() - - if options.program: - args=[options.program] - args.extend(options.program_args) - binary = IntrospectionBinary(args) - else: - binary = compile_introspection_binary(options, - glibtransformer.get_get_type_functions()) - - glibtransformer.set_introspection_binary(binary) - - namespace = glibtransformer.parse() - - ap = AnnotationParser(namespace, ss, transformer) - try: - ap.parse() - except InvalidAnnotationError, e: - raise SystemExit("ERROR in annotation: %s" % (str(e), )) - - # Write out AST - writer = Writer(namespace, libraries, transformer.get_includes(), - options.packages, options.c_includes) - data = writer.get_xml() - if options.output: - fd = open(options.output, "w") - fd.write(data) - else: - print data - - return 0 - -sys.exit(main(sys.argv)) |