diff options
Diffstat (limited to 'tools/net/sunrpc/xdrgen/generators/__init__.py')
-rw-r--r-- | tools/net/sunrpc/xdrgen/generators/__init__.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/tools/net/sunrpc/xdrgen/generators/__init__.py b/tools/net/sunrpc/xdrgen/generators/__init__.py new file mode 100644 index 000000000000..b98574a36a4a --- /dev/null +++ b/tools/net/sunrpc/xdrgen/generators/__init__.py @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: GPL-2.0 + +"""Define a base code generator class""" + +import sys +from jinja2 import Environment, FileSystemLoader, Template + +from xdr_ast import _XdrAst, Specification, _RpcProgram, _XdrTypeSpecifier +from xdr_ast import public_apis, pass_by_reference, get_header_name +from xdr_parse import get_xdr_annotate + + +def create_jinja2_environment(language: str, xdr_type: str) -> Environment: + """Open a set of templates based on output language""" + match language: + case "C": + environment = Environment( + loader=FileSystemLoader(sys.path[0] + "/templates/C/" + xdr_type + "/"), + trim_blocks=True, + lstrip_blocks=True, + ) + environment.globals["annotate"] = get_xdr_annotate() + environment.globals["public_apis"] = public_apis + environment.globals["pass_by_reference"] = pass_by_reference + return environment + case _: + raise NotImplementedError("Language not supported") + + +def get_jinja2_template( + environment: Environment, template_type: str, template_name: str +) -> Template: + """Retrieve a Jinja2 template for emitting source code""" + return environment.get_template(template_type + "/" + template_name + ".j2") + + +def find_xdr_program_name(root: Specification) -> str: + """Retrieve the RPC program name from an abstract syntax tree""" + raw_name = get_header_name() + if raw_name != "none": + return raw_name.lower() + for definition in root.definitions: + if isinstance(definition.value, _RpcProgram): + raw_name = definition.value.name + return raw_name.lower().removesuffix("_program").removesuffix("_prog") + return "noprog" + + +def header_guard_infix(filename: str) -> str: + """Extract the header guard infix from the specification filename""" + basename = filename.split("/")[-1] + program = basename.replace(".x", "") + return program.upper() + + +def kernel_c_type(spec: _XdrTypeSpecifier) -> str: + """Return name of C type""" + builtin_native_c_type = { + "bool": "bool", + "int": "s32", + "unsigned_int": "u32", + "long": "s32", + "unsigned_long": "u32", + "hyper": "s64", + "unsigned_hyper": "u64", + } + if spec.type_name in builtin_native_c_type: + return builtin_native_c_type[spec.type_name] + return spec.type_name + + +class Boilerplate: + """Base class to generate boilerplate for source files""" + + def __init__(self, language: str, peer: str): + """Initialize an instance of this class""" + raise NotImplementedError("No language support defined") + + def emit_declaration(self, filename: str, root: Specification) -> None: + """Emit declaration header boilerplate""" + raise NotImplementedError("Header boilerplate generation not supported") + + def emit_definition(self, filename: str, root: Specification) -> None: + """Emit definition header boilerplate""" + raise NotImplementedError("Header boilerplate generation not supported") + + def emit_source(self, filename: str, root: Specification) -> None: + """Emit generic source code for this XDR type""" + raise NotImplementedError("Source boilerplate generation not supported") + + +class SourceGenerator: + """Base class to generate header and source code for XDR types""" + + def __init__(self, language: str, peer: str): + """Initialize an instance of this class""" + raise NotImplementedError("No language support defined") + + def emit_declaration(self, node: _XdrAst) -> None: + """Emit one function declaration for this XDR type""" + raise NotImplementedError("Declaration generation not supported") + + def emit_decoder(self, node: _XdrAst) -> None: + """Emit one decoder function for this XDR type""" + raise NotImplementedError("Decoder generation not supported") + + def emit_definition(self, node: _XdrAst) -> None: + """Emit one definition for this XDR type""" + raise NotImplementedError("Definition generation not supported") + + def emit_encoder(self, node: _XdrAst) -> None: + """Emit one encoder function for this XDR type""" + raise NotImplementedError("Encoder generation not supported") + + def emit_maxsize(self, node: _XdrAst) -> None: + """Emit one maxsize macro for this XDR type""" + raise NotImplementedError("Maxsize macro generation not supported") |