273 lines · python
1#!/usr/bin/env python32# ex: set filetype=python:3 4"""Generate code to handle XDR struct types"""5 6from jinja2 import Environment7 8from generators import SourceGenerator, kernel_c_type9from generators import create_jinja2_environment, get_jinja2_template10 11from xdr_ast import _XdrBasic, _XdrVariableLengthString12from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque13from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray14from xdr_ast import _XdrOptionalData, _XdrStruct, _XdrDeclaration15from xdr_ast import public_apis16 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: _XdrDeclaration27) -> 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, _XdrVariableLengthString):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: _XdrDeclaration95) -> 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, _XdrVariableLengthString):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: _XdrDeclaration175) -> 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, _XdrVariableLengthString):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 250class XdrStructGenerator(SourceGenerator):251 """Generate source code for XDR structs"""252 253 def __init__(self, language: str, peer: str):254 """Initialize an instance of this class"""255 self.environment = create_jinja2_environment(language, "struct")256 self.peer = peer257 258 def emit_declaration(self, node: _XdrStruct) -> None:259 """Emit one declaration pair for an XDR struct type"""260 emit_struct_declaration(self.environment, node)261 262 def emit_definition(self, node: _XdrStruct) -> None:263 """Emit one definition for an XDR struct type"""264 emit_struct_definition(self.environment, node)265 266 def emit_decoder(self, node: _XdrStruct) -> None:267 """Emit one decoder function for an XDR struct type"""268 emit_struct_decoder(self.environment, node)269 270 def emit_encoder(self, node: _XdrStruct) -> None:271 """Emit one encoder function for an XDR struct type"""272 emit_struct_encoder(self.environment, node)273