__init__.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # -----------------------------------------------------------------
  2. # pycparser: __init__.py
  3. #
  4. # This package file exports some convenience functions for
  5. # interacting with pycparser
  6. #
  7. # Eli Bendersky [https://eli.thegreenplace.net/]
  8. # License: BSD
  9. # -----------------------------------------------------------------
  10. __all__ = ["c_lexer", "c_parser", "c_ast"]
  11. __version__ = "3.00"
  12. import io
  13. from subprocess import check_output
  14. from . import c_parser
  15. CParser = c_parser.CParser
  16. def preprocess_file(filename, cpp_path="cpp", cpp_args=""):
  17. """Preprocess a file using cpp.
  18. filename:
  19. Name of the file you want to preprocess.
  20. cpp_path:
  21. cpp_args:
  22. Refer to the documentation of parse_file for the meaning of these
  23. arguments.
  24. When successful, returns the preprocessed file's contents.
  25. Errors from cpp will be printed out.
  26. """
  27. path_list = [cpp_path]
  28. if isinstance(cpp_args, list):
  29. path_list += cpp_args
  30. elif cpp_args != "":
  31. path_list += [cpp_args]
  32. path_list += [filename]
  33. try:
  34. # Note the use of universal_newlines to treat all newlines
  35. # as \n for Python's purpose
  36. text = check_output(path_list, universal_newlines=True)
  37. except OSError as e:
  38. raise RuntimeError(
  39. "Unable to invoke 'cpp'. "
  40. + "Make sure its path was passed correctly\n"
  41. + f"Original error: {e}"
  42. )
  43. return text
  44. def parse_file(
  45. filename, use_cpp=False, cpp_path="cpp", cpp_args="", parser=None, encoding=None
  46. ):
  47. """Parse a C file using pycparser.
  48. filename:
  49. Name of the file you want to parse.
  50. use_cpp:
  51. Set to True if you want to execute the C pre-processor
  52. on the file prior to parsing it.
  53. cpp_path:
  54. If use_cpp is True, this is the path to 'cpp' on your
  55. system. If no path is provided, it attempts to just
  56. execute 'cpp', so it must be in your PATH.
  57. cpp_args:
  58. If use_cpp is True, set this to the command line arguments strings
  59. to cpp. Be careful with quotes - it's best to pass a raw string
  60. (r'') here. For example:
  61. r'-I../utils/fake_libc_include'
  62. If several arguments are required, pass a list of strings.
  63. encoding:
  64. Encoding to use for the file to parse
  65. parser:
  66. Optional parser object to be used instead of the default CParser
  67. When successful, an AST is returned. ParseError can be
  68. thrown if the file doesn't parse successfully.
  69. Errors from cpp will be printed out.
  70. """
  71. if use_cpp:
  72. text = preprocess_file(filename, cpp_path, cpp_args)
  73. else:
  74. with io.open(filename, encoding=encoding) as f:
  75. text = f.read()
  76. if parser is None:
  77. parser = CParser()
  78. return parser.parse(text, filename)