1#!/usr/bin/env python3 2# ex: set filetype=python: 3 4"""Generate code to handle XDR typedefs""" 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, _XdrTypedef, _XdrVariableLengthString 12from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque 13from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray 14from xdr_ast import _XdrOptionalData, _XdrVoid, _XdrDeclaration 15from xdr_ast import public_apis 16 17 18def emit_typedef_declaration(environment: Environment, node: _XdrDeclaration) -> None: 19 """Emit a declaration pair for one XDR typedef""" 20 if node.name not in public_apis: 21 return 22 if isinstance(node, _XdrBasic): 23 template = get_jinja2_template(environment, "declaration", node.template) 24 print( 25 template.render( 26 name=node.name, 27 type=kernel_c_type(node.spec), 28 classifier=node.spec.c_classifier, 29 ) 30 ) 31 elif isinstance(node, _XdrVariableLengthString): 32 template = get_jinja2_template(environment, "declaration", node.template) 33 print(template.render(name=node.name)) 34 elif isinstance(node, _XdrFixedLengthOpaque): 35 template = get_jinja2_template(environment, "declaration", node.template) 36 print(template.render(name=node.name, size=node.size)) 37 elif isinstance(node, _XdrVariableLengthOpaque): 38 template = get_jinja2_template(environment, "declaration", node.template) 39 print(template.render(name=node.name)) 40 elif isinstance(node, _XdrFixedLengthArray): 41 template = get_jinja2_template(environment, "declaration", node.template) 42 print( 43 template.render( 44 name=node.name, 45 type=node.spec.type_name, 46 size=node.size, 47 ) 48 ) 49 elif isinstance(node, _XdrVariableLengthArray): 50 template = get_jinja2_template(environment, "declaration", node.template) 51 print( 52 template.render( 53 name=node.name, 54 type=node.spec.type_name, 55 classifier=node.spec.c_classifier, 56 ) 57 ) 58 elif isinstance(node, _XdrOptionalData): 59 raise NotImplementedError("<optional_data> typedef not yet implemented") 60 elif isinstance(node, _XdrVoid): 61 raise NotImplementedError("<void> typedef not yet implemented") 62 else: 63 raise NotImplementedError("typedef: type not recognized") 64 65 66def emit_type_definition(environment: Environment, node: _XdrDeclaration) -> None: 67 """Emit a definition for one XDR typedef""" 68 if isinstance(node, _XdrBasic): 69 template = get_jinja2_template(environment, "definition", node.template) 70 print( 71 template.render( 72 name=node.name, 73 type=kernel_c_type(node.spec), 74 classifier=node.spec.c_classifier, 75 ) 76 ) 77 elif isinstance(node, _XdrVariableLengthString): 78 template = get_jinja2_template(environment, "definition", node.template) 79 print(template.render(name=node.name)) 80 elif isinstance(node, _XdrFixedLengthOpaque): 81 template = get_jinja2_template(environment, "definition", node.template) 82 print(template.render(name=node.name, size=node.size)) 83 elif isinstance(node, _XdrVariableLengthOpaque): 84 template = get_jinja2_template(environment, "definition", node.template) 85 print(template.render(name=node.name)) 86 elif isinstance(node, _XdrFixedLengthArray): 87 template = get_jinja2_template(environment, "definition", node.template) 88 print( 89 template.render( 90 name=node.name, 91 type=node.spec.type_name, 92 size=node.size, 93 ) 94 ) 95 elif isinstance(node, _XdrVariableLengthArray): 96 template = get_jinja2_template(environment, "definition", node.template) 97 print( 98 template.render( 99 name=node.name, 100 type=node.spec.type_name, 101 classifier=node.spec.c_classifier, 102 ) 103 ) 104 elif isinstance(node, _XdrOptionalData): 105 raise NotImplementedError("<optional_data> typedef not yet implemented") 106 elif isinstance(node, _XdrVoid): 107 raise NotImplementedError("<void> typedef not yet implemented") 108 else: 109 raise NotImplementedError("typedef: type not recognized") 110 111 112def emit_typedef_decoder(environment: Environment, node: _XdrDeclaration) -> None: 113 """Emit a decoder function for one XDR typedef""" 114 if isinstance(node, _XdrBasic): 115 template = get_jinja2_template(environment, "decoder", node.template) 116 print( 117 template.render( 118 name=node.name, 119 type=node.spec.type_name, 120 ) 121 ) 122 elif isinstance(node, _XdrVariableLengthString): 123 template = get_jinja2_template(environment, "decoder", node.template) 124 print( 125 template.render( 126 name=node.name, 127 maxsize=node.maxsize, 128 ) 129 ) 130 elif isinstance(node, _XdrFixedLengthOpaque): 131 template = get_jinja2_template(environment, "decoder", node.template) 132 print( 133 template.render( 134 name=node.name, 135 size=node.size, 136 ) 137 ) 138 elif isinstance(node, _XdrVariableLengthOpaque): 139 template = get_jinja2_template(environment, "decoder", node.template) 140 print( 141 template.render( 142 name=node.name, 143 maxsize=node.maxsize, 144 ) 145 ) 146 elif isinstance(node, _XdrFixedLengthArray): 147 template = get_jinja2_template(environment, "decoder", node.template) 148 print( 149 template.render( 150 name=node.name, 151 type=node.spec.type_name, 152 size=node.size, 153 classifier=node.spec.c_classifier, 154 ) 155 ) 156 elif isinstance(node, _XdrVariableLengthArray): 157 template = get_jinja2_template(environment, "decoder", node.template) 158 print( 159 template.render( 160 name=node.name, 161 type=node.spec.type_name, 162 maxsize=node.maxsize, 163 ) 164 ) 165 elif isinstance(node, _XdrOptionalData): 166 raise NotImplementedError("<optional_data> typedef not yet implemented") 167 elif isinstance(node, _XdrVoid): 168 raise NotImplementedError("<void> typedef not yet implemented") 169 else: 170 raise NotImplementedError("typedef: type not recognized") 171 172 173def emit_typedef_encoder(environment: Environment, node: _XdrDeclaration) -> None: 174 """Emit an encoder function for one XDR typedef""" 175 if isinstance(node, _XdrBasic): 176 template = get_jinja2_template(environment, "encoder", node.template) 177 print( 178 template.render( 179 name=node.name, 180 type=node.spec.type_name, 181 ) 182 ) 183 elif isinstance(node, _XdrVariableLengthString): 184 template = get_jinja2_template(environment, "encoder", node.template) 185 print( 186 template.render( 187 name=node.name, 188 maxsize=node.maxsize, 189 ) 190 ) 191 elif isinstance(node, _XdrFixedLengthOpaque): 192 template = get_jinja2_template(environment, "encoder", node.template) 193 print( 194 template.render( 195 name=node.name, 196 size=node.size, 197 ) 198 ) 199 elif isinstance(node, _XdrVariableLengthOpaque): 200 template = get_jinja2_template(environment, "encoder", node.template) 201 print( 202 template.render( 203 name=node.name, 204 maxsize=node.maxsize, 205 ) 206 ) 207 elif isinstance(node, _XdrFixedLengthArray): 208 template = get_jinja2_template(environment, "encoder", node.template) 209 print( 210 template.render( 211 name=node.name, 212 type=node.spec.type_name, 213 size=node.size, 214 ) 215 ) 216 elif isinstance(node, _XdrVariableLengthArray): 217 template = get_jinja2_template(environment, "encoder", node.template) 218 print( 219 template.render( 220 name=node.name, 221 type=node.spec.type_name, 222 maxsize=node.maxsize, 223 ) 224 ) 225 elif isinstance(node, _XdrOptionalData): 226 raise NotImplementedError("<optional_data> typedef not yet implemented") 227 elif isinstance(node, _XdrVoid): 228 raise NotImplementedError("<void> typedef not yet implemented") 229 else: 230 raise NotImplementedError("typedef: type not recognized") 231 232 233class XdrTypedefGenerator(SourceGenerator): 234 """Generate source code for XDR typedefs""" 235 236 def __init__(self, language: str, peer: str): 237 """Initialize an instance of this class""" 238 self.environment = create_jinja2_environment(language, "typedef") 239 self.peer = peer 240 241 def emit_declaration(self, node: _XdrTypedef) -> None: 242 """Emit one declaration pair for an XDR enum type""" 243 emit_typedef_declaration(self.environment, node.declaration) 244 245 def emit_definition(self, node: _XdrTypedef) -> None: 246 """Emit one definition for an XDR typedef""" 247 emit_type_definition(self.environment, node.declaration) 248 249 def emit_decoder(self, node: _XdrTypedef) -> None: 250 """Emit one decoder function for an XDR typedef""" 251 emit_typedef_decoder(self.environment, node.declaration) 252 253 def emit_encoder(self, node: _XdrTypedef) -> None: 254 """Emit one encoder function for an XDR typedef""" 255 emit_typedef_encoder(self.environment, node.declaration) 256