brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 5bf524a Raw
93 lines · python
1# ====- Information about standard headers used by docgen  ----*- python -*--==#2#3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4# See https://llvm.org/LICENSE.txt for license information.5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6#7# ==-------------------------------------------------------------------------==#8from pathlib import Path9from typing import Generator10 11 12class Header:13    """14    Maintains implementation information about a standard header file:15    * where does its implementation dir live16    * where is its macros file17    * where is its docgen yaml file18 19    By convention, the macro-only part of a header file is in a header-specific20    file somewhere in the directory tree with root at21    ``$LLVM_PROJECT_ROOT/libc/include/llvm-libc-macros``.  Docgen expects that22    if a macro is implemented, that it appears in a string23    ``#define MACRO_NAME`` in some ``*-macros.h`` file in the directory tree.24    Docgen searches for this string in the file to set the implementation status25    shown in the generated rst docs rendered as html for display at26    <libc.llvm.org>.27 28    By convention, each function for a header is implemented in a function-specific29    cpp file somewhere in the directory tree with root at, e.g,30    ``$LLVM_PROJECT_ROOT/libc/src/fenv``. Some headers have architecture-specific31    implementations, like ``math``, and some don't, like ``fenv``. Docgen uses the32    presence of this function-specific cpp file to set the implementation status33    shown in the generated rst docs rendered as html for display at34    <libc.llvm.org>.35    """36 37    def __init__(self, header_name: str):38        """39        :param header_name: e.g., ``"threads.h"`` or ``"signal.h"``40        """41        self.name = header_name42        self.stem = header_name.rstrip(".h")43        self.docgen_root = Path(__file__).parent44        self.libc_root = self.docgen_root.parent.parent45        self.docgen_yaml = self.docgen_root / Path(header_name).with_suffix(".yaml")46        self.fns_dir = Path(self.libc_root, "src", self.stem)47        self.macros_dir = Path(self.libc_root, "include", "llvm-libc-macros")48 49    def macro_file_exists(self) -> bool:50        for _ in self.__get_macro_files():51            return True52 53        return False54 55    def fns_dir_exists(self) -> bool:56        return self.fns_dir.exists() and self.fns_dir.is_dir()57 58    def implements_fn(self, fn_name: str) -> bool:59        for _ in self.fns_dir.glob(f"**/{fn_name}.cpp"):60            return True61 62        return False63 64    def implements_macro(self, m_name: str) -> bool:65        """66        Some macro files are in, e.g.,67        ``$LLVM_PROJECT_ROOT/libc/include/llvm-libc-macros/fenv-macros.h``,68        but others are in subdirectories, e.g., ``signal.h`` has the macro69        definitions in70        ``$LLVM_PROJECT_ROOT/libc/include/llvm-libc-macros/linux/signal-macros.h``.71 72        :param m_name: name of macro, e.g., ``FE_ALL_EXCEPT``73        """74        for f in self.__get_macro_files():75            if f"#define {m_name}" in f.read_text():76                return True77 78        return False79 80    def __get_macro_files(self) -> Generator[Path, None, None]:81        """82        This function uses a glob on, e.g., ``"**/fcntl.macros.h"`` because the83        macro file might be located in a subdirectory:84        libc/include/llvm-libc-macros/fcntl-macros.h85        libc/include/llvm-libc-macros/linux/fcntl-macros.h86 87        When a header would be nested in a dir (such as arpa/, sys/, etc) we88        instead use a hyphen in the name.89        libc/include/llvm-libc-macros/sys-mman-macros.h90        """91        stem = self.stem.replace("/", "-")92        return self.macros_dir.glob(f"**/{stem}-macros.h")93