From 10335b93b4e7190520f19c7c5fb8d816eb86ede2 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Sat, 14 Apr 2018 10:35:59 +0200 Subject: [PATCH] Support new hunspell C++ ABI if LyX is built against hunspell >= 1.5 Fixes: #10547 --- 3rdparty/hunspell/Makefile.am | 2 +- INSTALL | 3 +++ config/lyxinclude.m4 | 1 + config/spell.m4 | 25 ++++++++++++++++++++ development/cmake/ConfigureChecks.cmake | 30 ++++++++++++++++++++++++ development/cmake/configCompiler.h.cmake | 3 +++ src/HunspellChecker.cpp | 16 +++++++++++++ status.23x | 3 +++ 8 files changed, 82 insertions(+), 1 deletion(-) diff --git a/3rdparty/hunspell/Makefile.am b/3rdparty/hunspell/Makefile.am index 7e0429d014..fe0502dd21 100644 --- a/3rdparty/hunspell/Makefile.am +++ b/3rdparty/hunspell/Makefile.am @@ -16,7 +16,7 @@ EXTRA_DIST = \ 1.6.2/src/hunspell/hunvisapi.h.in \ 1.6.2/src/hunspell/utf_info.cxx -AM_CPPFLAGS += -DHUNSPELL_STATIC +AM_CPPFLAGS += -DHUNSPELL_STATIC @STDLIB_DEBUG@ liblyxhunspell_a_SOURCES = \ 1.6.2/src/hunspell/affentry.cxx \ diff --git a/INSTALL b/INSTALL index 8d3b609c76..9e91367337 100644 --- a/INSTALL +++ b/INSTALL @@ -227,6 +227,9 @@ The following options allow you to tweak the generated code more precisely (see --without-included-boost is specified). You may have to use --disable-stdlib-debug when linking development versions against your system's boost library. + The same problem applies to hunspell (as of hunspell 1.5). So either + compile --with-included-hunspell or --disable-stdlib-debug when + linking development versions against your system's hunspell library. o --enable-monolithic-build[=boost,client,insets,mathed,core,tex2lyx,frontend-qt4] that enables monolithic build of the given parts of the source diff --git a/config/lyxinclude.m4 b/config/lyxinclude.m4 index ead704b166..2c1a9af12a 100644 --- a/config/lyxinclude.m4 +++ b/config/lyxinclude.m4 @@ -420,6 +420,7 @@ if test x$GXX = xyes; then lyx_flags="$lyx_flags stdlib-debug" AC_DEFINE(_GLIBCXX_DEBUG, 1, [libstdc++ debug mode]) AC_DEFINE(_GLIBCXX_DEBUG_PEDANTIC, 1, [libstdc++ pedantic debug mode]) + AC_SUBST(STDLIB_DEBUG, "-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC") ;; esac fi diff --git a/config/spell.m4 b/config/spell.m4 index a15f9f6b3d..152e485ad7 100644 --- a/config/spell.m4 +++ b/config/spell.m4 @@ -43,6 +43,24 @@ AC_DEFUN([CHECK_WITH_ENCHANT], fi ]) +AC_DEFUN([LYX_HAVE_HUNSPELL_CXXABI], +[ + AC_MSG_CHECKING([whether hunspell C++ (rather than C) ABI is provided]) + save_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$ENCHANT_CFLAGS $AM_CXXFLAGS $CXXFLAGS" + +# in the C++ ABI, stem() returns a vector, in the C ABI, it returns an int + AC_TRY_COMPILE([#include ], + [Hunspell sp("foo", "bar"); + int i = sp.stem("test").size();], + [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_HUNSPELL_CXXABI, 1, [Define to 1 if hunspell C++ (rather than C) ABI is detected]) + have_hunspell_cxx_abi=yes + ], + [AC_MSG_RESULT(no)]) + CXXFLAGS=$save_CXXFLAGS +]) + # Macro to add for using hunspell spellchecker libraries! -*- sh -*- AC_DEFUN([CHECK_WITH_HUNSPELL], [ @@ -66,6 +84,12 @@ AC_DEFUN([CHECK_WITH_HUNSPELL], AC_MSG_RESULT(no) fi fi + LYX_HAVE_HUNSPELL_CXXABI + if test $enable_stdlib_debug = "yes" -a -n "$have_hunspell_cxx_abi" ; then + LYX_WARNING([Compiling LyX with stdlib-debug and system hunspell libraries may lead to + crashes. Consider using --disable-stdlib-debug or --with-included-hunspell.]) + fi + ]) dnl Usage: LYX_USE_INCLUDED_HUNSPELL : select if the included hunspell should @@ -96,6 +120,7 @@ AC_DEFUN([LYX_CHECK_SPELL_ENGINES], dnl the user wanted to use the included hunspell, so do not check for external hunspell lyx_use_hunspell=true AC_DEFINE(USE_HUNSPELL, 1, [Define as 1 to use the hunspell library]) + AC_DEFINE(HAVE_HUNSPELL_CXXABI, 1, [Define to 1 if hunspell C++ (rather than C) ABI is detected]) lyx_flags="$lyx_flags use-hunspell" else CHECK_WITH_HUNSPELL diff --git a/development/cmake/ConfigureChecks.cmake b/development/cmake/ConfigureChecks.cmake index f09ba8bd92..3d6d5880fb 100644 --- a/development/cmake/ConfigureChecks.cmake +++ b/development/cmake/ConfigureChecks.cmake @@ -72,6 +72,36 @@ check_type_size("long long" HAVE_LONG_LONG) check_type_size(wchar_t HAVE_WCHAR_T) check_type_size(wint_t HAVE_WINT_T) +if(HUNSPELL_FOUND) + # check whether hunspell C++ (rather than C) ABI is provided + set(HunspellTestFile "${CMAKE_BINARY_DIR}/hunspelltest.cpp") + file(WRITE "${HunspellTestFile}" + " + #include + + int main() + { + Hunspell sp(\"foo\", \"bar\"); + int i = sp.stem(\"test\").size(); + return(0); + } + " + ) + + try_compile(HAVE_HUNSPELL_CXXABI + "${CMAKE_BINARY_DIR}" + "${HunspellTestFile}" + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES:STRING=${HUNSPELL_INCLUDE_DIR}" + "-DCMAKE_CXX_LINK_EXECUTABLE='${CMAKE_COMMAD} echo not linking now...'" + OUTPUT_VARIABLE LOG2) + + message(STATUS "HAVE_HUNSPELL_CXXABI = ${HAVE_HUNSPELL_CXXABI}") + #message(STATUS "LOG2 = ${LOG2}") + if(LYX_EXTERNAL_HUNSPELL AND LYX_STDLIB_DEBUG AND HAVE_HUNSPELL_CXXABI) + message(WARNING "Compiling LyX with stdlib-debug and system hunspell libraries may lead to crashes. Consider using -DLYX_STDLIB_DEBUG=OFF or -DLYX_EXTERNAL_HUNSPELL=OFF.") + endif() +endif() #check_cxx_source_compiles( # " diff --git a/development/cmake/configCompiler.h.cmake b/development/cmake/configCompiler.h.cmake index 52f629e7bb..8934986cb0 100644 --- a/development/cmake/configCompiler.h.cmake +++ b/development/cmake/configCompiler.h.cmake @@ -66,6 +66,9 @@ #define HAVE_ALLOCA #endif +/* whether hunspell C++ (rather than C) ABI is provided */ +#cmakedefine HAVE_HUNSPELL_CXXABI 1 + #cmakedefine HAVE_ICONV_CONST 1 #ifdef HAVE_ICONV_CONST #define ICONV_CONST const diff --git a/src/HunspellChecker.cpp b/src/HunspellChecker.cpp index 6dc6647b5c..1c2612e78e 100644 --- a/src/HunspellChecker.cpp +++ b/src/HunspellChecker.cpp @@ -356,7 +356,11 @@ SpellChecker::Result HunspellChecker::check(WordLangTuple const & wl) LYXERR(Debug::GUI, "spellCheck: \"" << wl.word() << "\", lang = " << wl.lang()->lang()) ; +#ifdef HAVE_HUNSPELL_CXXABI + if (h->spell(word_to_check, &info)) +#else if (h->spell(word_to_check.c_str(), &info)) +#endif return d->learned(wl) ? LEARNED_WORD : WORD_OK; if (info & SPELL_COMPOUND) { @@ -411,6 +415,11 @@ void HunspellChecker::suggest(WordLangTuple const & wl, return; string const encoding = h->get_dic_encoding(); string const word_to_check = to_iconv_encoding(wl.word(), encoding); +#ifdef HAVE_HUNSPELL_CXXABI + vector wlst = h->suggest(word_to_check); + for (auto const s : wlst) + suggestions.push_back(from_iconv_encoding(s, encoding)); +#else char ** suggestion_list; int const suggestion_number = h->suggest(&suggestion_list, word_to_check.c_str()); if (suggestion_number <= 0) @@ -418,6 +427,7 @@ void HunspellChecker::suggest(WordLangTuple const & wl, for (int i = 0; i != suggestion_number; ++i) suggestions.push_back(from_iconv_encoding(suggestion_list[i], encoding)); h->free_list(&suggestion_list, suggestion_number); +#endif } @@ -430,6 +440,11 @@ void HunspellChecker::stem(WordLangTuple const & wl, return; string const encoding = h->get_dic_encoding(); string const word_to_check = to_iconv_encoding(wl.word(), encoding); +#ifdef HAVE_HUNSPELL_CXXABI + vector wlst = h->stem(word_to_check); + for (auto const s : wlst) + suggestions.push_back(from_iconv_encoding(s, encoding)); +#else char ** suggestion_list; int const suggestion_number = h->stem(&suggestion_list, word_to_check.c_str()); if (suggestion_number <= 0) @@ -437,6 +452,7 @@ void HunspellChecker::stem(WordLangTuple const & wl, for (int i = 0; i != suggestion_number; ++i) suggestions.push_back(from_iconv_encoding(suggestion_list[i], encoding)); h->free_list(&suggestion_list, suggestion_number); +#endif } diff --git a/status.23x b/status.23x index d85e56d0fb..265657be5b 100644 --- a/status.23x +++ b/status.23x @@ -89,6 +89,9 @@ What's new * BUILD/INSTALLATION +- Support new hunspell C++ ABI if LyX is built against hunspell >= 1.5 + (bug 10547). + ** Bug fixes: -- 2.39.2