sourcefix.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/usr/bin/python
  2. #
  3. # Copyright 2010, 2011 wkhtmltopdf authors
  4. #
  5. # This file is part of wkhtmltopdf.
  6. #
  7. # wkhtmltopdf is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Lesser General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # wkhtmltopdf is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Lesser General Public License
  18. # along with wkhtmltopdf. If not, see <http:#www.gnu.org/licenses/>.
  19. from sys import argv, exit
  20. import re
  21. from datetime import date
  22. import os
  23. import difflib
  24. cdate = re.compile(r"Copyright ([0-9 ,]*) wkhtmltopdf authors")
  25. ifdef = re.compile(r"^[\n\r \t]*#ifndef __(.*)__[\t ]*\n#define __(\1)__[\t ]*\n")
  26. endif = re.compile(r"#endif.*[\r\n \t]*$")
  27. ws = re.compile(r"[ \t]*[\r\n]")
  28. branchspace = re.compile(r"([ \t\r\n])(for|if|while|switch|foreach)[\t \r\n]*\(")
  29. hangelse = re.compile(r"}[\r\n\t ]*(else)")
  30. braceup = re.compile(r"(\)|else)[\r\n\t ]*{")
  31. include = re.compile(r"(#include (\"[^\"]*\"|<[^>]*>)\n)+")
  32. def includesort(x):
  33. return "\n".join(sorted(x.group(0)[:-1].split("\n"))+[""])
  34. changes=False
  35. progname="wkhtmltopdf"
  36. for path in argv[1:]:
  37. if path.split("/")[0] == "include": continue
  38. try:
  39. data = file(path).read()
  40. except:
  41. continue
  42. mo = cdate.search(data)
  43. years = set(mo.group(1).split(", ")) if mo else set()
  44. years.add(str(date.today().year))
  45. ext = path.rsplit(".",2)[-1]
  46. header = ""
  47. cc = "//"
  48. if ext in ["hh","h","c","cc","cpp","inl", "inc"]:
  49. header += """// -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
  50. // vi:set ts=4 sts=4 sw=4 noet :
  51. //
  52. """
  53. elif ext in ["sh"]:
  54. header += "#!/bin/bash\n#\n"
  55. cc = "#"
  56. elif ext in ["py"]:
  57. header += "#!/usr/bin/python\n#\n"
  58. cc = "#"
  59. elif ext in ["pro","pri"]:
  60. cc = "#"
  61. else:
  62. continue
  63. header += """// Copyright %(years)s %(name)s authors
  64. //
  65. // This file is part of %(name)s.
  66. //
  67. // %(name)s is free software: you can redistribute it and/or modify
  68. // it under the terms of the GNU Lesser General Public License as published by
  69. // the Free Software Foundation, either version 3 of the License, or
  70. // (at your option) any later version.
  71. //
  72. // %(name)s is distributed in the hope that it will be useful,
  73. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  74. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  75. // GNU General Public License for more details.
  76. //
  77. // You should have received a copy of the GNU Lesser General Public License
  78. // along with %(name)s. If not, see <http://www.gnu.org/licenses/>.
  79. """%{"years": (", ".join(sorted(list(years)))),"name":progname}
  80. if ext in ["c", "h", "inc"]:
  81. header = "/*" + header[2:-1] + " */\n\n"
  82. cc = " *"
  83. hexp = re.compile(r"^/\*([^*]*(\*[^/]))*[^*]*\*/[ \t\n]*");
  84. else:
  85. #Strip away generated header
  86. hexp = re.compile("^(%s[^\\n]*\\n)*"%(cc))
  87. ndata = hexp.sub("", data,1)
  88. ndata = ws.sub("\n", ndata)+"\n"
  89. if ext in ["hh","h","inl"]:
  90. s=0
  91. e=-1
  92. while ndata[s] in ['\r','\n',' ','\t']: s+=1
  93. while ndata[e] in ['\r','\n',' ','\t']: e-=1
  94. #Strip away generated ifdef
  95. if ifdef.search(ndata):
  96. ndata = endif.sub("",ifdef.sub("",ndata,1),1)
  97. s=0
  98. e=-1
  99. while ndata[s] in ['\r','\n',' ','\t']: s+=1
  100. while ndata[e] in ['\r','\n',' ','\t']: e-=1
  101. ndata=ndata[s:e+1].replace(" ",'\t')
  102. if ext in ["hh","h","c","cc","cpp","inl"]:
  103. ndata = branchspace.sub(r"\1\2 (",ndata)
  104. ndata = hangelse.sub("} else",ndata)
  105. ndata = braceup.sub(r"\1 {",ndata)
  106. ndata = include.sub(includesort, ndata)
  107. if ext in ["hh","h","inl"]:
  108. n = os.path.split(path)[-1].replace(".","_").replace(" ","_").upper()
  109. ndata = """#ifndef __%s__
  110. #define __%s__
  111. %s
  112. #endif %s__%s__%s"""%(n,n,ndata, "//" if ext != "h" else "/*", n, "" if ext != "h" else "*/")
  113. ndata = header.replace("//",cc)+ndata+"\n"
  114. if ndata != data:
  115. for x in difflib.unified_diff(data.split("\n"),ndata.split("\n"), "a/"+path, "b/"+path):
  116. print x
  117. changes=True
  118. file(path, "w").write(ndata)
  119. if changes: exit(1)