11b37a2a7SPierre Jolivet#!/usr/bin/env python3 23564227fSBarry Smith""" Loops through all the source using doctext to generate the manual pages""" 33564227fSBarry Smith 43564227fSBarry Smithimport os 53564227fSBarry Smithimport re 63564227fSBarry Smithimport subprocess 73564227fSBarry Smithimport pathlib 83564227fSBarry Smith 93564227fSBarry Smithdef findlmansec(file): 103564227fSBarry Smith mansec = None 113564227fSBarry Smith submansec = None 123564227fSBarry Smith with open(file) as mklines: 133564227fSBarry Smith #print(file) 144b64c689SBarry Smith submansecl = [line for line in mklines if (line.find('SUBMANSEC') > -1 and line.find('BFORT') == -1)] 153564227fSBarry Smith if submansecl: 1634c645fdSBarry Smith submansec = re.sub(r'[ ]*/\* [ ]*SUBMANSEC[ ]*=[ ]*','',submansecl[0]).strip('\n').strip('*/').strip() 173564227fSBarry Smith if submansec == submansecl[0].strip('\n'): 183564227fSBarry Smith submansec = re.sub('SUBMANSEC[ ]*=[ ]*','',submansecl[0]).strip('\n').strip() 193564227fSBarry Smith #print(':SUBMANSEC:'+submansec) 203564227fSBarry Smith return submansec 213564227fSBarry Smith with open(file) as mklines: 223564227fSBarry Smith mansecl = [line for line in mklines if line.startswith('MANSEC')] 233564227fSBarry Smith if mansecl: 243564227fSBarry Smith mansec = re.sub('MANSEC[ ]*=[ ]*','',mansecl[0]).strip('\n').strip() 253564227fSBarry Smith #print(':MANSEC:'+mansec) 263564227fSBarry Smith return mansec 273564227fSBarry Smith return None 283564227fSBarry Smith 29*7f019730SBarry Smithdef processdir(petsc_dir, build_dir, dir, doctext): 303564227fSBarry Smith '''Runs doctext on each source file in the directory''' 313564227fSBarry Smith #print('Processing '+dir) 32*7f019730SBarry Smith doctext_path = os.path.join(build_dir,'manualpages','doctext') 333564227fSBarry Smith lmansec = None 343564227fSBarry Smith if os.path.isfile(os.path.join(dir,'makefile')): 353564227fSBarry Smith lmansec = findlmansec(os.path.join(dir,'makefile')) 363564227fSBarry Smith 375a0a9f49SBarry Smith numberErrors = 0 383564227fSBarry Smith for file in os.listdir(dir): 393564227fSBarry Smith llmansec = lmansec 403564227fSBarry Smith if os.path.isfile(os.path.join(dir,file)) and pathlib.Path(file).suffix in ['.c', '.cxx', '.h', '.cu', '.cpp', '.hpp']: 413564227fSBarry Smith #print('Processing '+file) 423564227fSBarry Smith if not llmansec: 433564227fSBarry Smith llmansec = findlmansec(os.path.join(dir,file)) 443564227fSBarry Smith if not llmansec: continue 45*7f019730SBarry Smith if not os.path.isdir(os.path.join(build_dir,'manualpages',llmansec)): os.mkdir(os.path.join(build_dir,'manualpages',llmansec)) 463564227fSBarry Smith 473564227fSBarry Smith command = [doctext, 483564227fSBarry Smith '-myst', 49*7f019730SBarry Smith '-mpath', os.path.join(build_dir,'manualpages',llmansec), 503564227fSBarry Smith '-heading', 'PETSc', 51*7f019730SBarry Smith '-defn', os.path.join(build_dir,'manualpages','doctext','myst.def'), 523564227fSBarry Smith '-indexdir', '../'+llmansec, 53*7f019730SBarry Smith '-index', os.path.join(build_dir,'manualpages','manualpages.cit'), 543564227fSBarry Smith '-locdir', dir[len(petsc_dir)+1:]+'/', 55*7f019730SBarry Smith '-Wargdesc', os.path.join(build_dir,'manualpages','doctext','doctextcommon.txt'), 563564227fSBarry Smith file] 575a0a9f49SBarry Smith sp = subprocess.run(command, cwd=dir, capture_output=True, encoding='UTF-8', check=True) 585a0a9f49SBarry Smith if sp.stdout and sp.stdout.find('WARNING') > -1: 595a0a9f49SBarry Smith print(sp.stdout) 605a0a9f49SBarry Smith numberErrors = numberErrors + 1 615a0a9f49SBarry Smith if sp.stderr and sp.stderr.find('WARNING') > -1: 625a0a9f49SBarry Smith print(sp.stderr) 635a0a9f49SBarry Smith numberErrors = numberErrors + 1 645a0a9f49SBarry Smith return numberErrors 655a0a9f49SBarry Smith 663564227fSBarry Smith 673564227fSBarry Smithdef processkhash(T, t, KeyType, ValType, text): 683564227fSBarry Smith '''Replaces T, t, KeyType, and ValType in text (from include/petsc/private/hashset.txt) with a set of supported values''' 693564227fSBarry Smith import re 703564227fSBarry Smith return re.sub('<ValType>',ValType,re.sub('<KeyType>',KeyType,re.sub('<t>',t,re.sub('<T>',T,text)))) 713564227fSBarry Smith 72*7f019730SBarry Smithdef main(petsc_dir, build_dir, doctext): 733564227fSBarry Smith # generate source code for manual pages for PETSc khash functions 743564227fSBarry Smith text = '' 753564227fSBarry Smith for f in ['hashset.txt', 'hashmap.txt']: 763564227fSBarry Smith with open(os.path.join(petsc_dir,'include','petsc','private',f)) as mklines: 773564227fSBarry Smith text = mklines.read() 783564227fSBarry Smith with open(os.path.join(petsc_dir,'include','petsc','private',f+'.h'),mode='w') as khash: 793564227fSBarry Smith khash.write(processkhash('I','i','PetscInt','',text)) 803564227fSBarry Smith khash.write(processkhash('IJ','ij','struct {PetscInt i, j;}','',text)) 813564227fSBarry Smith khash.write(processkhash('I','i','PetscInt','PetscInt',text)) 823564227fSBarry Smith khash.write(processkhash('IJ','ij','struct {PetscInt i, j;}','PetscInt',text)) 833564227fSBarry Smith khash.write(processkhash('IJ','ij','struct {PetscInt i, j;}','PetscScalar',text)) 843564227fSBarry Smith khash.write(processkhash('IV','iv','PetscInt','PetscScalar',text)) 853564227fSBarry Smith khash.write(processkhash('Obj','obj','PetscInt64','PetscObject',text)) 863564227fSBarry Smith 873564227fSBarry Smith # generate the .md files for the manual pages from all the PETSc source code 885a0a9f49SBarry Smith try: 89*7f019730SBarry Smith os.unlink(os.path.join(build_dir,'manualpages','manualpages.cit')) 905a0a9f49SBarry Smith except: 915a0a9f49SBarry Smith pass 925a0a9f49SBarry Smith numberErrors = 0 933564227fSBarry Smith for dirpath, dirnames, filenames in os.walk(os.path.join(petsc_dir),topdown=True): 946dd63270SBarry Smith dirnames[:] = [d for d in dirnames if d not in ['tests', 'tutorials', 'doc', 'output', 'ftn-custom', 'ftn-auto', 'ftn-mod', 'binding', 'binding', 'config', 'lib', '.git', 'share', 'systems'] and not d.startswith('arch')] 95*7f019730SBarry Smith numberErrors = numberErrors + processdir(petsc_dir,build_dir,dirpath,doctext) 965a0a9f49SBarry Smith if numberErrors: 975a0a9f49SBarry Smith raise RuntimeError('Stopping document build since errors were detected in generating manual pages') 983564227fSBarry Smith 993564227fSBarry Smith # generate list of all manual pages 100*7f019730SBarry Smith with open(os.path.join(build_dir,'manualpages','htmlmap'),mode='w') as map: 101*7f019730SBarry Smith with open(os.path.join(build_dir,'manualpages','manualpages.cit')) as cit: 10234c645fdSBarry Smith map.write(re.sub(r'man\+../','man+manualpages/',cit.read())) 103*7f019730SBarry Smith with open(os.path.join(build_dir,'manualpages','mpi.www.index')) as mpi: 1043564227fSBarry Smith map.write(mpi.read()) 105