1# Future imports for Python 2.7, mandatory in 3.0
2from __future__ import division
3from __future__ import print_function
4from __future__ import unicode_literals
5
6import os
7
8# We don't want to run metrics for unittests, automatically-generated C files,
9# external libraries or git leftovers.
10EXCLUDE_SOURCE_DIRS = {"src/test/", "src/trunnel/", "src/rust/",
11                       "src/ext/" }
12
13EXCLUDE_FILES = {"orconfig.h"}
14
15def _norm(p):
16    return os.path.normcase(os.path.normpath(p))
17
18def get_tor_c_files(tor_topdir, include_dirs=None):
19    """
20    Return a list with the .c and .h filenames we want to get metrics of.
21    """
22    files_list = []
23    exclude_dirs = { _norm(os.path.join(tor_topdir, p)) for p in EXCLUDE_SOURCE_DIRS }
24
25    if include_dirs is None:
26        topdirs = [ tor_topdir ]
27    else:
28        topdirs = [ os.path.join(tor_topdir, inc) for inc in include_dirs ]
29
30    for topdir in topdirs:
31        for root, directories, filenames in os.walk(topdir):
32            # Remove all the directories that are excluded.
33            directories[:] = [ d for d in directories
34                               if _norm(os.path.join(root,d)) not in exclude_dirs ]
35            directories.sort()
36            filenames.sort()
37            for filename in filenames:
38                # We only care about .c and .h files
39                if not (filename.endswith(".c") or filename.endswith(".h")):
40                    continue
41                if filename in EXCLUDE_FILES:
42                    continue
43                # Avoid editor temporary files
44                bname = os.path.basename(filename)
45                if bname.startswith("."):
46                    continue
47                if bname.startswith("#"):
48                    continue
49
50                full_path = os.path.join(root,filename)
51
52                files_list.append(full_path)
53
54    return files_list
55
56class NullFile:
57    """A file-like object that we can us to suppress output."""
58    def __init__(self):
59        pass
60    def write(self, s):
61        pass
62