[libc-commits] [libc] [libc] added newhdrgen python script and class file (PR #96671)

Nick Desaulniers via libc-commits libc-commits at lists.llvm.org
Tue Jun 25 13:03:48 PDT 2024


================
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+#
+# ====- Generate headers 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
+#
+# ==-------------------------------------------------------------------------==#
+import yaml
+import os
+import re
+import argparse
+
+from header import HeaderFile
+from class_implementation.classes.macro import Macro
+from class_implementation.classes.type import Type
+from class_implementation.classes.function import Function
+from class_implementation.classes.include import Include
+from class_implementation.classes.enums import Enumeration
+from class_implementation.classes.object import Object
+
+
+def yaml_to_classes(yaml_data):
+    """
+    Convert YAML data to header classes.
+
+    Args:
+        yaml_data: The YAML data containing header specifications.
+
+    Returns:
+        HeaderFile: An instance of HeaderFile populated with the data.
+    """
+    header_name = yaml_data.get("header", "unknown.h")
+    header = HeaderFile(header_name)
+
+    for macro_data in yaml_data.get("macros", []):
+        header.add_macro(Macro(macro_data["macro_name"], macro_data["macro_value"]))
+
+    for type_data in yaml_data.get("types", []):
+        header.add_type(Type(type_data["type_name"]))
+
+    for enum_data in yaml_data.get("enums", []):
+        header.add_enumeration(
+            Enumeration(enum_data["name"], enum_data.get("value", None))
+        )
+
+    for object_data in yaml_data.get("objects", []):
+        header.add_object(
+            Object(object_data["object_name"], object_data["object_type"])
+        )
+
+    for function_data in yaml_data.get("functions", []):
+        arguments = [arg["type"] for arg in function_data["arguments"]]
+        header.add_function(
+            Function(
+                function_data["return_type"],
+                function_data["name"],
+                arguments,
+                function_data.get("guard"),
+                function_data.get("attributes", []),
+            )
+        )
+
+    for include_data in yaml_data.get("includes", []):
+        header.add_include(Include(include_data))
+
+    return header
+
+
+def load_yaml_file(yaml_file):
+    """
+    Load YAML file and convert it to header classes.
+
+    Args:
+        yaml_file: The path to the YAML file.
+
+    Returns:
+        HeaderFile: An instance of HeaderFile populated with the data from the YAML file.
+    """
+    with open(yaml_file, "r") as f:
+        yaml_data = yaml.safe_load(f)
+    return yaml_to_classes(yaml_data)
+
+
+def fill_public_api(header_str, h_def_content):
+    """
+    Replace the %%public_api() placeholder in the .h.def content with the generated header content.
+
+    Args:
+        header_str: The generated header string.
+        h_def_content: The content of the .h.def file.
+
+    Returns:
+        The final header content with the public API filled in.
+    """
+    return re.sub(r"%%public_api\(\)", header_str, h_def_content)
+
+
+def main(yaml_file, h_def_file, output_dir):
+    """
+    Main function to generate header files from YAML and .h.def templates.
+
+    Args:
+        yaml_file: Path to the YAML file containing header specification.
+        h_def_file: Path to the .h.def template file.
+        output_dir: Directory to output the generated header file.
+    """
+    
+    header = load_yaml_file(yaml_file)
+
+    with open(h_def_file, "r") as f:
+        h_def_content = f.read()
+
+    header_str = str(header)
+    final_header_content = fill_public_api(header_str, h_def_content)
+
+    output_file_name = os.path.basename(h_def_file).replace(".def", "")
+    output_file_path = os.path.join(output_dir, output_file_name)
----------------
nickdesaulniers wrote:

Python now has a `Path` class. Please use that instead of `os.path`.
https://docs.python.org/3/library/pathlib.html

https://github.com/llvm/llvm-project/pull/96671


More information about the libc-commits mailing list