Skip to content

Commit 6bc85ba

Browse files
committed
xdrgen: Implement pass-through lines in specifications
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>
1 parent 3daab31 commit 6bc85ba

12 files changed

Lines changed: 116 additions & 20 deletions

File tree

fs/nfsd/nfs4xdr_gen.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22
// Generated by xdrgen. Manual edits will be lost.
33
// XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x
4-
// XDR specification modification time: Thu Dec 25 13:44:43 2025
4+
// XDR specification modification time: Thu Jan 8 23:11:48 2026
55

66
#include <linux/sunrpc/svc.h>
77

@@ -178,6 +178,10 @@ xdrgen_decode_fattr4_open_arguments(struct xdr_stream *xdr, fattr4_open_argument
178178
return xdrgen_decode_open_arguments4(xdr, ptr);
179179
}
180180

181+
/*
182+
* Determine what OPEN supports.
183+
*/
184+
181185
bool
182186
xdrgen_decode_fattr4_time_deleg_access(struct xdr_stream *xdr, fattr4_time_deleg_access *ptr)
183187
{
@@ -190,6 +194,11 @@ xdrgen_decode_fattr4_time_deleg_modify(struct xdr_stream *xdr, fattr4_time_deleg
190194
return xdrgen_decode_nfstime4(xdr, ptr);
191195
}
192196

197+
/*
198+
* New RECOMMENDED Attribute for
199+
* delegation caching of times
200+
*/
201+
193202
static bool __maybe_unused
194203
xdrgen_decode_open_delegation_type4(struct xdr_stream *xdr, open_delegation_type4 *ptr)
195204
{

fs/nfsd/nfs4xdr_gen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
/* Generated by xdrgen. Manual edits will be lost. */
33
/* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */
4-
/* XDR specification modification time: Thu Dec 25 13:44:43 2025 */
4+
/* XDR specification modification time: Thu Jan 8 23:11:48 2026 */
55

66
#ifndef _LINUX_XDRGEN_NFS4_1_DECL_H
77
#define _LINUX_XDRGEN_NFS4_1_DECL_H

include/linux/sunrpc/xdrgen/nfs4_1.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
/* Generated by xdrgen. Manual edits will be lost. */
33
/* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */
4-
/* XDR specification modification time: Thu Dec 25 13:44:43 2025 */
4+
/* XDR specification modification time: Thu Jan 8 23:11:48 2026 */
55

66
#ifndef _LINUX_XDRGEN_NFS4_1_DEF_H
77
#define _LINUX_XDRGEN_NFS4_1_DEF_H
@@ -87,6 +87,10 @@ typedef enum open_args_createmode4 open_args_createmode4;
8787

8888
typedef struct open_arguments4 fattr4_open_arguments;
8989

90+
/*
91+
* Determine what OPEN supports.
92+
*/
93+
9094
enum { FATTR4_OPEN_ARGUMENTS = 86 };
9195

9296
enum { OPEN4_RESULT_NO_OPEN_STATEID = 0x00000010 };
@@ -95,6 +99,11 @@ typedef struct nfstime4 fattr4_time_deleg_access;
9599

96100
typedef struct nfstime4 fattr4_time_deleg_modify;
97101

102+
/*
103+
* New RECOMMENDED Attribute for
104+
* delegation caching of times
105+
*/
106+
98107
enum { FATTR4_TIME_DELEG_ACCESS = 84 };
99108

100109
enum { FATTR4_TIME_DELEG_MODIFY = 85 };

tools/net/sunrpc/xdrgen/README

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,6 @@ Add more pragma directives:
250250
Enable something like a #include to dynamically insert the content
251251
of other specification files
252252

253-
Properly support line-by-line pass-through via the "%" decorator
254-
255253
Build a unit test suite for verifying translation of XDR language
256254
into compilable code
257255

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env python3
2+
# ex: set filetype=python:
3+
4+
"""Generate code for XDR pass-through lines"""
5+
6+
from generators import SourceGenerator, create_jinja2_environment
7+
from xdr_ast import _XdrPassthru
8+
9+
10+
class XdrPassthruGenerator(SourceGenerator):
11+
"""Generate source code for XDR pass-through content"""
12+
13+
def __init__(self, language: str, peer: str):
14+
"""Initialize an instance of this class"""
15+
self.environment = create_jinja2_environment(language, "passthru")
16+
self.peer = peer
17+
18+
def emit_definition(self, node: _XdrPassthru) -> None:
19+
"""Emit one pass-through line"""
20+
template = self.environment.get_template("definition.j2")
21+
print(template.render(content=node.content))
22+
23+
def emit_decoder(self, node: _XdrPassthru) -> None:
24+
"""Emit one pass-through line"""
25+
template = self.environment.get_template("source.j2")
26+
print(template.render(content=node.content))

tools/net/sunrpc/xdrgen/grammars/xdr.lark

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ definition : constant_def
7878
| type_def
7979
| program_def
8080
| pragma_def
81+
| passthru_def
82+
83+
passthru_def : PASSTHRU
8184

8285
//
8386
// RPC program definitions not specified in RFC 4506
@@ -115,8 +118,7 @@ decimal_constant : /[\+-]?(0|[1-9][0-9]*)/
115118
hexadecimal_constant : /0x([a-f]|[A-F]|[0-9])+/
116119
octal_constant : /0[0-7]+/
117120

118-
PASSTHRU : "%" | "%" /.+/
119-
%ignore PASSTHRU
121+
PASSTHRU : /%.*/
120122

121123
%import common.C_COMMENT
122124
%ignore C_COMMENT

tools/net/sunrpc/xdrgen/subcmds/declarations.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from lark import logger
1111
from lark.exceptions import VisitError
1212

13-
from generators.constant import XdrConstantGenerator
1413
from generators.enum import XdrEnumGenerator
1514
from generators.header_bottom import XdrHeaderBottomGenerator
1615
from generators.header_top import XdrHeaderTopGenerator
@@ -21,8 +20,7 @@
2120
from generators.union import XdrUnionGenerator
2221

2322
from xdr_ast import transform_parse_tree, _RpcProgram, Specification
24-
from xdr_ast import _XdrConstant, _XdrEnum, _XdrPointer
25-
from xdr_ast import _XdrTypedef, _XdrStruct, _XdrUnion
23+
from xdr_ast import _XdrEnum, _XdrPointer, _XdrTypedef, _XdrStruct, _XdrUnion
2624
from xdr_parse import xdr_parser, set_xdr_annotate
2725
from xdr_parse import make_error_handler, XdrParseError
2826
from xdr_parse import handle_transform_error

tools/net/sunrpc/xdrgen/subcmds/definitions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
from generators.enum import XdrEnumGenerator
1515
from generators.header_bottom import XdrHeaderBottomGenerator
1616
from generators.header_top import XdrHeaderTopGenerator
17+
from generators.passthru import XdrPassthruGenerator
1718
from generators.pointer import XdrPointerGenerator
1819
from generators.program import XdrProgramGenerator
1920
from generators.typedef import XdrTypedefGenerator
2021
from generators.struct import XdrStructGenerator
2122
from generators.union import XdrUnionGenerator
2223

2324
from xdr_ast import transform_parse_tree, Specification
24-
from xdr_ast import _RpcProgram, _XdrConstant, _XdrEnum, _XdrPointer
25+
from xdr_ast import _RpcProgram, _XdrConstant, _XdrEnum, _XdrPassthru, _XdrPointer
2526
from xdr_ast import _XdrTypedef, _XdrStruct, _XdrUnion
2627
from xdr_parse import xdr_parser, set_xdr_annotate
2728
from xdr_parse import make_error_handler, XdrParseError
@@ -47,6 +48,8 @@ def emit_header_definitions(root: Specification, language: str, peer: str) -> No
4748
gen = XdrStructGenerator(language, peer)
4849
elif isinstance(definition.value, _XdrUnion):
4950
gen = XdrUnionGenerator(language, peer)
51+
elif isinstance(definition.value, _XdrPassthru):
52+
gen = XdrPassthruGenerator(language, peer)
5053
else:
5154
continue
5255
gen.emit_definition(definition.value)

tools/net/sunrpc/xdrgen/subcmds/source.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@
1212

1313
from generators.source_top import XdrSourceTopGenerator
1414
from generators.enum import XdrEnumGenerator
15+
from generators.passthru import XdrPassthruGenerator
1516
from generators.pointer import XdrPointerGenerator
1617
from generators.program import XdrProgramGenerator
1718
from generators.typedef import XdrTypedefGenerator
1819
from generators.struct import XdrStructGenerator
1920
from generators.union import XdrUnionGenerator
2021

2122
from xdr_ast import transform_parse_tree, _RpcProgram, Specification
22-
from xdr_ast import _XdrAst, _XdrEnum, _XdrPointer
23+
from xdr_ast import _XdrAst, _XdrEnum, _XdrPassthru, _XdrPointer
2324
from xdr_ast import _XdrStruct, _XdrTypedef, _XdrUnion
2425

2526
from xdr_parse import xdr_parser, set_xdr_annotate, set_xdr_enum_validation
@@ -74,22 +75,31 @@ def generate_server_source(filename: str, root: Specification, language: str) ->
7475
gen.emit_source(filename, root)
7576

7677
for definition in root.definitions:
77-
emit_source_decoder(definition.value, language, "server")
78+
if isinstance(definition.value, _XdrPassthru):
79+
passthru_gen = XdrPassthruGenerator(language, "server")
80+
passthru_gen.emit_decoder(definition.value)
81+
else:
82+
emit_source_decoder(definition.value, language, "server")
7883
for definition in root.definitions:
79-
emit_source_encoder(definition.value, language, "server")
84+
if not isinstance(definition.value, _XdrPassthru):
85+
emit_source_encoder(definition.value, language, "server")
8086

8187

8288
def generate_client_source(filename: str, root: Specification, language: str) -> None:
83-
"""Generate server-side source code"""
89+
"""Generate client-side source code"""
8490

8591
gen = XdrSourceTopGenerator(language, "client")
8692
gen.emit_source(filename, root)
8793

88-
print("")
8994
for definition in root.definitions:
90-
emit_source_encoder(definition.value, language, "client")
95+
if isinstance(definition.value, _XdrPassthru):
96+
passthru_gen = XdrPassthruGenerator(language, "client")
97+
passthru_gen.emit_decoder(definition.value)
98+
else:
99+
emit_source_encoder(definition.value, language, "client")
91100
for definition in root.definitions:
92-
emit_source_decoder(definition.value, language, "client")
101+
if not isinstance(definition.value, _XdrPassthru):
102+
emit_source_decoder(definition.value, language, "client")
93103

94104
# cel: todo: client needs PROC macros
95105

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{# SPDX-License-Identifier: GPL-2.0 #}
2+
3+
{{ content }}

0 commit comments

Comments
 (0)