You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

73 rivejä
2.1 KiB

  1. """
  2. Checks that the implementation does not make use of the `char` type.
  3. This is ambiguous; compilers can freely choose `signed` or `unsigned` char.
  4. """
  5. import pqclean
  6. import pycparser
  7. import os
  8. import helpers
  9. def test_char():
  10. if not(os.path.exists(os.path.join('pycparser', '.git'))):
  11. helpers.run_subprocess(
  12. ['git', 'submodule', 'update', '--init']
  13. )
  14. for scheme in pqclean.Scheme.all_schemes():
  15. for implementation in scheme.implementations:
  16. yield check_char, implementation
  17. def walk_tree(ast):
  18. if type(ast) is pycparser.c_ast.IdentifierType:
  19. if ast.names == ['char']:
  20. yield ast
  21. for (_, child) in ast.children():
  22. yield from walk_tree(child) # recursively yield prohibited nodes
  23. @helpers.filtered_test
  24. @helpers.skip_windows()
  25. def check_char(implementation):
  26. errors = []
  27. for fname in os.listdir(implementation.path()):
  28. if not fname.endswith(".c"):
  29. continue
  30. tdir, _ = os.path.split(os.path.realpath(__file__))
  31. ast = pycparser.parse_file(
  32. os.path.join(implementation.path(), fname),
  33. use_cpp=True,
  34. cpp_path='cc', # not all platforms link cpp correctly; cc -E works
  35. cpp_args=[
  36. '-E',
  37. '-std=c99',
  38. '-nostdinc', # pycparser cannot deal with e.g. __attribute__
  39. '-I{}'.format(os.path.join(tdir, "../common")),
  40. # necessary to mock e.g. <stdint.h>
  41. '-I{}'.format(
  42. os.path.join(tdir, 'pycparser/utils/fake_libc_include')),
  43. ]
  44. )
  45. for node in walk_tree(ast):
  46. # flatten nodes to a string to easily enforce uniqueness
  47. err = "\n at {c.file}:{c.line}:{c.column}".format(c=node.coord)
  48. if err not in errors:
  49. errors.append(err)
  50. if errors:
  51. raise AssertionError(
  52. "Prohibited use of char without explicit signed/unsigned" +
  53. "".join(errors)
  54. )
  55. if __name__ == '__main__':
  56. try:
  57. import nose2
  58. nose2.main()
  59. except ImportError:
  60. import nose
  61. nose.runmodule()