brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 763dc00 Raw
150 lines · python
1#!/usr/bin/env python32# A tool to parse the output of `llvm-bolt --help-hidden` and update the3# documentation in CommandLineArgumentReference.md automatically.4# Run from the directory in which this file is located to update the docs.5 6import subprocess7from textwrap import wrap8 9LINE_LIMIT = 8010 11 12def wrap_text(text, indent, limit=LINE_LIMIT):13    wrapped_lines = wrap(text, width=limit - len(indent))14    wrapped_text = ("\n" + indent).join(wrapped_lines)15    return wrapped_text16 17 18def add_info(sections, section, option, description):19    indent = "  "20    wrapped_description = "\n".join(21        [22            wrap_text(line, indent) if len(line) > LINE_LIMIT else line23            for line in description24        ]25    )26    sections[section].append((option, indent + wrapped_description))27 28 29def parse_bolt_options(output):30    section_headers = [31        "Generic options:",32        "Output options:",33        "BOLT generic options:",34        "BOLT optimization options:",35        "BOLT options in relocation mode:",36        "BOLT instrumentation options:",37        "BOLT printing options:",38    ]39 40    sections = {key: [] for key in section_headers}41    current_section, prev_section = None, None42    option, description = None, []43 44    for line in output.split("\n"):45        cleaned_line = line.strip()46 47        if cleaned_line.casefold() in map(str.casefold, section_headers):48            if prev_section is not None:  # Save last option from prev section49                add_info(sections, current_section, option, description)50                option, description = None, []51 52            cleaned_line = cleaned_line.split()53            # Apply lowercase to all words except the first one54            cleaned_line = [cleaned_line[0]] + [55                word.lower() for word in cleaned_line[1:]56            ]57            # Join the words back together into a string58            cleaned_line = " ".join(cleaned_line)59 60            current_section = cleaned_line61            prev_section = current_section62            continue63 64        if cleaned_line.startswith("-"):65            if option and description:66                # Join description lines, adding an extra newline for67                # sub-options that start with '='68                add_info(sections, current_section, option, description)69                option, description = None, []70 71            parts = cleaned_line.split("  ", 1)72            if len(parts) > 1:73                option = parts[0].strip()74                descr = parts[1].strip()75                descr = descr[2].upper() + descr[3:]76                description = [descr]77                if option.startswith("--print") or option.startswith("--time"):78                    current_section = "BOLT printing options:"79                elif prev_section is not None:80                    current_section = prev_section81            continue82 83        if cleaned_line.startswith("="):84            parts = cleaned_line.split(maxsplit=1)85            # Split into two parts: sub-option and description86            if len(parts) == 2:87                # Rejoin with a single space88                cleaned_line = parts[0] + " " + parts[1].rstrip()89            description.append(cleaned_line)90        elif cleaned_line:  # Multiline description continuation91            description.append(cleaned_line)92 93    add_info(sections, current_section, option, description)94    return sections95 96 97def generate_markdown(sections):98    markdown_lines = [99        "# BOLT - a post-link optimizer developed to speed up large applications\n",100        "## SYNOPSIS\n",101        "`llvm-bolt <executable> [-o outputfile] <executable>.bolt "102        "[-data=perf.fdata] [options]`\n",103        "## OPTIONS",104    ]105 106    for section, options in sections.items():107        markdown_lines.append(f"\n### {section}")108        if section == "BOLT instrumentation options:":109            markdown_lines.append(110                f"\n`llvm-bolt <executable> -instrument"111                " [-o outputfile] <instrumented-executable>`"112            )113        for option, desc in options:114            markdown_lines.append(f"\n- `{option}`\n")115            # Split description into lines to handle sub-options116            desc_lines = desc.split("\n")117            for line in desc_lines:118                if line.startswith("="):119                    # Sub-option: correct formatting with bullet120                    sub_option, sub_desc = line[1:].split(" ", 1)121                    markdown_lines.append(f"  - `{sub_option}`: {sub_desc[4:]}")122                else:123                    # Regular line of description124                    if line[2:].startswith("<"):125                        line = line.replace("<", "").replace(">", "")126                    markdown_lines.append(f"{line}")127 128    return "\n".join(markdown_lines)129 130 131def main():132    try:133        help_output = subprocess.run(134            ["llvm-bolt", "--help-hidden"], capture_output=True, text=True, check=True135        ).stdout136    except subprocess.CalledProcessError as e:137        print("Failed to execute llvm-bolt --help:")138        print(e)139        return140 141    sections = parse_bolt_options(help_output)142    markdown = generate_markdown(sections)143 144    with open("CommandLineArgumentReference.md", "w") as md_file:145        md_file.write(markdown)146 147 148if __name__ == "__main__":149    main()150