#!/usr/bin/python import sys,os,re,string,os.path,glob if not os.path.exists("ocr-utils"): sys.stderr.write("must be run from top level of ocropus installation") sys.exit(1) sources = glob.glob("*/*.h") + glob.glob("*/*.cc") class UnionFind: def __init__(self): self.num_weights = {} self.parent_pointers = {} self.num_to_objects = {} self.objects_to_num = {} self.__repr__ = self.__str__ def insert_objects(self, objects): for object in objects: self.find(object); def find(self, object): if not object in self.objects_to_num: obj_num = len(self.objects_to_num) self.num_weights[obj_num] = 1 self.objects_to_num[object] = obj_num self.num_to_objects[obj_num] = object self.parent_pointers[obj_num] = obj_num return object stk = [self.objects_to_num[object]] par = self.parent_pointers[stk[-1]] while par != stk[-1]: stk.append(par) par = self.parent_pointers[par] for i in stk: self.parent_pointers[i] = par return self.num_to_objects[par] def union(self, object1, object2): o1p = self.find(object1) o2p = self.find(object2) if o1p != o2p: on1 = self.objects_to_num[o1p] on2 = self.objects_to_num[o2p] w1 = self.num_weights[on1] w2 = self.num_weights[on2] if w1 < w2: o1p, o2p, on1, on2, w1, w2 = o2p, o1p, on2, on1, w2, w1 self.num_weights[on1] = w1+w2 del self.num_weights[on2] self.parent_pointers[on2] = on1 def __str__(self): sets = {} for i in xrange(len(self.objects_to_num)): sets[i] = [] for i in self.objects_to_num: sets[self.objects_to_num[self.find(i)]].append(i) out = [] for i in sets.itervalues(): if i: out.append(repr(i)) return ', '.join(out) def unique(l): h = {} for k in l: h[k] = 1 return h.keys() edges = [] for file in sources: text = open(file,"r").read() text = re.sub(r'/\*.*?\*/',' ',text) text = re.sub(r'//.*?\n',' ',text) text = re.sub("\n"," ",text) print file for cls in re.findall(r'(?:\s|^)((?:class|struct)\s[^.*/!]*?)[{;]',text): print cls m = re.search(r'(?:class|struct)\s+(\S+)\s*:\s*(.*)',cls) if m: derived = m.group(1).strip() for base in re.split(r'\s*,\s*',m.group(2)): base = re.sub(r'\s*public\s*','',base.strip()) base = re.sub(r'colib::','',base) derived = re.sub(r'colib::','',derived) base = re.sub(r'\s*virtual\s*','',base) derived = re.sub(r'\s*virtual\s*','',derived) edges.append((derived,base)) sys.stderr.write("%s: %s %s\n"%(file,derived,base)) edges = unique(edges) objects = unique([k for k,v in edges] + [v for k,v in edges]) uf = UnionFind() for derived,base in edges: uf.find(derived) uf.find(base) uf.union(derived,base) sets = {} for derived,base in edges: key = uf.find(derived) sets[key] = sets.get(key,[]) + [(derived,base)] dir = "doc/hierarchy" def graph(stream,name,edges): stream.write(""" digraph "%s" { rankdir = "LR"; size = "8,20"; ratio = compress; """ % name) for derived,base in edges: stream.write('"%s"'%derived+"->"+'"%s"'%base+";\n") stream.write(""" } """) html = open(dir+"/index.html","w") count = 1 for key in sets.keys(): set = sets[key] prefix = dir+("/graph%03d"%count) stream = open(prefix+".dot","w") graph(stream,"graph%d"%count,set) stream.close() os.system("dot -Tpng %s.dot -o %s.png"%(prefix,prefix)) html.write("

Diagram %d

\n"%count) html.write("

\n") html.write("\n") count += 1 html.close()