diff options
author | Colin Walters <walters@verbum.org> | 2010-07-27 06:16:37 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-08-31 16:05:56 -0400 |
commit | 36aa515f1036978ced8d4ffb808260844f7229e0 (patch) | |
tree | 93e06fb105a513a394365232bb632256f109dada /giscanner/testcodegen.py | |
parent | 552c1f1525e37a30376790151c1ba437776682c5 (diff) | |
download | gobject-introspection-36aa515f1036978ced8d4ffb808260844f7229e0.tar.gz |
Major rewrite
One of the first big changes in this rewrite is changing the Type
object to have separate target_fundamental and target_giname properties,
rather than just being strings. Previously in the scanner, it was
awful because we used heuristics around strings.
The ast.py is refactored so that not everything is a Node - that
was a rather useless abstraction. Now, only things which can have
a GIName are Node. E.g. Type and Field are no longer Node.
More things were merged from glibast.py into ast.py, since it isn't
a very useful split.
transformer.py gains more intelligence and will e.g. turn GLib.List
into a List() object earlier. The namespace processing is a lot
cleaner now; since we parse the included .girs, we know the C
prefix for each namespace, and have functions to parse both
C type names (GtkFooBar) and symbols gtk_foo_bar into their
symbols cleanly. Type resolution is much, much saner because
we know Type(target_giname=Gtk.Foo) maps to the namespace Gtk.
glibtransformer.py now just handles the XML processing from the dump,
and a few miscellaneous things.
The major heavy lifting now lives in primarytransformer.py, which
is a combination of most of annotationparser.py and half of
glibtransformer.py.
annotationparser.py now literally just parses annotations; it's
no longer in the business of e.g. guessing transfer too.
finaltransformer.py is a new file which does post-analysis for
"introspectability" mainly.
girparser.c is fixed for some introspectable=0 processing.
Diffstat (limited to 'giscanner/testcodegen.py')
-rw-r--r-- | giscanner/testcodegen.py | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/giscanner/testcodegen.py b/giscanner/testcodegen.py new file mode 100644 index 00000000..f304dc7a --- /dev/null +++ b/giscanner/testcodegen.py @@ -0,0 +1,119 @@ +# -*- Mode: Python -*- +# GObject-Introspection - a framework for introspecting GObject libraries +# Copyright (C) 2010 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +from StringIO import StringIO +from . import ast +from .codegen import CCodeGenerator + +DEFAULT_C_VALUES = {ast.TYPE_ANY: 'NULL', + ast.TYPE_STRING: '""', + ast.TYPE_FILENAME: '""', + ast.TYPE_GTYPE: 'g_object_get_type ()'} + +def get_default_for_typeval(typeval): + default = DEFAULT_C_VALUES.get(typeval) + if default: + return default + return "0" + +def uscore_from_type(typeval): + if typeval.target_fundamental: + return typeval.target_fundamental.replace(' ', '_') + elif typeval.target_giname: + return typeval.target_giname.replace('.', '').lower() + else: + assert False, typeval + +class EverythingCodeGenerator(object): + + def __init__(self, out_h_filename, out_c_filename): + self.namespace = ast.Namespace('Everything', '1.0') + self.gen = CCodeGenerator(self.namespace, out_h_filename, out_c_filename) + + def write(self): + func = ast.Function('nullfunc', + ast.Return(ast.TYPE_NONE, transfer=ast.PARAM_TRANSFER_NONE), + [], False, self.gen.gen_symbol('nullfunc')) + self.namespace.append(func) + body = " return;\n" + self.gen.set_function_body(func, body) + + # First pass, generate constant returns + prefix = 'const return ' + for typeval in ast.INTROSPECTABLE_BASIC: + name = prefix + uscore_from_type(typeval) + sym = self.gen.gen_symbol(name) + func = ast.Function(name, + ast.Return(typeval, transfer=ast.PARAM_TRANSFER_NONE), + [], False, sym) + self.namespace.append(func) + default = get_default_for_typeval(typeval) + body = " return %s;\n" % (default, ) + self.gen.set_function_body(func, body) + + # Void return, one parameter + prefix = 'oneparam ' + for typeval in ast.INTROSPECTABLE_BASIC: + if typeval is ast.TYPE_NONE: + continue + name = prefix + uscore_from_type(typeval) + sym = self.gen.gen_symbol(name) + func = ast.Function(name, + ast.Return(ast.TYPE_NONE, transfer=ast.PARAM_TRANSFER_NONE), + [ast.Parameter('arg0', typeval, transfer=ast.PARAM_TRANSFER_NONE, + direction=ast.PARAM_DIRECTION_IN)], False, sym) + self.namespace.append(func) + self.gen.set_function_body(func, " return;\n") + + # Void return, one (out) parameter + prefix = 'one_outparam ' + for typeval in ast.INTROSPECTABLE_BASIC: + if typeval is ast.TYPE_NONE: + continue + name = prefix + uscore_from_type(typeval) + sym = self.gen.gen_symbol(name) + func = ast.Function(name, + ast.Return(ast.TYPE_NONE, transfer=ast.PARAM_TRANSFER_NONE), + [ast.Parameter('arg0', typeval, transfer=ast.PARAM_TRANSFER_NONE, + direction=ast.PARAM_DIRECTION_OUT)], False, sym) + self.namespace.append(func) + body = StringIO('w') + default = get_default_for_typeval(func.retval) + body.write(" *arg0 = %s;\n" % (default, )) + body.write(" return;\n") + self.gen.set_function_body(func, body.getvalue()) + + # Passthrough one parameter + prefix = 'passthrough_one ' + for typeval in ast.INTROSPECTABLE_BASIC: + if typeval is ast.TYPE_NONE: + continue + name = prefix + uscore_from_type(typeval) + sym = self.gen.gen_symbol(name) + func = ast.Function(name, ast.Return(typeval, transfer=ast.PARAM_TRANSFER_NONE), + [ast.Parameter('arg0', typeval, transfer=ast.PARAM_TRANSFER_NONE, + direction=ast.PARAM_DIRECTION_IN)], False, sym) + self.namespace.append(func) + body = StringIO('w') + default = get_default_for_typeval(func.retval) + body.write(" return arg0;\n") + self.gen.set_function_body(func, body.getvalue()) + + self.gen.codegen() |