// Copyright (C) 2012-2015 ChaosForge Ltd // http://chaosforge.org/ // // This file is part of Nova libraries. // For conditions of distribution and use, see copying.txt file in root folder. #include "nv/lua/lua_raw.hh" #include "nv/stl/string.hh" std::string nlua_typecontent( lua_State* L, int idx ) { int type = lua_type( L, idx ); switch ( type ) { case LUA_TNONE : return "NONE"; case LUA_TNIL : return "NIL"; case LUA_TBOOLEAN : return lua_toboolean( L, idx ) == 0 ? "false" : "true"; //case LUA_TLIGHTUSERDATA : return std::to_string( nv::uint64( lua_touserdata( L, idx ) ) ); //case LUA_TNUMBER : return std::to_string( lua_tonumber( L, idx ) ); case LUA_TSTRING : return lua_tostring( L, idx ); case LUA_TTABLE : return "TABLE"; case LUA_TFUNCTION : return "FUNCTION"; // case LUA_TUSERDATA : return std::to_string( nv::uint64( lua_touserdata( L, idx ) ) ); case LUA_TTHREAD : return "THREAD"; default : break; } char buffer[64]; if ( type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA ) { size_t l = nv::uint64_to_buffer( nv::uint64( lua_touserdata( L, idx ) ), buffer ); return std::string( buffer, l ); } else if ( type == LUA_TNUMBER ) { size_t l = nv::f64_to_buffer( lua_tonumber( L, idx ), buffer ); return std::string( buffer, l ); } return "UNKNOWN!"; } void nlua_pushreversed( lua_State *L, int index ) { index = lua_absindex( L, index ); int len = static_cast( lua_rawlen( L, index ) ); int i = len; lua_createtable( L, len, 0 ); while ( i != 0 ) { lua_rawgeti( L, index, i ); lua_rawseti( L, -2, len-i+1 ); i--; } } void nlua_shallowcopy( lua_State *L, int index ) { index = lua_absindex( L, index ); lua_createtable( L, 0, 0 ); lua_pushnil( L ); while ( lua_next( L, index ) != 0 ) { lua_pushvalue( L, -2 ); lua_insert( L, -2 ); lua_settable( L, -4 ); } } void nlua_shallowicopy( lua_State *L, int index ) { index = lua_absindex( L, index ); lua_createtable( L, 0, 0 ); int i = 0; for(;;) { i++; lua_rawgeti( L, 1, i ); if ( lua_isnil( L, -1 ) ) { lua_pop( L, 1 ); break; } lua_rawseti( L, 2, i ); }; } void nlua_shallowmerge( lua_State *L, int index ) { index = lua_absindex( L, index ); lua_pushnil( L ); while( lua_next( L, index ) != 0 ) { lua_pushvalue( L, -2 ); lua_insert( L, -2 ); lua_rawset( L, -4 ); } } void nlua_deepcopy( lua_State *L, int index ) { index = lua_absindex( L, index ); lua_createtable( L, 0, 0 ); lua_pushnil( L ); while ( lua_next( L, index ) != 0 ) { if ( lua_istable( L, -1 ) ) { nlua_deepcopy( L, -1 ); lua_insert( L, -2 ); lua_pop( L, 1 ); } lua_pushvalue( L, -2 ); lua_insert( L, -2 ); lua_settable( L, -4 ); } } void nlua_toset( lua_State *L, int index ) { index = lua_absindex( L, index ); lua_createtable( L, 0, 0 ); int i = 0; for(;;) { i++; lua_rawgeti( L, index, i ); if ( lua_isnil( L, -1 ) ) { lua_pop( L, 1 ); break; } lua_pushboolean( L, true ); lua_rawset( L, -3 ); }; } void nlua_tokeyset( lua_State *L, int index ) { index = lua_absindex( L, index ); lua_createtable( L, 0, 0 ); lua_pushnil( L ); while ( lua_next( L, index ) != 0 ) { lua_pushvalue( L, -2 ); lua_pushboolean( L, true ); lua_settable( L, -5 ); lua_pop( L, 1 ); } } void nlua_register( lua_State *L, const char* fname, lua_CFunction func, int index ) { index = lua_absindex( L, index ); lua_pushstring( L, fname ); lua_pushcfunction( L, func ); lua_rawset( L, index ); } void nlua_register( lua_State *L, const luaL_Reg *l, int index ) { index = lua_absindex( L, index ); for (; l->name != NULL; l++) { lua_pushstring( L, l->name ); lua_pushcfunction( L, l->func ); lua_rawset( L, index ); } } void nlua_register( lua_State *L, const char* lname, const char* fname, lua_CFunction func ) { lua_getglobal( L, lname ); if ( !lua_istable( L, -1 ) ) { lua_pop( L, 1 ); lua_createtable( L, 0, 0 ); nlua_register( L, fname, func, -1 ); lua_setglobal( L, lname ); return; } nlua_register( L, fname, func, -1 ); lua_pop( L, 1 ); } void nlua_register( lua_State *L, const char* lname, const luaL_Reg *l ) { lua_getglobal( L, lname ); if ( !lua_istable( L, -1 ) ) { lua_pop( L, 1 ); lua_createtable( L, 0, 0 ); nlua_register( L, l, -1 ); lua_setglobal( L, lname ); return; } nlua_register( L, l, -1 ); lua_pop( L, 1 ); } void nlua_toflags( lua_State *L, int index, nv::uint8* data, nv::uint32 count ) { index = lua_absindex( L, index ); nv::uint32 flag; if ( lua_istable( L, index ) ) { lua_pushnil( L ); while ( lua_next( L, index ) != 0 ) { if ( lua_type( L, -1 ) == LUA_TBOOLEAN ) flag = static_cast< nv::uint32 >( lua_tointeger( L ,-2 ) ); else flag = static_cast< nv::uint32 >( lua_tointeger( L ,-1 ) ); lua_pop( L, 1 ); if ( flag < count ) { data[ flag / 8 ] |= ( 1 << static_cast< nv::uint8 >( flag % 8 ) ); } } } } void nlua_toflags_set( lua_State *L, int index, nv::uint8* data, nv::uint32 count ) { index = lua_absindex( L, index ); nv::uint32 flag; if ( lua_istable( L, index ) ) { lua_pushnil( L ); while ( lua_next( L, index ) != 0 ) { flag = static_cast< nv::uint32 >( lua_tointeger( L ,-2 ) ); lua_pop( L, 1 ); if ( flag < count ) { data[ flag / 8 ] |= ( 1 << static_cast< nv::uint8 >( flag % 8 ) ); } } } } void nlua_toflags_array( lua_State *L, int index, nv::uint8* data, nv::uint32 count ) { index = lua_absindex( L, index ); nv::uint32 flag; if ( lua_istable( L, index ) ) { lua_pushnil( L ); while ( lua_next( L, index ) != 0 ) { flag = static_cast< nv::uint32 >( lua_tointeger( L ,-1 ) ); lua_pop( L, 1 ); if ( flag < count ) { data[ flag / 8 ] |= ( 1 << static_cast< nv::uint8 >( flag % 8 ) ); } } } } nv::vector nlua_tobytearray( lua_State *L, int index ) { index = lua_absindex( L, index ); nv::vector result; if ( lua_istable( L, index ) ) { lua_pushnil( L ); while ( lua_next( L, index ) != 0 ) { result.push_back( static_cast( lua_tointeger( L, -1 ) ) ); lua_pop( L, 1 ); } } return result; }