Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RunStringEx breaking paths for includes #4

Merged
merged 4 commits into from
Nov 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions includes/modules/require.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ local function loadfilemodule(name, file_path)
end
end

return value
return value, errstr
end

local function loadlibmodule(name, file_path, entrypoint_name, isgmodmodule)
Expand Down Expand Up @@ -135,11 +135,13 @@ function require(name)

local messages = {""}
local loader = nil
local luapath = nil

for _, searcher in ipairs(package.loaders) do
local result = searcher(name)
local result, path = searcher(name)
if type(result) == "function" then
loader = result
luapath = path
break
elseif type(result) == "string" then
messages[#messages + 1] = result
Expand All @@ -150,8 +152,17 @@ function require(name)
error("module '" .. name .. "' not found: " .. table.concat(messages), 2)
else
package.loaded[name] = sentinel

if luapath ~= nil then
PushLuaPath(luapath)
end

local result = loader(name)

if luapath ~= nil then
PopLuaPath()
end

if result ~= nil then
package.loaded[name] = result
end
Expand Down
5 changes: 1 addition & 4 deletions projects/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ newoption({
})

local gmcommon = _OPTIONS.gmcommon or os.getenv("GARRYSMOD_COMMON")
if gmcommon == nil then
error("you didn't provide a path to your garrysmod_common (https://github.com/danielga/garrysmod_common) directory")
end

assert(gmcommon ~= nil, "you didn't provide a path to your garrysmod_common (https://github.com/danielga/garrysmod_common) directory")
include(gmcommon)

CreateWorkspace({name = "require.core", abi_compatible = true})
Expand Down
19 changes: 10 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# gmod_require
# gmod\_require

Modules for Garry's Mod for obtaining pointers to functions inside of modules (specially useful for loading Lua only modules).
Modules for Garry's Mod for obtaining pointers to functions inside of modules (specially useful for loading Lua only modules).

## Info
## Compiling

This project is composed by the Lua modules (in includes/modules) and the internal (binary) module (gm_require.core).
The Lua files go into lua/includes/modules (just copy includes from this repo onto lua) and the binary module goes into lua/bin.
The only supported compilation platform for this project on Windows is **Visual Studio 2017** on **release** mode.
On Linux, everything should work fine as is, on **release** mode.
For Mac OSX, any **Xcode (using the GCC compiler)** version *MIGHT* work as long as the **Mac OSX 10.7 SDK** is used, on **release** mode.
These restrictions are not random; they exist because of ABI compatibility reasons.
If stuff starts erroring or fails to work, be sure to check the correct line endings (\n and such) are present in the files for each OS.

Mac was not tested at all (sorry but I'm poor).
## Requirements

If stuff starts erroring or fails to work, be sure to check the correct line endings (\n and such) are present in the files for each OS.

This project requires [garrysmod_common][1], a framework to facilitate the creation of compilations files (Visual Studio, make, XCode, etc). Simply set the environment variable 'GARRYSMOD_COMMON' or the premake option 'gmcommon' to the path of your local copy of [garrysmod_common][1].
This project requires [garrysmod\_common][1], a framework to facilitate the creation of compilations files (Visual Studio, make, XCode, etc). Simply set the environment variable '**GARRYSMOD\_COMMON**' or the premake option '**gmcommon**' to the path of your local copy of [garrysmod\_common][1].

[1]: https://github.com/danielga/garrysmod_common
73 changes: 70 additions & 3 deletions source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ static SourceSDK::FactoryLoader lua_shared_loader(
"lua_shared", false, IS_SERVERSIDE, "garrysmod/bin/" );
static GarrysMod::Lua::ILuaShared *lua_shared = nullptr;

static const size_t maximum_path_pushes = 100000;
static size_t pushed_paths = 0;

static int32_t PushError( GarrysMod::Lua::ILuaBase *LUA, int idxError, const char *reason )
{
if( idxError < 0 )
Expand Down Expand Up @@ -155,15 +158,37 @@ LUA_FUNCTION_STATIC( loadfile )

auto lua = static_cast<GarrysMod::Lua::ILuaInterface *>( LUA );

auto file = lua_shared->LoadFile( path, lua->GetPathID( ), lua->IsClient( ), true );
GarrysMod::Lua::File *file = nullptr;

std::string newpath;
const char *relpath = lua->GetPath( );
if( relpath != nullptr )
{
newpath = relpath;
newpath += '/';
newpath += path;

file = lua_shared->LoadFile( newpath.c_str( ), lua->GetPathID( ), lua->IsClient( ), true );
}

if( file == nullptr )
{
newpath = path;

file = lua_shared->LoadFile( path, lua->GetPathID( ), lua->IsClient( ), true );
}

if( file == nullptr )
{
LUA->PushFormattedString( "cannot open %s: No such file or directory", path );
return PushError( LUA, -1, "open_fail" );
}

const char *contents = file->contents.c_str( );
if( !lua->RunStringEx( "", path, contents, false, false, false, false ) )
lua->PushPath( newpath.c_str( ) );
const bool success = lua->RunStringEx( file->name.c_str( ), "", file->contents.c_str( ),
false, false, false, false );
lua->PopPath( );
if( !success )
return PushError( LUA, -1, "load_fail" );

if( hasenv )
Expand All @@ -172,6 +197,36 @@ LUA_FUNCTION_STATIC( loadfile )
LUA->SetFEnv( -2 );
}

LUA->PushString( newpath.c_str( ) );
return 2;
}

LUA_FUNCTION_STATIC( PushLuaPath )
{
if( pushed_paths >= maximum_path_pushes )
{
LUA->PushBool( false );
return 1;
}

++pushed_paths;
const char *path = LUA->CheckString( 1 );
static_cast<GarrysMod::Lua::ILuaInterface *>( LUA )->PushPath( path );
LUA->PushBool( true );
return 1;
}

LUA_FUNCTION_STATIC( PopLuaPath )
{
if( pushed_paths == 0 )
{
LUA->PushBool( false );
return 1;
}

--pushed_paths;
static_cast<GarrysMod::Lua::ILuaInterface *>( LUA )->PopPath( );
LUA->PushBool( true );
return 1;
}

Expand All @@ -188,6 +243,12 @@ GMOD_MODULE_OPEN( )
LUA->PushCFunction( loadfile );
LUA->SetField( GarrysMod::Lua::INDEX_GLOBAL, "loadfile" );

LUA->PushCFunction( PushLuaPath );
LUA->SetField( GarrysMod::Lua::INDEX_GLOBAL, "PushLuaPath" );

LUA->PushCFunction( PopLuaPath );
LUA->SetField( GarrysMod::Lua::INDEX_GLOBAL, "PopLuaPath" );

return 0;
}

Expand All @@ -199,5 +260,11 @@ GMOD_MODULE_CLOSE( )
LUA->PushNil( );
LUA->SetField( GarrysMod::Lua::INDEX_GLOBAL, "loadfile" );

LUA->PushNil( );
LUA->SetField( GarrysMod::Lua::INDEX_GLOBAL, "PushLuaPath" );

LUA->PushNil( );
LUA->SetField( GarrysMod::Lua::INDEX_GLOBAL, "PopLuaPath" );

return 0;
}