aboutsummaryrefslogtreecommitdiff
path: root/libc/utils
diff options
context:
space:
mode:
authorNick Desaulniers <nickdesaulniers@users.noreply.github.com>2024-04-05 14:50:45 -0700
committerGitHub <noreply@github.com>2024-04-05 14:50:45 -0700
commitaf34a5d382bc7cd93c620efa00dce449de252a0a (patch)
treee97d26fbe52dad26d88e4b71f79d915fe5327e94 /libc/utils
parentfe45029dbdee6b3df2dbeaed17c9dd598ec511f2 (diff)
downloadllvm-af34a5d382bc7cd93c620efa00dce449de252a0a.zip
llvm-af34a5d382bc7cd93c620efa00dce449de252a0a.tar.gz
llvm-af34a5d382bc7cd93c620efa00dce449de252a0a.tar.bz2
[libc][docs] Introduce docgen (#87682)
This script+config should help us generate more consistent documentation wrt. what we currently support or not. As an example usage: $ ./libc/utils/docgen/docgen.py fenv.h Will spit out an RST formatted table that can be copy+pasted into our docs. The config is not filled out entirely, but doing so and then updating our docs would be great beginner bugs for new contributors. Having python+json generate things like docs, or headers (as imagined in https://github.com/nickdesaulniers/llvm-project/tree/hdr-gen2) is perhaps easier to work with than tablegen, and doesn't introduce a dependency on a host tool that needs to be compiled from llvm sources before building the rest of the libc. This can probably be merged with whatever we end up doing to replace libc-hdrgen. Please use https://llvm.org/docs/CodingStandards.html#python-version-and-source-code-formatting for keeping this file formatted.
Diffstat (limited to 'libc/utils')
-rw-r--r--libc/utils/docgen/ctype.json7
-rwxr-xr-xlibc/utils/docgen/docgen.py80
-rw-r--r--libc/utils/docgen/fenv.json58
3 files changed, 145 insertions, 0 deletions
diff --git a/libc/utils/docgen/ctype.json b/libc/utils/docgen/ctype.json
new file mode 100644
index 0000000..4102c2d
--- /dev/null
+++ b/libc/utils/docgen/ctype.json
@@ -0,0 +1,7 @@
+{
+ "functions": {
+ "isalnum": null,
+ "isalpha": null,
+ "isblank": null
+ }
+}
diff --git a/libc/utils/docgen/docgen.py b/libc/utils/docgen/docgen.py
new file mode 100755
index 0000000..7411b45
--- /dev/null
+++ b/libc/utils/docgen/docgen.py
@@ -0,0 +1,80 @@
+#!/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:
+ return Path(
+ Path(__file__).parent.parent.parent,
+ "src",
+ hname.rstrip(".h"),
+ fname + ".cpp",
+ ).exists()
+
+
+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):
+ 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)
diff --git a/libc/utils/docgen/fenv.json b/libc/utils/docgen/fenv.json
new file mode 100644
index 0000000..0af38b1
--- /dev/null
+++ b/libc/utils/docgen/fenv.json
@@ -0,0 +1,58 @@
+{
+ "macros": [
+ "__STDC_VERSION_FENV_H__"
+ ],
+ "functions": {
+ "feclearexcept": {
+ "defined": "7.6.4.1"
+ },
+ "fegetexceptflag": {
+ "defined": "7.6.4.2"
+ },
+ "feraiseexcept": {
+ "defined": "7.6.4.3"
+ },
+ "fesetexcept": {
+ "defined": "7.6.4.4"
+ },
+ "fesetexceptflag": {
+ "defined": "7.6.4.5"
+ },
+ "fetestexceptflag": {
+ "defined": "7.6.4.6"
+ },
+ "fetestexcept": {
+ "defined": "7.6.4.7"
+ },
+ "fegetmode": {
+ "defined": "7.6.5.1"
+ },
+ "fegetround": {
+ "defined": "7.6.5.2"
+ },
+ "fe_dec_getround": {
+ "defined": "7.6.5.3"
+ },
+ "fesetmode": {
+ "defined": "7.6.5.4"
+ },
+ "fesetround": {
+ "defined": "7.6.5.5"
+ },
+ "fe_dec_setround": {
+ "defined": "7.6.5.6"
+ },
+ "fegetenv": {
+ "defined": "7.6.6.1"
+ },
+ "feholdexcept": {
+ "defined": "7.6.6.2"
+ },
+ "fesetenv": {
+ "defined": "7.6.6.3"
+ },
+ "feupdateenv": {
+ "defined": "7.6.6.4"
+ }
+ }
+}