🔨 asdhjsahd DO NOT BUILD

- Add a flag to allow size_t(-1) and similar shenanigans (SOL_ALL_INTEGER_VALUES_FIT)
- Half-fix, but not fully, for #1183, #1072, #1038, #965
- Fix #1126
- Prepare for #1061
This commit is contained in:
ThePhD 2021-05-06 18:44:25 -04:00
parent f56b3c698c
commit 7aae1aaaaa
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
116 changed files with 2128 additions and 926 deletions

View File

@ -1,4 +1,4 @@
name: Mac OSX
name: Mac OS
on: [push]

View File

@ -22,17 +22,13 @@
# # # # sol2
# # # Required minimum version statement
cmake_minimum_required(VERSION 3.15.0)
cmake_minimum_required(VERSION 3.16.0)
# # # Project Include - file that is included after project declaration is finished
set(CMAKE_PROJECT_INCLUDE "${CMAKE_SOURCE_DIR}/cmake/Includes/Project.cmake")
# # # project declaration
project(sol2 VERSION 4.0.0 LANGUAGES CXX C)
# # # Modules
# # Include modules useful to the project, whether locally made in our own cmake DIRECTORY
# # our from the standard cmake libraries
# Add home-rolled modules path to front of module path list
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules" "${CMAKE_MODULE_PATH}")
if (PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(SOL2_IS_TOP_LEVEL TRUE)
message(STATUS "sol2 is the top-level directory...")
@ -78,23 +74,8 @@ CMAKE_DEPENDENT_OPTION(BUILD_LUA_AS_DLL "Build Lua as a DLL" ON
"SOL2_BUILD_LUA" OFF)
# # # Platform
# Detect x86 and x64 stuff
if (SOL2_PLATFORM MATCHES "i686" OR SOL2_PLATFORM STREQUAL "x86")
set(SOL2_IS_X86 TRUE)
elseif (SOL2_PLATFORM MATCHES "ARM64")
set(IS_ARM64 TRUE)
set(IS_X64 TRUE)
elseif (SOL2_PLATFORM MATCHES "ARM")
set(IS_ARM TRUE)
elseif (SOL2_PLATFORM MATCHES "x86_64" OR SOL2_PLATFORM STREQUAL "x64")
set(IS_X64 TRUE)
else()
set(IS_X64 TRUE)
endif()
if (SOL2_SYSTEM_INCLUDE)
set(--sol2-system-include SYSTEM)
set(sol2-system-include SYSTEM)
endif()
# # # sol2 Source Groups
@ -112,7 +93,7 @@ set_target_properties(sol2
PROPERTIES
EXPORT_NAME sol2::sol2)
target_include_directories(sol2 ${--sol2-system-include} INTERFACE
target_include_directories(sol2 ${sol2-system-include} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
@ -191,7 +172,7 @@ endif()
# # # Tests, Examples and other CI suites that come with sol2
if (SOL2_IS_TOP_LEVEL AND (SOL2_DO_TESTS OR SOL2_DO_EXAMPLES))
# # # General project output locations
if (SOL2_IS_X86 OR CMAKE_SIZEOF_VOID_P EQUAL 4)
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/bin")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/bin")
@ -204,26 +185,6 @@ if (SOL2_IS_TOP_LEVEL AND (SOL2_DO_TESTS OR SOL2_DO_EXAMPLES))
# # # Libraries
# Here, we pull in all the necessary libraries for building examples and tests
# Find threading library
if (NOT MSVC)
if (SOL2_IS_X86)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
set(CMAKE_EXECUTABLE_LINKER_FLAGS "${CMAKE_EXECUTABLE_LINKER_FLAGS} -m32")
endif()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
else()
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
if (BUILD_LUA_AS_DLL)
string(REGEX REPLACE "/MT" "/MD" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
string(REGEX REPLACE "/MT" "/MD" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
else ()
string(REGEX REPLACE "/MD" "/MT" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
string(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
endif()
endif()
find_package(Threads REQUIRED)
string(TOLOWER ${SOL2_LUA_VERSION} NORMALIZED_LUA_VERSION)

View File

@ -0,0 +1,77 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 - cmake - basic project configuration
include_guard(DIRECTORY)
list(PREPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Packages")
list(PREPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Modules")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
list(APPEND CMAKE_MESSAGE_CONTEXT "${PROJECT_NAME}")
# # Standard Project version
if (NOT CMAKE_CXX_STANDARD GREATER_EQUAL 17)
set(CMAKE_CXX_STANDARD 17)
endif()
if (NOT CMAKE_C_STANDARD GREATER_EQUAL 11)
set(CMAKE_C_STANDARD 11)
endif()
# # CMake and sol2 Includes
# CMake
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
include(CheckIPOSupported)
include(CMakeDependentOption)
include(CMakePrintHelpers)
include(GNUInstallDirs)
include(FeatureSummary)
include(FetchContent)
include(CTest)
# sol2
include(CheckCompilerDiagnostic)
include(CheckCompilerFlag)
include(FindVersion)
# # Check environment/prepare generator expressions
# Basic/Normal flags
check_compiler_flag(disable-permissive MSVC /permissive- GCC -pedantic)
check_compiler_flag(utf8-literal-encoding MSVC /execution-charset:utf-8 GCC -fexec-charset=utf-8)
check_compiler_flag(utf8-source-encoding MSVC /source-charset:utf-8 GCC -finput-charset=utf-8)
check_compiler_flag(extra-constexpr-depth MSVC /constexpr:depth2147483647 GCC -fconstexpr-depth=2147483647 CLANG -fconstexpr-depth=2147483647)
check_compiler_flag(extra-constexpr-steps MSVC /constexpr:steps2147483647 GCC -fconstexpr-ops-limit=2147483647 CLANG -fconstexpr-steps=2147483647)
check_compiler_flag(template-debugging-mode GCC -ftemplate-backtrace-limit=0)
check_compiler_flag(big-obj MSVC /bigobj)
# Overall warning flags
check_compiler_flag(pedantic GCC -pedantic)
check_compiler_flag(warn-pedantic GCC -Wpedantic)
check_compiler_flag(warn-all MSVC /W4 GCC -Wall)
check_compiler_flag(warn-extra GCC -Wextra)
check_compiler_flag(warn-errors MSVC /WX GCC -Werror)
# Individual warnings/errors
check_compiler_diagnostic(unknown-warning)
check_compiler_diagnostic(unknown-warning-option)
check_compiler_diagnostic(microsoft-cast)
check_compiler_diagnostic(noexcept-type)
check_compiler_diagnostic(unreachable-code MSVC 4702)

View File

@ -0,0 +1,93 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 - cmake - compiler diagnostic checking
include_guard(GLOBAL)
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
#[[
Given a diagnostic name and flag, like
check_cxx_compiler_diagnostic(pig MSVC 1312)
or
check_cxx_compiler_diagnostic(pig GCC acab)
we check if the given flag works C++ compiler. If it does, we then generate
a --warn, --allow, --deny, and --forbid prefixed set of variables. Users are
then free to simply apply them to targets at will.
]]
function (check_compiler_diagnostic diagnostic)
cmake_parse_arguments(diagnostic "" "GCC;MSVC;CLANG" "" ${ARGN})
if (NOT diagnostic_GCC)
set(diagnostic_GCC ${diagnostic})
endif()
if (NOT diagnostic_MSVC)
set(diagnostic_MSVC ${diagnostic})
endif()
if (NOT diagnostic_CLANG)
set(diagnostic_CLANG ${diagnostic_GCC})
endif()
string(MAKE_C_IDENTIFIER "${diagnostic}" suffix)
string(TOUPPER "${suffix}" suffix)
get_property(enabled-languages GLOBAL PROPERTY ENABLED_LANGUAGES)
if (CXX IN_LIST enabled-languages)
if (MSVC)
check_cxx_compiler_flag(-wo${diagnostic_MSVC} CXX_DIAGNOSTIC_${suffix})
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
check_cxx_compiler_flag(-W${diagnostic_CLANG} CXX_DIAGNOSTIC_${suffix})
else()
check_cxx_compiler_flag(-W${diagnostic_GCC} CXX_DIAGNOSTIC_${suffix})
endif()
endif()
if (C IN_LIST enabled-languages)
if (MSVC)
check_c_compiler_flag(-wo${diagnostic_MSVC} C_DIAGNOSTIC_${suffix})
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
check_c_compiler_flag(-W${diagnostic_CLANG} C_DIAGNOSTIC_${suffix})
else()
check_c_compiler_flag(-W${diagnostic_GCC} C_DIAGNOSTIC_${suffix})
endif()
endif()
string(CONCAT when $<OR:
$<AND:$<BOOL:${CXX_DIAGNOSTIC_${suffix}}>,$<COMPILE_LANGUAGE:CXX>>,
$<AND:$<BOOL:${C_DIAGNOSTIC_${suffix}}>,$<COMPILE_LANGUAGE:C>>
>)
string(CONCAT diagnostic_flag
$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:${diagnostic_MSVC}>
$<$<COMPILE_LANG_AND_ID:C,MSVC>:${diagnostic_MSVC}>
$<$<COMPILE_LANG_AND_ID:CXX,GCC>:${diagnostic_GCC}>
$<$<COMPILE_LANG_AND_ID:C,GCC>:${diagnostic_GCC}>
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:${diagnostic_CLANG}>
$<$<COMPILE_LANG_AND_ID:C,Clang,AppleClang>:${diagnostic_CLANG}>
)
set(forbid_prefix $<IF:$<BOOL:${MSVC}>,-we,-Werror=>)
set(allow_prefix $<IF:$<BOOL:${MSVC}>,-wd,-Wno->)
set(warn_prefix $<IF:$<BOOL:${MSVC}>,-w1,-W>)
set(--forbid-${diagnostic} $<${when}:${forbid_prefix}${diagnostic_flag}> PARENT_SCOPE)
set(--allow-${diagnostic} $<${when}:${allow_prefix}${diagnostic_flag}> PARENT_SCOPE)
# Set these warnings to level 1 warnings, so they appear by default
set(--warn-${diagnostic} $<${when}:${warn_prefix}${diagnostic_flag}> PARENT_SCOPE)
set(--deny-${diagnostic} ${--forbid-${diagnostic_flag}} PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,83 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 - cmake - compiler flag checking
include_guard(GLOBAL)
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
#[[
Given a flag name and the actual flag, like
check_cxx_compiler_flag(strict-conformance MSVC /permissive- GCC -pedantic)
we check if the given flag works C++ compiler. If it is, then
--strict-conformance will be the provided flag. MSVC and GCC are the 2 different
"style" of flags to be tested for.
]]
function (check_compiler_flag flag_name)
cmake_parse_arguments(PARSE_ARGV 1 flag "" "" "GCC;MSVC;CLANG")
if (NOT flag_MSVC)
set(flag_MSVC /${flag_name})
endif()
if (NOT flag_GCC)
set(flag_GCC ${flag_name})
endif()
if (NOT flag_CLANG)
set(flag_CLANG ${flag_GCC})
endif()
string(MAKE_C_IDENTIFIER "${flag_name}" suffix)
string(TOUPPER "${suffix}" suffix)
get_property(enabled-languages GLOBAL PROPERTY ENABLED_LANGUAGES)
if (CXX IN_LIST enabled-languages)
if (MSVC)
check_cxx_compiler_flag(${flag_MSVC} CXX_CHECK_FLAG_${suffix})
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
check_cxx_compiler_flag(${flag_CLANG} CXX_CHECK_FLAG_${suffix})
else()
check_cxx_compiler_flag(${flag_GCC} CXX_CHECK_FLAG_${suffix})
endif()
endif()
if (C IN_LIST enabled-languages)
if (MSVC)
check_c_compiler_flag(${flag_MSVC} C_CHECK_FLAG_${suffix})
elseif (CMAKE_C_COMPILER_ID MATCHES Clang)
check_c_compiler_flag(${flag_CLANG} C_CHECK_FLAG_${suffix})
else()
check_c_compiler_flag(${flag_GCC} C_CHECK_FLAG_${suffix})
endif()
endif()
string(CONCAT when $<OR:
$<AND:$<BOOL:${CXX_CHECK_FLAG_${suffix}}>,$<COMPILE_LANGUAGE:CXX>>,
$<AND:$<BOOL:${C_CHECK_FLAG_${suffix}}>,$<COMPILE_LANGUAGE:C>>
>)
string(CONCAT compiler_flag
$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:${flag_MSVC}>
$<$<COMPILE_LANG_AND_ID:C,MSVC>:${flag_MSVC}>
$<$<COMPILE_LANG_AND_ID:CXX,GCC>:${flag_GCC}>
$<$<COMPILE_LANG_AND_ID:C,GCC>:${flag_GCC}>
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:${flag_CLANG}>
$<$<COMPILE_LANG_AND_ID:C,Clang,AppleClang>:${flag_CLANG}>
)
set(--${flag_name} $<${when}:${compiler_flag}> PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,61 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 - cmake - version matching
include_guard(GLOBAL)
#[[
This is used to create a version variable. How these are used or set is up
to the user.
TODO: Support find_version(<VAR> SOURCE <FILE>) for parsing a version name from a header file
TODO: Support find_version(<VAR> LIBRARY <FILE>) for .dll/.lib/.so/.dylib parsing
]]
function (find_version output)
cmake_parse_arguments(ARG "" "OPTION;REGEX;COMMAND;DOC" "" ${ARGN})
unset(version-output)
unset(version-check)
if (NOT ARG_OPTION)
set(ARG_OPTION "--version")
endif()
if (NOT ARG_REGEX)
set(ARG_REGEX "[^0-9]*([0-9]+)[.]([0-9]+)?[.]?([0-9]+)?[.]?([0-9]+)?.*")
endif()
if (ARG_COMMAND AND NOT DEFINED ${output})
execute_process(
COMMAND ${ARG_COMMAND} ${ARG_OPTION}
OUTPUT_VARIABLE version-output
OUTPUT_STRIP_TRAILING_WHITESPACE
ENCODING UTF-8)
if (version-output)
string(REGEX MATCH "${ARG_REGEX}" version-check ${version-output})
endif()
if (version-check)
string(JOIN "." ${output}
${CMAKE_MATCH_1}
${CMAKE_MATCH_2}
${CMAKE_MATCH_3}
${CMAKE_MATCH_4})
set(${output} "${${output}}" CACHE STRING "${ARG_DOC}" FORCE)
endif()
endif()
endfunction()

View File

@ -22,7 +22,7 @@
# # # # sol2, documentation generation
# # # Required minimum version statement
cmake_minimum_required(VERSION 3.15.0)
cmake_minimum_required(VERSION 3.16.0)
find_package(Doxygen REQUIRED)
find_package(Python3 REQUIRED)
@ -98,7 +98,6 @@ if (NOT SOL2_DOCUMENTATION_NO_SPHINX)
endif()
# For the install target
include(GNUInstallDirs)
install(DIRECTORY ${SOL2_SPHINX_BUILD_DIR}
DESTINATION ${CMAKE_INSTALL_DOCDIR}
)
)

View File

@ -10,7 +10,7 @@ environment
class environment : public table;
template <typename T>
void set_environment( const environment& env, const T& target );
bool set_environment( const environment& env, const T& target );
template <typename E = reference, typename T>
basic_environment<E> get_environment( const T& target );

View File

@ -22,6 +22,47 @@
# # # sol2 Examples
function(sol2_add_example_properties target-name)
target_link_libraries(${target-name}
PUBLIC Threads::Threads ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
target_compile_definitions(${target-name}
PUBLIC SOL_PRINT_ERRORS=1)
target_compile_options(${target-name}
PRIVATE
${--template-debugging-mode}
${--big-obj}
${--no-unknown-warning}
${--disable-permissive}
${--pedantic}
${--warn-all}
${--warn-pedantic}
${--warn-extra}
${--warn-errors}
${--utf8-literal-encoding}
${--utf8-source-encoding}
${--allow-unknown-warning}
${--allow-unknown-warning-option}
${--allow-noexcept-type}
${--allow-microsoft-casts}
)
target_compile_definitions(${target-name}
PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE)
if (SOL2_CI)
target_compile_definitions(${target-name}
PRIVATE SOL2_CI)
endif()
if (SOL2_TESTS_EXAMPLES)
add_test(NAME ${target-name} COMMAND ${target-name})
endif()
if(SOL2_ENABLE_INSTALL)
install(TARGETS ${target-name} RUNTIME DESTINATION bin)
endif()
endfunction()
if (SOL2_DYNAMIC_LOADING_EXAMPLES OR SOL2_DYNAMIC_LOADING_EXAMPLES_SINGLE)
# # require_from_dll example
# just add the subdirectory
@ -45,7 +86,6 @@ file(GLOB sol2.examples.sources source/*.cpp source/tutorials/*.cpp source/tutor
source_group(examples FILES ${sol2.examples.sources})
function (MAKE_EXAMPLE example_source_file example_prefix target_sol)
get_filename_component(example_name ${example_source_file} NAME_WE)
file(RELATIVE_PATH example_source_file_relative ${CMAKE_SOURCE_DIR} ${example_source_file})
get_filename_component(example_output_relative_dir ${example_source_file_relative} DIRECTORY)
@ -60,42 +100,9 @@ function (MAKE_EXAMPLE example_source_file example_prefix target_sol)
endif()
add_executable(${example_name} ${example_source_file})
set_target_properties(${example_name}
PROPERTIES
OUTPUT_NAME "${example_output_name}")
if (MSVC)
target_compile_options(${example_name}
PRIVATE /std:c++latest /EHsc /W4)
target_compile_definitions(${example_name}
PRIVATE UNICODE _UNICODE
_CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE )
else()
target_compile_options(${example_name}
PRIVATE -std=c++1z
-ftemplate-backtrace-limit=0
-Wno-unknown-warning -Wno-unknown-warning-option
-Wall -Wpedantic -Werror -pedantic -pedantic-errors
-Wno-noexcept-type)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# For another day, when C++ is not so crap
# and we have time to audit the entire lib
# for all uses of `detail::swallow`...
#target_compile_options(${example_name}
# PRIVATE -Wcomma)
endif()
endif()
sol2_add_example_properties(${example_name})
target_link_libraries(${example_name}
PRIVATE Threads::Threads ${target_sol} ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
if (SOL2_TESTS_EXAMPLES)
add_test(NAME ${example_output_name} COMMAND ${example_name})
endif()
if(SOL2_ENABLE_INSTALL)
install(TARGETS ${example_name} RUNTIME DESTINATION bin)
endif()
PRIVATE ${target_sol})
endfunction(MAKE_EXAMPLE)
if (SOL2_EXAMPLES)

View File

@ -15,7 +15,8 @@ int main(int, char**) {
sol::environment env_f(lua, sol::create);
env_f["test"] = 31;
sol::set_environment(env_f, f);
bool env_f_set_success = sol::set_environment(env_f, f);
sol_c_assert(env_f_set_success);
// the function returns the value from the environment table
int result = f();
@ -27,7 +28,9 @@ int main(int, char**) {
lua.script("g = function() test = 5 end");
sol::function g = lua["g"];
sol::environment env_g(lua, sol::create);
env_g.set_on(g); // same as set_environment
bool env_g_set_success
= env_g.set_on(g); // same as set_environment
sol_c_assert(env_g_set_success);
g();
// the value can be retrieved from the env table

View File

@ -82,7 +82,7 @@ int main(int, char*[]) {
lua.new_usertype<my_thing>(
"my_thing", sol::meta_function::pairs, my_pairs);
#if SOL_LUA_VERSION > 501
#if SOL_LUA_VERSION_I_ > 501
lua.safe_script(R"(
local mt = my_thing.new()
for k, v in pairs(mt) do

View File

@ -76,7 +76,7 @@ int main(int, char*[]) {
lua.new_usertype<my_thing>(
"my_thing", sol::meta_function::pairs, &my_pairs);
#if SOL_LUA_VERSION > 501
#if SOL_LUA_VERSION_I_ > 501
lua.safe_script(R"(
local mt = my_thing.new()
for k, v in pairs(mt) do

View File

@ -106,7 +106,7 @@ print("#obj2:", #obj2)
print("#obj3:", #obj3)
)");
#if SOL_LUA_VERSION > 501
#if SOL_LUA_VERSION_I_ > 501
lua.script(R"(
for k, v in pairs(obj1) do
assert( (k / 3) == v )

View File

@ -91,9 +91,9 @@
#endif // SOL_LUA_VERSION
#if defined(SOL_LUA_VERSION)
#define SOL_LUA_VESION_I_ SOL_LUA_VERSION
#define SOL_LUA_VERSION_I_ SOL_LUA_VERSION
#else
#define SOL_LUA_VESION_I_ 504
#define SOL_LUA_VERSION_I_ 504
#endif
// Exception safety / propagation, according to Lua information
@ -184,7 +184,7 @@
#else
// Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags)
// Lua 5.2, or other versions of Lua with the compat flag, or Lua that is not 5.2 with the specific define (5.4.1 either removed it entirely or broke it)
#if (SOL_LUA_VESION_I_ == 502) || (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0)) || (SOL_LUA_VESION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
#if (SOL_LUA_VERSION_I_ == 502) || (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0)) || (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#else
#define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF

View File

@ -42,7 +42,7 @@ namespace sol {
call_status stats = call_status::yielded;
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
#if SOL_LUA_VESION_I_ >= 504
#if SOL_LUA_VERSION_I_ >= 504
int nresults;
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults));
#else

View File

@ -113,27 +113,69 @@ namespace sol {
}
template <typename T>
void set_on(const T& target) const {
bool set_on(const T& target) const {
lua_State* L = target.lua_state();
auto pp = stack::push_pop(target);
#if SOL_LUA_VESION_I_ < 502
int target_index = pp.index_of(target);
#if SOL_LUA_VERSION_I_ < 502
// Use lua_setfenv
this->push();
lua_setfenv(L, -2);
int success_result = lua_setfenv(L, target_index);
return success_result != 0;
#else
// Use upvalues as explained in Lua 5.2 and beyond's manual
this->push();
const char* name = lua_setupvalue(L, -2, 1);
if (name == nullptr) {
this->pop();
// If this is a C function, the environment is always placed in
// the first value, as is expected of sol2 (all upvalues have an empty name, "")
if (lua_iscfunction(L, target_index) != 0) {
const char* maybe_upvalue_name = lua_getupvalue(L, target_index, 1);
if (maybe_upvalue_name == nullptr) {
return false;
}
string_view upvalue_name(maybe_upvalue_name);
if (upvalue_name == "") {
this->push();
const char* success = lua_setupvalue(L, target_index, 1);
if (success == nullptr) {
// left things alone on the stack, pop them off
lua_pop(L, 1);
return false;
}
return true;
}
return false;
}
else {
// Must search for the right upvalue target on index
for (int upvalue_index = 1;; ++upvalue_index) {
const char* maybe_upvalue_name = lua_getupvalue(L, target_index, upvalue_index);
if (maybe_upvalue_name == nullptr) {
break;
}
string_view upvalue_name(maybe_upvalue_name);
if (upvalue_name == "_ENV") {
this->push();
const char* success = lua_setupvalue(L, target_index, upvalue_index);
if (success == nullptr) {
// left things alone on the stack, pop them off
lua_pop(L, 1);
break;
}
// whether or not we succeeded, we found _ENV
// so we need to break
return true;
}
lua_pop(L, 1);
}
// if we get here,
// we did not find an _ENV here...
return false;
}
#endif
}
};
template <typename T, typename E>
void set_environment(const basic_environment<E>& env, const T& target) {
env.set_on(target);
bool set_environment(const basic_environment<E>& env, const T& target) {
return env.set_on(target);
}
template <typename E = reference, typename T>

View File

@ -72,8 +72,8 @@ namespace sol {
template <bool is_yielding, bool no_trampoline, typename Fx, typename... Args>
void select_set_fx(lua_State* L, Args&&... args) {
lua_CFunction freefunc = no_trampoline ? detail::static_trampoline<function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>>
: function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>;
lua_CFunction freefunc = no_trampoline ? function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>
: detail::static_trampoline<function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>>;
int upvalues = 0;
upvalues += stack::push(L, nullptr);
@ -277,7 +277,7 @@ namespace sol {
template <typename... Sigs>
struct unqualified_pusher<function_sig<Sigs...>> {
template <bool is_yielding, typename Arg0, typename... Args>
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
static int push_yielding(lua_State* L, Arg0&& arg0, Args&&... args) {
if constexpr (meta::is_specialization_of_v<meta::unqualified_t<Arg0>, std::function>) {
if constexpr (is_yielding) {
return stack::push<meta::unqualified_t<Arg0>>(L, detail::yield_tag, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
@ -295,13 +295,13 @@ namespace sol {
template <typename Arg0, typename... Args>
static int push(lua_State* L, Arg0&& arg0, Args&&... args) {
if constexpr (std::is_same_v<meta::unqualified_t<Arg0>, detail::yield_tag_t>) {
push<true>(L, std::forward<Args>(args)...);
push_yielding<true>(L, std::forward<Args>(args)...);
}
else if constexpr (meta::is_specialization_of_v<meta::unqualified_t<Arg0>, yielding_t>) {
push<true>(L, std::forward<Arg0>(arg0).func, std::forward<Args>(args)...);
push_yielding<true>(L, std::forward<Arg0>(arg0).func, std::forward<Args>(args)...);
}
else {
push<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
push_yielding<false>(L, std::forward<Arg0>(arg0), std::forward<Args>(args)...);
}
return 1;
}
@ -315,7 +315,7 @@ namespace sol {
return stack::push<T>(L, detail::yield_tag, f.func, std::forward<Args>(args)...);
}
else {
function_detail::select<true, true>(L, f.func, std::forward<Args>(args)...);
function_detail::select<true, false>(L, f.func, std::forward<Args>(args)...);
return 1;
}
}
@ -326,7 +326,7 @@ namespace sol {
return stack::push<T>(L, detail::yield_tag, std::move(f.func), std::forward<Args>(args)...);
}
else {
function_detail::select<true, true>(L, std::move(f.func), std::forward<Args>(args)...);
function_detail::select<true, false>(L, std::move(f.func), std::forward<Args>(args)...);
return 1;
}
}
@ -350,9 +350,11 @@ namespace sol {
template <typename Signature>
struct unqualified_pusher<std::function<Signature>> {
using TargetFunctor = function_detail::functor_function<std::function<Signature>, false, true>;
static int push(lua_State* L, detail::yield_tag_t, const std::function<Signature>& fx) {
if (fx) {
function_detail::select<true, true>(L, fx);
function_detail::select_set_fx<true, false, TargetFunctor>(L, fx);
return 1;
}
return stack::push(L, lua_nil);
@ -360,7 +362,7 @@ namespace sol {
static int push(lua_State* L, detail::yield_tag_t, std::function<Signature>&& fx) {
if (fx) {
function_detail::select<true, true>(L, std::move(fx));
function_detail::select_set_fx<true, false, TargetFunctor>(L, std::move(fx));
return 1;
}
return stack::push(L, lua_nil);
@ -368,7 +370,7 @@ namespace sol {
static int push(lua_State* L, const std::function<Signature>& fx) {
if (fx) {
function_detail::select<false, true>(L, fx);
function_detail::select_set_fx<false, false, TargetFunctor>(L, fx);
return 1;
}
return stack::push(L, lua_nil);
@ -376,7 +378,7 @@ namespace sol {
static int push(lua_State* L, std::function<Signature>&& fx) {
if (fx) {
function_detail::select<false, true>(L, std::move(fx));
function_detail::select_set_fx<false, false, TargetFunctor>(L, std::move(fx));
return 1;
}
return stack::push(L, lua_nil);
@ -387,7 +389,7 @@ namespace sol {
struct unqualified_pusher<Signature, std::enable_if_t<meta::is_member_object_or_function_v<Signature>>> {
template <typename... Args>
static int push(lua_State* L, Args&&... args) {
function_detail::select<false, true>(L, std::forward<Args>(args)...);
function_detail::select<false, false>(L, std::forward<Args>(args)...);
return 1;
}
};
@ -527,7 +529,8 @@ namespace sol {
}
static int push(lua_State* L, no_construction c, function_detail::call_indicator) {
return push(L, c);
lua_CFunction cf = &function_detail::no_construction_error;
return stack::push(L, cf);
}
};

View File

@ -44,7 +44,7 @@ namespace sol {
sol::thread m_thread_reference;
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
#if SOL_LUA_VESION_I_ >= 504
#if SOL_LUA_VERSION_I_ >= 504
int nresults;
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults));
#else

View File

@ -218,7 +218,7 @@ namespace sol {
} // namespace stack
inline lua_State* main_thread(lua_State* L_, lua_State* backup_if_unsupported_ = nullptr) {
#if SOL_LUA_VESION_I_ < 502
#if SOL_LUA_VERSION_I_ < 502
if (L_ == nullptr)
return backup_if_unsupported_;
lua_getglobal(L_, detail::default_main_thread_name());

View File

@ -67,7 +67,7 @@ namespace sol { namespace stack {
}
}
else if constexpr ((std::is_integral_v<T> || std::is_same_v<T, lua_Integer>)&&!std::is_same_v<T, bool>) {
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
if (lua_isinteger(L, index) != 0) {
tracking.use(1);
return static_cast<T>(lua_tointeger(L, index));

View File

@ -113,7 +113,7 @@ namespace sol { namespace stack {
}
else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
tracking.use(1);
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
// Lua 5.3 and greater checks for numeric precision
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
// imprecise, sloppy conversions

View File

@ -71,7 +71,7 @@ namespace sol {
using unique_tag = detail::inheritance_unique_cast_function;
inline void* alloc_newuserdata(lua_State* L, std::size_t bytesize) {
#if SOL_LUA_VERSION >= 504
#if SOL_LUA_VERSION_I_ >= 504
return lua_newuserdatauv(L, bytesize, 1);
#else
return lua_newuserdata(L, bytesize);

View File

@ -39,10 +39,10 @@ namespace sol { namespace stack {
inline constexpr bool is_get_direct_v = (is_get_direct_tableless_v<T, global, raw>) // cf-hack
|| (!global && !raw && (meta::is_c_str_v<T> || meta::is_string_of_v<T, char>)) // cf-hack
|| (!global && raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
|| (!global && !raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
#endif // integer keys 5.3 or better
#if SOL_LUA_VESION_I_ >= 502
#if SOL_LUA_VERSION_I_ >= 502
|| (!global && raw && std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>)
#endif // void pointer keys 5.2 or better
;
@ -54,10 +54,10 @@ namespace sol { namespace stack {
inline constexpr bool is_set_direct_v = (is_set_direct_tableless_v<T, global, raw>) // cf-hack
|| (!global && !raw && (meta::is_c_str_v<T> || meta::is_string_of_v<T, char>)) // cf-hack
|| (!global && raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>)) // cf-hack
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
|| (!global && !raw && (std::is_integral_v<T> && !std::is_same_v<T, bool>))
#endif // integer keys 5.3 or better
#if SOL_LUA_VESION_I_ >= 502
#if SOL_LUA_VERSION_I_ >= 502
|| (!global && raw && (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>))
#endif // void pointer keys 5.2 or better
;
@ -77,7 +77,7 @@ namespace sol { namespace stack {
}
else if constexpr (std::is_same_v<T, env_key_t>) {
(void)key;
#if SOL_LUA_VESION_I_ < 502
#if SOL_LUA_VERSION_I_ < 502
// Use lua_setfenv
lua_getfenv(L, tableindex);
#else
@ -96,7 +96,7 @@ namespace sol { namespace stack {
if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
lua_rawgeti(L, tableindex, static_cast<lua_Integer>(key));
}
#if SOL_LUA_VESION_I_ >= 502
#if SOL_LUA_VERSION_I_ >= 502
else if constexpr (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>) {
lua_rawgetp(L, tableindex, key);
}
@ -120,7 +120,7 @@ namespace sol { namespace stack {
const auto& real_key = to_string(key);
lua_getfield(L, tableindex, &real_key[0]);
}
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
lua_geti(L, tableindex, static_cast<lua_Integer>(key));
}
@ -199,7 +199,7 @@ namespace sol { namespace stack {
push(L, std::forward<Value>(value));
lua_rawseti(L, tableindex, static_cast<lua_Integer>(key));
}
#if SOL_LUA_VESION_I_ >= 502
#if SOL_LUA_VERSION_I_ >= 502
else if constexpr (std::is_pointer_v<T> && std::is_void_v<std::remove_pointer_t<T>>) {
push(L, std::forward<Value>(value));
lua_rawsetp(L, tableindex, std::forward<Key>(key));
@ -223,7 +223,7 @@ namespace sol { namespace stack {
lua_setfield(L, tableindex, &key[0]);
}
}
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
push(L, std::forward<Value>(value));
lua_seti(L, tableindex, static_cast<lua_Integer>(key));

View File

@ -127,7 +127,7 @@ namespace sol { namespace stack {
}
else if constexpr (std::is_integral_v<T> || std::is_same_v<T, lua_Integer>) {
tracking.use(1);
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
if (lua_isinteger(L, index) != 0) {
return static_cast<T>(lua_tointeger(L, index));
}
@ -344,7 +344,7 @@ namespace sol { namespace stack {
int index = lua_absindex(L, relindex);
T cont;
std::size_t idx = 0;
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
// This method is HIGHLY performant over regular table iteration
// thanks to the Lua API changes in 5.3
// Questionable in 5.4
@ -355,7 +355,7 @@ namespace sol { namespace stack {
}
bool isnil = false;
for (int vi = 0; vi < lua_size<V>::value; ++vi) {
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VESION_I_ >= 600
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VERSION_I_ >= 600
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
@ -376,7 +376,7 @@ namespace sol { namespace stack {
if (i == 0) {
break;
}
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VESION_I_ >= 600
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VERSION_I_ >= 600
lua_pop(L, vi);
#else
lua_pop(L, (vi + 1));
@ -386,7 +386,7 @@ namespace sol { namespace stack {
}
}
if (isnil) {
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VESION_I_ >= 600
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VERSION_I_ >= 600
#else
lua_pop(L, lua_size<V>::value);
#endif
@ -494,7 +494,7 @@ namespace sol { namespace stack {
C cont;
auto at = cont.cbefore_begin();
std::size_t idx = 0;
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
// This method is HIGHLY performant over regular table iteration thanks to the Lua API changes in 5.3
for (lua_Integer i = 0;; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
if (idx >= cont.max_size()) {

View File

@ -45,7 +45,20 @@ namespace sol { namespace stack {
namespace stack_detail {
template <typename T>
inline bool integer_value_fits(const T& value) {
if constexpr (sizeof(T) < sizeof(lua_Integer) || (std::is_signed_v<T> && sizeof(T) == sizeof(lua_Integer))) {
// We check if we can rely on casts or a lack of padding bits to satisfy
// the requirements here
// If it lacks padding bits, we can jump back and forth between lua_Integer and whatever type without
// loss of information
constexpr bool is_same_signedness
= (std::is_signed_v<T> && std::is_signed_v<lua_Integer>) || (std::is_unsigned_v<T> && std::is_unsigned_v<lua_Integer>);
constexpr bool probaby_fits_within_lua_Integer = sizeof(T) == sizeof(lua_Integer)
#if SOL_IS_ON(SOL_ALL_INTEGER_VALUES_FIT_I_)
&& ((std::has_unique_object_representations_v<T> && std::has_unique_object_representations_v<lua_Integer>) ? true : is_same_signedness)
#else
&& is_same_signedness
#endif
;
if constexpr (sizeof(T) < sizeof(lua_Integer) || probaby_fits_within_lua_Integer) {
(void)value;
return true;
}
@ -87,18 +100,38 @@ namespace sol { namespace stack {
}
} // namespace stack_detail
inline int push_environment_of(lua_State* L, int index = -1) {
inline int push_environment_of(lua_State* L, int target_index = -1) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
luaL_checkstack(L, 1, detail::not_enough_stack_space_environment);
#endif // make sure stack doesn't overflow
#if SOL_LUA_VESION_I_ < 502
#if SOL_LUA_VERSION_I_ < 502
// Use lua_getfenv
lua_getfenv(L, index);
lua_getfenv(L, target_index);
#else
// Use upvalues as explained in Lua 5.2 and beyond's manual
if (lua_getupvalue(L, index, 1) == nullptr) {
push(L, lua_nil);
return 1;
if (lua_iscfunction(L, target_index) != 0) {
const char* maybe_upvalue_name = lua_getupvalue(L, target_index, 1);
if (maybe_upvalue_name != nullptr) {
// it worked, take this one
return 1;
}
}
// Nominally, we search for the `"_ENV"` value.
// If we don't find it.... uh, well. We've got a problem?
for (int upvalue_index = 1;; ++upvalue_index) {
const char* maybe_upvalue_name = lua_getupvalue(L, target_index, upvalue_index);
if (maybe_upvalue_name == nullptr) {
push(L, lua_nil);
break;
}
string_view upvalue_name(maybe_upvalue_name);
if (upvalue_name == "_ENV") {
// Keep this one!
break;
}
// Discard what we received, loop back around
lua_pop(L, 1);
}
#endif
return 1;
@ -106,8 +139,9 @@ namespace sol { namespace stack {
template <typename T>
int push_environment_of(const T& target) {
target.push();
return push_environment_of(target.lua_state(), -1) + 1;
lua_State* target_L = target.lua_state();
int target_index = absolute_index(target_L, -target.push());
return push_environment_of(target_L, target_index);
}
template <typename T>
@ -272,7 +306,7 @@ namespace sol { namespace stack {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
luaL_checkstack(L, 1, detail::not_enough_stack_space_integral);
#endif // make sure stack doesn't overflow
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
if (stack_detail::integer_value_fits<Tu>(value)) {
lua_pushinteger(L, static_cast<lua_Integer>(value));
return 1;
@ -383,7 +417,7 @@ namespace sol { namespace stack {
int tableindex = lua_gettop(L);
std::size_t index = 1;
for (const auto& i : cont) {
#if SOL_LUA_VESION_I_ >= 503
#if SOL_LUA_VERSION_I_ >= 503
int p = is_nested ? stack::push(L, as_nested_ref(i)) : stack::push(L, i);
for (int pi = 0; pi < p; ++pi) {
lua_seti(L, tableindex, static_cast<lua_Integer>(index++));

View File

@ -37,7 +37,7 @@
namespace sol {
inline void register_main_thread(lua_State* L) {
#if SOL_LUA_VESION_I_ < 502
#if SOL_LUA_VERSION_I_ < 502
if (L == nullptr) {
lua_pushnil(L);
lua_setglobal(L, detail::default_main_thread_name());

View File

@ -46,7 +46,7 @@ namespace sol {
bool is53mod = loaded && !(loaded->is<bool>() && !loaded->as<bool>());
if (is53mod)
return loaded;
#if SOL_LUA_VESION_I_ <= 501
#if SOL_LUA_VERSION_I_ <= 501
auto loaded51 = global.traverse_get<optional<object>>("package", "loaded", key);
bool is51mod = loaded51 && !(loaded51->is<bool>() && !loaded51->as<bool>());
if (is51mod)
@ -57,7 +57,7 @@ namespace sol {
template <typename T>
void ensure_package(const std::string& key, T&& sr) {
#if SOL_LUA_VESION_I_ <= 501
#if SOL_LUA_VERSION_I_ <= 501
auto pkg = global["package"];
if (!pkg.valid()) {
pkg = create_table_with("loaded", create_table_with(key, sr));
@ -129,7 +129,7 @@ namespace sol {
for (auto&& library : libraries) {
switch (library) {
#if SOL_LUA_VESION_I_ <= 501 && SOL_IS_ON(SOL_USE_LUAJIT_I_)
#if SOL_LUA_VERSION_I_ <= 501 && SOL_IS_ON(SOL_USE_LUAJIT_I_)
case lib::coroutine:
#endif // luajit opens coroutine base stuff
case lib::base:
@ -142,7 +142,7 @@ namespace sol {
break;
#if SOL_IS_OFF(SOL_USE_LUAJIT_I_)
case lib::coroutine:
#if SOL_LUA_VESION_I_ > 501
#if SOL_LUA_VERSION_I_ > 501
luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
lua_pop(L, 1);
#endif // Lua 5.2+ only
@ -183,7 +183,7 @@ namespace sol {
lua_pop(L, 1);
break;
case lib::utf8:
#if SOL_LUA_VESION_I_ > 502 && SOL_IS_OFF(SOL_USE_LUAJIT_I_)
#if SOL_LUA_VERSION_I_ > 502 && SOL_IS_OFF(SOL_USE_LUAJIT_I_)
luaL_requiref(L, "utf8", luaopen_utf8, 1);
lua_pop(L, 1);
#endif // Lua 5.3+ only
@ -236,7 +236,7 @@ namespace sol {
// one day Lua 5.1 will die a peaceful death
// and its old bones will find blissful rest
auto loaders_proxy = package
#if SOL_LUA_VESION_I_ < 502
#if SOL_LUA_VERSION_I_ < 502
["loaders"]
#else
["searchers"]
@ -264,7 +264,7 @@ namespace sol {
// one day Lua 5.1 will die a peaceful death
// and its old bones will find blissful rest
auto loaders_proxy = package
#if SOL_LUA_VESION_I_ < 502
#if SOL_LUA_VERSION_I_ < 502
["loaders"]
#else
["searchers"]
@ -647,7 +647,7 @@ namespace sol {
}
bool supports_gc_mode(gc_mode mode) const noexcept {
#if SOL_LUA_VESION_I_ >= 504
#if SOL_LUA_VERSION_I_ >= 504
// supports all modes
(void)mode;
return true;
@ -656,7 +656,7 @@ namespace sol {
}
bool is_gc_on() const {
#if SOL_LUA_VESION_I_ >= 502
#if SOL_LUA_VERSION_I_ >= 502
return lua_gc(lua_state(), LUA_GCISRUNNING, 0) == 1;
#else
// You cannot turn it off in Lua 5.1
@ -676,7 +676,7 @@ namespace sol {
// THOUGHT: std::chrono-alikes to map "kilobyte size" here...?
// Make it harder to give MB or KB to a B parameter...?
// Probably overkill for now.
#if SOL_LUA_VESION_I_ >= 504
#if SOL_LUA_VERSION_I_ >= 504
// The manual implies that this function is almost always successful...
// is it?? It could depend on the GC mode...
return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) != 0;
@ -701,7 +701,7 @@ namespace sol {
// THOUGHT: std::chrono-alikes to map "byte size" here...?
// Make it harder to give MB or KB to a B parameter...?
// Probably overkill for now.
#if SOL_LUA_VESION_I_ >= 504
#if SOL_LUA_VERSION_I_ >= 504
int old_mode = lua_gc(lua_state(), LUA_GCINC, pause, step_multiplier, step_byte_size);
if (old_mode == LUA_GCGEN) {
return gc_mode::generational;
@ -719,7 +719,7 @@ namespace sol {
// Returns the old GC mode. Check support using the supports_gc_mode function.
gc_mode change_gc_mode_generational(int minor_multiplier, int major_multiplier) {
#if SOL_LUA_VESION_I_ >= 504
#if SOL_LUA_VERSION_I_ >= 504
// "What does this shit mean?"
// http://www.lua.org/manual/5.4/manual.html#2.5.2
int old_mode = lua_gc(lua_state(), LUA_GCGEN, minor_multiplier, major_multiplier);

View File

@ -173,7 +173,7 @@ namespace sol { namespace u_detail {
}
struct string_for_each_metatable_func {
bool is_destroyion = false;
bool is_destruction = false;
bool is_index = false;
bool is_new_index = false;
bool is_static_index = false;
@ -207,7 +207,7 @@ namespace sol { namespace u_detail {
if (poison_indexing) {
(usb.*change_indexing)(L_, smt_, p_derived_usb, t, idx_call, new_idx_call, meta_idx_call, meta_new_idx_call);
}
if (is_destroyion
if (is_destruction
&& (smt_ == submetatable_type::reference || smt_ == submetatable_type::const_reference || smt_ == submetatable_type::named
|| smt_ == submetatable_type::unique)) {
// gc does not apply to us here
@ -473,45 +473,47 @@ namespace sol { namespace u_detail {
template <bool is_new_index = false, bool base_walking = false, bool from_named_metatable = false, typename... Bases>
static inline int self_index_call(types<Bases...>, lua_State* L, usertype_storage_base& self) {
type k_type = stack::get<type>(L, 2);
if (k_type == type::string) {
index_call_storage* target = nullptr;
{
if constexpr (!from_named_metatable || !is_new_index) {
type k_type = stack::get<type>(L, 2);
if (k_type == type::string) {
index_call_storage* target = nullptr;
string_view k = stack::get<string_view>(L, 2);
auto it = self.string_keys.find(k);
if (it != self.string_keys.cend()) {
target = &it->second;
{
auto it = self.string_keys.find(k);
if (it != self.string_keys.cend()) {
target = &it->second;
}
}
if (target != nullptr) {
// let the target decide what to do, unless it's named...
if constexpr (is_new_index) {
return (target->new_index)(L, target->binding_data);
}
else {
return (target->index)(L, target->binding_data);
}
}
}
if (target != nullptr) {
// let the target decide what to do
if constexpr (is_new_index) {
return (target->new_index)(L, target->binding_data);
else if (k_type != type::lua_nil && k_type != type::none) {
stateless_reference* target = nullptr;
{
stack_reference k = stack::get<stack_reference>(L, 2);
auto it = self.auxiliary_keys.find(k);
if (it != self.auxiliary_keys.cend()) {
target = &it->second;
}
}
else {
return (target->index)(L, target->binding_data);
}
}
}
else if (k_type != type::lua_nil && k_type != type::none) {
stateless_reference* target = nullptr;
{
stack_reference k = stack::get<stack_reference>(L, 2);
auto it = self.auxiliary_keys.find(k);
if (it != self.auxiliary_keys.cend()) {
target = &it->second;
}
}
if (target != nullptr) {
if constexpr (is_new_index) {
// set value and return
target->reset(L, 3);
return 0;
}
else {
// push target to return
// what we found
return stack::push(L, *target);
if (target != nullptr) {
if constexpr (is_new_index) {
// set value and return
target->reset(L, 3);
return 0;
}
else {
// push target to return
// what we found
return stack::push(L, *target);
}
}
}
}
@ -707,7 +709,7 @@ namespace sol { namespace u_detail {
bool is_new_index = (s == to_string(meta_function::new_index));
bool is_static_index = (s == to_string(meta_function::static_index));
bool is_static_new_index = (s == to_string(meta_function::static_new_index));
bool is_destroyion = s == to_string(meta_function::garbage_collect);
bool is_destruction = s == to_string(meta_function::garbage_collect);
bool poison_indexing = (!is_using_index || !is_using_new_index) && (is_var_bind::value || is_index || is_new_index);
void* derived_this = static_cast<void*>(static_cast<usertype_storage<T>*>(this));
index_call_storage ics;
@ -718,7 +720,7 @@ namespace sol { namespace u_detail {
: &Binding::template index_call_with_<false, is_var_bind::value>;
string_for_each_metatable_func for_each_fx;
for_each_fx.is_destroyion = is_destroyion;
for_each_fx.is_destruction = is_destruction;
for_each_fx.is_index = is_index;
for_each_fx.is_new_index = is_new_index;
for_each_fx.is_static_index = is_static_index;

View File

@ -330,6 +330,20 @@
#endif
#endif
#if defined(SOL_ALL_INTEGER_VALUES_FIT)
#if (SOL_ALL_INTEGER_VALUES_FIT != 0)
#define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_ON
#else
#define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_OFF
#endif
#elif !SOL_IS_DEFAULT_OFF(SOL_SAFE_NUMERICS_I_) && SOL_IS_OFF(SOL_SAFE_NUMERICS_I_)
// if numerics is intentionally turned off, flip this on
#define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_ON
#else
// default to off
#define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_OFF
#endif
#if defined(SOL_SAFE_STACK_CHECK)
#if SOL_SAFE_STACK_CHECK != 0
#define SOL_SAFE_STACK_CHECK_I_ SOL_ON

View File

@ -24,13 +24,65 @@
# # Dependencies
FetchContent_Declare(
Catch2
catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.13.4
GIT_TAG v2.13.6
)
FetchContent_MakeAvailable(Catch2)
FetchContent_MakeAvailable(catch2)
function(sol2_add_test_properties target-name)
target_link_libraries(${target-name}
PUBLIC Threads::Threads ${LUA_LIBRARIES} Catch2::Catch2 ${CMAKE_DL_LIBS})
target_compile_definitions(${target-name}
PUBLIC SOL_PRINT_ERRORS=1)
target_compile_options(${target-name}
PRIVATE
${--template-debugging-mode}
${--big-obj}
${--no-unknown-warning}
${--disable-permissive}
${--pedantic}
${--warn-all}
${--warn-pedantic}
${--warn-extra}
${--warn-errors}
${--utf8-literal-encoding}
${--utf8-source-encoding}
${--allow-unknown-warning}
${--allow-unknown-warning-option}
${--allow-noexcept-type}
${--allow-microsoft-casts}
)
target_compile_definitions(${target-name}
PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE)
if (SOL2_CI)
target_compile_definitions(${target-name}
PRIVATE SOL2_CI)
endif()
add_test(NAME ${target-name} COMMAND ${target-name})
if(SOL2_ENABLE_INSTALL)
install(TARGETS ${target-name} RUNTIME DESTINATION bin)
endif()
endfunction()
function(sol2_create_basic_test test_target_name target_sol)
set(test_target_name ${test_target_name})
add_executable(${test_target_name} ${sources})
sol2_add_test_properties(${test_target_name})
target_link_libraries(${test_target_name}
PRIVATE ${target_sol})
target_compile_definitions(${test_target_name}
PRIVATE SOL_ALL_SAFETIES_ON=1)
endfunction()
add_subdirectory(inclusion)
add_subdirectory(runtime_tests)
add_subdirectory(environment)
add_subdirectory(numerics)
add_subdirectory(exceptions)
add_subdirectory(config_tests)
add_subdirectory(regression_tests)
add_subdirectory(run_time)

View File

@ -23,3 +23,4 @@
# # # # sol2 tests
add_subdirectory(function_pointers)
add_subdirectory(integer_value_fits)

View File

@ -0,0 +1,36 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 tests - environment
file(GLOB sources
LIST_DIRECTORIES FALSE
CONFIGURE_DEPENDS
source/*.cpp)
source_group(test_sources FILES ${sources})
sol2_create_basic_test(sol2.tests.config.integer_value_fits sol2::sol2)
sol2_create_basic_test(sol2.tests.config.integer_value_fits.SOL_ALL_SAFETIES_ON sol2::sol2)
target_compile_definitions(sol2.tests.config.integer_value_fits PRIVATE
SOL_ALL_INTEGER_VALUES_FIT=1)
target_compile_definitions(sol2.tests.config.integer_value_fits.SOL_ALL_SAFETIES_ON PRIVATE
SOL_ALL_INTEGER_VALUES_FIT=1 SOL_ALL_SAFETIES_ON=1)

View File

@ -0,0 +1,30 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
int main(int argc, char* argv[]) {
int result = Catch::Session().run(argc, argv);
return result;
}

View File

@ -0,0 +1,51 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
#include <cstdint>
#include <limits>
inline namespace sol2_tests_negative_size_t {
static inline size_t npos_like_api() {
return size_t(-1);
}
} // namespace sol2_tests_negative_size_t
#if SOL_LUA_VERSION_I_ >= 502
TEST_CASE("numeric/negative size_t", "handle negative integers casted to size_t values") {
sol::state lua;
lua.set_function("f", &npos_like_api);
auto result = lua.safe_script("v = f()", sol::script_pass_on_error);
sol::optional<sol::error> maybe_error = result;
REQUIRE(result.valid());
REQUIRE(result.status() == sol::call_status::ok);
REQUIRE_FALSE(maybe_error.has_value());
size_t should_be_like_npos = lua["v"];
REQUIRE(should_be_like_npos == size_t(-1));
}
#endif

View File

@ -0,0 +1,33 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 tests - environment
file(GLOB sources
LIST_DIRECTORIES FALSE
CONFIGURE_DEPENDS
source/*.cpp)
source_group(test_sources FILES ${sources})
sol2_create_basic_test(sol2.tests.environment sol2::sol2)
target_compile_definitions(sol2.tests.environment PRIVATE
SOL_ALL_SAFETIES_ON=1)

View File

@ -0,0 +1,132 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
inline namespace sol2_tests_environments_get {
struct check_g_env {
sol::state* plua;
sol::environment* penv_g;
check_g_env(sol::state& lua, sol::environment& env_g) : plua(&lua), penv_g(&env_g) {
}
void operator()(sol::function target) const {
sol::state& lua = *plua;
sol::environment& env_g = *penv_g;
sol::stack_guard luasg(lua);
sol::environment target_env = sol::get_environment(target);
int test_env_g = env_g["test"];
int test_target_env = target_env["test"];
REQUIRE(test_env_g == test_target_env);
REQUIRE(test_env_g == 5);
REQUIRE(env_g == target_env);
}
};
struct check_f_env {
sol::state* plua;
sol::environment* penv_f;
check_f_env(sol::state& lua, sol::environment& env_f) : plua(&lua), penv_f(&env_f) {
}
void operator()(sol::function target) const {
sol::state& lua = *plua;
sol::environment& env_f = *penv_f;
sol::stack_guard luasg(lua);
sol::environment target_env(sol::env_key, target);
int test_env_f = env_f["test"];
int test_target_env = target_env["test"];
REQUIRE(test_env_f == test_target_env);
REQUIRE(test_env_f == 31);
REQUIRE(env_f == target_env);
}
};
struct check_h_env {
sol::state* plua;
check_h_env(sol::state& lua) : plua(&lua) {
}
void operator()(sol::function target) const {
sol::state& lua = *plua;
sol::stack_guard luasg(lua);
sol::environment target_env = sol::get_environment(target);
// cannot strictly test
// if it's the global table, because different lua runtimes
// give different envs when there is no env
}
};
} // namespace sol2_tests_environments_get
TEST_CASE("environments/get", "Envronments can be taken out of things like Lua functions properly") {
sol::state lua;
sol::stack_guard luasg(lua);
lua.open_libraries(sol::lib::base);
auto result1 = lua.safe_script("f = function() return test end", sol::script_pass_on_error);
REQUIRE(result1.valid());
sol::function f = lua["f"];
sol::environment env_f(lua, sol::create);
env_f["test"] = 31;
bool env_f_was_set = sol::set_environment(env_f, f);
REQUIRE(env_f_was_set);
int result = f();
REQUIRE(result == 31);
auto result2 = lua.safe_script("g = function() test = 5 end", sol::script_pass_on_error);
REQUIRE(result2.valid());
sol::function g = lua["g"];
sol::environment env_g(lua, sol::create);
bool env_g_was_set = env_g.set_on(g);
REQUIRE(env_g_was_set);
g();
int test = env_g["test"];
REQUIRE(test == 5);
sol::object global_test = lua["test"];
REQUIRE(!global_test.valid());
auto result3 = lua.safe_script("h = function() end", sol::script_pass_on_error);
REQUIRE(result3.valid());
lua.set_function("check_f_env", check_f_env(lua, env_f));
lua.set_function("check_g_env", check_g_env(lua, env_g));
lua.set_function("check_h_env", check_h_env(lua));
auto checkf = lua.safe_script("check_f_env(f)", sol::script_pass_on_error);
REQUIRE(checkf.valid());
auto checkg = lua.safe_script("check_g_env(g)", sol::script_pass_on_error);
REQUIRE(checkg.valid());
auto checkh = lua.safe_script("check_h_env(h)", sol::script_pass_on_error);
REQUIRE(checkh.valid());
}

View File

@ -0,0 +1,30 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
int main(int argc, char* argv[]) {
int result = Catch::Session().run(argc, argv);
return result;
}

View File

@ -0,0 +1,92 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
TEST_CASE("environments/sanboxing", "see if environments on functions are working properly") {
SECTION("basic") {
sol::state lua;
sol::stack_guard luasg(lua);
auto result1 = lua.safe_script("a = function() return 5 end", sol::script_pass_on_error);
REQUIRE(result1.valid());
REQUIRE(result1.status() == sol::call_status::ok);
sol::function a = lua["a"];
int result0 = a();
REQUIRE(result0 == 5);
sol::environment env(lua, sol::create);
bool env_set_on_a = sol::set_environment(env, a);
// either works; there can sometimes no environment
REQUIRE((env_set_on_a || !env_set_on_a));
int value = a();
REQUIRE(value == 5);
}
SECTION("return environment value") {
sol::state lua;
sol::stack_guard luasg(lua);
auto result1 = lua.safe_script("a = function() return test end", sol::script_pass_on_error);
REQUIRE(result1.valid());
REQUIRE(result1.status() == sol::call_status::ok);
sol::function a = lua["a"];
sol::environment env(lua, sol::create);
env["test"] = 5;
bool env_set_on_a = env.set_on(a);
REQUIRE(env_set_on_a);
// the function returns the value from the environment table
int result = a();
REQUIRE(result == 5);
}
SECTION("set environment value") {
sol::state lua;
sol::stack_guard luasg(lua);
auto result1 = lua.safe_script("a = function() test = 5 end", sol::script_pass_on_error);
REQUIRE(result1.valid());
REQUIRE(result1.status() == sol::call_status::ok);
sol::function a = lua["a"];
sol::environment env(lua, sol::create);
bool env_set_on_a = sol::set_environment(env, a);
REQUIRE(env_set_on_a);
a();
// the value can be retrieved from the env table
int result = env["test"];
REQUIRE(result == 5);
// the global environment is not polluted
auto gtest = lua["test"];
REQUIRE(!gtest.valid());
}
}

View File

@ -0,0 +1,111 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
TEST_CASE("environments/shadowing", "Environments can properly shadow and fallback on variables") {
sol::state lua;
sol::stack_guard luasg(lua);
lua["b"] = 2142;
SECTION("no fallback") {
sol::environment plain_env(lua, sol::create);
auto result1 = lua.safe_script("a = 24", plain_env, sol::script_pass_on_error);
REQUIRE(result1.valid());
REQUIRE(result1.status() == sol::call_status::ok);
sol::optional<int> maybe_env_a = plain_env["a"];
sol::optional<int> maybe_global_a = lua["a"];
sol::optional<int> maybe_env_b = plain_env["b"];
sol::optional<int> maybe_global_b = lua["b"];
REQUIRE(maybe_env_a != sol::nullopt);
REQUIRE(maybe_env_a.value() == 24);
REQUIRE(maybe_env_b == sol::nullopt);
REQUIRE(maybe_global_a == sol::nullopt);
REQUIRE(maybe_global_b != sol::nullopt);
REQUIRE(maybe_global_b.value() == 2142);
}
SECTION("fallback") {
sol::environment env_with_fallback(lua, sol::create, lua.globals());
auto result1 = lua.safe_script("a = 56", env_with_fallback, sol::script_pass_on_error);
REQUIRE(result1.valid());
REQUIRE(result1.status() == sol::call_status::ok);
sol::optional<int> maybe_env_a = env_with_fallback["a"];
sol::optional<int> maybe_global_a = lua["a"];
sol::optional<int> maybe_env_b = env_with_fallback["b"];
sol::optional<int> maybe_global_b = lua["b"];
REQUIRE(maybe_env_a != sol::nullopt);
REQUIRE(maybe_env_a.value() == 56);
REQUIRE(maybe_env_b != sol::nullopt);
REQUIRE(maybe_env_b.value() == 2142);
REQUIRE(maybe_global_a == sol::nullopt);
REQUIRE(maybe_global_b != sol::nullopt);
REQUIRE(maybe_global_b.value() == 2142);
}
SECTION("from name") {
sol::environment env_with_fallback(lua, sol::create, lua.globals());
lua["env"] = env_with_fallback;
sol::environment env = lua["env"];
auto result1 = lua.safe_script("a = 56", env, sol::script_pass_on_error);
REQUIRE(result1.valid());
sol::optional<int> maybe_env_a = env["a"];
sol::optional<int> maybe_global_a = lua["a"];
sol::optional<int> maybe_env_b = env["b"];
sol::optional<int> maybe_global_b = lua["b"];
REQUIRE(maybe_env_a != sol::nullopt);
REQUIRE(maybe_env_a.value() == 56);
REQUIRE(maybe_env_b != sol::nullopt);
REQUIRE(maybe_env_b.value() == 2142);
REQUIRE(maybe_global_a == sol::nullopt);
REQUIRE(maybe_global_b != sol::nullopt);
REQUIRE(maybe_global_b.value() == 2142);
}
SECTION("name with newtable") {
lua["blank_env"] = sol::new_table(0, 1);
sol::environment plain_env = lua["blank_env"];
auto result1 = lua.safe_script("a = 24", plain_env, sol::script_pass_on_error);
REQUIRE(result1.valid());
sol::optional<int> maybe_env_a = plain_env["a"];
sol::optional<int> maybe_global_a = lua["a"];
sol::optional<int> maybe_env_b = plain_env["b"];
sol::optional<int> maybe_global_b = lua["b"];
REQUIRE(maybe_env_a != sol::nullopt);
REQUIRE(maybe_env_a.value() == 24);
REQUIRE(maybe_env_b == sol::nullopt);
REQUIRE(maybe_global_a == sol::nullopt);
REQUIRE(maybe_global_b != sol::nullopt);
REQUIRE(maybe_global_b.value() == 2142);
}
}

View File

@ -0,0 +1,93 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
TEST_CASE("environments/this_environment", "test various situations of pulling out an environment") {
static std::string code = "return (f(10))";
sol::state lua;
sol::stack_guard luasg(lua);
lua["f"] = [](sol::this_environment te, int x, sol::this_state ts) {
if (te) {
sol::environment& env = te;
return x + static_cast<int>(env["x"]);
}
sol::state_view lua = ts;
return x + static_cast<int>(lua["x"]);
};
sol::environment e(lua, sol::create, lua.globals());
lua["x"] = 5;
e["x"] = 20;
SECTION("from Lua script") {
auto result1 = lua.safe_script(code, e, sol::script_pass_on_error);
REQUIRE(result1.valid());
int value = result1;
REQUIRE(value == 30);
}
SECTION("from C++") {
sol::function f = lua["f"];
bool env_set = e.set_on(f);
REQUIRE(env_set);
int value = f(10);
REQUIRE(value == 30);
}
SECTION("from C++, with no env") {
sol::function f = lua["f"];
int value = f(10);
REQUIRE(value == 15);
}
}
TEST_CASE("environment/this_environment/nested_calls", "Test that this_environment actually finds the right environment in specific nested Lua call contexts") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.set_function("print_no_env", [](int x) { REQUIRE(x == 1); });
lua.set_function("print_this_env", [](int x, sol::this_environment env) { REQUIRE(x == 2); });
sol::protected_function_result result = lua.safe_script(R"(
local var = nil
function test_1_no_env()
var = 1
print_no_env(1)
end
function test_2_this_env()
var = 1
print_this_env(2)
end
test_1_no_env() -- should be ok
test_2_this_env() -- should be okay
)",
sol::script_pass_on_error);
REQUIRE(result.valid());
}

View File

@ -0,0 +1,40 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 tests - environment
file(GLOB sources
LIST_DIRECTORIES FALSE
CONFIGURE_DEPENDS
source/*.cpp)
source_group(test_sources FILES ${sources})
sol2_create_basic_test(sol2.tests.exceptions sol2::sol2)
target_compile_definitions(sol2.tests.exceptions PRIVATE
SOL_ALL_SAFETIES_ON=1)
target_compile_options(sol2.tests.exceptions PRIVATE
${--allow-unreachable-code})
sol2_create_basic_test(sol2.tests.exceptions.SOL_ALL_SAFETIES_ON sol2::sol2)
target_compile_definitions(sol2.tests.exceptions.SOL_ALL_SAFETIES_ON PRIVATE
SOL_ALL_SAFETIES_ON=1)
target_compile_options(sol2.tests.exceptions.SOL_ALL_SAFETIES_ON PRIVATE
${--allow-unreachable-code})

View File

@ -0,0 +1,192 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
#include <stdexcept>
#include <string_view>
inline namespace sol2_tests_exceptions_functions {
inline constexpr const std::string_view special_string = "Whoopsie [expected]";
static void func_throw() {
throw std::runtime_error(special_string.data());
}
struct some_class {
void mem_func_throw() {
throw std::runtime_error(special_string.data());
}
};
} // namespace sol2_tests_exceptions_functions
TEST_CASE("exceptions/functions", "exercise the ability to throw exceptions many different function binding code paths") {
sol::state lua;
lua.open_libraries(sol::lib::base,
sol::lib::package,
sol::lib::coroutine,
sol::lib::string,
sol::lib::os,
sol::lib::math,
sol::lib::table,
sol::lib::io,
sol::lib::debug);
[[maybe_unused]] int a = 10;
some_class sc {};
auto throw_action = [](sol::state& lua, bool use_sc) {
if (use_sc) {
auto res = lua.safe_script("func_throw(sc)", sol::script_pass_on_error);
REQUIRE_FALSE(res.valid());
REQUIRE(res.status() == sol::call_status::runtime);
sol::error err = res.get<sol::error>();
std::string_view err_what(err.what());
REQUIRE(err_what.find(special_string) != std::string::npos);
}
else {
auto res = lua.safe_script("func_throw()", sol::script_pass_on_error);
REQUIRE_FALSE(res.valid());
REQUIRE(res.status() == sol::call_status::runtime);
sol::error err = res.get<sol::error>();
std::string_view err_what(err.what());
REQUIRE(err_what.find(special_string) != std::string::npos);
}
};
lua["sc"] = &sc;
SECTION("proxy") {
lua["func_throw"] = sol::property(&func_throw, &some_class::mem_func_throw);
REQUIRE_NOTHROW(throw_action(lua, false));
REQUIRE_NOTHROW(throw_action(lua, true));
lua["func_throw"] = sol::property(&some_class::mem_func_throw);
REQUIRE_NOTHROW(throw_action(lua, true));
lua["func_throw"] = sol::readonly_property(func_throw);
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = sol::writeonly_property(&some_class::mem_func_throw);
REQUIRE_NOTHROW(throw_action(lua, true));
lua["func_throw"] = [f = &func_throw] { return f(); };
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = &func_throw;
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = [] { return func_throw(); };
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = [a]() { return func_throw(); };
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = [&sc]() { return sc.mem_func_throw(); };
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = &some_class::mem_func_throw;
REQUIRE_NOTHROW(throw_action(lua, true));
lua["func_throw"] = std::function<void()>([f = &func_throw] { return f(); });
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = sol::overload(std::function<void()>([f = &func_throw] { return f(); }));
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = std::function<void()>([] { return func_throw(); });
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = std::function<void()>(&func_throw);
REQUIRE_NOTHROW(throw_action(lua, false));
lua["func_throw"] = std::function<void(some_class&)>(&some_class::mem_func_throw);
REQUIRE_NOTHROW(throw_action(lua, true));
}
SECTION("set_function") {
lua.set_function("func_throw", sol::property(&func_throw, &some_class::mem_func_throw));
REQUIRE_NOTHROW(throw_action(lua, false));
REQUIRE_NOTHROW(throw_action(lua, true));
lua.set_function("func_throw", sol::property(&some_class::mem_func_throw));
REQUIRE_NOTHROW(throw_action(lua, true));
lua.set_function("func_throw", sol::readonly_property(func_throw));
REQUIRE_NOTHROW(throw_action(lua, false));
// TODO: better handling of no_prop in this case here
// lua.set_function("func_throw", sol::writeonly_property(&some_class::mem_func_throw));
// REQUIRE_NOTHROW(throw_action(lua, true));
lua.set_function("func_throw", [f = &func_throw] { return f(); });
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", &func_throw);
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", [] { return func_throw(); });
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", [a]() { return func_throw(); });
REQUIRE_NOTHROW(throw_action(lua, false));
// TODO: this should work at some point, yeah?
/*
lua.set_function(
"func_throw", [](some_class& sc) { return sc.mem_func_throw(); }, sc);
REQUIRE_NOTHROW(throw_action(lua, false));
*/
lua.set_function("func_throw", [&sc]() { return sc.mem_func_throw(); });
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", &some_class::mem_func_throw);
REQUIRE_NOTHROW(throw_action(lua, true));
lua.set_function("func_throw", std::function<void()>([f = &func_throw] { return f(); }));
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", sol::overload(std::function<void()>([f = &func_throw] { return f(); })));
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", std::function<void()>([] { return func_throw(); }));
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", std::function<void()>(&func_throw));
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", &some_class::mem_func_throw, &sc);
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", &some_class::mem_func_throw, sc);
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", &some_class::mem_func_throw, std::ref(sc));
REQUIRE_NOTHROW(throw_action(lua, false));
lua.set_function("func_throw", std::function<void(some_class&)>(&some_class::mem_func_throw));
REQUIRE_NOTHROW(throw_action(lua, true));
}
}

View File

@ -0,0 +1,95 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
inline namespace sol2_tests_exceptions_functions_noexcept {
struct T {
static int noexcept_function() noexcept {
return 0x61;
}
int noexcept_method() noexcept {
return 0x62;
}
};
static int raw_noexcept_function(lua_State* L) noexcept {
return sol::stack::push(L, 0x63);
}
} // namespace sol2_tests_exceptions_functions_noexcept
TEST_CASE("exceptions/functions/noexcept", "allow noexcept functions to be serialized properly into Lua using sol2") {
T t {};
lua_CFunction ccall = sol::c_call<decltype(&raw_noexcept_function), &raw_noexcept_function>;
sol::state lua;
auto check_script_call = [&lua](std::string script) {
auto result = lua.safe_script(script, &sol::script_pass_on_error);
sol::optional<sol::error> maybe_err = result;
REQUIRE(result.valid());
REQUIRE(result.status() == sol::call_status::ok);
REQUIRE_FALSE(maybe_err.has_value());
};
lua.set_function("f", &T::noexcept_function);
lua.set_function("g", &T::noexcept_method);
lua.set_function("h", &T::noexcept_method, T());
lua.set_function("i", &T::noexcept_method, std::ref(t));
lua.set_function("j", &T::noexcept_method, &t);
lua.set_function("k", &T::noexcept_method, t);
lua.set_function("l", &raw_noexcept_function);
lua.set_function("m", ccall);
lua["t"] = T();
check_script_call("v1 = f()");
check_script_call("v2 = g(t)");
check_script_call("v3 = h()");
check_script_call("v4 = i()");
check_script_call("v5 = j()");
check_script_call("v6 = k()");
check_script_call("v7 = l()");
check_script_call("v8 = m()");
int v1 = lua["v1"];
int v2 = lua["v2"];
int v3 = lua["v3"];
int v4 = lua["v4"];
int v5 = lua["v5"];
int v6 = lua["v6"];
int v7 = lua["v7"];
int v8 = lua["v8"];
REQUIRE(v1 == 0x61);
REQUIRE(v2 == 0x62);
REQUIRE(v3 == 0x62);
REQUIRE(v4 == 0x62);
REQUIRE(v5 == 0x62);
REQUIRE(v6 == 0x62);
REQUIRE(v7 == 0x63);
REQUIRE(v8 == 0x63);
}

View File

@ -0,0 +1,30 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
TEST_CASE("exceptions/functions/yielding", "exercise the ability to throw exceptions many different function binding code paths for sol::yielding") {
sol::state lua;
}

View File

@ -0,0 +1,30 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
int main(int argc, char* argv[]) {
int result = Catch::Session().run(argc, argv);
return result;
}

View File

@ -0,0 +1,30 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
TEST_CASE("exceptions/usertypes", "exercise the ability to throw exceptions many different usertype code paths") {
sol::state lua;
}

View File

@ -0,0 +1,30 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
TEST_CASE("exceptions/usertypes/yielding", "exercise the ability to throw exceptions many different usertype code paths for sol::yielding") {
sol::state lua;
}

View File

@ -22,81 +22,36 @@
# # # # sol2 tests - header compilation tests
file(GLOB_RECURSE SOL2_COMPILE_TEST_SOURCES
file(GLOB_RECURSE sources
LIST_DIRECTORIES FALSE
CONFIGURE_DEPENDS
source/*.cpp)
source_group(compile_test_sources FILES "${SOL2_COMPILE_TEST_SOURCES}")
set(sources-single
"source/main.cpp" "source/forward.cpp"
"source/sol.cpp" "source/config.cpp")
function(CREATE_TEST test_target_name test_name target_sol)
if (test_name MATCHES ".single")
add_executable(${test_target_name} "source/main.cpp" "source/forward.cpp" "source/sol.cpp" "source/config.cpp")
else()
add_executable(${test_target_name} "${SOL2_COMPILE_TEST_SOURCES}")
endif()
set_target_properties(${test_target_name}
PROPERTIES
OUTPUT_NAME ${test_name}
EXPORT_NAME sol2::${test_name})
target_link_libraries(${test_target_name}
PUBLIC Threads::Threads ${LUA_LIBRARIES} ${target_sol} ${CMAKE_DL_LIBS})
target_compile_definitions(${test_target_name}
PRIVATE
SOL_ENABLE_INTEROP=1
SOL_ALL_SAFETIES_ON=1)
if (MSVC)
target_compile_options(${test_target_name}
PRIVATE /std:c++latest /EHsc "$<$<CONFIG:Debug>:/MDd>"
"$<$<CONFIG:Release>:/MD>"
"$<$<CONFIG:RelWithDebInfo>:/MD>"
"$<$<CONFIG:MinSizeRel>:/MD>")
target_compile_definitions(${test_target_name}
PRIVATE UNICODE _UNICODE
_CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE)
else()
target_compile_options(${test_target_name}
PRIVATE -std=c++1z
-Wno-unknown-warning -Wno-unknown-warning-option
-Wall -Wextra -Wpedantic -pedantic -pedantic-errors
-Wno-noexcept-type)
set(target-variants
"SOL_ALL_SAFETIES_ON"
"SOL_USE_INTEROP"
"SOL_STRINGS_ARE_NUMBERS")
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# For another day, when C++ is not so crap
# and we have time to audit the entire lib
# for all uses of `detail::swallow`...
#target_compile_options(${test_target_name}
# PRIVATE -Wcomma)
endif()
endif()
function(CREATE_TEST test_target_name target_sol)
set(test_sources ${ARGN})
add_executable(${test_target_name} ${test_sources})
sol2_add_test_properties(${test_target_name})
target_link_libraries(${test_target_name}
PRIVATE ${target_sol})
endfunction()
foreach(variant ${target-variants})
set(target-name "sol2.tests.inclusion.${variant}")
set(single-target-name "sol2.single.tests.inclusion.${variant}")
if (MSVC)
if (NOT CMAKE_COMPILER_ID MATCHES "Clang")
target_compile_options(${test_target_name}
PRIVATE /bigobj /W4)
endif()
else()
if (IS_X86)
if(MINGW)
set_target_properties(${test_target_name}
PROPERTIES
LINK_FLAGS -static-libstdc++)
endif()
endif()
endif()
if (SOL2_CI)
target_compile_definitions(${test_target_name}
PRIVATE SOL2_CI)
endif()
CREATE_TEST(${target-name} sol2::sol2 ${sources})
target_compile_definitions(${target-name} PRIVATE ${variant}=1)
add_test(NAME ${test_name} COMMAND ${test_target_name})
if(SOL2_ENABLE_INSTALL)
install(TARGETS ${test_target_name} RUNTIME DESTINATION bin)
if (SOL2_TESTS_SINGLE)
CREATE_TEST(${single-target-name} sol2::sol2::single ${sources-single})
target_compile_definitions(${single-target-name} PRIVATE ${variant}=1)
endif()
endfunction(CREATE_TEST)
if (SOL2_TESTS)
CREATE_TEST(compile_tests "sol2.compile_tests" sol2::sol2)
endif()
if (SOL2_TESTS_SINGLE)
CREATE_TEST(compile_tests_single "sol2.compile_tests.single" sol2::sol2::single)
endif()
endforeach()

View File

@ -0,0 +1,34 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 tests - environment
file(GLOB sources
LIST_DIRECTORIES FALSE
CONFIGURE_DEPENDS
source/*.cpp)
source_group(test_sources FILES ${sources})
sol2_create_basic_test(sol2.tests.numerics sol2::sol2)
sol2_create_basic_test(sol2.tests.numerics.SOL_ALL_SAFETIES_ON sol2::sol2)
target_compile_definitions(sol2.tests.numerics.SOL_ALL_SAFETIES_ON PRIVATE
SOL_ALL_SAFETIES_ON=1)

View File

@ -1,168 +1,168 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "sol_test.hpp"
#include <catch2/catch.hpp>
#include <cstdint>
#include <limits>
inline namespace sol2_test_large_integer {
inline bool bool_roundtrip(bool num) {
REQUIRE(num == true);
return num;
}
inline void trigger_passthrough_crash(sol::state& lua) {
sol::protected_function pf = lua["f"];
auto result = pf(0xFFFFFFFFFFFFFFFFull);
(void)result;
}
template <typename T>
inline T intT_passthrough(T num) {
return num;
}
template <typename T>
inline T intT_roundtrip(T num) {
REQUIRE(num == std::numeric_limits<T>::max());
return num;
}
inline std::uint64_t int53_roundtrip(std::uint64_t num) {
REQUIRE(num == 0x1FFFFFFFFFFFFFull);
return num;
}
} // namespace sol2_test_large_integer
TEST_CASE("large_integer/bool", "pass bool integral value to and from lua") {
sol::state lua;
lua.open_libraries();
lua.set_function("f", bool_roundtrip);
sol::optional<sol::error> result1 = lua.safe_script(
"x = f(true)\n"
"assert(x == true)",
sol::script_pass_on_error);
REQUIRE_FALSE(result1.has_value());
sol::object x = lua["x"];
REQUIRE(x.is<bool>());
REQUIRE(x.as<bool>() == true);
REQUIRE_FALSE(x.is<std::int32_t>());
{
auto result = lua.safe_script("f(1)", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
}
TEST_CASE("large_integers/unsigned32", "pass large unsigned 32bit values to and from lua") {
using T = std::uint32_t;
sol::state lua;
lua.open_libraries();
lua.set_function("f", intT_roundtrip<T>);
auto result1 = lua.safe_script(
"x = f(0xFFFFFFFF)\n"
"assert(x == 0xFFFFFFFF)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
sol::object x = lua["x"];
REQUIRE(x.is<T>());
REQUIRE(x.as<T>() == 0xFFFFFFFF);
}
TEST_CASE("large_integer/unsigned53", "pass large unsigned 53bit value to and from lua") {
using T = std::uint64_t;
sol::state lua;
lua.open_libraries();
lua.set_function("f", int53_roundtrip);
auto result1 = lua.safe_script(
"x = f(0x1FFFFFFFFFFFFF)\n"
"assert(x == 0x1FFFFFFFFFFFFF)");
REQUIRE(result1.valid());
sol::object x = lua["x"];
REQUIRE(x.is<T>());
REQUIRE(x.as<T>() == 0x1FFFFFFFFFFFFFull);
}
TEST_CASE("large_integer/unsigned64", "pass too large unsigned 64bit value to lua") {
using T = std::int64_t;
sol::state lua;
lua.set_function("f", intT_passthrough<T>);
REQUIRE_THROWS(trigger_passthrough_crash(lua));
}
TEST_CASE("large_integer/double", "pass negative and large positive values as signed and unsigned from and to lua") {
sol::state lua;
lua.open_libraries();
lua.set_function("s32", intT_passthrough<std::int32_t>);
lua.set_function("s64", intT_passthrough<std::int64_t>);
lua.set_function("u32", intT_passthrough<std::uint32_t>);
lua.set_function("u64", intT_passthrough<std::uint64_t>);
{
// signed 32bit
auto result1 = lua.safe_script("x = s32(-1)", sol::script_pass_on_error);
REQUIRE(result1.valid());
auto result2 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error);
REQUIRE(result2.valid());
auto result3 = lua.safe_script("x = s32(0xFFFFFFFF)", sol::script_pass_on_error);
REQUIRE(result3.valid());
auto result4 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error);
REQUIRE(result4.valid());
sol::object x = lua["x"];
REQUIRE(x.is<std::int32_t>());
REQUIRE(x.as<std::int32_t>() == -1);
REQUIRE(x.is<std::uint32_t>());
REQUIRE(x.as<std::uint32_t>() == 0xFFFFFFFF);
}
// unsigned 32bit
{
auto result1 = lua.safe_script("x = u32(0xFFFFFFFF)", sol::script_pass_on_error);
REQUIRE(result1.valid());
auto result2 = lua.safe_script("assert(x == 0xFFFFFFFF)", sol::script_pass_on_error);
REQUIRE(result2.valid());
auto result3 = lua.safe_script("x = u32(-1)", sol::script_pass_on_error);
REQUIRE(result3.valid());
auto result4 = lua.safe_script("assert(x == 0xFFFFFFFF)", sol::script_pass_on_error);
REQUIRE(result4.valid());
sol::object x = lua["x"];
REQUIRE(x.is<std::int32_t>());
REQUIRE(x.as<std::int32_t>() == -1);
REQUIRE(x.is<std::uint32_t>());
REQUIRE(x.as<std::uint32_t>() == 0xFFFFFFFF);
}
// signed 64bit
{
auto result1 = lua.safe_script("x = s64(-1)", sol::script_pass_on_error);
REQUIRE(result1.valid());
auto result2 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error);
REQUIRE(result2.valid());
sol::object x = lua["x"];
REQUIRE(x.is<std::int64_t>());
REQUIRE(x.as<std::int64_t>() == -1);
REQUIRE(x.is<std::uint64_t>());
REQUIRE(x.as<std::uint64_t>() == 0xFFFFFFFFFFFFFFFFull);
}
}
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch.hpp>
#include <sol/sol.hpp>
#include <cstdint>
#include <limits>
inline namespace sol2_tests_large_integer {
inline bool bool_roundtrip(bool num) {
REQUIRE(num == true);
return num;
}
inline void trigger_passthrough_crash(sol::state& lua) {
sol::protected_function pf = lua["f"];
auto result = pf(0xFFFFFFFFFFFFFFFFull);
(void)result;
}
template <typename T>
inline T intT_passthrough(T num) {
return num;
}
template <typename T>
inline T intT_roundtrip(T num) {
REQUIRE(num == std::numeric_limits<T>::max());
return num;
}
inline std::uint64_t int53_roundtrip(std::uint64_t num) {
REQUIRE(num == 0x1FFFFFFFFFFFFFull);
return num;
}
} // namespace sol2_tests_large_integer
TEST_CASE("large_integer/bool", "pass bool integral value to and from lua") {
sol::state lua;
lua.open_libraries();
lua.set_function("f", bool_roundtrip);
sol::optional<sol::error> result1 = lua.safe_script(
"x = f(true)\n"
"assert(x == true)",
sol::script_pass_on_error);
REQUIRE_FALSE(result1.has_value());
sol::object x = lua["x"];
REQUIRE(x.is<bool>());
REQUIRE(x.as<bool>() == true);
REQUIRE_FALSE(x.is<std::int32_t>());
{
auto result = lua.safe_script("f(1)", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
}
TEST_CASE("large_integers/unsigned32", "pass large unsigned 32bit values to and from lua") {
using T = std::uint32_t;
sol::state lua;
lua.open_libraries();
lua.set_function("f", intT_roundtrip<T>);
auto result1 = lua.safe_script(
"x = f(0xFFFFFFFF)\n"
"assert(x == 0xFFFFFFFF)",
sol::script_pass_on_error);
REQUIRE(result1.valid());
sol::object x = lua["x"];
REQUIRE(x.is<T>());
REQUIRE(x.as<T>() == 0xFFFFFFFF);
}
TEST_CASE("large_integer/unsigned53", "pass large unsigned 53bit value to and from lua") {
using T = std::uint64_t;
sol::state lua;
lua.open_libraries();
lua.set_function("f", int53_roundtrip);
auto result1 = lua.safe_script(
"x = f(0x1FFFFFFFFFFFFF)\n"
"assert(x == 0x1FFFFFFFFFFFFF)");
REQUIRE(result1.valid());
sol::object x = lua["x"];
REQUIRE(x.is<T>());
REQUIRE(x.as<T>() == 0x1FFFFFFFFFFFFFull);
}
TEST_CASE("large_integer/unsigned64", "pass too large unsigned 64bit value to lua") {
using T = std::int64_t;
sol::state lua;
lua.set_function("f", intT_passthrough<T>);
REQUIRE_THROWS(trigger_passthrough_crash(lua));
}
TEST_CASE("large_integer/double", "pass negative and large positive values as signed and unsigned from and to lua") {
sol::state lua;
lua.open_libraries();
lua.set_function("s32", intT_passthrough<std::int32_t>);
lua.set_function("s64", intT_passthrough<std::int64_t>);
lua.set_function("u32", intT_passthrough<std::uint32_t>);
lua.set_function("u64", intT_passthrough<std::uint64_t>);
{
// signed 32bit
auto result1 = lua.safe_script("x = s32(-1)", sol::script_pass_on_error);
REQUIRE(result1.valid());
auto result2 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error);
REQUIRE(result2.valid());
auto result3 = lua.safe_script("x = s32(0xFFFFFFFF)", sol::script_pass_on_error);
REQUIRE(result3.valid());
auto result4 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error);
REQUIRE(result4.valid());
sol::object x = lua["x"];
REQUIRE(x.is<std::int32_t>());
REQUIRE(x.as<std::int32_t>() == -1);
REQUIRE(x.is<std::uint32_t>());
REQUIRE(x.as<std::uint32_t>() == 0xFFFFFFFF);
}
// unsigned 32bit
{
auto result1 = lua.safe_script("x = u32(0xFFFFFFFF)", sol::script_pass_on_error);
REQUIRE(result1.valid());
auto result2 = lua.safe_script("assert(x == 0xFFFFFFFF)", sol::script_pass_on_error);
REQUIRE(result2.valid());
auto result3 = lua.safe_script("x = u32(-1)", sol::script_pass_on_error);
REQUIRE(result3.valid());
auto result4 = lua.safe_script("assert(x == 0xFFFFFFFF)", sol::script_pass_on_error);
REQUIRE(result4.valid());
sol::object x = lua["x"];
REQUIRE(x.is<std::int32_t>());
REQUIRE(x.as<std::int32_t>() == -1);
REQUIRE(x.is<std::uint32_t>());
REQUIRE(x.as<std::uint32_t>() == 0xFFFFFFFF);
}
// signed 64bit
{
auto result1 = lua.safe_script("x = s64(-1)", sol::script_pass_on_error);
REQUIRE(result1.valid());
auto result2 = lua.safe_script("assert(x == -1)", sol::script_pass_on_error);
REQUIRE(result2.valid());
sol::object x = lua["x"];
REQUIRE(x.is<std::int64_t>());
REQUIRE(x.as<std::int64_t>() == -1);
REQUIRE(x.is<std::uint64_t>());
REQUIRE(x.as<std::uint64_t>() == 0xFFFFFFFFFFFFFFFFull);
}
}

View File

@ -0,0 +1,30 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
int main(int argc, char* argv[]) {
int result = Catch::Session().run(argc, argv);
return result;
}

View File

@ -0,0 +1,33 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2021 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 tests - runtime tests
file(GLOB sources
LIST_DIRECTORIES FALSE
CONFIGURE_DEPENDS
source/*.cpp)
sol2_create_basic_test("sol2.tests.run_time" sol2::sol2)
if (SOL2_TESTS_SINGLE)
sol2_create_basic_test("sol2.single.tests.run_time" sol2::sol2::single)
endif()

View File

@ -257,7 +257,7 @@ void associative_ordered_container_key_value_check(sol::state& lua, T& data, T&
typedef typename T::mapped_type V;
lua["collect"] = [&reflect](K k, V v) { reflect.insert({ k, v }); };
#if SOL_LUA_VERSION > 502
#if SOL_LUA_VERSION_I_ > 502
lua["val"] = data;
auto r = lua.safe_script(R"(
for k, v in pairs(val) do

View File

@ -255,7 +255,7 @@ TEST_CASE("containers/input iterators", "test shitty input iterators that are al
not_really_a_container c;
lua["c"] = &c;
#if SOL_LUA_VERSION > 502
#if SOL_LUA_VERSION_I_ > 502
auto result0 = lua.safe_script(R"lua(
for k, v in pairs(c) do
assert((k - 1) == v:val())

View File

@ -65,7 +65,8 @@ inline namespace sol2_test_coroutines {
mThread = sol::thread::create(luaContext);
sol::state_view luaThreadState = mThread.state();
mThreadEnvironment = sol::environment(luaThreadState, sol::create, luaThreadState.globals());
sol::set_environment(mThreadEnvironment, mThread);
bool thread_environment_set_successfully = sol::set_environment(mThreadEnvironment, mThread);
REQUIRE(thread_environment_set_successfully);
sol::optional<sol::table> actionTable = luaThreadState["aTable"];
if (actionTable) {

View File

@ -105,10 +105,6 @@ struct fer {
}
};
static int raw_noexcept_function(lua_State* L) noexcept {
return sol::stack::push(L, 0x63);
}
TEST_CASE("functions/tuple returns", "Make sure tuple returns are ordered properly") {
sol::state lua;
auto result1 = lua.safe_script("function f() return '3', 4 end", sol::script_pass_on_error);
@ -1438,58 +1434,3 @@ TEST_CASE("functions/lua style default arguments", "allow default arguments usin
REQUIRE(10 == v2nd);
REQUIRE(10 == v3nd);
}
#if !defined(_MSC_VER) || !(defined(_WIN32) && !defined(_WIN64))
TEST_CASE("functions/noexcept", "allow noexcept functions to be serialized properly into Lua using sol2") {
struct T {
static int noexcept_function() noexcept {
return 0x61;
}
int noexcept_method() noexcept {
return 0x62;
}
} t;
lua_CFunction ccall = sol::c_call<decltype(&raw_noexcept_function), &raw_noexcept_function>;
sol::state lua;
lua.set_function("f", &T::noexcept_function);
lua.set_function("g", &T::noexcept_method);
lua.set_function("h", &T::noexcept_method, T());
lua.set_function("i", &T::noexcept_method, std::ref(t));
lua.set_function("j", &T::noexcept_method, &t);
lua.set_function("k", &T::noexcept_method, t);
lua.set_function("l", &raw_noexcept_function);
lua.set_function("m", ccall);
lua["t"] = T();
lua.safe_script("v1 = f()");
lua.safe_script("v2 = g(t)");
lua.safe_script("v3 = h()");
lua.safe_script("v4 = i()");
lua.safe_script("v5 = j()");
lua.safe_script("v6 = k()");
lua.safe_script("v7 = l()");
lua.safe_script("v8 = m()");
int v1 = lua["v1"];
int v2 = lua["v2"];
int v3 = lua["v3"];
int v4 = lua["v4"];
int v5 = lua["v5"];
int v6 = lua["v6"];
int v7 = lua["v7"];
int v8 = lua["v8"];
REQUIRE(v1 == 0x61);
REQUIRE(v2 == 0x62);
REQUIRE(v3 == 0x62);
REQUIRE(v4 == 0x62);
REQUIRE(v5 == 0x62);
REQUIRE(v6 == 0x62);
REQUIRE(v7 == 0x63);
REQUIRE(v8 == 0x63);
}
#endif // Strange VC++ stuff

View File

@ -0,0 +1,30 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
int main(int argc, char* argv[]) {
int result = Catch::Session().run(argc, argv);
return result;
}

View File

@ -282,7 +282,7 @@ TEST_CASE("operators/default with pointers", "test that default operations still
REQUIRE(ptr_test);
REQUIRE(unique_test);
#if SOL_LUA_VERSION > 502
#if SOL_LUA_VERSION_I_ > 502
lua.script("ptr_unique_test = t1 == t3");
bool ptr_unique_test = lua["ptr_unique_test"];
@ -419,7 +419,7 @@ TEST_CASE("operators/member_stringable", "test member to_string stringability")
}
TEST_CASE("operators/container-like", "test that generic begin/end and iterator are automatically bound") {
#if SOL_LUA_VERSION > 501
#if SOL_LUA_VERSION_I_ > 501
struct container {
typedef int* iterator;
typedef int value_type;

View File

@ -88,7 +88,7 @@ TEST_CASE("plain/indestructible", "test that we error for types that are innatel
lua["i"] = *i;
lua.safe_script("i = nil");
auto result = lua.safe_script("collectgarbage() collectgarbage()", sol::script_pass_on_error);
#if SOL_LUA_VERSION > 503
#if SOL_LUA_VERSION_I_ > 503
REQUIRE(result.valid());
#else
REQUIRE_FALSE(result.valid());

Some files were not shown because too many files have changed in this diff Show More