aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Face.py114
-rwxr-xr-xscripts/HFacer.py48
-rwxr-xr-xscripts/LexGen.py256
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()