declarations.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #!/usr/bin/env python3
  2. # ex: set filetype=python:
  3. """Translate an XDR specification into executable code that
  4. can be compiled for the Linux kernel."""
  5. import logging
  6. from argparse import Namespace
  7. from lark import logger
  8. from lark.exceptions import VisitError
  9. from generators.enum import XdrEnumGenerator
  10. from generators.header_bottom import XdrHeaderBottomGenerator
  11. from generators.header_top import XdrHeaderTopGenerator
  12. from generators.pointer import XdrPointerGenerator
  13. from generators.program import XdrProgramGenerator
  14. from generators.typedef import XdrTypedefGenerator
  15. from generators.struct import XdrStructGenerator
  16. from generators.union import XdrUnionGenerator
  17. from xdr_ast import transform_parse_tree, _RpcProgram, Specification
  18. from xdr_ast import _XdrEnum, _XdrPointer, _XdrTypedef, _XdrStruct, _XdrUnion
  19. from xdr_parse import xdr_parser, set_xdr_annotate
  20. from xdr_parse import make_error_handler, XdrParseError
  21. from xdr_parse import handle_transform_error
  22. logger.setLevel(logging.INFO)
  23. def emit_header_declarations(
  24. root: Specification, language: str, peer: str
  25. ) -> None:
  26. """Emit header declarations"""
  27. for definition in root.definitions:
  28. if isinstance(definition.value, _XdrEnum):
  29. gen = XdrEnumGenerator(language, peer)
  30. elif isinstance(definition.value, _XdrPointer):
  31. gen = XdrPointerGenerator(language, peer)
  32. elif isinstance(definition.value, _XdrTypedef):
  33. gen = XdrTypedefGenerator(language, peer)
  34. elif isinstance(definition.value, _XdrStruct):
  35. gen = XdrStructGenerator(language, peer)
  36. elif isinstance(definition.value, _XdrUnion):
  37. gen = XdrUnionGenerator(language, peer)
  38. elif isinstance(definition.value, _RpcProgram):
  39. gen = XdrProgramGenerator(language, peer)
  40. else:
  41. continue
  42. gen.emit_declaration(definition.value)
  43. def subcmd(args: Namespace) -> int:
  44. """Generate definitions and declarations"""
  45. set_xdr_annotate(args.annotate)
  46. parser = xdr_parser()
  47. with open(args.filename, encoding="utf-8") as f:
  48. source = f.read()
  49. try:
  50. parse_tree = parser.parse(
  51. source, on_error=make_error_handler(source, args.filename)
  52. )
  53. except XdrParseError:
  54. return 1
  55. try:
  56. ast = transform_parse_tree(parse_tree)
  57. except VisitError as e:
  58. handle_transform_error(e, source, args.filename)
  59. return 1
  60. gen = XdrHeaderTopGenerator(args.language, args.peer)
  61. gen.emit_declaration(args.filename, ast)
  62. emit_header_declarations(ast, args.language, args.peer)
  63. gen = XdrHeaderBottomGenerator(args.language, args.peer)
  64. gen.emit_declaration(args.filename, ast)
  65. return 0