aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2021-05-24 19:31:06 +1000
committerNeil <nyamatongwe@gmail.com>2021-05-24 19:31:06 +1000
commit92290868cf9753d2df0d494cb44e2ff62a570b58 (patch)
tree001e6cfce84372a03997de3138d630751ee8d38a /scripts
parentee1886079d0a5cd350ee8e3379be347943ba93ae (diff)
downloadscintilla-mirror-92290868cf9753d2df0d494cb44e2ff62a570b58.tar.gz
Define C++ version of the Scintilla API in ScintillaTypes.h, ScintillaMessages.h
and ScintillaStructures.h using scoped enumerations. Use these headers instead of Scintilla.h internally. External definitions go in the Scintilla namespace and internal definitio0ns in Scintilla::Internal.
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Face.py17
-rw-r--r--scripts/HeaderOrder.txt13
-rw-r--r--scripts/ScintillaAPIFacer.py107
3 files changed, 133 insertions, 4 deletions
diff --git a/scripts/Face.py b/scripts/Face.py
index 94451bc26..1559dfccd 100644
--- a/scripts/Face.py
+++ b/scripts/Face.py
@@ -41,6 +41,23 @@ def decodeParam(p):
def IsEnumeration(t):
return t[:1].isupper()
+def PascalCase(s):
+ capitalized = s.title()
+ # Remove '_' except between digits
+ pascalCase = ""
+ characterPrevious = " "
+ # Loop until penultimate character
+ for i in range(len(capitalized)-1):
+ character = capitalized[i]
+ characterNext = capitalized[i+1]
+ if character != "_" or (
+ characterPrevious.isnumeric() and characterNext.isnumeric()):
+ pascalCase += character
+ characterPrevious = character
+ # Add last character - not between digits so no special treatment
+ pascalCase += capitalized[-1]
+ return pascalCase
+
class Face:
def __init__(self):
diff --git a/scripts/HeaderOrder.txt b/scripts/HeaderOrder.txt
index 72ee15cb1..6d953af8f 100644
--- a/scripts/HeaderOrder.txt
+++ b/scripts/HeaderOrder.txt
@@ -90,14 +90,20 @@
// Non-platform-specific headers
+// Exported headers
+
+#include "Sci_Position.h"
+#include "ScintillaTypes.h"
+#include "ScintillaMessages.h"
+#include "ScintillaStructures.h"
+#include "ILoader.h"
+#include "ILexer.h"
+
// src platform interface
#include "Debugging.h"
#include "Geometry.h"
#include "Platform.h"
-#include "Sci_Position.h"
-#include "ILoader.h"
-#include "ILexer.h"
#include "Scintilla.h"
#include "ScintillaWidget.h"
@@ -130,7 +136,6 @@
#include "DBCS.h"
#include "Selection.h"
#include "PositionCache.h"
-#include "FontQuality.h"
#include "EditModel.h"
#include "MarginView.h"
#include "EditView.h"
diff --git a/scripts/ScintillaAPIFacer.py b/scripts/ScintillaAPIFacer.py
new file mode 100644
index 000000000..1d8463f18
--- /dev/null
+++ b/scripts/ScintillaAPIFacer.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+# ScintillaAPIFacer.py - regenerate the ScintillaTypes.h, and ScintillaMessages.h
+# from the Scintilla.iface interface definition file.
+# Implemented 2019 by Neil Hodgson neilh@scintilla.org
+# Requires Python 3.6 or later
+
+import Face
+import FileGenerator
+
+def HMessages(f):
+ out = ["enum class Message {"]
+ for name in f.order:
+ v = f.features[name]
+ if v["Category"] != "Deprecated":
+ if v["FeatureType"] in ["fun", "get", "set"]:
+ out.append("\t" + name + " = " + v["Value"] + ",")
+ out.append("};")
+ return out
+
+deadValues = [
+ "INDIC_CONTAINER",
+ "INDIC_IME",
+ "INDIC_IME_MAX",
+ "INDIC_MAX",
+]
+
+def HEnumerations(f):
+ out = []
+ for name in f.order:
+ v = f.features[name]
+ if v["Category"] != "Deprecated":
+ # Only want non-deprecated enumerations and lexers are not part of Scintilla API
+ if v["FeatureType"] in ["enu"] and name != "Lexer":
+ out.append("")
+ prefixes = v["Value"].split()
+ #out.append("enum class " + name + " {" + " // " + ",".join(prefixes))
+ out.append("enum class " + name + " {")
+ for valueName in f.order:
+ prefixMatched = ""
+ for p in prefixes:
+ if valueName.startswith(p) and valueName not in deadValues:
+ prefixMatched = p
+ if prefixMatched:
+ vEnum = f.features[valueName]
+ valueNameNoPrefix = ""
+ if valueName in f.aliases:
+ valueNameNoPrefix = f.aliases[valueName]
+ else:
+ valueNameNoPrefix = valueName[len(prefixMatched):]
+ if not valueNameNoPrefix: # Removed whole name
+ valueNameNoPrefix = valueName
+ if valueNameNoPrefix.startswith("SC_"):
+ valueNameNoPrefix = valueNameNoPrefix[len("SC_"):]
+ pascalName = Face.PascalCase(valueNameNoPrefix)
+ out.append("\t" + pascalName + " = " + vEnum["Value"] + ",")
+ out.append("};")
+
+ out.append("")
+ out.append("enum class Notification {")
+ for name in f.order:
+ v = f.features[name]
+ if v["Category"] != "Deprecated":
+ if v["FeatureType"] in ["evt"]:
+ out.append("\t" + name + " = " + v["Value"] + ",")
+ out.append("};")
+
+ return out
+
+def HConstants(f):
+ # Constants not in an eumeration
+ out = []
+ allEnumPrefixes = [
+ "SCE_", # Lexical styles
+ "SCI_", # Message number allocation
+ "SCEN_", # Notifications sent with WM_COMMAND
+ ]
+ for _n, v in f.features.items():
+ if v["Category"] != "Deprecated":
+ # Only want non-deprecated enumerations and lexers are not part of Scintilla API
+ if v["FeatureType"] in ["enu"]:
+ allEnumPrefixes.extend(v["Value"].split())
+ for name in f.order:
+ v = f.features[name]
+ if v["Category"] != "Deprecated":
+ # Only want non-deprecated enumerations and lexers are not part of Scintilla API
+ if v["FeatureType"] in ["val"]:
+ hasPrefix = False
+ for prefix in allEnumPrefixes:
+ if name.startswith(prefix):
+ hasPrefix = True
+ if not hasPrefix:
+ if name.startswith("SC_"):
+ name = name[3:]
+ type = "int"
+ if name == "INVALID_POSITION":
+ type = "Position"
+ out.append("constexpr " + type + " " + Face.PascalCase(name) + " = " + v["Value"] + ";")
+ return out
+
+def RegenerateAll(root):
+ f = Face.Face()
+ f.ReadFromFile(root + "include/Scintilla.iface")
+ FileGenerator.Regenerate(root + "include/ScintillaMessages.h", "//", HMessages(f))
+ FileGenerator.Regenerate(root + "include/ScintillaTypes.h", "//", HEnumerations(f), HConstants(f))
+
+if __name__ == "__main__":
+ RegenerateAll("../")