test.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env python2
  2. import re
  3. import sys
  4. import subprocess
  5. import os
  6. def generate(test):
  7. with open("scripts/template.fmt") as file:
  8. template = file.read()
  9. haslines = 'TEST_LINE' in os.environ and 'TEST_FILE' in os.environ
  10. lines = []
  11. for offset, line in enumerate(
  12. re.split('(?<=(?:.;| [{}]))\n', test.read())):
  13. match = re.match('((?: *\n)*)( *)(.*)=>(.*);',
  14. line, re.DOTALL | re.MULTILINE)
  15. if match:
  16. preface, tab, test, expect = match.groups()
  17. lines.extend(['']*preface.count('\n'))
  18. lines.append(tab+'test_assert({test}, {expect});'.format(
  19. test=test.strip(), expect=expect.strip()))
  20. else:
  21. lines.append(line)
  22. # Create test file
  23. with open('test.c', 'w') as file:
  24. if 'TEST_LINE' in os.environ and 'TEST_FILE' in os.environ:
  25. lines.insert(0, '#line %d "%s"' % (
  26. int(os.environ['TEST_LINE']) + 1,
  27. os.environ['TEST_FILE']))
  28. lines.append('#line %d "test.c"' % (
  29. template[:template.find('{tests}')].count('\n')
  30. + len(lines) + 2))
  31. file.write(template.format(tests='\n'.join(lines)))
  32. # Remove build artifacts to force rebuild
  33. try:
  34. os.remove('test.o')
  35. os.remove('lfs')
  36. except OSError:
  37. pass
  38. def compile():
  39. subprocess.check_call([
  40. os.environ.get('MAKE', 'make'),
  41. '--no-print-directory', '-s'])
  42. def execute():
  43. if 'EXEC' in os.environ:
  44. subprocess.check_call([os.environ['EXEC'], "./lfs"])
  45. else:
  46. subprocess.check_call(["./lfs"])
  47. def main(test=None):
  48. try:
  49. if test and not test.startswith('-'):
  50. with open(test) as file:
  51. generate(file)
  52. else:
  53. generate(sys.stdin)
  54. compile()
  55. if test == '-s':
  56. sys.exit(1)
  57. execute()
  58. except subprocess.CalledProcessError:
  59. # Python stack trace is counterproductive, just exit
  60. sys.exit(2)
  61. except KeyboardInterrupt:
  62. # Python stack trace is counterproductive, just exit
  63. sys.exit(3)
  64. if __name__ == "__main__":
  65. main(*sys.argv[1:])