[libc][docs][NFC] Remove dead files and consolidate check.rst (#194442)
Deleted check.rst, Helpers/Styles.rst, dev/cmake_build_rules.rst, and dev/clang_tidy_checks.rst. Moved the |check| substitution into rst_prolog in conf.py so it is available globally without per-file include directives. Removed all '.. include:: check.rst' lines from hand-written header docs and from the docgen.py generator that emits them for auto-generated header pages. Merged the clang-tidy checks documentation into code_style.rst under a new 'Static Analysis & Clang-Tidy' section, preserving the _clang_tidy_checks label for existing cross-references. Updated code examples in both libc docs and the upstream clang-tidy check docs to replace the stale LLVM_LIBC_ENTRYPOINT macro with the current LLVM_LIBC_FUNCTION macro. Updated dev/index.rst to drop the two deleted toctree entries.
This commit is contained in:
@@ -13,7 +13,7 @@ correct namespace.
|
|||||||
// - LIBC_NAMESPACE_DECL is a macro
|
// - LIBC_NAMESPACE_DECL is a macro
|
||||||
// - LIBC_NAMESPACE_DECL expansion starts with `[[gnu::visibility("hidden")]] __llvm_libc`
|
// - LIBC_NAMESPACE_DECL expansion starts with `[[gnu::visibility("hidden")]] __llvm_libc`
|
||||||
namespace LIBC_NAMESPACE_DECL {
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
|
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||||
// Namespaces within LIBC_NAMESPACE_DECL namespace are allowed.
|
// Namespaces within LIBC_NAMESPACE_DECL namespace are allowed.
|
||||||
namespace inner {
|
namespace inner {
|
||||||
int localVar = 0;
|
int localVar = 0;
|
||||||
@@ -23,15 +23,15 @@ correct namespace.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Incorrect: implementation not in the LIBC_NAMESPACE_DECL namespace.
|
// Incorrect: implementation not in the LIBC_NAMESPACE_DECL namespace.
|
||||||
void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
|
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||||
|
|
||||||
// Incorrect: outer most namespace is not the LIBC_NAMESPACE_DECL macro.
|
// Incorrect: outer most namespace is not the LIBC_NAMESPACE_DECL macro.
|
||||||
namespace something_else {
|
namespace something_else {
|
||||||
void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
|
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incorrect: outer most namespace expansion does not start with `[[gnu::visibility("hidden")]] __llvm_libc`.
|
// Incorrect: outer most namespace expansion does not start with `[[gnu::visibility("hidden")]] __llvm_libc`.
|
||||||
#define LIBC_NAMESPACE_DECL custom_namespace
|
#define LIBC_NAMESPACE_DECL custom_namespace
|
||||||
namespace LIBC_NAMESPACE_DECL {
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
|
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
.. ---------------------------------------------------------------------------
|
|
||||||
Shared substitution definitions for implementation-status badges.
|
|
||||||
This file is excluded from the toctree (via exclude_patterns in conf.py).
|
|
||||||
Include it in any RST page that needs status badges:
|
|
||||||
|
|
||||||
.. include:: /Helpers/Styles.rst (adjust path as needed)
|
|
||||||
|
|
||||||
Usage::
|
|
||||||
|
|
||||||
|Complete| — feature/function is fully implemented
|
|
||||||
|Partial| — partial implementation (some variants/platforms missing)
|
|
||||||
|InProgress| — implementation underway, not yet merged
|
|
||||||
|NotStarted| — no implementation exists yet
|
|
||||||
|GPUOnly| — implemented on GPU targets only
|
|
||||||
|LinuxOnly| — implemented on Linux targets only
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.. |Complete| raw:: html
|
|
||||||
|
|
||||||
<span class="badge badge-complete">Complete</span>
|
|
||||||
|
|
||||||
.. |Partial| raw:: html
|
|
||||||
|
|
||||||
<span class="badge badge-partial">Partial</span>
|
|
||||||
|
|
||||||
.. |InProgress| raw:: html
|
|
||||||
|
|
||||||
<span class="badge badge-inprogress">In Progress</span>
|
|
||||||
|
|
||||||
.. |NotStarted| raw:: html
|
|
||||||
|
|
||||||
<span class="badge badge-notstarted">Not Started</span>
|
|
||||||
|
|
||||||
.. |GPUOnly| raw:: html
|
|
||||||
|
|
||||||
<span class="badge badge-gpuonly">GPU Only</span>
|
|
||||||
|
|
||||||
.. |LinuxOnly| raw:: html
|
|
||||||
|
|
||||||
<span class="badge badge-linuxonly">Linux Only</span>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
.. role:: raw-html(raw)
|
|
||||||
:format: html
|
|
||||||
|
|
||||||
.. |check| replace:: :raw-html:`✅`
|
|
||||||
|
|
||||||
|
|
||||||
@@ -69,7 +69,14 @@ today_fmt = "%Y-%m-%d"
|
|||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
# List of patterns, relative to source directory, that match files and
|
||||||
# directories to ignore when looking for source files.
|
# directories to ignore when looking for source files.
|
||||||
exclude_patterns = ["_build", "Helpers"]
|
exclude_patterns = ["_build"]
|
||||||
|
|
||||||
|
rst_prolog = """
|
||||||
|
.. role:: raw-html(raw)
|
||||||
|
:format: html
|
||||||
|
|
||||||
|
.. |check| replace:: :raw-html:`✅`
|
||||||
|
"""
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||||
# default_role = None
|
# default_role = None
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
.. _clang_tidy_checks:
|
|
||||||
|
|
||||||
LLVM libc clang-tidy checks
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Configuration
|
|
||||||
-------------
|
|
||||||
|
|
||||||
LLVM libc uses layered ``.clang-tidy`` configuration files:
|
|
||||||
|
|
||||||
- ``libc/.clang-tidy``: baseline checks for the ``libc`` subtree (currently
|
|
||||||
focuses on identifier naming conventions).
|
|
||||||
- ``libc/src/.clang-tidy``: adds LLVM-libc-specific checks (``llvmlibc-*``) for
|
|
||||||
implementation code under ``libc/src`` and also enables
|
|
||||||
``readability-identifier-naming`` and ``llvm-header-guard``. Diagnostics from
|
|
||||||
``llvmlibc-*`` checks are treated as errors.
|
|
||||||
|
|
||||||
LLVM-libc checks
|
|
||||||
----------------
|
|
||||||
|
|
||||||
restrict-system-libc-headers
|
|
||||||
----------------------------
|
|
||||||
Check name: ``llvmlibc-restrict-system-libc-headers``.
|
|
||||||
|
|
||||||
One of libc-project’s design goals is to use kernel headers and compiler
|
|
||||||
provided headers to prevent code duplication on a per platform basis. This
|
|
||||||
presents a problem when writing implementations since system libc headers are
|
|
||||||
easy to include accidentally and we can't just use the ``-nostdinc`` flag.
|
|
||||||
Improperly included system headers can introduce runtime errors because the C
|
|
||||||
standard outlines function prototypes and behaviors but doesn’t define
|
|
||||||
underlying implementation details such as the layout of a struct.
|
|
||||||
|
|
||||||
This check prevents accidental inclusion of system libc headers when writing a
|
|
||||||
libc implementation.
|
|
||||||
|
|
||||||
.. code-block:: c++
|
|
||||||
|
|
||||||
#include <stdio.h> // Not allowed because it is part of system libc.
|
|
||||||
#include <stddef.h> // Allowed because it is provided by the compiler.
|
|
||||||
#include "internal/stdio.h" // Allowed because it is NOT part of system libc.
|
|
||||||
|
|
||||||
implementation-in-namespace
|
|
||||||
---------------------------
|
|
||||||
Check name: ``llvmlibc-implementation-in-namespace``.
|
|
||||||
|
|
||||||
All LLVM-libc implementation constructs must be enclosed in the
|
|
||||||
``LIBC_NAMESPACE_DECL`` namespace. See :ref:`code_style` for the full technical
|
|
||||||
rationale and macro definitions.
|
|
||||||
|
|
||||||
This check ensures that top-level declarations in a translation unit are
|
|
||||||
enclosed within the ``LIBC_NAMESPACE_DECL`` namespace.
|
|
||||||
|
|
||||||
.. code-block:: c++
|
|
||||||
|
|
||||||
// Correct: implementation inside the correct namespace.
|
|
||||||
namespace LIBC_NAMESPACE_DECL {
|
|
||||||
void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
|
|
||||||
// Namespaces within LIBC_NAMESPACE namespace are allowed.
|
|
||||||
namespace inner{
|
|
||||||
int localVar = 0;
|
|
||||||
}
|
|
||||||
// Functions with C linkage are allowed.
|
|
||||||
extern "C" void str_fuzz(){}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incorrect: implementation not in a namespace.
|
|
||||||
void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
|
|
||||||
|
|
||||||
// Incorrect: outer most namespace is not correct.
|
|
||||||
namespace something_else {
|
|
||||||
void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
callee-namespace
|
|
||||||
----------------
|
|
||||||
Check name: ``llvmlibc-callee-namespace``.
|
|
||||||
|
|
||||||
LLVM-libc is distinct because it is designed to maintain interoperability with
|
|
||||||
other libc libraries, including the one that lives on the system. This feature
|
|
||||||
creates some uncertainty about which library a call resolves to especially when
|
|
||||||
a public header with non-namespaced functions like ``string.h`` is included.
|
|
||||||
|
|
||||||
This check ensures any function call resolves to a function within the
|
|
||||||
LIBC_NAMESPACE namespace.
|
|
||||||
|
|
||||||
There are exceptions for the following functions:
|
|
||||||
``__errno_location`` so that ``errno`` can be set;
|
|
||||||
``malloc``, ``calloc``, ``realloc``, ``aligned_alloc``, and ``free`` since they
|
|
||||||
are always external and can be intercepted.
|
|
||||||
|
|
||||||
.. code-block:: c++
|
|
||||||
|
|
||||||
namespace LIBC_NAMESPACE_DECL {
|
|
||||||
|
|
||||||
// Allow calls with the fully qualified name.
|
|
||||||
LIBC_NAMESPACE::strlen("hello");
|
|
||||||
|
|
||||||
// Allow calls to compiler provided functions.
|
|
||||||
(void)__builtin_abs(-1);
|
|
||||||
|
|
||||||
// Bare calls are allowed as long as they resolve to the correct namespace.
|
|
||||||
strlen("world");
|
|
||||||
|
|
||||||
// Disallow calling into functions in the global namespace.
|
|
||||||
::strlen("!");
|
|
||||||
|
|
||||||
// Allow calling into specific global functions (explained above)
|
|
||||||
::malloc(10);
|
|
||||||
|
|
||||||
} // namespace LIBC_NAMESPACE_DECL
|
|
||||||
|
|
||||||
|
|
||||||
inline-function-decl
|
|
||||||
--------------------
|
|
||||||
Check name: ``llvmlibc-inline-function-decl``.
|
|
||||||
|
|
||||||
LLVM libc uses the ``LIBC_INLINE`` macro to tag inline function declarations in
|
|
||||||
headers. This check enforces that any inline function declaration in a header
|
|
||||||
begins with ``LIBC_INLINE`` and provides a fix-it to insert the macro.
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
.. _cmake_build_rules:
|
|
||||||
|
|
||||||
===========================
|
|
||||||
The libc CMake build system
|
|
||||||
===========================
|
|
||||||
|
|
||||||
At the cost of verbosity, we want to keep the build system of LLVM libc
|
|
||||||
as simple as possible. We also want to be highly modular with our build
|
|
||||||
targets. This makes picking and choosing desired pieces a straightforward
|
|
||||||
task.
|
|
||||||
|
|
||||||
Targets for entrypoints
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Every entrypoint in LLVM-libc has its own build target, listed using the
|
|
||||||
``add_entrypoint_object`` rule. This rule generates a single object file
|
|
||||||
containing the implementation.
|
|
||||||
|
|
||||||
For more technical details on how to register entrypoints, see the
|
|
||||||
:ref:`entrypoints` documentation.
|
|
||||||
|
|
||||||
Targets for entrypoint libraries
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
Standards like POSIX require that a libc provide certain library files like
|
|
||||||
``libc.a``, ``libm.a``, etc. The targets for such library files are listed in
|
|
||||||
the ``lib`` directory as ``add_entrypoint_library`` targets.
|
|
||||||
|
|
||||||
@@ -289,3 +289,123 @@ Example usage:
|
|||||||
Having hidden visibility on the namespace ensures extern declarations in a given TU
|
Having hidden visibility on the namespace ensures extern declarations in a given TU
|
||||||
have known visibility and never generate GOT indirections. The attribute guarantees
|
have known visibility and never generate GOT indirections. The attribute guarantees
|
||||||
this independently of global compile options and build systems.
|
this independently of global compile options and build systems.
|
||||||
|
|
||||||
|
.. _clang_tidy_checks:
|
||||||
|
|
||||||
|
Static Analysis & Clang-Tidy
|
||||||
|
=============================
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
LLVM libc uses layered ``.clang-tidy`` configuration files:
|
||||||
|
|
||||||
|
- ``libc/.clang-tidy``: baseline checks for the ``libc`` subtree (currently
|
||||||
|
focuses on identifier naming conventions).
|
||||||
|
- ``libc/src/.clang-tidy``: adds LLVM-libc-specific checks (``llvmlibc-*``) for
|
||||||
|
implementation code under ``libc/src`` and also enables
|
||||||
|
``readability-identifier-naming`` and ``llvm-header-guard``. Diagnostics from
|
||||||
|
``llvmlibc-*`` checks are treated as errors.
|
||||||
|
|
||||||
|
LLVM-libc checks
|
||||||
|
----------------
|
||||||
|
|
||||||
|
restrict-system-libc-headers
|
||||||
|
----------------------------
|
||||||
|
Check name: ``llvmlibc-restrict-system-libc-headers``.
|
||||||
|
|
||||||
|
One of libc-project's design goals is to use kernel headers and compiler
|
||||||
|
provided headers to prevent code duplication on a per platform basis. This
|
||||||
|
presents a problem when writing implementations since system libc headers are
|
||||||
|
easy to include accidentally and we can't just use the ``-nostdinc`` flag.
|
||||||
|
Improperly included system headers can introduce runtime errors because the C
|
||||||
|
standard outlines function prototypes and behaviors but doesn't define
|
||||||
|
underlying implementation details such as the layout of a struct.
|
||||||
|
|
||||||
|
This check prevents accidental inclusion of system libc headers when writing a
|
||||||
|
libc implementation.
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
#include <stdio.h> // Not allowed because it is part of system libc.
|
||||||
|
#include <stddef.h> // Allowed because it is provided by the compiler.
|
||||||
|
#include "internal/stdio.h" // Allowed because it is NOT part of system libc.
|
||||||
|
|
||||||
|
implementation-in-namespace
|
||||||
|
---------------------------
|
||||||
|
Check name: ``llvmlibc-implementation-in-namespace``.
|
||||||
|
|
||||||
|
All LLVM-libc implementation constructs must be enclosed in the
|
||||||
|
``LIBC_NAMESPACE_DECL`` namespace. See :ref:`code_style` for the full technical
|
||||||
|
rationale and macro definitions.
|
||||||
|
|
||||||
|
This check ensures that top-level declarations in a translation unit are
|
||||||
|
enclosed within the ``LIBC_NAMESPACE_DECL`` namespace.
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
// Correct: implementation inside the correct namespace.
|
||||||
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
|
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||||
|
// Namespaces within LIBC_NAMESPACE namespace are allowed.
|
||||||
|
namespace inner{
|
||||||
|
int localVar = 0;
|
||||||
|
}
|
||||||
|
// Functions with C linkage are allowed.
|
||||||
|
extern "C" void str_fuzz(){}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Incorrect: implementation not in a namespace.
|
||||||
|
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||||
|
|
||||||
|
// Incorrect: outer most namespace is not correct.
|
||||||
|
namespace something_else {
|
||||||
|
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
callee-namespace
|
||||||
|
----------------
|
||||||
|
Check name: ``llvmlibc-callee-namespace``.
|
||||||
|
|
||||||
|
LLVM-libc is distinct because it is designed to maintain interoperability with
|
||||||
|
other libc libraries, including the one that lives on the system. This feature
|
||||||
|
creates some uncertainty about which library a call resolves to especially when
|
||||||
|
a public header with non-namespaced functions like ``string.h`` is included.
|
||||||
|
|
||||||
|
This check ensures any function call resolves to a function within the
|
||||||
|
LIBC_NAMESPACE namespace.
|
||||||
|
|
||||||
|
There are exceptions for the following functions:
|
||||||
|
``__errno_location`` so that ``errno`` can be set;
|
||||||
|
``malloc``, ``calloc``, ``realloc``, ``aligned_alloc``, and ``free`` since they
|
||||||
|
are always external and can be intercepted.
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
|
|
||||||
|
// Disallow calls to the public versions with the LIBC_NAMESPACE.
|
||||||
|
LIBC_NAMESPACE::strlen("hello");
|
||||||
|
|
||||||
|
// Allow calls to compiler provided functions.
|
||||||
|
(void)__builtin_abs(-1);
|
||||||
|
|
||||||
|
// Disallow bare calls.
|
||||||
|
strlen("world");
|
||||||
|
|
||||||
|
// Disallow calling into functions in the global namespace.
|
||||||
|
::strlen("!");
|
||||||
|
|
||||||
|
// Allow calling into specific global functions (explained above).
|
||||||
|
::malloc(10);
|
||||||
|
|
||||||
|
} // namespace LIBC_NAMESPACE_DECL
|
||||||
|
|
||||||
|
|
||||||
|
inline-function-decl
|
||||||
|
--------------------
|
||||||
|
Check name: ``llvmlibc-inline-function-decl``.
|
||||||
|
|
||||||
|
LLVM libc uses the ``LIBC_INLINE`` macro to tag inline function declarations in
|
||||||
|
headers. This check enforces that any inline function declaration in a header
|
||||||
|
begins with ``LIBC_INLINE`` and provides a fix-it to insert the macro.
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ Navigate to the links below for information on the respective topics:
|
|||||||
source_tree_layout
|
source_tree_layout
|
||||||
entrypoints
|
entrypoints
|
||||||
implementing_a_function
|
implementing_a_function
|
||||||
cmake_build_rules
|
|
||||||
config_options
|
config_options
|
||||||
clang_tidy_checks
|
|
||||||
fuzzing
|
fuzzing
|
||||||
header_generation
|
header_generation
|
||||||
implementation_standard
|
implementation_standard
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
Supported Functions
|
Supported Functions
|
||||||
===================
|
===================
|
||||||
|
|
||||||
.. include:: ../check.rst
|
|
||||||
|
|
||||||
The following functions and headers are supported at least partially on the
|
The following functions and headers are supported at least partially on the
|
||||||
device. Some functions are implemented fully on the GPU, while others require a
|
device. Some functions are implemented fully on the GPU, while others require a
|
||||||
`remote procedure call <libc_gpu_rpc>`_.
|
`remote procedure call <libc_gpu_rpc>`_.
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. include:: ../check.rst
|
|
||||||
|
|
||||||
=========
|
=========
|
||||||
complex.h
|
complex.h
|
||||||
=========
|
=========
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
math.h
|
math.h
|
||||||
======
|
======
|
||||||
|
|
||||||
.. include:: ../../check.rst
|
|
||||||
|
|
||||||
.. raw:: html
|
.. raw:: html
|
||||||
|
|
||||||
<style> .green {color:green} </style>
|
<style> .green {color:green} </style>
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
search.h
|
search.h
|
||||||
========
|
========
|
||||||
|
|
||||||
.. include:: ../check.rst
|
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
Source Location
|
Source Location
|
||||||
---------------
|
---------------
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
stdfix.h
|
stdfix.h
|
||||||
========
|
========
|
||||||
|
|
||||||
.. include:: ../check.rst
|
|
||||||
|
|
||||||
Standards and Goals
|
Standards and Goals
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
time.h
|
time.h
|
||||||
======
|
======
|
||||||
|
|
||||||
.. include:: ../check.rst
|
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
Source location
|
Source location
|
||||||
---------------
|
---------------
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
Supported Functions
|
Supported Functions
|
||||||
===================
|
===================
|
||||||
|
|
||||||
.. include:: ../check.rst
|
|
||||||
|
|
||||||
The follow functions and headers are supported at least partially in
|
The follow functions and headers are supported at least partially in
|
||||||
UEFI. Some functions are implemented fully for UEFI.
|
UEFI. Some functions are implemented fully for UEFI.
|
||||||
|
|
||||||
|
|||||||
@@ -183,11 +183,6 @@ def print_macros_rst(header: Header, macros: Dict):
|
|||||||
|
|
||||||
|
|
||||||
def print_impl_status_rst(header: Header, api: Dict):
|
def print_impl_status_rst(header: Header, api: Dict):
|
||||||
if os.sep in header.name:
|
|
||||||
print(".. include:: ../../check.rst\n")
|
|
||||||
else:
|
|
||||||
print(".. include:: ../check.rst\n")
|
|
||||||
|
|
||||||
print("=" * len(header.name))
|
print("=" * len(header.name))
|
||||||
print(header.name)
|
print(header.name)
|
||||||
print("=" * len(header.name))
|
print("=" * len(header.name))
|
||||||
|
|||||||
Reference in New Issue
Block a user