pointer.py 10 KB

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