xref: /linux/tools/net/sunrpc/xdrgen/subcmds/definitions.py (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
1#!/usr/bin/env python3
2# ex: set filetype=python:
3
4"""Translate an XDR specification into executable code that
5can be compiled for the Linux kernel."""
6
7import logging
8
9from argparse import Namespace
10from lark import logger
11from lark.exceptions import VisitError
12
13from generators.constant import XdrConstantGenerator
14from generators.enum import XdrEnumGenerator
15from generators.header_bottom import XdrHeaderBottomGenerator
16from generators.header_top import XdrHeaderTopGenerator
17from generators.passthru import XdrPassthruGenerator
18from generators.pointer import XdrPointerGenerator
19from generators.program import XdrProgramGenerator
20from generators.typedef import XdrTypedefGenerator
21from generators.struct import XdrStructGenerator
22from generators.union import XdrUnionGenerator
23
24from xdr_ast import transform_parse_tree, Specification
25from xdr_ast import _RpcProgram, _XdrConstant, _XdrEnum, _XdrPassthru, _XdrPointer
26from xdr_ast import _XdrTypedef, _XdrStruct, _XdrUnion
27from xdr_parse import xdr_parser, set_xdr_annotate
28from xdr_parse import make_error_handler, XdrParseError
29from xdr_parse import handle_transform_error
30
31logger.setLevel(logging.INFO)
32
33
34def emit_header_definitions(root: Specification, language: str, peer: str) -> None:
35    """Emit header definitions"""
36    for definition in root.definitions:
37        if isinstance(definition.value, _XdrConstant):
38            gen = XdrConstantGenerator(language, peer)
39        elif isinstance(definition.value, _XdrEnum):
40            gen = XdrEnumGenerator(language, peer)
41        elif isinstance(definition.value, _XdrPointer):
42            gen = XdrPointerGenerator(language, peer)
43        elif isinstance(definition.value, _RpcProgram):
44            gen = XdrProgramGenerator(language, peer)
45        elif isinstance(definition.value, _XdrTypedef):
46            gen = XdrTypedefGenerator(language, peer)
47        elif isinstance(definition.value, _XdrStruct):
48            gen = XdrStructGenerator(language, peer)
49        elif isinstance(definition.value, _XdrUnion):
50            gen = XdrUnionGenerator(language, peer)
51        elif isinstance(definition.value, _XdrPassthru):
52            gen = XdrPassthruGenerator(language, peer)
53        else:
54            continue
55        gen.emit_definition(definition.value)
56
57
58def emit_header_maxsize(root: Specification, language: str, peer: str) -> None:
59    """Emit header maxsize macros"""
60    print("")
61    for definition in root.definitions:
62        if isinstance(definition.value, _XdrEnum):
63            gen = XdrEnumGenerator(language, peer)
64        elif isinstance(definition.value, _XdrPointer):
65            gen = XdrPointerGenerator(language, peer)
66        elif isinstance(definition.value, _XdrTypedef):
67            gen = XdrTypedefGenerator(language, peer)
68        elif isinstance(definition.value, _XdrStruct):
69            gen = XdrStructGenerator(language, peer)
70        elif isinstance(definition.value, _XdrUnion):
71            gen = XdrUnionGenerator(language, peer)
72        elif isinstance(definition.value, _RpcProgram):
73            gen = XdrProgramGenerator(language, peer)
74        else:
75            continue
76        gen.emit_maxsize(definition.value)
77
78
79def subcmd(args: Namespace) -> int:
80    """Generate definitions"""
81
82    set_xdr_annotate(args.annotate)
83    parser = xdr_parser()
84    with open(args.filename, encoding="utf-8") as f:
85        source = f.read()
86        try:
87            parse_tree = parser.parse(
88                source, on_error=make_error_handler(source, args.filename)
89            )
90        except XdrParseError:
91            return 1
92        try:
93            ast = transform_parse_tree(parse_tree)
94        except VisitError as e:
95            handle_transform_error(e, source, args.filename)
96            return 1
97
98        gen = XdrHeaderTopGenerator(args.language, args.peer)
99        gen.emit_definition(args.filename, ast)
100
101        emit_header_definitions(ast, args.language, args.peer)
102        emit_header_maxsize(ast, args.language, args.peer)
103
104        gen = XdrHeaderBottomGenerator(args.language, args.peer)
105        gen.emit_definition(args.filename, ast)
106
107    return 0
108