diff --git a/analyse_code.py b/analyse_code.py index 2c8ce9e..8ced622 100755 --- a/analyse_code.py +++ b/analyse_code.py @@ -1,113 +1,120 @@ #!/usr/bin/python import subprocess,os,sys import class_decriptor as cd tmp_directory = '/tmp' from class_dumper_classes import ClassDumperClasses ################################################################ import pygccxml.parser as gccparser from pygccxml import declarations + +################################################################ +def cleanName(n,**kwargs): + n = str(n) + if ('template' in kwargs) and kwargs['template'] is False: + n = declarations.templates.name(str(n)) + if ('namespace' in kwargs) and kwargs['namespace'] is False: + ns = n.split('::') + if len(ns) > 1: n = ns[-1] + n = str(n) + return n ################################################################ -def analyzeFile(fnames,include_paths=None,cflags=None,class_cache={},dec_dir=None): +def analyzeFile(fnames,include_paths=None,cflags=None,class_cache={},dec_dir=None,**kwargs): if type(fnames) is not list: fnames = [fnames] # print fnames #parsing source file #configure GCC-XML parser #print include_paths if cflags is None: cflags = '' config = gccparser.gccxml_configuration_t( include_paths=include_paths,cflags=cflags, ignore_gccxml_output=True) decls = gccparser.parse( fnames, config) global_ns = declarations.get_global_namespace( decls ) akantu = global_ns.namespace('akantu') for class_ in akantu.classes(): if dec_dir is not None: dec_file = declarations.declaration_files(class_) #print class_ #print list(dec_file) #print dec_dir #print [os.path.dirname(f) for f in dec_file] flags = [dec_dir == os.path.dirname(f) for f in dec_file] flag = False for f in flags: flag |= f #print flags if not flag: continue - def cleanName(n): - n = declarations.templates.name(str(n)) - ns = n.split('::') - if len(ns) > 1: n = ns[-1] - if not type(n) == str: raise Exception(str(n) + " - " + str(ns)) - return n #print class_ - class_.name = cleanName(class_.name) - inheritance = [cleanName(base.related_class.name) for base in class_.bases] + class_.name = cleanName(class_.name,**kwargs) + inheritance = [cleanName(base.related_class.name,**kwargs) for base in class_.bases] #print inheritance if inheritance == []: inheritance = None c = cd.ClassDescriptor(class_.name,inheritance=inheritance) for memb in class_.vars(allow_empty=True): name = memb.name static = "" if memb.type_qualifiers.has_static: static = 'static' - _type = cleanName(memb.type) + _type = cleanName(memb.type,**kwargs) encapsulation = memb.access_type c.addMember(name,_type,encapsulation,static,"") for foo in class_.member_functions(allow_empty=True): name = foo.name static = "" if foo.has_static: static = 'static' const = foo.has_const virtual = foo.virtuality if virtual == 'not virtual': virtual = '' - ret = cleanName(foo.return_type) + ret = cleanName(foo.return_type,**kwargs) encapsulation = foo.access_type args = foo.arguments - args = [(cleanName(a.type),a.name) for a in args] + args = [(cleanName(a.type,**kwargs),a.name) for a in args] c.addMethod(name,args,ret,encapsulation,virtual,static,const,"") #print c class_cache[class_.name] = c return class_cache ################################################################ -def analyzeFiles(dirname,extension_list = ['.cc','.cpp'],include_paths=None,cflags=None): +def analyzeFiles(dirname,extension_list = ['.cc','.cpp','.hh','.hpp'],output=None,**kwargs): read_classes = {} for f in os.listdir(dirname): base,ext = os.path.splitext(f) if ext in extension_list: - analyzeFile(os.path.join(dirname,f),include_paths=include_paths,cflags=cflags,class_cache=read_classes,dec_dir=dirname) - dumper_class = ClassDumperClasses('test.classes') - classes = [c for k,c in read_classes.iteritems()] - dumper_class.dump(classes=classes) + analyzeFile(os.path.join(dirname,f),class_cache=read_classes,dec_dir=dirname,**kwargs) + if output is not None: + dumper_class = ClassDumperClasses(output) + classes = [c for k,c in read_classes.iteritems()] + dumper_class.dump(classes=classes) ################################################################ if __name__ == '__main__': import argparse parser = argparse.ArgumentParser(description='Code analyzer to produce .classes description') parser.add_argument('--sources','-s', help='The directory where the sources are loacted',required=True) parser.add_argument('--includes','-I', type=str,help='The needed includes') parser.add_argument('--cflags','-f', type=str,help='The needed flags') + parser.add_argument('--template','-t', action='store_false',help='Remove templates from analysis') + parser.add_argument('--namespace','-n', action='store_false',help='Remove namespaces from analysis') + parser.add_argument('--output','-o', type=str,help='filename to store output') args = parser.parse_args() args = vars(args) -# print args src_dir = os.path.dirname(args['sources']) inc_dirs = None cflags = args['cflags'] - if cflags is not None: - cflags = cflags.replace('\-','-') -# print cflags + if cflags is not None: cflags = cflags.replace('\-','-') + args['cflags'] = cflags if args['includes'] is not None: inc_dirs = args['includes'].split(';') - analyzeFiles(src_dir,include_paths=inc_dirs,cflags=cflags) + analyzeFiles(src_dir,include_paths=inc_dirs,**args) diff --git a/class_decriptor.py b/class_decriptor.py index 9e2a76a..2f6e69d 100644 --- a/class_decriptor.py +++ b/class_decriptor.py @@ -1,105 +1,115 @@ class Typename: def __init__(self,name,encapsulation): self.name = name self.encapsulation = encapsulation class Method: def __init__(self,name,args,ret,encapsulation,virtual,static,const,comments): self.name = name self.virtual = virtual self.static = static self.args = dict() for k,v in args: self.args[v] = k self.ret = ret self.encapsulation = encapsulation if self.encapsulation == '': self.encapsulation = 'public' self.comments = comments self.const = const #print "creating method {0}".format(name) #print self.__dict__ def __str__(self): sstr = self.encapsulation + " " if not self.virtual == '': sstr += self.virtual + " " sstr += self.ret + " " + self.name + "(" pairs = list(self.args.iteritems()) pairs = [b + " " + a for a,b in pairs] sstr += ", ".join(pairs) sstr += ")" return sstr + def __eq__(self, other): + return (isinstance(other, self.__class__) + and self.__dict__ == other.__dict__) + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash(str(self)) + class Member: def __init__(self,name,_type,encapsulation,static,comments): self.name = name self.type = _type self.encapsulation = encapsulation self.static = static self.comments = comments def __str__(self): return self.encapsulation + " " + self.type + " " + self.name class ClassDescriptor: def __init__(self,name,inheritance=None): self.name = name self.inheritance = inheritance self.members = {'private':{},'public':{},'protected':{}} self.methods = {'private':{},'public':{},'protected':{}} self.types = {'private':{},'public':{},'protected':{}} def addMethod(self,name,args,ret,encapsulation,virtual,static,const,comments): new_method = Method(name,args,ret,encapsulation,virtual,static,const,comments) - if name not in self.methods[encapsulation]: self.methods[encapsulation][name] = [] - self.methods[encapsulation][name].append(new_method) + if name not in self.methods[encapsulation]: self.methods[encapsulation][name] = set() + self.methods[encapsulation][name].add(new_method) def addMember(self,name,_type,encapsulation,static,comments): new_member = Member(name,_type,encapsulation,static,comments) self.members[encapsulation][name] = new_member def addType(self,name,encapsulation): new_type = Typename(name,encapsulation) self.types[encapsulation][name] = new_type def getMembers(self,encapsulation=None): return self.members[encapsulation] def getTypes(self,encapsulation=None): return self.types[encapsulation] def getMethods(self,encapsulation=None): return self.methods[encapsulation] def __str__(self): sstr = "Class " + self.name + "\n" if (self.inheritance): sstr += "Inherit: " sstr += ",".join(self.inheritance) + "\n" sstr += "Methods:\n" for encaps,meths in self.methods.iteritems(): sstr += encaps + ":\n" for name,m_list in meths.iteritems(): for m in m_list: sstr += str(m) + "\n" sstr += "\n" sstr += "Members:\n" for encaps,membs in self.members.iteritems(): sstr += encaps + ":\n" for name,m in membs.iteritems(): sstr += str(m) + "\n" return sstr if __name__ == '__main__': my_class = ClassDescriptor('dummy') my_class.addMethod('compute',[('int','arg1'),('double','arg2')],'bool','public','') my_class.addMember('res','double','private') print my_class