You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.0 KiB

  1. #!/usr/bin/env python
  2. # Created for KiCad project by Miguel
  3. # Some modifications by Edwin
  4. # GPL2
  5. import subprocess
  6. import os
  7. import difflib
  8. # class for checking and uncrustifying files
  9. # defaults to cpp,cxx,h,hpp and c files
  10. class coding_checker(object):
  11. file_filter = ["cpp", "cxx", "h", "hpp", "c"]
  12. # Function to call uncrustify, it returns the re-formatted code and
  13. # any errors
  14. #
  15. def uncrustify_file(self, filename=None):
  16. try:
  17. args = ("uncrustify", "-c", "uncrustify.cfg", "-f", filename)
  18. popen = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  19. popen.wait()
  20. return [popen.stdout.readlines(), popen.stderr.read()]
  21. except OSError as e:
  22. print "System returned : {e}\nCould not run uncrustify. Is it installed?".format(e=e.strerror)
  23. return [None, None]
  24. # This function runs bzr, and gets the list of modified files
  25. def bzr_modified(self):
  26. modified_files = []
  27. args = ("bzr", "status")
  28. try:
  29. popen = subprocess.Popen(args, stdout=subprocess.PIPE)
  30. popen.wait()
  31. output = popen.stdout.readlines()
  32. except OSError as e:
  33. print "System returned : {e}\nCould not run bzr. Is it installed?".format(e=e.strerror)
  34. return None
  35. in_modifieds = False
  36. for line in output:
  37. line = line.rstrip("\r\n")
  38. if line.endswith(":"):
  39. in_modifieds = False
  40. if line.startswith("modified:"):
  41. in_modifieds = True
  42. continue
  43. if line.startswith("added:"):
  44. in_modifieds = True
  45. continue
  46. if in_modifieds:
  47. modified_files.append(line.lstrip("\t ").rstrip("\t "))
  48. return modified_files
  49. def extension(self, filename):
  50. return os.path.splitext(filename)[1][1:].strip().lower()
  51. def read_file(self, filename):
  52. f = open(filename, 'r')
  53. data = f.readlines()
  54. f.close()
  55. return data
  56. def ask_user(self, filename):
  57. msg = 'Shall I clean %s ?' % filename
  58. return raw_input("%s (y/N/E) " % msg).lower()
  59. def main(self):
  60. # make list of modified file names
  61. modified_files = self.bzr_modified()
  62. if not modified_files:
  63. print "No modified files\n"
  64. else:
  65. for filename in modified_files:
  66. if self.extension(filename) in self.file_filter:
  67. self.compare_and_suggest(filename)
  68. def compare_and_suggest(self,filename):
  69. # if it is a 'c' file try to uncrustify
  70. [uncrustified, errors] = self.uncrustify_file(filename)
  71. if not (uncrustified and errors):
  72. print "Program end"
  73. # problem in uncrustify
  74. return
  75. original = self.read_file(filename)
  76. if len(errors.split("\n")) > 2:
  77. print "There was a problem processing " + filename + ":" + errors
  78. return
  79. if uncrustified == original:
  80. print filename + " looks perfect!, well done!"
  81. else:
  82. print "Suggestions for: " + filename
  83. diff = difflib.unified_diff(original, uncrustified, filename, filename + ".uncrustified")
  84. for line in diff:
  85. print line.rstrip("\r\n")
  86. print ""
  87. reply = self.ask_user(filename)
  88. if reply in ["y", "yes"]:
  89. f = open(filename, 'w')
  90. for line in uncrustified:
  91. f.write(line)
  92. f.close()
  93. print filename + " UPDATED"
  94. if reply in ["e", "ed", "edit"]:
  95. os.system("$EDITOR " + filename)
  96. print ""
  97. if __name__ == '__main__':
  98. print "This program tries to do 2 things\n" \
  99. "1) call bzr to find changed files (related to the KiCad project)\n" \
  100. "2) call uncrustify on the changed files (to make the files comply with coding standards)\n"
  101. cc = coding_checker()
  102. cc.main()