// 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" nv::string64 nlua_typecontent( lua_State* L, int idx ) { int type = lua_type( L, idx ); switch ( type ) { case LUA_TNONE : return nv::string64( "NONE" ); case LUA_TNIL : return nv::string64( "NIL" ); case LUA_TBOOLEAN : return nv::string64( lua_toboolean( L, idx ) == 0 ? "false" : "true" ); case LUA_TSTRING : return nv::string64( nlua_tostringview( L, idx ) ); case LUA_TTABLE : return nv::string64( "TABLE" ); case LUA_TFUNCTION : return nv::string64( "FUNCTION" ); case LUA_TTHREAD : return nv::string64( "THREAD" ); default : break; } if ( type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA ) { nv::string64 buffer; buffer.append( nv::uint64( lua_touserdata( L, idx ) ) ); return buffer; } else if ( type == LUA_TNUMBER ) { nv::string64 buffer; buffer.append( nv::uint64( lua_touserdata( L, idx ) ) ); return buffer; } return nv::string64( "UNKNOWN!" ); } void nlua_pushreversed( lua_State *L, int index ) { index = nlua_absindex( L, index ); int len = static_cast( nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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 = nlua_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; } void * nlua_testudata( lua_State *L, int ud, const char *tname ) { void *p = lua_touserdata( L, ud ); if ( p != NULL ) { if ( lua_getmetatable( L, ud ) ) { luaL_getmetatable( L, tname ); if ( !lua_rawequal( L, -1, -2 ) ) p = NULL; lua_pop( L, 2 ); return p; } } return NULL; } void nlua_setmetatable( lua_State *L, const char *tname ) { int only_works_for_51; luaL_getmetatable( L, tname ); lua_setmetatable( L, -2 ); } void nlua_requiref( lua_State *L, const char *modname, lua_CFunction openf, int glb ) { int only_works_for_51; lua_pushcfunction( L, openf ); lua_pushstring( L, modname ); lua_call( L, 1, 1 ); if ( glb != 0 ) { lua_pushvalue( L, LUA_GLOBALSINDEX ); lua_pushvalue( L, -2 ); lua_setfield( L, -2, modname ); lua_pop( L, 1 ); } } int nlua_rawlen( lua_State* L, int index ) { return lua_objlen( L, index ); } void nlua_pushglobaltable( lua_State* L ) { int only_works_for_51; lua_pushvalue( L, LUA_GLOBALSINDEX ); }