mirror of
https://github.com/boostorg/leaf.git
synced 2026-01-25 06:12:27 +00:00
detab
This commit is contained in:
@@ -7,8 +7,8 @@
|
||||
// C-callback, converting them to leaf::result<T> as soon as controlreaches C++.
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
#include <boost/leaf/handle_errors.hpp>
|
||||
#include <boost/leaf/result.hpp>
|
||||
@@ -20,8 +20,8 @@ namespace leaf = boost::leaf;
|
||||
|
||||
enum do_work_error_code
|
||||
{
|
||||
ec1=1,
|
||||
ec2
|
||||
ec1=1,
|
||||
ec2
|
||||
};
|
||||
|
||||
struct e_lua_pcall_error { int value; };
|
||||
@@ -34,37 +34,37 @@ struct e_lua_error_message { std::string value; };
|
||||
// pop back into the C++ code which called it (see call_lua below).
|
||||
int do_work( lua_State * L )
|
||||
{
|
||||
bool success = rand()%2; // "Sometimes" do_work fails.
|
||||
if( success )
|
||||
{
|
||||
lua_pushnumber(L, 42); // Success, push the result on the Lua stack, return to Lua.
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return leaf::new_error(ec1), luaL_error(L,"do_work_error"); // luaL_error does not return (longjmp).
|
||||
}
|
||||
bool success = rand()%2; // "Sometimes" do_work fails.
|
||||
if( success )
|
||||
{
|
||||
lua_pushnumber(L, 42); // Success, push the result on the Lua stack, return to Lua.
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return leaf::new_error(ec1), luaL_error(L,"do_work_error"); // luaL_error does not return (longjmp).
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<lua_State> init_lua_state()
|
||||
{
|
||||
// Create a new lua_State, we'll use std::shared_ptr for automatic cleanup.
|
||||
std::shared_ptr<lua_State> L(lua_open(), &lua_close);
|
||||
// Create a new lua_State, we'll use std::shared_ptr for automatic cleanup.
|
||||
std::shared_ptr<lua_State> L(lua_open(), &lua_close);
|
||||
|
||||
// Register the do_work function (above) as a C callback, under the global
|
||||
// Lua name "do_work". With this, calls from Lua programs to do_work
|
||||
// will land in the do_work C function we've registered.
|
||||
lua_register( &*L, "do_work", &do_work );
|
||||
// Register the do_work function (above) as a C callback, under the global
|
||||
// Lua name "do_work". With this, calls from Lua programs to do_work
|
||||
// will land in the do_work C function we've registered.
|
||||
lua_register( &*L, "do_work", &do_work );
|
||||
|
||||
// Pass some Lua code as a C string literal to Lua. This creates a global Lua
|
||||
// function called "call_do_work", which we will later ask Lua to execute.
|
||||
luaL_dostring( &*L, "\
|
||||
// Pass some Lua code as a C string literal to Lua. This creates a global Lua
|
||||
// function called "call_do_work", which we will later ask Lua to execute.
|
||||
luaL_dostring( &*L, "\
|
||||
\n function call_do_work()\
|
||||
\n return do_work()\
|
||||
\n end" );
|
||||
|
||||
return L;
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,81 +76,81 @@ std::shared_ptr<lua_State> init_lua_state()
|
||||
// If it fails, we'll communicate that failure to our caller.
|
||||
leaf::result<int> call_lua( lua_State * L )
|
||||
{
|
||||
leaf::error_monitor cur_err;
|
||||
leaf::error_monitor cur_err;
|
||||
|
||||
// Ask the Lua interpreter to call the global Lua function call_do_work.
|
||||
lua_getfield( L, LUA_GLOBALSINDEX, "call_do_work" );
|
||||
if( int err = lua_pcall(L, 0, 1, 0) ) // Ask Lua to call the global function call_do_work.
|
||||
{
|
||||
auto load = leaf::on_error(e_lua_error_message{lua_tostring(L, 1)});
|
||||
lua_pop(L,1);
|
||||
// Ask the Lua interpreter to call the global Lua function call_do_work.
|
||||
lua_getfield( L, LUA_GLOBALSINDEX, "call_do_work" );
|
||||
if( int err = lua_pcall(L, 0, 1, 0) ) // Ask Lua to call the global function call_do_work.
|
||||
{
|
||||
auto load = leaf::on_error(e_lua_error_message{lua_tostring(L, 1)});
|
||||
lua_pop(L,1);
|
||||
|
||||
// We got a Lua error which may be the error we're reporting from do_work, or some other error.
|
||||
// If it is another error, cur_err.assigned_error_id() will return a new leaf::error_id,
|
||||
// otherwise we'll be working with the original value returned by leaf::new_error in do_work.
|
||||
return cur_err.assigned_error_id().load(e_lua_pcall_error{err});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Success! Just return the int answer.
|
||||
int answer=lua_tonumber(L, -1);
|
||||
lua_pop(L,1);
|
||||
return answer;
|
||||
}
|
||||
// We got a Lua error which may be the error we're reporting from do_work, or some other error.
|
||||
// If it is another error, cur_err.assigned_error_id() will return a new leaf::error_id,
|
||||
// otherwise we'll be working with the original value returned by leaf::new_error in do_work.
|
||||
return cur_err.assigned_error_id().load(e_lua_pcall_error{err});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Success! Just return the int answer.
|
||||
int answer=lua_tonumber(L, -1);
|
||||
lua_pop(L,1);
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::shared_ptr<lua_State> L=init_lua_state();
|
||||
std::shared_ptr<lua_State> L=init_lua_state();
|
||||
|
||||
for( int i=0; i!=10; ++i )
|
||||
{
|
||||
leaf::try_handle_all(
|
||||
for( int i=0; i!=10; ++i )
|
||||
{
|
||||
leaf::try_handle_all(
|
||||
|
||||
[&]() -> leaf::result<void>
|
||||
{
|
||||
BOOST_LEAF_AUTO(answer, call_lua(&*L));
|
||||
std::cout << "do_work succeeded, answer=" << answer << '\n';
|
||||
return { };
|
||||
},
|
||||
[&]() -> leaf::result<void>
|
||||
{
|
||||
BOOST_LEAF_AUTO(answer, call_lua(&*L));
|
||||
std::cout << "do_work succeeded, answer=" << answer << '\n';
|
||||
return { };
|
||||
},
|
||||
|
||||
[]( do_work_error_code e )
|
||||
{
|
||||
std::cout << "Got do_work_error_code = " << e << "!\n";
|
||||
},
|
||||
[]( do_work_error_code e )
|
||||
{
|
||||
std::cout << "Got do_work_error_code = " << e << "!\n";
|
||||
},
|
||||
|
||||
[]( e_lua_pcall_error const & err, e_lua_error_message const & msg )
|
||||
{
|
||||
std::cout << "Got e_lua_pcall_error, Lua error code = " << err.value << ", " << msg.value << "\n";
|
||||
},
|
||||
[]( e_lua_pcall_error const & err, e_lua_error_message const & msg )
|
||||
{
|
||||
std::cout << "Got e_lua_pcall_error, Lua error code = " << err.value << ", " << msg.value << "\n";
|
||||
},
|
||||
|
||||
[]( leaf::error_info const & unmatched )
|
||||
{
|
||||
std::cerr <<
|
||||
"Unknown failure detected" << std::endl <<
|
||||
"Cryptic diagnostic information follows" << std::endl <<
|
||||
unmatched;
|
||||
} );
|
||||
}
|
||||
[]( leaf::error_info const & unmatched )
|
||||
{
|
||||
std::cerr <<
|
||||
"Unknown failure detected" << std::endl <<
|
||||
"Cryptic diagnostic information follows" << std::endl <<
|
||||
unmatched;
|
||||
} );
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BOOST_LEAF_NO_EXCEPTIONS
|
||||
|
||||
namespace boost
|
||||
{
|
||||
BOOST_LEAF_NORETURN void throw_exception( std::exception const & e )
|
||||
{
|
||||
std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what();
|
||||
std::terminate();
|
||||
}
|
||||
BOOST_LEAF_NORETURN void throw_exception( std::exception const & e )
|
||||
{
|
||||
std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what();
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
struct source_location;
|
||||
BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & )
|
||||
{
|
||||
throw_exception(e);
|
||||
}
|
||||
struct source_location;
|
||||
BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & )
|
||||
{
|
||||
throw_exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user