#!/usr/bin/env python3 ''' A utility script for generating documentation. Preprocessor macro output from opts_macro.h is parsed and combined with bcachefs.5.rst.tmpl to generate bcachefs.5.rst. >=python3.6 ''' import sys import re INDENT = ' ' TEMPLATE = './doc/bcachefs.5.rst.tmpl' RST_FILE= './doc/bcachefs.5.rst' SANITIZE_CHARS = [ '\\\\n', '\\n', ' ', '"', '\\', ] def sanitize(text): ''' Parses opts_macro.h preprocessor output :param text: text to sanitize :type text: str :returns: a list of options :rtype: list ''' args = [] reg = re.search('FMT_START_SECTION(.*)FMT_END_SECTION', text, flags=re.DOTALL) if not reg: raise re.error('no text found') # decoding would probably be better, but this works for char in SANITIZE_CHARS: text = text.replace(char, '') text = re.split(r'FMT_END_LINE', text) # this seemed easier than getting preprocessor macros to play nice # with python's builtin csv module for line in text: vals = line.split(';') if not vals: continue if len(vals) != 4: continue vals = list(map(str.strip, vals)) name, is_bool, desc, arg_name = vals # this macro value from opts.h indicates that no values are passed if is_bool == 'OPT_BOOL()': args.append(f'--{name}\n{INDENT}{desc}') else: args.append(f'--{name} <{arg_name}>\n{INDENT}{desc}') if not args: raise re.error('no args found, likely parsing error') return args def main(): ''' Transform stdin to option list and write templated output to new file ''' out = '' stdin = sys.stdin.read() opts = sanitize(stdin) opts = '\n'.join(opts) # Insert into template with open(TEMPLATE, 'r') as in_handle: in_handle = in_handle.read() out = in_handle.replace('OPTIONS_TABLE', opts) with open(RST_FILE, 'w') as out_handle: out_handle.write(out) if __name__ == '__main__': main()