[gobject-introspection] Add an annotation tool



commit 7cc31be7753b124b7f17febbbe0607765b426fa0
Author: Johan Dahlin <johan gnome org>
Date:   Thu Sep 16 00:37:49 2010 -0300

    Add an annotation tool

 .gitignore                    |    1 +
 giscanner/Makefile.am         |    1 +
 giscanner/annotationmain.py   |   78 +++++++++++++++++++++++++++++++++++++++++
 giscanner/annotationparser.py |   52 +++++++++++++++++++++++++++
 tools/Makefile.am             |   10 ++++--
 tools/g-ir-annotation-tool.in |   45 +++++++++++++++++++++++
 6 files changed, 184 insertions(+), 3 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 7242dfa..4d38d0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -119,4 +119,5 @@ tests/extended.gir.test
 tools/g-ir-compiler
 tools/g-ir-generate
 tools/g-ir-scanner
+tools/g-ir-annotation-tool
 tools/g-ir-docgen
diff --git a/giscanner/Makefile.am b/giscanner/Makefile.am
index 6fee40d..2779b70 100644
--- a/giscanner/Makefile.am
+++ b/giscanner/Makefile.am
@@ -33,6 +33,7 @@ pkgpyexecdir = $(pkglibdir)/giscanner
 pkgpyexec_LTLIBRARIES = _giscanner.la
 pkgpyexec_PYTHON = 		\
 	__init__.py		\
+	annotationmain.py	\
 	annotationparser.py	\
 	ast.py			\
 	cachestore.py		\
diff --git a/giscanner/annotationmain.py b/giscanner/annotationmain.py
new file mode 100644
index 0000000..d6e2eef
--- /dev/null
+++ b/giscanner/annotationmain.py
@@ -0,0 +1,78 @@
+# -*- Mode: Python -*-
+# GObject-Introspection - a framework for introspecting GObject libraries
+# Copyright (C) 2010 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 optparse
+
+from giscanner.annotationparser import AnnotationParser
+from giscanner.scannermain import (get_preprocessor_option_group,
+                                   create_source_scanner,
+                                   process_packages)
+
+def annotation_main(args):
+    parser = optparse.OptionParser('%prog [options] sources')
+
+    group = optparse.OptionGroup(parser, "Tool modes, one is required")
+    group.add_option("-e", "--extract",
+                     action="store_true", dest="extract",
+                     help="Extract annotations from the input files")
+    parser.add_option_group(group)
+
+    group = get_preprocessor_option_group(parser)
+    group.add_option("-L", "--library-path",
+                     action="append", dest="library_paths", default=[],
+                     help="directories to search for libraries")
+    group.add_option("", "--pkg",
+                     action="append", dest="packages", default=[],
+                     help="pkg-config packages to get cflags from")
+    parser.add_option_group(group)
+
+    options, args = parser.parse_args(args)
+
+    if not options.extract:
+        raise SystemExit("ERROR: Nothing to do")
+
+    if options.packages:
+        process_packages(options, options.packages)
+
+    ss = create_source_scanner(options, args)
+
+    if options.extract:
+        ap = AnnotationParser()
+        blocks = ap.parse(ss.get_comments())
+        for block in blocks.values():
+            print block.to_gtk_doc()
+            print
+    elif options.validate:
+        transformer = create_transformer(namespace, options)
+        transformer.parse(ss.get_symbols())
+
+        shlibs = create_binary(transformer, options, args)
+
+        ap = AnnotationParser()
+        blocks = ap.parse(ss.get_comments())
+
+        main = MainTransformer(transformer, blocks)
+        main.transform()
+
+        final = IntrospectablePass(transformer)
+        final.validate()
+
+
+    return 0
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index f2bc1d4..282ea55 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -106,6 +106,9 @@ class DocBlock(object):
         self.params = []
         self.position = None
 
+    def __cmp__(self, other):
+        return cmp(self.name, other.name)
+
     def __repr__(self):
         return '<DocBlock %r %r>' % (self.name, self.options)
 
@@ -116,6 +119,29 @@ class DocBlock(object):
     def get(self, name):
         return self.tags.get(name)
 
+    def to_gtk_doc(self):
+        lines = [self.name + ':']
+        tags = []
+        for name, tag in self.tags.iteritems():
+            if name in self.params:
+                lines.append(tag.to_gtk_doc_param())
+            else:
+                tags.append(tag)
+
+        lines.append('')
+        for l in self.comment.split('\n'):
+            lines.append(l)
+        if tags:
+            lines.append('')
+            for tag in tags:
+                lines.append(tag.to_gtk_doc_tag())
+
+        comment = '/**\n'
+        for line in lines:
+            comment += ' * %s\n' % (line, )
+        comment += ' */\n'
+        return comment
+
     def validate(self):
         for tag in self.tags.values():
             tag.validate()
@@ -169,6 +195,32 @@ class DocTag(object):
         self.position = position
         self.options.position = position
 
+    def _get_gtk_doc_value(self):
+        def serialize_one(option, value, fmt, fmt2):
+            if value:
+                if type(value) != str:
+                    value = ' '.join((serialize_one(k, v, '%s=%s', '%s')
+                                      for k,v in value.all().iteritems()))
+                return fmt % (option, value)
+            else:
+                return fmt2 % (option, )
+        annotations = []
+        for option, value in self.options.iteritems():
+            annotations.append(
+                serialize_one(option, value, '(%s %s)', '(%s)'))
+        if annotations:
+            return ' '.join(annotations) + ': '
+        else:
+            return self.value
+
+    def to_gtk_doc_param(self):
+        return '@%s: %s%s' % (self.name, self._get_gtk_doc_value(), self.comment)
+
+    def to_gtk_doc_tag(self):
+        return '%s: %s%s' % (self.name.capitalize(),
+                             self._get_gtk_doc_value(),
+                             self.comment or '')
+
     def validate(self):
         for option in self.options:
             value = self.options[option]
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 31acd02..9d96b6a 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -3,13 +3,17 @@ INCLUDES = \
 	-I$(top_srcdir)/girepository
 
 bin_PROGRAMS = g-ir-compiler g-ir-generate
-bin_SCRIPTS = g-ir-scanner
-EXTRA_DIST = g-ir-scanner.in
+bin_SCRIPTS = g-ir-scanner g-ir-annotation-tool
+EXTRA_DIST = g-ir-scanner.in g-ir-annotation-tool.in
 
 g-ir-scanner: g-ir-scanner.in Makefile
 	$(AM_V_GEN) sed -e s,@libdir\@,$(libdir), -e s,@PYTHON\@,$(PYTHON), $< > $  tmp && mv $  tmp $@
 	@chmod a+x $@
 
+g-ir-annotation-tool: g-ir-annotation-tool.in Makefile
+	$(AM_V_GEN) sed -e s,@libdir\@,$(libdir), -e s,@PYTHON\@,$(PYTHON), $< > $  tmp && mv $  tmp $@
+	@chmod a+x $@
+
 g_ir_compiler_SOURCES = compiler.c	
 g_ir_compiler_CFLAGS = $(GIREPO_CFLAGS)
 g_ir_compiler_LDADD = \
@@ -28,4 +32,4 @@ GCOVSOURCES =					\
 	$(g_ir_compiler_SOURCES)		\
 	$(g_ir_generate_SOURCES)
 
-CLEANFILES=g-ir-scanner
+CLEANFILES=g-ir-scanner g-ir-annotation-tool
diff --git a/tools/g-ir-annotation-tool.in b/tools/g-ir-annotation-tool.in
new file mode 100755
index 0000000..4fbc449
--- /dev/null
+++ b/tools/g-ir-annotation-tool.in
@@ -0,0 +1,45 @@
+#! 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 os
+import sys
+
+if 'GI_SCANNER_DEBUG' in os.environ:
+    def on_exception(exctype, value, tb):
+        print "Caught exception: %r %r" % (exctype, value)
+        import pdb
+        pdb.pm()
+    sys.excepthook = on_exception
+
+# This only works on unix systems
+currentdir = os.path.dirname(os.path.abspath(sys.argv[0]))
+current_name = os.path.basename(currentdir)
+if current_name == 'tools':
+    path = os.path.abspath(os.path.join(currentdir, '..'))
+else:
+    # This is a private directory, we don't want to pollute the global
+    # namespace.
+    path = os.path.join('@libdir@', 'gobject-introspection')
+sys.path.insert(0, path)
+
+from giscanner.annotationmain import annotation_main
+
+sys.exit(annotation_main(sys.argv))



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