[gobject-introspection] giscanner: Add Optional Options for Codegen



commit c112e9830f8af59275d6f590bbcb365c9968c1fc
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Wed Sep 3 11:22:35 2014 +0800

    giscanner: Add Optional Options for Codegen
    
    This adds options to scannermain so that we can decorate functions with
    macros as needed, so that we can use compiler annotations for symbol export
    for example.
    
    Options are also added to include headers before or after the main include
    block at the top so that we can include headers as necessary in the
    generated sources and/or headers, so that we could for example grab
    definitions from those headers as needed, such as to grab definitions of
    macros used for symbol export.
    
    The testcodegen.py script has been updated as well to make use of this
    functionality, if needed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=732669

 giscanner/codegen.py     |   33 ++++++++++++++++++++++++++++++++-
 giscanner/scannermain.py |   37 ++++++++++++++++++++++++++++++++++---
 giscanner/testcodegen.py |   18 ++++++++++++++++--
 3 files changed, 82 insertions(+), 6 deletions(-)
---
diff --git a/giscanner/codegen.py b/giscanner/codegen.py
index e9ed941..e0eb182 100644
--- a/giscanner/codegen.py
+++ b/giscanner/codegen.py
@@ -26,9 +26,21 @@ from . import ast
 
 
 class CCodeGenerator(object):
-    def __init__(self, namespace, out_h_filename, out_c_filename):
+    def __init__(self, namespace,
+                 out_h_filename,
+                 out_c_filename,
+                 function_decoration=[],
+                 include_first_header=[],
+                 include_last_header=[],
+                 include_first_src=[],
+                 include_last_src=[]):
         self.out_h_filename = out_h_filename
         self.out_c_filename = out_c_filename
+        self.function_decoration = function_decoration
+        self.include_first_header = include_first_header
+        self.include_last_header = include_last_header
+        self.include_first_src = include_first_src
+        self.include_last_src = include_last_src
         self._function_bodies = {}
         self.namespace = namespace
 
@@ -50,6 +62,10 @@ class CCodeGenerator(object):
         return param.type.ctype + suffix
 
     def _write_prelude(self, out, func):
+        if self.function_decoration:
+            out.write("""
+%s""" % " ".join(self.function_decoration))
+
         out.write("""
 %s
 %s (""" % (self._typecontainer_to_ctype(func.retval), func.symbol))
@@ -105,16 +121,31 @@ class CCodeGenerator(object):
         warning = '/* GENERATED BY testcodegen.py; DO NOT EDIT */\n\n'
         self.out_h.write(warning)
         nsupper = self.namespace.name.upper()
+
+        for header in self.include_first_header:
+            self.out_h.write("""#include "%s"\n""" % header)
+
         self.out_h.write("""
 #ifndef __%s_H__
 #define __%s_H__
 
 #include <glib-object.h>
+
 """ % (nsupper, nsupper))
 
+        for header in self.include_last_header:
+            self.out_h.write("""#include "%s"\n""" % header)
+
         self.out_c.write(warning)
+
+        for header in self.include_first_src:
+            self.out_c.write("""#include "%s"\n""" % header)
+
         self.out_c.write("""#include "%s"\n\n""" % (self.out_h_filename, ))
 
+        for header in self.include_last_src:
+            self.out_c.write("""#include "%s"\n""" % header)
+
     def _codegen_end(self):
         self.out_h.write("""#endif\n""")
 
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index c3706f2..bca4a88 100755
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -217,6 +217,21 @@ match the namespace prefix.""")
     parser.add_option("", "--typelib-xml",
                       action="store_true", dest="typelib_xml",
                       help=optparse.SUPPRESS_HELP)
+    parser.add_option("", "--function-decoration",
+                      action="append", dest="function_decoration", default=[],
+                      help="Macro to decorate functions in generated code")
+    parser.add_option("", "--include-first-in-header",
+                      action="append", dest="include_first_header", default=[],
+                      help="Header to include first in generated header")
+    parser.add_option("", "--include-last-in-header",
+                      action="append", dest="include_last_header", default=[],
+                      help="Header to include after the other headers in generated header")
+    parser.add_option("", "--include-first-in-src",
+                      action="append", dest="include_first_src", default=[],
+                      help="Header to include first in generated sources")
+    parser.add_option("", "--include-last-in-src",
+                      action="append", dest="include_last_src", default=[],
+                      help="Header to include after the other headers in generated sources")
 
     return parser
 
@@ -233,11 +248,22 @@ def passthrough_gir(path, f):
     f.write(writer.get_xml())
 
 
-def test_codegen(optstring):
+def test_codegen(optstring,
+                 function_decoration,
+                 include_first_header,
+                 include_last_header,
+                 include_first_src,
+                 include_last_src):
     (namespace, out_h_filename, out_c_filename) = optstring.split(',')
     if namespace == 'Everything':
         from .testcodegen import EverythingCodeGenerator
-        gen = EverythingCodeGenerator(out_h_filename, out_c_filename)
+        gen = EverythingCodeGenerator(out_h_filename,
+                                      out_c_filename,
+                                      function_decoration,
+                                      include_first_header,
+                                      include_last_header,
+                                      include_first_src,
+                                      include_last_src)
         gen.write()
     else:
         _error("Invaild namespace %r" % (namespace, ))
@@ -450,7 +476,12 @@ def scanner_main(args):
     if options.passthrough_gir:
         passthrough_gir(options.passthrough_gir, sys.stdout)
     if options.test_codegen:
-        return test_codegen(options.test_codegen)
+        return test_codegen(options.test_codegen,
+                            options.function_decoration,
+                            options.include_first_header,
+                            options.include_last_header,
+                            options.include_first_src,
+                            options.include_last_src)
 
     if hasattr(options, 'filelist') and not options.filelist:
         if len(args) <= 1:
diff --git a/giscanner/testcodegen.py b/giscanner/testcodegen.py
index 1ed247c..32139e3 100644
--- a/giscanner/testcodegen.py
+++ b/giscanner/testcodegen.py
@@ -46,9 +46,23 @@ def uscore_from_type(typeval):
 
 class EverythingCodeGenerator(object):
 
-    def __init__(self, out_h_filename, out_c_filename):
+    def __init__(self,
+                 out_h_filename,
+                 out_c_filename,
+                 function_decoration,
+                 include_first_header,
+                 include_last_header,
+                 include_first_src,
+                 include_last_src):
         self.namespace = ast.Namespace('Everything', '1.0')
-        self.gen = CCodeGenerator(self.namespace, out_h_filename, out_c_filename)
+        self.gen = CCodeGenerator(self.namespace,
+                                  out_h_filename,
+                                  out_c_filename,
+                                  function_decoration,
+                                  include_first_header,
+                                  include_last_header,
+                                  include_first_src,
+                                  include_last_src)
 
     def write(self):
         func = ast.Function('nullfunc',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]