summaryrefslogtreecommitdiff
path: root/giscanner/testcodegen.py
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2010-07-27 06:16:37 -0400
committerColin Walters <walters@verbum.org>2010-08-31 16:05:56 -0400
commit36aa515f1036978ced8d4ffb808260844f7229e0 (patch)
tree93e06fb105a513a394365232bb632256f109dada /giscanner/testcodegen.py
parent552c1f1525e37a30376790151c1ba437776682c5 (diff)
downloadgobject-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.py119
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()