diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/FileGenerator.py | 44 | ||||
-rw-r--r-- | scripts/LexGen.py | 70 | ||||
-rw-r--r-- | scripts/ScintillaData.py | 28 |
3 files changed, 141 insertions, 1 deletions
diff --git a/scripts/FileGenerator.py b/scripts/FileGenerator.py index 11d6d70ba..3d488ef13 100644 --- a/scripts/FileGenerator.py +++ b/scripts/FileGenerator.py @@ -170,6 +170,50 @@ def UpdateLineInFile(path, linePrefix, lineReplace): contents = lineEnd.join(lines) + lineEnd UpdateFile(path, contents) +def ReadFileAsList(path): + """Read all the lnes in the file and return as a list of strings without line ends. + """ + with codecs.open(path, "rU", "utf-8") as f: + return [l.rstrip('\n') for l in f] + +def UpdateFileFromLines(path, lines, lineEndToUse): + """Join the lines with the lineEndToUse then update file if the result is different. + """ + contents = lineEndToUse.join(lines) + lineEndToUse + UpdateFile(path, contents) + +def FindSectionInList(lines, markers): + """Find a section defined by an initial start marker, an optional secondary + marker and an end marker. + The section is between the secondary/initial start and the end. + Report as a slice object so the section can be extracted or replaced. + Raises an exception if the markers can't be found. + """ + start = -1 + end = -1 + state = 0 + for i, l in enumerate(lines): + if markers[0] in l: + if markers[1]: + state = 1 + else: + start = i+1 + state = 2 + elif state == 1: + if markers[1] in l: + start = i+1 + state = 2 + elif state == 2: + if markers[2] in l: + end = i + state = 3 + # Check that section was found + if start == -1: + raise Exception("Could not find start marker(s) |" + markers[0] + "|" + markers[1] + "|") + if end == -1: + raise Exception("Could not find end marker " + markers[2]) + return slice(start, end) + def ReplaceREInFile(path, match, replace): with codecs.open(path, "r", "utf-8") as f: contents = f.read() diff --git a/scripts/LexGen.py b/scripts/LexGen.py index ba179eee0..ae7ae99d5 100644 --- a/scripts/LexGen.py +++ b/scripts/LexGen.py @@ -8,9 +8,12 @@ # Files are regenerated in place with templates stored in comments. # The format of generation comments is documented in FileGenerator.py. -from FileGenerator import Regenerate, UpdateLineInFile, ReplaceREInFile, UpdateLineInPlistFile +from FileGenerator import Regenerate, UpdateLineInFile, \ + ReplaceREInFile, UpdateLineInPlistFile, ReadFileAsList, UpdateFileFromLines, \ + FindSectionInList import ScintillaData import HFacer +import uuid def UpdateVersionNumbers(sci, root): UpdateLineInFile(root + "win32/ScintRes.rc", "#define VERSION_SCINTILLA", @@ -43,6 +46,68 @@ def UpdateVersionNumbers(sci, root): UpdateLineInPlistFile(root + "cocoa/ScintillaFramework/Info.plist", "CFBundleShortVersionString", sci.versionDotted) +# Last 24 digits of UUID, used for item IDs in Xcode +def uid24(): + return str(uuid.uuid4()).replace("-", "").upper()[-24:] + +def ciLexerKey(a): + return a.split()[2].lower() + +""" + 11F35FDB12AEFAF100F0236D /* LexA68k.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */; }; + 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexA68k.cxx; path = ../../lexers/LexA68k.cxx; sourceTree = SOURCE_ROOT; }; + 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */, + 11F35FDB12AEFAF100F0236D /* LexA68k.cxx in Sources */, +""" +def RegenerateXcodeProject(path, lexers, lexerReferences): + # Build 4 blocks for insertion: + # Each markers contains a unique section start, an optional wait string, and a section end + + markersPBXBuildFile = ["Begin PBXBuildFile section", "", "End PBXBuildFile section"] + sectionPBXBuildFile = [] + + markersPBXFileReference = ["Begin PBXFileReference section", "", "End PBXFileReference section"] + sectionPBXFileReference = [] + + markersLexers = ["/* Lexers */ =", "children", ");"] + sectionLexers = [] + + markersPBXSourcesBuildPhase = ["Begin PBXSourcesBuildPhase section", "files", ");"] + sectionPBXSourcesBuildPhase = [] + + for lexer in lexers: + if lexer not in lexerReferences: + uid1 = uid24() + uid2 = uid24() + print("Lexer", lexer, "is not in Xcode project. Use IDs", uid1, uid2) + lexerReferences[lexer] = [uid1, uid2] + linePBXBuildFile = "\t\t{} /* {}.cxx in Sources */ = {{isa = PBXBuildFile; fileRef = {} /* {}.cxx */; }};".format(uid1, lexer, uid2, lexer) + linePBXFileReference = "\t\t{} /* {}.cxx */ = {{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = {}.cxx; path = ../../lexers/{}.cxx; sourceTree = SOURCE_ROOT; }};".format(uid2, lexer, lexer, lexer) + lineLexers = "\t\t\t\t{} /* {}.cxx */,".format(uid2, lexer) + linePBXSourcesBuildPhase = "\t\t\t\t{} /* {}.cxx in Sources */,".format(uid1, lexer) + sectionPBXBuildFile.append(linePBXBuildFile) + sectionPBXFileReference.append(linePBXFileReference) + sectionLexers.append(lineLexers) + sectionPBXSourcesBuildPhase.append(linePBXSourcesBuildPhase) + + lines = ReadFileAsList(path) + + sli = FindSectionInList(lines, markersPBXBuildFile) + lines[sli.stop:sli.stop] = sectionPBXBuildFile + + sli = FindSectionInList(lines, markersPBXFileReference) + lines[sli.stop:sli.stop] = sectionPBXFileReference + + sli = FindSectionInList(lines, markersLexers) + # This section is shown in the project outline so sort it to make it easier to navigate. + allLexers = sorted(lines[sli.start:sli.stop] + sectionLexers, key=ciLexerKey) + lines[sli] = allLexers + + sli = FindSectionInList(lines, markersPBXSourcesBuildPhase) + lines[sli.stop:sli.stop] = sectionPBXSourcesBuildPhase + + UpdateFileFromLines(path, lines, "\n") + def RegenerateAll(root): sci = ScintillaData.ScintillaData(root) @@ -50,6 +115,9 @@ def RegenerateAll(root): Regenerate(root + "src/Catalogue.cxx", "//", sci.lexerModules) Regenerate(root + "win32/scintilla.mak", "#", sci.lexFiles) + RegenerateXcodeProject(root + "cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj", + sci.lexFiles, sci.lexersXcode) + UpdateVersionNumbers(sci, root) HFacer.RegenerateAll(root, False) diff --git a/scripts/ScintillaData.py b/scripts/ScintillaData.py index 7aeee4f62..0ac1eddfa 100644 --- a/scripts/ScintillaData.py +++ b/scripts/ScintillaData.py @@ -57,6 +57,31 @@ def FindModules(lexFile): partLine = partLine + l return modules +def FindLexersInXcode(xCodeProject): + lines = FileGenerator.ReadFileAsList(xCodeProject) + + uidsOfBuild = {} + markersPBXBuildFile = ["Begin PBXBuildFile section", "", "End PBXBuildFile section"] + for buildLine in lines[FileGenerator.FindSectionInList(lines, markersPBXBuildFile)]: + # Occurs for each file in the build. Find the UIDs used for the file. + #\t\t[0-9A-F]+ /* [a-zA-Z]+.cxx in sources */ = {isa = PBXBuildFile; fileRef = [0-9A-F]+ /* [a-zA-Z]+ */; }; + pieces = buildLine.split() + uid1 = pieces[0] + filename = pieces[2].split(".")[0] + uid2 = pieces[12] + uidsOfBuild[filename] = [uid1, uid2] + + lexers = {} + markersLexers = ["/* Lexers */ =", "children", ");"] + for lexerLine in lines[FileGenerator.FindSectionInList(lines, markersLexers)]: + #\t\t\t\t[0-9A-F]+ /* [a-zA-Z]+.cxx */, + uid, _, rest = lexerLine.partition("/* ") + uid = uid.strip() + lexer, _, _ = rest.partition(".") + lexers[lexer] = uidsOfBuild[lexer] + + return lexers + # Properties that start with lexer. or fold. are automatically found but there are some # older properties that don't follow this pattern so must be explicitly listed. knownIrregularProperties = [ @@ -217,6 +242,7 @@ class ScintillaData: self.lexerProperties = list(lexerProperties) SortListInsensitive(self.lexerProperties) + self.lexersXcode = FindLexersInXcode(scintillaRoot + "cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj") self.credits = FindCredits(scintillaRoot + "doc/ScintillaHistory.html") def printWrapped(text): @@ -229,6 +255,8 @@ if __name__=="__main__": sci.dateModified, sci.yearModified, sci.mdyModified, sci.dmyModified, sci.myModified)) printWrapped(str(len(sci.lexFiles)) + " lexer files: " + ", ".join(sci.lexFiles)) printWrapped(str(len(sci.lexerModules)) + " lexer modules: " + ", ".join(sci.lexerModules)) + #~ printWrapped(str(len(sci.lexersXcode)) + " Xcode lexer references: " + ", ".join( + #~ [lex+":"+uids[0]+","+uids[1] for lex, uids in sci.lexersXcode.items()])) print("Lexer name to ID:") lexNames = sorted(sci.sclexFromName.keys()) for lexName in lexNames: |