]> git.donarmstrong.com Git - lilypond.git/blobdiff - buildscripts/coverage.py
coverage.py improvements.
[lilypond.git] / buildscripts / coverage.py
index 259f0be06d20c96d70451bc4e18144ff5eb0b6b9..415c7100ff429390152286a161ad3a05c51c3d9f 100644 (file)
 import os
 import glob
 import re
+import sys
+import optparse
 
-cmds = """
-./configure --enable-config=cov --disable-optimising
-make conf=cov -j2
-make conf=cov test LILYPOND_JOBS=          
+#File 'accidental-engraver.cc'
+#Lines executed:87.70% of 252
 
-cd out-cov
-ln ../lily/* .
-ln ../lily/out-conv/*cc .
-mkdir include
-ln ../lily/include/* include/
-for a in *[cyl] ; do  gcov -o ../lily/out-cov/  -p $a > $a.gcov-summary ; done 
-"""
+def summary (args):
+    results = []
+    for f in args:
+        str = open (f).read ()
+        m = re.search ("File '([^']+.cc)'\s*Lines executed:([0-9.]+)% of ([0-9]+)", str)
 
-os.chdir ('out-cov')
+        if m and '/usr/lib' in m.group (1):
+            continue
 
-#File 'accidental-engraver.cc'
-#Lines executed:87.70% of 252
+        if m:
+            cov = float (m.group (2))
+            lines = int (m.group (3))
+            pain = lines * (100.0 - cov)
+            file = m.group (1)
+            tup = (pain, locals ().copy())
+
+            results.append(tup)
+
+    results.sort ()
+    results.reverse()
+
+    print 'files sorted by number of untested lines (decreasing)'
+    print
+    print '%5s (%6s): %s' % ('cov %', 'lines', 'file')
+    print '----------------------------------------------'
+
+    for (pain, d) in results:
+        print '%(cov)5.2f (%(lines)6d): %(file)s' % d
+
+
+
+def read_gcov (f):
+    ls = []
+
+    in_lines = [l for l in open (f).readlines ()]
+    (count_len, line_num_len) = tuple (map (len, in_lines[0].split( ':')[:2]))
+    
+    for l in in_lines:
+        c = l[:count_len].strip ()
+        l = l[count_len+1:]
+        n = int (l[:line_num_len].strip ())
+
+        if n == 0:
+            continue
+        
+        l = l[line_num_len+1:]
 
-results = []
-for f in glob.glob ('*.gcov-summary'):
-    str = open (f).read ()
-    m = re.search ("File '([^']+.cc)'\s*Lines executed:([0-9.]+)% of ([0-9]+)", str)
-    if '/usr/lib' in m.group (1):
-        continue
-   
-    if m:
-        cov = float (m.group (2))
-        lines = int (m.group (3))
-        pain = lines * (100.0 - cov)
-        file = m.group (1)
-        tup = (pain, locals ().copy())
+        ls.append ((c,n,l))
         
-        results.append(tup)
+    return ls
 
-results.sort ()
-results.reverse()
-for (pain, d) in results:
-    print '%(cov)5.2f (%(lines)6d): %(file)s' % d
+def get_chunks (ls):
+    chunks = []
+    chunk = []
+    for (c,n,l) in ls:
+        if '#' in c:
+            chunk.append ((n,l))
+        elif c.strip () != '-' or l == '}\n':
+            if chunk:
+                chunks.append (chunk)
+                chunk = []
+            
+    return chunks
 
+def is_exception_chunk (ch):
+    for (n,l) in ch:
+        for stat in  ('warning', 'error'):
+            if stat in l:
+                return True
+    return False
+
+def widen_chunk (ch, ls):
+    nums = [n-1 for (n, l) in ch]
+    (a, b) = (min (nums), max (nums)+1)
+    a -= 1
+    b += 1
+
+    return [(n, l)  for (c, n, l) in ls[a:b]]
+    
+
+def is_inspection_chunk (ch):
+    for (n,l) in ch:
+        for stat in  ('::print',):
+            if stat in l:
+                return True
+    return False
+
+def print_chunk (ch, lines):
+    nums = [n-1 for (n, l) in ch]
+    (a, b) = (min (nums), max (nums)+1)
+    a -= 1
+    b += 1
+    for (c, n, l) in lines[a:b]:
+        sys.stdout.write ('%8s:%8d:%s' % (c,n,l))
+
+
+def extract_uncovered (file):
+    try:
+        ls = read_gcov (file)
+    except IOError, s :
+        print s
+        return
+        
+    cs = get_chunks (ls)
+    cs = [widen_chunk(c, ls) for c in cs]
+    cs = [c for c in cs if not is_exception_chunk (c)]
+    cs = [c for c in cs if not is_inspection_chunk (c)]
+    for c in cs:
+        print 'Uncovered chunk in', file
+        print_chunk (c, ls)
+        print '\n\n: '
+    
+
+def main ():
+    p = optparse.OptionParser (usage="usage coverage.py [options] files",
+                               description="")
+    p.add_option ("--summary",
+                  action='store_true',
+                  default=False,
+                  dest="summary")
+    
+    p.add_option ("--uncovered",
+                  default=False,
+                  action='store_true',
+                  dest="uncovered")
+
+    
+    (options, args) = p.parse_args ()
+    
+
+    if options.summary:
+        summary (['%s.gcov-summary' % s for s in args])
+
+    if options.uncovered:
+        for a in args:
+            extract_uncovered ('%s.gcov' % a)
+        
+        
+if __name__ == '__main__':
+    main ()