summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2018-07-15 22:36:07 +0300
committeraunsane <aunsane@gmail.com>2018-07-15 22:36:39 +0300
commit0c37a8fd3a20e7087a31a68d0cca47e92c78a1e0 (patch)
tree19cdf0fa1d9f44bb76dd69bdc47be600e50fbf93
parentdba456c0069e4fd31a1532a901cb5ec60c978ca5 (diff)
MirLua: initial support of variables eval
- added math functions
-rw-r--r--plugins/MirLua/src/plugin.cpp1
-rw-r--r--plugins/MirLua/src/stdafx.h4
-rw-r--r--plugins/MirLua/src/variables_loader.cpp201
-rw-r--r--plugins/MirLua/src/variables_loader.h14
4 files changed, 220 insertions, 0 deletions
diff --git a/plugins/MirLua/src/plugin.cpp b/plugins/MirLua/src/plugin.cpp
index a5451d173b..bf2c47ced4 100644
--- a/plugins/MirLua/src/plugin.cpp
+++ b/plugins/MirLua/src/plugin.cpp
@@ -61,6 +61,7 @@ void CMPlugin::LoadLua()
CMLuaFunctionLoader::Load(L);
CMLuaModuleLoader::Load(L);
+ CMLuaVariablesLoader::Load(L);
LoadLuaScripts();
}
diff --git a/plugins/MirLua/src/stdafx.h b/plugins/MirLua/src/stdafx.h
index c24b840447..cd4873de17 100644
--- a/plugins/MirLua/src/stdafx.h
+++ b/plugins/MirLua/src/stdafx.h
@@ -5,6 +5,8 @@
#include <wchar.h>
#include <map>
+#include <regex>
+#include <string>
#include <newpluginapi.h>
#include <m_core.h>
@@ -28,6 +30,7 @@
#include <m_toptoolbar.h>
#include <m_json.h>
#include <m_gui.h>
+#include <m_variables.h>
#include <m_lua.h>
#include <mirlua.h>
@@ -44,6 +47,7 @@ class CMLuaScript;
#include "function_loader.h"
#include "module_loader.h"
#include "script_loader.h"
+#include "variables_loader.h"
#include "options.h"
#include "metatable.h"
diff --git a/plugins/MirLua/src/variables_loader.cpp b/plugins/MirLua/src/variables_loader.cpp
new file mode 100644
index 0000000000..c3cbd26c80
--- /dev/null
+++ b/plugins/MirLua/src/variables_loader.cpp
@@ -0,0 +1,201 @@
+#include "stdafx.h"
+
+CMLuaVariablesLoader::CMLuaVariablesLoader(lua_State *L) : L(L)
+{
+}
+
+/***********************************************/
+
+static int mlua__add(lua_State *L)
+{
+ int res = 0;
+
+ int nargs = lua_gettop(L);
+ for (int i = 1; i <= nargs; i++)
+ res += luaL_optinteger(L, i, 0);
+
+ lua_pushfstring(L, "%d", res);
+
+ return 1;
+}
+
+static int mlua__div(lua_State *L)
+{
+ int x = luaL_optinteger(L, 1, 0);
+ int y = luaL_optinteger(L, 2, 0);
+
+ lua_pushfstring(L, "%d", x - y);
+
+ return 1;
+}
+
+static int mlua__hex(lua_State *L)
+{
+ int x = luaL_optinteger(L, 1, 0);
+ int pad = luaL_optinteger(L, 2, 0);
+
+ CMStringA format(FORMAT, "0x%%0%dx", pad);
+ CMStringA value(FORMAT, format, x);
+ lua_pushstring(L, value);
+
+ return 1;
+}
+
+static int mlua__max(lua_State *L)
+{
+ int res = 0;
+
+ int nargs = lua_gettop(L);
+ for (int i = 1; i <= nargs; i++) {
+ int val = luaL_optinteger(L, i, INT_MIN);
+ if (val > res)
+ res = val;
+ }
+
+ lua_pushfstring(L, "%d", res);
+
+ return 1;
+}
+
+static int mlua__min(lua_State *L)
+{
+ int res = 0;
+
+ int nargs = lua_gettop(L);
+ for (int i = 1; i <= nargs; i++) {
+ int val = luaL_optinteger(L, i, INT_MAX);
+ if (val < res)
+ res = val;
+ }
+
+ lua_pushfstring(L, "%d", res);
+
+ return 1;
+}
+
+static int mlua__mod(lua_State *L)
+{
+ int x = luaL_optinteger(L, 1, 0);
+ int y = luaL_optinteger(L, 2, 0);
+
+ lua_pushfstring(L, "%d", x % y);
+
+ return 1;
+}
+
+static int mlua__mul(lua_State *L)
+{
+ int x = luaL_optinteger(L, 1, 0);
+ int y = luaL_optinteger(L, 2, 0);
+
+ lua_pushfstring(L, "%d", x * y);
+
+ return 1;
+}
+
+static int mlua__muldiv(lua_State *L)
+{
+ int x = luaL_optinteger(L, 1, 0);
+ int y = luaL_optinteger(L, 2, 0);
+ int z = luaL_optinteger(L, 3, 0);
+
+ lua_pushfstring(L, "%d", (x * y) / z);
+
+ return 1;
+}
+
+static int mlua__num(lua_State *L)
+{
+ int x = luaL_optinteger(L, 1, 0);
+ int pad = luaL_optinteger(L, 2, 0);
+
+ CMStringA format(FORMAT, "%%0%dx", pad);
+ CMStringA value(FORMAT, format, x);
+ lua_pushstring(L, value);
+
+ return 1;
+}
+
+static int mlua__rand(lua_State *L)
+{
+ lua_pushfstring(L, "%d", rand());
+
+ return 1;
+}
+
+static wchar_t* translate(lua_State *L, const wchar_t *format, const wchar_t *extra, MCONTACT hContact = NULL)
+{
+ std::wregex regex(L"\\?([a-z_0-9]+)\\(");
+ std::wstring query = std::regex_replace(format, regex, L"_v$1(");
+ query.insert(0, L"return ");
+
+ CMLuaEnvironment env(L);
+ wchar_t *result = env.Eval(query.c_str());
+ env.Unload();
+
+ return result;
+}
+
+static int mlua_vars(lua_State *L)
+{
+ ptrW format(mir_utf8decodeW(lua_tostring(L, 1)));
+ ptrW extra(mir_utf8decodeW(lua_tostring(L, 2)));
+ MCONTACT hContact = lua_tointeger(L, 3);
+
+ ptrW result(translate(L, format, extra, hContact));
+ lua_pushstring(L, T2Utf(result));
+
+ return 1;
+}
+
+/***********************************************/
+
+INT_PTR FormatString(void *obj, WPARAM wParam, LPARAM)
+{
+ lua_State *L = (lua_State*)obj;
+ FORMATINFO *fi = (FORMATINFO*)wParam;
+
+ ptrW result;
+ if ((fi->flags & FIF_UNICODE) == 0) {
+ _A2T format(fi->szFormat.a);
+ _A2T extra(fi->szExtraText.a);
+ result = translate(L, format, extra, fi->hContact);
+ }
+ else
+ result = translate(L, fi->szFormat.w, fi->szExtraText.w, fi->hContact);
+
+ lua_pushstring(L, T2Utf(result));
+
+ return (INT_PTR)result;
+}
+
+/***********************************************/
+
+void CMLuaVariablesLoader::LoadVariables()
+{
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ return;
+
+ CreateServiceFunctionObj(MS_VARS_FORMATSTRING, FormatString, L);
+
+ Log("Loading variables functions");
+
+ lua_register(L, "vars", mlua_vars);
+ // math
+ lua_register(L, "_vadd", mlua__add);
+ lua_register(L, "_vdiv", mlua__div);
+ lua_register(L, "_vhex", mlua__hex);
+ lua_register(L, "_vmax", mlua__max);
+ lua_register(L, "_vmin", mlua__min);
+ lua_register(L, "_vmod", mlua__mod);
+ lua_register(L, "_vmul", mlua__mul);
+ lua_register(L, "_vmuldiv", mlua__muldiv);
+ lua_register(L, "_vnum", mlua__num);
+ lua_register(L, "_vrand", mlua__rand);
+}
+
+void CMLuaVariablesLoader::Load(lua_State *L)
+{
+ CMLuaVariablesLoader loader(L);
+ loader.LoadVariables();
+} \ No newline at end of file
diff --git a/plugins/MirLua/src/variables_loader.h b/plugins/MirLua/src/variables_loader.h
new file mode 100644
index 0000000000..a9c7432480
--- /dev/null
+++ b/plugins/MirLua/src/variables_loader.h
@@ -0,0 +1,14 @@
+#pragma once
+
+class CMLuaVariablesLoader
+{
+private:
+ lua_State *L;
+
+ CMLuaVariablesLoader(lua_State *L);
+
+ void LoadVariables();
+
+public:
+ static void Load(lua_State *L);
+};