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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
#!/usr/bin/env python3
# LexillaGen.py - implemented 2019 by Neil Hodgson neilh@scintilla.org
# Released to the public domain.
"""
Regenerate the Lexilla source files that list all the lexers.
"""
# Should be run whenever a new lexer is added or removed.
# Requires Python 3.6 or later
# Files are regenerated in place with templates stored in comments.
# The format of generation comments is documented in FileGenerator.py.
import os, pathlib, sys, uuid
thisPath = pathlib.Path(__file__).resolve()
sys.path.append(str(thisPath.parent.parent.parent / "scintilla" / "scripts"))
from FileGenerator import Regenerate, UpdateLineInFile, \
ReplaceREInFile, UpdateLineInPlistFile, UpdateFileFromLines
import LexillaData
import LexFacer
sys.path.append(str(thisPath.parent.parent / "src"))
import DepGen
# RegenerateXcodeProject and associated functions are copied from scintilla/scripts/LexGen.py
def uid24():
""" Last 24 digits of UUID, used for item IDs in Xcode. """
return str(uuid.uuid4()).replace("-", "").upper()[-24:]
def ciLexerKey(a):
""" Return 3rd element of string lowered to be used when sorting. """
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):
""" Regenerate project to include any new lexers. """
# 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 = f"\t\t{uid1} /* {lexer}.cxx in Sources */ = {{isa = PBXBuildFile; fileRef = {uid2} /* {lexer}.cxx */; }};"
linePBXFileReference = f"\t\t{uid2} /* {lexer}.cxx */ = {{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = {lexer}.cxx; path = ../../lexers/{lexer}.cxx; sourceTree = SOURCE_ROOT; }};"
lineLexers = f"\t\t\t\t{uid2} /* {lexer}.cxx */,"
linePBXSourcesBuildPhase = f"\t\t\t\t{uid1} /* {lexer}.cxx in Sources */,"
sectionPBXBuildFile.append(linePBXBuildFile)
sectionPBXFileReference.append(linePBXFileReference)
sectionLexers.append(lineLexers)
sectionPBXSourcesBuildPhase.append(linePBXSourcesBuildPhase)
lines = LexillaData.ReadFileAsList(path)
sli = LexillaData.FindSectionInList(lines, markersPBXBuildFile)
lines[sli.stop:sli.stop] = sectionPBXBuildFile
sli = LexillaData.FindSectionInList(lines, markersPBXFileReference)
lines[sli.stop:sli.stop] = sectionPBXFileReference
sli = LexillaData.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 = LexillaData.FindSectionInList(lines, markersPBXSourcesBuildPhase)
lines[sli.stop:sli.stop] = sectionPBXSourcesBuildPhase
UpdateFileFromLines(path, lines, os.linesep)
def RegenerateAll(rootDirectory):
""" Regenerate all the files. """
root = pathlib.Path(rootDirectory)
lexillaBase = root.resolve()
lex = LexillaData.LexillaData(lexillaBase)
lexillaDir = lexillaBase
srcDir = lexillaDir / "src"
docDir = lexillaDir / "doc"
Regenerate(srcDir / "Lexilla.cxx", "//", lex.lexerModules)
Regenerate(srcDir / "lexilla.mak", "#", lex.lexFiles)
# Discover version information
version = (lexillaDir / "version.txt").read_text().strip()
versionDotted = version[0:-2] + '.' + version[-2] + '.' + version[-1]
versionCommad = versionDotted.replace(".", ", ") + ', 0'
rcPath = srcDir / "LexillaVersion.rc"
UpdateLineInFile(rcPath, "#define VERSION_LEXILLA",
"#define VERSION_LEXILLA \"" + versionDotted + "\"")
UpdateLineInFile(rcPath, "#define VERSION_WORDS",
"#define VERSION_WORDS " + versionCommad)
UpdateLineInFile(docDir / "LexillaDownload.html", " Release",
" Release " + versionDotted)
ReplaceREInFile(docDir / "LexillaDownload.html",
r"/www.scintilla.org/([a-zA-Z]+)\d{3,5}",
r"/www.scintilla.org/\g<1>" + version,
0)
pathMain = lexillaDir / "doc" / "Lexilla.html"
UpdateLineInFile(pathMain,
' <font color="#FFCC99" size="3">Release version',
' <font color="#FFCC99" size="3">Release version ' + \
versionDotted + '<br />')
UpdateLineInFile(pathMain,
' Site last modified',
' Site last modified ' + lex.mdyModified + '</font>')
UpdateLineInFile(pathMain,
' <meta name="Date.Modified"',
' <meta name="Date.Modified" content="' + lex.dateModified + '" />')
UpdateLineInFile(lexillaDir / "doc" / "LexillaHistory.html",
' Released ',
' Released ' + lex.dmyModified + '.')
lexillaXcode = lexillaDir / "src" / "Lexilla"
lexillaXcodeProject = lexillaXcode / "Lexilla.xcodeproj" / "project.pbxproj"
lexerReferences = LexillaData.FindLexersInXcode(lexillaXcodeProject)
UpdateLineInPlistFile(lexillaXcode / "Info.plist",
"CFBundleShortVersionString", versionDotted)
ReplaceREInFile(lexillaXcodeProject, "CURRENT_PROJECT_VERSION = [0-9.]+;",
f'CURRENT_PROJECT_VERSION = {versionDotted};',
0)
RegenerateXcodeProject(lexillaXcodeProject, lex.lexFiles, lexerReferences)
LexFacer.RegenerateAll(root, False)
currentDirectory = pathlib.Path.cwd()
os.chdir(srcDir)
DepGen.Generate()
os.chdir(currentDirectory)
if __name__=="__main__":
RegenerateAll(pathlib.Path(__file__).resolve().parent.parent)
|