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-formatted 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()
|