check-includes.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #!/usr/bin/env python
  2. import sys
  3. import re
  4. import os
  5. from subprocess import Popen, PIPE
  6. from argparse import ArgumentParser
  7. GENERATED_INCLUDE_RE = re.compile(
  8. r'^\s*#\s*include\s*"([/a-z_0-9.]+\.generated\.h)"(\s+//.*)?$')
  9. def main(argv):
  10. argparser = ArgumentParser()
  11. argparser.add_argument('--generated-includes-dir', action='append',
  12. help='Directory where generated includes are located.')
  13. argparser.add_argument('--file', type=open, help='File to check.')
  14. argparser.add_argument('iwyu_args', nargs='*',
  15. help='IWYU arguments, must go after --.')
  16. args = argparser.parse_args(argv)
  17. with args.file:
  18. iwyu = Popen(['include-what-you-use', '-xc'] + args.iwyu_args + ['/dev/stdin'],
  19. stdin=PIPE, stdout=PIPE, stderr=PIPE)
  20. for line in args.file:
  21. match = GENERATED_INCLUDE_RE.match(line)
  22. if match:
  23. for d in args.generated_includes_dir:
  24. try:
  25. f = open(os.path.join(d, match.group(1)))
  26. except IOError:
  27. continue
  28. else:
  29. with f:
  30. for generated_line in f:
  31. iwyu.stdin.write(generated_line)
  32. break
  33. else:
  34. raise IOError('Failed to find {0}'.format(match.group(1)))
  35. else:
  36. iwyu.stdin.write(line)
  37. iwyu.stdin.close()
  38. out = iwyu.stdout.read()
  39. err = iwyu.stderr.read()
  40. ret = iwyu.wait()
  41. if ret != 2:
  42. print('IWYU failed with exit code {0}:'.format(ret))
  43. print('{0} stdout {0}'.format('=' * ((80 - len(' stdout ')) // 2)))
  44. print(out)
  45. print('{0} stderr {0}'.format('=' * ((80 - len(' stderr ')) // 2)))
  46. print(err)
  47. return 1
  48. return 0
  49. if __name__ == '__main__':
  50. raise SystemExit(main(sys.argv[1:]))