summaryrefslogtreecommitdiff
path: root/mnv
diff options
context:
space:
mode:
Diffstat (limited to 'mnv')
-rw-r--r--mnv/CMakeLists.txt213
-rw-r--r--mnv/CMakePresets.json318
-rw-r--r--mnv/cmake/config.h.cmake16
-rw-r--r--mnv/src/if_ruby.c18
-rw-r--r--mnv/src/scriptfile.c2
-rw-r--r--mnv/src/testdir/test_regexp_latin.mnv60
-rw-r--r--mnv/src/testdir/util/screendump.mnv16
7 files changed, 601 insertions, 42 deletions
diff --git a/mnv/CMakeLists.txt b/mnv/CMakeLists.txt
index 99c9debc14..0e2d9bc394 100644
--- a/mnv/CMakeLists.txt
+++ b/mnv/CMakeLists.txt
@@ -392,8 +392,6 @@ if(PKG_CONFIG_FOUND)
pkg_check_modules(WAYLAND QUIET wayland-client)
if(WAYLAND_FOUND)
set(HAVE_WAYLAND 1)
- set(FEAT_WAYLAND 1)
- set(FEAT_WAYLAND_CLIPBOARD 1)
# Generate wayland protocol files using wayland-scanner
find_program(WAYLAND_SCANNER wayland-scanner)
@@ -585,6 +583,17 @@ if(MNV_LUA)
set(FEAT_LUA 1)
if(MNV_LUA_DYNAMIC)
set(DYNAMIC_LUA 1)
+ # Determine the shared library filename for dynamic loading
+ foreach(_lua_lib ${LUA_LIBRARIES})
+ if(_lua_lib MATCHES "\\.(so|dylib)")
+ get_filename_component(_lua_realpath "${_lua_lib}" REALPATH)
+ get_filename_component(DYNAMIC_LUA_DLL "${_lua_realpath}" NAME)
+ break()
+ endif()
+ endforeach()
+ if(NOT DYNAMIC_LUA_DLL)
+ set(DYNAMIC_LUA_DLL "liblua.so")
+ endif()
endif()
message(STATUS "Lua: ${LUA_VERSION_STRING}")
else()
@@ -600,6 +609,22 @@ if(MNV_PERL)
set(FEAT_PERL 1)
if(MNV_PERL_DYNAMIC)
set(DYNAMIC_PERL 1)
+ # Determine the shared library filename for dynamic loading
+ if(PERL_LIBRARY)
+ get_filename_component(_perl_realpath "${PERL_LIBRARY}" REALPATH)
+ get_filename_component(DYNAMIC_PERL_DLL "${_perl_realpath}" NAME)
+ else()
+ foreach(_perl_lib ${PERLLIBS_LIBRARIES})
+ if(_perl_lib MATCHES "\\.(so|dylib)")
+ get_filename_component(_perl_realpath "${_perl_lib}" REALPATH)
+ get_filename_component(DYNAMIC_PERL_DLL "${_perl_realpath}" NAME)
+ break()
+ endif()
+ endforeach()
+ endif()
+ if(NOT DYNAMIC_PERL_DLL)
+ set(DYNAMIC_PERL_DLL "libperl.so")
+ endif()
endif()
message(STATUS "Perl: ${PERL_VERSION_STRING}")
else()
@@ -614,6 +639,19 @@ if(MNV_PYTHON3)
set(FEAT_PYTHON3 1)
if(MNV_PYTHON3_DYNAMIC)
set(DYNAMIC_PYTHON3 1)
+ # Determine the shared library filename for dynamic loading
+ if(Python3_LIBRARIES)
+ foreach(_py3_lib ${Python3_LIBRARIES})
+ if(_py3_lib MATCHES "\\.(so|dylib)")
+ get_filename_component(_py3_realpath "${_py3_lib}" REALPATH)
+ get_filename_component(DYNAMIC_PYTHON3_DLL "${_py3_realpath}" NAME)
+ break()
+ endif()
+ endforeach()
+ endif()
+ if(NOT DYNAMIC_PYTHON3_DLL)
+ set(DYNAMIC_PYTHON3_DLL "libpython${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}.so")
+ endif()
endif()
message(STATUS "Python3: ${Python3_VERSION}")
else()
@@ -628,6 +666,14 @@ if(MNV_RUBY)
set(FEAT_RUBY 1)
if(MNV_RUBY_DYNAMIC)
set(DYNAMIC_RUBY 1)
+ # Determine the shared library filename for dynamic loading
+ if(RUBY_LIBRARY)
+ get_filename_component(_ruby_realpath "${RUBY_LIBRARY}" REALPATH)
+ get_filename_component(DYNAMIC_RUBY_DLL "${_ruby_realpath}" NAME)
+ endif()
+ if(NOT DYNAMIC_RUBY_DLL)
+ set(DYNAMIC_RUBY_DLL "libruby.so")
+ endif()
endif()
message(STATUS "Ruby: ${RUBY_VERSION}")
else()
@@ -642,6 +688,14 @@ if(MNV_TCL)
set(FEAT_TCL 1)
if(MNV_TCL_DYNAMIC)
set(DYNAMIC_TCL 1)
+ # Determine the shared library filename for dynamic loading
+ if(TCL_LIBRARY)
+ get_filename_component(_tcl_realpath "${TCL_LIBRARY}" REALPATH)
+ get_filename_component(DYNAMIC_TCL_DLL "${_tcl_realpath}" NAME)
+ endif()
+ if(NOT DYNAMIC_TCL_DLL)
+ set(DYNAMIC_TCL_DLL "libtcl.so")
+ endif()
endif()
message(STATUS "Tcl: found")
else()
@@ -672,6 +726,9 @@ if(MNV_FEATURE STREQUAL "huge")
# Socket-based clientserver on Unix
set(FEAT_CLIENTSERVER 1)
endif()
+ if(HAVE_WAYLAND)
+ set(FEAT_WAYLAND 1)
+ endif()
elseif(MNV_FEATURE STREQUAL "normal")
set(FEAT_NORMAL 1)
set(FEAT_EVAL 1)
@@ -682,6 +739,9 @@ elseif(MNV_FEATURE STREQUAL "normal")
if(MNV_CHANNEL)
set(FEAT_JOB_CHANNEL 1)
endif()
+ if(HAVE_WAYLAND)
+ set(FEAT_WAYLAND 1)
+ endif()
elseif(MNV_FEATURE STREQUAL "tiny")
set(FEAT_TINY 1)
set(FEAT_TERMINAL 0)
@@ -975,8 +1035,55 @@ if(FEAT_LUA)
endif()
if(FEAT_PERL)
- # Perl requires special preprocessing of .xs files, handle separately
- list(APPEND MNV_CORE_SRC src/if_perl.xs)
+ # Perl .xs files need preprocessing with xsubpp to generate C code
+ find_program(PERL_EXECUTABLE perl)
+ if(PERL_EXECUTABLE)
+ # Find xsubpp
+ execute_process(
+ COMMAND ${PERL_EXECUTABLE} -MConfig -e "print \$Config{privlibexp}"
+ OUTPUT_VARIABLE PERL_PRIVLIB
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ find_program(XSUBPP xsubpp HINTS ${PERL_PRIVLIB}/ExtUtils /usr/bin/core_perl)
+
+ if(XSUBPP)
+ set(_perl_generated "${CMAKE_CURRENT_BINARY_DIR}/auto/if_perl.c")
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/auto")
+ add_custom_command(
+ OUTPUT "${_perl_generated}"
+ COMMAND ${PERL_EXECUTABLE} ${XSUBPP} -prototypes -typemap
+ "${PERL_PRIVLIB}/ExtUtils/typemap"
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/if_perl.xs"
+ > "${_perl_generated}"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/if_perl.xs"
+ COMMENT "Generating if_perl.c from if_perl.xs"
+ )
+ list(APPEND MNV_CORE_SRC "${_perl_generated}")
+
+ # Get Perl compile flags
+ execute_process(
+ COMMAND ${PERL_EXECUTABLE} -MExtUtils::Embed -e ccopts
+ OUTPUT_VARIABLE PERL_CFLAGS
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ # Extract include dirs from Perl ccopts
+ string(REGEX MATCHALL "-I[^ ]+" PERL_INCLUDE_FLAGS "${PERL_CFLAGS}")
+ foreach(_flag ${PERL_INCLUDE_FLAGS})
+ string(REGEX REPLACE "^-I" "" _dir "${_flag}")
+ list(APPEND PERL_INCLUDE_DIRS "${_dir}")
+ endforeach()
+ # Extract compile definitions from Perl ccopts (-D flags)
+ string(REGEX MATCHALL "-D[^ ]+" PERL_DEFINE_FLAGS "${PERL_CFLAGS}")
+ # Extract other compile options (-f flags etc.)
+ string(REGEX MATCHALL "-f[^ ]+" PERL_COMPILE_OPTIONS "${PERL_CFLAGS}")
+ else()
+ message(WARNING "xsubpp not found, Perl support disabled")
+ set(FEAT_PERL 0)
+ endif()
+ else()
+ message(WARNING "perl not found, Perl support disabled")
+ set(FEAT_PERL 0)
+ endif()
endif()
if(FEAT_PYTHON3)
@@ -985,6 +1092,10 @@ endif()
if(FEAT_RUBY)
list(APPEND MNV_CORE_SRC src/if_ruby.c)
+
+ # Compute numeric Ruby version (e.g. 34 for Ruby 3.4.x)
+ string(REGEX REPLACE "\\." "" _ruby_ver_nodots "${RUBY_VERSION}")
+ string(SUBSTRING "${_ruby_ver_nodots}" 0 2 RUBY_VERSION_NUM)
endif()
if(FEAT_TCL)
@@ -1110,6 +1221,25 @@ if(FEAT_LUA)
target_include_directories(mnv PRIVATE ${LUA_INCLUDE_DIR})
endif()
+# Perl
+if(FEAT_PERL)
+ if(NOT DYNAMIC_PERL AND PERLLIBS_LIBRARIES)
+ target_link_libraries(mnv PRIVATE ${PERLLIBS_LIBRARIES})
+ endif()
+ if(PERL_INCLUDE_DIRS)
+ target_include_directories(mnv PRIVATE ${PERL_INCLUDE_DIRS})
+ endif()
+ if(PERL_INCLUDE_PATH)
+ target_include_directories(mnv PRIVATE ${PERL_INCLUDE_PATH})
+ endif()
+ # Apply Perl-specific compile definitions to the generated if_perl.c
+ if(_perl_generated AND PERL_DEFINE_FLAGS)
+ set_source_files_properties("${_perl_generated}" PROPERTIES
+ COMPILE_OPTIONS "${PERL_DEFINE_FLAGS}"
+ )
+ endif()
+endif()
+
# Python 3
if(FEAT_PYTHON3)
if(NOT DYNAMIC_PYTHON3)
@@ -1124,12 +1254,23 @@ if(FEAT_RUBY)
target_link_libraries(mnv PRIVATE ${RUBY_LIBRARY})
endif()
target_include_directories(mnv PRIVATE ${RUBY_INCLUDE_DIRS})
+ target_compile_definitions(mnv PRIVATE RUBY_VERSION=${RUBY_VERSION_NUM})
endif()
# Tcl
if(FEAT_TCL)
if(NOT DYNAMIC_TCL)
target_link_libraries(mnv PRIVATE ${TCL_LIBRARY})
+ else()
+ # Dynamic Tcl still requires the stubs library for Tcl_InitStubs
+ find_library(TCL_STUB_LIBRARY NAMES tclstub tclstub8.6 tclstub8.5
+ HINTS "${TCL_LIBRARY_DIR}" "${TCL_PREFIX}/lib"
+ )
+ if(TCL_STUB_LIBRARY)
+ target_link_libraries(mnv PRIVATE ${TCL_STUB_LIBRARY})
+ else()
+ message(WARNING "Tcl stubs library not found, dynamic Tcl may fail")
+ endif()
endif()
target_include_directories(mnv PRIVATE ${TCL_INCLUDE_PATH})
endif()
@@ -1226,7 +1367,53 @@ if(MNV_BUILD_TESTS)
endif()
endif()
+ # Language interpreter support for tests
+ if(FEAT_LUA)
+ if(NOT DYNAMIC_LUA)
+ target_link_libraries(${TEST_NAME} PRIVATE ${LUA_LIBRARIES})
+ endif()
+ target_include_directories(${TEST_NAME} PRIVATE ${LUA_INCLUDE_DIR})
+ endif()
+ if(FEAT_PERL)
+ if(NOT DYNAMIC_PERL AND PERLLIBS_LIBRARIES)
+ target_link_libraries(${TEST_NAME} PRIVATE ${PERLLIBS_LIBRARIES})
+ endif()
+ if(PERL_INCLUDE_DIRS)
+ target_include_directories(${TEST_NAME} PRIVATE ${PERL_INCLUDE_DIRS})
+ endif()
+ if(PERL_INCLUDE_PATH)
+ target_include_directories(${TEST_NAME} PRIVATE ${PERL_INCLUDE_PATH})
+ endif()
+ endif()
+ if(FEAT_PYTHON3)
+ if(NOT DYNAMIC_PYTHON3)
+ target_link_libraries(${TEST_NAME} PRIVATE Python3::Python)
+ endif()
+ target_include_directories(${TEST_NAME} PRIVATE ${Python3_INCLUDE_DIRS})
+ endif()
+ if(FEAT_RUBY)
+ if(NOT DYNAMIC_RUBY)
+ target_link_libraries(${TEST_NAME} PRIVATE ${RUBY_LIBRARY})
+ endif()
+ target_include_directories(${TEST_NAME} PRIVATE ${RUBY_INCLUDE_DIRS})
+ target_compile_definitions(${TEST_NAME} PRIVATE RUBY_VERSION=${RUBY_VERSION_NUM})
+ endif()
+ if(FEAT_TCL)
+ if(NOT DYNAMIC_TCL)
+ target_link_libraries(${TEST_NAME} PRIVATE ${TCL_LIBRARY})
+ else()
+ if(TCL_STUB_LIBRARY)
+ target_link_libraries(${TEST_NAME} PRIVATE ${TCL_STUB_LIBRARY})
+ endif()
+ endif()
+ target_include_directories(${TEST_NAME} PRIVATE ${TCL_INCLUDE_PATH})
+ endif()
+
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES
+ TIMEOUT 120
+ ENVIRONMENT "DISPLAY=;WAYLAND_DISPLAY="
+ )
endfunction()
# Create unit test executables
@@ -1242,6 +1429,8 @@ if(MNV_BUILD_TESTS)
COMMAND ${CMAKE_COMMAND} -E env
"MNVPROG=$<TARGET_FILE:mnv>"
"MNVRUNTIME=${CMAKE_CURRENT_SOURCE_DIR}/runtime"
+ "LINES=24"
+ "COLUMNS=80"
${CMAKE_MAKE_PROGRAM} -C ${CMAKE_CURRENT_SOURCE_DIR}/src/testdir
-f Makefile nongui
MNVPROG=$<TARGET_FILE:mnv>
@@ -1257,8 +1446,12 @@ if(MNV_BUILD_TESTS)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/runtime/indent/Makefile")
add_test(
NAME indent_tests
- COMMAND ${CMAKE_MAKE_PROGRAM} -C ${CMAKE_CURRENT_SOURCE_DIR}/runtime/indent
- test MNVPROG=$<TARGET_FILE:mnv>
+ COMMAND ${CMAKE_COMMAND} -E env
+ "MNVRUNTIME=${CMAKE_CURRENT_SOURCE_DIR}/runtime"
+ "LINES=24"
+ "COLUMNS=80"
+ ${CMAKE_MAKE_PROGRAM} -C ${CMAKE_CURRENT_SOURCE_DIR}/runtime/indent
+ test MNVPROG=$<TARGET_FILE:mnv>
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/runtime/indent
)
set_tests_properties(indent_tests PROPERTIES
@@ -1271,8 +1464,12 @@ if(MNV_BUILD_TESTS)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/runtime/syntax/Makefile")
add_test(
NAME syntax_tests
- COMMAND ${CMAKE_MAKE_PROGRAM} -C ${CMAKE_CURRENT_SOURCE_DIR}/runtime/syntax
- test MNVPROG=$<TARGET_FILE:mnv>
+ COMMAND ${CMAKE_COMMAND} -E env
+ "MNVRUNTIME=${CMAKE_CURRENT_SOURCE_DIR}/runtime"
+ "LINES=24"
+ "COLUMNS=80"
+ ${CMAKE_MAKE_PROGRAM} -C ${CMAKE_CURRENT_SOURCE_DIR}/runtime/syntax
+ test MNVPROG=$<TARGET_FILE:mnv>
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/runtime/syntax
)
set_tests_properties(syntax_tests PROPERTIES
diff --git a/mnv/CMakePresets.json b/mnv/CMakePresets.json
new file mode 100644
index 0000000000..0dbfcd515e
--- /dev/null
+++ b/mnv/CMakePresets.json
@@ -0,0 +1,318 @@
+{
+ "version": 6,
+ "cmakeMinimumRequired": {
+ "major": 3,
+ "minor": 15,
+ "patch": 0
+ },
+ "configurePresets": [
+ {
+ "name": "base",
+ "hidden": true,
+ "binaryDir": "${sourceDir}/build/${presetName}",
+ "cacheVariables": {
+ "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
+ "MNV_BUILD_TESTS": "ON"
+ }
+ },
+ {
+ "name": "dev-base",
+ "hidden": true,
+ "inherits": "base",
+ "cacheVariables": {
+ "MNV_DEBUG": "ON",
+ "MNV_LEAK_CHECK": "ON"
+ }
+ },
+ {
+ "name": "default",
+ "displayName": "Default (huge, no interpreters)",
+ "description": "Default build with huge feature set, no language interpreters",
+ "inherits": "base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "auto"
+ }
+ },
+ {
+ "name": "minimal",
+ "displayName": "Minimal (tiny, no extras)",
+ "description": "Minimal build with tiny feature set",
+ "inherits": "base",
+ "cacheVariables": {
+ "MNV_FEATURE": "tiny",
+ "MNV_GUI": "none",
+ "MNV_TERMINAL": "OFF",
+ "MNV_CHANNEL": "OFF",
+ "MNV_SOUND": "OFF",
+ "MNV_GPM": "OFF",
+ "MNV_SODIUM": "OFF"
+ }
+ },
+ {
+ "name": "normal",
+ "displayName": "Normal feature set",
+ "description": "Normal feature set, no GUI, no interpreters",
+ "inherits": "base",
+ "cacheVariables": {
+ "MNV_FEATURE": "normal",
+ "MNV_GUI": "none"
+ }
+ },
+ {
+ "name": "all-interp",
+ "displayName": "All interpreters (dynamic)",
+ "description": "Huge feature set with all language interpreters loaded dynamically",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "auto",
+ "MNV_LUA": "ON",
+ "MNV_LUA_DYNAMIC": "ON",
+ "MNV_PERL": "ON",
+ "MNV_PERL_DYNAMIC": "ON",
+ "MNV_PYTHON3": "ON",
+ "MNV_PYTHON3_DYNAMIC": "ON",
+ "MNV_RUBY": "ON",
+ "MNV_RUBY_DYNAMIC": "ON",
+ "MNV_TCL": "ON",
+ "MNV_TCL_DYNAMIC": "ON"
+ }
+ },
+ {
+ "name": "all-interp-static",
+ "displayName": "All interpreters (static link)",
+ "description": "Huge feature set with all interpreters linked statically",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "auto",
+ "MNV_LUA": "ON",
+ "MNV_LUA_DYNAMIC": "OFF",
+ "MNV_PERL": "ON",
+ "MNV_PERL_DYNAMIC": "OFF",
+ "MNV_PYTHON3": "ON",
+ "MNV_PYTHON3_DYNAMIC": "OFF",
+ "MNV_RUBY": "ON",
+ "MNV_RUBY_DYNAMIC": "OFF",
+ "MNV_TCL": "ON",
+ "MNV_TCL_DYNAMIC": "OFF"
+ }
+ },
+ {
+ "name": "lua-only",
+ "displayName": "Lua only (dynamic)",
+ "description": "Huge feature set with only Lua interpreter",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "none",
+ "MNV_LUA": "ON",
+ "MNV_LUA_DYNAMIC": "ON"
+ }
+ },
+ {
+ "name": "python3-only",
+ "displayName": "Python3 only (dynamic)",
+ "description": "Huge feature set with only Python3 interpreter",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "none",
+ "MNV_PYTHON3": "ON",
+ "MNV_PYTHON3_DYNAMIC": "ON"
+ }
+ },
+ {
+ "name": "ruby-only",
+ "displayName": "Ruby only (dynamic)",
+ "description": "Huge feature set with only Ruby interpreter",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "none",
+ "MNV_RUBY": "ON",
+ "MNV_RUBY_DYNAMIC": "ON"
+ }
+ },
+ {
+ "name": "perl-only",
+ "displayName": "Perl only (dynamic)",
+ "description": "Huge feature set with only Perl interpreter",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "none",
+ "MNV_PERL": "ON",
+ "MNV_PERL_DYNAMIC": "ON"
+ }
+ },
+ {
+ "name": "tcl-only",
+ "displayName": "Tcl only (dynamic)",
+ "description": "Huge feature set with only Tcl interpreter",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "none",
+ "MNV_TCL": "ON",
+ "MNV_TCL_DYNAMIC": "ON"
+ }
+ },
+ {
+ "name": "nogui",
+ "displayName": "No GUI (huge)",
+ "description": "Huge feature set without any GUI",
+ "inherits": "base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "none"
+ }
+ },
+ {
+ "name": "gtk3",
+ "displayName": "GTK3 GUI",
+ "description": "Huge feature set with GTK3 GUI",
+ "inherits": "base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "gtk3"
+ }
+ },
+ {
+ "name": "sanitize",
+ "displayName": "Sanitizers (ASan + UBSan)",
+ "description": "Debug build with address and undefined behavior sanitizers",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "none",
+ "MNV_SANITIZE": "ON"
+ }
+ },
+ {
+ "name": "profile",
+ "displayName": "Profile build",
+ "description": "Profiling build with gprof instrumentation",
+ "inherits": "base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "none",
+ "MNV_PROFILE": "ON"
+ }
+ },
+ {
+ "name": "full-debug",
+ "displayName": "Full debug (all interpreters + debug + leak check + profile)",
+ "description": "Maximum debug build matching: -DMNV_LUA=ON -DMNV_PERL=ON -DMNV_PYTHON3=ON -DMNV_RUBY=ON -DMNV_TCL=ON -DMNV_DEBUG=ON -DMNV_PROFILE=ON -DMNV_LEAK_CHECK=ON",
+ "inherits": "dev-base",
+ "cacheVariables": {
+ "MNV_FEATURE": "huge",
+ "MNV_GUI": "auto",
+ "MNV_LUA": "ON",
+ "MNV_PERL": "ON",
+ "MNV_PYTHON3": "ON",
+ "MNV_RUBY": "ON",
+ "MNV_TCL": "ON",
+ "MNV_PROFILE": "ON"
+ }
+ }
+ ],
+ "buildPresets": [
+ {
+ "name": "default",
+ "configurePreset": "default"
+ },
+ {
+ "name": "minimal",
+ "configurePreset": "minimal"
+ },
+ {
+ "name": "normal",
+ "configurePreset": "normal"
+ },
+ {
+ "name": "all-interp",
+ "configurePreset": "all-interp"
+ },
+ {
+ "name": "all-interp-static",
+ "configurePreset": "all-interp-static"
+ },
+ {
+ "name": "lua-only",
+ "configurePreset": "lua-only"
+ },
+ {
+ "name": "python3-only",
+ "configurePreset": "python3-only"
+ },
+ {
+ "name": "ruby-only",
+ "configurePreset": "ruby-only"
+ },
+ {
+ "name": "perl-only",
+ "configurePreset": "perl-only"
+ },
+ {
+ "name": "tcl-only",
+ "configurePreset": "tcl-only"
+ },
+ {
+ "name": "nogui",
+ "configurePreset": "nogui"
+ },
+ {
+ "name": "gtk3",
+ "configurePreset": "gtk3"
+ },
+ {
+ "name": "sanitize",
+ "configurePreset": "sanitize"
+ },
+ {
+ "name": "profile",
+ "configurePreset": "profile"
+ },
+ {
+ "name": "full-debug",
+ "configurePreset": "full-debug"
+ }
+ ],
+ "testPresets": [
+ {
+ "name": "default",
+ "configurePreset": "default",
+ "output": {
+ "outputOnFailure": true
+ }
+ },
+ {
+ "name": "unit-only",
+ "configurePreset": "default",
+ "filter": {
+ "exclude": {
+ "name": "script_tests|indent_tests|syntax_tests"
+ }
+ },
+ "output": {
+ "outputOnFailure": true
+ }
+ },
+ {
+ "name": "all-interp",
+ "configurePreset": "all-interp",
+ "output": {
+ "outputOnFailure": true
+ }
+ },
+ {
+ "name": "full-debug",
+ "configurePreset": "full-debug",
+ "output": {
+ "outputOnFailure": true
+ }
+ }
+ ]
+}
diff --git a/mnv/cmake/config.h.cmake b/mnv/cmake/config.h.cmake
index a1107c99b6..2b5e69c2a7 100644
--- a/mnv/cmake/config.h.cmake
+++ b/mnv/cmake/config.h.cmake
@@ -243,21 +243,35 @@
#cmakedefine FEAT_GUI_MOTIF
#cmakedefine FEAT_GUI_X11
#cmakedefine FEAT_WAYLAND
-#cmakedefine FEAT_WAYLAND_CLIPBOARD
#cmakedefine FEAT_IPV6
#cmakedefine WANT_SOCKETSERVER
/* Interpreter support */
#cmakedefine FEAT_LUA
#cmakedefine DYNAMIC_LUA
+#ifdef DYNAMIC_LUA
+# define DYNAMIC_LUA_DLL "@DYNAMIC_LUA_DLL@"
+#endif
#cmakedefine FEAT_PERL
#cmakedefine DYNAMIC_PERL
+#ifdef DYNAMIC_PERL
+# define DYNAMIC_PERL_DLL "@DYNAMIC_PERL_DLL@"
+#endif
#cmakedefine FEAT_PYTHON3
#cmakedefine DYNAMIC_PYTHON3
+#ifdef DYNAMIC_PYTHON3
+# define DYNAMIC_PYTHON3_DLL "@DYNAMIC_PYTHON3_DLL@"
+#endif
#cmakedefine FEAT_RUBY
#cmakedefine DYNAMIC_RUBY
+#ifdef DYNAMIC_RUBY
+# define DYNAMIC_RUBY_DLL "@DYNAMIC_RUBY_DLL@"
+#endif
#cmakedefine FEAT_TCL
#cmakedefine DYNAMIC_TCL
+#ifdef DYNAMIC_TCL
+# define DYNAMIC_TCL_DLL "@DYNAMIC_TCL_DLL@"
+#endif
#cmakedefine FEAT_MZSCHEME
#cmakedefine DYNAMIC_MZSCHEME
diff --git a/mnv/src/if_ruby.c b/mnv/src/if_ruby.c
index 796c074664..b6c950ba58 100644
--- a/mnv/src/if_ruby.c
+++ b/mnv/src/if_ruby.c
@@ -103,6 +103,10 @@
# define rb_unexpected_type rb_unexpected_type_stub
# endif
+# if RUBY_VERSION >= 34
+# define rb_data_object_wrap rb_data_object_wrap_stub
+# endif
+
#endif // ifdef DYNAMIC_RUBY
// On macOS pre-installed Ruby defines "SIZEOF_TIME_T" as "SIZEOF_LONG" so it
@@ -500,6 +504,10 @@ NORETURN(static void (*dll_ruby_malloc_size_overflow)(size_t, size_t));
# endif
# endif
+# if RUBY_VERSION >= 34
+static VALUE (*dll_rb_data_object_wrap)(VALUE, void*, RUBY_DATA_FUNC, RUBY_DATA_FUNC);
+# endif
+
# if RUBY_VERSION >= 26 && RUBY_VERSION <= 32
void rb_ary_detransient_stub(VALUE x);
# endif
@@ -606,6 +614,13 @@ rb_unexpected_type_stub(VALUE self, int t)
dll_rb_unexpected_type(self, t);
}
# endif
+# if RUBY_VERSION >= 34
+ VALUE
+rb_data_object_wrap_stub(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
+{
+ return dll_rb_data_object_wrap(klass, datap, dmark, dfree);
+}
+# endif
# ifdef USE_TYPEDDATA
void *rb_check_typeddata_stub(VALUE obj, const rb_data_type_t *data_type)
{
@@ -658,6 +673,9 @@ static struct
# if RUBY_VERSION >= 31
{"rb_debug_rstring_null_ptr", (RUBY_PROC*)&dll_rb_debug_rstring_null_ptr},
# endif
+# if RUBY_VERSION >= 34
+ {"rb_data_object_wrap", (RUBY_PROC*)&dll_rb_data_object_wrap},
+# endif
{"rb_define_class_under", (RUBY_PROC*)&dll_rb_define_class_under},
{"rb_define_const", (RUBY_PROC*)&dll_rb_define_const},
{"rb_define_global_function", (RUBY_PROC*)&dll_rb_define_global_function},
diff --git a/mnv/src/scriptfile.c b/mnv/src/scriptfile.c
index 37f055eed5..afa36b6ca5 100644
--- a/mnv/src/scriptfile.c
+++ b/mnv/src/scriptfile.c
@@ -1004,7 +1004,7 @@ load_pack_plugin(char_u *fname)
source_all_matches(pat);
{
- char_u *cmd = mnv_strsave((char_u *)"g:did_load_filetypes");
+ char_u *cmd = mnv_strsave((char_u *)"get(g:, 'did_load_filetypes', 0)");
// If runtime/filetype.mnv wasn't loaded yet, the scripts will be
// found when it loads.
diff --git a/mnv/src/testdir/test_regexp_latin.mnv b/mnv/src/testdir/test_regexp_latin.mnv
index e88045db38..62b2ffd256 100644
--- a/mnv/src/testdir/test_regexp_latin.mnv
+++ b/mnv/src/testdir/test_regexp_latin.mnv
@@ -4,8 +4,8 @@ set encoding=latin1
scriptencoding latin1
func s:equivalence_test()
- let str = 'A������ B C D E���� F G H I���� J K L M N� O������ P Q R S T U���� V W X Y� Z '
- \ .. 'a������ b c d e���� f g h i���� j k l m n� o������ p q r s t u���� v w x y�� z '
+ let str = 'AÀÁÂÃÄÅ B CÇ D EÈÉÊË F G H IÌÍÎÏ J K L M NÑ OÒÓÔÕÖØ P Q R S T UÙÚÛÜ V W X YÝ Z '
+ \ .. 'aàáâãäå b cç d eèéêë f g h iìíîï j k l m nñ oòóôõöø p q r s t uùúûü v w x yýÿ z '
\ .. "0 1 2 3 4 5 6 7 8 9 "
\ .. "` ~ ! ? ; : . , / \\ ' \" | < > [ ] { } ( ) @ # $ % ^ & * _ - + \b \e \f \n \r \t"
let groups = split(str)
@@ -404,7 +404,7 @@ func Test_regexp_single_line_pat()
call add(tl, [2, '\v((ab)|c*)+', 'abcccaba', 'abcccab', '', 'ab'])
call add(tl, [2, '\v(a(c*)+b)+', 'acbababaaa', 'acbabab', 'ab', ''])
call add(tl, [2, '\v(a|b*)+', 'aaaa', 'aaaa', ''])
- call add(tl, [2, '\p*', 'a� ', 'a� '])
+ call add(tl, [2, '\p*', 'aà ', 'aà '])
" Test greedy-ness and lazy-ness
call add(tl, [2, 'a\{-2,7}','aaaaaaaaaaaaa', 'aa'])
@@ -993,12 +993,12 @@ endfunc
" Check patterns matching cursor position.
func s:curpos_test2()
new
- call setline(1, ['1', '2 foobar eins zwei drei vier f�nf sechse',
- \ '3 foobar eins zwei drei vier f�nf sechse',
- \ '4 foobar eins zwei drei vier f�nf sechse',
- \ '5 foobar eins zwei drei vier f�nf sechse',
- \ '6 foobar eins zwei drei vier f�nf sechse',
- \ '7 foobar eins zwei drei vier f�nf sechse'])
+ call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse',
+ \ '3 foobar eins zwei drei vier fünf sechse',
+ \ '4 foobar eins zwei drei vier fünf sechse',
+ \ '5 foobar eins zwei drei vier fünf sechse',
+ \ '6 foobar eins zwei drei vier fünf sechse',
+ \ '7 foobar eins zwei drei vier fünf sechse'])
call setpos('.', [0, 2, 10, 0])
s/\%.c.*//g
call setpos('.', [0, 3, 15, 0])
@@ -1008,10 +1008,10 @@ func s:curpos_test2()
call assert_equal(['1',
\ '2 foobar ',
\ '',
- \ '4 foobar eins zwei drei vier f�nf sechse',
+ \ '4 foobar eins zwei drei vier fünf sechse',
\ '5 _',
- \ '6 foobar eins zwei drei vier f�nf sechse',
- \ '7 foobar eins zwei drei vier f�nf sechse'],
+ \ '6 foobar eins zwei drei vier fünf sechse',
+ \ '7 foobar eins zwei drei vier fünf sechse'],
\ getline(1, '$'))
call assert_fails('call search("\\%.1l")', 'E1204:')
call assert_fails('call search("\\%.1c")', 'E1204:')
@@ -1022,12 +1022,12 @@ endfunc
" Check patterns matching before or after cursor position.
func s:curpos_test3()
new
- call setline(1, ['1', '2 foobar eins zwei drei vier f�nf sechse',
- \ '3 foobar eins zwei drei vier f�nf sechse',
- \ '4 foobar eins zwei drei vier f�nf sechse',
- \ '5 foobar eins zwei drei vier f�nf sechse',
- \ '6 foobar eins zwei drei vier f�nf sechse',
- \ '7 foobar eins zwei drei vier f�nf sechse'])
+ call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse',
+ \ '3 foobar eins zwei drei vier fünf sechse',
+ \ '4 foobar eins zwei drei vier fünf sechse',
+ \ '5 foobar eins zwei drei vier fünf sechse',
+ \ '6 foobar eins zwei drei vier fünf sechse',
+ \ '7 foobar eins zwei drei vier fünf sechse'])
call setpos('.', [0, 2, 10, 0])
" Note: This removes all columns, except for the column directly in front of
" the cursor. Bug????
@@ -1041,27 +1041,27 @@ func s:curpos_test3()
call setpos('.', [0, 6, 4, 0])
:s/\%>.v.*$/_/
call assert_equal(['1',
- \ ' eins zwei drei vier f�nf sechse',
+ \ ' eins zwei drei vier fünf sechse',
\ '3 foobar e',
- \ '4 foobar eins zwei drei vier f�nf sechse',
- \ '_foobar eins zwei drei vier f�nf sechse',
+ \ '4 foobar eins zwei drei vier fünf sechse',
+ \ '_foobar eins zwei drei vier fünf sechse',
\ '6 fo_',
- \ '7 foobar eins zwei drei vier f�nf sechse'],
+ \ '7 foobar eins zwei drei vier fünf sechse'],
\ getline(1, '$'))
sil %d
- call setline(1, ['1', '2 foobar eins zwei drei vier f�nf sechse',
- \ '3 foobar eins zwei drei vier f�nf sechse',
- \ '4 foobar eins zwei drei vier f�nf sechse',
- \ '5 foobar eins zwei drei vier f�nf sechse',
- \ '6 foobar eins zwei drei vier f�nf sechse',
- \ '7 foobar eins zwei drei vier f�nf sechse'])
+ call setline(1, ['1', '2 foobar eins zwei drei vier fünf sechse',
+ \ '3 foobar eins zwei drei vier fünf sechse',
+ \ '4 foobar eins zwei drei vier fünf sechse',
+ \ '5 foobar eins zwei drei vier fünf sechse',
+ \ '6 foobar eins zwei drei vier fünf sechse',
+ \ '7 foobar eins zwei drei vier fünf sechse'])
call setpos('.', [0, 4, 4, 0])
%s/\%<.l.*//
call setpos('.', [0, 5, 4, 0])
%s/\%>.l.*//
call assert_equal(['', '', '',
- \ '4 foobar eins zwei drei vier f�nf sechse',
- \ '5 foobar eins zwei drei vier f�nf sechse',
+ \ '4 foobar eins zwei drei vier fünf sechse',
+ \ '5 foobar eins zwei drei vier fünf sechse',
\ '', ''],
\ getline(1, '$'))
bwipe!
diff --git a/mnv/src/testdir/util/screendump.mnv b/mnv/src/testdir/util/screendump.mnv
index 2f28c759a8..91346911a1 100644
--- a/mnv/src/testdir/util/screendump.mnv
+++ b/mnv/src/testdir/util/screendump.mnv
@@ -165,7 +165,11 @@ func VerifyScreenDump(buf, filename, options, ...)
" Leave a bit of time for updating the original window while we spin wait.
sleep 10m
call delete(testfile)
- call term_dumpwrite(a:buf, testfile, options_copy)
+ try
+ call term_dumpwrite(a:buf, testfile, options_copy)
+ catch /E958/
+ return 1
+ endtry
call assert_report('See new dump file: call term_dumpload("testdir/' .. testfile .. '")')
" No point in retrying.
let g:run_nr = 10
@@ -179,7 +183,15 @@ func VerifyScreenDump(buf, filename, options, ...)
" Leave a bit of time for updating the original window while we spin wait.
sleep 1m
call delete(testfile)
- call term_dumpwrite(a:buf, testfile, options_copy)
+ try
+ call term_dumpwrite(a:buf, testfile, options_copy)
+ catch /E958/
+ " The terminal job already finished; no point retrying.
+ return 1
+ endtry
+ if !filereadable(testfile)
+ return 1
+ endif
" Filtering done with "FileComparisonPreAction()" may change "refdump*".
let refdump = CopyStringList(refdump_orig)
let testdump = ReadAndFilter(testfile, filter)