1*12c85518Srobert#!/usr/bin/env python3 2*12c85518Srobert# A tool to parse the output of `clang-format --help` and update the 3*12c85518Srobert# documentation in ../ClangFormat.rst automatically. 4*12c85518Srobert 5*12c85518Srobertimport os 6*12c85518Srobertimport re 7*12c85518Srobertimport subprocess 8*12c85518Srobertimport sys 9*12c85518Srobert 10*12c85518SrobertCLANG_DIR = os.path.join(os.path.dirname(__file__), '../..') 11*12c85518SrobertDOC_FILE = os.path.join(CLANG_DIR, 'docs/ClangFormat.rst') 12*12c85518Srobert 13*12c85518Srobert 14*12c85518Srobertdef substitute(text, tag, contents): 15*12c85518Srobert replacement = '\n.. START_%s\n\n%s\n\n.. END_%s\n' % (tag, contents, tag) 16*12c85518Srobert pattern = r'\n\.\. START_%s\n.*\n\.\. END_%s\n' % (tag, tag) 17*12c85518Srobert return re.sub(pattern, '%s', text, flags=re.S) % replacement 18*12c85518Srobert 19*12c85518Srobert 20*12c85518Srobertdef indent(text, columns, indent_first_line=True): 21*12c85518Srobert indent_str = ' ' * columns 22*12c85518Srobert s = re.sub(r'\n([^\n])', '\n' + indent_str + '\\1', text, flags=re.S) 23*12c85518Srobert if not indent_first_line or s.startswith('\n'): 24*12c85518Srobert return s 25*12c85518Srobert return indent_str + s 26*12c85518Srobert 27*12c85518Srobert 28*12c85518Srobertdef get_help_output(): 29*12c85518Srobert args = ["clang-format", "--help"] 30*12c85518Srobert cmd = subprocess.Popen(args, stdout=subprocess.PIPE, 31*12c85518Srobert stderr=subprocess.STDOUT) 32*12c85518Srobert out, _ = cmd.communicate() 33*12c85518Srobert out = out.decode(sys.stdout.encoding) 34*12c85518Srobert return out 35*12c85518Srobert 36*12c85518Srobert 37*12c85518Srobertdef get_help_text(): 38*12c85518Srobert out = get_help_output() 39*12c85518Srobert out = re.sub(r' clang-format\.exe ', ' clang-format ', out) 40*12c85518Srobert 41*12c85518Srobert out = '''.. code-block:: console 42*12c85518Srobert 43*12c85518Srobert$ clang-format -help 44*12c85518Srobert''' + out 45*12c85518Srobert out = indent(out, 2, indent_first_line=False) 46*12c85518Srobert return out 47*12c85518Srobert 48*12c85518Srobert 49*12c85518Srobertdef validate(text, columns): 50*12c85518Srobert for line in text.splitlines(): 51*12c85518Srobert if len(line) > columns: 52*12c85518Srobert print('warning: line too long:\n', line, file=sys.stderr) 53*12c85518Srobert 54*12c85518Srobert 55*12c85518Sroberthelp_text = get_help_text() 56*12c85518Srobertvalidate(help_text, 95) 57*12c85518Srobert 58*12c85518Srobertwith open(DOC_FILE) as f: 59*12c85518Srobert contents = f.read() 60*12c85518Srobert 61*12c85518Srobertcontents = substitute(contents, 'FORMAT_HELP', help_text) 62*12c85518Srobert 63*12c85518Srobertwith open(DOC_FILE, 'wb') as output: 64*12c85518Srobert output.write(contents.encode()) 65