summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2010-09-01 12:39:52 -0400
committerColin Walters <walters@verbum.org>2010-09-01 12:39:52 -0400
commitc8e227432c5072ab858f8acd93b24ffc26ed1c68 (patch)
tree74e8a56e665da9d2ccc9c72068ae1f1f2ac13636
parent5d114c3832a8ac6b3897c02be420d299fb90692c (diff)
downloadgobject-introspection-c8e227432c5072ab858f8acd93b24ffc26ed1c68.tar.gz
scanner: Refactor name parsing
First, merge the implementations of parsing both identifiers and symbols, since they had more in common than they had differences. Secondly, fix the logic for priority of --accept-unprefixed in the presence of unprefixed includes. The current namespace should win. An example of this is mutter which has unprefixed public symbols, but also includes xlib, which has no prefix. Third, for unprefixed namespaces, actually look at the contents rather than just blindly returning them. This is a bit of a hack, but better than the alternatives.
-rw-r--r--giscanner/scannermain.py3
-rw-r--r--giscanner/transformer.py58
2 files changed, 35 insertions, 26 deletions
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index 384727e2..3b7cd533 100644
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -102,7 +102,8 @@ the latter is not specified.""")
help="Remove this prefix from C symbols (function names)")
parser.add_option("", "--accept-unprefixed",
action="store_true", dest="accept_unprefixed", default=False,
- help="If specified, accept symbols and identifiers that do not match the namespace prefix.")
+ help="""If specified, accept symbols and identifiers that do not
+match the namespace prefix.""")
parser.add_option("", "--add-init-section",
action="append", dest="init_sections", default=[],
help="add extra initialization code in the introspection program")
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index aa1f4eb0..5d4c299f 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -275,44 +275,52 @@ currently-scanned namespace is first."""
return -1
return cmp(x[2], y[2])
- def split_ctype_namespaces(self, ident):
- """Given a StudlyCaps string identifier like FooBar, return a
-list of (namespace, stripped_identifier) sorted by namespace length,
-or raise ValueError. As a special case, if the current namespace matches,
-it is always biggest (i.e. last)."""
- matches = []
+ def _split_c_string_for_namespace_matches(self, name, is_identifier=False):
+ matches = [] # Namespaces which might contain this name
+ unprefixed_namespaces = [] # Namespaces with no prefix, last resort
for ns in self._iter_namespaces():
- if ns.identifier_prefixes:
- for prefix in ns.identifier_prefixes:
- if ident.startswith(prefix):
- matches.append((ns, ident[len(prefix):], len(prefix)))
+ if is_identifier:
+ prefixes = ns.identifier_prefixes
+ else:
+ prefixes = ns.symbol_prefixes
+ if prefixes:
+ for prefix in prefixes:
+ if (not is_identifier) and (not prefix.endswith('_')):
+ prefix = prefix + '_'
+ if name.startswith(prefix):
+ matches.append((ns, name[len(prefix):], len(prefix)))
break
else:
- # A special case for namespaces without a prefix, such as X
- matches.append((ns, ident, 0))
+ unprefixed_namespaces.append(ns)
if matches:
matches.sort(self._sort_matches)
return map(lambda x: (x[0], x[1]), matches)
elif self._accept_unprefixed:
- return [(self._namespace, ident)]
- raise ValueError("Unknown namespace for identifier %r" % (ident, ))
+ return [(self._namespace, name)]
+ elif unprefixed_namespaces:
+ # A bit of a hack; this function ideally shouldn't look through the
+ # contents of namespaces; but since we aren't scanning anything
+ # without a prefix, it's not too bad.
+ for ns in unprefixed_namespaces:
+ if name in ns:
+ return [(ns, name)]
+ else:
+ raise ValueError("Unknown namespace for %s %r"
+ % ('identifier' if is_identifier else 'symbol', name, ))
+
+ def split_ctype_namespaces(self, ident):
+ """Given a StudlyCaps string identifier like FooBar, return a
+list of (namespace, stripped_identifier) sorted by namespace length,
+or raise ValueError. As a special case, if the current namespace matches,
+it is always biggest (i.e. last)."""
+ return self._split_c_string_for_namespace_matches(ident, is_identifier=True)
def split_csymbol(self, symbol):
"""Given a C symbol like foo_bar_do_baz, return a pair of
(namespace, stripped_symbol) or raise ValueError."""
- matches = []
- for ns in self._iter_namespaces():
- for prefix in ns.symbol_prefixes:
- if not prefix.endswith('_'):
- prefix = prefix + '_'
- if symbol.startswith(prefix):
- matches.append((ns, symbol[len(prefix):], len(prefix)))
- break
+ matches = self._split_c_string_for_namespace_matches(symbol, is_identifier=False)
if matches:
- matches.sort(self._sort_matches)
return (matches[-1][0], matches[-1][1])
- elif self._accept_unprefixed:
- return (self._namespace, symbol)
raise ValueError("Unknown namespace for symbol %r" % (symbol, ))
def strip_identifier_or_warn(self, ident, fatal=False):