-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add python scripts to update template; fix bugs
1. Ported over (from kbilsted's old template) the ToolsForMaintainersOfTheProjectTemplate folder for updating some of the PluginInfrastructure files to stay up to date with Notepad++. 2. Fix bug where running tests multiple times in a single Notepad++ session causes the user interface tests to fail.
- Loading branch information
1 parent
5a47ef5
commit 048a020
Showing
11 changed files
with
799 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
ToolsForMaintainersOfTheProjectTemplate/Scintilla_iface_synchronizer/Face.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# Face.py - module for reading and parsing Scintilla.iface file | ||
# Implemented 2000 by Neil Hodgson neilh@scintilla.org | ||
# Released to the public domain. | ||
# Requires Python 2.5 or later | ||
|
||
def sanitiseLine(line): | ||
if line[-1:] == '\n': line = line[:-1] | ||
pos = line.find("##") | ||
if pos != -1: | ||
line = line[:pos] | ||
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, | ||
"Comment": currentComment | ||
} | ||
self.order.append(name) | ||
|
159 changes: 159 additions & 0 deletions
159
ToolsForMaintainersOfTheProjectTemplate/Scintilla_iface_synchronizer/FileGenerator.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
#!/usr/bin/env python | ||
# FileGenerator.py - implemented 2013 by Neil Hodgson neilh@scintilla.org | ||
# Released to the public domain. | ||
|
||
# Generate or regenerate source files based on comments in those files. | ||
# May be modified in-place or a template may be generated into a complete file. | ||
# Requires Python 2.5 or later | ||
# The files are copied to a string apart from sections between a | ||
# ++Autogenerated comment and a --Autogenerated comment which is | ||
# generated by the CopyWithInsertion function. After the whole string is | ||
# instantiated, it is compared with the target file and if different the file | ||
# is rewritten. | ||
|
||
from __future__ import with_statement | ||
|
||
import codecs, os, re, string, sys | ||
|
||
lineEnd = "\r\n" if sys.platform == "win32" else "\n" | ||
|
||
def UpdateFile(filename, updated): | ||
""" If the file contents are different to updated then copy updated into the | ||
file else leave alone so Mercurial and make don't treat it as modified. """ | ||
newOrChanged = "Changed" | ||
try: | ||
with codecs.open(filename, "r", "utf-8") as infile: | ||
original = infile.read() | ||
if updated == original: | ||
print("Nothing new to update:", os.path.basename(filename)) | ||
# Same as before so don't write | ||
return | ||
os.unlink(filename) | ||
except IOError: # File is not there yet | ||
newOrChanged = "New" | ||
with codecs.open(filename, "w", "utf-8") as outfile: | ||
outfile.write(updated) | ||
print("%s %s" % (newOrChanged, filename)) | ||
|
||
# Automatically generated sections contain start and end comments, | ||
# a definition line and the results. | ||
# The results are replaced by regenerating based on the definition line. | ||
# The definition line is a comment prefix followed by "**". | ||
# If there is a digit after the ** then this indicates which list to use | ||
# and the digit and next character are not part of the definition | ||
# Backslash is used as an escape within the definition line. | ||
# The part between \( and \) is repeated for each item in the list. | ||
# \* is replaced by each list item. \t, and \n are tab and newline. | ||
# If there is no definition line than the first list is copied verbatim. | ||
# If retainDefs then the comments controlling generation are copied. | ||
def CopyWithInsertion(input, commentPrefix, retainDefs, lists): | ||
copying = 1 | ||
generated = False | ||
listid = 0 | ||
output = [] | ||
for line in input.splitlines(0): | ||
isStartGenerated = line.lstrip().startswith(commentPrefix + "++Autogenerated") | ||
if copying and not isStartGenerated: | ||
output.append(line) | ||
if isStartGenerated: | ||
if retainDefs: | ||
output.append(line) | ||
copying = 0 | ||
generated = False | ||
elif not copying and not generated: | ||
# Generating | ||
if line.startswith(commentPrefix + "**"): | ||
# Pattern to transform input data | ||
if retainDefs: | ||
output.append(line) | ||
definition = line[len(commentPrefix + "**"):] | ||
if (commentPrefix == "<!--") and (" -->" in definition): | ||
definition = definition.replace(" -->", "") | ||
listid = 0 | ||
if definition[0] in string.digits: | ||
listid = int(definition[:1]) | ||
definition = definition[2:] | ||
# Hide double slashes as a control character | ||
definition = definition.replace("\\\\", "\001") | ||
# Do some normal C style transforms | ||
definition = definition.replace("\\n", "\n") | ||
definition = definition.replace("\\t", "\t") | ||
# Get the doubled backslashes back as single backslashes | ||
definition = definition.replace("\001", "\\") | ||
startRepeat = definition.find("\\(") | ||
endRepeat = definition.find("\\)") | ||
intro = definition[:startRepeat] | ||
out = "" | ||
if intro.endswith("\n"): | ||
pos = 0 | ||
else: | ||
pos = len(intro) | ||
out += intro | ||
middle = definition[startRepeat+2:endRepeat] | ||
for i in lists[listid]: | ||
item = middle.replace("\\*", i) | ||
if pos and (pos + len(item) >= 80): | ||
out += "\\\n" | ||
pos = 0 | ||
out += item | ||
pos += len(item) | ||
if item.endswith("\n"): | ||
pos = 0 | ||
outro = definition[endRepeat+2:] | ||
out += outro | ||
out = out.replace("\n", lineEnd) # correct EOLs in generated content | ||
output.append(out) | ||
else: | ||
# Simple form with no rule to transform input | ||
output.extend(lists[0]) | ||
generated = True | ||
if line.lstrip().startswith(commentPrefix + "--Autogenerated") or \ | ||
line.lstrip().startswith(commentPrefix + "~~Autogenerated"): | ||
copying = 1 | ||
if retainDefs: | ||
output.append(line) | ||
output = [line.rstrip(" \t") for line in output] # trim trailing whitespace | ||
return lineEnd.join(output) + lineEnd | ||
|
||
def GenerateFile(inpath, outpath, commentPrefix, retainDefs, *lists): | ||
"""Generate 'outpath' from 'inpath'. | ||
""" | ||
|
||
try: | ||
with codecs.open(inpath, "r", "UTF-8") as infile: | ||
original = infile.read() | ||
updated = CopyWithInsertion(original, commentPrefix, | ||
retainDefs, lists) | ||
UpdateFile(outpath, updated) | ||
except IOError: | ||
print("Can not open %s" % inpath) | ||
|
||
def Generate(inpath, outpath, commentPrefix, *lists): | ||
"""Generate 'outpath' from 'inpath'. | ||
""" | ||
GenerateFile(inpath, outpath, commentPrefix, inpath == outpath, *lists) | ||
|
||
def Regenerate(filename, commentPrefix, *lists): | ||
"""Regenerate the given file. | ||
""" | ||
Generate(filename, filename, commentPrefix, *lists) | ||
|
||
def UpdateLineInFile(path, linePrefix, lineReplace): | ||
lines = [] | ||
updated = False | ||
with codecs.open(path, "r", "utf-8") as f: | ||
for l in f.readlines(): | ||
l = l.rstrip() | ||
if not updated and l.startswith(linePrefix): | ||
lines.append(lineReplace) | ||
updated = True | ||
else: | ||
lines.append(l) | ||
contents = lineEnd.join(lines) + lineEnd | ||
UpdateFile(path, contents) | ||
|
||
def ReplaceREInFile(path, match, replace): | ||
with codecs.open(path, "r", "utf-8") as f: | ||
contents = f.read() | ||
contents = re.sub(match, replace, contents) | ||
UpdateFile(path, contents) |
Oops, something went wrong.