[libc-commits] [libc] af34a5d - [libc][docs] Introduce docgen (#87682)

via libc-commits libc-commits at lists.llvm.org
Fri Apr 5 14:50:49 PDT 2024


Author: Nick Desaulniers
Date: 2024-04-05T14:50:45-07:00
New Revision: af34a5d382bc7cd93c620efa00dce449de252a0a

URL: https://github.com/llvm/llvm-project/commit/af34a5d382bc7cd93c620efa00dce449de252a0a
DIFF: https://github.com/llvm/llvm-project/commit/af34a5d382bc7cd93c620efa00dce449de252a0a.diff

LOG: [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.

Added: 
    libc/docs/fenv.rst
    libc/utils/docgen/ctype.json
    libc/utils/docgen/docgen.py
    libc/utils/docgen/fenv.json

Modified: 
    libc/docs/index.rst

Removed: 
    


################################################################################
diff  --git a/libc/docs/fenv.rst b/libc/docs/fenv.rst
new file mode 100644
index 00000000000000..6574fb7246ddd2
--- /dev/null
+++ b/libc/docs/fenv.rst
@@ -0,0 +1,64 @@
+.. include:: check.rst
+
+fenv.h Functions
+================
+
+.. list-table::
+  :widths: auto
+  :align: center
+  :header-rows: 1
+
+  * - Function
+    - Implemented
+    - Standard
+  * - fe_dec_getround
+    -
+    - 7.6.5.3
+  * - fe_dec_setround
+    -
+    - 7.6.5.6
+  * - feclearexcept
+    - |check|
+    - 7.6.4.1
+  * - fegetenv
+    - |check|
+    - 7.6.6.1
+  * - fegetexceptflag
+    - |check|
+    - 7.6.4.2
+  * - fegetmode
+    -
+    - 7.6.5.1
+  * - fegetround
+    - |check|
+    - 7.6.5.2
+  * - feholdexcept
+    - |check|
+    - 7.6.6.2
+  * - feraiseexcept
+    - |check|
+    - 7.6.4.3
+  * - fesetenv
+    - |check|
+    - 7.6.6.3
+  * - fesetexcept
+    -
+    - 7.6.4.4
+  * - fesetexceptflag
+    - |check|
+    - 7.6.4.5
+  * - fesetmode
+    -
+    - 7.6.5.4
+  * - fesetround
+    - |check|
+    - 7.6.5.5
+  * - fetestexcept
+    - |check|
+    - 7.6.4.7
+  * - fetestexceptflag
+    -
+    - 7.6.4.6
+  * - feupdateenv
+    - |check|
+    - 7.6.6.4

diff  --git a/libc/docs/index.rst b/libc/docs/index.rst
index 370fcd843974e8..65ccb91e92ffe1 100644
--- a/libc/docs/index.rst
+++ b/libc/docs/index.rst
@@ -66,6 +66,7 @@ stages there is no ABI stability in any form.
    strings
    stdio
    stdbit
+   fenv
    libc_search
    c23
 

diff  --git a/libc/utils/docgen/ctype.json b/libc/utils/docgen/ctype.json
new file mode 100644
index 00000000000000..4102c2dd110911
--- /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 00000000000000..7411b4506f082f
--- /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 00000000000000..0af38b16b2d982
--- /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"
+    }
+  }
+}


        


More information about the libc-commits mailing list