Skip to content

Commit af34a5d

Browse files
[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.
1 parent fe45029 commit af34a5d

File tree

5 files changed

+210
-0
lines changed

5 files changed

+210
-0
lines changed

libc/docs/fenv.rst

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
.. include:: check.rst
2+
3+
fenv.h Functions
4+
================
5+
6+
.. list-table::
7+
:widths: auto
8+
:align: center
9+
:header-rows: 1
10+
11+
* - Function
12+
- Implemented
13+
- Standard
14+
* - fe_dec_getround
15+
-
16+
- 7.6.5.3
17+
* - fe_dec_setround
18+
-
19+
- 7.6.5.6
20+
* - feclearexcept
21+
- |check|
22+
- 7.6.4.1
23+
* - fegetenv
24+
- |check|
25+
- 7.6.6.1
26+
* - fegetexceptflag
27+
- |check|
28+
- 7.6.4.2
29+
* - fegetmode
30+
-
31+
- 7.6.5.1
32+
* - fegetround
33+
- |check|
34+
- 7.6.5.2
35+
* - feholdexcept
36+
- |check|
37+
- 7.6.6.2
38+
* - feraiseexcept
39+
- |check|
40+
- 7.6.4.3
41+
* - fesetenv
42+
- |check|
43+
- 7.6.6.3
44+
* - fesetexcept
45+
-
46+
- 7.6.4.4
47+
* - fesetexceptflag
48+
- |check|
49+
- 7.6.4.5
50+
* - fesetmode
51+
-
52+
- 7.6.5.4
53+
* - fesetround
54+
- |check|
55+
- 7.6.5.5
56+
* - fetestexcept
57+
- |check|
58+
- 7.6.4.7
59+
* - fetestexceptflag
60+
-
61+
- 7.6.4.6
62+
* - feupdateenv
63+
- |check|
64+
- 7.6.6.4

libc/docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ stages there is no ABI stability in any form.
6666
strings
6767
stdio
6868
stdbit
69+
fenv
6970
libc_search
7071
c23
7172

libc/utils/docgen/ctype.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"functions": {
3+
"isalnum": null,
4+
"isalpha": null,
5+
"isblank": null
6+
}
7+
}

libc/utils/docgen/docgen.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env python
2+
#
3+
# ====- Generate documentation for libc functions ------------*- python -*--==#
4+
#
5+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6+
# See https://llvm.org/LICENSE.txt for license information.
7+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
#
9+
# ==-------------------------------------------------------------------------==#
10+
from argparse import ArgumentParser, Namespace
11+
from pathlib import Path
12+
from typing import Dict
13+
import sys
14+
import json
15+
16+
17+
def load_api(hname: str) -> Dict:
18+
p = Path(__file__).parent / Path(hname).with_suffix(".json")
19+
api = p.read_text(encoding="utf-8")
20+
return json.loads(api)
21+
22+
23+
# TODO: we may need to get more sophisticated for less generic implementations.
24+
# Does libc/src/{hname minus .h suffix}/{fname}.cpp exist?
25+
def is_implemented(hname: str, fname: str) -> bool:
26+
return Path(
27+
Path(__file__).parent.parent.parent,
28+
"src",
29+
hname.rstrip(".h"),
30+
fname + ".cpp",
31+
).exists()
32+
33+
34+
def print_functions(header: str, functions: Dict):
35+
for key in sorted(functions.keys()):
36+
print(f" * - {key}")
37+
38+
if is_implemented(header, key):
39+
print(" - |check|")
40+
else:
41+
print(" -")
42+
43+
# defined is optional. Having any content is optional.
44+
if functions[key] is not None and "defined" in functions[key]:
45+
print(f' - {functions[key]["defined"]}')
46+
else:
47+
print(" -")
48+
49+
50+
def print_header(header: str, api: Dict):
51+
fns = f"{header} Functions"
52+
print(fns)
53+
print("=" * (len(fns)))
54+
print(
55+
f"""
56+
.. list-table::
57+
:widths: auto
58+
:align: center
59+
:header-rows: 1
60+
61+
* - Function
62+
- Implemented
63+
- Standard"""
64+
)
65+
# TODO: how do we want to signal implementation of macros?
66+
print_functions(header, api["functions"])
67+
68+
69+
def parse_args() -> Namespace:
70+
parser = ArgumentParser()
71+
choices = [p.with_suffix(".h").name for p in Path(__file__).parent.glob("*.json")]
72+
parser.add_argument("header_name", choices=choices)
73+
return parser.parse_args()
74+
75+
76+
if __name__ == "__main__":
77+
args = parse_args()
78+
api = load_api(args.header_name)
79+
80+
print_header(args.header_name, api)

libc/utils/docgen/fenv.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"macros": [
3+
"__STDC_VERSION_FENV_H__"
4+
],
5+
"functions": {
6+
"feclearexcept": {
7+
"defined": "7.6.4.1"
8+
},
9+
"fegetexceptflag": {
10+
"defined": "7.6.4.2"
11+
},
12+
"feraiseexcept": {
13+
"defined": "7.6.4.3"
14+
},
15+
"fesetexcept": {
16+
"defined": "7.6.4.4"
17+
},
18+
"fesetexceptflag": {
19+
"defined": "7.6.4.5"
20+
},
21+
"fetestexceptflag": {
22+
"defined": "7.6.4.6"
23+
},
24+
"fetestexcept": {
25+
"defined": "7.6.4.7"
26+
},
27+
"fegetmode": {
28+
"defined": "7.6.5.1"
29+
},
30+
"fegetround": {
31+
"defined": "7.6.5.2"
32+
},
33+
"fe_dec_getround": {
34+
"defined": "7.6.5.3"
35+
},
36+
"fesetmode": {
37+
"defined": "7.6.5.4"
38+
},
39+
"fesetround": {
40+
"defined": "7.6.5.5"
41+
},
42+
"fe_dec_setround": {
43+
"defined": "7.6.5.6"
44+
},
45+
"fegetenv": {
46+
"defined": "7.6.6.1"
47+
},
48+
"feholdexcept": {
49+
"defined": "7.6.6.2"
50+
},
51+
"fesetenv": {
52+
"defined": "7.6.6.3"
53+
},
54+
"feupdateenv": {
55+
"defined": "7.6.6.4"
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)