Format header, Remove dummy sys.path.insert
[platform/upstream/gobject-introspection.git] / tools / g-ir-scanner
1 #!/usr/bin/env python
2 # -*- Mode: Python -*-
3 # GObject-Introspection - a framework for introspecting GObject libraries
4 # Copyright (C) 2008  Johan Dahlin
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20 #
21
22 import commands
23 import optparse
24 import os
25 import sys
26
27 from giscanner.glibtransformer import GLibTransformer
28 from giscanner.sourcescanner import SourceScanner
29 from giscanner.transformer import Transformer
30
31
32 def _get_option_parser():
33     parser = optparse.OptionParser('%prog [options] sources')
34     parser.add_option("", "--format",
35                       action="store", dest="format",
36                       default="gir",
37                       help="format to use, one of gidl, gir")
38     parser.add_option("-i", "--include",
39                       action="append", dest="includes", default=[],
40                       help="include types for other gidls")
41     parser.add_option("-l", "--library",
42                       action="store", dest="library",
43                       help="library of this unit")
44     parser.add_option("-n", "--namespace",
45                       action="store", dest="namespace",
46                       help="namespace of this unit")
47     parser.add_option("", "--strip-prefix",
48                       action="store", dest="strip_prefix", default="",
49                       help="prefix to strip from functions, like g_")
50     parser.add_option("-o", "--output",
51                       action="store", dest="output",
52                       help="output to writeout, defaults to stdout")
53     parser.add_option("", "--pkg",
54                       action="append", dest="packages", default=[],
55                       help="pkg-config packages to get cflags from")
56     parser.add_option("-v", "--verbose",
57                       action="store_true", dest="verbose",
58                       help="be verbose")
59
60     group = optparse.OptionGroup(parser, "Preprocessor options")
61     group.add_option("-I", help="Pre-processor include file",
62                      action="append", dest="cpp_includes",
63                      default=[])
64     group.add_option("-D", help="Pre-processor define",
65                      action="append", dest="cpp_defines",
66                      default=[])
67     group.add_option("-U", help="Pre-processor undefine",
68                      action="append", dest="cpp_undefines",
69                      default=[])
70     group.add_option("-p", dest="", help="Ignored")
71     parser.add_option_group(group)
72
73     return parser
74
75 def _error(msg):
76     raise SystemExit('ERROR: %s' % (msg,))
77
78 def main(args):
79     parser = _get_option_parser()
80     (options, args) = parser.parse_args(args)
81
82     if len(args) <= 1:
83         _error('Need at least one filename')
84
85     if not options.namespace:
86         _error('Namespace missing')
87
88     if options.format == 'gir':
89         from giscanner.girwriter import GIRWriter as Writer
90     elif options.format == 'gidl':
91         from giscanner.gidlwriter import GIDLWriter as Writer
92     else:
93         _error("Unknown format: %s" % (options.format,))
94
95     for package in options.packages:
96         output = commands.getoutput('pkg-config --cflags %s' % (package,))
97         pkg_options, unused = parser.parse_args(output.split())
98         options.cpp_includes.extend(pkg_options.cpp_includes)
99         options.cpp_defines.extend(pkg_options.cpp_defines)
100         options.cpp_undefines.extend(pkg_options.cpp_undefines)
101
102     filenames = []
103     for arg in args:
104         if (arg.endswith('.c') or
105             arg.endswith('.h')):
106             if not os.path.exists(arg):
107                 _error('%s: no such a file or directory' % (arg,))
108             filenames.append(arg)
109
110     # Run the preprocessor, tokenize and construct simple
111     # objects representing the raw C symbols
112     ss = SourceScanner()
113     ss.set_cpp_options(options.cpp_includes,
114                        options.cpp_defines,
115                        options.cpp_undefines)
116     ss.parse_files(filenames)
117     ss.parse_macros()
118
119     # Transform the C symbols into AST nodes
120     transformer = Transformer(ss)
121     transformer.set_strip_prefix(options.strip_prefix)
122
123     # Transform the C AST nodes into higher level
124     # GLib/GObject nodes
125     glibtransformer = GLibTransformer(options.namespace)
126     if options.library:
127         glibtransformer.load_library(options.library)
128     for include in options.includes:
129         glibtransformer.register_include(include)
130
131     transformer.parse()
132     nodes = transformer.get_nodes()
133     glibtransformer.parse(nodes)
134
135     # Write out AST
136     writer = Writer(options.namespace, glibtransformer.get_nodes())
137     data = writer.get_xml()
138     if options.output:
139         fd = open(options.output, "w")
140         fd.write(data)
141     else:
142         print data
143
144     return 0
145
146 sys.exit(main(sys.argv))