File indexing completed on 2023-10-01 07:35:49
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2014 Lucas Hermann Negri <lucashnegri@gmail.com> 0004 */ 0005 0006 #include "luahelper.h" 0007 #include "luakeywords.h" 0008 0009 #include <lua.hpp> 0010 #include <QRegularExpression> 0011 #include <QString> 0012 0013 QString luahelper_tostring(lua_State* L, int idx) 0014 { 0015 lua_getglobal(L, "tostring"); 0016 lua_pushvalue(L, idx - 1); // tostring is on the top now! 0017 lua_call(L, 1, 1); 0018 QString str = QString::fromUtf8(lua_tostring(L, -1)); 0019 lua_pop(L, 1); 0020 return str; 0021 } 0022 0023 QString luahelper_dostring(lua_State* L, const QString& str) 0024 { 0025 const QByteArray arr = str.toUtf8(); 0026 bool err = ( luaL_loadbuffer(L, arr.data(), arr.size(), nullptr) || lua_pcall (L, 0, LUA_MULTRET, 0) ); 0027 QString ret; 0028 0029 if(err) 0030 { 0031 ret = QString::fromUtf8(lua_tostring(L, -1)); 0032 lua_pop(L, 1); 0033 } 0034 0035 return ret; 0036 } 0037 0038 QString luahelper_getprinted(lua_State* L) 0039 { 0040 luaL_loadstring(L, "return table.concat(__cantor, '\\n')"); 0041 QString printed; 0042 0043 if(!lua_pcall(L, 0, 1, 0) ) 0044 printed = QString::fromUtf8(lua_tostring(L, -1)); 0045 0046 lua_pop(L, 1); 0047 0048 luaL_loadstring(L, "__cantor = {}"); // survives a __cantor = nil! 0049 if( lua_pcall(L, 0, 0, 0) ) lua_pop(L, 1); 0050 0051 return printed; 0052 } 0053 0054 static void luahelper_getkeys(lua_State* L, QStringList& list, const QString& prefix = QLatin1String("")) 0055 { 0056 if(lua_type(L, -1) == LUA_TTABLE) 0057 { 0058 // ok, its a table, iterate the keys 0059 lua_pushnil(L); 0060 while (lua_next(L, -2) != 0) 0061 { 0062 if(lua_type(L, -2) == LUA_TSTRING) 0063 { 0064 QString key = QString::fromUtf8(lua_tostring(L, -2)); 0065 list << prefix + key; 0066 } 0067 lua_pop(L, 1); 0068 } 0069 } 0070 } 0071 0072 QStringList luahelper_completion(lua_State* L, const QString& name) 0073 { 0074 int top = lua_gettop(L); 0075 0076 QStringList list; 0077 0078 QStringList sections = name.split(QRegularExpression(QStringLiteral("\\.|:"))); 0079 QString table, prefix; 0080 0081 if(sections.size() == 1) // global table 0082 { 0083 list = LuaKeywords::instance()->keywords(); 0084 table = QLatin1String("_G"); 0085 } 0086 else 0087 { 0088 if(sections.size() == 2) 0089 { 0090 table = sections.first(); // table.key 0091 prefix = name.left(sections.first().length() + 1); // table. 0092 } 0093 } 0094 0095 if(!table.isEmpty()) 0096 { 0097 // get keys from the table 0098 QByteArray arr = table.toUtf8(); 0099 lua_getglobal(L, arr.data()); 0100 luahelper_getkeys(L, list, prefix); 0101 0102 // get keys from the metatable.__index 0103 if( lua_getmetatable(L, -1) ) 0104 { 0105 lua_getfield (L, -1, "__index"); 0106 luahelper_getkeys(L, list, prefix); 0107 lua_pop(L, 2); 0108 // pop metatable and metatable.__index 0109 } 0110 0111 lua_pop(L, 1); // pop table 0112 } 0113 0114 lua_settop(L, top); 0115 0116 return list; 0117 }