1*ec83d434SBarry Smith#!/usr/bin/env python 2*ec83d434SBarry Smith""" Builds the html files for all the source""" 3*ec83d434SBarry Smith 4*ec83d434SBarry Smithimport os 5*ec83d434SBarry Smithimport re 6*ec83d434SBarry Smithimport subprocess 7*ec83d434SBarry Smithimport pathlib 8*ec83d434SBarry Smithfrom itertools import chain 9*ec83d434SBarry Smith 10*ec83d434SBarry Smithdef compute_make_np(i): 11*ec83d434SBarry Smith '''Number of cores to run make c2html on''' 12*ec83d434SBarry Smith f16 = .80 13*ec83d434SBarry Smith f32 = .65 14*ec83d434SBarry Smith f64 = .50 15*ec83d434SBarry Smith f99 = .30 16*ec83d434SBarry Smith if (i<=2): return 2 17*ec83d434SBarry Smith elif (i<=4): return i 18*ec83d434SBarry Smith elif (i<=16): return int(4+(i-4)*f16) 19*ec83d434SBarry Smith elif (i<=32): return int(4+12*f16+(i-16)*f32) 20*ec83d434SBarry Smith elif (i<=64): return int(4+12*f16+16*f32+(i-32)*f64) 21*ec83d434SBarry Smith else: return int(4+12*f16+16*f32+32*f64+(i-64)*f99) 22*ec83d434SBarry Smith 23*ec83d434SBarry Smithdef main(petsc_dir,loc,c2html,mapnames): 24*ec83d434SBarry Smith os.chdir(petsc_dir) 25*ec83d434SBarry Smith 26*ec83d434SBarry Smith # reformat file that maps manual pages to directory location and add MPI manual pages 27*ec83d434SBarry Smith with open('htmlmap.tmp', "w") as fdw, open(os.path.join(petsc_dir,'doc','manualpages','htmlmap'), "r") as fd: 28*ec83d434SBarry Smith fdw.write(fd.read().replace('man+manualpages/','man+HTML_ROOT/manualpages/')) 29*ec83d434SBarry Smith with open('htmlmap.tmp', "a") as fdw, open(os.path.join(petsc_dir,'doc','manualpages','mpi.www.index'), "r") as fd: 30*ec83d434SBarry Smith fdw.write(fd.read()) 31*ec83d434SBarry Smith 32*ec83d434SBarry Smith # walk directories generating list of all source code that needs processing and creating index.html for each directory 33*ec83d434SBarry Smith SKIPDIRS = set('public html benchmarks output arch doc binding config petsc-doc lib bin .git systems share mpiuni kernels khash valgrind interfaces data linter'.split()) 34*ec83d434SBarry Smith SUFFIXES = set('.F90 .F .c .cxx .cpp .h .cu'.split()) 35*ec83d434SBarry Smith allfiles = [] 36*ec83d434SBarry Smith for root, dirs, files in chain.from_iterable(os.walk(path) for path in [petsc_dir]): 37*ec83d434SBarry Smith dirs[:] = [d for d in dirs if not any([s for s in SKIPDIRS if d.startswith(s)])] 38*ec83d434SBarry Smith root = root[len(petsc_dir)+1:] 39*ec83d434SBarry Smith if not root: continue 40*ec83d434SBarry Smith if not os.path.isdir(os.path.join(loc,root)): os.makedirs(os.path.join(loc,root)) 41*ec83d434SBarry Smith allfiles.extend([os.path.join(loc,root,f+'.html') for f in files if any([s for s in SUFFIXES if f.endswith(s)])]) 42*ec83d434SBarry Smith 43*ec83d434SBarry Smith # create index.html file for each directory 44*ec83d434SBarry Smith with open(os.path.join(loc,root,'index.html'),'w') as fdw: 45*ec83d434SBarry Smith if root.startswith('src'): 46*ec83d434SBarry Smith 47*ec83d434SBarry Smith # get MANSEC from the makefile and copy the MANSEC basic information into the index 48*ec83d434SBarry Smith # TODO: the text is actually .md so needs processing 49*ec83d434SBarry Smith if os.path.isfile(os.path.join(root,'makefile')): 50*ec83d434SBarry Smith with open(os.path.join(root,'makefile')) as mklines: 51*ec83d434SBarry Smith mansecl = [line for line in mklines if line.startswith('MANSEC')] 52*ec83d434SBarry Smith if mansecl: 53*ec83d434SBarry Smith mansec = re.sub('MANSEC[ ]*=[ ]*','',mansecl[0]).strip('\n').strip() 54*ec83d434SBarry Smith with open(os.path.join('doc','manualpages','MANSECHeaders',mansec)) as fd: 55*ec83d434SBarry Smith fdw.write(fd.read()) 56*ec83d434SBarry Smith 57*ec83d434SBarry Smith fdw.write('\n<p>\n') 58*ec83d434SBarry Smith 59*ec83d434SBarry Smith # TODO: use HTML lists for the list below 60*ec83d434SBarry Smith 61*ec83d434SBarry Smith # list examples 62*ec83d434SBarry Smith if root.find('/tests') > -1 or root.find('tutorials') > -1: 63*ec83d434SBarry Smith fdw.write('\n<p>\nExamples\n<p>') 64*ec83d434SBarry Smith for f in files: 65*ec83d434SBarry Smith if any([s for s in SUFFIXES if f.endswith(s)]): 66*ec83d434SBarry Smith with open(os.path.join(root,f)) as fd: 67*ec83d434SBarry Smith line = fd.readline() 68*ec83d434SBarry Smith l = line.find('char help[] = ') 69*ec83d434SBarry Smith if l > -1: 70*ec83d434SBarry Smith s = line.find('\\n') 71*ec83d434SBarry Smith line = line[l + 15:s] 72*ec83d434SBarry Smith else: line = '' 73*ec83d434SBarry Smith fdw.write('<a href="' + f + '.html">' + f + ': ' + line + '</a><br>\n') 74*ec83d434SBarry Smith 75*ec83d434SBarry Smith # list source code 76*ec83d434SBarry Smith else: 77*ec83d434SBarry Smith if any([f for f in files if any([s for s in SUFFIXES if f.endswith(s)])]): 78*ec83d434SBarry Smith fdw.write('\n<p>\nSource files\n<p>') 79*ec83d434SBarry Smith for f in files: 80*ec83d434SBarry Smith if any([s for s in SUFFIXES if f.endswith(s)]): 81*ec83d434SBarry Smith fdw.write('<a href=\"' + f + '.html\">' + f + '</a><br>\n') 82*ec83d434SBarry Smith 83*ec83d434SBarry Smith # list subdirectories 84*ec83d434SBarry Smith if dirs: 85*ec83d434SBarry Smith fdw.write('\n<p>\nDirectories\n<p>') 86*ec83d434SBarry Smith for d in dirs: 87*ec83d434SBarry Smith fdw.write('<a href="' + os.path.join(d,'index.html') + '">' + d + '</a><br>\n') 88*ec83d434SBarry Smith 89*ec83d434SBarry Smith # create makefile that will run c2html on all source files in parallel 90*ec83d434SBarry Smith git_sha = subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).rstrip() 91*ec83d434SBarry Smith with open(os.path.join(petsc_dir,'c2html.mk'),'w') as fd: 92*ec83d434SBarry Smith fd.write('files = ') 93*ec83d434SBarry Smith fd.write(' '.join(allfiles)) 94*ec83d434SBarry Smith fd.write('\n') 95*ec83d434SBarry Smith fd.write('\n') 96*ec83d434SBarry Smith fd.write(os.path.join(loc,'%.html')+' : %\n') 97*ec83d434SBarry Smith fd.write(' @' + os.path.join(petsc_dir,'doc','build_c2html_file.py') + ' ' + petsc_dir + ' ' + loc + ' '+ git_sha + ' ' + c2html + ' ' + mapnames + ' $< $@\n') 98*ec83d434SBarry Smith fd.write('\n') 99*ec83d434SBarry Smith fd.write('all: $(files)\n') 100*ec83d434SBarry Smith 101*ec83d434SBarry Smith import multiprocessing 102*ec83d434SBarry Smith command = ['make', '-j', str(compute_make_np(multiprocessing.cpu_count())), '-f', 'c2html.mk', 'all'] 103*ec83d434SBarry Smith subprocess.run(command, cwd=petsc_dir, check=True) 104*ec83d434SBarry Smith 105*ec83d434SBarry Smith os.unlink('c2html.mk') 106*ec83d434SBarry Smith os.unlink('htmlmap.tmp') 107*ec83d434SBarry Smith 108*ec83d434SBarry Smithif __name__ == "__main__": 109*ec83d434SBarry Smith main(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4]) 110