"Fossies" - the Fresh Open Source Software Archive

Member "highlight-3.57-x64/src/core/Diluculum/LuaUtils.cpp" (12 May 2020, 7330 Bytes) of package /windows/www/highlight-3.57-x64.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /******************************************************************************\
    2 * LuaUtils.cpp                                                                 *
    3 * Some utilities related to Lua.                                               *
    4 *                                                                              *
    5 *                                                                              *
    6 * Copyright (C) 2005-2013 by Leandro Motta Barros.                             *
    7 *                                                                              *
    8 * Permission is hereby granted, free of charge, to any person obtaining a copy *
    9 * of this software and associated documentation files (the "Software"), to     *
   10 * deal in the Software without restriction, including without limitation the   *
   11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  *
   12 * sell copies of the Software, and to permit persons to whom the Software is   *
   13 * furnished to do so, subject to the following conditions:                     *
   14 *                                                                              *
   15 * The above copyright notice and this permission notice shall be included in   *
   16 * all copies or substantial portions of the Software.                          *
   17 *                                                                              *
   18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   *
   19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,     *
   20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE *
   21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER       *
   22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      *
   23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
   24 * IN THE SOFTWARE.                                                             *
   25 \******************************************************************************/
   26 
   27 #include <cstring>
   28 #include <Diluculum/LuaUtils.hpp>
   29 #include <Diluculum/LuaExceptions.hpp>
   30 #include <boost/lexical_cast.hpp>
   31 #include "InternalUtils.hpp"
   32 
   33 
   34 namespace Diluculum
   35 {
   36    // - ToLuaValue -------------------------------------------------------------
   37    LuaValue ToLuaValue (lua_State* state, int index)
   38    {
   39       switch (lua_type (state, index))
   40       {
   41          case LUA_TNIL:
   42             return Nil;
   43 
   44          case LUA_TNUMBER:
   45             return lua_tonumber (state, index);
   46 
   47          case LUA_TBOOLEAN:
   48             // this (instead of a cast) avoids a warning on Visual C++
   49             return lua_toboolean (state, index) != 0;
   50 
   51          case LUA_TSTRING:
   52             return std::string(lua_tostring (state, index),
   53 #if LUA_VERSION_NUM >= 502
   54                 lua_rawlen(state, index));
   55 #else
   56                 lua_objlen(state, index));
   57 #endif
   58          case LUA_TUSERDATA:
   59          {
   60             void* addr = lua_touserdata (state, index);
   61 #if LUA_VERSION_NUM >= 502
   62         size_t size = lua_rawlen(state, index);
   63 #else
   64             size_t size = lua_objlen (state, index);
   65 #endif
   66             LuaUserData ud (size);
   67             memcpy (ud.getData(), addr, size);
   68             return ud;
   69          }
   70 
   71          case LUA_TTABLE:
   72          {
   73             // Make the index positive if necessary (using a negative index here
   74             // will be *bad*, because the stack will be changed in the
   75             // 'lua_next()' and a negative index will mess everything).
   76             if (index < 0)
   77                index = lua_gettop(state) + index + 1;
   78 
   79             // Traverse the table adding the key/value pairs to 'ret'
   80             LuaValueMap ret;
   81 
   82             lua_pushnil (state);
   83             while (lua_next (state, index) != 0)
   84             {
   85                ret[ToLuaValue (state, -2)] = ToLuaValue (state, -1);
   86                lua_pop (state, 1);
   87             }
   88 
   89             // Alright, return the result
   90             return ret;
   91          }
   92 
   93          case LUA_TFUNCTION:
   94          {
   95             if (lua_iscfunction (state, index))
   96             {
   97                return lua_tocfunction (state, index);
   98             }
   99             else
  100             {
  101                LuaFunction func("", 0);
  102                lua_pushvalue (state, index);
  103 
  104 #if LUA_VERSION_NUM >= 503
  105                lua_dump(state, Impl::LuaFunctionWriter, &func, 0);
  106 #else
  107                lua_dump(state, Impl::LuaFunctionWriter, &func);
  108 #endif
  109                lua_pop(state, 1);
  110                return func;
  111             }
  112          }
  113 
  114          default:
  115          {
  116             throw LuaTypeError(
  117                ("Unsupported type found in call to 'ToLuaValue()': "
  118                 + boost::lexical_cast<std::string>(lua_type (state, index))
  119                 + " (typename: \'" + luaL_typename (state, index)
  120                 + "')").c_str());
  121          }
  122       }
  123    }
  124 
  125 
  126 
  127    // - PushLuaValue -----------------------------------------------------------
  128    void PushLuaValue (lua_State* state, const LuaValue& value)
  129    {
  130       switch (value.type())
  131       {
  132          case LUA_TNIL:
  133             lua_pushnil (state);
  134             break;
  135 
  136          case LUA_TNUMBER:
  137             lua_pushnumber (state, value.asNumber());
  138             break;
  139 
  140          case LUA_TSTRING:
  141          {
  142             const std::string& tmp = value.asString();
  143             lua_pushlstring (state, tmp.c_str(), tmp.length());
  144             break;
  145          }
  146 
  147          case LUA_TBOOLEAN:
  148             lua_pushboolean (state, value.asBoolean());
  149             break;
  150 
  151          case LUA_TUSERDATA:
  152          {
  153             size_t size = value.asUserData().getSize();
  154             void* addr = lua_newuserdata (state, size);
  155             memcpy (addr, value.asUserData().getData(), size);
  156             break;
  157          }
  158 
  159          case LUA_TTABLE:
  160          {
  161             lua_newtable (state);
  162 
  163             typedef LuaValueMap::const_iterator iter_t;
  164             const LuaValueMap table = value.asTable();
  165             for (iter_t p = table.begin(); p != table.end(); ++p)
  166             {
  167                if (p->first != Nil) // Ignore 'Nil'-indexed entries
  168                {
  169                   PushLuaValue (state, p->first);
  170                   PushLuaValue (state, p->second);
  171                   lua_settable (state, -3);
  172                }
  173             }
  174 
  175             break;
  176          }
  177 
  178          case LUA_TFUNCTION:
  179          {
  180             const LuaFunction& f = value.asFunction();
  181             if (f.isCFunction())
  182             {
  183                lua_pushcfunction (state, f.getCFunction());
  184             }
  185             else
  186             {
  187                LuaFunction* pf = const_cast<LuaFunction*>(&f); // yikes!
  188                pf->setReaderFlag (false);
  189                int status = lua_load (state, Impl::LuaFunctionReader, pf,
  190 #if LUA_VERSION_NUM >= 502
  191                                       "Diluculum Lua chunk", NULL);
  192 #else
  193                                       "Diluculum Lua chunk");
  194 #endif
  195                Impl::ThrowOnLuaError (state, status);
  196             }
  197             break;
  198          }
  199 
  200          default:
  201          {
  202             throw LuaTypeError(
  203                ("Unsupported type found in call to 'PushLuaValue()': "
  204                 + boost::lexical_cast<std::string>(value.type())
  205                 + " (typename: \'" + value.typeName() + "')").c_str());
  206          }
  207       }
  208    }
  209 
  210 } // namespace Diluculum