[gobject-introspection/wip/transformer] [major] process constants again
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection/wip/transformer] [major] process constants again
- Date: Mon, 16 Aug 2010 22:35:38 +0000 (UTC)
commit eb60ba427c79637bc328e8ea982332d0b1cf23f1
Author: Colin Walters <walters verbum org>
Date: Mon Aug 16 16:00:45 2010 -0400
[major] process constants again
giscanner/transformer.py | 63 +++++++++++++++++++++++-------------
tests/scanner/Foo-1.0-expected.gir | 2 +-
2 files changed, 41 insertions(+), 24 deletions(-)
---
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index e03ede2..bde2c0a 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -20,12 +20,13 @@
import os
import sys
+import re
from .ast import (Bitfield, Callback, Enum, Function, Namespace, Member,
Parameter, Return, Record, Field,
Type, Array, List, Map, Alias, Interface, Class, Node, Union,
Varargs, Constant, type_names, basic_type_names,
- TYPE_STRING, TYPE_ANY)
+ TYPE_STRING, TYPE_ANY, TYPE_INT, TYPE_DOUBLE)
from .config import DATADIR, GIR_DIR, GIR_SUFFIX
from .girparser import GIRParser
from .odict import odict
@@ -48,6 +49,8 @@ _xdg_data_dirs = [x for x in os.environ.get('XDG_DATA_DIRS', '').split(':') \
class Transformer(object):
namespace = property(lambda self: self._namespace)
+ UCASE_CONSTANT_RE = re.compile(r'[_A-Z0-9]+')
+
def __init__(self, cachestore, namespace_name, namespace_version,
strip_prefix=None):
self._cwd = os.getcwd() + os.sep
@@ -79,21 +82,30 @@ class Transformer(object):
def set_source_ast(self, src_ast):
self.generator = src_ast
+ def _append_new_node(self, node):
+ original = self._namespace.get(node.name)
+ # Special case constants here; we allow duplication to sort-of
+ # handle #ifdef. But this introduces an arch-dependency in the .gir
+ # file. So far this has only come up scanning glib - in theory, other
+ # modules will just depend on that.
+ if isinstance(original, Constant) and isinstance(node, Constant):
+ pass
+ elif original:
+ positions = set()
+ positions.update(original.file_positions)
+ positions.update(node.file_positions)
+ self.log_warning("Namespace conflict for '%s'" % (node.name, ),
+ positions)
+ sys.exit(1)
+ else:
+ self._namespace.append(node)
+
def parse(self):
- nodes = []
for symbol in self.generator.get_symbols():
node = self._traverse_one(symbol)
if node:
- try:
- self._namespace.append(node)
- except ValueError, e:
- original = self._namespace.get(node.name)
- positions = set()
- positions.update(original.file_positions)
- positions.update(node.file_positions)
- self.log_warning("Namespace conflict for '%s'" % (node.name, ),
- positions)
- sys.exit(1)
+ self._append_new_node(node)
+
# Now look through the namespace for things like
# typedef struct _Foo Foo;
# where we've never seen the struct _Foo. Just create
@@ -282,8 +294,11 @@ or raise ValueError."""
return matches[0]
raise ValueError("Unknown namespace for symbol %r" % (symbol, ))
- def _strip_symbol_or_warn(self, symbol):
+ def _strip_symbol_or_warn(self, symbol, is_constant=False):
ident = symbol.ident
+ if is_constant:
+ # Temporarily lowercase
+ ident = ident.lower()
hidden = ident.startswith('_')
if hidden:
ident = ident[1:]
@@ -295,6 +310,8 @@ or raise ValueError."""
if ns != self._namespace:
self.log_symbol_warning(symbol, "Skipping foreign symbol from namespace %s" % (ns.name, ))
return None
+ if is_constant:
+ name = name.upper()
if hidden:
return '_' + name
return name
@@ -330,11 +347,8 @@ or raise ValueError."""
return self._create_member(symbol)
elif stype == CSYMBOL_TYPE_UNION:
return self._create_union(symbol)
- # FIXME - we need to require an annotation on
- # #defines to have them be constants, otherwise
- # namespace explosion can occur
elif stype == CSYMBOL_TYPE_CONST:
- pass
+ return self._create_const(symbol)
# Ignore variable declarations in the header
elif stype == CSYMBOL_TYPE_OBJECT:
pass
@@ -595,22 +609,25 @@ or raise ValueError."""
if (symbol.source_filename is None or
not symbol.source_filename.endswith('.h')):
return None
- name = self._strip_symbol_or_warn(symbol)
+ # ignore non-uppercase defines
+ if not self.UCASE_CONSTANT_RE.match(symbol.ident):
+ return None
+ name = self._strip_symbol_or_warn(symbol, is_constant=True)
if not name:
return None
if symbol.const_string is not None:
typeval = TYPE_STRING
value = symbol.const_string
elif symbol.const_int is not None:
- type_name = 'int'
- value = symbol.const_int
+ typeval = TYPE_INT
+ value = '%d' % (symbol.const_int, )
elif symbol.const_double is not None:
- type_name = 'double'
- value = symbol.const_double
+ typeval = TYPE_DOUBLE
+ value = '%f' % (symbol.const_double, )
else:
raise AssertionError()
- const = Constant(name, type_name, value)
+ const = Constant(name, typeval, value)
const.add_symbol_reference(symbol)
return const
diff --git a/tests/scanner/Foo-1.0-expected.gir b/tests/scanner/Foo-1.0-expected.gir
index b9a957d..388f0be 100644
--- a/tests/scanner/Foo-1.0-expected.gir
+++ b/tests/scanner/Foo-1.0-expected.gir
@@ -156,7 +156,7 @@ and/or use gtk-doc annotations. -->
</method>
</record>
<constant name="DEFINE_SHOULD_BE_EXPOSED" value="should be exposed">
- <type name="utf8"/>
+ <type name="utf8" c:type="gchar*"/>
</constant>
<enumeration name="EnumFullname" c:type="FooEnumFullname">
<member name="one" value="1" c:identifier="FOO_ENUM_FULLNAME_ONE"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]