• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2
3# 2017, Georg Sauthoff <mail@gms.tf>, GPLv3
4
5import sys
6
7def skip_comments(lines):
8  state = 0
9  for line in lines:
10    n = len(line)
11    l = ''
12    p = 0
13    while p < n:
14      if state == 0:
15        a = line.find('//', p)
16        b = line.find('/*', p)
17        if a > -1 and (a < b or b == -1):
18          l += line[p:a]
19          p = n
20        elif b > -1 and (b < a or a == -1):
21          l += line[p:b]
22          p = b+2
23          state = 1
24        else:
25          l += line[p:]
26          p = n
27      elif state == 1:
28        a = line.rfind('*/', p)
29        if a == -1:
30          p = n
31        else:
32          p = a + 2
33          state = 0
34    yield l
35
36def cond_lines(lines):
37  state = 0
38  pcnt = 0
39  for nr, line in enumerate(lines, 1):
40    if not line:
41      continue
42    n = len(line)
43    p = 0
44    do_yield = False
45    while p < n:
46      if state == 0:
47        p = line.find('if', p)
48        if p == -1:
49          p = n
50          continue
51        if (p == 0 or not line[p-1].isalpha()) \
52            and (p+2 == len(line) or not line[p+2].isalpha()):
53          do_yield = True
54          state = 1
55        p += 2
56      elif state == 1:
57        do_yield = True
58        p = line.find('(', p)
59        if p == -1:
60          p = n
61        else:
62          p += 1
63          state = 2
64          pcnt = 1
65      elif state == 2:
66        do_yield = True
67        for p in range(p, n):
68          if line[p] == '(':
69            pcnt += 1
70          elif line[p] == ')':
71            pcnt -= 1
72          if not pcnt:
73            state = 0
74            break
75        p += 1
76    if do_yield:
77      yield nr
78
79def cond_lines_from_file(filename):
80  with open(filename) as f:
81    yield from cond_lines(skip_comments(f))
82
83def filter_lcov_trace(lines):
84  nrs = set()
85  for line in lines:
86    if line.startswith('SF:'):
87      nrs = set(cond_lines_from_file(line[3:-1]))
88    elif line.startswith('BRDA:'):
89      xs = line[5:].split(',')
90      nr = int(xs[0]) if xs else 0
91      if nr not in nrs:
92        continue
93    yield line
94
95def filter_lcov_trace_file(s_filename, d_file):
96  with open(s_filename) as f:
97    for l in filter_lcov_trace(f):
98      print(l, end='', file=d_file)
99
100if __name__ == '__main__':
101  #for l in cond_lines_from_file(sys.argv[1]):
102  #  print(l)
103
104  filter_lcov_trace_file(sys.argv[1], sys.stdout)
105
106  #with open(sys.argv[1]) as f:
107  #  for l in skip_comments(f):
108  #    print(l)
109
110