locatemissingdoxygen.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/python
  2. """
  3. This script parses the stderr output of doxygen and looks for undocumented
  4. stuff. By default, it just counts the undocumented things per file. But with
  5. the -A option, it rewrites the files to stick in /*DOCDOC*/ comments
  6. to highlight the undocumented stuff.
  7. """
  8. import os
  9. import re
  10. import shutil
  11. import sys
  12. warning_pattern = re.compile(r'^([^:]+):(\d+): warning: (.*) is not documented')
  13. def readDoxygenOutput(f):
  14. " yields (cfilename, lineno, thingname) "
  15. for line in f:
  16. m = warning_pattern.match(line)
  17. if m:
  18. yield m.groups()
  19. warnings = {}
  20. def buildWarnings():
  21. for fn, lineno, what in list(readDoxygenOutput(sys.stdin)):
  22. warnings.setdefault(fn, []).append( (int(lineno), what) )
  23. def count(fn):
  24. if os.path.abspath(fn) not in warnings:
  25. print "0\t%s"%fn
  26. else:
  27. n = len(warnings[os.path.abspath(fn)])
  28. print "%d\t%s"%(n,fn)
  29. def getIndentation(line):
  30. s = line.lstrip()
  31. return line[:len(line)-len(s)]
  32. def annotate(filename):
  33. if os.path.abspath(filename) not in warnings:
  34. return
  35. with open(filename) as f:
  36. lines = f.readlines()
  37. w = warnings[os.path.abspath(filename)][:]
  38. w.sort()
  39. w.reverse()
  40. for lineno, what in w:
  41. lineno -= 1 # list is 0-indexed.
  42. if 'DOCDOC' in lines[lineno]:
  43. continue
  44. ind = getIndentation(lines[lineno])
  45. lines.insert(lineno, "%s/* DOCDOC %s */\n"%(ind,what))
  46. shutil.copy(filename, filename+".orig")
  47. with open(filename, 'w') as f:
  48. for l in lines:
  49. f.write(l)
  50. if __name__ == '__main__':
  51. if len(sys.argv) == 1:
  52. print "Usage: locatemissingdoxygen.py [-A] filename... <doxygen_log"
  53. sys.exit(1)
  54. buildWarnings()
  55. if sys.argv[1] == '-A':
  56. del sys.argv[1]
  57. func = annotate
  58. else:
  59. func = count
  60. for fname in sys.argv[1:]:
  61. func(fname)