mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
XDR specification files can contain lines prefixed with '%' that pass through unchanged to generated output. Traditional rpcgen removes the '%' and emits the remainder verbatim, allowing direct insertion of C includes, pragma directives, or other language- specific content into the generated code. Until now, xdrgen silently discarded these lines during parsing. This prevented specifications from including necessary headers or preprocessor directives that might be required for the generated code to compile correctly. The grammar now captures pass-through lines instead of ignoring them. A new AST node type represents pass-through content, and the AST transformer strips the leading '%' character. Definition and source generators emit pass-through content in document order, preserving the original placement within the specification. This brings xdrgen closer to feature parity with traditional rpcgen while maintaining the existing document-order processing model. Existing generated xdrgen source code has been regenerated. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
81 lines
2.7 KiB
Python
81 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
# ex: set filetype=python:
|
|
|
|
"""Translate an XDR specification into executable code that
|
|
can be compiled for the Linux kernel."""
|
|
|
|
import logging
|
|
|
|
from argparse import Namespace
|
|
from lark import logger
|
|
from lark.exceptions import VisitError
|
|
|
|
from generators.enum import XdrEnumGenerator
|
|
from generators.header_bottom import XdrHeaderBottomGenerator
|
|
from generators.header_top import XdrHeaderTopGenerator
|
|
from generators.pointer import XdrPointerGenerator
|
|
from generators.program import XdrProgramGenerator
|
|
from generators.typedef import XdrTypedefGenerator
|
|
from generators.struct import XdrStructGenerator
|
|
from generators.union import XdrUnionGenerator
|
|
|
|
from xdr_ast import transform_parse_tree, _RpcProgram, Specification
|
|
from xdr_ast import _XdrEnum, _XdrPointer, _XdrTypedef, _XdrStruct, _XdrUnion
|
|
from xdr_parse import xdr_parser, set_xdr_annotate
|
|
from xdr_parse import make_error_handler, XdrParseError
|
|
from xdr_parse import handle_transform_error
|
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
|
|
def emit_header_declarations(
|
|
root: Specification, language: str, peer: str
|
|
) -> None:
|
|
"""Emit header declarations"""
|
|
for definition in root.definitions:
|
|
if isinstance(definition.value, _XdrEnum):
|
|
gen = XdrEnumGenerator(language, peer)
|
|
elif isinstance(definition.value, _XdrPointer):
|
|
gen = XdrPointerGenerator(language, peer)
|
|
elif isinstance(definition.value, _XdrTypedef):
|
|
gen = XdrTypedefGenerator(language, peer)
|
|
elif isinstance(definition.value, _XdrStruct):
|
|
gen = XdrStructGenerator(language, peer)
|
|
elif isinstance(definition.value, _XdrUnion):
|
|
gen = XdrUnionGenerator(language, peer)
|
|
elif isinstance(definition.value, _RpcProgram):
|
|
gen = XdrProgramGenerator(language, peer)
|
|
else:
|
|
continue
|
|
gen.emit_declaration(definition.value)
|
|
|
|
|
|
def subcmd(args: Namespace) -> int:
|
|
"""Generate definitions and declarations"""
|
|
|
|
set_xdr_annotate(args.annotate)
|
|
parser = xdr_parser()
|
|
with open(args.filename, encoding="utf-8") as f:
|
|
source = f.read()
|
|
try:
|
|
parse_tree = parser.parse(
|
|
source, on_error=make_error_handler(source, args.filename)
|
|
)
|
|
except XdrParseError:
|
|
return 1
|
|
try:
|
|
ast = transform_parse_tree(parse_tree)
|
|
except VisitError as e:
|
|
handle_transform_error(e, source, args.filename)
|
|
return 1
|
|
|
|
gen = XdrHeaderTopGenerator(args.language, args.peer)
|
|
gen.emit_declaration(args.filename, ast)
|
|
|
|
emit_header_declarations(ast, args.language, args.peer)
|
|
|
|
gen = XdrHeaderBottomGenerator(args.language, args.peer)
|
|
gen.emit_declaration(args.filename, ast)
|
|
|
|
return 0
|