diff options
author | Colin Walters <walters@verbum.org> | 2010-09-01 12:39:52 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-09-01 12:39:52 -0400 |
commit | c8e227432c5072ab858f8acd93b24ffc26ed1c68 (patch) | |
tree | 74e8a56e665da9d2ccc9c72068ae1f1f2ac13636 | |
parent | 5d114c3832a8ac6b3897c02be420d299fb90692c (diff) | |
download | gobject-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.py | 3 | ||||
-rw-r--r-- | giscanner/transformer.py | 58 |
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): |