129921a8fSScott Kruger#!/usr/bin/env python 229921a8fSScott Kruger""" 329921a8fSScott KrugerParse the test file and return a dictionary. 429921a8fSScott Kruger 529921a8fSScott KrugerQuick usage:: 629921a8fSScott Kruger 729921a8fSScott Kruger bin/maint/testparse.py -t src/ksp/ksp/examples/tutorials/ex1.c 829921a8fSScott Kruger 929921a8fSScott KrugerFrom the command line, it prints out the dictionary. 1029921a8fSScott KrugerThis is meant to be used by other scripts, but it is 1129921a8fSScott Krugeruseful to debug individual files. 1229921a8fSScott Kruger 1329921a8fSScott Kruger 1429921a8fSScott Kruger 1529921a8fSScott KrugerExample language 1629921a8fSScott Kruger---------------- 1729921a8fSScott Kruger/*T 1829921a8fSScott Kruger Concepts: 1929921a8fSScott Kruger requires: moab 2029921a8fSScott KrugerT*/ 2129921a8fSScott Kruger 2229921a8fSScott Kruger 2329921a8fSScott Kruger 2429921a8fSScott Kruger/*TEST 2529921a8fSScott Kruger 2629921a8fSScott Kruger test: 2729921a8fSScott Kruger args: -pc_type mg -ksp_type fgmres -da_refine 2 -ksp_monitor_short -mg_levels_ksp_monitor_short -mg_levels_ksp_norm_type unpreconditioned -ksp_view -pc_mg_type full 2829921a8fSScott Kruger 2929921a8fSScott Kruger test: 3029921a8fSScott Kruger suffix: 2 3129921a8fSScott Kruger nsize: 2 3229921a8fSScott Kruger args: -pc_type mg -ksp_type fgmres -da_refine 2 -ksp_monitor_short -mg_levels_ksp_monitor_short -mg_levels_ksp_norm_type unpreconditioned -ksp_view -pc_mg_type full 3329921a8fSScott Kruger 3429921a8fSScott KrugerTEST*/ 3529921a8fSScott Kruger 3629921a8fSScott Kruger""" 3729921a8fSScott Kruger 3829921a8fSScott Krugerimport os, re, glob, types 3929921a8fSScott Krugerfrom distutils.sysconfig import parse_makefile 4029921a8fSScott Krugerimport sys 4129921a8fSScott Krugerimport logging 4229921a8fSScott Krugersys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) 4329921a8fSScott Kruger 4429921a8fSScott Krugerimport inspect 4529921a8fSScott Krugerthisscriptdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 4629921a8fSScott Krugermaintdir=os.path.join(os.path.join(os.path.dirname(thisscriptdir),'bin'),'maint') 4729921a8fSScott Krugersys.path.insert(0,maintdir) 4829921a8fSScott Kruger 4929921a8fSScott Kruger# These are special keys describing build 5029921a8fSScott Krugerbuildkeys="requires TODO SKIP depends".split() 5129921a8fSScott Kruger 5244776d8cSScott Krugeracceptedkeys="test nsize requires command suffix args separate_testvars filter filter_output localrunfiles comments TODO SKIP output_file".split() 5344776d8cSScott Krugerappendlist="args requires comments".split() 5468a9e459SScott Kruger 5568a9e459SScott Krugerimport re 5668a9e459SScott Kruger 5744776d8cSScott Krugerdef _stripIndent(block,srcfile,entireBlock=False,fileNums=[]): 5829921a8fSScott Kruger """ 5929921a8fSScott Kruger Go through and remove a level of indentation 6029921a8fSScott Kruger Also strip of trailing whitespace 6129921a8fSScott Kruger """ 6229921a8fSScott Kruger # The first entry should be test: but it might be indented. 6329921a8fSScott Kruger ext=os.path.splitext(srcfile)[1] 6444776d8cSScott Kruger stripstr=" " 658ccd5183SScott Kruger for lline in block.split("\n"): 668ccd5183SScott Kruger line=lline[1:] if lline.startswith("!") else lline 6729921a8fSScott Kruger if not line.strip(): continue 68c4b80baaSScott Kruger if line.strip().startswith('#'): continue 6944776d8cSScott Kruger if entireBlock: 7044776d8cSScott Kruger var=line.split(":")[0].strip() 7144776d8cSScott Kruger if not var=='test': 7244776d8cSScott Kruger raise Exception("Formatting error in finding test in file: "+srcfile+"\n") 7329921a8fSScott Kruger nspace=len(line)-len(line.lstrip(stripstr)) 7429921a8fSScott Kruger newline=line[nspace:] 7529921a8fSScott Kruger break 7629921a8fSScott Kruger 7729921a8fSScott Kruger # Strip off any indentation for the whole string and any trailing 7829921a8fSScott Kruger # whitespace for convenience 7929921a8fSScott Kruger newTestStr="\n" 8044776d8cSScott Kruger if len(fileNums)>0: lineNum=fileNums[0]-1 8144776d8cSScott Kruger firstPass=True 828ccd5183SScott Kruger for lline in block.split("\n"): 8344776d8cSScott Kruger if len(fileNums)>0: lineNum+=1 848ccd5183SScott Kruger line=lline[1:] if lline.startswith("!") else lline 8529921a8fSScott Kruger if not line.strip(): continue 86c4b80baaSScott Kruger if line.strip().startswith('#'): 87c4b80baaSScott Kruger newTestStr+=line+'\n' 88c4b80baaSScott Kruger else: 8929921a8fSScott Kruger newline=line[nspace:] 90c4b80baaSScott Kruger newTestStr+=newline.rstrip()+"\n" 9144776d8cSScott Kruger # Do some basic indentation checks 9244776d8cSScott Kruger if entireBlock: 9344776d8cSScott Kruger # Don't need to check comment lines 9444776d8cSScott Kruger if line.strip().startswith('#'): continue 9544776d8cSScott Kruger if not newline.startswith(" "): 9644776d8cSScott Kruger var=newline.split(":")[0].strip() 9744776d8cSScott Kruger if not var=='test': 9844776d8cSScott Kruger err="Formatting error in file "+srcfile+" at line: " +line+"\n" 9944776d8cSScott Kruger if len(fileNums)>0: 10044776d8cSScott Kruger raise Exception(err+"Check indentation at line number: "+str(lineNum)) 10144776d8cSScott Kruger else: 10244776d8cSScott Kruger raise Exception(err) 10344776d8cSScott Kruger else: 10444776d8cSScott Kruger var=line.split(":")[0].strip() 10544776d8cSScott Kruger if var=='test': 10644776d8cSScott Kruger subnspace=len(line)-len(line.lstrip(stripstr)) 10744776d8cSScott Kruger if firstPass: 10844776d8cSScott Kruger firstsubnspace=subnspace 10944776d8cSScott Kruger firstPass=False 11044776d8cSScott Kruger else: 11144776d8cSScott Kruger if firstsubnspace!=subnspace: 11244776d8cSScott Kruger err="Formatting subtest error in file "+srcfile+" at line: " +line+"\n" 11344776d8cSScott Kruger if len(fileNums)>0: 11444776d8cSScott Kruger raise Exception(err+"Check indentation at line number: "+str(lineNum)) 11544776d8cSScott Kruger else: 11644776d8cSScott Kruger raise Exception(err) 11744776d8cSScott Kruger 11829921a8fSScott Kruger 11929921a8fSScott Kruger return newTestStr 12029921a8fSScott Kruger 12144776d8cSScott Krugerdef _getNewArgs(kvar,val,argStr): 12244776d8cSScott Kruger """ 12344776d8cSScott Kruger Given: String containing arguments 12444776d8cSScott Kruger Return: String without the value in it 12544776d8cSScott Kruger """ 12644776d8cSScott Kruger return newTestStr 12744776d8cSScott Kruger 12844776d8cSScott Krugerdef _getVarVals(findvar,testDict): 12944776d8cSScott Kruger """ 13044776d8cSScott Kruger Given: variable that is either nsize or in args 13144776d8cSScott Kruger Return: Values to loop over 13244776d8cSScott Kruger """ 13344776d8cSScott Kruger vals=None 13444776d8cSScott Kruger newargs='' 13544776d8cSScott Kruger if findvar=='nsize': 13644776d8cSScott Kruger vals=testDict[findvar] 13744776d8cSScott Kruger else: 13844776d8cSScott Kruger varlist=[] 13944776d8cSScott Kruger for varset in re.split('-(?=[a-zA-Z])',testDict['args']): 14044776d8cSScott Kruger if not varset.strip(): continue 14144776d8cSScott Kruger if len(re.findall('{{(.*?)}}',varset))>0: 14244776d8cSScott Kruger # Assuming only one for loop per var specification 14344776d8cSScott Kruger keyvar=varset.split("{{")[0].strip() 14444776d8cSScott Kruger if keyvar!=findvar: 14544776d8cSScott Kruger newargs+="-"+varset+" " 14644776d8cSScott Kruger continue 14744776d8cSScott Kruger vals=re.findall('{{(.*?)}}',varset)[0] 14844776d8cSScott Kruger 14944776d8cSScott Kruger if not vals: raise StandardError("Could not find separate_testvar: "+findvar) 15044776d8cSScott Kruger return vals,newargs 15144776d8cSScott Kruger 15244776d8cSScott Krugerdef genTestsSeparateTestvars(intests,indicts): 15344776d8cSScott Kruger """ 15444776d8cSScott Kruger Given: testname, sdict with separate_testvars 15544776d8cSScott Kruger Return: testnames,sdicts: List of generated tests 15644776d8cSScott Kruger """ 15744776d8cSScott Kruger testnames=[]; sdicts=[] 15844776d8cSScott Kruger for i in range(len(intests)): 15944776d8cSScott Kruger testname=intests[i]; sdict=indicts[i]; i+=1 16044776d8cSScott Kruger if sdict.has_key('separate_testvars'): 16144776d8cSScott Kruger for kvar in sdict['separate_testvars'].split(): 16244776d8cSScott Kruger kvals,newargs=_getVarVals(kvar,sdict) 16344776d8cSScott Kruger # No errors means we are good to go 16444776d8cSScott Kruger for val in kvals.split(): 16544776d8cSScott Kruger kvardict=sdict.copy() 16644776d8cSScott Kruger del kvardict['separate_testvars'] 16744776d8cSScott Kruger gensuffix="_"+kvar+"-"+val 16844776d8cSScott Kruger newtestnm=testname+gensuffix 16944776d8cSScott Kruger kvardict['suffix']=sdict['suffix']+gensuffix 17044776d8cSScott Kruger if kvar=='nsize': 17144776d8cSScott Kruger kvardict[kvar]=val 17244776d8cSScott Kruger else: 17344776d8cSScott Kruger kvardict['args']=newargs+"-"+kvar+" "+val 17444776d8cSScott Kruger testnames.append(newtestnm) 17544776d8cSScott Kruger sdicts.append(kvardict) 17644776d8cSScott Kruger else: 17744776d8cSScott Kruger testnames.append(testname) 17844776d8cSScott Kruger sdicts.append(sdict) 17944776d8cSScott Kruger return testnames,sdicts 18044776d8cSScott Kruger 18144776d8cSScott Krugerdef genTestsSubtestSuffix(testnames,sdicts): 18244776d8cSScott Kruger """ 18344776d8cSScott Kruger Given: testname, sdict with separate_testvars 18444776d8cSScott Kruger Return: testnames,sdicts: List of generated tests 18544776d8cSScott Kruger """ 18644776d8cSScott Kruger tnms=[]; sdcts=[] 18744776d8cSScott Kruger for i in range(len(testnames)): 18844776d8cSScott Kruger testname=testnames[i] 18944776d8cSScott Kruger rmsubtests=[]; keepSubtests=False 19044776d8cSScott Kruger if sdicts[i].has_key('subtests'): 19144776d8cSScott Kruger for stest in sdicts[i]["subtests"]: 19244776d8cSScott Kruger if sdicts[i][stest].has_key('suffix'): 19344776d8cSScott Kruger rmsubtests.append(stest) 19444776d8cSScott Kruger gensuffix="_"+sdicts[i][stest]['suffix'] 19544776d8cSScott Kruger newtestnm=testname+gensuffix 19644776d8cSScott Kruger tnms.append(newtestnm) 19744776d8cSScott Kruger newsdict=sdicts[i].copy() 19844776d8cSScott Kruger del newsdict['subtests'] 19944776d8cSScott Kruger # Have to hand update 20044776d8cSScott Kruger # Append 20144776d8cSScott Kruger for kup in appendlist: 20244776d8cSScott Kruger if sdicts[i][stest].has_key(kup): 20344776d8cSScott Kruger if sdicts[i].has_key(kup): 20444776d8cSScott Kruger newsdict[kup]=sdicts[i][kup]+" "+sdicts[i][stest][kup] 20544776d8cSScott Kruger else: 20644776d8cSScott Kruger newsdict[kup]=sdicts[i][stest][kup] 20744776d8cSScott Kruger # Promote 20844776d8cSScott Kruger for kup in acceptedkeys: 20944776d8cSScott Kruger if kup in appendlist: continue 21044776d8cSScott Kruger if sdicts[i][stest].has_key(kup): 21144776d8cSScott Kruger newsdict[kup]=sdicts[i][stest][kup] 21244776d8cSScott Kruger # Cleanup 21344776d8cSScott Kruger for st in sdicts[i]["subtests"]: del newsdict[st] 21444776d8cSScott Kruger sdcts.append(newsdict) 21544776d8cSScott Kruger else: 21644776d8cSScott Kruger keepSubtests=True 21744776d8cSScott Kruger else: 21844776d8cSScott Kruger tnms.append(testnames[i]) 21944776d8cSScott Kruger sdcts.append(sdicts[i]) 22044776d8cSScott Kruger # Prune the tests to prepare for keeping 22144776d8cSScott Kruger for rmtest in rmsubtests: 22244776d8cSScott Kruger sdicts[i]['subtests'].remove(rmtest) 22344776d8cSScott Kruger del sdicts[i][rmtest] 22444776d8cSScott Kruger # If we are keeping any tests, then append 22544776d8cSScott Kruger if keepSubtests: 22644776d8cSScott Kruger tnms.append(testnames[i]) 22744776d8cSScott Kruger sdcts.append(sdicts[i]) 22844776d8cSScott Kruger i+=1 22944776d8cSScott Kruger return tnms,sdcts 23044776d8cSScott Kruger 23144776d8cSScott Krugerdef splitTests(testname,sdict): 23244776d8cSScott Kruger """ 23344776d8cSScott Kruger Given: testname and YAML-generated dictionary 23444776d8cSScott Kruger Return: list of names and dictionaries corresponding to each test 23544776d8cSScott Kruger given that the YAML language allows for multiple tests 23644776d8cSScott Kruger """ 23744776d8cSScott Kruger 23844776d8cSScott Kruger # Order: Parent sep_tv, subtests suffix, subtests sep_tv 23944776d8cSScott Kruger testnames,sdicts=genTestsSeparateTestvars([testname],[sdict]) 24044776d8cSScott Kruger testnames,sdicts=genTestsSubtestSuffix(testnames,sdicts) 24144776d8cSScott Kruger testnames,sdicts=genTestsSeparateTestvars(testnames,sdicts) 24244776d8cSScott Kruger 24344776d8cSScott Kruger # Because I am altering the list, I do this in passes. Inelegant 24444776d8cSScott Kruger 24544776d8cSScott Kruger return testnames, sdicts 24644776d8cSScott Kruger 247*6cecdbdcSScott Krugerdef parseTest(testStr,srcfile,verbosity): 24829921a8fSScott Kruger """ 24929921a8fSScott Kruger This parses an individual test 25029921a8fSScott Kruger YAML is hierarchial so should use a state machine in the general case, 25153f2a965SBarry Smith but in practice we only support two levels of test: 25229921a8fSScott Kruger """ 25329921a8fSScott Kruger basename=os.path.basename(srcfile) 25429921a8fSScott Kruger # Handle the new at the begininng 25529921a8fSScott Kruger bn=re.sub("new_","",basename) 25629921a8fSScott Kruger # This is the default 25729921a8fSScott Kruger testname="run"+os.path.splitext(bn)[0] 25829921a8fSScott Kruger 25929921a8fSScott Kruger # Tests that have default everything (so empty effectively) 26029921a8fSScott Kruger if len(testStr)==0: return testname, {} 26129921a8fSScott Kruger 26229921a8fSScott Kruger striptest=_stripIndent(testStr,srcfile) 26329921a8fSScott Kruger 26429921a8fSScott Kruger # go through and parse 26529921a8fSScott Kruger subtestnum=0 26629921a8fSScott Kruger subdict={} 26768a9e459SScott Kruger comments=[] 26868a9e459SScott Kruger indentlevel=0 26968a9e459SScott Kruger for ln in striptest.split("\n"): 270c4b80baaSScott Kruger line=ln.split('#')[0].rstrip() 271*6cecdbdcSScott Kruger if verbosity>2: print line 27268a9e459SScott Kruger comment=("" if len(ln.split("#"))==1 else " ".join(ln.split("#")[1:]).strip()) 27368a9e459SScott Kruger if comment: comments.append(comment) 27429921a8fSScott Kruger if not line.strip(): continue 27544776d8cSScott Kruger lsplit=line.split(':') 27644776d8cSScott Kruger if len(lsplit)==0: raise Exception("Missing : in line: "+line) 27744776d8cSScott Kruger indentcount=lsplit[0].count(" ") 27844776d8cSScott Kruger var=lsplit[0].strip() 27944776d8cSScott Kruger val=lsplit[1].strip() 28044776d8cSScott Kruger if not var in acceptedkeys: raise Exception("Not a defined key: "+var+" from: "+line) 28129921a8fSScott Kruger # Start by seeing if we are in a subtest 28229921a8fSScott Kruger if line.startswith(" "): 283c0658d2aSScott Kruger subdict[subtestname][var]=val 28468a9e459SScott Kruger if not indentlevel: indentlevel=indentcount 28568a9e459SScott Kruger #if indentlevel!=indentcount: print "Error in indentation:", ln 28629921a8fSScott Kruger # Determine subtest name and make dict 28729921a8fSScott Kruger elif var=="test": 28829921a8fSScott Kruger subtestname="test"+str(subtestnum) 28929921a8fSScott Kruger subdict[subtestname]={} 29029921a8fSScott Kruger if not subdict.has_key("subtests"): subdict["subtests"]=[] 29129921a8fSScott Kruger subdict["subtests"].append(subtestname) 29229921a8fSScott Kruger subtestnum=subtestnum+1 29368a9e459SScott Kruger # The rest are easy 29429921a8fSScott Kruger else: 29544776d8cSScott Kruger # For convenience, it is sometimes convenient to list twice 29644776d8cSScott Kruger if subdict.has_key(var): 29744776d8cSScott Kruger if var in appendlist: 29844776d8cSScott Kruger subdict[var]+=" "+val 29944776d8cSScott Kruger else: 30044776d8cSScott Kruger raise Exception(var+" entered twice: "+line) 30144776d8cSScott Kruger else: 302c0658d2aSScott Kruger subdict[var]=val 30329921a8fSScott Kruger if var=="suffix": 30429921a8fSScott Kruger if len(val)>0: 30529921a8fSScott Kruger testname=testname+"_"+val 30629921a8fSScott Kruger 30768a9e459SScott Kruger if len(comments): subdict['comments']="\n".join(comments).lstrip("\n") 30844776d8cSScott Kruger # A test block can create multiple tests. This does 30944776d8cSScott Kruger # that logic 31044776d8cSScott Kruger testnames,subdicts=splitTests(testname,subdict) 31144776d8cSScott Kruger return testnames,subdicts 31229921a8fSScott Kruger 313*6cecdbdcSScott Krugerdef parseTests(testStr,srcfile,fileNums,verbosity): 31429921a8fSScott Kruger """ 31529921a8fSScott Kruger Parse the yaml string describing tests and return 31629921a8fSScott Kruger a dictionary with the info in the form of: 31729921a8fSScott Kruger testDict[test][subtest] 31829921a8fSScott Kruger This is an inelegant parser as we do not wish to 31929921a8fSScott Kruger introduce a new dependency by bringing in pyyaml. 32029921a8fSScott Kruger The advantage is that validation can be done as 32129921a8fSScott Kruger it is parsed (e.g., 'test' is the only top-level node) 32229921a8fSScott Kruger """ 32329921a8fSScott Kruger 32429921a8fSScott Kruger testDict={} 32529921a8fSScott Kruger 32629921a8fSScott Kruger # The first entry should be test: but it might be indented. 32744776d8cSScott Kruger newTestStr=_stripIndent(testStr,srcfile,entireBlock=True,fileNums=fileNums) 328*6cecdbdcSScott Kruger if verbosity>2: print srcfile 32929921a8fSScott Kruger 33029921a8fSScott Kruger # Now go through each test. First elem in split is blank 331c4b80baaSScott Kruger for test in newTestStr.split("\ntest:")[1:]: 332*6cecdbdcSScott Kruger testnames,subdicts=parseTest(test,srcfile,verbosity) 33344776d8cSScott Kruger for i in range(len(testnames)): 33444776d8cSScott Kruger if testDict.has_key(testnames[i]): 33544776d8cSScott Kruger raise Error("Multiple test names specified: "+testname+" in file: "+srcfile) 33644776d8cSScott Kruger testDict[testnames[i]]=subdicts[i] 33729921a8fSScott Kruger 33829921a8fSScott Kruger return testDict 33929921a8fSScott Kruger 340*6cecdbdcSScott Krugerdef parseTestFile(srcfile,verbosity): 34129921a8fSScott Kruger """ 34229921a8fSScott Kruger Parse single example files and return dictionary of the form: 34329921a8fSScott Kruger testDict[srcfile][test][subtest] 34429921a8fSScott Kruger """ 34529921a8fSScott Kruger debug=False 34629921a8fSScott Kruger curdir=os.path.realpath(os.path.curdir) 34729921a8fSScott Kruger basedir=os.path.dirname(os.path.realpath(srcfile)) 34829921a8fSScott Kruger basename=os.path.basename(srcfile) 34929921a8fSScott Kruger os.chdir(basedir) 35029921a8fSScott Kruger 35129921a8fSScott Kruger testDict={} 35229921a8fSScott Kruger sh=open(srcfile,"r"); fileStr=sh.read(); sh.close() 35329921a8fSScott Kruger 35429921a8fSScott Kruger ## Start with doing the tests 35529921a8fSScott Kruger # 35629921a8fSScott Kruger fsplit=fileStr.split("/*TEST\n")[1:] 35729921a8fSScott Kruger if len(fsplit)==0: 35829921a8fSScott Kruger if debug: print "No test found in: "+srcfile 35929921a8fSScott Kruger return {} 36044776d8cSScott Kruger fstart=len(fileStr.split("/*TEST\n")[0].split("\n"))+1 36129921a8fSScott Kruger # Allow for multiple "/*TEST" blocks even though it really should be 36229921a8fSScott Kruger # on 36329921a8fSScott Kruger srcTests=[] 36429921a8fSScott Kruger for t in fsplit: srcTests.append(t.split("TEST*/")[0]) 36529921a8fSScott Kruger testString=" ".join(srcTests) 36629921a8fSScott Kruger if len(testString.strip())==0: 36729921a8fSScott Kruger print "No test found in: "+srcfile 36829921a8fSScott Kruger return {} 36944776d8cSScott Kruger flen=len(testString.split("\n")) 37044776d8cSScott Kruger fend=fstart+flen-1 37144776d8cSScott Kruger fileNums=range(fstart,fend) 372*6cecdbdcSScott Kruger testDict[basename]=parseTests(testString,srcfile,fileNums,verbosity) 37329921a8fSScott Kruger 37429921a8fSScott Kruger ## Check and see if we have build reuqirements 37529921a8fSScott Kruger # 37629921a8fSScott Kruger if "/*T\n" in fileStr or "/*T " in fileStr: 37729921a8fSScott Kruger # The file info is already here and need to append 37829921a8fSScott Kruger Part1=fileStr.split("T*/")[0] 37929921a8fSScott Kruger fileInfo=Part1.split("/*T")[1] 38029921a8fSScott Kruger for bkey in buildkeys: 38129921a8fSScott Kruger if bkey+":" in fileInfo: 38229921a8fSScott Kruger testDict[basename][bkey]=fileInfo.split(bkey+":")[1].split("\n")[0].strip() 38329921a8fSScott Kruger 38429921a8fSScott Kruger os.chdir(curdir) 38529921a8fSScott Kruger return testDict 38629921a8fSScott Kruger 387*6cecdbdcSScott Krugerdef parseTestDir(directory,verbosity): 38829921a8fSScott Kruger """ 38929921a8fSScott Kruger Parse single example files and return dictionary of the form: 39029921a8fSScott Kruger testDict[srcfile][test][subtest] 39129921a8fSScott Kruger """ 39229921a8fSScott Kruger curdir=os.path.realpath(os.path.curdir) 39329921a8fSScott Kruger basedir=os.path.realpath(directory) 39429921a8fSScott Kruger os.chdir(basedir) 39529921a8fSScott Kruger 39629921a8fSScott Kruger tDict={} 39729921a8fSScott Kruger for test_file in glob.glob("new_ex*.*"): 398*6cecdbdcSScott Kruger tDict.update(parseTestFile(test_file,verbosity)) 39929921a8fSScott Kruger 40029921a8fSScott Kruger os.chdir(curdir) 40129921a8fSScott Kruger return tDict 40229921a8fSScott Kruger 40329921a8fSScott Krugerdef printExParseDict(rDict): 40429921a8fSScott Kruger """ 40529921a8fSScott Kruger This is useful for debugging 40629921a8fSScott Kruger """ 40729921a8fSScott Kruger indent=" " 40829921a8fSScott Kruger for sfile in rDict: 40944776d8cSScott Kruger print sfile 41044776d8cSScott Kruger sortkeys=rDict[sfile].keys() 41144776d8cSScott Kruger sortkeys.sort() 41244776d8cSScott Kruger for runex in sortkeys: 41329921a8fSScott Kruger print indent+runex 41429921a8fSScott Kruger if type(rDict[sfile][runex])==types.StringType: 41529921a8fSScott Kruger print indent*2+rDict[sfile][runex] 41629921a8fSScott Kruger else: 41729921a8fSScott Kruger for var in rDict[sfile][runex]: 41844776d8cSScott Kruger if var.startswith("test"): continue 41944776d8cSScott Kruger print indent*2+var+": "+str(rDict[sfile][runex][var]) 42044776d8cSScott Kruger if rDict[sfile][runex].has_key('subtests'): 42144776d8cSScott Kruger for var in rDict[sfile][runex]['subtests']: 42229921a8fSScott Kruger print indent*2+var 42329921a8fSScott Kruger for var2 in rDict[sfile][runex][var]: 42429921a8fSScott Kruger print indent*3+var2+": "+str(rDict[sfile][runex][var][var2]) 42544776d8cSScott Kruger print "\n" 42629921a8fSScott Kruger return 42729921a8fSScott Kruger 42829921a8fSScott Krugerdef main(directory='',test_file='',verbosity=0): 42929921a8fSScott Kruger 43029921a8fSScott Kruger if directory: 431*6cecdbdcSScott Kruger tDict=parseTestDir(directory,verbosity) 43229921a8fSScott Kruger else: 433*6cecdbdcSScott Kruger tDict=parseTestFile(test_file,verbosity) 43429921a8fSScott Kruger if verbosity>0: printExParseDict(tDict) 43529921a8fSScott Kruger 43629921a8fSScott Kruger return 43729921a8fSScott Kruger 43829921a8fSScott Krugerif __name__ == '__main__': 43929921a8fSScott Kruger import optparse 44029921a8fSScott Kruger parser = optparse.OptionParser() 44129921a8fSScott Kruger parser.add_option('-d', '--directory', dest='directory', 44229921a8fSScott Kruger default="", help='Directory containing files to parse') 44329921a8fSScott Kruger parser.add_option('-t', '--test_file', dest='test_file', 44429921a8fSScott Kruger default="", help='Test file, e.g., ex1.c, to parse') 44529921a8fSScott Kruger parser.add_option('-v', '--verbosity', dest='verbosity', 44629921a8fSScott Kruger help='Verbosity of output by level: 1, 2, or 3', default=0) 44729921a8fSScott Kruger opts, extra_args = parser.parse_args() 44829921a8fSScott Kruger 44929921a8fSScott Kruger if extra_args: 45029921a8fSScott Kruger import sys 45129921a8fSScott Kruger sys.stderr.write('Unknown arguments: %s\n' % ' '.join(extra_args)) 45229921a8fSScott Kruger exit(1) 45329921a8fSScott Kruger if not opts.test_file and not opts.directory: 45429921a8fSScott Kruger print "test file or directory is required" 45529921a8fSScott Kruger parser.print_usage() 45629921a8fSScott Kruger sys.exit() 45729921a8fSScott Kruger 45829921a8fSScott Kruger # Need verbosity to be an integer 45929921a8fSScott Kruger try: 46029921a8fSScott Kruger verbosity=int(opts.verbosity) 46129921a8fSScott Kruger except: 46229921a8fSScott Kruger raise Exception("Error: Verbosity must be integer") 46329921a8fSScott Kruger 46429921a8fSScott Kruger main(directory=opts.directory,test_file=opts.test_file,verbosity=verbosity) 465