[FarGroup/FarManager] master: Add more stack operations to Macro-API engine. (b0f6f98b8)

0 views
Skip to first unread message

farg...@farmanager.com

unread,
Oct 25, 2025, 10:15:49 AM (22 hours ago) Oct 25
to farco...@googlegroups.com
Repository : https://github.com/FarGroup/FarManager
On branch : master
Link : https://github.com/FarGroup/FarManager/commit/b0f6f98b80f9eb90f21657692a7afc54b629e0d4

>---------------------------------------------------------------

commit b0f6f98b80f9eb90f21657692a7afc54b629e0d4
Author: Shmuel Zeigerman <solo...@gmail.com>
Date: Sat Oct 25 17:12:14 2025 +0300

Add more stack operations to Macro-API engine.


>---------------------------------------------------------------

b0f6f98b80f9eb90f21657692a7afc54b629e0d4
enc/enc_lua/macroapi_manual.en.tsi | 6 +-
enc/enc_lua/macroapi_manual.pl.tsi | 6 +-
enc/enc_lua/macroapi_manual.ru.tsi | 6 +-
far/changelog | 5 ++
far/macroapi.cpp | 94 +++++++++++++----------
far/plugin.hpp | 34 ++++++---
far/tvar.cpp | 6 ++
far/tvar.hpp | 4 +-
far/vbuild.m4 | 2 +-
plugins/luamacro/_globalinfo.lua | 2 +-
plugins/luamacro/changelog | 4 +
plugins/luamacro/luafar/lf_exported.c | 37 +++++----
plugins/luamacro/luafar/lf_luamacro.c | 138 +++++++++++++++++-----------------
plugins/luamacro/luafar/lf_service.c | 25 ++----
plugins/luamacro/luafar/lf_service.h | 2 +
plugins/luamacro/luafar/lf_version.h | 2 +-
plugins/luamacro/macrotest.lua | 11 ++-
17 files changed, 210 insertions(+), 174 deletions(-)

diff --git a/enc/enc_lua/macroapi_manual.en.tsi b/enc/enc_lua/macroapi_manual.en.tsi
index bcfe4fe9a..f742263cf 100644
--- a/enc/enc_lua/macroapi_manual.en.tsi
+++ b/enc/enc_lua/macroapi_manual.en.tsi
@@ -2396,7 +2396,7 @@ lv=3
dt=Text
nm=Call
ctime=3560706460
-mtime=3717266757
+mtime=3970573039
<article>
#_... = Plugin.Call (PluginId [, ...])
#_
@@ -2427,7 +2427,7 @@ mtime=3717266757
#_ string -> FMVT_STRING (automatically converted from UTF-8 to UTF-16LE)
#_ {string} -> FMVT_BINARY (in order to pass an arbitrary string without UTF-8 -> UTF16LE
#_ conversion, the string should be placed in a table as an element
-#_ with its key==1)
+#_ with its key=="__binary")
#_
#_ 4. Values returned by the plugin via a *FarMacroCall* structure are passed to the macro
#_ the following way:
@@ -2436,7 +2436,7 @@ mtime=3717266757
#_ FMVT_DOUBLE -> number
#_ FMVT_INTEGER -> number, if it "fits" in 53 bits, otherwise int64
#_ FMVT_STRING -> string (automatically converted from UTF-16LE to UTF-8)
-#_ FMVT_BINARY -> table (the table contains a string as an element with its key==1;
+#_ FMVT_BINARY -> table (the table contains a string as an element with its key=="__binary";
#_ the string is placed as is, without conversion)
#_ FMVT_POINTER -> light userdata
#_ FMVT_ARRAY -> table (array of elements; the table contains 2 fields:
diff --git a/enc/enc_lua/macroapi_manual.pl.tsi b/enc/enc_lua/macroapi_manual.pl.tsi
index 6180455b7..1059f1103 100644
--- a/enc/enc_lua/macroapi_manual.pl.tsi
+++ b/enc/enc_lua/macroapi_manual.pl.tsi
@@ -2395,7 +2395,7 @@ lv=3
dt=Text
nm=Call
ctime=3560706460
-mtime=3717266757
+mtime=3970573104
<article>
#_... = Plugin.Call (PluginId [, ...])
#_
@@ -2426,7 +2426,7 @@ mtime=3717266757
#_ string -> FMVT_STRING (automatically converted from UTF-8 to UTF-16LE)
#_ {string} -> FMVT_BINARY (in order to pass an arbitrary string without UTF-8 -> UTF16LE
#_ conversion, the string should be placed in a table as an element
-#_ with its key==1)
+#_ with its key=="__binary")
#_
#_ 4. Values returned by the plugin via a *FarMacroCall* structure are passed to the macro
#_ the following way:
@@ -2435,7 +2435,7 @@ mtime=3717266757
#_ FMVT_DOUBLE -> number
#_ FMVT_INTEGER -> number, if it "fits" in 53 bits, otherwise int64
#_ FMVT_STRING -> string (automatically converted from UTF-16LE to UTF-8)
-#_ FMVT_BINARY -> table (the table contains a string as an element with its key==1;
+#_ FMVT_BINARY -> table (the table contains a string as an element with its key=="__binary";
#_ the string is placed as is, without conversion)
#_ FMVT_POINTER -> light userdata
#_ FMVT_ARRAY -> table (array of elements; the table contains 2 fields:
diff --git a/enc/enc_lua/macroapi_manual.ru.tsi b/enc/enc_lua/macroapi_manual.ru.tsi
index 181c47717..312f4ccf6 100644
--- a/enc/enc_lua/macroapi_manual.ru.tsi
+++ b/enc/enc_lua/macroapi_manual.ru.tsi
@@ -2391,7 +2391,7 @@ lv=3
dt=Text
nm=Call
ctime=3560706460
-mtime=3717267269
+mtime=3970573080
<article>
#_... = Plugin.Call (PluginId, ...)
#_
@@ -2422,7 +2422,7 @@ mtime=3717267269
#_ string -> FMVT_STRING (автоматически преобразуется из UTF-8 в UTF-16LE)
#_ {string} -> FMVT_BINARY (для того, чтобы передать произвольный стринг без
#_ преобразования UTF-8 -> UTF16LE, его нужно передавать,
-#_ помещённым в таблицу как элемент с ключом 1)
+#_ помещённым в таблицу как элемент с ключом "__binary")
#_
#_ 4. Величины, возвращаемые плагином через структуру *FarMacroCall*, передаются макросу
#_ следующим образом:
@@ -2431,7 +2431,7 @@ mtime=3717267269
#_ FMVT_DOUBLE -> number
#_ FMVT_INTEGER -> number, если "укладывается" в 53 бита, иначе int64
#_ FMVT_STRING -> string (автоматически преобразуется из UTF-16LE в UTF-8)
-#_ FMVT_BINARY -> table (в таблице передаётся строка как элемент с ключом 1;
+#_ FMVT_BINARY -> table (в таблице передаётся строка как элемент с ключом "__binary";
#_ передаётся как есть, без преобразования)
#_ FMVT_POINTER -> light userdata
#_ FMVT_ARRAY -> table (массив элементов; в таблице установлено два поля:
diff --git a/far/changelog b/far/changelog
index ae18d6ab5..0369b0fde 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,8 @@
+--------------------------------------------------------------------------------
+shmuel 2025-10-25 17:09:40+03:00 - build 6578
+
+1. Add more stack operations to Macro-API engine.
+
--------------------------------------------------------------------------------
ssvine 2025-10-25 10:12:06+03:00 - build 6577

diff --git a/far/macroapi.cpp b/far/macroapi.cpp
index f15550b64..644abd434 100644
--- a/far/macroapi.cpp
+++ b/far/macroapi.cpp
@@ -103,6 +103,25 @@ static panel_ptr SelectPanel(long long const Which)
}
}

+static TVar Convert2TVar(const FarMacroValue &val)
+{
+ switch (val.Type)
+ {
+ case FMVT_INTEGER: return TVar(val.Integer);
+ case FMVT_BOOLEAN: return TVar(val.Boolean);
+ case FMVT_DOUBLE: return TVar(val.Double);
+ case FMVT_STRING: return TVar(val.String);
+ case FMVT_POINTER: return TVar(val.Pointer);
+ case FMVT_DIALOG: return TVar(static_cast<Dialog*>(val.Pointer));
+ case FMVT_TABLE: {
+ TVar tv(val.Integer);
+ tv.SetType(TVar::Type::Table);
+ return tv;
+ }
+ default: return TVar();
+ }
+}
+
class FarMacroApi
{
public:
@@ -119,10 +138,16 @@ public:
void PushNil() const { SendValue(FMVT_NIL); }
void PushTable() const { SendValue(FMVT_NEWTABLE); }
void SetTable() const { SendValue(FMVT_SETTABLE); }
+ void StackSetTop(int top) const { SendValue(FarMacroValue(FMVT_STACKSETTOP, top)); }
+ void StackPop(int count) const { SendValue(FarMacroValue(FMVT_STACKPOP, count)); }
+ void StackPushValue(int pos) const { SendValue(FarMacroValue(FMVT_STACKPUSHVALUE, pos)); }
+
void PushError(const wchar_t* str) const;
void PushValue(long long Int) const;
void PushValue(const TVar& Var) const;
- void SetField(const FarMacroValue &Key, const FarMacroValue &Value) const;
+ void SetField(const FarMacroValue &Key, const FarMacroValue &Value, int Pos) const;
+ int StackGetTop() const;
+ TVar GetTable(int pos, const TVar &Key) const;

template<typename T> requires std::integral<T> || std::is_enum_v<T>
void PushValue(T const Value) const
@@ -130,31 +155,6 @@ public:
return PushValue(static_cast<long long>(Value));
}

- int StackGetTop() const
- {
- FarMacroValue val(FMVT_STACKGETTOP);
- SendValue(val);
- return val.Integer;
- }
- void StackSetTop(int top) const
- {
- FarMacroValue val(FMVT_STACKSETTOP);
- val.Integer = top;
- SendValue(val);
- }
- void StackPop(int count) const
- {
- FarMacroValue val(FMVT_STACKPOP);
- val.Integer = count;
- SendValue(val);
- }
- void StackPushValue(int pos) const
- {
- FarMacroValue val(FMVT_STACKPUSHVALUE);
- val.Integer = pos;
- SendValue(val);
- }
-
void absFunc() const;
void ascFunc() const;
void atoiFunc() const;
@@ -257,11 +257,28 @@ void FarMacroApi::PushValue(const TVar& Var) const
PushValue(Var.asInteger());
}

-void FarMacroApi::SetField(const FarMacroValue &Key, const FarMacroValue &Value) const
+void FarMacroApi::SetField(const FarMacroValue &Key, const FarMacroValue &Value, int Pos) const
{
SendValue(Key);
SendValue(Value);
- SendValue(FMVT_SETTABLE);
+ SendValue(FarMacroValue(FMVT_SETTABLE, Pos));
+}
+
+int FarMacroApi::StackGetTop() const
+{
+ FarMacroValue val(FMVT_STACKGETTOP); //[IN,OUT]
+ SendValue(val);
+ return val.Integer;
+}
+
+TVar FarMacroApi::GetTable(int pos, const TVar &Key) const
+{
+ pos = pos > 0 ? pos : StackGetTop() + 1 + pos;
+ FarMacroValue Res(FMVT_GETTABLE, pos);
+ PushValue(Key);
+ SendValue(Res);
+ StackPop(1);
+ return Convert2TVar(Res);
}

std::vector<TVar> FarMacroApi::parseParams(size_t Count) const
@@ -271,16 +288,7 @@ std::vector<TVar> FarMacroApi::parseParams(size_t Count) const
Params.reserve(Count);
std::ranges::transform(mData->Values, mData->Values + argNum, std::back_inserter(Params), [](const auto& i)
{
- switch (i.Type)
- {
- case FMVT_INTEGER: return TVar(i.Integer);
- case FMVT_BOOLEAN: return TVar(i.Boolean);
- case FMVT_DOUBLE: return TVar(i.Double);
- case FMVT_STRING: return TVar(i.String);
- case FMVT_POINTER: return TVar(i.Pointer);
- case FMVT_DIALOG: return TVar(static_cast<Dialog*>(i.Pointer));
- default: return TVar();
- }
+ return Convert2TVar(i);
});
Params.resize(Count);
return Params;
@@ -1216,7 +1224,7 @@ void KeyMacro::CallFar(intptr_t CheckCode, FarMacroCall* Data)
api.PushTable();
for (const auto& [Key, Value] : ExtendedData)
{
- api.SetField(Key, Value);
+ api.SetField(Key, Value, -3);
}
return;
}
@@ -1500,6 +1508,9 @@ void FarMacroApi::maxFunc() const
{
const auto Params = parseParams(2);
PushValue(std::max(Params[0], Params[1]));
+//### const auto &tbl = Params[0];
+//### if (tbl.isTable())
+//### PushValue(GetTable(tbl.asInteger(), TVar(L"foo")));
}

// n=mod(n1,n2)
@@ -2542,6 +2553,11 @@ void FarMacroApi::dlggetvalueFunc() const
fgv.Value.Type = FMVT_DIALOG;
fgv.Value.Pointer = Ret.asDialog();
break;
+
+ case TVar::Type::Table:
+ fgv.Value.Type = FMVT_TABLE;
+ fgv.Value.Integer = Ret.asInteger();
+ break;
}

if (Dlg->SendMessage(DN_GETVALUE,Index,&fgv))
diff --git a/far/plugin.hpp b/far/plugin.hpp
index 153877c3a..02e2ad2c0 100644
--- a/far/plugin.hpp
+++ b/far/plugin.hpp
@@ -1519,19 +1519,31 @@ struct FarMacroValue
#endif
;
#ifdef __cplusplus
- FarMacroValue() { Type=FMVT_NIL; }
- FarMacroValue(int v) { Type=FMVT_INTEGER; Integer=v; }
- FarMacroValue(unsigned int v) { Type=FMVT_INTEGER; Integer=v; }
+ FarMacroValue() { Type=FMVT_NIL; }
+ FarMacroValue(int v) { Type=FMVT_INTEGER; Integer=v; }
+ FarMacroValue(unsigned int v) { Type=FMVT_INTEGER; Integer=v; }
FarMacroValue(long long v) { Type=FMVT_INTEGER; Integer=v; }
FarMacroValue(unsigned long long v) { Type=FMVT_INTEGER; Integer=v; }
- FarMacroValue(bool v) { Type=FMVT_BOOLEAN; Boolean=v; }
- FarMacroValue(double v) { Type=FMVT_DOUBLE; Double=v; }
- FarMacroValue(const wchar_t* v) { Type=FMVT_STRING; String=v; }
- FarMacroValue(void* v) { Type=FMVT_POINTER; Pointer=v; }
- FarMacroValue(const char* v) { Type=FMVT_MBSTRING; MBString=v; }
- FarMacroValue(FARMACROVARTYPE tp) { Type=tp; Integer=0; }
- FarMacroValue(const UUID& v) { Type=FMVT_BINARY; Binary.Data=&const_cast<UUID&>(v); Binary.Size=sizeof(UUID); }
- FarMacroValue(FarMacroValue* arr,size_t count) { Type=FMVT_ARRAY; Array.Values=arr; Array.Count=count; }
+ FarMacroValue(bool v) { Type=FMVT_BOOLEAN; Boolean=v; }
+ FarMacroValue(double v) { Type=FMVT_DOUBLE; Double=v; }
+ FarMacroValue(const wchar_t* v) { Type=FMVT_STRING; String=v; }
+ FarMacroValue(void* v) { Type=FMVT_POINTER; Pointer=v; }
+ FarMacroValue(const char* v) { Type=FMVT_MBSTRING; MBString=v; }
+
+ FarMacroValue(FARMACROVARTYPE tp, long long param=0) {
+ Type = tp;
+ Integer = param;
+ }
+ FarMacroValue(const UUID& v) {
+ Type = FMVT_BINARY;
+ Binary.Data = &const_cast<UUID&>(v);
+ Binary.Size = sizeof(UUID);
+ }
+ FarMacroValue(FarMacroValue* arr, size_t count) {
+ Type = FMVT_ARRAY;
+ Array.Values = arr;
+ Array.Count = count;
+ }
#ifdef FAR_USE_INTERNALS
explicit(false) FarMacroValue(const string& v) { Type=FMVT_STRING; String=v.c_str(); }
#endif // END FAR_USE_INTERNALS
diff --git a/far/tvar.cpp b/far/tvar.cpp
index c90251f48..95a7b7fb1 100644
--- a/far/tvar.cpp
+++ b/far/tvar.cpp
@@ -333,6 +333,7 @@ long long TVar::asInteger() const
switch (vType)
{
case Type::Integer:
+ case Type::Table:
case Type::Unknown:
return inum;

@@ -355,6 +356,7 @@ double TVar::asDouble() const
switch (vType)
{
case Type::Integer:
+ case Type::Table:
case Type::Unknown:
return inum;

@@ -403,6 +405,7 @@ bool TVar::isNumber() const
case Type::Unknown:
case Type::Integer:
case Type::Double:
+ case Type::Table:
return true;

case Type::String:
@@ -446,10 +449,12 @@ bool TVar::operator<(const TVar& rhs) const
{
case Type::Unknown:
case Type::Integer:
+ case Type::Table:
switch (rhs.type())
{
case Type::Unknown:
case Type::Integer:
+ case Type::Table:
return asInteger() < rhs.asInteger();

case Type::Double:
@@ -479,6 +484,7 @@ bool TVar::operator<(const TVar& rhs) const
{
case Type::Unknown:
case Type::Integer:
+ case Type::Table:
case Type::Double:
return asDouble() < rhs.asDouble();

diff --git a/far/tvar.hpp b/far/tvar.hpp
index d39aa0a3d..0c43306a9 100644
--- a/far/tvar.hpp
+++ b/far/tvar.hpp
@@ -65,6 +65,7 @@ public:
Double = 3,
Pointer = 4,
Dialog = 5,
+ Table = 6,
};

COPYABLE(TVar);
@@ -97,7 +98,8 @@ public:
bool isInteger() const { return vType == Type::Integer || vType == Type::Unknown; }
bool isDouble() const { return vType == Type::Double; }
bool isPointer() const { return vType == Type::Pointer; }
- bool isDialog() const { return vType == Type::Dialog; }
+ bool isDialog() const { return vType == Type::Dialog; }
+ bool isTable() const { return vType == Type::Table; }
bool isUnknown() const { return vType == Type::Unknown; }

bool isNumber() const;
diff --git a/far/vbuild.m4 b/far/vbuild.m4
index 3a5c1c66c..d4e8d6fba 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6577
+6578
diff --git a/plugins/luamacro/_globalinfo.lua b/plugins/luamacro/_globalinfo.lua
index d8fb6b2f0..f505ffafc 100644
--- a/plugins/luamacro/_globalinfo.lua
+++ b/plugins/luamacro/_globalinfo.lua
@@ -1,6 +1,6 @@
function export.GetGlobalInfo()
return {
- Version = { 3, 0, 0, 897 },
+ Version = { 3, 0, 0, 898 },
MinFarVersion = { 3, 0, 0, 6564 },
Guid = win.Uuid("4EBBEFC8-2084-4B7F-94C0-692CE136894D"),
Title = "LuaMacro",
diff --git a/plugins/luamacro/changelog b/plugins/luamacro/changelog
index eae7f848e..5b7842727 100644
--- a/plugins/luamacro/changelog
+++ b/plugins/luamacro/changelog
@@ -1,3 +1,7 @@
+shmuel 2025-10-25 17:10:58+03:00 - build 898
+
+1. LuaFAR: Add more stack operations to Macro-API engine.
+
shmuel 2025-10-24 20:23:49+03:00 - build 897

1. LuaFAR: add a few stack operations to Macro-API engine.
diff --git a/plugins/luamacro/luafar/lf_exported.c b/plugins/luamacro/luafar/lf_exported.c
index 08b3229fc..289d60c5e 100644
--- a/plugins/luamacro/luafar/lf_exported.c
+++ b/plugins/luamacro/luafar/lf_exported.c
@@ -793,7 +793,7 @@ void PushFarMacroValue(lua_State* L, const struct FarMacroValue* val)
case FMVT_BINARY:
lua_createtable(L,1,0);
lua_pushlstring(L, (char*)val->Value.Binary.Data, val->Value.Binary.Size);
- lua_rawseti(L,-2,1);
+ lua_setfield(L, -2, TKEY_BINARY);
break;

case FMVT_ARRAY:
@@ -841,7 +841,6 @@ static void WINAPI FillFarMacroCall_Callback (void *CallbackData, struct FarMacr
static HANDLE FillFarMacroCall (lua_State* L, int narg)
{
INT64 val64;
- int i;

struct FarMacroCall *fmc = (struct FarMacroCall*)
malloc(sizeof(struct FarMacroCall) + narg*sizeof(struct FarMacroValue));
@@ -852,54 +851,52 @@ static HANDLE FillFarMacroCall (lua_State* L, int narg)
fmc->Callback = FillFarMacroCall_Callback;
fmc->CallbackData = fmc;

- for (i=0; i<narg; i++)
+ for (int i=0; i<narg; i++)
{
- int type = lua_type(L, i-narg);
+ int pos = i - narg;
+ int type = lua_type(L, pos);
+ fmc->Values[i].Type = FMVT_NIL;
+
if (type == LUA_TNUMBER)
{
fmc->Values[i].Type = FMVT_DOUBLE;
- fmc->Values[i].Value.Double = lua_tonumber(L, i-narg);
+ fmc->Values[i].Value.Double = lua_tonumber(L, pos);
}
else if (type == LUA_TBOOLEAN)
{
fmc->Values[i].Type = FMVT_BOOLEAN;
- fmc->Values[i].Value.Boolean = lua_toboolean(L, i-narg);
+ fmc->Values[i].Value.Boolean = lua_toboolean(L, pos);
}
else if (type == LUA_TSTRING)
{
fmc->Values[i].Type = FMVT_STRING;
- fmc->Values[i].Value.String = _wcsdup(check_utf8_string(L, i-narg, NULL));
+ fmc->Values[i].Value.String = _wcsdup(check_utf8_string(L, pos, NULL));
}
else if (type == LUA_TLIGHTUSERDATA)
{
fmc->Values[i].Type = FMVT_POINTER;
- fmc->Values[i].Value.Pointer = lua_touserdata(L, i-narg);
+ fmc->Values[i].Value.Pointer = lua_touserdata(L, pos);
}
else if (type == LUA_TTABLE)
{
- size_t len;
- fmc->Values[i].Type = FMVT_BINARY;
- fmc->Values[i].Value.Binary.Data = (char*)"";
- fmc->Values[i].Value.Binary.Size = 0;
- lua_rawgeti(L, i-narg, 1);
- if (lua_type(L,-1) == LUA_TSTRING && (len=lua_objlen(L,-1)) != 0)
+ lua_getfield(L, pos, TKEY_BINARY);
+ if (lua_type(L,-1) == LUA_TSTRING)
{
+ size_t len;
+ const char *str = lua_tolstring(L, -1, &len);
void* arr = malloc(len);
- memcpy(arr, lua_tostring(L,-1), len);
+ memcpy(arr, str, len);
fmc->Values[i].Value.Binary.Data = arr;
fmc->Values[i].Value.Binary.Size = len;
+ fmc->Values[i].Type = FMVT_BINARY;
}
lua_pop(L,1);
}
- else if (bit64_getvalue(L, i-narg, &val64))
+ else if (bit64_getvalue(L, pos, &val64))
{
fmc->Values[i].Type = FMVT_INTEGER;
fmc->Values[i].Value.Integer = val64;
}
- else
- {
- fmc->Values[i].Type = FMVT_NIL;
- }
}

return (HANDLE)fmc;
diff --git a/plugins/luamacro/luafar/lf_luamacro.c b/plugins/luamacro/luafar/lf_luamacro.c
index 9eafba1bd..2c777a9d2 100644
--- a/plugins/luamacro/luafar/lf_luamacro.c
+++ b/plugins/luamacro/luafar/lf_luamacro.c
@@ -62,13 +62,13 @@ HANDLE Open_Luamacro(lua_State* L, const struct OpenInfo *Info)

if (pcall_msg(L, 2+(int)argc, 2) == 0)
{
- intptr_t ReturnType;
if (!lua_toboolean(L,-2))
{
lua_pop(L,2);
return NULL;
}
- ReturnType = lua_type(L,-2)==LUA_TNUMBER ? lua_tointeger(L,-2) : 1;
+
+ intptr_t ReturnType = lua_type(L,-2)==LUA_TNUMBER ? lua_tointeger(L,-2) : 1;

if (lua_istable(L,-2))
{
@@ -84,74 +84,72 @@ HANDLE Open_Luamacro(lua_State* L, const struct OpenInfo *Info)
else
{
struct MacroPluginReturn* Ret = &om_info->Ret;
- int nargs, idx;

lua_getfield(L,-1,"n");
- nargs = lua_type(L,-1)==LUA_TNUMBER ? (int)lua_tointeger(L,-1) : (int)lua_objlen(L,-2);
+ int nargs = lua_type(L,-1)==LUA_TNUMBER ? (int)lua_tointeger(L,-1) : (int)lua_objlen(L,-2);
lua_pop(L,1);
- if (nargs < 0) nargs = 0;
+ if (nargs < 0)
+ nargs = 0;

InitMPR(L, Ret, (size_t)nargs, ReturnType);

- for(idx=0; idx<nargs; idx++)
+ for(int idx=0; idx<nargs; idx++)
{
- int type;
- INT64 val64;
+ Ret->Values[idx].Type = FMVT_NIL;
lua_rawgeti(L,-1,idx+1);
- type = lua_type(L, -1);

- if (type == LUA_TNUMBER)
- {
- Ret->Values[idx].Type = FMVT_DOUBLE;
- Ret->Values[idx].Value.Double = lua_tonumber(L, -1);
- lua_pop(L,1);
- }
- else if (type == LUA_TSTRING)
- {
- Ret->Values[idx].Type = FMVT_STRING;
- Ret->Values[idx].Value.String = check_utf8_string(L, -1, NULL);
- lua_rawseti(L,-2,idx+1);
- }
- else if (type == LUA_TBOOLEAN)
+ switch (lua_type(L, -1))
{
- Ret->Values[idx].Type = FMVT_BOOLEAN;
- Ret->Values[idx].Value.Boolean = lua_toboolean(L, -1);
- lua_pop(L,1);
- }
- else if (type == LUA_TLIGHTUSERDATA)
- {
- Ret->Values[idx].Type = FMVT_POINTER;
- Ret->Values[idx].Value.Pointer = lua_touserdata(L, -1);
- lua_rawseti(L,-2,idx+1);
- }
- else if (type == LUA_TTABLE)
- {
- Ret->Values[idx].Type = FMVT_BINARY;
- lua_rawgeti(L,-1,1);
- if (lua_type(L,-1) == LUA_TSTRING)
- {
- Ret->Values[idx].Value.Binary.Data = (char*)lua_tostring(L,-1);
- Ret->Values[idx].Value.Binary.Size = lua_objlen(L,-1);
- lua_rawseti(L,-3,idx+1);
- }
- else
- {
- Ret->Values[idx].Value.Binary.Data = (char*)"";
- Ret->Values[idx].Value.Binary.Size = 0;
+ case LUA_TNUMBER:
+ Ret->Values[idx].Type = FMVT_DOUBLE;
+ Ret->Values[idx].Value.Double = lua_tonumber(L, -1);
lua_pop(L,1);
- }
- lua_pop(L,1);
- }
- else if (bit64_getvalue(L, -1, &val64))
- {
- Ret->Values[idx].Type = FMVT_INTEGER;
- Ret->Values[idx].Value.Integer = val64;
- lua_pop(L,1);
- }
- else
- {
- Ret->Values[idx].Type = FMVT_NIL;
- lua_pop(L,1);
+ break;
+
+ case LUA_TSTRING:
+ Ret->Values[idx].Type = FMVT_STRING;
+ Ret->Values[idx].Value.String = check_utf8_string(L, -1, NULL);
+ lua_rawseti(L,-2,idx+1);
+ break;
+
+ case LUA_TBOOLEAN:
+ Ret->Values[idx].Type = FMVT_BOOLEAN;
+ Ret->Values[idx].Value.Boolean = lua_toboolean(L, -1);
+ lua_pop(L,1);
+ break;
+
+ case LUA_TLIGHTUSERDATA:
+ Ret->Values[idx].Type = FMVT_POINTER;
+ Ret->Values[idx].Value.Pointer = lua_touserdata(L, -1);
+ lua_rawseti(L,-2,idx+1);
+ break;
+
+ case LUA_TTABLE:
+ lua_getfield(L, -1, TKEY_BINARY);
+ if (lua_type(L, -1) == LUA_TSTRING)
+ {
+ Ret->Values[idx].Type = FMVT_BINARY;
+ Ret->Values[idx].Value.Binary.Data = (char*)lua_tostring(L,-1);
+ Ret->Values[idx].Value.Binary.Size = lua_objlen(L,-1);
+ lua_rawseti(L,-3,idx+1);
+ }
+ lua_pop(L,1);
+ break;
+
+ default:
+ INT64 val64;
+ if (bit64_getvalue(L, -1, &val64))
+ {
+ Ret->Values[idx].Type = FMVT_INTEGER;
+ Ret->Values[idx].Value.Integer = val64;
+ lua_pop(L,1);
+ }
+ else
+ {
+ Ret->Values[idx].Type = FMVT_NIL;
+ lua_pop(L,1);
+ }
+ break;
}
}

@@ -181,6 +179,8 @@ static void WINAPI MacroCallFarCallback(void *Data, struct FarMacroValue *Val, s
lua_State *L = cbdata->L;
int top = lua_gettop(L);
int stack_avail = cbdata->max_stack - top;
+ int param = (int)Val->Value.Integer;
+ int pos = param >= 0 ? param : top + 1 + param;

switch(Val->Type)
{
@@ -190,38 +190,36 @@ static void WINAPI MacroCallFarCallback(void *Data, struct FarMacroValue *Val, s
break;

case FMVT_SETTABLE:
- if (lua_istable(L, -3))
- lua_settable(L, -3);
+ if (pos >= 1 && pos <= top-2 && lua_istable(L, pos))
+ lua_settable(L, pos);
break;

case FMVT_GETTABLE:
- if (stack_avail > 0)
+ if (pos >= 1 && pos <= top-1 && lua_istable(L, pos))
{
- lua_gettable(L, -3);
+ lua_gettable(L, pos);
ConvertLuaValue(L, -1, Val);
}
break;

case FMVT_STACKPOP:
- int param = (int)Val->Value.Integer;
if (param > 0 && (top - param) >= cbdata->start_stack)
lua_pop(L, param);
break;

case FMVT_STACKGETTOP:
Val->Type = FMVT_INTEGER;
- Val->Value.Integer = lua_gettop(L);
+ Val->Value.Integer = top;
break;

case FMVT_STACKSETTOP:
- int val = (int)Val->Value.Integer;
- if (val >= cbdata->start_stack && val <= cbdata->max_stack)
- lua_settop(L, val);
+ if (pos >= cbdata->start_stack && pos <= cbdata->max_stack)
+ lua_settop(L, pos);
break;

case FMVT_STACKPUSHVALUE:
- if (stack_avail > 0)
- lua_pushvalue(L, (int)Val->Value.Integer);
+ if (stack_avail > 0 && pos >= 1 && pos <= top)
+ lua_pushvalue(L, pos);
break;

default:
diff --git a/plugins/luamacro/luafar/lf_service.c b/plugins/luamacro/luafar/lf_service.c
index edd757592..08af0764b 100644
--- a/plugins/luamacro/luafar/lf_service.c
+++ b/plugins/luamacro/luafar/lf_service.c
@@ -456,27 +456,18 @@ void ConvertLuaValue (lua_State *L, int pos, struct FarMacroValue *target)
}
else if (type == LUA_TTABLE)
{
- lua_rawgeti(L,pos,1);
- if (lua_type(L,-1) == LUA_TSTRING)
+ lua_getfield(L, pos, TKEY_BINARY);
+ if (lua_type(L, -1) == LUA_TSTRING)
{
target->Type = FMVT_BINARY;
target->Value.Binary.Data = (void*)lua_tolstring(L, -1, &target->Value.Binary.Size);
}
- lua_pop(L,1);
-// lua_rawgeti(L,pos,0);
-// if (lua_type(L,-1) == LUA_TSTRING && !strcmp("binary", lua_tostring(L,-1)))
-// {
-// lua_rawgeti(L,pos,1);
-// target->Type = FMVT_BINARY;
-// target->Value.Binary.Size = 0;
-// target->Value.Binary.Data = (void*)lua_tolstring(L, -1, &target->Value.Binary.Size);
-// lua_pop(L,1);
-// }
-// else
-// {
-// target->Type = FMVT_TABLE;
-// }
-// lua_pop(L,1);
+ else
+ {
+ target->Type = FMVT_TABLE;
+ target->Value.Integer = pos;
+ }
+ lua_pop(L, 1);
}
else if (type == LUA_TBOOLEAN)
{
diff --git a/plugins/luamacro/luafar/lf_service.h b/plugins/luamacro/luafar/lf_service.h
index c3d22a9e9..05a3c6a5c 100644
--- a/plugins/luamacro/luafar/lf_service.h
+++ b/plugins/luamacro/luafar/lf_service.h
@@ -1,6 +1,8 @@
#ifndef LUAFAR_SERVICE_H
#define LUAFAR_SERVICE_H

+#define TKEY_BINARY "__binary"
+
UINT64 OptFlags(lua_State* L, int pos, UINT64 dflt);
UINT64 GetFlagCombination(lua_State *L, int pos, int *success);
UINT64 GetFlagsFromTable(lua_State *L, int pos, const char* key);
diff --git a/plugins/luamacro/luafar/lf_version.h b/plugins/luamacro/luafar/lf_version.h
index 1a56b299b..efd070c58 100644
--- a/plugins/luamacro/luafar/lf_version.h
+++ b/plugins/luamacro/luafar/lf_version.h
@@ -1,3 +1,3 @@
#include <farversion.hpp>

-#define PLUGIN_BUILD 897
+#define PLUGIN_BUILD 898
diff --git a/plugins/luamacro/macrotest.lua b/plugins/luamacro/macrotest.lua
index 35918a8d9..e38bad5ea 100644
--- a/plugins/luamacro/macrotest.lua
+++ b/plugins/luamacro/macrotest.lua
@@ -45,6 +45,7 @@ local MT = {} -- "macrotest", this module
local F = far.Flags
local band, bor, bnot = bit64.band, bit64.bor, bit64.bnot
local luamacroId="4ebbefc8-2084-4b7f-94c0-692ce136894d" -- LuaMacro plugin GUID
+local TKEY_BINARY = "__binary"

local function pack (...)
return { n=select("#",...), ... }
@@ -1419,8 +1420,10 @@ function MT.test_Plugin()

local function test (func, N) -- Plugin.Call, Plugin.SyncCall: test arguments and returns
local i1 = bit64.new("0x8765876587658765")
- local r1,r2,r3,r4,r5 = func(luamacroId, "argtest", "foo", i1, -2.34, false, {"foo\0bar"})
- assert(r1=="foo" and r2==i1 and r3==-2.34 and r4==false and type(r5)=="table" and r5[1]=="foo\0bar")
+ local a1,a2,a3,a4,a5 = "foo", i1, -2.34, false, {[TKEY_BINARY]="foo\0bar"}
+ local r1,r2,r3,r4,r5 = func(luamacroId, "argtest", a1,a2,a3,a4,a5)
+ assert(r1==a1 and r2==a2 and r3==a3 and r4==a4
+ and type(r5)=="table" and r5[TKEY_BINARY]==a5[TKEY_BINARY])

local src = {}
for k=1,N do src[k]=k end
@@ -1439,7 +1442,7 @@ local function test_far_MacroExecute()
5,
nil,
bit64.new("0x8765876587658765"),
- {"bar"})
+ {[TKEY_BINARY] = "bar"})
assert_table (t)
assert_eq (t.n, 6)
assert_eq (t[1], "foo")
@@ -1447,7 +1450,7 @@ local function test_far_MacroExecute()
assert_eq (t[3], 5)
assert_nil (t[4])
assert_eq (t[5], bit64.new("0x8765876587658765"))
- assert_eq (assert_table(t[6])[1], "bar")
+ assert_eq (assert_table(t[6])[TKEY_BINARY], "bar")
end
test("return ...", nil)
test("return ...", "KMFLAGS_LUA")


Reply all
Reply to author
Forward
0 new messages