File indexing completed on 2024-04-28 11:20:31

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 }