Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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