diff options
author | nyamatongwe <unknown> | 2012-05-17 12:46:29 +1000 |
---|---|---|
committer | nyamatongwe <unknown> | 2012-05-17 12:46:29 +1000 |
commit | bf8b35542c4be4b8eebb71ca2ad518da2e12b850 (patch) | |
tree | eab094df23f84c33c7ed03f3412a63a060d31eac /qt/ScintillaEdit/WidgetGen.py | |
parent | 29c92749f25f24795ecd9fec2b6705129ebbd654 (diff) | |
download | scintilla-mirror-bf8b35542c4be4b8eebb71ca2ad518da2e12b850.tar.gz |
Qt platform layer added. Based on an implementation from Jason Haslam
at Scientific Toolworks, Inc. with additions performed for Wingware.
Diffstat (limited to 'qt/ScintillaEdit/WidgetGen.py')
-rw-r--r-- | qt/ScintillaEdit/WidgetGen.py | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/qt/ScintillaEdit/WidgetGen.py b/qt/ScintillaEdit/WidgetGen.py new file mode 100644 index 000000000..8065b5f9d --- /dev/null +++ b/qt/ScintillaEdit/WidgetGen.py @@ -0,0 +1,275 @@ +#!/usr/bin/env python +# WidgetGen.py - regenerate the ScintillaWidgetCpp.cpp and ScintillaWidgetCpp.h files +# Check that API includes all gtkscintilla2 functions + +import sys +import os +import getopt + +scintillaDirectory = "../.." +scintillaIncludeDirectory = os.path.join(scintillaDirectory, "include") +sys.path.append(scintillaIncludeDirectory) +import Face + +def Contains(s,sub): + return s.find(sub) != -1 + +def underscoreName(s): + # Name conversion fixes to match gtkscintilla2 + irregular = ['WS', 'EOL', 'AutoC', 'KeyWords', 'BackSpace', 'UnIndents', 'RE', 'RGBA'] + for word in irregular: + replacement = word[0] + word[1:].lower() + s = s.replace(word, replacement) + + out = "" + for c in s: + if c.isupper(): + if out: + out += "_" + out += c.lower() + else: + out += c + return out + +def normalisedName(s, options, role=None): + if options["qtStyle"]: + if role == "get": + s = s.replace("Get", "") + return s[0].lower() + s[1:] + else: + return underscoreName(s) + +typeAliases = { + "position": "int", + "colour": "int", + "keymod": "int", + "string": "const char *", + "stringresult": "const char *", + "cells": "const char *", +} + +def cppAlias(s): + if s in typeAliases: + return typeAliases[s] + else: + return s + +understoodTypes = ["", "void", "int", "bool", "position", + "colour", "keymod", "string", "stringresult", "cells"] + +def checkTypes(name, v): + understandAllTypes = True + if v["ReturnType"] not in understoodTypes: + #~ print("Do not understand", v["ReturnType"], "for", name) + understandAllTypes = False + if v["Param1Type"] not in understoodTypes: + #~ print("Do not understand", v["Param1Type"], "for", name) + understandAllTypes = False + if v["Param2Type"] not in understoodTypes: + #~ print("Do not understand", v["Param2Type"], "for", name) + understandAllTypes = False + return understandAllTypes + +def arguments(v, stringResult, options): + ret = "" + p1Type = cppAlias(v["Param1Type"]) + if p1Type: + ret = ret + p1Type + " " + normalisedName(v["Param1Name"], options) + p2Type = cppAlias(v["Param2Type"]) + if p2Type and not stringResult: + if p1Type: + ret = ret + ", " + ret = ret + p2Type + " " + normalisedName(v["Param2Name"], options) + return ret + +def printPyFile(f,out, options): + for name in f.order: + v = f.features[name] + if v["Category"] != "Deprecated": + feat = v["FeatureType"] + if feat in ["val"]: + out.write(name + "=" + v["Value"] + "\n") + if feat in ["evt"]: + out.write("SCN_" + name.upper() + "=" + v["Value"] + "\n") + +def printHFile(f,out, options): + for name in f.order: + v = f.features[name] + if v["Category"] != "Deprecated": + feat = v["FeatureType"] + if feat in ["fun", "get", "set"]: + if checkTypes(name, v): + constDeclarator = " const" if feat == "get" else "" + returnType = cppAlias(v["ReturnType"]) + stringResult = v["Param2Type"] == "stringresult" + if stringResult: + returnType = "QByteArray" + out.write("\t" + returnType + " " + normalisedName(name, options, feat) + "(") + out.write(arguments(v, stringResult, options)) + out.write(")" + constDeclarator + ";\n") + +def methodNames(f, options): + for name in f.order: + v = f.features[name] + if v["Category"] != "Deprecated": + feat = v["FeatureType"] + if feat in ["fun", "get", "set"]: + if checkTypes(name, v): + yield normalisedName(name, options) + +def printCPPFile(f,out, options): + for name in f.order: + v = f.features[name] + if v["Category"] != "Deprecated": + feat = v["FeatureType"] + if feat in ["fun", "get", "set"]: + if checkTypes(name, v): + constDeclarator = " const" if feat == "get" else "" + featureDefineName = "SCI_" + name.upper() + returnType = cppAlias(v["ReturnType"]) + stringResult = v["Param2Type"] == "stringresult" + if stringResult: + returnType = "QByteArray" + returnStatement = "" + if returnType != "void": + returnStatement = "return " + out.write(returnType + " ScintillaEdit::" + normalisedName(name, options, feat) + "(") + out.write(arguments(v, stringResult, options)) + out.write(")" + constDeclarator + " {\n") + if stringResult: + out.write(" " + returnStatement + "TextReturner(" + featureDefineName + ", ") + if "*" in cppAlias(v["Param1Type"]): + out.write("(uptr_t)") + if v["Param1Name"]: + out.write(normalisedName(v["Param1Name"], options)) + else: + out.write("0") + out.write(");\n") + else: + out.write(" " + returnStatement + "send(" + featureDefineName + ", ") + if "*" in cppAlias(v["Param1Type"]): + out.write("(uptr_t)") + if v["Param1Name"]: + out.write(normalisedName(v["Param1Name"], options)) + else: + out.write("0") + out.write(", ") + if "*" in cppAlias(v["Param2Type"]): + out.write("(sptr_t)") + if v["Param2Name"]: + out.write(normalisedName(v["Param2Name"], options)) + else: + out.write("0") + out.write(");\n") + out.write("}\n") + out.write("\n") + +def CopyWithInsertion(input, output, genfn, definition, options): + copying = 1 + for line in input.readlines(): + if copying: + output.write(line) + if "/* ++Autogenerated" in line or "# ++Autogenerated" in line or "<!-- ++Autogenerated" in line: + copying = 0 + genfn(definition, output, options) + # ~~ form needed as XML comments can not contain -- + if "/* --Autogenerated" in line or "# --Autogenerated" in line or "<!-- ~~Autogenerated" in line: + copying = 1 + output.write(line) + +def contents(filename): + with open(filename, "U") as f: + t = f.read() + return t + +def Generate(templateFile, destinationFile, genfn, definition, options): + inText = contents(templateFile) + try: + currentText = contents(destinationFile) + except IOError: + currentText = "" + tempname = "WidgetGen.tmp" + with open(tempname, "w") as out: + with open(templateFile, "U") as hfile: + CopyWithInsertion(hfile, out, genfn, definition, options) + outText = contents(tempname) + if currentText == outText: + os.unlink(tempname) + else: + try: + os.unlink(destinationFile) + except OSError: + # Will see failure if file does not yet exist + pass + os.rename(tempname, destinationFile) + +def gtkNames(): + # The full path on my machine: should be altered for anyone else + p = "C:/Users/Neil/Downloads/wingide-source-4.0.1-1/wingide-source-4.0.1-1/external/gtkscintilla2/gtkscintilla.c" + with open(p) as f: + for l in f.readlines(): + if "gtk_scintilla_" in l: + name = l.split()[1][14:] + if '(' in name: + name = name.split('(')[0] + yield name + +def usage(): + print("WidgetGen.py [-c|--clean][-h|--help][-u|--underscore-names]") + print("") + print("Generate full APIs for ScintillaEdit class and ScintillaConstants.py.") + print("") + print("options:") + print("") + print("-c --clean remove all generated code from files") + print("-h --help display this text") + print("-u --underscore-names use method_names consistent with GTK+ standards") + +def readInterface(cleanGenerated): + f = Face.Face() + if not cleanGenerated: + f.ReadFromFile("../../include/Scintilla.iface") + return f + +def main(argv): + # Using local path for gtkscintilla2 so don't default to checking + checkGTK = False + cleanGenerated = False + qtStyleInterface = True + # The --gtk-check option checks for full coverage of the gtkscintilla2 API but + # depends on a particular directory so is not mentioned in --help. + opts, args = getopt.getopt(argv, "hcgu", ["help", "clean", "gtk-check", "underscore-names"]) + for opt, arg in opts: + if opt in ("-h", "--help"): + usage() + sys.exit() + elif opt in ("-c", "--clean"): + cleanGenerated = True + elif opt in ("-g", "--gtk-check"): + checkGTK = True + elif opt in ("-u", "--underscore-names"): + qtStyleInterface = False + + options = {"qtStyle": qtStyleInterface} + f = readInterface(cleanGenerated) + try: + Generate("ScintillaEdit.cpp.template", "ScintillaEdit.cpp", printCPPFile, f, options) + Generate("ScintillaEdit.h.template", "ScintillaEdit.h", printHFile, f, options) + Generate("../ScintillaEditPy/ScintillaConstants.py.template", + "../ScintillaEditPy/ScintillaConstants.py", + printPyFile, f, options) + if checkGTK: + names = set(methodNames(f)) + #~ print("\n".join(names)) + namesGtk = set(gtkNames()) + for name in namesGtk: + if name not in names: + print(name, "not found in Qt version") + for name in names: + if name not in namesGtk: + print(name, "not found in GTK+ version") + except: + raise + +if __name__ == "__main__": + main(sys.argv[1:]) |