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