diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Face.py | 114 | ||||
-rwxr-xr-x | scripts/HFacer.py | 48 | ||||
-rwxr-xr-x | scripts/LexGen.py | 256 |
3 files changed, 418 insertions, 0 deletions
diff --git a/scripts/Face.py b/scripts/Face.py new file mode 100644 index 000000000..855d6321a --- /dev/null +++ b/scripts/Face.py @@ -0,0 +1,114 @@ +# Module for reading and parsing Scintilla.iface file + +def sanitiseLine(line): + if line[-1:] == '\n': line = line[:-1] + if line.find("##") != -1: + line = line[:line.find("##")] + line = line.strip() + return line + +def decodeFunction(featureVal): + retType, rest = featureVal.split(" ", 1) + nameIdent, params = rest.split("(") + name, value = nameIdent.split("=") + params, rest = params.split(")") + param1, param2 = params.split(",") + return retType, name, value, param1, param2 + +def decodeEvent(featureVal): + retType, rest = featureVal.split(" ", 1) + nameIdent, params = rest.split("(") + name, value = nameIdent.split("=") + return retType, name, value + +def decodeParam(p): + param = p.strip() + type = "" + name = "" + value = "" + if " " in param: + type, nv = param.split(" ") + if "=" in nv: + name, value = nv.split("=") + else: + name = nv + return type, name, value + +class Face: + + def __init__(self): + self.order = [] + self.features = {} + self.values = {} + self.events = {} + + def ReadFromFile(self, name): + currentCategory = "" + currentComment = [] + currentCommentFinished = 0 + file = open(name) + for line in file.readlines(): + line = sanitiseLine(line) + if line: + if line[0] == "#": + if line[1] == " ": + if currentCommentFinished: + currentComment = [] + currentCommentFinished = 0 + currentComment.append(line[2:]) + else: + currentCommentFinished = 1 + featureType, featureVal = line.split(" ", 1) + if featureType in ["fun", "get", "set"]: + try: + retType, name, value, param1, param2 = decodeFunction(featureVal) + except ValueError: + print("Failed to decode %s" % line) + raise + p1 = decodeParam(param1) + p2 = decodeParam(param2) + self.features[name] = { + "FeatureType": featureType, + "ReturnType": retType, + "Value": value, + "Param1Type": p1[0], "Param1Name": p1[1], "Param1Value": p1[2], + "Param2Type": p2[0], "Param2Name": p2[1], "Param2Value": p2[2], + "Category": currentCategory, "Comment": currentComment + } + if value in self.values: + raise Exception("Duplicate value " + value + " " + name) + self.values[value] = 1 + self.order.append(name) + elif featureType == "evt": + retType, name, value = decodeEvent(featureVal) + self.features[name] = { + "FeatureType": featureType, + "ReturnType": retType, + "Value": value, + "Category": currentCategory, "Comment": currentComment + } + if value in self.events: + raise Exception("Duplicate event " + value + " " + name) + self.events[value] = 1 + self.order.append(name) + elif featureType == "cat": + currentCategory = featureVal + elif featureType == "val": + try: + name, value = featureVal.split("=", 1) + except ValueError: + print("Failure %s" % featureVal) + raise Exception() + self.features[name] = { + "FeatureType": featureType, + "Category": currentCategory, + "Value": value } + self.order.append(name) + elif featureType == "enu" or featureType == "lex": + name, value = featureVal.split("=", 1) + self.features[name] = { + "FeatureType": featureType, + "Category": currentCategory, + "Value": value } + self.order.append(name) + diff --git a/scripts/HFacer.py b/scripts/HFacer.py new file mode 100755 index 000000000..27537fec3 --- /dev/null +++ b/scripts/HFacer.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# HFacer.py - regenerate the Scintilla.h and SciLexer.h files from the Scintilla.iface interface +# definition file. + +import sys +import os +import Face + +from FileGenerator import UpdateFile, Generate, Regenerate, UpdateLineInFile, lineEnd + +def printLexHFile(f): + out = [] + for name in f.order: + v = f.features[name] + if v["FeatureType"] in ["val"]: + if "SCE_" in name or "SCLEX_" in name: + out.append("#define " + name + " " + v["Value"]) + return out + +def printHFile(f): + out = [] + previousCategory = "" + for name in f.order: + v = f.features[name] + if v["Category"] != "Deprecated": + if v["Category"] == "Provisional" and previousCategory != "Provisional": + out.append("#ifndef SCI_DISABLE_PROVISIONAL") + previousCategory = v["Category"] + if v["FeatureType"] in ["fun", "get", "set"]: + featureDefineName = "SCI_" + name.upper() + out.append("#define " + featureDefineName + " " + v["Value"]) + elif v["FeatureType"] in ["evt"]: + featureDefineName = "SCN_" + name.upper() + out.append("#define " + featureDefineName + " " + v["Value"]) + elif v["FeatureType"] in ["val"]: + if not ("SCE_" in name or "SCLEX_" in name): + out.append("#define " + name + " " + v["Value"]) + out.append("#endif") + return out + +f = Face.Face() +try: + f.ReadFromFile("../include/Scintilla.iface") + Regenerate("../include/Scintilla.h", "/* ", printHFile(f)) + Regenerate("../include/SciLexer.h", "/* ", printLexHFile(f)) + print("Maximum ID is %s" % max([x for x in f.values if int(x) < 3000])) +except: + raise diff --git a/scripts/LexGen.py b/scripts/LexGen.py new file mode 100755 index 000000000..4068ee485 --- /dev/null +++ b/scripts/LexGen.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python +# LexGen.py - implemented 2002 by Neil Hodgson neilh@scintilla.org +# Released to the public domain. + +# Regenerate the Scintilla and SciTE source files that list +# all the lexers and all the properties files. +# Should be run whenever a new lexer is added or removed. +# Requires Python 2.4 or later +# Most files are regenerated in place with templates stored in comments. +# The VS .NET project file is generated into a different file as the +# VS .NET environment will not retain comments when modifying the file. +# The format of generation comments is documented in FileGenerator.py. + +import string +import sys +import os +import glob +import codecs +import datetime + +from FileGenerator import UpdateFile, Generate, Regenerate, UpdateLineInFile, lineEnd + +def FindModules(lexFile): + modules = [] + with open(lexFile) as f: + for l in f.readlines(): + if l.startswith("LexerModule"): + l = l.replace("(", " ") + modules.append(l.split()[1]) + return modules + +# 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 = [ + "fold", + "styling.within.preprocessor", + "tab.timmy.whinge.level", + "asp.default.language", + "html.tags.case.sensitive", + "ps.level", + "ps.tokenize", + "sql.backslash.escapes", + "nsis.uservars", + "nsis.ignorecase" +] + +def FindProperties(lexFile): + properties = {} + with open(lexFile) as f: + for l in f.readlines(): + if ("GetProperty" in l or "DefineProperty" in l) and "\"" in l: + l = l.strip() + if not l.startswith("//"): # Drop comments + propertyName = l.split("\"")[1] + if propertyName.lower() == propertyName: + # Only allow lower case property names + if propertyName in knownIrregularProperties or \ + propertyName.startswith("fold.") or \ + propertyName.startswith("lexer."): + properties[propertyName] = 1 + return properties + +def FindPropertyDocumentation(lexFile): + documents = {} + with open(lexFile) as f: + name = "" + for l in f.readlines(): + l = l.strip() + if "// property " in l: + propertyName = l.split()[2] + if propertyName.lower() == propertyName: + # Only allow lower case property names + name = propertyName + documents[name] = "" + elif "DefineProperty" in l and "\"" in l: + propertyName = l.split("\"")[1] + if propertyName.lower() == propertyName: + # Only allow lower case property names + name = propertyName + documents[name] = "" + elif name: + if l.startswith("//"): + if documents[name]: + documents[name] += " " + documents[name] += l[2:].strip() + elif l.startswith("\""): + l = l[1:].strip() + if l.endswith(";"): + l = l[:-1].strip() + if l.endswith(")"): + l = l[:-1].strip() + if l.endswith("\""): + l = l[:-1] + # Fix escaped double quotes + l = l.replace("\\\"", "\"") + documents[name] += l + else: + name = "" + for name in list(documents.keys()): + if documents[name] == "": + del documents[name] + return documents + +def ciCompare(a,b): + return cmp(a.lower(), b.lower()) + +def ciKey(a): + return a.lower() + +def sortListInsensitive(l): + try: # Try key function + l.sort(key=ciKey) + except TypeError: # Earlier version of Python, so use comparison function + l.sort(ciCompare) + +host = "prdownloads.sourceforge.net/" +def UpdateDownloadLinks(path, version): + lines = [] + with open(path, "r") as f: + for l in f.readlines(): + l = l.rstrip() + if host in l: + start, prd, rest = l.partition(host) + pth, dot, ending = rest.partition(".") + pthNew = pth[:-3] + version.rstrip() + lineWithNewVersion = start + prd +pthNew + dot + ending + lines.append(lineWithNewVersion) + else: + lines.append(l) + contents = lineEnd.join(lines) + lineEnd + UpdateFile(path, contents) + +def UpdateVersionNumbers(root): + with open(root + "scintilla/version.txt") as f: + version = f.read() + versionDotted = version[0] + '.' + version[1] + '.' + version[2] + versionCommad = version[0] + ', ' + version[1] + ', ' + version[2] + ', 0' + with open(root + "scintilla/doc/index.html") as f: + dateModified = [l for l in f.readlines() if "Date.Modified" in l][0].split('\"')[3] + # 20130602 + # index.html, SciTE.html + dtModified = datetime.datetime.strptime(dateModified, "%Y%m%d") + yearModified = dateModified[0:4] + monthModified = dtModified.strftime("%B") + dayModified = "%d" % dtModified.day + mdyModified = monthModified + " " + dayModified + " " + yearModified + # May 22 2013 + # index.html, SciTE.html + dmyModified = dayModified + " " + monthModified + " " + yearModified + # 22 May 2013 + # ScintillaHistory.html -- only first should change + myModified = monthModified + " " + yearModified + # scite/src/SciTE.h + #define COPYRIGHT_DATES "December 1998-May 2013" + #define COPYRIGHT_YEARS "1998-2013" + dateLine = f.readlines() + + UpdateLineInFile(root + "scintilla/win32/ScintRes.rc", "#define VERSION_SCINTILLA", + "#define VERSION_SCINTILLA \"" + versionDotted + "\"") + UpdateLineInFile(root + "scintilla/win32/ScintRes.rc", "#define VERSION_WORDS", + "#define VERSION_WORDS " + versionCommad) + UpdateLineInFile(root + "scintilla/qt/ScintillaEditBase/ScintillaEditBase.pro", + "VERSION =", + "VERSION = " + versionDotted) + UpdateLineInFile(root + "scintilla/qt/ScintillaEdit/ScintillaEdit.pro", + "VERSION =", + "VERSION = " + versionDotted) + UpdateLineInFile(root + "scintilla/doc/ScintillaDownload.html", " Release", + " Release " + versionDotted) + UpdateDownloadLinks(root + "scintilla/doc/ScintillaDownload.html", version) + UpdateLineInFile(root + "scintilla/doc/index.html", + ' <font color="#FFCC99" size="3"> Release version', + ' <font color="#FFCC99" size="3"> Release version ' + versionDotted + '<br />') + UpdateLineInFile(root + "scintilla/doc/index.html", + ' Site last modified', + ' Site last modified ' + mdyModified + '</font>') + UpdateLineInFile(root + "scintilla/doc/ScintillaHistory.html", + ' Released ', + ' Released ' + dmyModified + '.') + + if os.path.exists(root + "scite"): + UpdateLineInFile(root + "scite/src/SciTE.h", "#define VERSION_SCITE", + "#define VERSION_SCITE \"" + versionDotted + "\"") + UpdateLineInFile(root + "scite/src/SciTE.h", "#define VERSION_WORDS", + "#define VERSION_WORDS " + versionCommad) + UpdateLineInFile(root + "scite/src/SciTE.h", "#define COPYRIGHT_DATES", + '#define COPYRIGHT_DATES "December 1998-' + myModified + '"') + UpdateLineInFile(root + "scite/src/SciTE.h", "#define COPYRIGHT_YEARS", + '#define COPYRIGHT_YEARS "1998-' + yearModified + '"') + UpdateLineInFile(root + "scite/doc/SciTEDownload.html", " Release", + " Release " + versionDotted) + UpdateDownloadLinks(root + "scite/doc/SciTEDownload.html", version) + UpdateLineInFile(root + "scite/doc/SciTE.html", + ' <font color="#FFCC99" size="3"> Release version', + ' <font color="#FFCC99" size="3"> Release version ' + versionDotted + '<br />') + UpdateLineInFile(root + "scite/doc/SciTE.html", + ' Site last modified', + ' Site last modified ' + mdyModified + '</font>') + UpdateLineInFile(root + "scite/doc/SciTE.html", + ' <meta name="Date.Modified"', + ' <meta name="Date.Modified" content="' + dateModified + '" />') + +def RegenerateAll(): + root="../../" + + # Find all the lexer source code files + lexFilePaths = glob.glob(root + "scintilla/lexers/Lex*.cxx") + sortListInsensitive(lexFilePaths) + lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths] + print(lexFiles) + lexerModules = [] + lexerProperties = {} + propertyDocuments = {} + for lexFile in lexFilePaths: + lexerModules.extend(FindModules(lexFile)) + for k in FindProperties(lexFile).keys(): + lexerProperties[k] = 1 + documents = FindPropertyDocumentation(lexFile) + for k in documents.keys(): + if k not in propertyDocuments: + propertyDocuments[k] = documents[k] + sortListInsensitive(lexerModules) + lexerProperties = list(lexerProperties.keys()) + sortListInsensitive(lexerProperties) + + # Generate HTML to document each property + # This is done because tags can not be safely put inside comments in HTML + documentProperties = list(propertyDocuments.keys()) + sortListInsensitive(documentProperties) + propertiesHTML = [] + for k in documentProperties: + propertiesHTML.append("\t<tr id='property-%s'>\n\t<td>%s</td>\n\t<td>%s</td>\n\t</tr>" % + (k, k, propertyDocuments[k])) + + # Find all the SciTE properties files + otherProps = ["abbrev.properties", "Embedded.properties", "SciTEGlobal.properties", "SciTE.properties"] + if os.path.exists(root + "scite"): + propFilePaths = glob.glob(root + "scite/src/*.properties") + sortListInsensitive(propFilePaths) + propFiles = [os.path.basename(f) for f in propFilePaths if os.path.basename(f) not in otherProps] + sortListInsensitive(propFiles) + print(propFiles) + + Regenerate(root + "scintilla/src/Catalogue.cxx", "//", lexerModules) + Regenerate(root + "scintilla/win32/scintilla.mak", "#", lexFiles) + if os.path.exists(root + "scite"): + Regenerate(root + "scite/win32/makefile", "#", propFiles) + Regenerate(root + "scite/win32/scite.mak", "#", propFiles) + Regenerate(root + "scite/src/SciTEProps.cxx", "//", lexerProperties) + Regenerate(root + "scite/doc/SciTEDoc.html", "<!--", propertiesHTML) + Generate(root + "scite/boundscheck/vcproj.gen", + root + "scite/boundscheck/SciTE.vcproj", "#", lexFiles) + + UpdateVersionNumbers(root) + +RegenerateAll() |