Merge branch 'maint-0.4.8'
[tor.git] / scripts / maint / practracker / metrics.py
blob300a4501a95d770bec74df18cb4009c6ebdea95f
1 #!/usr/bin/env python
3 # Implementation of various source code metrics.
4 # These are currently ad-hoc string operations and regexps.
5 # We might want to use a proper static analysis library in the future, if we want to get more advanced metrics.
7 # Future imports for Python 2.7, mandatory in 3.0
8 from __future__ import division
9 from __future__ import print_function
10 from __future__ import unicode_literals
12 import re
14 def get_file_len(f):
15 """Get file length of file"""
16 i = -1
17 for i, l in enumerate(f):
18 pass
19 return i + 1
21 def get_include_count(f):
22 """Get number of #include statements in the file"""
23 include_count = 0
24 for line in f:
25 if re.match(r'\s*#\s*include', line):
26 include_count += 1
27 return include_count
29 def get_function_lines(f):
30 """
31 Return iterator which iterates over functions and returns (function name, function lines)
32 """
34 # Skip lines that look like they are defining functions with these
35 # names: they aren't real function definitions.
36 REGEXP_CONFUSE_TERMS = {"MOCK_IMPL", "MOCK_DECL", "HANDLE_DECL",
37 "ENABLE_GCC_WARNINGS", "ENABLE_GCC_WARNING",
38 "DUMMY_TYPECHECK_INSTANCE",
39 "DISABLE_GCC_WARNING", "DISABLE_GCC_WARNINGS"}
41 in_function = False
42 found_openbrace = False
43 for lineno, line in enumerate(f):
44 if not in_function:
45 # find the start of a function
46 m = re.match(r'^([a-zA-Z_][a-zA-Z_0-9]*),?\(', line)
47 if m:
48 func_name = m.group(1)
49 if func_name in REGEXP_CONFUSE_TERMS:
50 continue
51 func_start = lineno
52 in_function = True
53 elif not found_openbrace and line.startswith("{"):
54 found_openbrace = True
55 func_start = lineno
56 else:
57 # Find the end of a function
58 if line.startswith("}"):
59 n_lines = lineno - func_start + 1
60 in_function = False
61 found_openbrace = False
62 yield (func_name, n_lines)