Initial import of Lutok, version 0.2.
This is a required component of Kyua and its build will be guarded by the MKKYUA knob. core@ has approved this import. Description: Lutok is a lightweight C++ API library for Lua. Lutok provides thin C++ wrappers around the Lua C API to ease the interaction between C++ and Lua. These wrappers make intensive use of RAII to prevent resource leakage, expose C++-friendly data types, report errors by means of exceptions and ensure that the Lua stack is always left untouched in the face of errors. The library also provides a small subset of miscellaneous utility functions built on top of the wrappers. Lutok focuses on providing a clean and safe C++ interface; the drawback is that it is not suitable for performance-critical environments. In order to implement error-safe C++ wrappers on top of a Lua C binary library, Lutok adds several layers or abstraction and error checking that go against the original spirit of the Lua C API and thus degrade performance.
This commit is contained in:
parent
3bd42d5026
commit
a15637525a
1
external/bsd/lutok/dist/AUTHORS
vendored
Normal file
1
external/bsd/lutok/dist/AUTHORS
vendored
Normal file
@ -0,0 +1 @@
|
||||
* Julio Merino <jmmv@google.com>
|
11
external/bsd/lutok/dist/Atffile
vendored
Normal file
11
external/bsd/lutok/dist/Atffile
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
Content-Type: application/X-atf-atffile; version="1"
|
||||
|
||||
prop: test-suite = lutok
|
||||
|
||||
tp: c_gate_test
|
||||
tp: debug_test
|
||||
tp: examples_test
|
||||
tp: exceptions_test
|
||||
tp: operations_test
|
||||
tp: stack_cleaner_test
|
||||
tp: state_test
|
27
external/bsd/lutok/dist/COPYING
vendored
Normal file
27
external/bsd/lutok/dist/COPYING
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Copyright 2011, 2012 Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Google Inc. nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
11
external/bsd/lutok/dist/Kyuafile
vendored
Normal file
11
external/bsd/lutok/dist/Kyuafile
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
syntax("kyuafile", 1)
|
||||
|
||||
test_suite("lutok")
|
||||
|
||||
atf_test_program{name="c_gate_test"}
|
||||
atf_test_program{name="debug_test"}
|
||||
atf_test_program{name="examples_test"}
|
||||
atf_test_program{name="exceptions_test"}
|
||||
atf_test_program{name="operations_test"}
|
||||
atf_test_program{name="stack_cleaner_test"}
|
||||
atf_test_program{name="state_test"}
|
19
external/bsd/lutok/dist/NEWS
vendored
Normal file
19
external/bsd/lutok/dist/NEWS
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Changes in version 0.2
|
||||
======================
|
||||
|
||||
Released on 2012/05/30.
|
||||
|
||||
* New global constants: globals_index.
|
||||
|
||||
* New methods added to the state class: get_metafield, get_metatable,
|
||||
insert, push_value, raw_get and raw_set.
|
||||
|
||||
* Acknowledged that Lua 5.2 is currently not supported.
|
||||
|
||||
|
||||
Changes in version 0.1
|
||||
======================
|
||||
|
||||
Released on 2012/01/29.
|
||||
|
||||
* This is the first public release of the Lutok package.
|
27
external/bsd/lutok/dist/README
vendored
Normal file
27
external/bsd/lutok/dist/README
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Lutok is a lightweight C++ API library for Lua.
|
||||
|
||||
Lutok provides thin C++ wrappers around the Lua C API to ease the
|
||||
interaction between C++ and Lua. These wrappers make intensive use of
|
||||
RAII to prevent resource leakage, expose C++-friendly data types, report
|
||||
errors by means of exceptions and ensure that the Lua stack is always
|
||||
left untouched in the face of errors. The library also provides a small
|
||||
subset of miscellaneous utility functions built on top of the wrappers.
|
||||
|
||||
Lutok focuses on providing a clean and safe C++ interface; the drawback
|
||||
is that it is not suitable for performance-critical environments. In
|
||||
order to implement error-safe C++ wrappers on top of a Lua C binary
|
||||
library, Lutok adds several layers or abstraction and error checking
|
||||
that go against the original spirit of the Lua C API and thus degrade
|
||||
performance.
|
||||
|
||||
For further information on the contents of this distribution file,
|
||||
please refer to the following other documents:
|
||||
|
||||
* AUTHORS: List of authors and contributors to this project.
|
||||
* COPYING: License information.
|
||||
* INSTALL: Compilation and installation instructions.
|
||||
* NEWS: List of major changes between formal releases.
|
||||
|
||||
For general project information, please visit:
|
||||
|
||||
http://code.google.com/p/lutok/
|
76
external/bsd/lutok/dist/c_gate.cpp
vendored
Normal file
76
external/bsd/lutok/dist/c_gate.cpp
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "c_gate.hpp"
|
||||
#include "state.ipp"
|
||||
|
||||
|
||||
/// Creates a new gateway to an existing C++ Lua state.
|
||||
///
|
||||
/// \param state_ The state to connect to. This object must remain alive while
|
||||
/// the newly-constructed state_c_gate is alive.
|
||||
lutok::state_c_gate::state_c_gate(state& state_) :
|
||||
_state(state_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Destructor.
|
||||
///
|
||||
/// Destroying this object has no implications on the life cycle of the Lua
|
||||
/// state. Only the corresponding state object controls when the Lua state is
|
||||
/// closed.
|
||||
lutok::state_c_gate::~state_c_gate(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Creates a C++ state for a C Lua state.
|
||||
///
|
||||
/// \warning The created state object does NOT own the C state. You must take
|
||||
/// care to properly destroy the input lua_State when you are done with it to
|
||||
/// not leak resources.
|
||||
///
|
||||
/// \param raw_state The raw state to wrap temporarily.
|
||||
///
|
||||
/// \return The wrapped state without strong ownership on the input state.
|
||||
lutok::state
|
||||
lutok::state_c_gate::connect(lua_State* raw_state)
|
||||
{
|
||||
return state(static_cast< void* >(raw_state));
|
||||
}
|
||||
|
||||
|
||||
/// Returns the C native Lua state.
|
||||
///
|
||||
/// \return A native lua_State object holding the Lua C API state.
|
||||
lua_State*
|
||||
lutok::state_c_gate::c_state(void)
|
||||
{
|
||||
return static_cast< lua_State* >(_state.raw_state());
|
||||
}
|
71
external/bsd/lutok/dist/c_gate.hpp
vendored
Normal file
71
external/bsd/lutok/dist/c_gate.hpp
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file c_gate.hpp
|
||||
/// Provides direct access to the C state of the Lua wrappers.
|
||||
|
||||
#if !defined(LUTOK_C_GATE_HPP)
|
||||
#define LUTOK_C_GATE_HPP
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
namespace lutok {
|
||||
|
||||
|
||||
class state;
|
||||
|
||||
|
||||
/// Gateway to the raw C state of Lua.
|
||||
///
|
||||
/// This class provides a mechanism to muck with the internals of the state
|
||||
/// wrapper class. Client code may wish to do so if Lutok is missing some
|
||||
/// features of the performance of Lutok in a particular situation is not
|
||||
/// reasonable.
|
||||
///
|
||||
/// \warning The use of this class is discouraged. By using this class, you are
|
||||
/// entering the world of unsafety. Anything you do through the objects exposed
|
||||
/// through this class will not be controlled by RAII patterns not validated in
|
||||
/// any other way, so you can end up corrupting the Lua state and later get
|
||||
/// crashes on otherwise perfectly-valid C++ code.
|
||||
class state_c_gate {
|
||||
/// The C++ state that this class wraps.
|
||||
state& _state;
|
||||
|
||||
public:
|
||||
state_c_gate(state&);
|
||||
~state_c_gate(void);
|
||||
|
||||
static state connect(lua_State*);
|
||||
|
||||
lua_State* c_state(void);
|
||||
};
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
#endif // !defined(LUTOK_C_GATE_HPP)
|
74
external/bsd/lutok/dist/c_gate_test.cpp
vendored
Normal file
74
external/bsd/lutok/dist/c_gate_test.cpp
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "c_gate.hpp"
|
||||
|
||||
#include <atf-c++.hpp>
|
||||
#include <lua.hpp>
|
||||
|
||||
#include "state.ipp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(connect);
|
||||
ATF_TEST_CASE_BODY(connect)
|
||||
{
|
||||
lua_State* raw_state = lua_open();
|
||||
ATF_REQUIRE(raw_state != NULL);
|
||||
|
||||
{
|
||||
lutok::state state = lutok::state_c_gate::connect(raw_state);
|
||||
lua_pushinteger(raw(state), 123);
|
||||
}
|
||||
// If the wrapper object had closed the Lua state, we could very well crash
|
||||
// here.
|
||||
ATF_REQUIRE_EQ(123, lua_tointeger(raw_state, -1));
|
||||
|
||||
lua_close(raw_state);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(c_state);
|
||||
ATF_TEST_CASE_BODY(c_state)
|
||||
{
|
||||
lutok::state state;
|
||||
state.push_integer(5);
|
||||
{
|
||||
lutok::state_c_gate gate(state);
|
||||
lua_State* raw_state = gate.c_state();
|
||||
ATF_REQUIRE_EQ(5, lua_tointeger(raw_state, -1));
|
||||
}
|
||||
state.pop(1);
|
||||
}
|
||||
|
||||
|
||||
ATF_INIT_TEST_CASES(tcs)
|
||||
{
|
||||
ATF_ADD_TEST_CASE(tcs, c_state);
|
||||
ATF_ADD_TEST_CASE(tcs, connect);
|
||||
}
|
192
external/bsd/lutok/dist/debug.cpp
vendored
Normal file
192
external/bsd/lutok/dist/debug.cpp
vendored
Normal file
@ -0,0 +1,192 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
#include <lutok/c_gate.hpp>
|
||||
#include <lutok/debug.hpp>
|
||||
#include <lutok/exceptions.hpp>
|
||||
#include <lutok/state.ipp>
|
||||
|
||||
|
||||
/// Internal implementation for lutok::debug.
|
||||
struct lutok::debug::impl {
|
||||
/// The Lua internal debug state.
|
||||
lua_Debug lua_debug;
|
||||
};
|
||||
|
||||
|
||||
/// Constructor for an empty debug structure.
|
||||
lutok::debug::debug(void) :
|
||||
_pimpl(new impl())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Destructor.
|
||||
lutok::debug::~debug(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_getinfo.
|
||||
///
|
||||
/// \param s The Lua state.
|
||||
/// \param what_ The second parameter to lua_getinfo.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory to manipulate
|
||||
/// the Lua stack.
|
||||
void
|
||||
lutok::debug::get_info(state& s, const std::string& what_)
|
||||
{
|
||||
lua_State* raw_state = state_c_gate(s).c_state();
|
||||
|
||||
if (lua_getinfo(raw_state, what_.c_str(), &_pimpl->lua_debug) == 0)
|
||||
throw lutok::api_error::from_stack(s, "lua_getinfo");
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_getstack.
|
||||
///
|
||||
/// \param s The Lua state.
|
||||
/// \param level The second parameter to lua_getstack.
|
||||
void
|
||||
lutok::debug::get_stack(state& s, const int level)
|
||||
{
|
||||
lua_State* raw_state = state_c_gate(s).c_state();
|
||||
|
||||
lua_getstack(raw_state, level, &_pimpl->lua_debug);
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'event' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'event' field of the internal lua_Debug structure.
|
||||
int
|
||||
lutok::debug::event(void) const
|
||||
{
|
||||
return _pimpl->lua_debug.event;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'name' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'name' field of the internal lua_Debug structure.
|
||||
std::string
|
||||
lutok::debug::name(void) const
|
||||
{
|
||||
assert(_pimpl->lua_debug.name != NULL);
|
||||
return _pimpl->lua_debug.name;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'namewhat' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'namewhat' field of the internal lua_Debug structure.
|
||||
std::string
|
||||
lutok::debug::name_what(void) const
|
||||
{
|
||||
assert(_pimpl->lua_debug.namewhat != NULL);
|
||||
return _pimpl->lua_debug.namewhat;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'what' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'what' field of the internal lua_Debug structure.
|
||||
std::string
|
||||
lutok::debug::what(void) const
|
||||
{
|
||||
assert(_pimpl->lua_debug.what != NULL);
|
||||
return _pimpl->lua_debug.what;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'source' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'source' field of the internal lua_Debug structure.
|
||||
std::string
|
||||
lutok::debug::source(void) const
|
||||
{
|
||||
assert(_pimpl->lua_debug.source != NULL);
|
||||
return _pimpl->lua_debug.source;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'currentline' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'currentline' field of the internal lua_Debug structure.
|
||||
int
|
||||
lutok::debug::current_line(void) const
|
||||
{
|
||||
return _pimpl->lua_debug.currentline;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'nups' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'nups' field of the internal lua_Debug structure.
|
||||
int
|
||||
lutok::debug::n_ups(void) const
|
||||
{
|
||||
return _pimpl->lua_debug.nups;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'linedefined' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'linedefined' field of the internal lua_Debug structure.
|
||||
int
|
||||
lutok::debug::line_defined(void) const
|
||||
{
|
||||
return _pimpl->lua_debug.linedefined;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'lastlinedefined' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'lastlinedefined' field of the internal lua_Debug
|
||||
/// structure.
|
||||
int
|
||||
lutok::debug::last_line_defined(void) const
|
||||
{
|
||||
return _pimpl->lua_debug.lastlinedefined;
|
||||
}
|
||||
|
||||
|
||||
/// Accessor for the 'short_src' field of lua_Debug.
|
||||
///
|
||||
/// \return Returns the 'short_src' field of the internal lua_Debug structure.
|
||||
std::string
|
||||
lutok::debug::short_src(void) const
|
||||
{
|
||||
assert(_pimpl->lua_debug.short_src != NULL);
|
||||
return _pimpl->lua_debug.short_src;
|
||||
}
|
83
external/bsd/lutok/dist/debug.hpp
vendored
Normal file
83
external/bsd/lutok/dist/debug.hpp
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file debug.hpp
|
||||
/// Provides the debug wrapper class for the Lua C debug state.
|
||||
|
||||
#if !defined(LUTOK_DEBUG_HPP)
|
||||
#define LUTOK_DEBUG_HPP
|
||||
|
||||
#include <string>
|
||||
#include <tr1/memory>
|
||||
|
||||
|
||||
namespace lutok {
|
||||
|
||||
|
||||
class state;
|
||||
|
||||
|
||||
/// A model for the Lua debug state.
|
||||
///
|
||||
/// This extremely-simple class provides a mechanism to hide the internals of
|
||||
/// the C native lua_Debug type, exposing its internal fields using friendlier
|
||||
/// C++ types.
|
||||
///
|
||||
/// This class also acts as a complement to the state class by exposing any
|
||||
/// state-related functions as methods of this function. For example, while it
|
||||
/// might seem that get_info() belongs in state, we expose it from here because
|
||||
/// its result is really mutating a debug object, not the state object.
|
||||
class debug {
|
||||
struct impl;
|
||||
|
||||
/// Pointer to the shared internal implementation.
|
||||
std::tr1::shared_ptr< impl > _pimpl;
|
||||
|
||||
public:
|
||||
debug(void);
|
||||
~debug(void);
|
||||
|
||||
void get_info(state&, const std::string&);
|
||||
void get_stack(state&, const int);
|
||||
|
||||
int event(void) const;
|
||||
std::string name(void) const;
|
||||
std::string name_what(void) const;
|
||||
std::string what(void) const;
|
||||
std::string source(void) const;
|
||||
int current_line(void) const;
|
||||
int n_ups(void) const;
|
||||
int line_defined(void) const;
|
||||
int last_line_defined(void) const;
|
||||
std::string short_src(void) const;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
#endif // !defined(LUTOK_DEBUG_HPP)
|
68
external/bsd/lutok/dist/debug_test.cpp
vendored
Normal file
68
external/bsd/lutok/dist/debug_test.cpp
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "debug.hpp"
|
||||
|
||||
#include <atf-c++.hpp>
|
||||
#include <lua.hpp>
|
||||
|
||||
#include "state.ipp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(get_info);
|
||||
ATF_TEST_CASE_BODY(get_info)
|
||||
{
|
||||
lutok::state state;
|
||||
ATF_REQUIRE(luaL_dostring(raw(state), "\n\nfunction hello() end\n"
|
||||
"return hello") == 0);
|
||||
lutok::debug debug;
|
||||
debug.get_info(state, ">S");
|
||||
ATF_REQUIRE_EQ(3, debug.line_defined());
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(get_stack);
|
||||
ATF_TEST_CASE_BODY(get_stack)
|
||||
{
|
||||
lutok::state state;
|
||||
ATF_REQUIRE(luaL_dostring(raw(state), "error('Hello')") == 1);
|
||||
lutok::debug debug;
|
||||
debug.get_stack(state, 0);
|
||||
lua_pop(raw(state), 1);
|
||||
// Not sure if we can actually validate anything here, other than we did not
|
||||
// crash... (because get_stack only is supposed to update internal values of
|
||||
// the debug structure).
|
||||
}
|
||||
|
||||
|
||||
ATF_INIT_TEST_CASES(tcs)
|
||||
{
|
||||
ATF_ADD_TEST_CASE(tcs, get_info);
|
||||
ATF_ADD_TEST_CASE(tcs, get_stack);
|
||||
}
|
133
external/bsd/lutok/dist/examples/bindings.cpp
vendored
Normal file
133
external/bsd/lutok/dist/examples/bindings.cpp
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
// Copyright 2012 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file examples/bindings.cpp
|
||||
/// Showcases how to define Lua functions from C++ code.
|
||||
///
|
||||
/// A major selling point of Lua is that it is very easy too hook native C and
|
||||
/// C++ functions into the runtime environment so that Lua can call them. The
|
||||
/// purpose of this example program is to show how this is done by using Lutok.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <lutok/exceptions.hpp>
|
||||
#include <lutok/operations.hpp>
|
||||
#include <lutok/state.ipp>
|
||||
|
||||
|
||||
/// Calculates the factorial of a given number.
|
||||
///
|
||||
/// \param i The postivie number to calculate the factorial of.
|
||||
///
|
||||
/// \return The factorial of i.
|
||||
static int
|
||||
factorial(const int i)
|
||||
{
|
||||
assert(i >= 0);
|
||||
|
||||
if (i == 0)
|
||||
return 1;
|
||||
else
|
||||
return i * factorial(i - 1);
|
||||
}
|
||||
|
||||
|
||||
/// A custom factorial function for Lua.
|
||||
///
|
||||
/// \pre stack(-1) contains the number to calculate the factorial of.
|
||||
/// \post stack(-1) contains the result of the operation.
|
||||
///
|
||||
/// \param state The Lua state from which to get the function arguments and into
|
||||
/// which to push the results.
|
||||
///
|
||||
/// \return The number of results pushed onto the stack, i.e. 1.
|
||||
///
|
||||
/// \throw std::runtime_error If the input parameters are invalid. Note that
|
||||
/// Lutok will convert this exception to lutok::error.
|
||||
static int
|
||||
lua_factorial(lutok::state& state)
|
||||
{
|
||||
if (!state.is_number())
|
||||
throw std::runtime_error("Argument to factorial must be an integer");
|
||||
const int i = state.to_integer();
|
||||
if (i < 0)
|
||||
throw std::runtime_error("Argument to factorial must be positive");
|
||||
state.push_integer(factorial(i));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/// Program's entry point.
|
||||
///
|
||||
/// \param argc Length of argv. Must be 2.
|
||||
/// \param argv Command-line arguments to the program. The first argument to
|
||||
/// the tool has to be a number.
|
||||
///
|
||||
/// \return A system exit code.
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: bindings <number>\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Create a new Lua session and load the print() function.
|
||||
lutok::state state;
|
||||
state.open_base();
|
||||
|
||||
// Construct a 'module' that contains an entry point to our native factorial
|
||||
// function. A module is just a Lua table that contains a mapping of names
|
||||
// to functions. Instead of creating a module by using our create_module()
|
||||
// helper function, we could have used push_cxx_function on the state to
|
||||
// define the function ourselves.
|
||||
std::map< std::string, lutok::cxx_function > module;
|
||||
module["factorial"] = lua_factorial;
|
||||
lutok::create_module(state, "native", module);
|
||||
|
||||
// Use a little Lua script to call our native factorial function providing
|
||||
// it the first argument passed to the program. Note that this will error
|
||||
// out in a controlled manner if the passed argument is not an integer. The
|
||||
// important thing to notice is that the exception comes from our own C++
|
||||
// binding and that it has been converted to a lutok::error.
|
||||
std::ostringstream script;
|
||||
script << "print(native.factorial(" << argv[1] << "))";
|
||||
try {
|
||||
lutok::do_string(state, script.str());
|
||||
return EXIT_SUCCESS;
|
||||
} catch (const lutok::error& e) {
|
||||
std::cerr << "ERROR: " << e.what() << '\n';
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
58
external/bsd/lutok/dist/examples/hello.cpp
vendored
Normal file
58
external/bsd/lutok/dist/examples/hello.cpp
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2012 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file examples/hello.cpp
|
||||
/// Minimal example using Lua code to print a traditional hello-world message.
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <lutok/state.ipp>
|
||||
|
||||
|
||||
/// Program's entry point.
|
||||
///
|
||||
/// \return A system exit code.
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
// Initializes a new Lua state. Every Lua state is independent from each
|
||||
// other.
|
||||
lutok::state state;
|
||||
|
||||
// Loads the standard library into the Lua state. Among many other
|
||||
// functions, this gives us access to print(), which is used below.
|
||||
state.open_base();
|
||||
|
||||
// Pushes the print() function into the Lua stack, then its only argument,
|
||||
// and then proceeds to execute it within the Lua state.
|
||||
state.get_global("print");
|
||||
state.push_string("Hello, world!");
|
||||
state.pcall(1, 0, 0);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
83
external/bsd/lutok/dist/examples/interpreter.cpp
vendored
Normal file
83
external/bsd/lutok/dist/examples/interpreter.cpp
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2012 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file examples/interpreter.cpp
|
||||
/// Implementation of a basic command-line Lua interpreter.
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <lutok/exceptions.hpp>
|
||||
#include <lutok/operations.hpp>
|
||||
#include <lutok/state.ipp>
|
||||
|
||||
|
||||
/// Executes a Lua statement provided by the user with error checking.
|
||||
///
|
||||
/// \param state The Lua state in which to process the statement.
|
||||
/// \param line The textual statement provided by the user.
|
||||
static void
|
||||
run_statement(lutok::state& state, const std::string& line)
|
||||
{
|
||||
try {
|
||||
// This utility function allows us to feed a given piece of Lua code to
|
||||
// the interpreter and process it. The piece of code can include
|
||||
// multiple statements separated by a semicolon or by a newline
|
||||
// character.
|
||||
lutok::do_string(state, line);
|
||||
} catch (const lutok::error& error) {
|
||||
std::cerr << "ERROR: " << error.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Program's entry point.
|
||||
///
|
||||
/// \return A system exit code.
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
// Create a new session and load some standard libraries.
|
||||
lutok::state state;
|
||||
state.open_base();
|
||||
state.open_string();
|
||||
state.open_table();
|
||||
|
||||
for (;;) {
|
||||
std::cout << "lua> ";
|
||||
std::cout.flush();
|
||||
|
||||
std::string line;
|
||||
if (!std::getline(std::cin, line).good())
|
||||
break;
|
||||
run_statement(state, line);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
125
external/bsd/lutok/dist/examples/raii.cpp
vendored
Normal file
125
external/bsd/lutok/dist/examples/raii.cpp
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
// Copyright 2012 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file examples/raii.cpp
|
||||
/// Demonstrates how RAII helps in keeping the Lua state consistent.
|
||||
///
|
||||
/// One of the major complains that is raised against the Lua C API is that it
|
||||
/// is very hard to ensure it remains consistent during the execution of the
|
||||
/// program. In the case of native C code, there exist many tools that help the
|
||||
/// developer catch memory leaks, access to uninitialized variables, etc.
|
||||
/// However, when using the Lua C API, none of these tools can validate that,
|
||||
/// for example, the Lua stack remains balanced across calls.
|
||||
///
|
||||
/// Enter RAII. The RAII pattern, intensively applied by Lutok, helps the
|
||||
/// developer in maintaining the Lua state consistent at all times in a
|
||||
/// transparent manner. This example program attempts to illustrate this.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <lutok/operations.hpp>
|
||||
#include <lutok/stack_cleaner.hpp>
|
||||
#include <lutok/state.ipp>
|
||||
|
||||
|
||||
/// Prints the string-typed field of a table.
|
||||
///
|
||||
/// If the field contains a string, this function prints its value. If the
|
||||
/// field contains any other type, this prints an error message.
|
||||
///
|
||||
/// \pre The top of the Lua stack in 'state' references a table.
|
||||
///
|
||||
/// \param state The Lua state.
|
||||
/// \param field The name of the string-typed field.
|
||||
static void
|
||||
print_table_field(lutok::state& state, const std::string& field)
|
||||
{
|
||||
assert(state.is_table());
|
||||
|
||||
// Bring in some RAII magic: the stack_cleaner object captures the current
|
||||
// height of the Lua stack at this point. Whenever the object goes out of
|
||||
// scope, it will pop as many entries from the stack as necessary to restore
|
||||
// the stack to its previous level.
|
||||
//
|
||||
// This ensures that, no matter how we exit the function, we do not leak
|
||||
// objects in the stack.
|
||||
lutok::stack_cleaner cleaner(state);
|
||||
|
||||
// Stack contents: -1: table.
|
||||
state.push_string(field);
|
||||
// Stack contents: -2: table, -1: field name.
|
||||
state.get_table();
|
||||
// Stack contents: -2: table, -1: field value.
|
||||
|
||||
if (!state.is_string()) {
|
||||
std::cout << "The field " << field << " does not contain a string\n";
|
||||
// Stack contents: -2: table, -1: field value.
|
||||
//
|
||||
// This is different than when we started! We should pop our extra
|
||||
// value from the stack at this point. However, it is extremely common
|
||||
// for software to have bugs (in this case, leaks) in error paths,
|
||||
// mostly because such code paths are rarely exercised.
|
||||
//
|
||||
// By using the stack_cleaner object, we can be confident that the Lua
|
||||
// stack will be cleared for us at this point, no matter what happened
|
||||
// earlier on the stack nor how we exit the function.
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "String in field " << field << ": " << state.to_string()
|
||||
<< '\n';
|
||||
// A well-behaved program explicitly pops anything extra from the stack to
|
||||
// return it to its original state. Mostly for clarity.
|
||||
state.pop(1);
|
||||
|
||||
// Stack contents: -1: table. Same as when we started.
|
||||
}
|
||||
|
||||
|
||||
/// Program's entry point.
|
||||
///
|
||||
/// \return A system exit code.
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
lutok::state state;
|
||||
state.open_base();
|
||||
|
||||
lutok::do_string(state, "example = {foo='hello', bar=123, baz='bye'}");
|
||||
|
||||
state.get_global("example");
|
||||
print_table_field(state, "foo");
|
||||
print_table_field(state, "bar");
|
||||
print_table_field(state, "baz");
|
||||
state.pop(1);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
114
external/bsd/lutok/dist/examples_test.sh
vendored
Normal file
114
external/bsd/lutok/dist/examples_test.sh
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
#! __ATF_SH__
|
||||
# Copyright 2012 Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
ExamplesDir="__EXAMPLESDIR__"
|
||||
LibDir="__LIBDIR__"
|
||||
|
||||
|
||||
make_example() {
|
||||
cp "${ExamplesDir}/Makefile" "${ExamplesDir}/${1}.cpp" .
|
||||
make "${1}"
|
||||
|
||||
# Ensure that the binary we just built can find liblutok. This is
|
||||
# needed because the lutok.pc file (which the Makefile used above
|
||||
# queries) does not provide rpaths to the installed library and
|
||||
# therefore the binary may not be able to locate it. Hardcoding the
|
||||
# rpath flags into lutok.pc is non-trivial because we simply don't
|
||||
# have any knowledge about what the correct flag to set an rpath is.
|
||||
#
|
||||
# Additionally, setting rpaths is not always the right thing to do.
|
||||
# For example, pkgsrc will automatically change lutok.pc to add the
|
||||
# missing rpath, in which case this is unnecessary. But in the case
|
||||
# of Fedora, adding rpaths goes against the packaging guidelines.
|
||||
if [ -n "${LD_LIBRARY_PATH}" ]; then
|
||||
export LD_LIBRARY_PATH="${LibDir}:${LD_LIBRARY_PATH}"
|
||||
else
|
||||
export LD_LIBRARY_PATH="${LibDir}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
example_test_case() {
|
||||
local name="${1}"; shift
|
||||
|
||||
atf_test_case "${name}"
|
||||
eval "${name}_head() { \
|
||||
atf_set 'require.files' '${ExamplesDir}/${name}.cpp'; \
|
||||
atf_set 'require.progs' 'make pkg-config'; \
|
||||
}"
|
||||
eval "${name}_body() { \
|
||||
make_example '${name}'; \
|
||||
${name}_validate; \
|
||||
}"
|
||||
}
|
||||
|
||||
|
||||
example_test_case bindings
|
||||
bindings_validate() {
|
||||
atf_check -s exit:0 -o inline:'120\n' ./bindings 5
|
||||
atf_check -s exit:1 -e match:'Argument.*must be an integer' ./bindings foo
|
||||
atf_check -s exit:1 -e match:'Argument.*must be positive' ./bindings -5
|
||||
}
|
||||
|
||||
|
||||
example_test_case hello
|
||||
hello_validate() {
|
||||
atf_check -s exit:0 -o inline:'Hello, world!\n' ./hello
|
||||
}
|
||||
|
||||
|
||||
example_test_case interpreter
|
||||
interpreter_validate() {
|
||||
cat >script.lua <<EOF
|
||||
test_variable = 12345
|
||||
print("From the interpreter: " .. (test_variable - 345))
|
||||
EOF
|
||||
|
||||
atf_check -s exit:0 -o match:"From the interpreter: 12000" \
|
||||
-x "./interpreter <script.lua"
|
||||
}
|
||||
|
||||
|
||||
example_test_case raii
|
||||
raii_validate() {
|
||||
cat >expout <<EOF
|
||||
String in field foo: hello
|
||||
String in field bar: 123
|
||||
String in field baz: bye
|
||||
EOF
|
||||
atf_check -s exit:0 -o file:expout ./raii
|
||||
}
|
||||
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case bindings
|
||||
atf_add_test_case hello
|
||||
atf_add_test_case interpreter
|
||||
atf_add_test_case raii
|
||||
}
|
126
external/bsd/lutok/dist/exceptions.cpp
vendored
Normal file
126
external/bsd/lutok/dist/exceptions.cpp
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
#include "c_gate.hpp"
|
||||
#include "exceptions.hpp"
|
||||
#include "state.ipp"
|
||||
|
||||
|
||||
/// Constructs a new error with a plain-text message.
|
||||
///
|
||||
/// \param message The plain-text error message.
|
||||
lutok::error::error(const std::string& message) :
|
||||
std::runtime_error(message)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Destructor for the error.
|
||||
lutok::error::~error(void) throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Constructs a new error.
|
||||
///
|
||||
/// \param api_function_ The name of the API function that caused the error.
|
||||
/// \param message The plain-text error message provided by Lua.
|
||||
lutok::api_error::api_error(const std::string& api_function_,
|
||||
const std::string& message) :
|
||||
error(message),
|
||||
_api_function(api_function_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Destructor for the error.
|
||||
lutok::api_error::~api_error(void) throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Constructs a new api_error with the message on the top of the Lua stack.
|
||||
///
|
||||
/// \pre There is an error message on the top of the stack.
|
||||
/// \post The error message is popped from the stack.
|
||||
///
|
||||
/// \param state_ The Lua state.
|
||||
/// \param api_function_ The name of the Lua API function that caused the error.
|
||||
///
|
||||
/// \return A new api_error with the popped message.
|
||||
lutok::api_error
|
||||
lutok::api_error::from_stack(state& state_, const std::string& api_function_)
|
||||
{
|
||||
lua_State* raw_state = lutok::state_c_gate(state_).c_state();
|
||||
|
||||
assert(lua_isstring(raw_state, -1));
|
||||
const std::string message = lua_tostring(raw_state, -1);
|
||||
lua_pop(raw_state, 1);
|
||||
return lutok::api_error(api_function_, message);
|
||||
}
|
||||
|
||||
|
||||
/// Gets the name of the Lua API function that caused this error.
|
||||
///
|
||||
/// \return The name of the function.
|
||||
const std::string&
|
||||
lutok::api_error::api_function(void) const
|
||||
{
|
||||
return _api_function;
|
||||
}
|
||||
|
||||
|
||||
/// Constructs a new error.
|
||||
///
|
||||
/// \param filename_ The file that count not be found.
|
||||
lutok::file_not_found_error::file_not_found_error(
|
||||
const std::string& filename_) :
|
||||
error("File '" + filename_ + "' not found"),
|
||||
_filename(filename_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Destructor for the error.
|
||||
lutok::file_not_found_error::~file_not_found_error(void) throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Gets the name of the file that could not be found.
|
||||
///
|
||||
/// \return The name of the file.
|
||||
const std::string&
|
||||
lutok::file_not_found_error::filename(void) const
|
||||
{
|
||||
return _filename;
|
||||
}
|
83
external/bsd/lutok/dist/exceptions.hpp
vendored
Normal file
83
external/bsd/lutok/dist/exceptions.hpp
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file exceptions.hpp
|
||||
/// Exception types raised by lutok.
|
||||
|
||||
#if !defined(LUTOK_EXCEPTIONS_HPP)
|
||||
#define LUTOK_EXCEPTIONS_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace lutok {
|
||||
|
||||
|
||||
class state;
|
||||
|
||||
|
||||
/// Base exception for lua errors.
|
||||
class error : public std::runtime_error {
|
||||
public:
|
||||
explicit error(const std::string&);
|
||||
virtual ~error(void) throw();
|
||||
};
|
||||
|
||||
|
||||
/// Exception for errors raised by the Lua API library.
|
||||
class api_error : public error {
|
||||
/// Name of the Lua C API function that caused the error.
|
||||
std::string _api_function;
|
||||
|
||||
public:
|
||||
explicit api_error(const std::string&, const std::string&);
|
||||
virtual ~api_error(void) throw();
|
||||
|
||||
static api_error from_stack(state&, const std::string&);
|
||||
|
||||
const std::string& api_function(void) const;
|
||||
};
|
||||
|
||||
|
||||
/// File not found error.
|
||||
class file_not_found_error : public error {
|
||||
/// Name of the not-found file.
|
||||
std::string _filename;
|
||||
|
||||
public:
|
||||
explicit file_not_found_error(const std::string&);
|
||||
virtual ~file_not_found_error(void) throw();
|
||||
|
||||
const std::string& filename(void) const;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
|
||||
#endif // !defined(LUTOK_EXCEPTIONS_HPP)
|
88
external/bsd/lutok/dist/exceptions_test.cpp
vendored
Normal file
88
external/bsd/lutok/dist/exceptions_test.cpp
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "exceptions.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <atf-c++.hpp>
|
||||
|
||||
#include "state.ipp"
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(error);
|
||||
ATF_TEST_CASE_BODY(error)
|
||||
{
|
||||
const lutok::error e("Some text");
|
||||
ATF_REQUIRE(std::strcmp("Some text", e.what()) == 0);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(api_error__explicit);
|
||||
ATF_TEST_CASE_BODY(api_error__explicit)
|
||||
{
|
||||
const lutok::api_error e("some_function", "Some text");
|
||||
ATF_REQUIRE(std::strcmp("Some text", e.what()) == 0);
|
||||
ATF_REQUIRE_EQ("some_function", e.api_function());
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(api_error__from_stack);
|
||||
ATF_TEST_CASE_BODY(api_error__from_stack)
|
||||
{
|
||||
lutok::state state;
|
||||
state.push_integer(123);
|
||||
state.push_string("The error message");
|
||||
const lutok::api_error e = lutok::api_error::from_stack(state,
|
||||
"the_function");
|
||||
ATF_REQUIRE_EQ(1, state.get_top());
|
||||
ATF_REQUIRE_EQ(123, state.to_integer());
|
||||
state.pop(1);
|
||||
ATF_REQUIRE(std::strcmp("The error message", e.what()) == 0);
|
||||
ATF_REQUIRE_EQ("the_function", e.api_function());
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(file_not_found_error);
|
||||
ATF_TEST_CASE_BODY(file_not_found_error)
|
||||
{
|
||||
const lutok::file_not_found_error e("missing-file");
|
||||
ATF_REQUIRE(std::strcmp("File 'missing-file' not found", e.what()) == 0);
|
||||
ATF_REQUIRE_EQ("missing-file", e.filename());
|
||||
}
|
||||
|
||||
|
||||
ATF_INIT_TEST_CASES(tcs)
|
||||
{
|
||||
ATF_ADD_TEST_CASE(tcs, error);
|
||||
|
||||
ATF_ADD_TEST_CASE(tcs, api_error__explicit);
|
||||
ATF_ADD_TEST_CASE(tcs, api_error__from_stack);
|
||||
|
||||
ATF_ADD_TEST_CASE(tcs, file_not_found_error);
|
||||
}
|
8
external/bsd/lutok/dist/lutok.pc.in
vendored
Normal file
8
external/bsd/lutok/dist/lutok.pc.in
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
includedir=__INCLUDEDIR__
|
||||
libdir=__LIBDIR__
|
||||
|
||||
Name: lutok
|
||||
Description: Lightweight C++ API for Lua
|
||||
Version: __VERSION__
|
||||
Cflags: __LUA_CFLAGS__ -I${includedir}
|
||||
Libs: __LUA_LIBS__ -L${libdir} -llutok
|
143
external/bsd/lutok/dist/operations.cpp
vendored
Normal file
143
external/bsd/lutok/dist/operations.cpp
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
#include "exceptions.hpp"
|
||||
#include "operations.hpp"
|
||||
#include "stack_cleaner.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
|
||||
/// Creates a module: i.e. a table with a set of methods in it.
|
||||
///
|
||||
/// \param s The Lua state.
|
||||
/// \param name The name of the module to create.
|
||||
/// \param members The list of member functions to add to the module.
|
||||
void
|
||||
lutok::create_module(state& s, const std::string& name,
|
||||
const std::map< std::string, cxx_function >& members)
|
||||
{
|
||||
stack_cleaner cleaner(s);
|
||||
s.new_table();
|
||||
for (std::map< std::string, cxx_function >::const_iterator
|
||||
iter = members.begin(); iter != members.end(); iter++) {
|
||||
s.push_string((*iter).first);
|
||||
s.push_cxx_function((*iter).second);
|
||||
s.set_table(-3);
|
||||
}
|
||||
s.set_global(name);
|
||||
}
|
||||
|
||||
|
||||
/// Loads and processes a Lua file.
|
||||
///
|
||||
/// This is a replacement for luaL_dofile but with proper error reporting
|
||||
/// and stack control.
|
||||
///
|
||||
/// \param s The Lua state.
|
||||
/// \param file The file to load.
|
||||
/// \param nresults The number of results to expect; -1 for any.
|
||||
///
|
||||
/// \return The number of results left on the stack.
|
||||
///
|
||||
/// \throw error If there is a problem processing the file.
|
||||
unsigned int
|
||||
lutok::do_file(state& s, const std::string& file, const int nresults)
|
||||
{
|
||||
assert(nresults >= -1);
|
||||
const int height = s.get_top();
|
||||
|
||||
stack_cleaner cleaner(s);
|
||||
try {
|
||||
s.load_file(file);
|
||||
s.pcall(0, nresults == -1 ? LUA_MULTRET : nresults, 0);
|
||||
} catch (const lutok::api_error& e) {
|
||||
throw lutok::error("Failed to load Lua file '" + file + "': " +
|
||||
e.what());
|
||||
}
|
||||
cleaner.forget();
|
||||
|
||||
const int actual_results = s.get_top() - height;
|
||||
assert(nresults == -1 || actual_results == nresults);
|
||||
assert(actual_results >= 0);
|
||||
return static_cast< unsigned int >(actual_results);
|
||||
}
|
||||
|
||||
|
||||
/// Processes a Lua script.
|
||||
///
|
||||
/// This is a replacement for luaL_dostring but with proper error reporting
|
||||
/// and stack control.
|
||||
///
|
||||
/// \param s The Lua state.
|
||||
/// \param str The string to process.
|
||||
/// \param nresults The number of results to expect; -1 for any.
|
||||
///
|
||||
/// \return The number of results left on the stack.
|
||||
///
|
||||
/// \throw error If there is a problem processing the string.
|
||||
unsigned int
|
||||
lutok::do_string(state& s, const std::string& str, const int nresults)
|
||||
{
|
||||
assert(nresults >= -1);
|
||||
const int height = s.get_top();
|
||||
|
||||
stack_cleaner cleaner(s);
|
||||
try {
|
||||
s.load_string(str);
|
||||
s.pcall(0, nresults == -1 ? LUA_MULTRET : nresults, 0);
|
||||
} catch (const lutok::api_error& e) {
|
||||
throw lutok::error("Failed to process Lua string '" + str + "': " +
|
||||
e.what());
|
||||
}
|
||||
cleaner.forget();
|
||||
|
||||
const int actual_results = s.get_top() - height;
|
||||
assert(nresults == -1 || actual_results == nresults);
|
||||
assert(actual_results >= 0);
|
||||
return static_cast< unsigned int >(actual_results);
|
||||
}
|
||||
|
||||
|
||||
/// Convenience function to evaluate a Lua expression.
|
||||
///
|
||||
/// \param s The Lua state.
|
||||
/// \param expression The textual expression to evaluate.
|
||||
/// \param nresults The number of results to leave on the stack. Must be
|
||||
/// positive.
|
||||
///
|
||||
/// \throw api_error If there is a problem evaluating the expression.
|
||||
void
|
||||
lutok::eval(state& s, const std::string& expression, const int nresults)
|
||||
{
|
||||
assert(nresults > 0);
|
||||
do_string(s, "return " + expression, nresults);
|
||||
}
|
53
external/bsd/lutok/dist/operations.hpp
vendored
Normal file
53
external/bsd/lutok/dist/operations.hpp
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file operations.hpp
|
||||
/// Extra generic functions to interact with Lua.
|
||||
|
||||
#if !defined(LUTOK_OPERATIONS_HPP)
|
||||
#define LUTOK_OPERATIONS_HPP
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <lutok/state.hpp>
|
||||
|
||||
namespace lutok {
|
||||
|
||||
|
||||
void create_module(state&, const std::string&,
|
||||
const std::map< std::string, cxx_function >&);
|
||||
unsigned int do_file(state&, const std::string&, const int = 0);
|
||||
unsigned int do_string(state&, const std::string&, const int = 0);
|
||||
void eval(state&, const std::string&, const int = 1);
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
#endif // !defined(LUTOK_OPERATIONS_HPP)
|
296
external/bsd/lutok/dist/operations_test.cpp
vendored
Normal file
296
external/bsd/lutok/dist/operations_test.cpp
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "operations.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <atf-c++.hpp>
|
||||
|
||||
#include "exceptions.hpp"
|
||||
#include "state.ipp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
/// Addition function for injection into Lua.
|
||||
///
|
||||
/// \pre stack(-2) The first summand.
|
||||
/// \pre stack(-1) The second summand.
|
||||
/// \post stack(-1) The result of the sum.
|
||||
///
|
||||
/// \param state The Lua state.
|
||||
///
|
||||
/// \return The number of results (1).
|
||||
static int
|
||||
hook_add(lutok::state& state)
|
||||
{
|
||||
state.push_integer(state.to_integer(-1) + state.to_integer(-2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/// Multiplication function for injection into Lua.
|
||||
///
|
||||
/// \pre stack(-2) The first factor.
|
||||
/// \pre stack(-1) The second factor.
|
||||
/// \post stack(-1) The product.
|
||||
///
|
||||
/// \param state The Lua state.
|
||||
///
|
||||
/// \return The number of results (1).
|
||||
static int
|
||||
hook_multiply(lutok::state& state)
|
||||
{
|
||||
state.push_integer(state.to_integer(-1) * state.to_integer(-2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(create_module__empty);
|
||||
ATF_TEST_CASE_BODY(create_module__empty)
|
||||
{
|
||||
lutok::state state;
|
||||
std::map< std::string, lutok::cxx_function > members;
|
||||
lutok::create_module(state, "my_math", members);
|
||||
|
||||
state.open_base();
|
||||
lutok::do_string(state, "return next(my_math) == nil", 1);
|
||||
ATF_REQUIRE(state.to_boolean());
|
||||
state.pop(1);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(create_module__one);
|
||||
ATF_TEST_CASE_BODY(create_module__one)
|
||||
{
|
||||
lutok::state state;
|
||||
std::map< std::string, lutok::cxx_function > members;
|
||||
members["add"] = hook_add;
|
||||
lutok::create_module(state, "my_math", members);
|
||||
|
||||
lutok::do_string(state, "return my_math.add(10, 20)", 1);
|
||||
ATF_REQUIRE_EQ(30, state.to_integer());
|
||||
state.pop(1);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(create_module__many);
|
||||
ATF_TEST_CASE_BODY(create_module__many)
|
||||
{
|
||||
lutok::state state;
|
||||
std::map< std::string, lutok::cxx_function > members;
|
||||
members["add"] = hook_add;
|
||||
members["multiply"] = hook_multiply;
|
||||
members["add2"] = hook_add;
|
||||
lutok::create_module(state, "my_math", members);
|
||||
|
||||
lutok::do_string(state, "return my_math.add(10, 20)", 1);
|
||||
ATF_REQUIRE_EQ(30, state.to_integer());
|
||||
lutok::do_string(state, "return my_math.multiply(10, 20)", 1);
|
||||
ATF_REQUIRE_EQ(200, state.to_integer());
|
||||
lutok::do_string(state, "return my_math.add2(20, 30)", 1);
|
||||
ATF_REQUIRE_EQ(50, state.to_integer());
|
||||
state.pop(3);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_file__any_results);
|
||||
ATF_TEST_CASE_BODY(do_file__any_results)
|
||||
{
|
||||
std::ofstream output("test.lua");
|
||||
output << "return 10, 20, 30\n";
|
||||
output.close();
|
||||
|
||||
lutok::state state;
|
||||
ATF_REQUIRE_EQ(3, lutok::do_file(state, "test.lua", -1));
|
||||
ATF_REQUIRE_EQ(3, state.get_top());
|
||||
ATF_REQUIRE_EQ(10, state.to_integer(-3));
|
||||
ATF_REQUIRE_EQ(20, state.to_integer(-2));
|
||||
ATF_REQUIRE_EQ(30, state.to_integer(-1));
|
||||
state.pop(3);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_file__no_results);
|
||||
ATF_TEST_CASE_BODY(do_file__no_results)
|
||||
{
|
||||
std::ofstream output("test.lua");
|
||||
output << "return 10, 20, 30\n";
|
||||
output.close();
|
||||
|
||||
lutok::state state;
|
||||
ATF_REQUIRE_EQ(0, lutok::do_file(state, "test.lua"));
|
||||
ATF_REQUIRE_EQ(0, state.get_top());
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_file__many_results);
|
||||
ATF_TEST_CASE_BODY(do_file__many_results)
|
||||
{
|
||||
std::ofstream output("test.lua");
|
||||
output << "return 10, 20, 30\n";
|
||||
output.close();
|
||||
|
||||
lutok::state state;
|
||||
ATF_REQUIRE_EQ(2, lutok::do_file(state, "test.lua", 2));
|
||||
ATF_REQUIRE_EQ(2, state.get_top());
|
||||
ATF_REQUIRE_EQ(10, state.to_integer(-2));
|
||||
ATF_REQUIRE_EQ(20, state.to_integer(-1));
|
||||
state.pop(2);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_file__not_found);
|
||||
ATF_TEST_CASE_BODY(do_file__not_found)
|
||||
{
|
||||
lutok::state state;
|
||||
stack_balance_checker checker(state);
|
||||
ATF_REQUIRE_THROW_RE(lutok::file_not_found_error, "missing.lua",
|
||||
lutok::do_file(state, "missing.lua"));
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_file__error);
|
||||
ATF_TEST_CASE_BODY(do_file__error)
|
||||
{
|
||||
std::ofstream output("test.lua");
|
||||
output << "a b c\n";
|
||||
output.close();
|
||||
|
||||
lutok::state state;
|
||||
stack_balance_checker checker(state);
|
||||
ATF_REQUIRE_THROW_RE(lutok::error, "Failed to load Lua file 'test.lua'",
|
||||
lutok::do_file(state, "test.lua"));
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_string__any_results);
|
||||
ATF_TEST_CASE_BODY(do_string__any_results)
|
||||
{
|
||||
lutok::state state;
|
||||
ATF_REQUIRE_EQ(3, lutok::do_string(state, "return 10, 20, 30", -1));
|
||||
ATF_REQUIRE_EQ(3, state.get_top());
|
||||
ATF_REQUIRE_EQ(10, state.to_integer(-3));
|
||||
ATF_REQUIRE_EQ(20, state.to_integer(-2));
|
||||
ATF_REQUIRE_EQ(30, state.to_integer(-1));
|
||||
state.pop(3);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_string__no_results);
|
||||
ATF_TEST_CASE_BODY(do_string__no_results)
|
||||
{
|
||||
lutok::state state;
|
||||
ATF_REQUIRE_EQ(0, lutok::do_string(state, "return 10, 20, 30"));
|
||||
ATF_REQUIRE_EQ(0, state.get_top());
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_string__many_results);
|
||||
ATF_TEST_CASE_BODY(do_string__many_results)
|
||||
{
|
||||
lutok::state state;
|
||||
ATF_REQUIRE_EQ(2, lutok::do_string(state, "return 10, 20, 30", 2));
|
||||
ATF_REQUIRE_EQ(2, state.get_top());
|
||||
ATF_REQUIRE_EQ(10, state.to_integer(-2));
|
||||
ATF_REQUIRE_EQ(20, state.to_integer(-1));
|
||||
state.pop(2);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_string__error);
|
||||
ATF_TEST_CASE_BODY(do_string__error)
|
||||
{
|
||||
lutok::state state;
|
||||
stack_balance_checker checker(state);
|
||||
ATF_REQUIRE_THROW_RE(lutok::error, "Failed to process Lua string 'a b c'",
|
||||
lutok::do_string(state, "a b c"));
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(eval__one_result);
|
||||
ATF_TEST_CASE_BODY(eval__one_result)
|
||||
{
|
||||
lutok::state state;
|
||||
stack_balance_checker checker(state);
|
||||
lutok::eval(state, "3 + 10");
|
||||
ATF_REQUIRE_EQ(13, state.to_integer());
|
||||
state.pop(1);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(eval__many_results);
|
||||
ATF_TEST_CASE_BODY(eval__many_results)
|
||||
{
|
||||
lutok::state state;
|
||||
stack_balance_checker checker(state);
|
||||
lutok::eval(state, "5, 8, 10", 3);
|
||||
ATF_REQUIRE_EQ(5, state.to_integer(-3));
|
||||
ATF_REQUIRE_EQ(8, state.to_integer(-2));
|
||||
ATF_REQUIRE_EQ(10, state.to_integer(-1));
|
||||
state.pop(3);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(eval__error);
|
||||
ATF_TEST_CASE_BODY(eval__error)
|
||||
{
|
||||
lutok::state state;
|
||||
stack_balance_checker checker(state);
|
||||
ATF_REQUIRE_THROW(lutok::error,
|
||||
lutok::eval(state, "non_existent.method()"));
|
||||
}
|
||||
|
||||
|
||||
ATF_INIT_TEST_CASES(tcs)
|
||||
{
|
||||
ATF_ADD_TEST_CASE(tcs, create_module__empty);
|
||||
ATF_ADD_TEST_CASE(tcs, create_module__one);
|
||||
ATF_ADD_TEST_CASE(tcs, create_module__many);
|
||||
|
||||
ATF_ADD_TEST_CASE(tcs, do_file__any_results);
|
||||
ATF_ADD_TEST_CASE(tcs, do_file__no_results);
|
||||
ATF_ADD_TEST_CASE(tcs, do_file__many_results);
|
||||
ATF_ADD_TEST_CASE(tcs, do_file__not_found);
|
||||
ATF_ADD_TEST_CASE(tcs, do_file__error);
|
||||
|
||||
ATF_ADD_TEST_CASE(tcs, do_string__any_results);
|
||||
ATF_ADD_TEST_CASE(tcs, do_string__no_results);
|
||||
ATF_ADD_TEST_CASE(tcs, do_string__many_results);
|
||||
ATF_ADD_TEST_CASE(tcs, do_string__error);
|
||||
|
||||
ATF_ADD_TEST_CASE(tcs, eval__one_result);
|
||||
ATF_ADD_TEST_CASE(tcs, eval__many_results);
|
||||
ATF_ADD_TEST_CASE(tcs, eval__error);
|
||||
}
|
91
external/bsd/lutok/dist/stack_cleaner.cpp
vendored
Normal file
91
external/bsd/lutok/dist/stack_cleaner.cpp
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "stack_cleaner.hpp"
|
||||
#include "state.ipp"
|
||||
|
||||
|
||||
/// Internal implementation for lutok::stack_cleaner.
|
||||
struct lutok::stack_cleaner::impl {
|
||||
/// Reference to the Lua state this stack_cleaner refers to.
|
||||
state& state_ref;
|
||||
|
||||
/// The depth of the Lua stack to be restored.
|
||||
unsigned int original_depth;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param state_ref_ Reference to the Lua state.
|
||||
/// \param original_depth_ The depth of the Lua stack.
|
||||
impl(state& state_ref_, const unsigned int original_depth_) :
|
||||
state_ref(state_ref_),
|
||||
original_depth(original_depth_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Creates a new stack cleaner.
|
||||
///
|
||||
/// This gathers the current height of the stack so that extra elements can be
|
||||
/// popped during destruction.
|
||||
///
|
||||
/// \param state_ The Lua state.
|
||||
lutok::stack_cleaner::stack_cleaner(state& state_) :
|
||||
_pimpl(new impl(state_, state_.get_top()))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Pops any values from the stack not known at construction time.
|
||||
///
|
||||
/// \pre The current height of the stack must be equal or greater to the height
|
||||
/// of the stack when this object was instantiated.
|
||||
lutok::stack_cleaner::~stack_cleaner(void)
|
||||
{
|
||||
const unsigned int current_depth = _pimpl->state_ref.get_top();
|
||||
assert(current_depth >= _pimpl->original_depth);
|
||||
const unsigned int diff = current_depth - _pimpl->original_depth;
|
||||
if (diff > 0)
|
||||
_pimpl->state_ref.pop(diff);
|
||||
}
|
||||
|
||||
|
||||
/// Forgets about any elements currently in the stack.
|
||||
///
|
||||
/// This allows a function to return values on the stack because all the
|
||||
/// elements that are currently in the stack will not be touched during
|
||||
/// destruction when the function is called.
|
||||
void
|
||||
lutok::stack_cleaner::forget(void)
|
||||
{
|
||||
_pimpl->original_depth = _pimpl->state_ref.get_top();
|
||||
}
|
93
external/bsd/lutok/dist/stack_cleaner.hpp
vendored
Normal file
93
external/bsd/lutok/dist/stack_cleaner.hpp
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file stack_cleaner.hpp
|
||||
/// Provides the stack_cleaner class.
|
||||
|
||||
#if !defined(LUTOK_STACK_CLEANER_HPP)
|
||||
#define LUTOK_STACK_CLEANER_HPP
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <lutok/state.hpp>
|
||||
|
||||
namespace lutok {
|
||||
|
||||
|
||||
/// A RAII model for values on the Lua stack.
|
||||
///
|
||||
/// At creation time, the object records the current depth of the Lua stack and,
|
||||
/// during destruction, restores the recorded depth by popping as many stack
|
||||
/// entries as required. As a corollary, the stack can only grow during the
|
||||
/// lifetime of a stack_cleaner object (or shrink, but cannot become shorter
|
||||
/// than the depth recorded at creation time).
|
||||
///
|
||||
/// Use this class as follows:
|
||||
///
|
||||
/// state s;
|
||||
/// {
|
||||
/// stack_cleaner cleaner1(s);
|
||||
/// s.push_integer(3);
|
||||
/// s.push_integer(5);
|
||||
/// ... do stuff here ...
|
||||
/// for (...) {
|
||||
/// stack_cleaner cleaner2(s);
|
||||
/// s.load_string("...");
|
||||
/// s.pcall(0, 1, 0);
|
||||
/// ... do stuff here ...
|
||||
/// }
|
||||
/// // cleaner2 destroyed; the result of pcall is gone.
|
||||
/// }
|
||||
/// // cleaner1 destroyed; the integers 3 and 5 are gone.
|
||||
///
|
||||
/// You must give a name to the instantiated objects even if they cannot be
|
||||
/// accessed later. Otherwise, the instance will be destroyed right away and
|
||||
/// will not have the desired effect.
|
||||
class stack_cleaner {
|
||||
struct impl;
|
||||
|
||||
/// Pointer to the shared internal implementation.
|
||||
std::auto_ptr< impl > _pimpl;
|
||||
|
||||
/// Disallow copies.
|
||||
stack_cleaner(const stack_cleaner&);
|
||||
|
||||
/// Disallow assignment.
|
||||
stack_cleaner& operator=(const stack_cleaner&);
|
||||
|
||||
public:
|
||||
stack_cleaner(state&);
|
||||
~stack_cleaner(void);
|
||||
|
||||
void forget(void);
|
||||
};
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
#endif // !defined(LUTOK_STACK_CLEANER_HPP)
|
108
external/bsd/lutok/dist/stack_cleaner_test.cpp
vendored
Normal file
108
external/bsd/lutok/dist/stack_cleaner_test.cpp
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "stack_cleaner.hpp"
|
||||
|
||||
#include <atf-c++.hpp>
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(empty);
|
||||
ATF_TEST_CASE_BODY(empty)
|
||||
{
|
||||
lutok::state state;
|
||||
{
|
||||
lutok::stack_cleaner cleaner(state);
|
||||
ATF_REQUIRE_EQ(0, state.get_top());
|
||||
}
|
||||
ATF_REQUIRE_EQ(0, state.get_top());
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(some);
|
||||
ATF_TEST_CASE_BODY(some)
|
||||
{
|
||||
lutok::state state;
|
||||
{
|
||||
lutok::stack_cleaner cleaner(state);
|
||||
state.push_integer(15);
|
||||
ATF_REQUIRE_EQ(1, state.get_top());
|
||||
state.push_integer(30);
|
||||
ATF_REQUIRE_EQ(2, state.get_top());
|
||||
}
|
||||
ATF_REQUIRE_EQ(0, state.get_top());
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(nested);
|
||||
ATF_TEST_CASE_BODY(nested)
|
||||
{
|
||||
lutok::state state;
|
||||
{
|
||||
lutok::stack_cleaner cleaner1(state);
|
||||
state.push_integer(10);
|
||||
ATF_REQUIRE_EQ(1, state.get_top());
|
||||
ATF_REQUIRE_EQ(10, state.to_integer());
|
||||
{
|
||||
lutok::stack_cleaner cleaner2(state);
|
||||
state.push_integer(20);
|
||||
ATF_REQUIRE_EQ(2, state.get_top());
|
||||
ATF_REQUIRE_EQ(20, state.to_integer(-1));
|
||||
ATF_REQUIRE_EQ(10, state.to_integer(-2));
|
||||
}
|
||||
ATF_REQUIRE_EQ(1, state.get_top());
|
||||
ATF_REQUIRE_EQ(10, state.to_integer());
|
||||
}
|
||||
ATF_REQUIRE_EQ(0, state.get_top());
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(forget);
|
||||
ATF_TEST_CASE_BODY(forget)
|
||||
{
|
||||
lutok::state state;
|
||||
{
|
||||
lutok::stack_cleaner cleaner(state);
|
||||
state.push_integer(15);
|
||||
state.push_integer(30);
|
||||
cleaner.forget();
|
||||
state.push_integer(60);
|
||||
ATF_REQUIRE_EQ(3, state.get_top());
|
||||
}
|
||||
ATF_REQUIRE_EQ(2, state.get_top());
|
||||
ATF_REQUIRE_EQ(30, state.to_integer());
|
||||
state.pop(2);
|
||||
}
|
||||
|
||||
|
||||
ATF_INIT_TEST_CASES(tcs)
|
||||
{
|
||||
ATF_ADD_TEST_CASE(tcs, empty);
|
||||
ATF_ADD_TEST_CASE(tcs, some);
|
||||
ATF_ADD_TEST_CASE(tcs, nested);
|
||||
ATF_ADD_TEST_CASE(tcs, forget);
|
||||
}
|
862
external/bsd/lutok/dist/state.cpp
vendored
Normal file
862
external/bsd/lutok/dist/state.cpp
vendored
Normal file
@ -0,0 +1,862 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
}
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "c_gate.hpp"
|
||||
#include "exceptions.hpp"
|
||||
#include "state.ipp"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
/// Wrapper around lua_getglobal to run in a protected environment.
|
||||
///
|
||||
/// \pre stack(-1) is the name of the global to get.
|
||||
/// \post stack(-1) is the value of the global.
|
||||
///
|
||||
/// \param state The Lua C API state.
|
||||
///
|
||||
/// \return The number of return values pushed onto the stack.
|
||||
static int
|
||||
protected_getglobal(lua_State* state)
|
||||
{
|
||||
lua_getglobal(state, lua_tostring(state, -1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_gettable to run in a protected environment.
|
||||
///
|
||||
/// \pre stack(-2) is the table to get the element from.
|
||||
/// \pre stack(-1) is the table index.
|
||||
/// \post stack(-1) is the value of stack(-2)[stack(-1)].
|
||||
///
|
||||
/// \param state The Lua C API state.
|
||||
///
|
||||
/// \return The number of return values pushed onto the stack.
|
||||
static int
|
||||
protected_gettable(lua_State* state)
|
||||
{
|
||||
lua_gettable(state, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_next to run in a protected environment.
|
||||
///
|
||||
/// \pre stack(-2) is the table to get the next element from.
|
||||
/// \pre stack(-1) is the last processed key.
|
||||
/// \post stack(-1) is the value of next(stack(-2), stack(-1)).
|
||||
///
|
||||
/// \param state The Lua C API state.
|
||||
///
|
||||
/// \return The number of return values pushed onto the stack.
|
||||
static int
|
||||
protected_next(lua_State* state)
|
||||
{
|
||||
const int more = lua_next(state, -2) != 0;
|
||||
lua_pushboolean(state, more);
|
||||
return more ? 3 : 1;
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_setglobal to run in a protected environment.
|
||||
///
|
||||
/// \pre stack(-2) is the name of the global to set.
|
||||
/// \pre stack(-1) is the value to set the global to.
|
||||
///
|
||||
/// \param state The Lua C API state.
|
||||
///
|
||||
/// \return The number of return values pushed onto the stack.
|
||||
static int
|
||||
protected_setglobal(lua_State* state)
|
||||
{
|
||||
lua_setglobal(state, lua_tostring(state, -2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_settable to run in a protected environment.
|
||||
///
|
||||
/// \pre stack(-3) is the table to set the element into.
|
||||
/// \pre stack(-2) is the table index.
|
||||
/// \pre stack(-1) is the value to set.
|
||||
///
|
||||
/// \param state The Lua C API state.
|
||||
///
|
||||
/// \return The number of return values pushed onto the stack.
|
||||
static int
|
||||
protected_settable(lua_State* state)
|
||||
{
|
||||
lua_settable(state, -3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// Calls a C++ Lua function from a C calling environment.
|
||||
///
|
||||
/// Any errors reported by the C++ function are caught and reported to the
|
||||
/// caller as Lua errors.
|
||||
///
|
||||
/// \param function The C++ function to call.
|
||||
/// \param raw_state The raw Lua state.
|
||||
///
|
||||
/// \return The number of return values pushed onto the Lua stack by the
|
||||
/// function.
|
||||
static int
|
||||
call_cxx_function_from_c(lutok::cxx_function function,
|
||||
lua_State* raw_state) throw()
|
||||
{
|
||||
char error_buf[1024];
|
||||
|
||||
try {
|
||||
lutok::state state = lutok::state_c_gate::connect(raw_state);
|
||||
return function(state);
|
||||
} catch (const std::exception& e) {
|
||||
std::strncpy(error_buf, e.what(), sizeof(error_buf));
|
||||
} catch (...) {
|
||||
std::strncpy(error_buf, "Unhandled exception in Lua C++ hook",
|
||||
sizeof(error_buf));
|
||||
}
|
||||
error_buf[sizeof(error_buf) - 1] = '\0';
|
||||
// We raise the Lua error from outside the try/catch context and we use
|
||||
// a stack-based buffer to hold the message to ensure that we do not leak
|
||||
// any C++ objects (and, as a likely result, memory) when Lua performs its
|
||||
// longjmp.
|
||||
return luaL_error(raw_state, "%s", error_buf);
|
||||
}
|
||||
|
||||
|
||||
/// Lua glue to call a C++ closure.
|
||||
///
|
||||
/// This Lua binding is actually a closure that we have constructed from the
|
||||
/// state.push_cxx_closure() method. The closure contains the same upvalues
|
||||
/// provided by the user plus an extra upvalue that contains the address of the
|
||||
/// C++ function we have to call. All we do here is safely delegate the
|
||||
/// execution to the wrapped C++ closure.
|
||||
///
|
||||
/// \param raw_state The Lua C API state.
|
||||
///
|
||||
/// \return The number of return values of the called closure.
|
||||
static int
|
||||
cxx_closure_trampoline(lua_State* raw_state)
|
||||
{
|
||||
lutok::state state = lutok::state_c_gate::connect(raw_state);
|
||||
|
||||
int nupvalues;
|
||||
{
|
||||
lua_Debug debug;
|
||||
lua_getstack(raw_state, 0, &debug);
|
||||
lua_getinfo(raw_state, "u", &debug);
|
||||
nupvalues = debug.nups;
|
||||
}
|
||||
|
||||
lutok::cxx_function* function = state.to_userdata< lutok::cxx_function >(
|
||||
state.upvalue_index(nupvalues));
|
||||
return call_cxx_function_from_c(*function, raw_state);
|
||||
}
|
||||
|
||||
|
||||
/// Lua glue to call a C++ function.
|
||||
///
|
||||
/// This Lua binding is actually a closure that we have constructed from the
|
||||
/// state.push_cxx_function() method. The closure has a single upvalue that
|
||||
/// contains the address of the C++ function we have to call. All we do here is
|
||||
/// safely delegate the execution to the wrapped C++ function.
|
||||
///
|
||||
/// \param raw_state The Lua C API state.
|
||||
///
|
||||
/// \return The number of return values of the called function.
|
||||
static int
|
||||
cxx_function_trampoline(lua_State* raw_state)
|
||||
{
|
||||
lutok::state state = lutok::state_c_gate::connect(raw_state);
|
||||
lutok::cxx_function* function = state.to_userdata< lutok::cxx_function >(
|
||||
state.upvalue_index(1));
|
||||
return call_cxx_function_from_c(*function, raw_state);
|
||||
}
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
const int lutok::globals_index = LUA_GLOBALSINDEX;
|
||||
|
||||
|
||||
/// Internal implementation for lutok::state.
|
||||
struct lutok::state::impl {
|
||||
/// The Lua internal state.
|
||||
lua_State* lua_state;
|
||||
|
||||
/// Whether we own the state or not (to decide if we close it).
|
||||
bool owned;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// \param lua_ The Lua internal state.
|
||||
/// \param owned_ Whether we own the state or not.
|
||||
impl(lua_State* lua_, bool owned_) :
|
||||
lua_state(lua_),
|
||||
owned(owned_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Initializes the Lua state.
|
||||
///
|
||||
/// You must share the same state object alongside the lifetime of your Lua
|
||||
/// session. As soon as the object is destroyed, the session is terminated.
|
||||
lutok::state::state(void)
|
||||
{
|
||||
lua_State* lua = lua_open();
|
||||
if (lua == NULL)
|
||||
throw lutok::error("lua open failed");
|
||||
_pimpl.reset(new impl(lua, true));
|
||||
}
|
||||
|
||||
|
||||
/// Initializes the Lua state from an existing raw state.
|
||||
///
|
||||
/// Instances constructed using this method do NOT own the raw state. This
|
||||
/// means that, on exit, the state will not be destroyed.
|
||||
///
|
||||
/// \param raw_state_ The raw Lua state to wrap.
|
||||
lutok::state::state(void* raw_state_) :
|
||||
_pimpl(new impl(reinterpret_cast< lua_State* >(raw_state_), false))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Destructor for the Lua state.
|
||||
///
|
||||
/// Closes the session unless it has already been closed by calling the
|
||||
/// close() method. It is recommended to explicitly close the session in the
|
||||
/// code.
|
||||
lutok::state::~state(void)
|
||||
{
|
||||
if (_pimpl->owned && _pimpl->lua_state != NULL)
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
/// Terminates this Lua session.
|
||||
///
|
||||
/// It is recommended to call this instead of relying on the destructor to do
|
||||
/// the cleanup, but it is not a requirement to use close().
|
||||
///
|
||||
/// \pre close() has not yet been called.
|
||||
/// \pre The Lua stack is empty. This is not truly necessary but ensures that
|
||||
/// our code is consistent and clears the stack explicitly.
|
||||
void
|
||||
lutok::state::close(void)
|
||||
{
|
||||
assert(_pimpl->lua_state != NULL);
|
||||
assert(lua_gettop(_pimpl->lua_state) == 0);
|
||||
lua_close(_pimpl->lua_state);
|
||||
_pimpl->lua_state = NULL;
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_getglobal.
|
||||
///
|
||||
/// \param name The second parameter to lua_getglobal.
|
||||
///
|
||||
/// \throw api_error If lua_getglobal fails.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory to manipulate
|
||||
/// the Lua stack.
|
||||
void
|
||||
lutok::state::get_global(const std::string& name)
|
||||
{
|
||||
lua_pushcfunction(_pimpl->lua_state, protected_getglobal);
|
||||
lua_pushstring(_pimpl->lua_state, name.c_str());
|
||||
if (lua_pcall(_pimpl->lua_state, 1, 1, 0) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "lua_getglobal");
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around luaL_getmetafield.
|
||||
///
|
||||
/// \param index The second parameter to luaL_getmetafield.
|
||||
/// \param name The third parameter to luaL_getmetafield.
|
||||
///
|
||||
/// \return The return value of luaL_getmetafield.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory to manipulate
|
||||
/// the Lua stack.
|
||||
bool
|
||||
lutok::state::get_metafield(const int index, const std::string& name)
|
||||
{
|
||||
return luaL_getmetafield(_pimpl->lua_state, index, name.c_str()) != 0;
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_getmetatable.
|
||||
///
|
||||
/// \param index The second parameter to lua_getmetatable.
|
||||
///
|
||||
/// \return The return value of lua_getmetatable.
|
||||
bool
|
||||
lutok::state::get_metatable(const int index)
|
||||
{
|
||||
return lua_getmetatable(_pimpl->lua_state, index) != 0;
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_gettable.
|
||||
///
|
||||
/// \param index The second parameter to lua_gettable.
|
||||
///
|
||||
/// \throw api_error If lua_gettable fails.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory to manipulate
|
||||
/// the Lua stack.
|
||||
void
|
||||
lutok::state::get_table(const int index)
|
||||
{
|
||||
assert(lua_gettop(_pimpl->lua_state) >= 2);
|
||||
lua_pushcfunction(_pimpl->lua_state, protected_gettable);
|
||||
lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
|
||||
lua_pushvalue(_pimpl->lua_state, -3);
|
||||
if (lua_pcall(_pimpl->lua_state, 2, 1, 0) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "lua_gettable");
|
||||
lua_remove(_pimpl->lua_state, -2);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_gettop.
|
||||
///
|
||||
/// \return The return value of lua_gettop.
|
||||
int
|
||||
lutok::state::get_top(void)
|
||||
{
|
||||
return lua_gettop(_pimpl->lua_state);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_insert.
|
||||
///
|
||||
/// \param index The second parameter to lua_insert.
|
||||
void
|
||||
lutok::state::insert(const int index)
|
||||
{
|
||||
lua_insert(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_isboolean.
|
||||
///
|
||||
/// \param index The second parameter to lua_isboolean.
|
||||
///
|
||||
/// \return The return value of lua_isboolean.
|
||||
bool
|
||||
lutok::state::is_boolean(const int index)
|
||||
{
|
||||
return lua_isboolean(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_isfunction.
|
||||
///
|
||||
/// \param index The second parameter to lua_isfunction.
|
||||
///
|
||||
/// \return The return value of lua_isfunction.
|
||||
bool
|
||||
lutok::state::is_function(const int index)
|
||||
{
|
||||
return lua_isfunction(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_isnil.
|
||||
///
|
||||
/// \param index The second parameter to lua_isnil.
|
||||
///
|
||||
/// \return The return value of lua_isnil.
|
||||
bool
|
||||
lutok::state::is_nil(const int index)
|
||||
{
|
||||
return lua_isnil(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_isnumber.
|
||||
///
|
||||
/// \param index The second parameter to lua_isnumber.
|
||||
///
|
||||
/// \return The return value of lua_isnumber.
|
||||
bool
|
||||
lutok::state::is_number(const int index)
|
||||
{
|
||||
return lua_isnumber(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_isstring.
|
||||
///
|
||||
/// \param index The second parameter to lua_isstring.
|
||||
///
|
||||
/// \return The return value of lua_isstring.
|
||||
bool
|
||||
lutok::state::is_string(const int index)
|
||||
{
|
||||
return lua_isstring(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_istable.
|
||||
///
|
||||
/// \param index The second parameter to lua_istable.
|
||||
///
|
||||
/// \return The return value of lua_istable.
|
||||
bool
|
||||
lutok::state::is_table(const int index)
|
||||
{
|
||||
return lua_istable(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_isuserdata.
|
||||
///
|
||||
/// \param index The second parameter to lua_isuserdata.
|
||||
///
|
||||
/// \return The return value of lua_isuserdata.
|
||||
bool
|
||||
lutok::state::is_userdata(const int index)
|
||||
{
|
||||
return lua_isuserdata(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around luaL_loadfile.
|
||||
///
|
||||
/// \param file The second parameter to luaL_loadfile.
|
||||
///
|
||||
/// \throw api_error If luaL_loadfile returns an error.
|
||||
/// \throw file_not_found_error If the file cannot be accessed.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void
|
||||
lutok::state::load_file(const std::string& file)
|
||||
{
|
||||
if (!::access(file.c_str(), R_OK) == 0)
|
||||
throw lutok::file_not_found_error(file);
|
||||
if (luaL_loadfile(_pimpl->lua_state, file.c_str()) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "luaL_loadfile");
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around luaL_loadstring.
|
||||
///
|
||||
/// \param str The second parameter to luaL_loadstring.
|
||||
///
|
||||
/// \throw api_error If luaL_loadstring returns an error.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void
|
||||
lutok::state::load_string(const std::string& str)
|
||||
{
|
||||
if (luaL_loadstring(_pimpl->lua_state, str.c_str()) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "luaL_loadstring");
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_newtable.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void
|
||||
lutok::state::new_table(void)
|
||||
{
|
||||
lua_newtable(_pimpl->lua_state);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_newuserdata.
|
||||
///
|
||||
/// This is internal. The public type-safe interface of this method should be
|
||||
/// used instead.
|
||||
///
|
||||
/// \param size The second parameter to lua_newuserdata.
|
||||
///
|
||||
/// \return The return value of lua_newuserdata.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void*
|
||||
lutok::state::new_userdata_voidp(const size_t size)
|
||||
{
|
||||
return lua_newuserdata(_pimpl->lua_state, size);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_next.
|
||||
///
|
||||
/// \param index The second parameter to lua_next.
|
||||
///
|
||||
/// \return True if there are more elements to process; false otherwise.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
bool
|
||||
lutok::state::next(const int index)
|
||||
{
|
||||
assert(lua_istable(_pimpl->lua_state, index));
|
||||
assert(lua_gettop(_pimpl->lua_state) >= 1);
|
||||
lua_pushcfunction(_pimpl->lua_state, protected_next);
|
||||
lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
|
||||
lua_pushvalue(_pimpl->lua_state, -3);
|
||||
if (lua_pcall(_pimpl->lua_state, 2, LUA_MULTRET, 0) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "lua_next");
|
||||
const bool more = lua_toboolean(_pimpl->lua_state, -1);
|
||||
lua_pop(_pimpl->lua_state, 1);
|
||||
if (more)
|
||||
lua_remove(_pimpl->lua_state, -3);
|
||||
else
|
||||
lua_pop(_pimpl->lua_state, 1);
|
||||
return more;
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around luaopen_base.
|
||||
///
|
||||
/// \throw api_error If luaopen_base fails.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void
|
||||
lutok::state::open_base(void)
|
||||
{
|
||||
lua_pushcfunction(_pimpl->lua_state, luaopen_base);
|
||||
if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "luaopen_base");
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around luaopen_string.
|
||||
///
|
||||
/// \throw api_error If luaopen_string fails.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void
|
||||
lutok::state::open_string(void)
|
||||
{
|
||||
lua_pushcfunction(_pimpl->lua_state, luaopen_string);
|
||||
if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "luaopen_string");
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around luaopen_table.
|
||||
///
|
||||
/// \throw api_error If luaopen_table fails.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void
|
||||
lutok::state::open_table(void)
|
||||
{
|
||||
lua_pushcfunction(_pimpl->lua_state, luaopen_table);
|
||||
if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "luaopen_table");
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pcall.
|
||||
///
|
||||
/// \param nargs The second parameter to lua_pcall.
|
||||
/// \param nresults The third parameter to lua_pcall.
|
||||
/// \param errfunc The fourth parameter to lua_pcall.
|
||||
///
|
||||
/// \throw api_error If lua_pcall returns an error.
|
||||
void
|
||||
lutok::state::pcall(const int nargs, const int nresults, const int errfunc)
|
||||
{
|
||||
if (lua_pcall(_pimpl->lua_state, nargs, nresults, errfunc) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "lua_pcall");
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pop.
|
||||
///
|
||||
/// \param count The second parameter to lua_pop.
|
||||
void
|
||||
lutok::state::pop(const int count)
|
||||
{
|
||||
assert(count <= lua_gettop(_pimpl->lua_state));
|
||||
lua_pop(_pimpl->lua_state, count);
|
||||
assert(lua_gettop(_pimpl->lua_state) >= 0);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pushboolean.
|
||||
///
|
||||
/// \param value The second parameter to lua_pushboolean.
|
||||
void
|
||||
lutok::state::push_boolean(const bool value)
|
||||
{
|
||||
lua_pushboolean(_pimpl->lua_state, value ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pushcclosure.
|
||||
///
|
||||
/// This is not a pure wrapper around lua_pushcclosure because this has to do
|
||||
/// extra magic to allow passing C++ functions instead of plain C functions.
|
||||
///
|
||||
/// \param function The C++ function to be pushed as a closure.
|
||||
/// \param nvalues The number of upvalues that the function receives.
|
||||
void
|
||||
lutok::state::push_cxx_closure(cxx_function function, const int nvalues)
|
||||
{
|
||||
cxx_function *data = static_cast< cxx_function* >(
|
||||
lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function)));
|
||||
*data = function;
|
||||
lua_pushcclosure(_pimpl->lua_state, cxx_closure_trampoline, nvalues + 1);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pushcfunction.
|
||||
///
|
||||
/// This is not a pure wrapper around lua_pushcfunction because this has to do
|
||||
/// extra magic to allow passing C++ functions instead of plain C functions.
|
||||
///
|
||||
/// \param function The C++ function to be pushed.
|
||||
void
|
||||
lutok::state::push_cxx_function(cxx_function function)
|
||||
{
|
||||
cxx_function *data = static_cast< cxx_function* >(
|
||||
lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function)));
|
||||
*data = function;
|
||||
lua_pushcclosure(_pimpl->lua_state, cxx_function_trampoline, 1);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pushinteger.
|
||||
///
|
||||
/// \param value The second parameter to lua_pushinteger.
|
||||
void
|
||||
lutok::state::push_integer(const int value)
|
||||
{
|
||||
lua_pushinteger(_pimpl->lua_state, value);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pushnil.
|
||||
void
|
||||
lutok::state::push_nil(void)
|
||||
{
|
||||
lua_pushnil(_pimpl->lua_state);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pushstring.
|
||||
///
|
||||
/// \param str The second parameter to lua_pushstring.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void
|
||||
lutok::state::push_string(const std::string& str)
|
||||
{
|
||||
lua_pushstring(_pimpl->lua_state, str.c_str());
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_pushvalue.
|
||||
///
|
||||
/// \param index The second parameter to lua_pushvalue.
|
||||
void
|
||||
lutok::state::push_value(const int index)
|
||||
{
|
||||
lua_pushvalue(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_rawget.
|
||||
///
|
||||
/// \param index The second parameter to lua_rawget.
|
||||
void
|
||||
lutok::state::raw_get(const int index)
|
||||
{
|
||||
lua_rawget(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_rawset.
|
||||
///
|
||||
/// \param index The second parameter to lua_rawset.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory to manipulate
|
||||
/// the Lua stack.
|
||||
void
|
||||
lutok::state::raw_set(const int index)
|
||||
{
|
||||
lua_rawset(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_setglobal.
|
||||
///
|
||||
/// \param name The second parameter to lua_setglobal.
|
||||
///
|
||||
/// \throw api_error If lua_setglobal fails.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory to manipulate
|
||||
/// the Lua stack.
|
||||
void
|
||||
lutok::state::set_global(const std::string& name)
|
||||
{
|
||||
lua_pushcfunction(_pimpl->lua_state, protected_setglobal);
|
||||
lua_pushstring(_pimpl->lua_state, name.c_str());
|
||||
lua_pushvalue(_pimpl->lua_state, -3);
|
||||
if (lua_pcall(_pimpl->lua_state, 2, 0, 0) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "lua_setglobal");
|
||||
lua_pop(_pimpl->lua_state, 1);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_setmetatable.
|
||||
///
|
||||
/// \param index The second parameter to lua_setmetatable.
|
||||
void
|
||||
lutok::state::set_metatable(const int index)
|
||||
{
|
||||
lua_setmetatable(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_settable.
|
||||
///
|
||||
/// \param index The second parameter to lua_settable.
|
||||
///
|
||||
/// \throw api_error If lua_settable fails.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory to manipulate
|
||||
/// the Lua stack.
|
||||
void
|
||||
lutok::state::set_table(const int index)
|
||||
{
|
||||
lua_pushcfunction(_pimpl->lua_state, protected_settable);
|
||||
lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
|
||||
lua_pushvalue(_pimpl->lua_state, -4);
|
||||
lua_pushvalue(_pimpl->lua_state, -4);
|
||||
if (lua_pcall(_pimpl->lua_state, 3, 0, 0) != 0)
|
||||
throw lutok::api_error::from_stack(*this, "lua_settable");
|
||||
lua_pop(_pimpl->lua_state, 2);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_toboolean.
|
||||
///
|
||||
/// \param index The second parameter to lua_toboolean.
|
||||
///
|
||||
/// \return The return value of lua_toboolean.
|
||||
bool
|
||||
lutok::state::to_boolean(const int index)
|
||||
{
|
||||
assert(is_boolean(index));
|
||||
return lua_toboolean(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_tointeger.
|
||||
///
|
||||
/// \param index The second parameter to lua_tointeger.
|
||||
///
|
||||
/// \return The return value of lua_tointeger.
|
||||
long
|
||||
lutok::state::to_integer(const int index)
|
||||
{
|
||||
assert(is_number(index));
|
||||
return lua_tointeger(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_touserdata.
|
||||
///
|
||||
/// This is internal. The public type-safe interface of this method should be
|
||||
/// used instead.
|
||||
///
|
||||
/// \param index The second parameter to lua_touserdata.
|
||||
///
|
||||
/// \return The return value of lua_touserdata.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void*
|
||||
lutok::state::to_userdata_voidp(const int index)
|
||||
{
|
||||
return lua_touserdata(_pimpl->lua_state, index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Wrapper around lua_tostring.
|
||||
///
|
||||
/// \param index The second parameter to lua_tostring.
|
||||
///
|
||||
/// \return The return value of lua_tostring.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
std::string
|
||||
lutok::state::to_string(const int index)
|
||||
{
|
||||
assert(is_string(index));
|
||||
const char *raw_string = lua_tostring(_pimpl->lua_state, index);
|
||||
// Note that the creation of a string object below (explicit for clarity)
|
||||
// implies that the raw string is duplicated and, henceforth, the string is
|
||||
// safe even if the corresponding element is popped from the Lua stack.
|
||||
return std::string(raw_string);
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_upvalueindex.
|
||||
///
|
||||
/// \param index The first parameter to lua_upvalueindex.
|
||||
///
|
||||
/// \return The return value of lua_upvalueindex.
|
||||
int
|
||||
lutok::state::upvalue_index(const int index)
|
||||
{
|
||||
return lua_upvalueindex(index);
|
||||
}
|
||||
|
||||
|
||||
/// Gets the internal lua_State object.
|
||||
///
|
||||
/// \return The raw Lua state. This is returned as a void pointer to prevent
|
||||
/// including the lua.hpp header file from our public interface. The only way
|
||||
/// to call this method is by using the c_gate module, and c_gate takes care of
|
||||
/// casting this object to the appropriate type.
|
||||
void*
|
||||
lutok::state::raw_state(void)
|
||||
{
|
||||
return _pimpl->lua_state;
|
||||
}
|
134
external/bsd/lutok/dist/state.hpp
vendored
Normal file
134
external/bsd/lutok/dist/state.hpp
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file state.hpp
|
||||
/// Provides the state wrapper class for the Lua C state.
|
||||
|
||||
#if !defined(LUTOK_STATE_HPP)
|
||||
#define LUTOK_STATE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <tr1/memory>
|
||||
|
||||
namespace lutok {
|
||||
|
||||
|
||||
class debug;
|
||||
class state;
|
||||
|
||||
|
||||
/// The type of a C++ function that can be bound into Lua.
|
||||
///
|
||||
/// Functions of this type are free to raise exceptions. These will not
|
||||
/// propagate into the Lua C API. However, any such exceptions will be reported
|
||||
/// as a Lua error and their type will be lost.
|
||||
typedef int (*cxx_function)(state&);
|
||||
|
||||
|
||||
/// Stack index constant pointing to the globals table (_G).
|
||||
extern const int globals_index;
|
||||
|
||||
|
||||
/// A RAII model for the Lua state.
|
||||
///
|
||||
/// This class holds the state of the Lua interpreter during its existence and
|
||||
/// provides wrappers around several Lua library functions that operate on such
|
||||
/// state.
|
||||
///
|
||||
/// These wrapper functions differ from the C versions in that they use the
|
||||
/// implicit state hold by the class, they use C++ types where appropriate and
|
||||
/// they use exceptions to report errors.
|
||||
///
|
||||
/// The wrappers intend to be as lightweight as possible but, in some
|
||||
/// situations, they are pretty complex because they need to do extra work to
|
||||
/// capture the errors reported by the Lua C API. We prefer having fine-grained
|
||||
/// error control rather than efficiency, so this is OK.
|
||||
class state {
|
||||
struct impl;
|
||||
|
||||
/// Pointer to the shared internal implementation.
|
||||
std::tr1::shared_ptr< impl > _pimpl;
|
||||
|
||||
void* new_userdata_voidp(const size_t);
|
||||
void* to_userdata_voidp(const int);
|
||||
|
||||
friend class state_c_gate;
|
||||
explicit state(void*);
|
||||
void* raw_state(void);
|
||||
|
||||
public:
|
||||
state(void);
|
||||
~state(void);
|
||||
|
||||
void close(void);
|
||||
void get_global(const std::string&);
|
||||
bool get_metafield(const int, const std::string&);
|
||||
bool get_metatable(const int = -1);
|
||||
void get_table(const int = -2);
|
||||
int get_top(void);
|
||||
void insert(const int);
|
||||
bool is_boolean(const int = -1);
|
||||
bool is_function(const int = -1);
|
||||
bool is_nil(const int = -1);
|
||||
bool is_number(const int = -1);
|
||||
bool is_string(const int = -1);
|
||||
bool is_table(const int = -1);
|
||||
bool is_userdata(const int = -1);
|
||||
void load_file(const std::string&);
|
||||
void load_string(const std::string&);
|
||||
void new_table(void);
|
||||
template< typename Type > Type* new_userdata(void);
|
||||
bool next(const int = -2);
|
||||
void open_base(void);
|
||||
void open_string(void);
|
||||
void open_table(void);
|
||||
void pcall(const int, const int, const int);
|
||||
void pop(const int);
|
||||
void push_boolean(const bool);
|
||||
void push_cxx_closure(cxx_function, const int);
|
||||
void push_cxx_function(cxx_function);
|
||||
void push_integer(const int);
|
||||
void push_nil(void);
|
||||
void push_string(const std::string&);
|
||||
void push_value(const int = -1);
|
||||
void raw_get(const int = -2);
|
||||
void raw_set(const int = -3);
|
||||
void set_global(const std::string&);
|
||||
void set_metatable(const int = -2);
|
||||
void set_table(const int = -3);
|
||||
bool to_boolean(const int = -1);
|
||||
long to_integer(const int = -1);
|
||||
template< typename Type > Type* to_userdata(const int = -1);
|
||||
std::string to_string(const int = -1);
|
||||
int upvalue_index(const int);
|
||||
};
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
#endif // !defined(LUTOK_STATE_HPP)
|
67
external/bsd/lutok/dist/state.ipp
vendored
Normal file
67
external/bsd/lutok/dist/state.ipp
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#if !defined(LUTOK_STATE_IPP)
|
||||
#define LUTOK_STATE_IPP
|
||||
|
||||
#include <lutok/state.hpp>
|
||||
|
||||
namespace lutok {
|
||||
|
||||
|
||||
/// Wrapper around lua_newuserdata.
|
||||
///
|
||||
/// This allocates an object as big as the size of the provided Type.
|
||||
///
|
||||
/// \return The pointer to the allocated userdata object.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
template< typename Type >
|
||||
Type*
|
||||
state::new_userdata(void)
|
||||
{
|
||||
return static_cast< Type* >(new_userdata_voidp(sizeof(Type)));
|
||||
}
|
||||
|
||||
|
||||
/// Wrapper around lua_touserdata.
|
||||
///
|
||||
/// \param index The second parameter to lua_touserdata.
|
||||
///
|
||||
/// \return The return value of lua_touserdata.
|
||||
template< typename Type >
|
||||
Type*
|
||||
state::to_userdata(const int index)
|
||||
{
|
||||
return static_cast< Type* >(to_userdata_voidp(index));
|
||||
}
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
#endif // !defined(LUTOK_STATE_IPP)
|
1404
external/bsd/lutok/dist/state_test.cpp
vendored
Normal file
1404
external/bsd/lutok/dist/state_test.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
141
external/bsd/lutok/dist/test_utils.hpp
vendored
Normal file
141
external/bsd/lutok/dist/test_utils.hpp
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
// Copyright 2011 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/// \file test_utils.hpp
|
||||
/// Utilities for tests of the lua modules.
|
||||
///
|
||||
/// This file is intended to be included once, and only once, for every test
|
||||
/// program that needs it. All the code is herein contained to simplify the
|
||||
/// dependency chain in the build rules.
|
||||
|
||||
#if !defined(LUTOK_TEST_UTILS_HPP)
|
||||
# define LUTOK_TEST_UTILS_HPP
|
||||
#else
|
||||
# error "test_utils.hpp can only be included once"
|
||||
#endif
|
||||
|
||||
#include <atf-c++.hpp>
|
||||
|
||||
#include "c_gate.hpp"
|
||||
#include "exceptions.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
/// Checks that a given expression raises a particular lutok::api_error.
|
||||
///
|
||||
/// We cannot make any assumptions regarding the error text provided by Lua, so
|
||||
/// we resort to checking only which API function raised the error (because our
|
||||
/// code is the one hardcoding these strings).
|
||||
///
|
||||
/// \param exp_api_function The name of the Lua C API function that causes the
|
||||
/// error.
|
||||
/// \param statement The statement to execute.
|
||||
#define REQUIRE_API_ERROR(exp_api_function, statement) \
|
||||
do { \
|
||||
try { \
|
||||
statement; \
|
||||
ATF_FAIL("api_error not raised by " #statement); \
|
||||
} catch (const lutok::api_error& api_error) { \
|
||||
ATF_REQUIRE_EQ(exp_api_function, api_error.api_function()); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// Gets the pointer to the internal lua_State of a state object.
|
||||
///
|
||||
/// This is pure syntactic sugar to simplify typing in the test cases.
|
||||
///
|
||||
/// \param state The Lua state.
|
||||
///
|
||||
/// \return The internal lua_State of the input Lua state.
|
||||
static inline lua_State*
|
||||
raw(lutok::state& state)
|
||||
{
|
||||
return lutok::state_c_gate(state).c_state();
|
||||
}
|
||||
|
||||
|
||||
/// Ensures that the Lua stack maintains its original height upon exit.
|
||||
///
|
||||
/// Use an instance of this class to check that a piece of code does not have
|
||||
/// side-effects on the Lua stack.
|
||||
///
|
||||
/// To be used within a test case only.
|
||||
class stack_balance_checker {
|
||||
/// The Lua state.
|
||||
lutok::state& _state;
|
||||
|
||||
/// Whether to install a sentinel on the stack for balance enforcement.
|
||||
bool _with_sentinel;
|
||||
|
||||
/// The height of the stack on creation.
|
||||
unsigned int _old_count;
|
||||
|
||||
public:
|
||||
/// Constructs a new stack balance checker.
|
||||
///
|
||||
/// \param state_ The Lua state to validate.
|
||||
/// \param with_sentinel_ If true, insert a sentinel item into the stack and
|
||||
/// validate upon exit that the item is still there. This is an attempt
|
||||
/// to ensure that already-existing items are not removed from the stack
|
||||
/// by the code under test.
|
||||
stack_balance_checker(lutok::state& state_,
|
||||
const bool with_sentinel_ = true) :
|
||||
_state(state_),
|
||||
_with_sentinel(with_sentinel_),
|
||||
_old_count(_state.get_top())
|
||||
{
|
||||
if (_with_sentinel)
|
||||
_state.push_integer(987654321);
|
||||
}
|
||||
|
||||
/// Destructor for the object.
|
||||
///
|
||||
/// If the stack height does not match the height when the instance was
|
||||
/// created, this fails the test case.
|
||||
~stack_balance_checker(void)
|
||||
{
|
||||
if (_with_sentinel) {
|
||||
if (!_state.is_number() || _state.to_integer() != 987654321)
|
||||
ATF_FAIL("Stack corrupted: sentinel not found");
|
||||
_state.pop(1);
|
||||
}
|
||||
|
||||
unsigned int new_count = _state.get_top();
|
||||
if (_old_count != new_count)
|
||||
//ATF_FAIL(F("Stack not balanced: before %d, after %d") %
|
||||
// _old_count % new_count);
|
||||
ATF_FAIL("Stack not balanced");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // anonymous namespace
|
Loading…
Reference in New Issue
Block a user