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"""Generate code to handle XDR struct types"""
5
6from jinja2 import Environment
7
8from generators import SourceGenerator, kernel_c_type
9from generators import create_jinja2_environment, get_jinja2_template
10
11from xdr_ast import _XdrBasic, _XdrString
12from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque
13from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray
14from xdr_ast import _XdrOptionalData, _XdrStruct, _XdrDeclaration
15from xdr_ast import public_apis, get_header_name
16
17
18def emit_struct_declaration(environment: Environment, node: _XdrStruct) -> None:
19 """Emit one declaration pair for an XDR struct type"""
20 if node.name in public_apis:
21 template = get_jinja2_template(environment, "declaration", "close")
22 print(template.render(name=node.name))
23
24
25def emit_struct_member_definition(
26 environment: Environment, field: _XdrDeclaration
27) -> None:
28 """Emit a definition for one field in an XDR struct"""
29 if isinstance(field, _XdrBasic):
30 template = get_jinja2_template(environment, "definition", field.template)
31 print(
32 template.render(
33 name=field.name,
34 type=kernel_c_type(field.spec),
35 classifier=field.spec.c_classifier,
36 )
37 )
38 elif isinstance(field, _XdrFixedLengthOpaque):
39 template = get_jinja2_template(environment, "definition", field.template)
40 print(
41 template.render(
42 name=field.name,
43 size=field.size,
44 )
45 )
46 elif isinstance(field, _XdrVariableLengthOpaque):
47 template = get_jinja2_template(environment, "definition", field.template)
48 print(template.render(name=field.name))
49 elif isinstance(field, _XdrString):
50 template = get_jinja2_template(environment, "definition", field.template)
51 print(template.render(name=field.name))
52 elif isinstance(field, _XdrFixedLengthArray):
53 template = get_jinja2_template(environment, "definition", field.template)
54 print(
55 template.render(
56 name=field.name,
57 type=kernel_c_type(field.spec),
58 size=field.size,
59 )
60 )
61 elif isinstance(field, _XdrVariableLengthArray):
62 template = get_jinja2_template(environment, "definition", field.template)
63 print(
64 template.render(
65 name=field.name,
66 type=kernel_c_type(field.spec),
67 classifier=field.spec.c_classifier,
68 )
69 )
70 elif isinstance(field, _XdrOptionalData):
71 template = get_jinja2_template(environment, "definition", field.template)
72 print(
73 template.render(
74 name=field.name,
75 type=kernel_c_type(field.spec),
76 classifier=field.spec.c_classifier,
77 )
78 )
79
80
81def emit_struct_definition(environment: Environment, node: _XdrStruct) -> None:
82 """Emit one definition for an XDR struct type"""
83 template = get_jinja2_template(environment, "definition", "open")
84 print(template.render(name=node.name))
85
86 for field in node.fields:
87 emit_struct_member_definition(environment, field)
88
89 template = get_jinja2_template(environment, "definition", "close")
90 print(template.render(name=node.name))
91
92
93def emit_struct_member_decoder(
94 environment: Environment, field: _XdrDeclaration
95) -> None:
96 """Emit a decoder for one field in an XDR struct"""
97 if isinstance(field, _XdrBasic):
98 template = get_jinja2_template(environment, "decoder", field.template)
99 print(
100 template.render(
101 name=field.name,
102 type=field.spec.type_name,
103 classifier=field.spec.c_classifier,
104 )
105 )
106 elif isinstance(field, _XdrFixedLengthOpaque):
107 template = get_jinja2_template(environment, "decoder", field.template)
108 print(
109 template.render(
110 name=field.name,
111 size=field.size,
112 )
113 )
114 elif isinstance(field, _XdrVariableLengthOpaque):
115 template = get_jinja2_template(environment, "decoder", field.template)
116 print(
117 template.render(
118 name=field.name,
119 maxsize=field.maxsize,
120 )
121 )
122 elif isinstance(field, _XdrString):
123 template = get_jinja2_template(environment, "decoder", field.template)
124 print(
125 template.render(
126 name=field.name,
127 maxsize=field.maxsize,
128 )
129 )
130 elif isinstance(field, _XdrFixedLengthArray):
131 template = get_jinja2_template(environment, "decoder", field.template)
132 print(
133 template.render(
134 name=field.name,
135 type=field.spec.type_name,
136 size=field.size,
137 classifier=field.spec.c_classifier,
138 )
139 )
140 elif isinstance(field, _XdrVariableLengthArray):
141 template = get_jinja2_template(environment, "decoder", field.template)
142 print(
143 template.render(
144 name=field.name,
145 type=field.spec.type_name,
146 maxsize=field.maxsize,
147 classifier=field.spec.c_classifier,
148 )
149 )
150 elif isinstance(field, _XdrOptionalData):
151 template = get_jinja2_template(environment, "decoder", field.template)
152 print(
153 template.render(
154 name=field.name,
155 type=field.spec.type_name,
156 classifier=field.spec.c_classifier,
157 )
158 )
159
160
161def emit_struct_decoder(environment: Environment, node: _XdrStruct) -> None:
162 """Emit one decoder function for an XDR struct type"""
163 template = get_jinja2_template(environment, "decoder", "open")
164 print(template.render(name=node.name))
165
166 for field in node.fields:
167 emit_struct_member_decoder(environment, field)
168
169 template = get_jinja2_template(environment, "decoder", "close")
170 print(template.render())
171
172
173def emit_struct_member_encoder(
174 environment: Environment, field: _XdrDeclaration
175) -> None:
176 """Emit an encoder for one field in an XDR struct"""
177 if isinstance(field, _XdrBasic):
178 template = get_jinja2_template(environment, "encoder", field.template)
179 print(
180 template.render(
181 name=field.name,
182 type=field.spec.type_name,
183 )
184 )
185 elif isinstance(field, _XdrFixedLengthOpaque):
186 template = get_jinja2_template(environment, "encoder", field.template)
187 print(
188 template.render(
189 name=field.name,
190 size=field.size,
191 )
192 )
193 elif isinstance(field, _XdrVariableLengthOpaque):
194 template = get_jinja2_template(environment, "encoder", field.template)
195 print(
196 template.render(
197 name=field.name,
198 maxsize=field.maxsize,
199 )
200 )
201 elif isinstance(field, _XdrString):
202 template = get_jinja2_template(environment, "encoder", field.template)
203 print(
204 template.render(
205 name=field.name,
206 maxsize=field.maxsize,
207 )
208 )
209 elif isinstance(field, _XdrFixedLengthArray):
210 template = get_jinja2_template(environment, "encoder", field.template)
211 print(
212 template.render(
213 name=field.name,
214 type=field.spec.type_name,
215 size=field.size,
216 )
217 )
218 elif isinstance(field, _XdrVariableLengthArray):
219 template = get_jinja2_template(environment, "encoder", field.template)
220 print(
221 template.render(
222 name=field.name,
223 type=field.spec.type_name,
224 maxsize=field.maxsize,
225 )
226 )
227 elif isinstance(field, _XdrOptionalData):
228 template = get_jinja2_template(environment, "encoder", field.template)
229 print(
230 template.render(
231 name=field.name,
232 type=field.spec.type_name,
233 classifier=field.spec.c_classifier,
234 )
235 )
236
237
238def emit_struct_encoder(environment: Environment, node: _XdrStruct) -> None:
239 """Emit one encoder function for an XDR struct type"""
240 template = get_jinja2_template(environment, "encoder", "open")
241 print(template.render(name=node.name))
242
243 for field in node.fields:
244 emit_struct_member_encoder(environment, field)
245
246 template = get_jinja2_template(environment, "encoder", "close")
247 print(template.render())
248
249
250def emit_struct_maxsize(environment: Environment, node: _XdrStruct) -> None:
251 """Emit one maxsize macro for an XDR struct type"""
252 macro_name = get_header_name().upper() + "_" + node.name + "_sz"
253 template = get_jinja2_template(environment, "maxsize", "struct")
254 print(
255 template.render(
256 macro=macro_name,
257 width=" + ".join(node.symbolic_width()),
258 )
259 )
260
261
262class XdrStructGenerator(SourceGenerator):
263 """Generate source code for XDR structs"""
264
265 def __init__(self, language: str, peer: str):
266 """Initialize an instance of this class"""
267 self.environment = create_jinja2_environment(language, "struct")
268 self.peer = peer
269
270 def emit_declaration(self, node: _XdrStruct) -> None:
271 """Emit one declaration pair for an XDR struct type"""
272 emit_struct_declaration(self.environment, node)
273
274 def emit_definition(self, node: _XdrStruct) -> None:
275 """Emit one definition for an XDR struct type"""
276 emit_struct_definition(self.environment, node)
277
278 def emit_decoder(self, node: _XdrStruct) -> None:
279 """Emit one decoder function for an XDR struct type"""
280 emit_struct_decoder(self.environment, node)
281
282 def emit_encoder(self, node: _XdrStruct) -> None:
283 """Emit one encoder function for an XDR struct type"""
284 emit_struct_encoder(self.environment, node)
285
286 def emit_maxsize(self, node: _XdrStruct) -> None:
287 """Emit one maxsize macro for an XDR struct type"""
288 emit_struct_maxsize(self.environment, node)