aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts/HeaderCheck.py
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2020-06-04 09:58:12 +1000
committerNeil <nyamatongwe@gmail.com>2020-06-04 09:58:12 +1000
commiteadb190f1bb1303dffcfcb1e8d5305a2c1e2ef60 (patch)
treef824e208a6ab574a702f5508129e453100f353e5 /scripts/HeaderCheck.py
parentd370d281e31fd2d3ea6ef383a98253d1a530bc0a (diff)
downloadscintilla-mirror-eadb190f1bb1303dffcfcb1e8d5305a2c1e2ef60.tar.gz
Use pathlib.
Read files as cp437 so all bytes are valid and windows-1252 invalid characters do not fail. When new headers found, save reasonable order of headers to "NewOrder.txt" making it easier to update HeaderOrder.txt. When a file is out-of-order, save list of headers used in the same order as HeaderOrder.txt to "<path>.ordered".
Diffstat (limited to 'scripts/HeaderCheck.py')
-rw-r--r--scripts/HeaderCheck.py92
1 files changed, 64 insertions, 28 deletions
diff --git a/scripts/HeaderCheck.py b/scripts/HeaderCheck.py
index 058832e31..29dc4fba3 100644
--- a/scripts/HeaderCheck.py
+++ b/scripts/HeaderCheck.py
@@ -3,7 +3,7 @@
# Canonical header order is defined in scripts/HeaderOrder.txt
# Requires Python 3.6 or later
-import codecs, glob, os
+import pathlib
patterns = [
"include/*.h",
@@ -20,65 +20,101 @@ patterns = [
]
def IsHeader(x):
- return x.strip().startswith("#") and ("include" in x or "import" in x)
+ return x.strip().startswith("#") and \
+ ("include" in x or "import" in x) and \
+ "dllimport" not in x
def HeaderFromIncludeLine(s):
#\s*#\s*(include|import)\s+\S+\s*
return s.strip()[1:].strip()[7:].strip()
def ExtractHeaders(filename):
- with codecs.open(filename, "r", "windows-1252") as infile:
+ with filename.open(encoding="cp437") as infile:
return [HeaderFromIncludeLine(l) for l in infile if IsHeader(l)]
+def ExcludeName(name):
+ # LexCaml adds system headers in #if to be an external lexer
+ # moc_ files are generated by Qt and follow its rules
+ return "LexCaml" in name or "moc_" in name
+
+def SortLike(incs, order):
+ return sorted(incs, key = lambda i: order.index(i))
+
def CheckFiles(root):
# Find all the lexer source code files
filePaths = []
for p in patterns:
- filePaths += glob.glob(os.path.join(root, p))
+ filePaths += root.glob(p)
# The Qt platform code interleaves system and Scintilla headers
- #~ filePaths += glob.glob(root + "/qt/ScintillaEditBase/*.cpp")
- #~ filePaths += glob.glob(root + "/qt/ScintillaEdit/*.cpp")
+ #~ filePaths += root.glob("qt/ScintillaEditBase/*.cpp")
+ #~ filePaths += root.glob("qt/ScintillaEdit/*.cpp")
#~ print(filePaths)
- masterHeaderList = ExtractHeaders(os.path.join(root, "scripts/HeaderOrder.txt"))
- orderedPaths = sorted(filePaths, key=str.casefold)
+ scriptDirectory = root / "scripts"
+ headerOrderFile = scriptDirectory / "HeaderOrder.txt"
+ headerOrder = ExtractHeaders(headerOrderFile)
+ originalOrder = headerOrder[:]
+ orderedPaths = [p for p in sorted(filePaths) if not ExcludeName(str(p))]
allIncs = set()
for f in orderedPaths:
- if "LexCaml" in f: # LexCaml adds system headers in #if to be an external lexer
- continue
- print(" File ", f)
+ print(" File ", f.relative_to(root))
incs = ExtractHeaders(f)
#~ print("\n".join(incs))
- news = set(incs) - set(masterHeaderList)
+ news = set(incs) - set(headerOrder)
allIncs = allIncs.union(set(incs))
+
m = 0
i = 0
+ # Detect headers not in header order list and insert at OK position
+ needs = []
while i < len(incs):
- if m == len(masterHeaderList):
- print("**** extend", incs[i:])
- masterHeaderList.extend(incs[i:])
+ if m == len(headerOrder):
+ #~ print("**** extend", incs[i:])
+ headerOrder.extend(incs[i:])
+ needs.extend(incs[i:])
break
- if masterHeaderList[m] == incs[i]:
- #~ print("equal", masterHeaderList[m])
+ if headerOrder[m] == incs[i]:
+ #~ print("equal", headerOrder[m])
i += 1
m += 1
else:
- if masterHeaderList[m] not in incs:
- #~ print("skip", masterHeaderList[m])
+ if headerOrder[m] not in incs:
+ #~ print("skip", headerOrder[m])
m += 1
- elif incs[i] not in masterHeaderList:
- print(f + ":1: Add master", incs[i])
- masterHeaderList.insert(m, incs[i])
+ elif incs[i] not in headerOrder:
+ #~ print(str(f) + ":1: Add master", incs[i])
+ headerOrder.insert(m, incs[i])
+ needs.append(incs[i])
i += 1
m += 1
else:
- print(f + ":1: Header out of order", incs[i], masterHeaderList[m])
- print("incs", " ".join(incs))
i += 1
- #~ return
- #print("Master header list", " ".join(masterHeaderList))
- unused = sorted(set(masterHeaderList) - allIncs)
+ if needs:
+ print(f"{f}:1: needs these headers:")
+ for header in needs:
+ print("#include " + header)
+
+ # Detect out of order
+ ordered = SortLike(incs, headerOrder)
+ if incs != ordered:
+ print(f"{f}:1: is out of order")
+ fOrdered = pathlib.Path(str(f) + ".ordered")
+ with fOrdered.open("w") as headerOut:
+ for header in ordered:
+ headerOut.write("#include " + header + "\n")
+ print(f"{fOrdered}:1: is ordered")
+
+ if headerOrder != originalOrder:
+ newIncludes = set(headerOrder) - set(originalOrder)
+ headerOrderNew = scriptDirectory / "NewOrder.txt"
+ print(f"{headerOrderFile}:1: changed to {headerOrderNew}")
+ print(f" Added {', '.join(newIncludes)}.")
+ with headerOrderNew.open("w") as headerOut:
+ for header in headerOrder:
+ headerOut.write("#include " + header + "\n")
+
+ unused = sorted(set(headerOrder) - allIncs)
if unused:
print("In HeaderOrder.txt but not used")
print("\n".join(unused))
-CheckFiles("..")
+CheckFiles(pathlib.Path(__file__).resolve().parent.parent)