[gobject-introspection] [scanner] add a message module



commit 0b0a3cc7705ca797bc8315ba0815644bef5d30fb
Author: Johan Dahlin <johan gnome org>
Date:   Thu Sep 2 11:04:58 2010 -0300

    [scanner] add a message module
    
    This module will be used to report warnings, which
    doesn't explicitly depend on the transformer instance.

 giscanner/Makefile.am    |    1 +
 giscanner/message.py     |  155 ++++++++++++++++++++++++++++++++++++++++++++++
 giscanner/scannermain.py |    5 +-
 3 files changed, 159 insertions(+), 2 deletions(-)
---
diff --git a/giscanner/Makefile.am b/giscanner/Makefile.am
index c01599f..a2044cf 100644
--- a/giscanner/Makefile.am
+++ b/giscanner/Makefile.am
@@ -47,6 +47,7 @@ pkgpyexec_PYTHON = 		\
 	libtoolimporter.py	\
 	odict.py		\
 	maintransformer.py	\
+	message.py		\
 	shlibs.py		\
 	scannermain.py		\
 	sourcescanner.py	\
diff --git a/giscanner/message.py b/giscanner/message.py
new file mode 100644
index 0000000..4355514
--- /dev/null
+++ b/giscanner/message.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+# -*- Mode: Python -*-
+# GObject-Introspection - a framework for introspecting GObject libraries
+# Copyright (C) 2010 Red Hat, Inc.
+# 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 os
+import sys
+
+from . import ast
+
+(WARNING,
+ ERROR,
+ FATAL) = range(3)
+
+class MessageLogger(object):
+    _instance = None
+
+    def __init__(self, namespace):
+        self._cwd = os.getcwd() + os.sep
+        self._namespace = namespace
+        self._enable_warnings = False
+        self._warned = False
+
+    @classmethod
+    def get(cls, *args, **kwargs):
+        if cls._instance is None:
+            cls._instance = cls(*args, **kwargs)
+        return cls._instance
+
+    def enable_warnings(self, enable):
+        self._enable_warnings = enable
+
+    def did_warn(self):
+        return self._warned
+
+    def log(self, log_type, text, file_positions=None, prefix=None):
+        """Log a warning, using optional file positioning information.
+If the warning is related to a ast.Node type, see log_node_warning()."""
+        if not self._enable_warnings:
+            return
+
+        self._warned = True
+
+        if file_positions is None or len(file_positions) == 0:
+            target_file_positions = [('<unknown>', -1, -1)]
+        else:
+            target_file_positions = file_positions
+
+        position_strings = []
+        for (filename, line, column) in target_file_positions:
+            if filename.startswith(self._cwd):
+                filename = filename[len(self._cwd):]
+            if column != -1:
+                position = '%s:%d:%d' % (filename, line, column)
+            elif line != -1:
+                position = '%s:%d' % (filename, line, )
+            else:
+                position = '%s:' % (filename, )
+            position_strings.append(position)
+
+        for position in position_strings[:-1]:
+            print >>sys.stderr, "%s:" % (position, )
+        last_position = position_strings[-1]
+
+        if log_type == WARNING:
+            error_type = "Warning"
+        elif log_type == ERROR:
+            error_type = "Error"
+        elif log_type == FATAL:
+            error_type = "Fatal"
+        if prefix:
+            print >>sys.stderr, \
+'''%s: %s: %s: %s: %s''' % (last_position, error_type, self._namespace.name,
+                            prefix, text)
+        else:
+            print >>sys.stderr, \
+'''%s: %s: %s: %s''' % (last_position, error_type, self._namespace.name, text)
+
+
+        if log_type == FATAL:
+            raise SystemExit
+
+    def log_node(self, log_type, node, text, context=None):
+        """Log a warning, using information about file positions from
+the given node.  The optional context argument, if given, should be
+another ast.Node type which will also be displayed.  If no file position
+information is available from the node, the position data from the
+context will be used."""
+        if hasattr(node, 'file_positions'):
+            if (len(node.file_positions) == 0 and
+                (context is not None) and len(context.file_positions) > 0):
+                file_positions = context.file_positions
+            else:
+                file_positions = node.file_positions
+        else:
+            file_positions = None
+            if not context:
+                text = "context=%r %s" % (node, text)
+
+        if context:
+            if isinstance(context, ast.Function):
+                name = context.symbol
+            else:
+                name = context.name
+            text = "%s: %s" % (name, text)
+        elif len(file_positions) == 0 and hasattr(node, 'name'):
+            text = "(%s)%s: %s" % (node.__class__.__name__, node.name, text)
+
+        self.log(log_type, text, file_positions)
+
+    def log_symbol(self, log_type, symbol, text, **kwargs):
+        """Log a warning in the context of the given symbol."""
+        if symbol.source_filename:
+            file_positions = [(symbol.source_filename, symbol.line, -1)]
+        else:
+            file_positions = None
+        prefix = "symbol=%r" % (symbol.ident, )
+        self.log(log_type, text, file_positions, prefix=prefix, **kwargs)
+
+
+def log_node(log_type, node, text, context=None):
+    ml = MessageLogger.get()
+    ml.log_node(log_type, node, text, context=context)
+
+def warn(text, file_positions=None, prefix=None):
+    ml = MessageLogger.get()
+    ml.log(WARNING, text, file_positions, prefix)
+
+def warn_node(node, text, context=None):
+    log_node(WARNING, node, text, context=context)
+
+def warn_symbol(symbol, text):
+    ml = MessageLogger.get()
+    ml.log_symbol(WARNING, symbol, text)
+
+def fatal(text, file_positions=None, prefix=None):
+    ml = MessageLogger.get()
+    ml.log(FATAL, text, file_positions, prefix)
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index cc01032..eae10f7 100644
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -28,6 +28,7 @@ import subprocess
 import sys
 import tempfile
 
+from giscanner import message
 from giscanner.annotationparser import AnnotationParser
 from giscanner.ast import Include, Namespace
 from giscanner.dumper import compile_introspection_binary
@@ -264,10 +265,10 @@ def scanner_main(args):
                           options.namespace_version,
                           identifier_prefixes=identifier_prefixes,
                           symbol_prefixes=symbol_prefixes)
+    message.MessageLogger.get(namespace=namespace,
+                              enable_warnings=options.warn_all)
     transformer = Transformer(namespace,
                               accept_unprefixed=options.accept_unprefixed)
-    if options.warn_all:
-        transformer.enable_warnings(True)
     transformer.set_include_paths(options.include_paths)
     shown_include_warning = False
     for include in options.includes:



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