blob: 23d45305fe513c09f40232ea889f37ad3af32c6f [file] [log] [blame]
#!/usr/bin/env python
#
# ====- Generate documentation for libc functions ------------*- python -*--==#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ==-------------------------------------------------------------------------==#
from argparse import ArgumentParser, Namespace
from pathlib import Path
from typing import Dict
import sys
import json
def load_api(hname: str) -> Dict:
p = Path(__file__).parent / Path(hname).with_suffix(".json")
api = p.read_text(encoding="utf-8")
return json.loads(api)
# TODO: we may need to get more sophisticated for less generic implementations.
# Does libc/src/{hname minus .h suffix}/{fname}.cpp exist?
def is_implemented(hname: str, fname: str) -> bool:
path = Path(
Path(__file__).parent.parent.parent,
"src",
hname.rstrip(".h")
)
if not path.exists():
raise FileNotFoundError(f"implementation dir does not exist: {path}")
if not path.is_dir():
raise NotADirectoryError(f"implementation dir is not a dir: {path}")
# Recursively search for the target source file in the subdirectories under
# libc/src/{hname}.
for _ in path.glob("**/" + fname + ".cpp"):
return True
return False
def print_functions(header: str, functions: Dict):
for key in sorted(functions.keys()):
print(f" * - {key}")
if is_implemented(header, key):
print(" - |check|")
else:
print(" -")
# defined is optional. Having any content is optional.
if functions[key] is not None and "defined" in functions[key]:
print(f' - {functions[key]["defined"]}')
else:
print(" -")
def print_header(header: str, api: Dict):
print(".. include:: check.rst\n")
fns = f"{header} Functions"
print(fns)
print("=" * (len(fns)))
print(
f"""
.. list-table::
:widths: auto
:align: center
:header-rows: 1
* - Function
- Implemented
- Standard"""
)
# TODO: how do we want to signal implementation of macros?
print_functions(header, api["functions"])
def parse_args() -> Namespace:
parser = ArgumentParser()
choices = [p.with_suffix(".h").name for p in Path(__file__).parent.glob("*.json")]
parser.add_argument("header_name", choices=choices)
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
api = load_api(args.header_name)
print_header(args.header_name, api)