1df3bd252SSatish Balay#!/usr/bin/env python3 26f5e9bd5SScott Krugerimport fnmatch 36f5e9bd5SScott Krugerimport glob 46f5e9bd5SScott Krugerimport inspect 56f5e9bd5SScott Krugerimport os 66f5e9bd5SScott Krugerimport optparse 76f5e9bd5SScott Krugerimport pickle 86f5e9bd5SScott Krugerimport re 96f5e9bd5SScott Krugerimport sys 106f5e9bd5SScott Kruger 116f5e9bd5SScott Krugerthisfile = os.path.abspath(inspect.getfile(inspect.currentframe())) 1284533492SBarry Smithpetscdir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(thisfile))))) 1384533492SBarry Smithsys.path.insert(0, os.path.join(petscdir, 'config')) 146f5e9bd5SScott Kruger 156f5e9bd5SScott Krugerimport testparse 166f5e9bd5SScott Krugerfrom gmakegentest import nameSpace 176f5e9bd5SScott Kruger 186f5e9bd5SScott Kruger""" 1984533492SBarry Smith This is used by gmakefile.test for the following searches 2084533492SBarry Smith 2184533492SBarry Smith - make test search=X (or s=X) 2284533492SBarry Smith - make test query=X (or q=X) queryval=Y (or qv=Y) 2384533492SBarry Smith 246f5e9bd5SScott Kruger Which tests to query? Two options: 256f5e9bd5SScott Kruger 1. Query only the tests that are run for a given configuration. 266f5e9bd5SScott Kruger 2. Query all of the test files in the source directory 276f5e9bd5SScott Kruger For #1: 286f5e9bd5SScott Kruger Use dataDict as written out by gmakegentest.py in $PETSC_ARCH/$TESTBASE 296f5e9bd5SScott Kruger For #2: 306f5e9bd5SScott Kruger Walk the entire tree parsing the files as we go along using testparse. 316f5e9bd5SScott Kruger The tree walker is simpler than what is in gmakegentest.py 326f5e9bd5SScott Kruger 336f5e9bd5SScott Kruger The dataDict follows that generated by testparse. gmakegentest.py does 346f5e9bd5SScott Kruger further manipulations of the dataDict to handle things like for loops 356f5e9bd5SScott Kruger so if using #2, those modifications are not included. 366f5e9bd5SScott Kruger 376f5e9bd5SScott Kruger Querying: 386f5e9bd5SScott Kruger The dataDict dictionary is then "inverted" to create a dictionary with the 396f5e9bd5SScott Kruger range of field values as keys and list test names as the values. This 406f5e9bd5SScott Kruger allows fast searching 416f5e9bd5SScott Kruger 426f5e9bd5SScott Kruger""" 436f5e9bd5SScott Kruger 4485bc9deeSScott Krugerdef isFile(maybeFile): 4585bc9deeSScott Kruger ext=os.path.splitext(maybeFile)[1] 4685bc9deeSScott Kruger if not ext: return False 4785bc9deeSScott Kruger if ext not in ['.c','.cxx','.cpp','F90','F','cu']: return False 4885bc9deeSScott Kruger return True 4985bc9deeSScott Kruger 5085bc9deeSScott Krugerdef pathToLabel(path): 5185bc9deeSScott Kruger """ 5285bc9deeSScott Kruger Because the scripts have a non-unique naming, the pretty-printing 5385bc9deeSScott Kruger needs to convey the srcdir and srcfile. There are two ways of doing this. 5485bc9deeSScott Kruger """ 5585bc9deeSScott Kruger # Strip off any top-level directories or spaces 5684533492SBarry Smith path=path.strip().replace(petscdir,'') 5785bc9deeSScott Kruger path=path.replace('src/','') 5885bc9deeSScott Kruger if isFile(path): 5985bc9deeSScott Kruger prefix=os.path.dirname(path).replace("/","_") 6085bc9deeSScott Kruger suffix=os.path.splitext(os.path.basename(path))[0] 6185bc9deeSScott Kruger label=prefix+"-"+suffix+'_*' 6285bc9deeSScott Kruger else: 6385bc9deeSScott Kruger path=path.rstrip('/') 649ea87190SJacob Faibussowitsch label=path.replace("/","_").replace('tests_','tests-').replace('tutorials_','tutorials-') 6585bc9deeSScott Kruger return label 6685bc9deeSScott Kruger 6785bc9deeSScott Krugerdef get_value(varset): 6885bc9deeSScott Kruger """ 6985bc9deeSScott Kruger Searching args is a bit funky: 7085bc9deeSScott Kruger Consider 7185bc9deeSScott Kruger args: -ksp_monitor_short -pc_type ml -ksp_max_it 3 7285bc9deeSScott Kruger Search terms are: 7385bc9deeSScott Kruger ksp_monitor, 'pc_type ml', ksp_max_it 7485bc9deeSScott Kruger Also ignore all loops 7585bc9deeSScott Kruger -pc_fieldsplit_diag_use_amat {{0 1}} 7685bc9deeSScott Kruger Gives: pc_fieldsplit_diag_use_amat as the search term 7785bc9deeSScott Kruger Also ignore -f ... (use matrices from file) because I'll assume 7885bc9deeSScott Kruger that this kind of information isn't needed for testing. If it's 7985bc9deeSScott Kruger a separate search than just grep it 8085bc9deeSScott Kruger """ 8185bc9deeSScott Kruger if varset.startswith('-f '): return None 8285bc9deeSScott Kruger 8385bc9deeSScott Kruger # First remove loops 8485bc9deeSScott Kruger value=re.sub('{{.*}}','',varset) 8585bc9deeSScott Kruger # Next remove - 8685bc9deeSScott Kruger value=varset.lstrip("-") 8785bc9deeSScott Kruger # Get rid of numbers 8885bc9deeSScott Kruger value=re.sub(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?",'',value) 8985bc9deeSScott Kruger # return without spaces 9085bc9deeSScott Kruger return value.strip() 9185bc9deeSScott Kruger 9285bc9deeSScott Krugerdef query(invDict,fields,labels): 936f5e9bd5SScott Kruger """ 946f5e9bd5SScott Kruger Search the keys using fnmatch to find matching names and return list with 956f5e9bd5SScott Kruger the results 966f5e9bd5SScott Kruger """ 97d5b43468SJose E. Roman setlist=[] # setlist is a list of lists that set operations will operate on 9885bc9deeSScott Kruger llist=labels.replace('|',',').split(',') 9985bc9deeSScott Kruger i=-1 10085bc9deeSScott Kruger for field in fields.replace('|',',').split(','): 10185bc9deeSScott Kruger i+=1 10285bc9deeSScott Kruger label=llist[i] 10385bc9deeSScott Kruger if field == 'name': 10485bc9deeSScott Kruger if '/' in label: 10585bc9deeSScott Kruger label=pathToLabel(label) 106f538e455SScott Kruger elif label.startswith('src'): 107f538e455SScott Kruger label=label.lstrip('src').lstrip('*') 10885bc9deeSScott Kruger setlist.append(fnmatch.filter(invDict['name'],label)) 10985bc9deeSScott Kruger continue 1105b6dee57SScott Kruger 11185bc9deeSScott Kruger foundLabel=False # easy to do if you misspell argument search 112ca84c248SScott Kruger label=label.lower() 11385bc9deeSScott Kruger for key in invDict[field]: 114ca84c248SScott Kruger if fnmatch.filter([key.lower()],label): 11585bc9deeSScott Kruger foundLabel=True 1166f5e9bd5SScott Kruger # Do not return values with not unless label itself has not 1176f5e9bd5SScott Kruger if label.startswith('!') and not key.startswith('!'): continue 1186f5e9bd5SScott Kruger if not label.startswith('!') and key.startswith('!'): continue 11985bc9deeSScott Kruger setlist.append(invDict[field][key]) 12085bc9deeSScott Kruger if not foundLabel: 12185bc9deeSScott Kruger setlist.append([]) 1226f5e9bd5SScott Kruger 12385bc9deeSScott Kruger # Now process the union and intersection operators based on setlist 12485bc9deeSScott Kruger allresults=[] 12585bc9deeSScott Kruger # Union 12685bc9deeSScott Kruger i=-1 12785bc9deeSScott Kruger for ufield in fields.split(','): 12885bc9deeSScott Kruger i+=1 12985bc9deeSScott Kruger if '|' in ufield: 13085bc9deeSScott Kruger # Intersection 13185bc9deeSScott Kruger label=llist[i] 13285bc9deeSScott Kruger results=set(setlist[i]) 13385bc9deeSScott Kruger for field in ufield.split('|')[1:]: 13485bc9deeSScott Kruger i+=1 13585bc9deeSScott Kruger label=llist[i] 13685bc9deeSScott Kruger results=results.intersection(set(setlist[i])) 13785bc9deeSScott Kruger allresults+=list(results) 13885bc9deeSScott Kruger else: 13985bc9deeSScott Kruger allresults+=setlist[i] 1406f5e9bd5SScott Kruger 14185bc9deeSScott Kruger # remove duplicate entries and sort to give consistent results 14285bc9deeSScott Kruger uniqlist=list(set(allresults)) 14385bc9deeSScott Kruger uniqlist.sort() 14485bc9deeSScott Kruger return uniqlist 14585bc9deeSScott Kruger 14685bc9deeSScott Krugerdef get_inverse_dictionary(dataDict,fields,srcdir): 1476f5e9bd5SScott Kruger """ 1486f5e9bd5SScott Kruger Create a dictionary with the values of field as the keys, and the name of 1496f5e9bd5SScott Kruger the tests as the results. 1506f5e9bd5SScott Kruger """ 1516f5e9bd5SScott Kruger invDict={} 15285bc9deeSScott Kruger # Comma-delimited lists denote union 15385bc9deeSScott Kruger for field in fields.replace('|',',').split(','): 15485bc9deeSScott Kruger if field not in invDict: 15585bc9deeSScott Kruger if field == 'name': 15685bc9deeSScott Kruger invDict[field]=[] # List for ease 15785bc9deeSScott Kruger else: 15885bc9deeSScott Kruger invDict[field]={} 1596f5e9bd5SScott Kruger for root in dataDict: 1606f5e9bd5SScott Kruger for exfile in dataDict[root]: 1616f5e9bd5SScott Kruger for test in dataDict[root][exfile]: 162aec279ffSScott Kruger if test in testparse.buildkeys: continue 1636f5e9bd5SScott Kruger defroot = testparse.getDefaultOutputFileRoot(test) 16485bc9deeSScott Kruger fname=nameSpace(defroot,os.path.relpath(root,srcdir)) 1655b6dee57SScott Kruger if field == 'name': 16685bc9deeSScott Kruger invDict['name'].append(fname) 1675b6dee57SScott Kruger continue 1685b6dee57SScott Kruger if field not in dataDict[root][exfile][test]: continue 1696f5e9bd5SScott Kruger values=dataDict[root][exfile][test][field] 1706f5e9bd5SScott Kruger 17185bc9deeSScott Kruger if not field == 'args' and not field == 'diff_args': 1726f5e9bd5SScott Kruger for val in values.split(): 17385bc9deeSScott Kruger if val in invDict[field]: 17485bc9deeSScott Kruger invDict[field][val].append(fname) 1756f5e9bd5SScott Kruger else: 17685bc9deeSScott Kruger invDict[field][val] = [fname] 17785bc9deeSScott Kruger else: 17885bc9deeSScott Kruger # Args are funky. 1793be2e2fdSJose E. Roman for varset in re.split(r'(^|\W)-(?=[a-zA-Z])',values): 18085bc9deeSScott Kruger val=get_value(varset) 18185bc9deeSScott Kruger if not val: continue 18285bc9deeSScott Kruger if val in invDict[field]: 18385bc9deeSScott Kruger invDict[field][val].append(fname) 18485bc9deeSScott Kruger else: 18585bc9deeSScott Kruger invDict[field][val] = [fname] 18685bc9deeSScott Kruger # remove duplicate entries (multiple test/file) 18785bc9deeSScott Kruger if not field == 'name': 18885bc9deeSScott Kruger for val in invDict[field]: 18985bc9deeSScott Kruger invDict[field][val]=list(set(invDict[field][val])) 19085bc9deeSScott Kruger 1916f5e9bd5SScott Kruger return invDict 1926f5e9bd5SScott Kruger 193*8fd06648SMatthew G. Knepleydef get_gmakegentest_data(srcdir,testdir,petsc_dir,petsc_arch): 1946f5e9bd5SScott Kruger """ 1956f5e9bd5SScott Kruger Write out the dataDict into a pickle file 1966f5e9bd5SScott Kruger """ 1976f5e9bd5SScott Kruger # This needs to be consistent with gmakegentest.py of course 1984e028dedSScott Kruger pkl_file=os.path.join(testdir,'datatest.pkl') 1994e028dedSScott Kruger # If it doesn't exist, then we need to regenerate 2004e028dedSScott Kruger if not os.path.exists(pkl_file): 2014e028dedSScott Kruger startdir=os.path.abspath(os.curdir) 2024e028dedSScott Kruger os.chdir(petsc_dir) 203*8fd06648SMatthew G. Knepley args='--petsc-dir='+petsc_dir+' --petsc-arch='+petsc_arch+' --testdir='+testdir+' --srcdir='+srcdir 2044e028dedSScott Kruger buf = os.popen('config/gmakegentest.py '+args).read() 2054e028dedSScott Kruger os.chdir(startdir) 2064e028dedSScott Kruger 2074e028dedSScott Kruger fd = open(pkl_file, 'rb') 2086f5e9bd5SScott Kruger dataDict=pickle.load(fd) 2096f5e9bd5SScott Kruger fd.close() 2106f5e9bd5SScott Kruger return dataDict 2116f5e9bd5SScott Kruger 2126f5e9bd5SScott Krugerdef walktree(top): 2136f5e9bd5SScott Kruger """ 2146f5e9bd5SScott Kruger Walk a directory tree, starting from 'top' 2156f5e9bd5SScott Kruger """ 2166f5e9bd5SScott Kruger verbose = False 2176f5e9bd5SScott Kruger dataDict = {} 2186f5e9bd5SScott Kruger alldatafiles = [] 2196f5e9bd5SScott Kruger for root, dirs, files in os.walk(top, topdown=False): 2206f5e9bd5SScott Kruger if root == 'output': continue 2216f5e9bd5SScott Kruger if '.dSYM' in root: continue 2226f5e9bd5SScott Kruger if verbose: print(root) 2236f5e9bd5SScott Kruger 2246f5e9bd5SScott Kruger dataDict[root] = {} 2256f5e9bd5SScott Kruger 2266f5e9bd5SScott Kruger for exfile in files: 2276f5e9bd5SScott Kruger # Ignore emacs files 2286f5e9bd5SScott Kruger if exfile.startswith("#") or exfile.startswith(".#"): continue 2296f5e9bd5SScott Kruger ext=os.path.splitext(exfile)[1] 2306f5e9bd5SScott Kruger if ext[1:] not in ['c','cxx','cpp','cu','F90','F']: continue 2316f5e9bd5SScott Kruger 2326f5e9bd5SScott Kruger # Convenience 2336f5e9bd5SScott Kruger fullex = os.path.join(root, exfile) 2346f5e9bd5SScott Kruger if verbose: print(' --> '+fullex) 2356f5e9bd5SScott Kruger dataDict[root].update(testparse.parseTestFile(fullex, 0)) 2366f5e9bd5SScott Kruger 2376f5e9bd5SScott Kruger return dataDict 2386f5e9bd5SScott Kruger 23985bc9deeSScott Krugerdef do_query(use_source, startdir, srcdir, testdir, petsc_dir, petsc_arch, 24085bc9deeSScott Kruger fields, labels, searchin): 2416f5e9bd5SScott Kruger """ 2426f5e9bd5SScott Kruger Do the actual query 2436f5e9bd5SScott Kruger This part of the code is placed here instead of main() 2446f5e9bd5SScott Kruger to show how one could translate this into ipython/jupyer notebook 2456f5e9bd5SScott Kruger commands for more advanced queries 2466f5e9bd5SScott Kruger """ 2476f5e9bd5SScott Kruger # Get dictionary 2486f5e9bd5SScott Kruger if use_source: 2496f5e9bd5SScott Kruger dataDict=walktree(startdir) 2506f5e9bd5SScott Kruger else: 251*8fd06648SMatthew G. Knepley dataDict=get_gmakegentest_data(srcdir,testdir, petsc_dir, petsc_arch) 2526f5e9bd5SScott Kruger 2536f5e9bd5SScott Kruger # Get inverse dictionary for searching 25485bc9deeSScott Kruger invDict=get_inverse_dictionary(dataDict, fields, srcdir) 2556f5e9bd5SScott Kruger 2566f5e9bd5SScott Kruger # Now do query 25785bc9deeSScott Kruger resList=query(invDict, fields, labels) 25885bc9deeSScott Kruger 25985bc9deeSScott Kruger # Filter results using searchin 26085bc9deeSScott Kruger newresList=[] 26185bc9deeSScott Kruger if searchin.strip(): 262be89fe9eSScott Kruger if not searchin.startswith('!'): 26385bc9deeSScott Kruger for key in resList: 26485bc9deeSScott Kruger if fnmatch.filter([key],searchin): 26585bc9deeSScott Kruger newresList.append(key) 266be89fe9eSScott Kruger else: 267be89fe9eSScott Kruger for key in resList: 268be89fe9eSScott Kruger if not fnmatch.filter([key],searchin[1:]): 269be89fe9eSScott Kruger newresList.append(key) 27085bc9deeSScott Kruger resList=newresList 2716f5e9bd5SScott Kruger 2726f5e9bd5SScott Kruger # Print in flat list suitable for use by gmakefile.test 2736f5e9bd5SScott Kruger print(' '.join(resList)) 2746f5e9bd5SScott Kruger 2756f5e9bd5SScott Kruger return 2766f5e9bd5SScott Kruger 2779ea87190SJacob Faibussowitschdef expand_path_like(petscdir,petscarch,pathlike): 2789ea87190SJacob Faibussowitsch def remove_prefix(text,prefix): 2799ea87190SJacob Faibussowitsch return text[text.startswith(prefix) and len(prefix):] 2809ea87190SJacob Faibussowitsch 2819ea87190SJacob Faibussowitsch # expand user second, as expandvars may insert a '~' 2829ea87190SJacob Faibussowitsch string = os.path.expanduser(os.path.expandvars(pathlike)) 2839ea87190SJacob Faibussowitsch # if the dirname check succeeds then likely we have a glob expression 2849ea87190SJacob Faibussowitsch pardir = os.path.dirname(string) 2859ea87190SJacob Faibussowitsch if os.path.exists(pardir): 2869ea87190SJacob Faibussowitsch suffix = string.replace(pardir,'') # get whatever is left over 2879ea87190SJacob Faibussowitsch pathlike = remove_prefix(os.path.relpath(os.path.abspath(pardir),petscdir),'.'+os.path.sep) 2889ea87190SJacob Faibussowitsch if petscarch == '': 2899ea87190SJacob Faibussowitsch pathlike = pathlike.replace(os.path.sep.join(('share','petsc','examples'))+'/','') 2909ea87190SJacob Faibussowitsch pathlike += suffix 29184533492SBarry Smith pathlike = pathlike.replace('diff-','') 2929ea87190SJacob Faibussowitsch return pathlike 2939ea87190SJacob Faibussowitsch 2946f5e9bd5SScott Krugerdef main(): 2956f5e9bd5SScott Kruger parser = optparse.OptionParser(usage="%prog [options] field match_pattern") 2966f5e9bd5SScott Kruger parser.add_option('-s', '--startdir', dest='startdir', 2976f5e9bd5SScott Kruger help='Where to start the recursion if not srcdir', 2986f5e9bd5SScott Kruger default='') 299aec279ffSScott Kruger parser.add_option('-p', '--petsc-dir', dest='petsc_dir', 300aec279ffSScott Kruger help='Set PETSC_DIR different from environment', 3016f5e9bd5SScott Kruger default=os.environ.get('PETSC_DIR')) 3026f5e9bd5SScott Kruger parser.add_option('-a', '--petsc-arch', dest='petsc_arch', 3036f5e9bd5SScott Kruger help='Set PETSC_ARCH different from environment', 3046f5e9bd5SScott Kruger default=os.environ.get('PETSC_ARCH')) 3056f5e9bd5SScott Kruger parser.add_option('--srcdir', dest='srcdir', 3066f5e9bd5SScott Kruger help='Set location of sources different from PETSC_DIR/src. Must be full path.', 3076f5e9bd5SScott Kruger default='src') 3086f5e9bd5SScott Kruger parser.add_option('-t', '--testdir', dest='testdir', 3096f5e9bd5SScott Kruger help='Test directory if not PETSC_ARCH/tests. Must be full path', 3106f5e9bd5SScott Kruger default='tests') 3116f5e9bd5SScott Kruger parser.add_option('-u', '--use-source', action="store_false", 3126f5e9bd5SScott Kruger dest='use_source', 3136f5e9bd5SScott Kruger help='Query all sources rather than those configured in PETSC_ARCH') 31485bc9deeSScott Kruger parser.add_option('-i', '--searchin', dest='searchin', 31585bc9deeSScott Kruger help='Filter results from the arguments', 31685bc9deeSScott Kruger default='') 3176f5e9bd5SScott Kruger 3186f5e9bd5SScott Kruger opts, args = parser.parse_args() 3196f5e9bd5SScott Kruger 3206f5e9bd5SScott Kruger # Argument Sanity checks 3216f5e9bd5SScott Kruger if len(args) != 2: 3226f5e9bd5SScott Kruger parser.print_usage() 3236f5e9bd5SScott Kruger print('Arguments: ') 3246f5e9bd5SScott Kruger print(' field: Field to search for; e.g., requires') 3255b6dee57SScott Kruger print(' To just match names, use "name"') 3266f5e9bd5SScott Kruger print(' match_pattern: Matching pattern for field; e.g., cuda') 3276f5e9bd5SScott Kruger return 3286f5e9bd5SScott Kruger 3293c5439e2SJacob Faibussowitsch def shell_unquote(string): 3303c5439e2SJacob Faibussowitsch """ 3313c5439e2SJacob Faibussowitsch Remove quotes from STRING. Useful in the case where you need to bury escaped quotes in a query 3323c5439e2SJacob Faibussowitsch string in order to escape shell characters. For example: 3333c5439e2SJacob Faibussowitsch 3343c5439e2SJacob Faibussowitsch $ make test query='foo,bar' queryval='requires|name' 3353c5439e2SJacob Faibussowitsch /usr/bin/bash: line 1: name: command not found 3363c5439e2SJacob Faibussowitsch 3373c5439e2SJacob Faibussowitsch While the original shell does not see the pipe character, the actual query is done via a second 3383c5439e2SJacob Faibussowitsch shell, which is (literally) passed '$(queryval)', i.e. 'queryval='requires|name'' when expanded. 3393c5439e2SJacob Faibussowitsch Note the fact that the expansion cancels out the quoting!!! 3403c5439e2SJacob Faibussowitsch 3413c5439e2SJacob Faibussowitsch You can fix this by doing: 3423c5439e2SJacob Faibussowitsch 3433c5439e2SJacob Faibussowitsch $ make test query='foo,bar' queryval='"requires|name"' 3443c5439e2SJacob Faibussowitsch 3453c5439e2SJacob Faibussowitsch However this then shows up here as labels = 'queryval="requires|name"'. So we need to remove the 3463c5439e2SJacob Faibussowitsch '"'. Applying shlex.split() on this returns: 3473c5439e2SJacob Faibussowitsch 3483c5439e2SJacob Faibussowitsch >>> shlex.split('queryval="requires|name"') 3493c5439e2SJacob Faibussowitsch ['queryval=requires|name'] 3503c5439e2SJacob Faibussowitsch 3513c5439e2SJacob Faibussowitsch And voila. Note also that: 3523c5439e2SJacob Faibussowitsch 3533c5439e2SJacob Faibussowitsch >>> shlex.split('queryval=requires|name') 3543c5439e2SJacob Faibussowitsch ['queryval=requires|name'] 3553c5439e2SJacob Faibussowitsch """ 3563c5439e2SJacob Faibussowitsch import shlex 3573c5439e2SJacob Faibussowitsch 3583c5439e2SJacob Faibussowitsch if string: 3593c5439e2SJacob Faibussowitsch ret = shlex.split(string) 3603c5439e2SJacob Faibussowitsch assert len(ret) == 1, "Dont know what to do if shlex.split() produces more than 1 value?" 3613c5439e2SJacob Faibussowitsch string = ret[0] 3623c5439e2SJacob Faibussowitsch return string 3633c5439e2SJacob Faibussowitsch 364168c8686SJacob Faibussowitsch def alternate_command_preprocess(string): 365168c8686SJacob Faibussowitsch """ 366168c8686SJacob Faibussowitsch Replace the alternate versions in STRING with the regular variants 367168c8686SJacob Faibussowitsch """ 368168c8686SJacob Faibussowitsch return string.replace('%OR%', '|').replace('%AND%', ',').replace('%NEG%', '!') 369168c8686SJacob Faibussowitsch 3706f5e9bd5SScott Kruger # Process arguments and options -- mostly just paths here 371168c8686SJacob Faibussowitsch field=alternate_command_preprocess(shell_unquote(args[0])) 37284533492SBarry Smith labels=alternate_command_preprocess(shell_unquote(args[1])) 37385bc9deeSScott Kruger searchin=opts.searchin 3746f5e9bd5SScott Kruger 3756f5e9bd5SScott Kruger petsc_dir = opts.petsc_dir 3766f5e9bd5SScott Kruger petsc_arch = opts.petsc_arch 3776f5e9bd5SScott Kruger petsc_full_arch = os.path.join(petsc_dir, petsc_arch) 3786f5e9bd5SScott Kruger 37958780e5dSStefano Zampini if petsc_arch == '': 38058780e5dSStefano Zampini petsc_full_src = os.path.join(petsc_dir, 'share', 'petsc', 'examples', 'src') 38158780e5dSStefano Zampini else: 3826f5e9bd5SScott Kruger if opts.srcdir == 'src': 3836f5e9bd5SScott Kruger petsc_full_src = os.path.join(petsc_dir, 'src') 3846f5e9bd5SScott Kruger else: 3856f5e9bd5SScott Kruger petsc_full_src = opts.srcdir 3866f5e9bd5SScott Kruger if opts.testdir == 'tests': 3876f5e9bd5SScott Kruger petsc_full_test = os.path.join(petsc_full_arch, 'tests') 3886f5e9bd5SScott Kruger else: 3896f5e9bd5SScott Kruger petsc_full_test = opts.testdir 3906f5e9bd5SScott Kruger if opts.startdir: 3916f5e9bd5SScott Kruger startdir=opts.startdir=petsc_full_src 3926f5e9bd5SScott Kruger else: 3936f5e9bd5SScott Kruger startdir=petsc_full_src 3946f5e9bd5SScott Kruger 3956f5e9bd5SScott Kruger # Options Sanity checks 3966f5e9bd5SScott Kruger if not os.path.isdir(petsc_dir): 3976f5e9bd5SScott Kruger print("PETSC_DIR must be a directory") 3986f5e9bd5SScott Kruger return 3996f5e9bd5SScott Kruger 4006f5e9bd5SScott Kruger if not opts.use_source: 4016f5e9bd5SScott Kruger if not os.path.isdir(petsc_full_arch): 4026f5e9bd5SScott Kruger print("PETSC_DIR/PETSC_ARCH must be a directory") 4036f5e9bd5SScott Kruger return 4046f5e9bd5SScott Kruger elif not os.path.isdir(petsc_full_test): 4056f5e9bd5SScott Kruger print("Testdir must be a directory"+petsc_full_test) 4066f5e9bd5SScott Kruger return 4076f5e9bd5SScott Kruger else: 4086f5e9bd5SScott Kruger if not os.path.isdir(petsc_full_src): 4096f5e9bd5SScott Kruger print("Source directory must be a directory"+petsc_full_src) 4106f5e9bd5SScott Kruger return 4116f5e9bd5SScott Kruger 41284533492SBarry Smith labels = expand_path_like(petsc_dir,petsc_arch,labels) 4139ea87190SJacob Faibussowitsch 4146f5e9bd5SScott Kruger # Do the actual query 4154e028dedSScott Kruger do_query(opts.use_source, startdir, petsc_full_src, petsc_full_test, 41684533492SBarry Smith petsc_dir, petsc_arch, field, labels, searchin) 4176f5e9bd5SScott Kruger 4186f5e9bd5SScott Kruger return 4196f5e9bd5SScott Kruger 4206f5e9bd5SScott Krugerif __name__ == "__main__": 4216f5e9bd5SScott Kruger main() 422