[gobject-introspection/wip/dieterv/g-ir-fix] tools: Add a tool fixing GTK-Doc comment blocks in .c and .h files



commit 6d2688bb655121b1b166076225fd8cb40f5cf6d6
Author: Dieter Verfaillie <dieterv optionexplicit be>
Date:   Sun Mar 15 21:33:14 2015 +0100

    tools: Add a tool fixing GTK-Doc comment blocks in .c and .h files
    
    Just a standalone script for now, should probably eventually
    go into g-ir-doctool or g-ir-annotation-tool...

 tools/g-ir-fix.py |  132 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 132 insertions(+), 0 deletions(-)
---
diff --git a/tools/g-ir-fix.py b/tools/g-ir-fix.py
new file mode 100755
index 0000000..7e43a36
--- /dev/null
+++ b/tools/g-ir-fix.py
@@ -0,0 +1,132 @@
+#! 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.
+#
+
+from __future__ import with_statement
+
+import optparse
+import os
+import sys
+import __builtin__
+
+__builtin__.__dict__['DATADIR'] = '@datarootdir@'
+
+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
+
+srcdir=os.getenv('UNINSTALLED_INTROSPECTION_SRCDIR', None)
+if srcdir is not None:
+    path = srcdir
+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.annotationparser import (COMMENT_BLOCK_START_RE, COMMENT_BLOCK_END_RE,
+                                        GtkDocCommentBlockParser, GtkDocCommentBlockWriter)
+from giscanner.message import MessageLogger, ERROR, FATAL
+
+
+(CHUNK_DOC,
+ CHUNK_DATA) = range(2)
+
+
+if __name__ == '__main__':
+    parser = optparse.OptionParser('%prog [options]')
+
+    parser.add_option('-f', '--file',
+                      action='store', dest='input',
+                      help='Parse GTK-Doc comment blocks from the specified file')
+    parser.add_option('--fix',
+                      action="store_true", dest="fix", default=False,
+                      help='Write back fixed GTK-Doc comment blocks')
+
+    options, args = parser.parse_args(sys.argv)
+    if not options.input:
+        raise SystemExit('missing input file')
+    elif not os.path.isfile(options.input):
+        raise SystemExit('%s is not a file' % (options.input, ))
+
+    logger = MessageLogger.get(namespace=None)
+    parser = GtkDocCommentBlockParser()
+    writer = GtkDocCommentBlockWriter(indent=True)
+    logger.enable_warnings((ERROR, FATAL))
+
+    with open(options.input, 'rU') as f:
+        lines = f.readlines()
+
+    chunks = []
+    in_comment = False
+    chunk_start = 0
+    chunk_end = 0
+
+    for line_index, line in enumerate(lines):
+        if not in_comment:
+            if COMMENT_BLOCK_START_RE.match(line):
+                # We are at a line that starts a GTK-Doc comment block
+                in_comment = True
+                # Store everything before the GTK-Doc comment block as data
+                chunks.append([CHUNK_DATA,
+                               ''.join(lines[chunk_start:line_index])])
+                # Store where this GTK-Doc comment block starts
+                chunk_start = line_index
+        else:
+            if COMMENT_BLOCK_END_RE.match(line):
+                # We are at a line that closes a GTK-Doc comment block
+                in_comment = False
+                # Store the GTK-Doc comment block
+                chunks.append([CHUNK_DOC,
+                               ''.join(lines[chunk_start:line_index+1]),
+                               chunk_start + 1])
+                # Data chunk after the GTK-Doc comment block starts at the next line
+                chunk_start = line_index + 1
+                # Store where the GTK-Doc comment block ends
+                chunk_end = line_index
+    else:
+        # Store everything after the last GTK-Doc comment block (if any) as data
+        chunks.append([CHUNK_DATA,
+                       ''.join(lines[chunk_end if chunk_end == 0 else chunk_end + 1:])])
+
+    # We cannot use a for loop here as chunks is modified from within the loop
+    fixed = False
+    for i in range(len(chunks)):
+        chunk = chunks[i]
+        if chunk[0] == CHUNK_DOC:
+            docblock = parser.parse_comment_block(chunk[1].rstrip(), options.input, chunk[2])
+            if docblock:
+                fixed = True
+                chunk[1] = writer.write(docblock)
+
+    if options.fix:
+        error_count = logger.get_error_count()
+        if error_count > 0:
+            raise SystemExit('ERROR: %s will not be rewritten, please fix above %s and try again.\n' %
+                             (options.input, 'error' if error_count == 1 else 'errors'))
+
+        if fixed:
+            with open(options.input, 'wb') as f:
+                for chunk in chunks:
+                    f.write(chunk[1])
+


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