Import lutok, a Lightweight C++ API for Lua.
This a snapshot of the latest version with git hash: 8f8eaef. Obtained from: https://github.com/jmmv/lutok Sponsored by: DARPA
This commit is contained in:
commit
4b2c3eb9d4
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*_test
|
||||
|
||||
.deps
|
||||
.libs
|
||||
Doxyfile
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
api-docs
|
||||
autom4te.cache
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
libtool
|
||||
lutok.pc
|
||||
stamp-h1
|
25
.travis.yml
Normal file
25
.travis.yml
Normal file
@ -0,0 +1,25 @@
|
||||
language: cpp
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
before_install:
|
||||
- ./admin/travis-install-deps.sh
|
||||
|
||||
env:
|
||||
- ARCH=amd64 AS_ROOT=no
|
||||
- ARCH=amd64 AS_ROOT=yes
|
||||
- ARCH=i386 AS_ROOT=no
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- compiler: clang
|
||||
env: ARCH=i386 AS_ROOT=no
|
||||
|
||||
script:
|
||||
- ./admin/travis-build.sh
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- lutok-log@googlegroups.com
|
27
COPYING
Normal file
27
COPYING
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.
|
53
Doxyfile.in
Normal file
53
Doxyfile.in
Normal file
@ -0,0 +1,53 @@
|
||||
# Copyright 2010 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.
|
||||
|
||||
BUILTIN_STL_SUPPORT = YES
|
||||
ENABLE_PREPROCESSING = YES
|
||||
EXTRACT_ANON_NSPACES = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
FILE_PATTERNS = *.cpp *.hpp *.ipp
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_TAGFILE = @top_builddir@/api-docs/api-docs.tag
|
||||
INPUT = @top_srcdir@
|
||||
INPUT_ENCODING = ISO-8859-1
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
MACRO_EXPANSION = YES
|
||||
OUTPUT_DIRECTORY = @top_builddir@/api-docs
|
||||
OUTPUT_LANGUAGE = English
|
||||
PREDEFINED = "UTILS_UNUSED_PARAM(name)=unused_ ## name"
|
||||
PROJECT_NAME = "@PACKAGE_NAME@"
|
||||
PROJECT_NUMBER = @VERSION@
|
||||
QUIET = YES
|
||||
RECURSIVE = NO
|
||||
SHORT_NAMES = YES # Cope with gnutar limitations during 'make dist'.
|
||||
SORT_BY_SCOPE_NAME = YES
|
||||
SORT_MEMBERS_CTORS_1ST = YES
|
||||
WARN_NO_PARAMDOC = YES
|
181
INSTALL
Normal file
181
INSTALL
Normal file
@ -0,0 +1,181 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
Lutok uses the GNU Automake, GNU Autoconf and GNU Libtool utilities as
|
||||
its build system. These are used only when compiling the library from
|
||||
the source code package. If you want to install Lutok from a binary
|
||||
package, you do not need to read this document.
|
||||
|
||||
For the impatient:
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make check
|
||||
Gain root privileges
|
||||
# make install
|
||||
Drop root privileges
|
||||
$ make installcheck
|
||||
|
||||
Or alternatively, install as a regular user into your home directory:
|
||||
|
||||
$ ./configure --prefix ~/local
|
||||
$ make
|
||||
$ make check
|
||||
$ make install
|
||||
$ make installcheck
|
||||
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
To build and use Lutok successfully you need:
|
||||
|
||||
* A standards-compliant C++ complier.
|
||||
* Lua 5.1 or greater.
|
||||
* pkg-config.
|
||||
|
||||
Optionally, if you want to build and run the tests (recommended), you
|
||||
need:
|
||||
|
||||
* Kyua 0.5 or greater.
|
||||
* ATF 0.15 or greater.
|
||||
|
||||
If you are building Lutok from the code on the repository, you will also
|
||||
need the following tools:
|
||||
|
||||
* GNU Autoconf.
|
||||
* GNU Automake.
|
||||
* GNU Libtool.
|
||||
|
||||
|
||||
Regenerating the build system
|
||||
=============================
|
||||
|
||||
This is not necessary if you are building from a formal release
|
||||
distribution file.
|
||||
|
||||
On the other hand, if you are building Lutok from code extracted from
|
||||
the repository, you must first regenerate the files used by the build
|
||||
system. You will also need to do this if you modify configure.ac,
|
||||
Makefile.am or any of the other build system files. To do this, simply
|
||||
run:
|
||||
|
||||
$ autoreconf -i -s
|
||||
|
||||
If ATF is installed in a different prefix than Autoconf, you will also
|
||||
need to tell autoreconf where the ATF M4 macros are located. Otherwise,
|
||||
the configure script will be incomplete and will show confusing syntax
|
||||
errors mentioning, for example, ATF_CHECK_SH. To fix this, you have
|
||||
to run autoreconf in the following manner, replacing '<atf-prefix>' with
|
||||
the appropriate path:
|
||||
|
||||
$ autoreconf -i -s -I <atf-prefix>/share/aclocal
|
||||
|
||||
|
||||
General build procedure
|
||||
=======================
|
||||
|
||||
To build and install the source package, you must follow these steps:
|
||||
|
||||
1. Configure the sources to adapt to your operating system. This is
|
||||
done using the 'configure' script located on the sources' top
|
||||
directory, and it is usually invoked without arguments unless you
|
||||
want to change the installation prefix. More details on this
|
||||
procedure are given on a later section.
|
||||
|
||||
2. Build the sources to generate the binaries and scripts. Simply run
|
||||
'make' on the sources' top directory after configuring them. No
|
||||
problems should arise.
|
||||
|
||||
3. Install the library by running 'make install'. You may need to
|
||||
become root to issue this step.
|
||||
|
||||
4. Issue any manual installation steps that may be required. These are
|
||||
described later in their own section.
|
||||
|
||||
5. Check that the installed library works by running 'make
|
||||
installcheck'. You do not need to be root to do this.
|
||||
|
||||
|
||||
Configuration flags
|
||||
===================
|
||||
|
||||
The most common, standard flags given to 'configure' are:
|
||||
|
||||
* --prefix=directory
|
||||
Possible values: Any path
|
||||
Default: /usr/local
|
||||
|
||||
Specifies where the library (binaries and all associated files) will
|
||||
be installed.
|
||||
|
||||
* --help
|
||||
Shows information about all available flags and exits immediately,
|
||||
without running any configuration tasks.
|
||||
|
||||
The following flags are specific to Lutok's 'configure' script:
|
||||
|
||||
* --enable-developer
|
||||
Possible values: yes, no
|
||||
Default: 'yes' in Git HEAD builds; 'no' in formal releases.
|
||||
|
||||
Enables several features useful for development, such as the inclusion
|
||||
of debugging symbols in all objects or the enforcement of compilation
|
||||
warnings.
|
||||
|
||||
The compiler will be executed with an exhaustive collection of warning
|
||||
detection features regardless of the value of this flag. However, such
|
||||
warnings are only fatal when --enable-developer is 'yes'.
|
||||
|
||||
* --with-atf
|
||||
Possible values: yes, no, auto.
|
||||
Default: auto.
|
||||
|
||||
Enables usage of ATF to build (and later install) the tests.
|
||||
|
||||
Setting this to 'yes' causes the configure script to look for ATF
|
||||
unconditionally and abort if not found. Setting this to 'auto' lets
|
||||
configure perform the best decision based on availability of ATF.
|
||||
Setting this to 'no' explicitly disables ATF usage.
|
||||
|
||||
When support for tests is enabled, the build process will generate the
|
||||
test programs and will later install them into the tests tree.
|
||||
Running 'make check' or 'make installcheck' from within the source
|
||||
directory will cause these tests to be run with Kyua (assuming it is
|
||||
also installed).
|
||||
|
||||
* --with-doxygen
|
||||
Possible values: yes, no, auto or a path.
|
||||
Default: auto.
|
||||
|
||||
Enables usage of Doxygen to generate documentation for internal APIs.
|
||||
|
||||
Setting this to 'yes' causes the configure script to look for Doxygen
|
||||
unconditionally and abort if not found. Setting this to 'auto' lets
|
||||
configure perform the best decision based on availability of Doxygen.
|
||||
Setting this to 'no' explicitly disables Doxygen usage. And, lastly,
|
||||
setting this to a path forces configure to use a specific Doxygen
|
||||
binary, which must exist.
|
||||
|
||||
When support for Doxygen is enabled, the build process will generate
|
||||
HTML documentation for the Lutok API. This documentation will later
|
||||
be installed in the HTML directory specified by the configure script.
|
||||
You can change the location of the HTML documents by providing your
|
||||
desired override with the '--htmldir' flag to the configure script.
|
||||
|
||||
|
||||
Run the tests!
|
||||
==============
|
||||
|
||||
Lastly, after a successful installation (and assuming you built the
|
||||
sources with support for ATF), you should periodically run the tests
|
||||
from the final location to ensure things remain stable. Do so as
|
||||
follows:
|
||||
|
||||
$ kyua test -k /usr/local/tests/lutok/Kyuafile
|
||||
|
||||
And if you see any tests fail, do not hesitate to report them in:
|
||||
|
||||
https://github.com/jmmv/lutok/issues/
|
||||
|
||||
Thank you!
|
11
Kyuafile
Normal file
11
Kyuafile
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"}
|
221
Makefile.am
Normal file
221
Makefile.am
Normal file
@ -0,0 +1,221 @@
|
||||
# Copyright 2010 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.
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
doc_DATA = AUTHORS COPYING NEWS README
|
||||
noinst_DATA = INSTALL README
|
||||
EXTRA_DIST = $(doc_DATA) INSTALL README
|
||||
|
||||
LUTOK_CFLAGS = -I$(srcdir)/include $(LUA_CFLAGS)
|
||||
LUTOK_LIBS = liblutok.la $(LUA_LIBS)
|
||||
|
||||
pkginclude_HEADERS = c_gate.hpp
|
||||
pkginclude_HEADERS += debug.hpp
|
||||
pkginclude_HEADERS += exceptions.hpp
|
||||
pkginclude_HEADERS += operations.hpp
|
||||
pkginclude_HEADERS += stack_cleaner.hpp
|
||||
pkginclude_HEADERS += state.hpp
|
||||
pkginclude_HEADERS += state.ipp
|
||||
pkginclude_HEADERS += test_utils.hpp
|
||||
|
||||
EXTRA_DIST += include/lutok/README
|
||||
EXTRA_DIST += include/lutok/c_gate.hpp
|
||||
EXTRA_DIST += include/lutok/debug.hpp
|
||||
EXTRA_DIST += include/lutok/exceptions.hpp
|
||||
EXTRA_DIST += include/lutok/operations.hpp
|
||||
EXTRA_DIST += include/lutok/stack_cleaner.hpp
|
||||
EXTRA_DIST += include/lutok/state.hpp
|
||||
EXTRA_DIST += include/lutok/state.ipp
|
||||
|
||||
lib_LTLIBRARIES = liblutok.la
|
||||
liblutok_la_SOURCES = c_gate.cpp
|
||||
liblutok_la_SOURCES += c_gate.hpp
|
||||
liblutok_la_SOURCES += debug.cpp
|
||||
liblutok_la_SOURCES += debug.hpp
|
||||
liblutok_la_SOURCES += exceptions.cpp
|
||||
liblutok_la_SOURCES += exceptions.hpp
|
||||
liblutok_la_SOURCES += operations.cpp
|
||||
liblutok_la_SOURCES += operations.hpp
|
||||
liblutok_la_SOURCES += stack_cleaner.cpp
|
||||
liblutok_la_SOURCES += stack_cleaner.hpp
|
||||
liblutok_la_SOURCES += state.cpp
|
||||
liblutok_la_SOURCES += state.hpp
|
||||
liblutok_la_SOURCES += state.ipp
|
||||
liblutok_la_SOURCES += test_utils.hpp
|
||||
liblutok_la_CPPFLAGS = $(LUTOK_CFLAGS)
|
||||
liblutok_la_LDFLAGS = -version-info 3:0:0
|
||||
liblutok_la_LIBADD = $(LUA_LIBS)
|
||||
|
||||
pkgconfig_DATA = lutok.pc
|
||||
CLEANFILES = lutok.pc
|
||||
EXTRA_DIST += lutok.pc.in
|
||||
lutok.pc: $(srcdir)/lutok.pc.in Makefile
|
||||
$(AM_V_GEN)sed -e 's#__INCLUDEDIR__#$(includedir)#g' \
|
||||
-e 's#__LIBDIR__#$(libdir)#g' \
|
||||
-e 's#__LUA_CFLAGS__#$(LUA_CFLAGS)#g' \
|
||||
-e 's#__LUA_LIBS__#$(LUA_LIBS)#g' \
|
||||
-e 's#__VERSION__#$(PACKAGE_VERSION)#g' \
|
||||
<$(srcdir)/lutok.pc.in >lutok.pc.tmp; \
|
||||
mv lutok.pc.tmp lutok.pc
|
||||
|
||||
CLEAN_TARGETS =
|
||||
DIST_HOOKS =
|
||||
PHONY_TARGETS =
|
||||
|
||||
examplesdir = $(docdir)/examples
|
||||
examples_DATA = examples/Makefile
|
||||
examples_DATA += examples/bindings.cpp
|
||||
examples_DATA += examples/hello.cpp
|
||||
examples_DATA += examples/interpreter.cpp
|
||||
examples_DATA += examples/raii.cpp
|
||||
EXTRA_DIST += $(examples_DATA)
|
||||
|
||||
if WITH_ATF
|
||||
tests_DATA = Kyuafile
|
||||
EXTRA_DIST += $(tests_DATA)
|
||||
|
||||
tests_PROGRAMS = c_gate_test
|
||||
c_gate_test_SOURCES = c_gate_test.cpp test_utils.hpp
|
||||
c_gate_test_CXXFLAGS = $(LUTOK_CFLAGS) $(ATF_CXX_CFLAGS)
|
||||
c_gate_test_LDADD = $(LUTOK_LIBS) $(ATF_CXX_LIBS)
|
||||
|
||||
tests_PROGRAMS += debug_test
|
||||
debug_test_SOURCES = debug_test.cpp test_utils.hpp
|
||||
debug_test_CXXFLAGS = $(LUTOK_CFLAGS) $(ATF_CXX_CFLAGS)
|
||||
debug_test_LDADD = $(LUTOK_LIBS) $(ATF_CXX_LIBS)
|
||||
|
||||
tests_SCRIPTS = examples_test
|
||||
CLEANFILES += examples_test
|
||||
EXTRA_DIST += examples_test.sh
|
||||
examples_test: $(srcdir)/examples_test.sh
|
||||
$(AM_V_GEN)sed -e 's,__ATF_SH__,$(ATF_SH),g' \
|
||||
-e 's,__CXX__,$(CXX),g' \
|
||||
-e 's,__EXAMPLESDIR__,$(examplesdir),g' \
|
||||
-e 's,__LIBDIR__,$(libdir),g' \
|
||||
<$(srcdir)/examples_test.sh >examples_test.tmp; \
|
||||
chmod +x examples_test.tmp; \
|
||||
rm -f examples_test; \
|
||||
mv examples_test.tmp examples_test
|
||||
|
||||
tests_PROGRAMS += exceptions_test
|
||||
exceptions_test_SOURCES = exceptions_test.cpp
|
||||
exceptions_test_CXXFLAGS = $(LUTOK_CFLAGS) $(ATF_CXX_CFLAGS)
|
||||
exceptions_test_LDADD = $(LUTOK_LIBS) $(ATF_CXX_LIBS)
|
||||
|
||||
tests_PROGRAMS += operations_test
|
||||
operations_test_SOURCES = operations_test.cpp test_utils.hpp
|
||||
operations_test_CXXFLAGS = $(LUTOK_CFLAGS) $(ATF_CXX_CFLAGS)
|
||||
operations_test_LDADD = $(LUTOK_LIBS) $(ATF_CXX_LIBS)
|
||||
|
||||
tests_PROGRAMS += stack_cleaner_test
|
||||
stack_cleaner_test_SOURCES = stack_cleaner_test.cpp test_utils.hpp
|
||||
stack_cleaner_test_CXXFLAGS = $(LUTOK_CFLAGS) $(ATF_CXX_CFLAGS)
|
||||
stack_cleaner_test_LDADD = $(LUTOK_LIBS) $(ATF_CXX_LIBS)
|
||||
|
||||
tests_PROGRAMS += state_test
|
||||
state_test_SOURCES = state_test.cpp test_utils.hpp
|
||||
state_test_CXXFLAGS = $(LUTOK_CFLAGS) $(ATF_CXX_CFLAGS)
|
||||
state_test_LDADD = $(LUTOK_LIBS) $(ATF_CXX_LIBS)
|
||||
|
||||
if HAVE_KYUA
|
||||
check-local: check-kyua
|
||||
PHONY_TARGETS += check-kyua
|
||||
check-kyua:
|
||||
$(TESTS_ENVIRONMENT) kyua test \
|
||||
--kyuafile='$(top_srcdir)/Kyuafile' --build-root='$(top_builddir)'
|
||||
|
||||
installcheck-local: installcheck-kyua
|
||||
PHONY_TARGETS += installcheck-kyua
|
||||
installcheck-kyua:
|
||||
cd $(testsdir) && $(TESTS_ENVIRONMENT) kyua test
|
||||
endif
|
||||
else
|
||||
DIST_HOOKS += dist-no-atf
|
||||
PHONY_TARGETS += dist-no-atf
|
||||
dist-no-atf:
|
||||
@echo "Sorry; cannot build a distfile without atf"
|
||||
@false
|
||||
endif
|
||||
|
||||
if WITH_DOXYGEN
|
||||
# This should probably be html-local, but it seems better to generate the
|
||||
# documentation in all cases to get warnings about missing documentation every
|
||||
# time the code is modified. (And, after all, the documentation is not
|
||||
# installed so generating it unconditionally is not a big problem.)
|
||||
all-local: api-docs/api-docs.tag
|
||||
|
||||
api-docs/api-docs.tag: $(builddir)/Doxyfile $(SOURCES)
|
||||
$(AM_V_GEN)rm -rf api-docs; \
|
||||
mkdir -p api-docs; \
|
||||
${DOXYGEN} $(builddir)/Doxyfile 2>&1 | tee api-docs/warnings; \
|
||||
rm -f api-docs/html/installdox
|
||||
api-docs/html: api-docs/api-docs.tag
|
||||
|
||||
CLEAN_TARGETS += clean-api-docs
|
||||
clean-api-docs:
|
||||
rm -rf api-docs
|
||||
|
||||
EXTRA_DIST += api-docs/html
|
||||
else
|
||||
DIST_HOOKS += dist-no-doxygen
|
||||
PHONY_TARGETS += dist-no-doxygen
|
||||
dist-no-doxygen:
|
||||
@echo "Sorry; cannot build a distfile without Doxygen"
|
||||
@false
|
||||
endif
|
||||
|
||||
install-data-local: install-api-docs
|
||||
install-api-docs: install-docDATA
|
||||
@echo "Installing HTML documentation into $(DESTDIR)$(htmldir)"
|
||||
@if [ -d api-docs/html ]; then \
|
||||
test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"; \
|
||||
( cd api-docs/html && tar cf - . ) | \
|
||||
( cd "$(DESTDIR)$(htmldir)" && tar xf - ); \
|
||||
elif [ -d "$(srcdir)/api-docs/html" ]; then \
|
||||
test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"; \
|
||||
( cd "$(srcdir)/api-docs/html" && tar cf - . ) | \
|
||||
( cd "$(DESTDIR)$(htmldir)" && tar xf - ); \
|
||||
else \
|
||||
echo "Doxygen not installed and prebuilt documents not found"; \
|
||||
fi
|
||||
|
||||
uninstall-local: uninstall-api-docs
|
||||
uninstall-api-docs:
|
||||
find "$(DESTDIR)$(htmldir)" -type d -exec chmod 755 {} \;
|
||||
rm -rf "$(DESTDIR)$(htmldir)"
|
||||
|
||||
clean-local: $(CLEAN_TARGETS)
|
||||
|
||||
PHONY_TARGETS += clean-all
|
||||
clean-all:
|
||||
GIT="$(GIT)" $(SH) $(srcdir)/admin/clean-all.sh
|
||||
|
||||
dist-hook: $(DIST_HOOKS)
|
||||
|
||||
.PHONY: ${PHONY_TARGETS}
|
68
NEWS
Normal file
68
NEWS
Normal file
@ -0,0 +1,68 @@
|
||||
Changes in version 0.4
|
||||
======================
|
||||
|
||||
Released on 2013/12/07.
|
||||
|
||||
* Cope with the lack of AM_PROG_AR in configure.ac, which first
|
||||
appeared in Automake 1.11.2. Fixes a problem in Ubuntu 10.04
|
||||
LTS, which appears stuck in 1.11.1.
|
||||
|
||||
* Stopped shipping an Atffile. The only supported way to run the tests
|
||||
is via Kyua.
|
||||
|
||||
Interface changes:
|
||||
|
||||
* Issue 5: New methods added to the state class: open_all.
|
||||
|
||||
* Removed default parameter values from all state methods and all
|
||||
standalone operations. It is often unclear what the default value is
|
||||
given that it depends on the specific Lua operation. Being explicit
|
||||
on the caller side is clearer.
|
||||
|
||||
* Modified operations do_file and do_string to support passing a number
|
||||
of arguments to the loaded chunks and an error handler to the backing
|
||||
pcall call.
|
||||
|
||||
|
||||
Changes in version 0.3
|
||||
======================
|
||||
|
||||
Released on 2013/06/14.
|
||||
|
||||
* Issue 1: Added support for Lua 5.2 while maintaining support for Lua
|
||||
5.1. Applications using Lutok can be modified to use the new
|
||||
interface in this new version and thus support both Lua releases.
|
||||
However, because of incompatible changes to the Lua API, this release
|
||||
of Lutok is incompatible with previous releases as well.
|
||||
|
||||
* Issue 3: Tweaked configure to look for Lua using the pkg-config names
|
||||
lua-5.2 and lua-5.1. These are the names used by FreeBSD.
|
||||
|
||||
Interface changes:
|
||||
|
||||
* New global constants: registry_index.
|
||||
|
||||
* New methods added to the state class: get_global_table.
|
||||
|
||||
* Removed global constants: globals_index.
|
||||
|
||||
|
||||
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
README
Normal file
27
README
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:
|
||||
|
||||
https://github.com/jmmv/lutok/
|
8
admin/.gitignore
vendored
Normal file
8
admin/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
ar-lib
|
||||
compile
|
||||
config.guess
|
||||
config.sub
|
||||
depcomp
|
||||
install-sh
|
||||
ltmain.sh
|
||||
missing
|
90
admin/clean-all.sh
Executable file
90
admin/clean-all.sh
Executable file
@ -0,0 +1,90 @@
|
||||
#! /bin/sh
|
||||
# Copyright 2010 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.
|
||||
|
||||
Prog_Name=${0##*/}
|
||||
|
||||
if [ ! -f ./state.hpp ]; then
|
||||
echo "${Prog_Name}: must be run from the source top directory" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f configure ]; then
|
||||
echo "${Prog_Name}: configure not found; nothing to clean?" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -f Makefile ] || ./configure
|
||||
make distclean
|
||||
|
||||
# Top-level directory.
|
||||
rm -f Makefile.in
|
||||
rm -f aclocal.m4
|
||||
rm -rf autom4te.cache
|
||||
rm -f config.h.in
|
||||
rm -f configure
|
||||
rm -f mkinstalldirs
|
||||
rm -f lutok-*.tar.gz
|
||||
|
||||
# admin directory.
|
||||
rm -f admin/compile
|
||||
rm -f admin/config.guess
|
||||
rm -f admin/config.sub
|
||||
rm -f admin/depcomp
|
||||
rm -f admin/install-sh
|
||||
rm -f admin/ltmain.sh
|
||||
rm -f admin/mdate-sh
|
||||
rm -f admin/missing
|
||||
rm -f admin/texinfo.tex
|
||||
|
||||
# bootstrap directory.
|
||||
rm -f bootstrap/package.m4
|
||||
rm -f bootstrap/testsuite
|
||||
|
||||
# doc directory.
|
||||
rm -f doc/*.info
|
||||
rm -f doc/stamp-vti
|
||||
rm -f doc/version.texi
|
||||
|
||||
# m4 directory.
|
||||
rm -f m4/libtool.m4
|
||||
rm -f m4/lt*.m4
|
||||
|
||||
# Files and directories spread all around the tree.
|
||||
find . -name '#*' | xargs rm -rf
|
||||
find . -name '*~' | xargs rm -rf
|
||||
find . -name .deps | xargs rm -rf
|
||||
find . -name .gdb_history | xargs rm -rf
|
||||
find . -name .libs | xargs rm -rf
|
||||
find . -name .tmp | xargs rm -rf
|
||||
|
||||
# Show remaining files.
|
||||
if [ -n "${GIT}" ]; then
|
||||
echo ">>> untracked and ignored files"
|
||||
"${GIT}" status --porcelain --ignored | grep -E '^(\?\?|!!)' || true
|
||||
fi
|
51
admin/travis-build.sh
Executable file
51
admin/travis-build.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#! /bin/sh
|
||||
# Copyright 2014 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.
|
||||
|
||||
set -e -x
|
||||
|
||||
if [ -d /usr/local/share/aclocal ]; then
|
||||
autoreconf -isv -I/usr/local/share/aclocal
|
||||
else
|
||||
autoreconf -isv
|
||||
fi
|
||||
./configure
|
||||
|
||||
archflags=
|
||||
[ "${ARCH?}" != i386 ] || archflags=-m32
|
||||
|
||||
f=
|
||||
f="${f} CPPFLAGS='-I/usr/local/include'"
|
||||
f="${f} CXX='${CXX} ${archflags}'"
|
||||
f="${f} LDFLAGS='-L/usr/local/lib -Wl,-R/usr/local/lib'"
|
||||
f="${f} PKG_CONFIG_PATH='/usr/local/lib/pkgconfig'"
|
||||
if [ "${AS_ROOT:-no}" = yes ]; then
|
||||
sudo -H PATH="${PATH}" make distcheck DISTCHECK_CONFIGURE_FLAGS="${f}"
|
||||
else
|
||||
make distcheck DISTCHECK_CONFIGURE_FLAGS="${f}"
|
||||
fi
|
109
admin/travis-install-deps.sh
Executable file
109
admin/travis-install-deps.sh
Executable file
@ -0,0 +1,109 @@
|
||||
#! /bin/sh
|
||||
# Copyright 2014 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.
|
||||
|
||||
set -e -x
|
||||
|
||||
install_deps() {
|
||||
sudo apt-get update -qq
|
||||
|
||||
local pkgsuffix=
|
||||
local packages=
|
||||
if [ "${ARCH?}" = i386 ]; then
|
||||
pkgsuffix=:i386
|
||||
packages="${packages} gcc-multilib"
|
||||
packages="${packages} g++-multilib"
|
||||
fi
|
||||
packages="${packages} doxygen"
|
||||
packages="${packages} gdb"
|
||||
packages="${packages} liblua5.2-0${pkgsuffix}"
|
||||
packages="${packages} liblua5.2-dev${pkgsuffix}"
|
||||
packages="${packages} libsqlite3-0${pkgsuffix}"
|
||||
packages="${packages} libsqlite3-dev${pkgsuffix}"
|
||||
packages="${packages} pkg-config${pkgsuffix}"
|
||||
packages="${packages} sqlite3"
|
||||
sudo apt-get install -y ${packages}
|
||||
}
|
||||
|
||||
install_from_github() {
|
||||
local project="${1}"; shift
|
||||
local name="${1}"; shift
|
||||
local release="${1}"; shift
|
||||
|
||||
local distname="${name}-${release}"
|
||||
|
||||
local baseurl="https://github.com/jmmv/${project}"
|
||||
wget --no-check-certificate \
|
||||
"${baseurl}/releases/download/${distname}/${distname}.tar.gz"
|
||||
tar -xzvf "${distname}.tar.gz"
|
||||
|
||||
local archflags=
|
||||
[ "${ARCH?}" != i386 ] || archflags=-m32
|
||||
|
||||
cd "${distname}"
|
||||
./configure \
|
||||
--disable-developer \
|
||||
--without-atf \
|
||||
--without-doxygen \
|
||||
CFLAGS="${archflags}" \
|
||||
CPPFLAGS="-I/usr/local/include" \
|
||||
CXXFLAGS="${archflags}" \
|
||||
LDFLAGS="-L/usr/local/lib -Wl,-R/usr/local/lib" \
|
||||
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
|
||||
make
|
||||
sudo make install
|
||||
cd -
|
||||
|
||||
rm -rf "${distname}" "${distname}.tar.gz"
|
||||
}
|
||||
|
||||
install_from_bintray() {
|
||||
case "${ARCH?}" in
|
||||
amd64)
|
||||
name="20160204-usr-local-kyua-ubuntu-12-04-amd64-${CC?}.tar.gz"
|
||||
;;
|
||||
i386)
|
||||
name="20160714-usr-local-kyua-ubuntu-12-04-i386-${CC?}.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unknown ARCH value ${ARCH}" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
wget "http://dl.bintray.com/jmmv/kyua/${name}" || return 1
|
||||
sudo tar -xzvp -C / -f "${name}"
|
||||
rm -f "${name}"
|
||||
}
|
||||
|
||||
install_deps
|
||||
if ! install_from_bintray; then
|
||||
install_from_github atf atf 0.20
|
||||
install_from_github lutok lutok 0.4
|
||||
install_from_github kyua kyua-testers 0.2
|
||||
install_from_github kyua kyua-cli 0.8
|
||||
fi
|
76
c_gate.cpp
Normal file
76
c_gate.cpp
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
c_gate.hpp
Normal file
71
c_gate.hpp
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
c_gate_test.cpp
Normal file
74
c_gate_test.cpp
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 = luaL_newstate();
|
||||
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);
|
||||
}
|
70
configure.ac
Normal file
70
configure.ac
Normal file
@ -0,0 +1,70 @@
|
||||
dnl Copyright 2011 Google Inc.
|
||||
dnl All rights reserved.
|
||||
dnl
|
||||
dnl Redistribution and use in source and binary forms, with or without
|
||||
dnl modification, are permitted provided that the following conditions are
|
||||
dnl met:
|
||||
dnl
|
||||
dnl * Redistributions of source code must retain the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer.
|
||||
dnl * Redistributions in binary form must reproduce the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer in the
|
||||
dnl documentation and/or other materials provided with the distribution.
|
||||
dnl * Neither the name of Google Inc. nor the names of its contributors
|
||||
dnl may be used to endorse or promote products derived from this software
|
||||
dnl without specific prior written permission.
|
||||
dnl
|
||||
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
AC_INIT([Lutok], [0.4],
|
||||
[lutok-discuss@googlegroups.com], [lutok],
|
||||
[https://github.com/jmmv/lutok/])
|
||||
AC_PREREQ([2.65])
|
||||
|
||||
|
||||
AC_COPYRIGHT([Copyright 2011 Google Inc.])
|
||||
AC_CONFIG_AUX_DIR([admin])
|
||||
AC_CONFIG_FILES([Doxyfile Makefile])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_SRCDIR([state.hpp])
|
||||
|
||||
|
||||
AM_INIT_AUTOMAKE([1.9 check-news foreign subdir-objects -Wall])
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
LT_INIT
|
||||
|
||||
|
||||
AC_LANG([C++])
|
||||
AC_PROG_CXX
|
||||
KYUA_REQUIRE_CXX
|
||||
KYUA_DEVELOPER_MODE([C++])
|
||||
|
||||
|
||||
ATF_CHECK_CXX([>= 0.15])
|
||||
ATF_CHECK_SH([>= 0.15])
|
||||
ATF_ARG_WITH
|
||||
KYUA_DOXYGEN
|
||||
KYUA_LUA
|
||||
|
||||
|
||||
AC_PATH_PROG([KYUA], [kyua])
|
||||
AM_CONDITIONAL([HAVE_KYUA], [test -n "${KYUA}"])
|
||||
AC_PATH_PROG([GIT], [git])
|
||||
|
||||
|
||||
AC_SUBST(pkgconfigdir, \${libdir}/pkgconfig)
|
||||
AC_SUBST(testsdir, \${exec_prefix}/tests/lutok)
|
||||
|
||||
|
||||
AC_OUTPUT
|
192
debug.cpp
Normal file
192
debug.cpp
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;
|
||||
}
|
90
debug.hpp
Normal file
90
debug.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
// 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>
|
||||
#if defined(_LIBCPP_VERSION) || __cplusplus >= 201103L
|
||||
#include <memory>
|
||||
#else
|
||||
#include <tr1/memory>
|
||||
#endif
|
||||
|
||||
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.
|
||||
#if defined(_LIBCPP_VERSION) || __cplusplus >= 201103L
|
||||
std::shared_ptr< impl > _pimpl;
|
||||
#else
|
||||
std::tr1::shared_ptr< impl > _pimpl;
|
||||
#endif
|
||||
|
||||
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
debug_test.cpp
Normal file
68
debug_test.cpp
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);
|
||||
}
|
67
examples/Makefile
Normal file
67
examples/Makefile
Normal file
@ -0,0 +1,67 @@
|
||||
# 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.
|
||||
|
||||
CXX ?= c++
|
||||
CPPFLAGS ?=
|
||||
CXXFLAGS ?= -Wall -O2
|
||||
LDFLAGS ?=
|
||||
LIBS ?=
|
||||
|
||||
LUTOK_CPPFLAGS = $$(pkg-config --cflags-only-I lutok)
|
||||
LUTOK_CXXFLAGS = $$(pkg-config --cflags-only-other lutok)
|
||||
LUTOK_LDFLAGS = $$(pkg-config --libs-only-L lutok) \
|
||||
$$(pkg-config --libs-only-other lutok)
|
||||
LUTOK_LIBS = $$(pkg-config --libs-only-l lutok)
|
||||
|
||||
BUILD = $(CXX) \
|
||||
$(CPPFLAGS) $(LUTOK_CPPFLAGS) \
|
||||
$(CXXFLAGS) $(LUTOK_CXXFLAGS) \
|
||||
$(LDFLAGS) $(LUTOK_LDFLAGS) \
|
||||
-o $${target} $${source} \
|
||||
$(LIBS) $(LUTOK_LIBS)
|
||||
|
||||
PROGRAMS = bindings hello interpreter raii
|
||||
|
||||
.PHONY: all
|
||||
all: $(PROGRAMS)
|
||||
|
||||
bindings: bindings.cpp
|
||||
@target=bindings source=bindings.cpp; echo $(BUILD); $(BUILD)
|
||||
|
||||
hello: hello.cpp
|
||||
@target=hello source=hello.cpp; echo $(BUILD); $(BUILD)
|
||||
|
||||
interpreter: interpreter.cpp
|
||||
@target=interpreter source=interpreter.cpp; echo $(BUILD); $(BUILD)
|
||||
|
||||
raii: raii.cpp
|
||||
@target=raii source=raii.cpp; echo $(BUILD); $(BUILD)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(PROGRAMS)
|
133
examples/bindings.cpp
Normal file
133
examples/bindings.cpp
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(-1))
|
||||
throw std::runtime_error("Argument to factorial must be an integer");
|
||||
const int i = state.to_integer(-1);
|
||||
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(), 0, 0, 0);
|
||||
return EXIT_SUCCESS;
|
||||
} catch (const lutok::error& e) {
|
||||
std::cerr << "ERROR: " << e.what() << '\n';
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
58
examples/hello.cpp
Normal file
58
examples/hello.cpp
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
examples/interpreter.cpp
Normal file
83
examples/interpreter.cpp
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, 0, 0, 0);
|
||||
} 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;
|
||||
}
|
126
examples/raii.cpp
Normal file
126
examples/raii.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
// 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(-1));
|
||||
|
||||
// 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(-2);
|
||||
// Stack contents: -2: table, -1: field value.
|
||||
|
||||
if (!state.is_string(-1)) {
|
||||
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(-1)
|
||||
<< '\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'}",
|
||||
0, 0, 0);
|
||||
|
||||
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;
|
||||
}
|
115
examples_test.sh
Executable file
115
examples_test.sh
Executable file
@ -0,0 +1,115 @@
|
||||
#! __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.
|
||||
|
||||
Cxx="__CXX__"
|
||||
ExamplesDir="__EXAMPLESDIR__"
|
||||
LibDir="__LIBDIR__"
|
||||
|
||||
|
||||
make_example() {
|
||||
cp "${ExamplesDir}/Makefile" "${ExamplesDir}/${1}.cpp" .
|
||||
make CXX="${Cxx}" "${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
exceptions.cpp
Normal file
126
exceptions.cpp
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
exceptions.hpp
Normal file
83
exceptions.hpp
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
exceptions_test.cpp
Normal file
88
exceptions_test.cpp
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(-1));
|
||||
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);
|
||||
}
|
4
include/lutok/README
Normal file
4
include/lutok/README
Normal file
@ -0,0 +1,4 @@
|
||||
This directory contains forward includes for the public header files of
|
||||
Lutok. These files are only necessary during the build of Lutok itself
|
||||
so that the compiler can locate the include files in a path that mimics
|
||||
the final installation location.
|
1
include/lutok/c_gate.hpp
Normal file
1
include/lutok/c_gate.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "../../c_gate.hpp"
|
1
include/lutok/debug.hpp
Normal file
1
include/lutok/debug.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "../../debug.hpp"
|
1
include/lutok/exceptions.hpp
Normal file
1
include/lutok/exceptions.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "../../exceptions.hpp"
|
1
include/lutok/operations.hpp
Normal file
1
include/lutok/operations.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "../../operations.hpp"
|
1
include/lutok/stack_cleaner.hpp
Normal file
1
include/lutok/stack_cleaner.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "../../stack_cleaner.hpp"
|
1
include/lutok/state.hpp
Normal file
1
include/lutok/state.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "../../state.hpp"
|
1
include/lutok/state.ipp
Normal file
1
include/lutok/state.ipp
Normal file
@ -0,0 +1 @@
|
||||
#include "../../state.ipp"
|
8
lutok.pc.in
Normal file
8
lutok.pc.in
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
|
5
m4/.gitignore
vendored
Normal file
5
m4/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
libtool.m4
|
||||
ltoptions.m4
|
||||
ltsugar.m4
|
||||
ltversion.m4
|
||||
lt~obsolete.m4
|
100
m4/compiler-features.m4
Normal file
100
m4/compiler-features.m4
Normal file
@ -0,0 +1,100 @@
|
||||
dnl Copyright 2010 Google Inc.
|
||||
dnl All rights reserved.
|
||||
dnl
|
||||
dnl Redistribution and use in source and binary forms, with or without
|
||||
dnl modification, are permitted provided that the following conditions are
|
||||
dnl met:
|
||||
dnl
|
||||
dnl * Redistributions of source code must retain the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer.
|
||||
dnl * Redistributions in binary form must reproduce the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer in the
|
||||
dnl documentation and/or other materials provided with the distribution.
|
||||
dnl * Neither the name of Google Inc. nor the names of its contributors
|
||||
dnl may be used to endorse or promote products derived from this software
|
||||
dnl without specific prior written permission.
|
||||
dnl
|
||||
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
dnl
|
||||
dnl KYUA_REQUIRE_CXX
|
||||
dnl
|
||||
dnl Ensures the C++ compiler detected by AC_PROG_CXX is present and works.
|
||||
dnl The compiler check should be performed here, but it seems like Autoconf
|
||||
dnl does not allow it.
|
||||
dnl
|
||||
AC_DEFUN([KYUA_REQUIRE_CXX], [
|
||||
AC_CACHE_CHECK([whether the C++ compiler works],
|
||||
[atf_cv_prog_cxx_works],
|
||||
[AC_LANG_PUSH([C++])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
|
||||
[atf_cv_prog_cxx_works=yes],
|
||||
[atf_cv_prog_cxx_works=no])
|
||||
AC_LANG_POP([C++])])
|
||||
if test "${atf_cv_prog_cxx_works}" = no; then
|
||||
AC_MSG_ERROR([C++ compiler cannot create executables])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl KYUA_ATTRIBUTE_NORETURN
|
||||
dnl
|
||||
dnl Checks if the current compiler has a way to mark functions that do not
|
||||
dnl return and defines ATTRIBUTE_NORETURN to the appropriate string.
|
||||
dnl
|
||||
AC_DEFUN([KYUA_ATTRIBUTE_NORETURN], [
|
||||
dnl This check is overly simple and should be fixed. For example,
|
||||
dnl Sun's cc does support the noreturn attribute but CC (the C++
|
||||
dnl compiler) does not. And in that case, CC just raises a warning
|
||||
dnl during compilation, not an error.
|
||||
AC_MSG_CHECKING(whether __attribute__((noreturn)) is supported)
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM([], [
|
||||
#if ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
])],
|
||||
[AC_MSG_RESULT(yes)
|
||||
value="__attribute__((noreturn))"],
|
||||
[AC_MSG_RESULT(no)
|
||||
value=""]
|
||||
)
|
||||
AC_SUBST([ATTRIBUTE_NORETURN], [${value}])
|
||||
])
|
||||
|
||||
|
||||
dnl
|
||||
dnl KYUA_ATTRIBUTE_UNUSED
|
||||
dnl
|
||||
dnl Checks if the current compiler has a way to mark parameters as unused
|
||||
dnl so that the -Wunused-parameter warning can be avoided.
|
||||
dnl
|
||||
AC_DEFUN([KYUA_ATTRIBUTE_UNUSED], [
|
||||
AC_MSG_CHECKING(whether __attribute__((__unused__)) is supported)
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([
|
||||
static void
|
||||
function(int a __attribute__((__unused__)))
|
||||
{
|
||||
}], [
|
||||
function(3);
|
||||
return 0;
|
||||
])],
|
||||
[AC_MSG_RESULT(yes)
|
||||
value="__attribute__((__unused__))"],
|
||||
[AC_MSG_RESULT(no)
|
||||
value=""]
|
||||
)
|
||||
AC_SUBST([ATTRIBUTE_UNUSED], [${value}])
|
||||
])
|
159
m4/compiler-flags.m4
Normal file
159
m4/compiler-flags.m4
Normal file
@ -0,0 +1,159 @@
|
||||
dnl Copyright 2010 Google Inc.
|
||||
dnl All rights reserved.
|
||||
dnl
|
||||
dnl Redistribution and use in source and binary forms, with or without
|
||||
dnl modification, are permitted provided that the following conditions are
|
||||
dnl met:
|
||||
dnl
|
||||
dnl * Redistributions of source code must retain the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer.
|
||||
dnl * Redistributions in binary form must reproduce the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer in the
|
||||
dnl documentation and/or other materials provided with the distribution.
|
||||
dnl * Neither the name of Google Inc. nor the names of its contributors
|
||||
dnl may be used to endorse or promote products derived from this software
|
||||
dnl without specific prior written permission.
|
||||
dnl
|
||||
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
dnl \file compiler-flags.m4
|
||||
dnl
|
||||
dnl Macros to check for the existence of compiler flags. The macros in this
|
||||
dnl file support both C and C++.
|
||||
dnl
|
||||
dnl Be aware that, in order to detect a flag accurately, we may need to enable
|
||||
dnl strict warning checking in the compiler (i.e. enable -Werror). Some
|
||||
dnl compilers, e.g. Clang, report unknown -W flags as warnings unless -Werror is
|
||||
dnl selected. This fact would confuse the flag checks below because we would
|
||||
dnl conclude that a flag is valid while in reality it is not. To resolve this,
|
||||
dnl the macros below will pass -Werror to the compiler along with any other flag
|
||||
dnl being checked.
|
||||
|
||||
|
||||
dnl Checks for a compiler flag and sets a result variable.
|
||||
dnl
|
||||
dnl This is an auxiliary macro for the implementation of _KYUA_FLAG.
|
||||
dnl
|
||||
dnl \param 1 The shell variable containing the compiler name. Used for
|
||||
dnl reporting purposes only. C or CXX.
|
||||
dnl \param 2 The shell variable containing the flags for the compiler.
|
||||
dnl CFLAGS or CXXFLAGS.
|
||||
dnl \param 3 The name of the compiler flag to check for.
|
||||
dnl \param 4 The shell variable to set with the result of the test. Will
|
||||
dnl be set to 'yes' if the flag is valid, 'no' otherwise.
|
||||
dnl \param 5 Additional, optional flags to pass to the C compiler while
|
||||
dnl looking for the flag in $3. We use this here to pass -Werror to the
|
||||
dnl flag checks (unless we are checking for -Werror already).
|
||||
AC_DEFUN([_KYUA_FLAG_AUX], [
|
||||
if test x"${$4-unset}" = xunset; then
|
||||
AC_MSG_CHECKING(whether ${$1} supports $3)
|
||||
saved_flags="${$2}"
|
||||
$4=no
|
||||
$2="${$2} $5 $3"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
|
||||
AC_MSG_RESULT(yes)
|
||||
$4=yes,
|
||||
AC_MSG_RESULT(no))
|
||||
$2="${saved_flags}"
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl Checks for a compiler flag and appends it to a result variable.
|
||||
dnl
|
||||
dnl \param 1 The shell variable containing the compiler name. Used for
|
||||
dnl reporting purposes only. CC or CXX.
|
||||
dnl \param 2 The shell variable containing the flags for the compiler.
|
||||
dnl CFLAGS or CXXFLAGS.
|
||||
dnl \param 3 The name of the compiler flag to check for.
|
||||
dnl \param 4 The shell variable to which to append $3 if the flag is valid.
|
||||
AC_DEFUN([_KYUA_FLAG], [
|
||||
_KYUA_FLAG_AUX([$1], [$2], [-Werror], [kyua_$1_has_werror])
|
||||
if test "$3" = "-Werror"; then
|
||||
found=${kyua_$1_has_werror}
|
||||
else
|
||||
found=unset
|
||||
if test ${kyua_$1_has_werror} = yes; then
|
||||
_KYUA_FLAG_AUX([$1], [$2], [$3], [found], [-Werror])
|
||||
else
|
||||
_KYUA_FLAG_AUX([$1], [$2], [$3], [found], [])
|
||||
fi
|
||||
fi
|
||||
if test ${found} = yes; then
|
||||
$4="${$4} $3"
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl Checks for a C compiler flag and appends it to a variable.
|
||||
dnl
|
||||
dnl \pre The current language is C.
|
||||
dnl
|
||||
dnl \param 1 The name of the compiler flag to check for.
|
||||
dnl \param 2 The shell variable to which to append $1 if the flag is valid.
|
||||
AC_DEFUN([KYUA_CC_FLAG], [
|
||||
AC_LANG_ASSERT([C])
|
||||
_KYUA_FLAG([CC], [CFLAGS], [$1], [$2])
|
||||
])
|
||||
|
||||
|
||||
dnl Checks for a C++ compiler flag and appends it to a variable.
|
||||
dnl
|
||||
dnl \pre The current language is C++.
|
||||
dnl
|
||||
dnl \param 1 The name of the compiler flag to check for.
|
||||
dnl \param 2 The shell variable to which to append $1 if the flag is valid.
|
||||
AC_DEFUN([KYUA_CXX_FLAG], [
|
||||
AC_LANG_ASSERT([C++])
|
||||
_KYUA_FLAG([CXX], [CXXFLAGS], [$1], [$2])
|
||||
])
|
||||
|
||||
|
||||
dnl Checks for a set of C compiler flags and appends them to CFLAGS.
|
||||
dnl
|
||||
dnl The checks are performed independently and only when all the checks are
|
||||
dnl done, the output variable is modified.
|
||||
dnl
|
||||
dnl \param 1 Whitespace-separated list of C flags to check.
|
||||
AC_DEFUN([KYUA_CC_FLAGS], [
|
||||
AC_LANG_PUSH([C])
|
||||
valid_cflags=
|
||||
for f in $1; do
|
||||
KYUA_CC_FLAG(${f}, valid_cflags)
|
||||
done
|
||||
if test -n "${valid_cflags}"; then
|
||||
CFLAGS="${CFLAGS} ${valid_cflags}"
|
||||
fi
|
||||
AC_LANG_POP([C])
|
||||
])
|
||||
|
||||
|
||||
dnl Checks for a set of C++ compiler flags and appends them to CXXFLAGS.
|
||||
dnl
|
||||
dnl The checks are performed independently and only when all the checks are
|
||||
dnl done, the output variable is modified.
|
||||
dnl
|
||||
dnl \pre The current language is C++.
|
||||
dnl
|
||||
dnl \param 1 Whitespace-separated list of C flags to check.
|
||||
AC_DEFUN([KYUA_CXX_FLAGS], [
|
||||
AC_LANG_PUSH([C++])
|
||||
valid_cxxflags=
|
||||
for f in $1; do
|
||||
KYUA_CXX_FLAG(${f}, valid_cxxflags)
|
||||
done
|
||||
if test -n "${valid_cxxflags}"; then
|
||||
CXXFLAGS="${CXXFLAGS} ${valid_cxxflags}"
|
||||
fi
|
||||
AC_LANG_POP([C++])
|
||||
])
|
112
m4/developer-mode.m4
Normal file
112
m4/developer-mode.m4
Normal file
@ -0,0 +1,112 @@
|
||||
dnl Copyright 2010 Google Inc.
|
||||
dnl All rights reserved.
|
||||
dnl
|
||||
dnl Redistribution and use in source and binary forms, with or without
|
||||
dnl modification, are permitted provided that the following conditions are
|
||||
dnl met:
|
||||
dnl
|
||||
dnl * Redistributions of source code must retain the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer.
|
||||
dnl * Redistributions in binary form must reproduce the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer in the
|
||||
dnl documentation and/or other materials provided with the distribution.
|
||||
dnl * Neither the name of Google Inc. nor the names of its contributors
|
||||
dnl may be used to endorse or promote products derived from this software
|
||||
dnl without specific prior written permission.
|
||||
dnl
|
||||
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
dnl \file developer-mode.m4
|
||||
dnl
|
||||
dnl "Developer mode" is a mode in which the build system reports any
|
||||
dnl build-time warnings as fatal errors. This helps in minimizing the
|
||||
dnl amount of trivial coding problems introduced in the code.
|
||||
dnl Unfortunately, this is not bullet-proof due to the wide variety of
|
||||
dnl compilers available and their different warning diagnostics.
|
||||
dnl
|
||||
dnl When developer mode support is added to a package, the compilation will
|
||||
dnl gain a bunch of extra warning diagnostics. These will NOT be enforced
|
||||
dnl unless developer mode is enabled.
|
||||
dnl
|
||||
dnl Developer mode is enabled when the user requests it through the
|
||||
dnl configure command line, or when building from the repository. The
|
||||
dnl latter is to minimize the risk of committing new code with warnings
|
||||
dnl into the tree.
|
||||
|
||||
|
||||
dnl Adds "developer mode" support to the package.
|
||||
dnl
|
||||
dnl This macro performs the actual definition of the --enable-developer
|
||||
dnl flag and implements all of its logic. See the file-level comment for
|
||||
dnl details as to what this implies.
|
||||
AC_DEFUN([KYUA_DEVELOPER_MODE], [
|
||||
m4_foreach([language], [$1], [m4_set_add([languages], language)])
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[developer],
|
||||
AS_HELP_STRING([--enable-developer], [enable developer features]),,
|
||||
[if test -d ${srcdir}/.git; then
|
||||
AC_MSG_NOTICE([building from HEAD; developer mode autoenabled])
|
||||
enable_developer=yes
|
||||
else
|
||||
enable_developer=no
|
||||
fi])
|
||||
|
||||
#
|
||||
# The following warning flags should also be enabled but cannot be.
|
||||
# Reasons given below.
|
||||
#
|
||||
# -Wold-style-cast: Raises errors when using TIOCGWINSZ, at least under
|
||||
# Mac OS X. This is due to the way _IOR is defined.
|
||||
#
|
||||
|
||||
try_c_cxx_flags="-D_FORTIFY_SOURCE=2 \
|
||||
-Wall \
|
||||
-Wcast-qual \
|
||||
-Wextra \
|
||||
-Wpointer-arith \
|
||||
-Wredundant-decls \
|
||||
-Wreturn-type \
|
||||
-Wshadow \
|
||||
-Wsign-compare \
|
||||
-Wswitch \
|
||||
-Wwrite-strings"
|
||||
|
||||
try_c_flags="-Wmissing-prototypes \
|
||||
-Wno-traditional \
|
||||
-Wstrict-prototypes"
|
||||
|
||||
try_cxx_flags="-Wabi \
|
||||
-Wctor-dtor-privacy \
|
||||
-Wno-deprecated \
|
||||
-Wno-non-template-friend \
|
||||
-Wno-pmf-conversions \
|
||||
-Wnon-virtual-dtor \
|
||||
-Woverloaded-virtual \
|
||||
-Wreorder \
|
||||
-Wsign-promo \
|
||||
-Wsynth"
|
||||
|
||||
if test ${enable_developer} = yes; then
|
||||
try_werror=yes
|
||||
try_c_cxx_flags="${try_c_cxx_flags} -g -Werror"
|
||||
else
|
||||
try_werror=no
|
||||
try_c_cxx_flags="${try_c_cxx_flags} -DNDEBUG"
|
||||
fi
|
||||
|
||||
m4_set_contains([languages], [C],
|
||||
[KYUA_CC_FLAGS(${try_c_cxx_flags} ${try_c_flags})])
|
||||
m4_set_contains([languages], [C++],
|
||||
[KYUA_CXX_FLAGS(${try_c_cxx_flags} ${try_cxx_flags})])
|
||||
])
|
62
m4/doxygen.m4
Normal file
62
m4/doxygen.m4
Normal file
@ -0,0 +1,62 @@
|
||||
dnl Copyright 2010 Google Inc.
|
||||
dnl All rights reserved.
|
||||
dnl
|
||||
dnl Redistribution and use in source and binary forms, with or without
|
||||
dnl modification, are permitted provided that the following conditions are
|
||||
dnl met:
|
||||
dnl
|
||||
dnl * Redistributions of source code must retain the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer.
|
||||
dnl * Redistributions in binary form must reproduce the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer in the
|
||||
dnl documentation and/or other materials provided with the distribution.
|
||||
dnl * Neither the name of Google Inc. nor the names of its contributors
|
||||
dnl may be used to endorse or promote products derived from this software
|
||||
dnl without specific prior written permission.
|
||||
dnl
|
||||
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
dnl
|
||||
dnl KYUA_DOXYGEN
|
||||
dnl
|
||||
dnl Adds a --with-doxygen flag to the configure script and, when Doxygen support
|
||||
dnl is requested by the user, sets DOXYGEN to the path of the Doxygen binary and
|
||||
dnl enables the WITH_DOXYGEN Automake conditional.
|
||||
dnl
|
||||
AC_DEFUN([KYUA_DOXYGEN], [
|
||||
AC_ARG_WITH([doxygen],
|
||||
AS_HELP_STRING([--with-doxygen],
|
||||
[build documentation for internal APIs]),
|
||||
[],
|
||||
[with_doxygen=auto])
|
||||
|
||||
if test "${with_doxygen}" = yes; then
|
||||
AC_PATH_PROG([DOXYGEN], [doxygen], [])
|
||||
if test -z "${DOXYGEN}"; then
|
||||
AC_MSG_ERROR([Doxygen explicitly requested but not found])
|
||||
fi
|
||||
elif test "${with_doxygen}" = auto; then
|
||||
AC_PATH_PROG([DOXYGEN], [doxygen], [])
|
||||
elif test "${with_doxygen}" = no; then
|
||||
DOXYGEN=
|
||||
else
|
||||
AC_MSG_CHECKING([for doxygen])
|
||||
DOXYGEN="${with_doxygen}"
|
||||
AC_MSG_RESULT([${DOXYGEN}])
|
||||
if test ! -x "${DOXYGEN}"; then
|
||||
AC_MSG_ERROR([Doxygen binary ${DOXYGEN} is not executable])
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_DOXYGEN], [test -n "${DOXYGEN}"])
|
||||
AC_SUBST([DOXYGEN])
|
||||
])
|
69
m4/lua.m4
Normal file
69
m4/lua.m4
Normal file
@ -0,0 +1,69 @@
|
||||
dnl Copyright 2011 Google Inc.
|
||||
dnl All rights reserved.
|
||||
dnl
|
||||
dnl Redistribution and use in source and binary forms, with or without
|
||||
dnl modification, are permitted provided that the following conditions are
|
||||
dnl met:
|
||||
dnl
|
||||
dnl * Redistributions of source code must retain the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer.
|
||||
dnl * Redistributions in binary form must reproduce the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer in the
|
||||
dnl documentation and/or other materials provided with the distribution.
|
||||
dnl * Neither the name of Google Inc. nor the names of its contributors
|
||||
dnl may be used to endorse or promote products derived from this software
|
||||
dnl without specific prior written permission.
|
||||
dnl
|
||||
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
dnl
|
||||
dnl KYUA_LUA
|
||||
dnl
|
||||
dnl Helper macro to detect Lua in a variety of systems.
|
||||
dnl
|
||||
AC_DEFUN([KYUA_LUA], [
|
||||
lua_found=no
|
||||
|
||||
for lua_release in 5.2 5.1; do
|
||||
if test "${lua_found}" = no; then
|
||||
PKG_CHECK_MODULES([LUA], [lua${lua_release} >= ${lua_release}],
|
||||
[lua_found=yes], [true])
|
||||
fi
|
||||
if test "${lua_found}" = no; then
|
||||
PKG_CHECK_MODULES([LUA], [lua-${lua_release} >= ${lua_release}],
|
||||
[lua_found=yes], [true])
|
||||
fi
|
||||
if test "${lua_found}" = no; then
|
||||
PKG_CHECK_MODULES([LUA], [lua >= ${lua_release}],
|
||||
[lua_found=yes], [true])
|
||||
fi
|
||||
|
||||
test "${lua_found}" = no || break
|
||||
done
|
||||
|
||||
if test "${lua_found}" = no; then
|
||||
AC_PATH_PROGS([LUA_CONFIG], [lua-config], [unset])
|
||||
if test "${LUA_CONFIG}" != unset; then
|
||||
AC_SUBST([LUA_CFLAGS], [$(${LUA_CONFIG} --include)])
|
||||
AC_SUBST([LUA_LIBS], [$(${LUA_CONFIG} --libs)])
|
||||
lua_found=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${lua_found}" = no; then
|
||||
AC_MSG_ERROR([lua (5.1 or newer) is required])
|
||||
else
|
||||
AC_MSG_NOTICE([using LUA_CFLAGS = ${LUA_CFLAGS}])
|
||||
AC_MSG_NOTICE([using LUA_LIBS = ${LUA_LIBS}])
|
||||
fi
|
||||
])
|
153
operations.cpp
Normal file
153
operations.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
// 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 nargs The number of arguments on the stack to pass to the file.
|
||||
/// \param nresults The number of results to expect; -1 for any.
|
||||
/// \param errfunc If not 0, index of a function in the stack to act as an
|
||||
/// error handler.
|
||||
///
|
||||
/// \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 nargs,
|
||||
const int nresults, const int errfunc)
|
||||
{
|
||||
assert(nresults >= -1);
|
||||
const int height = s.get_top() - nargs;
|
||||
|
||||
try {
|
||||
s.load_file(file);
|
||||
if (nargs > 0)
|
||||
s.insert(-nargs - 1);
|
||||
s.pcall(nargs, nresults == -1 ? LUA_MULTRET : nresults,
|
||||
errfunc == 0 ? 0 : errfunc - 1);
|
||||
} catch (const lutok::api_error& e) {
|
||||
throw lutok::error("Failed to load Lua file '" + file + "': " +
|
||||
e.what());
|
||||
}
|
||||
|
||||
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 nargs The number of arguments on the stack to pass to the chunk.
|
||||
/// \param nresults The number of results to expect; -1 for any.
|
||||
/// \param errfunc If not 0, index of a function in the stack to act as an
|
||||
/// error handler.
|
||||
///
|
||||
/// \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 nargs,
|
||||
const int nresults, const int errfunc)
|
||||
{
|
||||
assert(nresults >= -1);
|
||||
const int height = s.get_top() - nargs;
|
||||
|
||||
try {
|
||||
s.load_string(str);
|
||||
if (nargs > 0)
|
||||
s.insert(-nargs - 1);
|
||||
s.pcall(nargs, nresults == -1 ? LUA_MULTRET : nresults,
|
||||
errfunc == 0 ? 0 : errfunc - 1);
|
||||
} catch (const lutok::api_error& e) {
|
||||
throw lutok::error("Failed to process Lua string '" + str + "': " +
|
||||
e.what());
|
||||
}
|
||||
|
||||
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, 0, nresults, 0);
|
||||
}
|
55
operations.hpp
Normal file
55
operations.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
// 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, const int,
|
||||
const int);
|
||||
unsigned int do_string(state&, const std::string&, const int, const int,
|
||||
const int);
|
||||
void eval(state&, const std::string&, const int);
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
#endif // !defined(LUTOK_OPERATIONS_HPP)
|
372
operations_test.cpp
Normal file
372
operations_test.cpp
Normal file
@ -0,0 +1,372 @@
|
||||
// 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", 0, 1, 0);
|
||||
ATF_REQUIRE(state.to_boolean(-1));
|
||||
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)", 0, 1, 0);
|
||||
ATF_REQUIRE_EQ(30, state.to_integer(-1));
|
||||
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)", 0, 1, 0);
|
||||
ATF_REQUIRE_EQ(30, state.to_integer(-1));
|
||||
lutok::do_string(state, "return my_math.multiply(10, 20)", 0, 1, 0);
|
||||
ATF_REQUIRE_EQ(200, state.to_integer(-1));
|
||||
lutok::do_string(state, "return my_math.add2(20, 30)", 0, 1, 0);
|
||||
ATF_REQUIRE_EQ(50, state.to_integer(-1));
|
||||
state.pop(3);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_file__some_args);
|
||||
ATF_TEST_CASE_BODY(do_file__some_args)
|
||||
{
|
||||
std::ofstream output("test.lua");
|
||||
output << "local a1, a2 = ...\nreturn a1 * 2, a2 * 2\n";
|
||||
output.close();
|
||||
|
||||
lutok::state state;
|
||||
state.push_integer(456);
|
||||
state.push_integer(3);
|
||||
state.push_integer(5);
|
||||
state.push_integer(123);
|
||||
ATF_REQUIRE_EQ(2, lutok::do_file(state, "test.lua", 3, -1, 0));
|
||||
ATF_REQUIRE_EQ(3, state.get_top());
|
||||
ATF_REQUIRE_EQ(456, state.to_integer(-3));
|
||||
ATF_REQUIRE_EQ(6, state.to_integer(-2));
|
||||
ATF_REQUIRE_EQ(10, state.to_integer(-1));
|
||||
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", 0, -1, 0));
|
||||
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", 0, 0, 0));
|
||||
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", 0, 2, 0));
|
||||
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", 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
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", 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_file__error_with_errfunc);
|
||||
ATF_TEST_CASE_BODY(do_file__error_with_errfunc)
|
||||
{
|
||||
std::ofstream output("test.lua");
|
||||
output << "unknown_function()\n";
|
||||
output.close();
|
||||
|
||||
lutok::state state;
|
||||
lutok::eval(state, "function(message) return 'This is an error!' end", 1);
|
||||
{
|
||||
stack_balance_checker checker(state);
|
||||
ATF_REQUIRE_THROW_RE(lutok::error, "This is an error!",
|
||||
lutok::do_file(state, "test.lua", 0, 0, -2));
|
||||
}
|
||||
state.pop(1);
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_string__some_args);
|
||||
ATF_TEST_CASE_BODY(do_string__some_args)
|
||||
{
|
||||
lutok::state state;
|
||||
state.push_integer(456);
|
||||
state.push_integer(3);
|
||||
state.push_integer(5);
|
||||
state.push_integer(123);
|
||||
ATF_REQUIRE_EQ(2, lutok::do_string(
|
||||
state, "local a1, a2 = ...\nreturn a1 * 2, a2 * 2\n", 3, -1, 0));
|
||||
ATF_REQUIRE_EQ(3, state.get_top());
|
||||
ATF_REQUIRE_EQ(456, state.to_integer(-3));
|
||||
ATF_REQUIRE_EQ(6, state.to_integer(-2));
|
||||
ATF_REQUIRE_EQ(10, state.to_integer(-1));
|
||||
state.pop(3);
|
||||
}
|
||||
|
||||
|
||||
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", 0, -1, 0));
|
||||
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", 0, 0, 0));
|
||||
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", 0, 2, 0));
|
||||
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", 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
ATF_TEST_CASE_WITHOUT_HEAD(do_string__error_with_errfunc);
|
||||
ATF_TEST_CASE_BODY(do_string__error_with_errfunc)
|
||||
{
|
||||
lutok::state state;
|
||||
lutok::eval(state, "function(message) return 'This is an error!' end", 1);
|
||||
{
|
||||
stack_balance_checker checker(state);
|
||||
ATF_REQUIRE_THROW_RE(lutok::error, "This is an error!",
|
||||
lutok::do_string(state, "unknown_function()",
|
||||
0, 0, -2));
|
||||
}
|
||||
state.pop(1);
|
||||
}
|
||||
|
||||
|
||||
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", 1);
|
||||
ATF_REQUIRE_EQ(13, state.to_integer(-1));
|
||||
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()", 1));
|
||||
}
|
||||
|
||||
|
||||
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__some_args);
|
||||
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_file__error_with_errfunc);
|
||||
|
||||
ATF_ADD_TEST_CASE(tcs, do_string__some_args);
|
||||
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, do_string__error_with_errfunc);
|
||||
|
||||
ATF_ADD_TEST_CASE(tcs, eval__one_result);
|
||||
ATF_ADD_TEST_CASE(tcs, eval__many_results);
|
||||
ATF_ADD_TEST_CASE(tcs, eval__error);
|
||||
}
|
91
stack_cleaner.cpp
Normal file
91
stack_cleaner.cpp
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
stack_cleaner.hpp
Normal file
93
stack_cleaner.hpp
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
stack_cleaner_test.cpp
Normal file
108
stack_cleaner_test.cpp
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(-1));
|
||||
{
|
||||
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(-1));
|
||||
}
|
||||
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(-1));
|
||||
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);
|
||||
}
|
904
state.cpp
Normal file
904
state.cpp
Normal file
@ -0,0 +1,904 @@
|
||||
// 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::registry_index = LUA_REGISTRYINDEX;
|
||||
|
||||
|
||||
/// 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 = luaL_newstate();
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
/// Pushes a reference to the global table onto the stack.
|
||||
///
|
||||
/// This is a wrapper around the incompatible differences between Lua 5.1 and
|
||||
/// 5.2 to access to the globals table.
|
||||
///
|
||||
/// \post state(-1) Contains the reference to the globals table.
|
||||
void
|
||||
lutok::state::get_global_table(void)
|
||||
{
|
||||
#if LUA_VERSION_NUM >= 502
|
||||
lua_pushvalue(_pimpl->lua_state, registry_index);
|
||||
lua_pushinteger(_pimpl->lua_state, LUA_RIDX_GLOBALS);
|
||||
lua_gettable(_pimpl->lua_state, -2);
|
||||
lua_remove(_pimpl->lua_state, -2);
|
||||
#else
|
||||
lua_pushvalue(_pimpl->lua_state, LUA_GLOBALSINDEX);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// 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) == -1)
|
||||
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 luaL_openlibs.
|
||||
///
|
||||
/// \throw api_error If luaL_openlibs fails.
|
||||
///
|
||||
/// \warning Terminates execution if there is not enough memory.
|
||||
void
|
||||
lutok::state::open_all(void)
|
||||
{
|
||||
luaL_openlibs(_pimpl->lua_state);
|
||||
}
|
||||
|
||||
|
||||
/// 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)
|
||||
{
|
||||
#if LUA_VERSION_NUM >= 502
|
||||
luaL_requiref(_pimpl->lua_state, LUA_STRLIBNAME, luaopen_string, 1);
|
||||
lua_pop(_pimpl->lua_state, 1);
|
||||
#else
|
||||
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");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// 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)
|
||||
{
|
||||
#if LUA_VERSION_NUM >= 502
|
||||
luaL_requiref(_pimpl->lua_state, LUA_TABLIBNAME, luaopen_table, 1);
|
||||
lua_pop(_pimpl->lua_state, 1);
|
||||
#else
|
||||
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");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// 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;
|
||||
}
|
145
state.hpp
Normal file
145
state.hpp
Normal file
@ -0,0 +1,145 @@
|
||||
// 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>
|
||||
|
||||
#if defined(_LIBCPP_VERSION) || __cplusplus >= 201103L
|
||||
#include <memory>
|
||||
#else
|
||||
#include <tr1/memory>
|
||||
#endif
|
||||
|
||||
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 registry table.
|
||||
extern const int registry_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.
|
||||
#if defined(_LIBCPP_VERSION) || __cplusplus >= 201103L
|
||||
std::shared_ptr< impl > _pimpl;
|
||||
#else
|
||||
std::tr1::shared_ptr< impl > _pimpl;
|
||||
#endif
|
||||
|
||||
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&);
|
||||
void get_global_table(void);
|
||||
bool get_metafield(const int, const std::string&);
|
||||
bool get_metatable(const int);
|
||||
void get_table(const int);
|
||||
int get_top(void);
|
||||
void insert(const int);
|
||||
bool is_boolean(const int);
|
||||
bool is_function(const int);
|
||||
bool is_nil(const int);
|
||||
bool is_number(const int);
|
||||
bool is_string(const int);
|
||||
bool is_table(const int);
|
||||
bool is_userdata(const int);
|
||||
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);
|
||||
void open_all(void);
|
||||
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);
|
||||
void raw_get(const int);
|
||||
void raw_set(const int);
|
||||
void set_global(const std::string&);
|
||||
void set_metatable(const int);
|
||||
void set_table(const int);
|
||||
bool to_boolean(const int);
|
||||
long to_integer(const int);
|
||||
template< typename Type > Type* to_userdata(const int);
|
||||
std::string to_string(const int);
|
||||
int upvalue_index(const int);
|
||||
};
|
||||
|
||||
|
||||
} // namespace lutok
|
||||
|
||||
#endif // !defined(LUTOK_STATE_HPP)
|
67
state.ipp
Normal file
67
state.ipp
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)
|
1164
state_test.cpp
Normal file
1164
state_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
141
test_utils.hpp
Normal file
141
test_utils.hpp
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(-1) || _state.to_integer(-1) != 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