diff options
author | aaryanshukla <53713108+aaryanshukla@users.noreply.github.com> | 2024-06-26 16:37:25 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-26 16:37:25 -0700 |
commit | 1fa9f506d33a25c83f23862abd2400f1df3c413e (patch) | |
tree | 42b98ad9bb27f31ae33e2da5826e07c0ce26cfbe /libc | |
parent | 4558e45e7e33d1cfc1a54af761085e358dbab64b (diff) | |
download | llvm-1fa9f506d33a25c83f23862abd2400f1df3c413e.zip llvm-1fa9f506d33a25c83f23862abd2400f1df3c413e.tar.gz llvm-1fa9f506d33a25c83f23862abd2400f1df3c413e.tar.bz2 |
[libc] added newhdrgen python script and class file (#96671)
python script uses yaml and classes to generate c headers
header.py is only the main class file, the rest will be in another pr
more files to be added in multiple prs
Diffstat (limited to 'libc')
-rw-r--r-- | libc/newhdrgen/header.py | 67 | ||||
-rw-r--r-- | libc/newhdrgen/yaml_to_classes.py | 144 |
2 files changed, 211 insertions, 0 deletions
diff --git a/libc/newhdrgen/header.py b/libc/newhdrgen/header.py new file mode 100644 index 0000000..7ce3568 --- /dev/null +++ b/libc/newhdrgen/header.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# ====- HeaderFile Class for libc function headers -----------*- 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 +# +# ==-------------------------------------------------------------------------==# + + +class HeaderFile: + def __init__(self, name): + self.name = name + self.macros = [] + self.types = [] + self.enumerations = [] + self.objects = [] + self.functions = [] + self.includes = [] + + def add_macro(self, macro): + self.macros.append(macro) + + def add_type(self, type_): + self.types.append(type_) + + def add_enumeration(self, enumeration): + self.enumerations.append(enumeration) + + def add_object(self, object): + self.objects.append(object) + + def add_function(self, function): + self.functions.append(function) + + def add_include(self, include): + self.includes.append(include) + + def __str__(self): + content = [""] + + for include in self.includes: + content.append(str(include)) + + for macro in self.macros: + content.append(str(macro)) + + for object in self.objects: + content.append(str(object)) + + for type_ in self.types: + content.append(str(type_)) + + if self.enumerations: + content.append("enum {") + for enum in self.enumerations: + content.append(f"\t{str(enum)},") + content.append("};") + + # TODO: replace line below with common.h functionality + content.append("__BEGIN_C_DECLS\n") + for function in self.functions: + content.append(str(function)) + content.append("") + content.append("__END_C_DECLS\n") + return "\n".join(content) diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py new file mode 100644 index 0000000..1ac4484 --- /dev/null +++ b/libc/newhdrgen/yaml_to_classes.py @@ -0,0 +1,144 @@ +#!/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 re +import argparse + +from pathlib import Path +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.enumeration 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") + 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 h_def_content.replace("%%public_api()", header_str, 1) + + +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 = Path(h_def_file).stem + output_file_path = Path(output_dir) / output_file_name + + with open(output_file_path, "w") as f: + f.write(final_header_content) + + print(f"Generated header file: {output_file_path}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Generate header files from YAML and .h.def templates" + ) + parser.add_argument( + "yaml_file", help="Path to the YAML file containing header specification" + ) + parser.add_argument("h_def_file", help="Path to the .h.def template file") + parser.add_argument( + "--output_dir", + default=".", + help="Directory to output the generated header file", + ) + args = parser.parse_args() + + main(args.yaml_file, args.h_def_file, args.output_dir) |