1 // Thanks to OrfeasZ for their answer to
2 // an issue for this example!
3 #define SOL_ALL_SAFETIES_ON 1
4 #include <sol/sol.hpp>
5 
6 
7 #include <iostream>
8 #include <exception>
9 
10 // Use raw function of form "int(lua_State*)"
11 // -- this is called a "raw C function",
12 // and matches the type for lua_CFunction
LoadFileRequire(lua_State * L)13 int LoadFileRequire(lua_State* L) {
14 	// use sol3 stack API to pull
15 	// "first argument"
16 	std::string path = sol::stack::get<std::string>(L, 1);
17 
18 	if (path == "a") {
19 		std::string script = R"(
20 			print("Hello from module land!")
21 			test = 123
22 			return "bananas"
23 		)";
24 		// load "module", but don't run it
25 		luaL_loadbuffer(L, script.data(), script.size(), path.c_str());
26 		// returning 1 object left on Lua stack:
27 		// a function that, when called, executes the script
28 		// (this is what lua_loadX/luaL_loadX functions return
29 		return 1;
30 	}
31 
32 	sol::stack::push(L, "This is not the module you're looking for!");
33 	return 1;
34 }
35 
main()36 int main() {
37 	std::cout << "=== require override behavior ===" << std::endl;
38 
39 	sol::state lua;
40 	// need base for print,
41 	// need package for package/searchers/require
42 	lua.open_libraries(sol::lib::base, sol::lib::package);
43 
44 	lua.clear_package_loaders();
45 	lua.add_package_loader(LoadFileRequire);
46 
47 	// this will call our function for
48 	// the searcher and it will succeed
49 	auto a_result = lua.safe_script(R"(
50 		local a = require("a")
51 		print(a)
52 		print(test)
53 	)",
54 	     sol::script_pass_on_error);
55 	sol_c_assert(a_result.valid());
56 	try {
57 		// this will always fail
58 		auto b_result = lua.safe_script(R"(
59 			local b = require("b")
60 			print(b)
61 		)",
62 		     sol::script_throw_on_error);
63 		// this will not be executed because of the throw,
64 		// but it better be true regardless!
65 		sol_c_assert(!b_result.valid());
66 	}
67 	catch (const std::exception& ex) {
68 		// Whenever sol3 throws an exception from panic,
69 		// catch
70 		std::cout << "Something went wrong, as expected:\n" << ex.what() << std::endl;
71 		// and CRASH / exit the application
72 		return 0;
73 	}
74 
75 	// If we get here something went wrong...!
76 	return -1;
77 }
78