aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/ScintillaAPIFacer.py185
1 files changed, 178 insertions, 7 deletions
diff --git a/scripts/ScintillaAPIFacer.py b/scripts/ScintillaAPIFacer.py
index 3078b49c6..9fe5f56ce 100644
--- a/scripts/ScintillaAPIFacer.py
+++ b/scripts/ScintillaAPIFacer.py
@@ -10,6 +10,121 @@ import Face
import FileGenerator
import HFacer
+namespace = "Scintilla::"
+
+typeAliases = {
+ # Convert iface types to C++ types
+ # bool and void are OK as is
+ "cells": "const char *",
+ "colour": "Colour",
+ "colouralpha": "ColourAlpha",
+ "findtext": "void *",
+ "formatrange": "void *",
+ "int": "int",
+ "keymod": "int",
+ "line": "Line",
+ "pointer": "void *",
+ "position": "Position",
+ "string": "const char *",
+ "stringresult": "char *",
+ "textrange": "void *",
+}
+
+basicTypes = [
+ "bool",
+ "char *",
+ "Colour",
+ "ColourAlpha",
+ "const char *",
+ "int",
+ "intptr_t",
+ "Line",
+ "Position",
+ "void",
+ "void *",
+]
+
+deadValues = [
+ "INDIC_CONTAINER",
+ "INDIC_IME",
+ "INDIC_IME_MAX",
+ "INDIC_MAX",
+]
+
+def ActualTypeName(type, identifier=None):
+ if type in typeAliases:
+ return typeAliases[type]
+ else:
+ return type
+
+def IsEnumeration(s):
+ if s in ["Position", "Line", "Colour", "ColourAlpha"]:
+ return False
+ return s[:1].isupper()
+
+def JoinTypeAndIdentifier(type, identifier):
+ # Add a space to separate type from identifier unless type is pointer
+ if type.endswith("*"):
+ return type + identifier
+ else:
+ return type + " " + identifier
+
+def ParametersArgsCallname(v):
+ parameters = ""
+ args = ""
+ callName = "Call"
+
+ param1TypeBase = v["Param1Type"]
+ param1Name = v["Param1Name"]
+ param1Type = ActualTypeName(param1TypeBase, param1Name)
+ param1Arg = ""
+ if param1Type:
+ castName = param1Name
+ if param1Type.endswith("*"):
+ castName = "reinterpret_cast<uintptr_t>(" + param1Name + ")"
+ elif param1Type not in basicTypes:
+ castName = "static_cast<uintptr_t>(" + param1Name + ")"
+ if IsEnumeration(param1TypeBase):
+ param1Type = namespace + param1Type
+ param1Arg = JoinTypeAndIdentifier(param1Type, param1Name)
+ parameters = param1Arg
+ args = castName
+
+ param2TypeBase = v["Param2Type"]
+ param2Name = v["Param2Name"]
+ param2Type = ActualTypeName(param2TypeBase, param2Name)
+ param2Arg = ""
+ if param2Type:
+ castName = param2Name
+ if param2Type.endswith("*"):
+ if param2Type == "const char *":
+ callName = "CallString"
+ else:
+ callName = "CallPointer"
+ elif param2Type not in basicTypes:
+ castName = "static_cast<intptr_t>(" + param2Name + ")"
+ if IsEnumeration(param2TypeBase):
+ param2Type = namespace + param2Type
+ param2Arg = JoinTypeAndIdentifier(param2Type, param2Name)
+ if param1Arg:
+ parameters = parameters + ", "
+ parameters = parameters + param2Arg
+ if not args:
+ args = args + "0"
+ if args:
+ args = args + ", "
+ args = args + castName
+
+ if args:
+ args = ", " + args
+ return (parameters, args, callName)
+
+def ParametersExceptLast(parameters):
+ if "," in parameters:
+ return parameters[:parameters.rfind(",")]
+ else:
+ return ""
+
def HMessages(f):
out = ["enum class Message {"]
for name in f.order:
@@ -20,13 +135,6 @@ def HMessages(f):
out.append("};")
return out
-deadValues = [
- "INDIC_CONTAINER",
- "INDIC_IME",
- "INDIC_IME_MAX",
- "INDIC_MAX",
-]
-
def HEnumerations(f):
out = []
for name in f.order:
@@ -100,6 +208,67 @@ def HConstants(f):
out.append("constexpr " + type + " " + Face.PascalCase(name) + " = " + v["Value"] + ";")
return out
+def HMethods(f):
+ out = []
+ for name in f.order:
+ v = f.features[name]
+ if v["Category"] != "Deprecated":
+ if v["FeatureType"] in ["fun", "get", "set"]:
+ if v["FeatureType"] == "get" and name.startswith("Get"):
+ name = name[len("Get"):]
+ retType = ActualTypeName(v["ReturnType"])
+ if IsEnumeration(retType):
+ retType = namespace + retType
+ parameters, args, callName = ParametersArgsCallname(v)
+
+ out.append("\t" + JoinTypeAndIdentifier(retType, name) + "(" + parameters + ");")
+
+ # Extra method for stringresult that returns std::string
+ if v["Param2Type"] == "stringresult":
+ out.append("\t" + JoinTypeAndIdentifier("std::string", name) + \
+ "(" + ParametersExceptLast(parameters) + ");")
+ return out
+
+def CXXMethods(f):
+ out = []
+ for name in f.order:
+ v = f.features[name]
+ if v["Category"] != "Deprecated":
+ if v["FeatureType"] in ["fun", "get", "set"]:
+ msgName = "Message::" + name
+ if v["FeatureType"] == "get" and name.startswith("Get"):
+ name = name[len("Get"):]
+ retType = ActualTypeName(v["ReturnType"])
+ parameters, args, callName = ParametersArgsCallname(v)
+ returnIfNeeded = "return " if retType != "void" else ""
+
+ out.append(JoinTypeAndIdentifier(retType, "ScintillaCall::" + name) + "(" + parameters + ")" + " {")
+ retCast = ""
+ retCastEnd = ""
+ if retType not in basicTypes or retType in ["int", "Colour", "ColourAlpha"]:
+ if IsEnumeration(retType):
+ retType = namespace + retType
+ retCast = "static_cast<" + retType + ">("
+ retCastEnd = ")"
+ elif retType in ["void *"]:
+ retCast = "reinterpret_cast<" + retType + ">("
+ retCastEnd = ")"
+ out.append("\t" + returnIfNeeded + retCast + callName + "(" + msgName + args + ")" + retCastEnd + ";")
+ out.append("}")
+ out.append("")
+
+ # Extra method for stringresult that returns std::string
+ if v["Param2Type"] == "stringresult":
+ paramList = ParametersExceptLast(parameters)
+ argList = ParametersExceptLast(args)
+ out.append(JoinTypeAndIdentifier("std::string", "ScintillaCall::" + name) + \
+ "(" + paramList + ") {")
+ out.append("\treturn CallReturnString(" + msgName + argList + ");")
+ out.append("}")
+ out.append("")
+
+ return out
+
def RegenerateAll(root):
HFacer.RegenerateAll(root, False)
f = Face.Face()
@@ -107,6 +276,8 @@ def RegenerateAll(root):
f.ReadFromFile(include / "Scintilla.iface")
FileGenerator.Regenerate(include / "ScintillaMessages.h", "//", HMessages(f))
FileGenerator.Regenerate(include / "ScintillaTypes.h", "//", HEnumerations(f), HConstants(f))
+ FileGenerator.Regenerate(include / "ScintillaCall.h", "//", HMethods(f))
+ FileGenerator.Regenerate(root / "call" / "ScintillaCall.cxx", "//", CXXMethods(f))
if __name__ == "__main__":
RegenerateAll(pathlib.Path(__file__).resolve().parent.parent)