diff options
Diffstat (limited to 'DTTemplateFunctions.c')
| -rw-r--r-- | DTTemplateFunctions.c | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/DTTemplateFunctions.c b/DTTemplateFunctions.c new file mode 100644 index 0000000..860c9e1 --- /dev/null +++ b/DTTemplateFunctions.c @@ -0,0 +1,307 @@ +/*-- Template Functions --*/
+
+#strict 2
+
+static v;
+static TMPL_Funcs;
+static const TMPL_FuncArguments = 0;
+static const TMPL_FuncContents = 1;
+static const TMPL_FuncName = 2;
+static const TMPL_FuncCommands = 3;
+
+global func InitializeTemplateFunctions()
+{
+ if(GetType(v) != C4V_Array) v = [];
+ if(GetType(TMPL_Funcs) != C4V_Array) TMPL_Funcs = [];
+}
+
+global func DefineFunction(string name, arguments, commands)
+{
+ InitializeTemplateFunctions();
+
+ var anonymousFunction = Function(arguments, commands);
+
+ var function = [anonymousFunction[0], anonymousFunction[1], name, commands];
+
+ SetFunction(name, function);
+}
+
+global func SetFunction(string name, array function)
+{
+ var index = FindTemplateFunction(name);
+ if(index != -1)
+ {
+ TMPL_Funcs[index] = function;
+ }
+ else
+ {
+ TMPL_Funcs[GetLength(TMPL_Funcs)] = function;
+ }
+}
+
+global func RemoveFunction(string name)
+{
+ var index = FindTemplateFunction(name);
+ if(index != -1)
+ {
+ var i;
+ for(i = index; i < GetLength(TMPL_Funcs) - 1; ++i)
+ {
+ TMPL_Funcs[i] = TMPL_Funcs[i + 1];
+ }
+ TMPL_Funcs[GetLength(TMPL_Funcs) - 1] = 0;
+ }
+}
+
+global func Function(arguments, commands)
+{
+ if(!commands)
+ {
+ commands = arguments;
+ arguments = [];
+ }
+
+ if(GetType(arguments) == C4V_String) arguments = [arguments];
+ else if(arguments == 0) arguments = [];
+
+ if(GetType(commands) == C4V_String) commands = [commands];
+
+ var funcContents = [];
+ for(var command in commands)
+ {
+ var isArg = false;
+ var argument = "";
+ var funcContent = [];
+ var contentPart = "";
+ var escapeCount = 0;
+ for(var i = 0; i < GetLength(command); ++i)
+ {
+ var c = GetChar(command, i);
+ if(isArg)
+ {
+ if(c == 37) // %
+ {
+ if(argument == "")
+ {
+ contentPart = Format("%s%%", contentPart);
+ }
+ else
+ {
+ var index = GetIndexOf2(argument, arguments);
+ if(index == -1)
+ {
+ FatalError(Format("Function: Unknown argument-name %s", argument));
+ return;
+ }
+ else
+ {
+ funcContent[GetLength(funcContent)] = [index, escapeCount];
+ argument = "";
+ escapeCount = 0;
+ }
+ }
+ isArg = false;
+ }
+ else if(argument == "" && c == 47) // /
+ {
+ ++escapeCount;
+ }
+ else
+ {
+ if(contentPart != "")
+ {
+ funcContent[GetLength(funcContent)] = contentPart;
+ contentPart = "";
+ }
+
+ argument = Format("%s%c", argument, c);
+ }
+ }
+ else
+ {
+ if(c == 37) // %
+ {
+ isArg = true;
+ }
+ else if(c == 39) // '
+ {
+ contentPart = Format("%s\"", contentPart);
+ }
+ else
+ {
+ contentPart = Format("%s%c", contentPart, c);
+ }
+ }
+ }
+ if(isArg) FatalError(Format("Function: argument-reference \"%s\" not closed.", argument));
+ else if(contentPart) funcContent[GetLength(funcContent)] = contentPart;
+ funcContents[GetLength(funcContents)] = funcContent;
+ }
+
+ return [arguments, funcContents];
+}
+
+global func FindTemplateFunction(string name)
+{
+ var i = 0;
+ for(var function in TMPL_Funcs)
+ {
+ if(GetType(function) == C4V_Array && function[TMPL_FuncName] == name) return i;
+ ++i;
+ }
+ return -1;
+}
+
+global func F(string name, array args)
+{
+ return f(Func(name), args);
+}
+
+global func f(array function, array args)
+{
+ var ret;
+ for(var content in function[TMPL_FuncContents])
+ {
+ var command = "";
+ for(var contentPart in content)
+ {
+ if(GetType(contentPart) == C4V_Array)
+ {
+ var part = StringReplace("'", Serialize(args[contentPart[0]]), "\\\"");
+ for(var i = 0; i < contentPart[1]; ++i)
+ {
+ part = EscapeString(part);
+ }
+ command = Format("%s%s", command, part);
+ }
+ else command = Format("%s%s", command, contentPart);
+ }
+ ret = eval(command);
+ }
+ return ret;
+}
+
+global func DebugF(string function, array args)
+{
+ return DebugFunc(Func(function), args);
+}
+
+global func DebugFunc(array function, array args)
+{
+ var ret;
+ for(var content in function[TMPL_FuncContents])
+ {
+ var command = "";
+ for(var contentPart in content)
+ {
+ if(GetType(contentPart) == C4V_Array)
+ {
+ var part = StringReplace("'", Serialize(args[contentPart[0]]), "\\\"");
+ for(var i = 0; i < contentPart[1]; ++i)
+ {
+ part = EscapeString(part);
+ }
+ command = Format("%s%s", command, part);
+ }
+ else command = Format("%s%s", command, contentPart);
+ }
+ Log(command);
+ }
+ return ret;
+}
+
+global func Func(string name)
+{
+ var index = FindTemplateFunction(name);
+ if(index == -1)
+ {
+ FatalError(Format("Func: Unknown function %s.", name));
+ return;
+ }
+ return TMPL_Funcs[index];
+}
+
+global func SaveFunction(int plr, string name, array function)
+{
+ return SetPlrExtraDataArray(plr, Format("TemplateFunction_%s", name), function);
+}
+
+global func LoadFunction(int plr, string name, string loadAs)
+{
+ var function = GetPlrExtraDataArray(plr, Format("TemplateFunction_%s", name));
+ if(function == 0)
+ {
+ FatalError(Format("LoadFunction: Unknown function: \"%s\"", name));
+ return;
+ }
+ if(loadAs != 0)
+ {
+ SetFunction(loadAs, function);
+ }
+ return function;
+}
+
+global func DeleteFunction(int plr, string name)
+{
+ return SetPlrExtraDataString(plr, Format("TemplateFunction_%s", name), "");
+}
+
+global func CallCustom(callback, args)
+{
+ if(GetType(callback) == C4V_Array && GetLength(callback) >= 2 && GetType(callback[0]) == C4V_Array && GetType(callback[1]) == C4V_Array)
+ {
+ return f(callback, args);
+ }
+ else
+ {
+ return _inherited(callback, args, ...);
+ }
+}
+
+global func CheckCustomCallback(callback)
+{
+ if(GetType(callback) == C4V_Array && (GetLength(callback) == 2 || (GetLength(callback) == 4 && GetType(callback[2]) == C4V_String && GetType(callback[3]) == C4V_Array)) && GetType(callback[0]) == C4V_Array && GetType(callback[1]) == C4V_Array)
+ {
+ var stringOnlyChecks = [callback[0]];
+
+ if(GetLength(callback) == 4)
+ {
+ stringOnlyChecks[1] = callback[3];
+ }
+
+ for(var check in stringOnlyChecks)
+ {
+ for(var val in check)
+ {
+ if(GetType(val) != C4V_String)
+ {
+ return _inherited(callback, ...);
+ }
+ }
+ }
+
+ for(var contentParts in callback[1])
+ {
+ if(GetType(contentParts) != C4V_Array)
+ {
+ return _inherited(callback, ...);
+ }
+
+ for(var content in contentParts)
+ {
+ if(GetType(content) == C4V_String)
+ {
+ continue;
+ }
+
+ if(GetType(content) != C4V_Array || GetLength(content) != 2 || (content[0] && GetType(content[0]) == C4V_Int && content[0] < 0) || (content[1] && GetType(content[1]) == C4V_Int && content[1] < 0))
+ {
+ return _inherited(callback, ...);
+ }
+ }
+ }
+
+ return true;
+ }
+ return _inherited(callback, ...);
+}
|
