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())) 12*84533492SBarry Smithpetscdir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(thisfile))))) 13*84533492SBarry Smithsys.path.insert(0, os.path.join(petscdir, 'config')) 146f5e9bd5SScott Kruger 156f5e9bd5SScott Krugerimport testparse 166f5e9bd5SScott Krugerfrom gmakegentest import nameSpace 176f5e9bd5SScott Kruger 186f5e9bd5SScott Kruger 196f5e9bd5SScott Kruger""" 20*84533492SBarry Smith This is used by gmakefile.test for the following searches 21*84533492SBarry Smith 22*84533492SBarry Smith - make test search=X (or s=X) 23*84533492SBarry Smith - make test query=X (or q=X) queryval=Y (or qv=Y) 24*84533492SBarry Smith 256f5e9bd5SScott Kruger 266f5e9bd5SScott Kruger Which tests to query? Two options: 276f5e9bd5SScott Kruger 1. Query only the tests that are run for a given configuration. 286f5e9bd5SScott Kruger 2. Query all of the test files in the source directory 296f5e9bd5SScott Kruger For #1: 306f5e9bd5SScott Kruger Use dataDict as written out by gmakegentest.py in $PETSC_ARCH/$TESTBASE 316f5e9bd5SScott Kruger For #2: 326f5e9bd5SScott Kruger Walk the entire tree parsing the files as we go along using testparse. 336f5e9bd5SScott Kruger The tree walker is simpler than what is in gmakegentest.py 346f5e9bd5SScott Kruger 356f5e9bd5SScott Kruger The dataDict follows that generated by testparse. gmakegentest.py does 366f5e9bd5SScott Kruger further manipulations of the dataDict to handle things like for loops 376f5e9bd5SScott Kruger so if using #2, those modifications are not included. 386f5e9bd5SScott Kruger 396f5e9bd5SScott Kruger Querying: 406f5e9bd5SScott Kruger The dataDict dictionary is then "inverted" to create a dictionary with the 416f5e9bd5SScott Kruger range of field values as keys and list test names as the values. This 426f5e9bd5SScott Kruger allows fast searching 436f5e9bd5SScott Kruger 446f5e9bd5SScott Kruger""" 456f5e9bd5SScott Kruger 4685bc9deeSScott Krugerdef isFile(maybeFile): 4785bc9deeSScott Kruger ext=os.path.splitext(maybeFile)[1] 4885bc9deeSScott Kruger if not ext: return False 4985bc9deeSScott Kruger if ext not in ['.c','.cxx','.cpp','F90','F','cu']: return False 5085bc9deeSScott Kruger return True 5185bc9deeSScott Kruger 5285bc9deeSScott Krugerdef pathToLabel(path): 5385bc9deeSScott Kruger """ 5485bc9deeSScott Kruger Because the scripts have a non-unique naming, the pretty-printing 5585bc9deeSScott Kruger needs to convey the srcdir and srcfile. There are two ways of doing this. 5685bc9deeSScott Kruger """ 5785bc9deeSScott Kruger # Strip off any top-level directories or spaces 58*84533492SBarry Smith path=path.strip().replace(petscdir,'') 5985bc9deeSScott Kruger path=path.replace('src/','') 6085bc9deeSScott Kruger if isFile(path): 6185bc9deeSScott Kruger prefix=os.path.dirname(path).replace("/","_") 6285bc9deeSScott Kruger suffix=os.path.splitext(os.path.basename(path))[0] 6385bc9deeSScott Kruger label=prefix+"-"+suffix+'_*' 6485bc9deeSScott Kruger else: 6585bc9deeSScott Kruger path=path.rstrip('/') 669ea87190SJacob Faibussowitsch label=path.replace("/","_").replace('tests_','tests-').replace('tutorials_','tutorials-') 6785bc9deeSScott Kruger return label 6885bc9deeSScott Kruger 6985bc9deeSScott Krugerdef get_value(varset): 7085bc9deeSScott Kruger """ 7185bc9deeSScott Kruger Searching args is a bit funky: 7285bc9deeSScott Kruger Consider 7385bc9deeSScott Kruger args: -ksp_monitor_short -pc_type ml -ksp_max_it 3 7485bc9deeSScott Kruger Search terms are: 7585bc9deeSScott Kruger ksp_monitor, 'pc_type ml', ksp_max_it 7685bc9deeSScott Kruger Also ignore all loops 7785bc9deeSScott Kruger -pc_fieldsplit_diag_use_amat {{0 1}} 7885bc9deeSScott Kruger Gives: pc_fieldsplit_diag_use_amat as the search term 7985bc9deeSScott Kruger Also ignore -f ... (use matrices from file) because I'll assume 8085bc9deeSScott Kruger that this kind of information isn't needed for testing. If it's 8185bc9deeSScott Kruger a separate search than just grep it 8285bc9deeSScott Kruger """ 8385bc9deeSScott Kruger if varset.startswith('-f '): return None 8485bc9deeSScott Kruger 8585bc9deeSScott Kruger # First remove loops 8685bc9deeSScott Kruger value=re.sub('{{.*}}','',varset) 8785bc9deeSScott Kruger # Next remove - 8885bc9deeSScott Kruger value=varset.lstrip("-") 8985bc9deeSScott Kruger # Get rid of numbers 9085bc9deeSScott Kruger value=re.sub(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?",'',value) 9185bc9deeSScott Kruger # return without spaces 9285bc9deeSScott Kruger return value.strip() 9385bc9deeSScott Kruger 9485bc9deeSScott Krugerdef query(invDict,fields,labels): 956f5e9bd5SScott Kruger """ 966f5e9bd5SScott Kruger Search the keys using fnmatch to find matching names and return list with 976f5e9bd5SScott Kruger the results 986f5e9bd5SScott Kruger """ 99d5b43468SJose E. Roman setlist=[] # setlist is a list of lists that set operations will operate on 10085bc9deeSScott Kruger llist=labels.replace('|',',').split(',') 10185bc9deeSScott Kruger i=-1 10285bc9deeSScott Kruger for field in fields.replace('|',',').split(','): 10385bc9deeSScott Kruger i+=1 10485bc9deeSScott Kruger label=llist[i] 10585bc9deeSScott Kruger if field == 'name': 10685bc9deeSScott Kruger if '/' in label: 10785bc9deeSScott Kruger label=pathToLabel(label) 108f538e455SScott Kruger elif label.startswith('src'): 109f538e455SScott Kruger label=label.lstrip('src').lstrip('*') 11085bc9deeSScott Kruger setlist.append(fnmatch.filter(invDict['name'],label)) 11185bc9deeSScott Kruger continue 1125b6dee57SScott Kruger 11385bc9deeSScott Kruger foundLabel=False # easy to do if you misspell argument search 114ca84c248SScott Kruger label=label.lower() 11585bc9deeSScott Kruger for key in invDict[field]: 116ca84c248SScott Kruger if fnmatch.filter([key.lower()],label): 11785bc9deeSScott Kruger foundLabel=True 1186f5e9bd5SScott Kruger # Do not return values with not unless label itself has not 1196f5e9bd5SScott Kruger if label.startswith('!') and not key.startswith('!'): continue 1206f5e9bd5SScott Kruger if not label.startswith('!') and key.startswith('!'): continue 12185bc9deeSScott Kruger setlist.append(invDict[field][key]) 12285bc9deeSScott Kruger if not foundLabel: 12385bc9deeSScott Kruger setlist.append([]) 1246f5e9bd5SScott Kruger 12585bc9deeSScott Kruger # Now process the union and intersection operators based on setlist 12685bc9deeSScott Kruger allresults=[] 12785bc9deeSScott Kruger # Union 12885bc9deeSScott Kruger i=-1 12985bc9deeSScott Kruger for ufield in fields.split(','): 13085bc9deeSScott Kruger i+=1 13185bc9deeSScott Kruger if '|' in ufield: 13285bc9deeSScott Kruger # Intersection 13385bc9deeSScott Kruger label=llist[i] 13485bc9deeSScott Kruger results=set(setlist[i]) 13585bc9deeSScott Kruger for field in ufield.split('|')[1:]: 13685bc9deeSScott Kruger i+=1 13785bc9deeSScott Kruger label=llist[i] 13885bc9deeSScott Kruger results=results.intersection(set(setlist[i])) 13985bc9deeSScott Kruger allresults+=list(results) 14085bc9deeSScott Kruger else: 14185bc9deeSScott Kruger allresults+=setlist[i] 1426f5e9bd5SScott Kruger 14385bc9deeSScott Kruger # remove duplicate entries and sort to give consistent results 14485bc9deeSScott Kruger uniqlist=list(set(allresults)) 14585bc9deeSScott Kruger uniqlist.sort() 14685bc9deeSScott Kruger return uniqlist 14785bc9deeSScott Kruger 14885bc9deeSScott Krugerdef get_inverse_dictionary(dataDict,fields,srcdir): 1496f5e9bd5SScott Kruger """ 1506f5e9bd5SScott Kruger Create a dictionary with the values of field as the keys, and the name of 1516f5e9bd5SScott Kruger the tests as the results. 1526f5e9bd5SScott Kruger """ 1536f5e9bd5SScott Kruger invDict={} 15485bc9deeSScott Kruger # Comma-delimited lists denote union 15585bc9deeSScott Kruger for field in fields.replace('|',',').split(','): 15685bc9deeSScott Kruger if field not in invDict: 15785bc9deeSScott Kruger if field == 'name': 15885bc9deeSScott Kruger invDict[field]=[] # List for ease 15985bc9deeSScott Kruger else: 16085bc9deeSScott Kruger invDict[field]={} 1616f5e9bd5SScott Kruger for root in dataDict: 1626f5e9bd5SScott Kruger for exfile in dataDict[root]: 1636f5e9bd5SScott Kruger for test in dataDict[root][exfile]: 164aec279ffSScott Kruger if test in testparse.buildkeys: continue 1656f5e9bd5SScott Kruger defroot = testparse.getDefaultOutputFileRoot(test) 16685bc9deeSScott Kruger fname=nameSpace(defroot,os.path.relpath(root,srcdir)) 1675b6dee57SScott Kruger if field == 'name': 16885bc9deeSScott Kruger invDict['name'].append(fname) 1695b6dee57SScott Kruger continue 1705b6dee57SScott Kruger if field not in dataDict[root][exfile][test]: continue 1716f5e9bd5SScott Kruger values=dataDict[root][exfile][test][field] 1726f5e9bd5SScott Kruger 17385bc9deeSScott Kruger if not field == 'args' and not field == 'diff_args': 1746f5e9bd5SScott Kruger for val in values.split(): 17585bc9deeSScott Kruger if val in invDict[field]: 17685bc9deeSScott Kruger invDict[field][val].append(fname) 1776f5e9bd5SScott Kruger else: 17885bc9deeSScott Kruger invDict[field][val] = [fname] 17985bc9deeSScott Kruger else: 18085bc9deeSScott Kruger # Args are funky. 1813be2e2fdSJose E. Roman for varset in re.split(r'(^|\W)-(?=[a-zA-Z])',values): 18285bc9deeSScott Kruger val=get_value(varset) 18385bc9deeSScott Kruger if not val: continue 18485bc9deeSScott Kruger if val in invDict[field]: 18585bc9deeSScott Kruger invDict[field][val].append(fname) 18685bc9deeSScott Kruger else: 18785bc9deeSScott Kruger invDict[field][val] = [fname] 18885bc9deeSScott Kruger # remove duplicate entries (multiple test/file) 18985bc9deeSScott Kruger if not field == 'name': 19085bc9deeSScott Kruger for val in invDict[field]: 19185bc9deeSScott Kruger invDict[field][val]=list(set(invDict[field][val])) 19285bc9deeSScott Kruger 1936f5e9bd5SScott Kruger return invDict 1946f5e9bd5SScott Kruger 1954e028dedSScott Krugerdef get_gmakegentest_data(testdir,petsc_dir,petsc_arch): 1966f5e9bd5SScott Kruger """ 1976f5e9bd5SScott Kruger Write out the dataDict into a pickle file 1986f5e9bd5SScott Kruger """ 1996f5e9bd5SScott Kruger # This needs to be consistent with gmakegentest.py of course 2004e028dedSScott Kruger pkl_file=os.path.join(testdir,'datatest.pkl') 2014e028dedSScott Kruger # If it doesn't exist, then we need to regenerate 2024e028dedSScott Kruger if not os.path.exists(pkl_file): 2034e028dedSScott Kruger startdir=os.path.abspath(os.curdir) 2044e028dedSScott Kruger os.chdir(petsc_dir) 2054e028dedSScott Kruger args='--petsc-dir='+petsc_dir+' --petsc-arch='+petsc_arch+' --testdir='+testdir 2064e028dedSScott Kruger buf = os.popen('config/gmakegentest.py '+args).read() 2074e028dedSScott Kruger os.chdir(startdir) 2084e028dedSScott Kruger 2094e028dedSScott Kruger fd = open(pkl_file, 'rb') 2106f5e9bd5SScott Kruger dataDict=pickle.load(fd) 2116f5e9bd5SScott Kruger fd.close() 2126f5e9bd5SScott Kruger return dataDict 2136f5e9bd5SScott Kruger 2146f5e9bd5SScott Krugerdef walktree(top): 2156f5e9bd5SScott Kruger """ 2166f5e9bd5SScott Kruger Walk a directory tree, starting from 'top' 2176f5e9bd5SScott Kruger """ 2186f5e9bd5SScott Kruger verbose = False 2196f5e9bd5SScott Kruger dataDict = {} 2206f5e9bd5SScott Kruger alldatafiles = [] 2216f5e9bd5SScott Kruger for root, dirs, files in os.walk(top, topdown=False): 2226f5e9bd5SScott Kruger if root == 'output': continue 2236f5e9bd5SScott Kruger if '.dSYM' in root: continue 2246f5e9bd5SScott Kruger if verbose: print(root) 2256f5e9bd5SScott Kruger 2266f5e9bd5SScott Kruger dataDict[root] = {} 2276f5e9bd5SScott Kruger 2286f5e9bd5SScott Kruger for exfile in files: 2296f5e9bd5SScott Kruger # Ignore emacs files 2306f5e9bd5SScott Kruger if exfile.startswith("#") or exfile.startswith(".#"): continue 2316f5e9bd5SScott Kruger ext=os.path.splitext(exfile)[1] 2326f5e9bd5SScott Kruger if ext[1:] not in ['c','cxx','cpp','cu','F90','F']: continue 2336f5e9bd5SScott Kruger 2346f5e9bd5SScott Kruger # Convenience 2356f5e9bd5SScott Kruger fullex = os.path.join(root, exfile) 2366f5e9bd5SScott Kruger if verbose: print(' --> '+fullex) 2376f5e9bd5SScott Kruger dataDict[root].update(testparse.parseTestFile(fullex, 0)) 2386f5e9bd5SScott Kruger 2396f5e9bd5SScott Kruger return dataDict 2406f5e9bd5SScott Kruger 24185bc9deeSScott Krugerdef do_query(use_source, startdir, srcdir, testdir, petsc_dir, petsc_arch, 24285bc9deeSScott Kruger fields, labels, searchin): 2436f5e9bd5SScott Kruger """ 2446f5e9bd5SScott Kruger Do the actual query 2456f5e9bd5SScott Kruger This part of the code is placed here instead of main() 2466f5e9bd5SScott Kruger to show how one could translate this into ipython/jupyer notebook 2476f5e9bd5SScott Kruger commands for more advanced queries 2486f5e9bd5SScott Kruger """ 2496f5e9bd5SScott Kruger # Get dictionary 2506f5e9bd5SScott Kruger if use_source: 2516f5e9bd5SScott Kruger dataDict=walktree(startdir) 2526f5e9bd5SScott Kruger else: 2534e028dedSScott Kruger dataDict=get_gmakegentest_data(testdir, petsc_dir, petsc_arch) 2546f5e9bd5SScott Kruger 2556f5e9bd5SScott Kruger # Get inverse dictionary for searching 25685bc9deeSScott Kruger invDict=get_inverse_dictionary(dataDict, fields, srcdir) 2576f5e9bd5SScott Kruger 2586f5e9bd5SScott Kruger # Now do query 25985bc9deeSScott Kruger resList=query(invDict, fields, labels) 26085bc9deeSScott Kruger 26185bc9deeSScott Kruger # Filter results using searchin 26285bc9deeSScott Kruger newresList=[] 26385bc9deeSScott Kruger if searchin.strip(): 264be89fe9eSScott Kruger if not searchin.startswith('!'): 26585bc9deeSScott Kruger for key in resList: 26685bc9deeSScott Kruger if fnmatch.filter([key],searchin): 26785bc9deeSScott Kruger newresList.append(key) 268be89fe9eSScott Kruger else: 269be89fe9eSScott Kruger for key in resList: 270be89fe9eSScott Kruger if not fnmatch.filter([key],searchin[1:]): 271be89fe9eSScott Kruger newresList.append(key) 27285bc9deeSScott Kruger resList=newresList 2736f5e9bd5SScott Kruger 2746f5e9bd5SScott Kruger # Print in flat list suitable for use by gmakefile.test 2756f5e9bd5SScott Kruger print(' '.join(resList)) 2766f5e9bd5SScott Kruger 2776f5e9bd5SScott Kruger return 2786f5e9bd5SScott Kruger 2799ea87190SJacob Faibussowitschdef expand_path_like(petscdir,petscarch,pathlike): 2809ea87190SJacob Faibussowitsch def remove_prefix(text,prefix): 2819ea87190SJacob Faibussowitsch return text[text.startswith(prefix) and len(prefix):] 2829ea87190SJacob Faibussowitsch 2839ea87190SJacob Faibussowitsch # expand user second, as expandvars may insert a '~' 2849ea87190SJacob Faibussowitsch string = os.path.expanduser(os.path.expandvars(pathlike)) 2859ea87190SJacob Faibussowitsch # if the dirname check succeeds then likely we have a glob expression 2869ea87190SJacob Faibussowitsch pardir = os.path.dirname(string) 2879ea87190SJacob Faibussowitsch if os.path.exists(pardir): 2889ea87190SJacob Faibussowitsch suffix = string.replace(pardir,'') # get whatever is left over 2899ea87190SJacob Faibussowitsch pathlike = remove_prefix(os.path.relpath(os.path.abspath(pardir),petscdir),'.'+os.path.sep) 2909ea87190SJacob Faibussowitsch if petscarch == '': 2919ea87190SJacob Faibussowitsch pathlike = pathlike.replace(os.path.sep.join(('share','petsc','examples'))+'/','') 2929ea87190SJacob Faibussowitsch pathlike += suffix 293*84533492SBarry Smith pathlike = pathlike.replace('diff-','') 2949ea87190SJacob Faibussowitsch return pathlike 2959ea87190SJacob Faibussowitsch 2966f5e9bd5SScott Krugerdef main(): 2976f5e9bd5SScott Kruger parser = optparse.OptionParser(usage="%prog [options] field match_pattern") 2986f5e9bd5SScott Kruger parser.add_option('-s', '--startdir', dest='startdir', 2996f5e9bd5SScott Kruger help='Where to start the recursion if not srcdir', 3006f5e9bd5SScott Kruger default='') 301aec279ffSScott Kruger parser.add_option('-p', '--petsc-dir', dest='petsc_dir', 302aec279ffSScott Kruger help='Set PETSC_DIR different from environment', 3036f5e9bd5SScott Kruger default=os.environ.get('PETSC_DIR')) 3046f5e9bd5SScott Kruger parser.add_option('-a', '--petsc-arch', dest='petsc_arch', 3056f5e9bd5SScott Kruger help='Set PETSC_ARCH different from environment', 3066f5e9bd5SScott Kruger default=os.environ.get('PETSC_ARCH')) 3076f5e9bd5SScott Kruger parser.add_option('--srcdir', dest='srcdir', 3086f5e9bd5SScott Kruger help='Set location of sources different from PETSC_DIR/src. Must be full path.', 3096f5e9bd5SScott Kruger default='src') 3106f5e9bd5SScott Kruger parser.add_option('-t', '--testdir', dest='testdir', 3116f5e9bd5SScott Kruger help='Test directory if not PETSC_ARCH/tests. Must be full path', 3126f5e9bd5SScott Kruger default='tests') 3136f5e9bd5SScott Kruger parser.add_option('-u', '--use-source', action="store_false", 3146f5e9bd5SScott Kruger dest='use_source', 3156f5e9bd5SScott Kruger help='Query all sources rather than those configured in PETSC_ARCH') 31685bc9deeSScott Kruger parser.add_option('-i', '--searchin', dest='searchin', 31785bc9deeSScott Kruger help='Filter results from the arguments', 31885bc9deeSScott Kruger default='') 3196f5e9bd5SScott Kruger 3206f5e9bd5SScott Kruger opts, args = parser.parse_args() 3216f5e9bd5SScott Kruger 3226f5e9bd5SScott Kruger # Argument Sanity checks 3236f5e9bd5SScott Kruger if len(args) != 2: 3246f5e9bd5SScott Kruger parser.print_usage() 3256f5e9bd5SScott Kruger print('Arguments: ') 3266f5e9bd5SScott Kruger print(' field: Field to search for; e.g., requires') 3275b6dee57SScott Kruger print(' To just match names, use "name"') 3286f5e9bd5SScott Kruger print(' match_pattern: Matching pattern for field; e.g., cuda') 3296f5e9bd5SScott Kruger return 3306f5e9bd5SScott Kruger 3313c5439e2SJacob Faibussowitsch def shell_unquote(string): 3323c5439e2SJacob Faibussowitsch """ 3333c5439e2SJacob Faibussowitsch Remove quotes from STRING. Useful in the case where you need to bury escaped quotes in a query 3343c5439e2SJacob Faibussowitsch string in order to escape shell characters. For example: 3353c5439e2SJacob Faibussowitsch 3363c5439e2SJacob Faibussowitsch $ make test query='foo,bar' queryval='requires|name' 3373c5439e2SJacob Faibussowitsch /usr/bin/bash: line 1: name: command not found 3383c5439e2SJacob Faibussowitsch 3393c5439e2SJacob Faibussowitsch While the original shell does not see the pipe character, the actual query is done via a second 3403c5439e2SJacob Faibussowitsch shell, which is (literally) passed '$(queryval)', i.e. 'queryval='requires|name'' when expanded. 3413c5439e2SJacob Faibussowitsch Note the fact that the expansion cancels out the quoting!!! 3423c5439e2SJacob Faibussowitsch 3433c5439e2SJacob Faibussowitsch You can fix this by doing: 3443c5439e2SJacob Faibussowitsch 3453c5439e2SJacob Faibussowitsch $ make test query='foo,bar' queryval='"requires|name"' 3463c5439e2SJacob Faibussowitsch 3473c5439e2SJacob Faibussowitsch However this then shows up here as labels = 'queryval="requires|name"'. So we need to remove the 3483c5439e2SJacob Faibussowitsch '"'. Applying shlex.split() on this returns: 3493c5439e2SJacob Faibussowitsch 3503c5439e2SJacob Faibussowitsch >>> shlex.split('queryval="requires|name"') 3513c5439e2SJacob Faibussowitsch ['queryval=requires|name'] 3523c5439e2SJacob Faibussowitsch 3533c5439e2SJacob Faibussowitsch And voila. Note also that: 3543c5439e2SJacob Faibussowitsch 3553c5439e2SJacob Faibussowitsch >>> shlex.split('queryval=requires|name') 3563c5439e2SJacob Faibussowitsch ['queryval=requires|name'] 3573c5439e2SJacob Faibussowitsch """ 3583c5439e2SJacob Faibussowitsch import shlex 3593c5439e2SJacob Faibussowitsch 3603c5439e2SJacob Faibussowitsch if string: 3613c5439e2SJacob Faibussowitsch ret = shlex.split(string) 3623c5439e2SJacob Faibussowitsch assert len(ret) == 1, "Dont know what to do if shlex.split() produces more than 1 value?" 3633c5439e2SJacob Faibussowitsch string = ret[0] 3643c5439e2SJacob Faibussowitsch return string 3653c5439e2SJacob Faibussowitsch 366168c8686SJacob Faibussowitsch def alternate_command_preprocess(string): 367168c8686SJacob Faibussowitsch """ 368168c8686SJacob Faibussowitsch Replace the alternate versions in STRING with the regular variants 369168c8686SJacob Faibussowitsch """ 370168c8686SJacob Faibussowitsch return string.replace('%OR%', '|').replace('%AND%', ',').replace('%NEG%', '!') 371168c8686SJacob Faibussowitsch 3726f5e9bd5SScott Kruger # Process arguments and options -- mostly just paths here 373168c8686SJacob Faibussowitsch field=alternate_command_preprocess(shell_unquote(args[0])) 374*84533492SBarry Smith labels=alternate_command_preprocess(shell_unquote(args[1])) 37585bc9deeSScott Kruger searchin=opts.searchin 3766f5e9bd5SScott Kruger 3776f5e9bd5SScott Kruger petsc_dir = opts.petsc_dir 3786f5e9bd5SScott Kruger petsc_arch = opts.petsc_arch 3796f5e9bd5SScott Kruger petsc_full_arch = os.path.join(petsc_dir, petsc_arch) 3806f5e9bd5SScott Kruger 38158780e5dSStefano Zampini if petsc_arch == '': 38258780e5dSStefano Zampini petsc_full_src = os.path.join(petsc_dir, 'share', 'petsc', 'examples', 'src') 38358780e5dSStefano Zampini else: 3846f5e9bd5SScott Kruger if opts.srcdir == 'src': 3856f5e9bd5SScott Kruger petsc_full_src = os.path.join(petsc_dir, 'src') 3866f5e9bd5SScott Kruger else: 3876f5e9bd5SScott Kruger petsc_full_src = opts.srcdir 3886f5e9bd5SScott Kruger if opts.testdir == 'tests': 3896f5e9bd5SScott Kruger petsc_full_test = os.path.join(petsc_full_arch, 'tests') 3906f5e9bd5SScott Kruger else: 3916f5e9bd5SScott Kruger petsc_full_test = opts.testdir 3926f5e9bd5SScott Kruger if opts.startdir: 3936f5e9bd5SScott Kruger startdir=opts.startdir=petsc_full_src 3946f5e9bd5SScott Kruger else: 3956f5e9bd5SScott Kruger startdir=petsc_full_src 3966f5e9bd5SScott Kruger 3976f5e9bd5SScott Kruger # Options Sanity checks 3986f5e9bd5SScott Kruger if not os.path.isdir(petsc_dir): 3996f5e9bd5SScott Kruger print("PETSC_DIR must be a directory") 4006f5e9bd5SScott Kruger return 4016f5e9bd5SScott Kruger 4026f5e9bd5SScott Kruger if not opts.use_source: 4036f5e9bd5SScott Kruger if not os.path.isdir(petsc_full_arch): 4046f5e9bd5SScott Kruger print("PETSC_DIR/PETSC_ARCH must be a directory") 4056f5e9bd5SScott Kruger return 4066f5e9bd5SScott Kruger elif not os.path.isdir(petsc_full_test): 4076f5e9bd5SScott Kruger print("Testdir must be a directory"+petsc_full_test) 4086f5e9bd5SScott Kruger return 4096f5e9bd5SScott Kruger else: 4106f5e9bd5SScott Kruger if not os.path.isdir(petsc_full_src): 4116f5e9bd5SScott Kruger print("Source directory must be a directory"+petsc_full_src) 4126f5e9bd5SScott Kruger return 4136f5e9bd5SScott Kruger 414*84533492SBarry Smith labels = expand_path_like(petsc_dir,petsc_arch,labels) 4159ea87190SJacob Faibussowitsch 4166f5e9bd5SScott Kruger # Do the actual query 4174e028dedSScott Kruger do_query(opts.use_source, startdir, petsc_full_src, petsc_full_test, 418*84533492SBarry Smith petsc_dir, petsc_arch, field, labels, searchin) 4196f5e9bd5SScott Kruger 4206f5e9bd5SScott Kruger return 4216f5e9bd5SScott Kruger 4226f5e9bd5SScott Krugerif __name__ == "__main__": 4236f5e9bd5SScott Kruger main() 424