gencov 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #!/usr/bin/env python
  2. #
  3. # Copyright (c) 2011, 2012, Simon Howard
  4. #
  5. # Permission to use, copy, modify, and/or distribute this software
  6. # for any purpose with or without fee is hereby granted, provided
  7. # that the above copyright notice and this permission notice appear
  8. # in all copies.
  9. #
  10. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  14. # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  15. # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  16. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  17. # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. #
  19. from re import match
  20. from os import rename, popen, getcwd, chdir
  21. from os.path import exists, dirname, basename
  22. from os.path import join as path_join
  23. from glob import glob
  24. import sys
  25. def parse_stats(text):
  26. m = match(r"(.*)% of (.*)", text)
  27. pct = m.group(1)
  28. lines = int(m.group(2))
  29. cov_lines = int(float(pct) * lines / 100 + 0.5)
  30. uncov_lines = lines - cov_lines
  31. return (pct + "%", uncov_lines, cov_lines, lines)
  32. def gcov(filename):
  33. # gcov must be run from within the same directory as the source
  34. # file that we are analysing.
  35. old_wd = getcwd()
  36. src_dir = dirname(filename)
  37. chdir(src_dir)
  38. s = popen("gcov %s" % basename(filename))
  39. chdir(old_wd)
  40. # Process output from gcov.
  41. # This may cover multiple files when one .c file includes another.
  42. results = {}
  43. filename = None
  44. # File 'lha_file_header.c'
  45. # Lines executed:88.97% of 136
  46. for line in s:
  47. m = match(r"File '(.*)'", line)
  48. if m:
  49. filename = m.group(1)
  50. m = match(r"Lines executed:(.*)", line)
  51. if m:
  52. full_path = path_join(src_dir, filename)
  53. results[full_path] = parse_stats(m.group(1))
  54. s.close()
  55. return results
  56. def format_output(filename, stats):
  57. print " %-35s%7s%7s%7s%7s" % ((filename, ) + stats)
  58. print
  59. format_output("Filename", ("Percent", "Uncov", "Cov", "Total"))
  60. print " " + ("-" * 65)
  61. for filename in sorted(sys.argv[1:]):
  62. gcno = filename.replace(".c", ".gcno")
  63. gcda = filename.replace(".c", ".gcda")
  64. xgcno = glob(path_join(dirname(gcno), "*-" + basename(gcno)))
  65. xgcda = glob(path_join(dirname(gcda), "*-" + basename(gcda)))
  66. # Must rename eg. liblhasatest_a-foo.gcno to foo.gcno:
  67. if len(xgcno) > 0:
  68. rename(xgcno[0], gcno)
  69. if len(xgcda) > 0:
  70. rename(xgcda[0], gcda)
  71. if not exists(gcno) or not exists(gcda):
  72. continue
  73. # Run gcov and parse output:
  74. results = gcov(filename)
  75. if len(results) > 0:
  76. if filename in results:
  77. format_output(filename, results[filename])
  78. else:
  79. format_output(filename, ("", "", "", ""))
  80. for subfile in sorted(results.keys()):
  81. if subfile.endswith(".h"):
  82. continue
  83. if subfile != filename:
  84. format_output(" -> " + subfile, results[subfile])
  85. print