summaryrefslogtreecommitdiff
path: root/tools/checkcoding.py
blob: 7b001510f15535939ab29c029ae3eb56ca41a1f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python
# Created for KiCad project by Miguel
# Some modifications by Edwin
# GPL2

import subprocess
import os
import difflib


# class for checking and uncrustifying files
# defaults to cpp,cxx,h,hpp and c files
class coding_checker(object):
    file_filter = ["cpp", "cxx", "h", "hpp", "c"]

    # Function to call uncrustify, it returns the re-formated code and
    # any errors
    #

    def uncrustify_file(self, filename=None):
        try:
            args = ("uncrustify", "-c", "uncrustify.cfg", "-f", filename)
            popen = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            popen.wait()
            return [popen.stdout.readlines(), popen.stderr.read()]
        except OSError as e:
            print "System returned : {e}\nCould not run uncrustify. Is it installed?".format(e=e.strerror)
            return [None, None]

    # This function runs bzr, and gets the list of modified files
    def bzr_modified(self):
        modified_files = []
        args = ("bzr", "status")
        try:
            popen = subprocess.Popen(args, stdout=subprocess.PIPE)
            popen.wait()
            output = popen.stdout.readlines()
        except OSError as e:
            print "System returned : {e}\nCould not run bzr. Is it installed?".format(e=e.strerror)
            return None

        in_modifieds = False
        for line in output:
            line = line.rstrip("\r\n")
            if line.endswith(":"):
                in_modifieds = False
            if line.startswith("modified:"):
                in_modifieds = True
                continue
            if line.startswith("added:"):
                in_modifieds = True
                continue

            if in_modifieds:
                modified_files.append(line.lstrip("\t ").rstrip("\t "))

        return modified_files


    def extension(self, filename):
        return os.path.splitext(filename)[1][1:].strip().lower()


    def read_file(self, filename):
        f = open(filename, 'r')
        data = f.readlines()
        f.close()
        return data


    def ask_user(self, filename):
        msg = 'Shall I clean %s ?' % filename
        return raw_input("%s (y/N/E) " % msg).lower()


    def main(self):
        # make list of modified file names
        modified_files = self.bzr_modified()

        if not modified_files:
            print "No modified files\n"
        else:

            for filename in modified_files:
                if self.extension(filename) in self.file_filter:
                    self.compare_and_suggest(filename)

    def compare_and_suggest(self,filename):
        # if it is a 'c' file try to uncrustify
        [uncrustified, errors] = self.uncrustify_file(filename)

        if not (uncrustified and errors):
            print "Program end"
            # problem in uncrustify
            return

        original = self.read_file(filename)

        if len(errors.split("\n")) > 2:
            print "There was a problem processing " + filename + ":" + errors
            return

        if uncrustified == original:
            print filename + " looks perfect!, well done!"
        else:
            print "Suggestions for: " + filename

            diff = difflib.unified_diff(original, uncrustified, filename, filename + ".uncrustified")

            for line in diff:
                print line.rstrip("\r\n")
            print ""
            reply = self.ask_user(filename)

            if reply in ["y", "yes"]:
                f = open(filename, 'w')
                for line in uncrustified:
                    f.write(line)
                f.close()
                print filename + " UPDATED"

            if reply in ["e", "ed", "edit"]:
                os.system("$EDITOR " + filename)

            print ""


if __name__ == '__main__':
    print "This program tries to do 2 things\n" \
          "1) call bzr to find changed files (related to the KiCad project)\n" \
          "2) call uncrustify on the changed files (to make the files comply with coding standards)\n"

    cc = coding_checker()
    cc.main()