import os, sys from _dia import * import _dia SYM_TAGS = dict ((getattr (_dia, i), i) for i in dir (_dia) if i.startswith ("SymTag")) BASIC_TYPES = dict ((getattr (_dia, i), i) for i in dir (_dia) if i.startswith ("bt")) del _dia class Symbol (object): def __init__ (self, dia_symbol): self._dia_symbol = dia_symbol try: self._name = dia_symbol.name except ValueError: self._name = repr (dia_symbol) def __getattr__ (self, attr): try: return getattr (self._dia_symbol, attr) except ValueError: return None def __str__ (self): return "Symbol: %s - %s" % ((SYM_TAGS.get (self.symTag) or "*"), self._name) def __eq__ (self, other): return self._dia_symbol.symIndexId == other._dia_symbol.symIndexId def __hash__ (self): return hash (self._dia_symbol.symIndexId) def dump (self, level=0, already_seen=None): if already_seen is None: already_seen = set () else: if self in already_seen: return already_seen.add (self) IGNORE = set (["findChildren", "findAllChildren", "name"]) MAP = { "lexicalParent" : Symbol, "symTag" : SYM_TAGS.get, "baseType" : BASIC_TYPES.get, "guid" : lambda g: "".join ("%02x" % ord (i) for i in g) } print " " * level, "{" print " " * (level + 1), self for d in sorted (d for d in dir (self._dia_symbol) if not d.startswith ("_") and d not in IGNORE): try: v = getattr (self._dia_symbol, d) except ValueError: continue except NotImplementedError: v = "" mapper = MAP.get (d) if mapper: v = mapper (v) print " " * (level + 1), d, "=>", v children = list (self) if children: print for child in children: child.dump (level + 1, already_seen) print print " " * level, "}" print def find (self, tags=SymTagNull, name=None, flags=nsNone): BATCH_SIZE = 100 children = self._dia_symbol.findChildren (tags, name, flags) while True: next_kids = children.Next (BATCH_SIZE) if not next_kids: raise StopIteration else: for kid in next_kids: yield Symbol (kid) __iter__ = find class Pdb (object): def __init__ (self, filepath): data_source = DataSource () data_source.loadDataFromPdb (filepath) self.root = Symbol (data_source.openSession ().globalScope) def __iter__ (self): return iter (self.root) def find (self, *args, **kwargs): return self.root.find (*args, **kwargs) def dump (self): self.root.dump () def main (pdb_filepath): Pdb (unicode (pdb_filepath)).dump () if __name__ == '__main__': main (*sys.argv[1:])