1#!/usr/bin/env python3 2# A tool to parse the output of `clang-format --help` and update the 3# documentation in ../ClangFormat.rst automatically. 4 5import argparse 6import os 7import re 8import subprocess 9import sys 10 11PARENT_DIR = os.path.join(os.path.dirname(__file__), "..") 12DOC_FILE = os.path.join(PARENT_DIR, "ClangFormat.rst") 13 14 15def substitute(text, tag, contents): 16 replacement = "\n.. START_%s\n\n%s\n\n.. END_%s\n" % (tag, contents, tag) 17 pattern = r"\n\.\. START_%s\n.*\n\.\. END_%s\n" % (tag, tag) 18 return re.sub(pattern, replacement, text, flags=re.S) 19 20 21def indent(text, columns, indent_first_line=True): 22 indent_str = " " * columns 23 s = re.sub(r"\n([^\n])", "\n" + indent_str + "\\1", text, flags=re.S) 24 if not indent_first_line or s.startswith("\n"): 25 return s 26 return indent_str + s 27 28 29def get_help_output(): 30 args = [binary, "--help"] 31 cmd = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 32 out, _ = cmd.communicate() 33 out = out.decode(sys.stdout.encoding) 34 return out 35 36 37def get_help_text(): 38 out = get_help_output() 39 out = re.sub(r" clang-format\.exe ", " clang-format ", out) 40 41 out = ( 42 """.. code-block:: console 43 44$ clang-format --help 45""" 46 + out 47 ) 48 out = indent(out, 2, indent_first_line=False) 49 return out 50 51 52def validate(text, columns): 53 for line in text.splitlines(): 54 if len(line) > columns: 55 print("warning: line too long:\n", line, file=sys.stderr) 56 57 58p = argparse.ArgumentParser() 59p.add_argument("-d", "--directory", help="directory of clang-format") 60p.add_argument("-o", "--output", help="path of output file") 61opts = p.parse_args() 62 63binary = "clang-format" 64if opts.directory: 65 binary = opts.directory + "/" + binary 66 67help_text = get_help_text() 68validate(help_text, 100) 69 70with open(DOC_FILE, encoding="utf-8") as f: 71 contents = f.read() 72 73contents = substitute(contents, "FORMAT_HELP", help_text) 74 75with open( 76 opts.output if opts.output else DOC_FILE, "w", newline="", encoding="utf-8" 77) as f: 78 f.write(contents) 79