#!/usr/bin/python # these are possible justifications; please stick to one of them STANDARD = "it's a textbook algorithm" APIDOCS = "it's based on a sample from the API documentation of the corresponding library" PERFORMANCE = "strict inlining is demonstrably necessary for performance" STABLE = "we don't expect to be making any changes to this code" DEBUGGING = "code used for debugging" exceptions = [ (r'quicksort',STANDARD,"tmb"), (r'rowsort',STANDARD,"tmb"), (r'io_png',APIDOCS,"tmb"), (r'io_pbm',STABLE,"tmb"), (r'debug_array',DEBUGGING,"tmb"), (r'/commands/',DEBUGGING,"tmb"), (r'seg-cuts',STABLE,"tmb"), ] ################################################################ # nothing configurable below this line ################################################################ import sys,os,string,re,getopt optlist,args = getopt.getopt(sys.argv[1:],'jr') options = {} for k,v in optlist: options[k] = v justifications = options.has_key("-j") want_author = options.get("-r",None) if want_author: want_author = want_author.lower() if os.system("pmccabe -V > /dev/null")!=0: sys.stderr.write("you must install the pmccabe tool (apt-get install pmccabe)") sys.exit(1) maxlines = 150 maxcyc1 = 15 temp = ".___temp___.cc" for file in os.popen("find . -name '*.cc' -o -name '*.h'","r").readlines(): file = file[:-1] # open each of the source files source = open(file,"r").read() # check the responsible person m = re.search(r'Responsible:\s+([a-zA-Z0-9_-]+)',source) if m: author = m.group(1).lower() else: author = "nobody" if want_author and want_author!=author: continue # pmccabe dies on templates and namespaces, so we remove those if re.search('tolua_.*_open',source): continue source = re.sub(r'template *\<.*?\>',r'',source) source = re.sub(r'namespace[ a-zA-Z0-9_]*{',r'',source) stream = open(temp,"w"); stream.write(source); stream.close() # read the output from pmccabe and try to find bad cases for line in os.popen("pmccabe %s 2> .pmccabe.errs"%temp): if "too many }'s" in line: continue line = line[:-1] line = line.replace(temp,file) fields = string.split(line,"\t") try: cyc1,cyc,nstat,where,nlines,location = fields except: sys.stderr.write("OOPS %s\n"%line) continue cyc1=int(cyc1) nlines=int(nlines) location = re.sub(r'\(([0-9]+)\)\s*:\s*',r':\1:',location) if cyc1>maxcyc1 or nlines>maxlines: exception = None for e in exceptions: pattern,reason,person = e if re.search(pattern,location)>0: exception = e if not justifications: # print everything that is not an exception if not exception: sys.stdout.write("%s cyc=%d nlines=%d [%s]\n"%(location,cyc1,nlines,author)) else: # print all the justifications if exception: pattern,reason,person = exception sys.stdout.write("%s cyc=%d nlines=%d [%s] %s\n"%(location,cyc1,nlines,person,reason))