From ded6e1aeb34299832f29c5e13d3b474bb7466fdd Mon Sep 17 00:00:00 2001 From: Dom Lachowicz Date: Thu, 28 Feb 2008 19:42:07 +0000 Subject: bug 11412 - use D-BUS zemberek backend; from Serkan Kaba git-svn-id: svn+ssh://svn.abisource.com/svnroot/enchant/trunk@22972 bcba8976-2d24-0410-9c9c-aab3bd5fdfd6 --- configure.in | 45 ++---- data/enchant.ordering | 1 + src/zemberek/Makefile.am | 9 +- src/zemberek/zemberek.cpp | 84 ++++++++++ src/zemberek/zemberek.h | 41 +++++ src/zemberek/zemberek_provider.cpp | 306 ++++--------------------------------- 6 files changed, 174 insertions(+), 312 deletions(-) create mode 100644 src/zemberek/zemberek.cpp create mode 100644 src/zemberek/zemberek.h diff --git a/configure.in b/configure.in index 0c12185..6510a1d 100644 --- a/configure.in +++ b/configure.in @@ -333,47 +333,28 @@ fi AM_CONDITIONAL(WITH_HSPELL, test "$build_hspell" = yes) -build_zemberek=no - -# -# disable building zemberek unless explicitly requested. -# since it requires a running server, i'd prefer that this be an -# "opt-in" backend, rather than an opt-out. this attitude may change. -# -AC_ARG_ENABLE(zemberek, [ --disable-zemberek enable the zemberek backend (https://zemberek.dev.java.net/) [default=no]], build_zemberek="$enableval", build_zemberek=no) -AC_ARG_WITH(zemberek-server, [ --with-zemberek-server=HOST - specify a zemberek server other than the default.], zemberek_server="$withval", ) -AC_ARG_WITH(zemberek-server-port, [ --with-zemberek-server-port=PORT - specify a zemberek server port other than the default.], zemberek_port="$withval", ) +build_zemberek=yes + +AC_ARG_ENABLE(zemberek, [ --disable-zemberek enable the zemberek backend [default=auto]], build_zemberek="$enableval", build_zemberek=yes) if test "x$have_cxx" = "xno"; then build_zemberek=no fi - -if test "x$build_zemberek" != "xno"; then - AC_MSG_NOTICE(checking required headers for zemberek backend) - AC_CHECK_HEADERS([sys/socket.h netinet/in.h netdb.h], [], [build_zemberek=no; break]) - if test "x$build_zemberek" = "xno"; then - AC_MSG_WARN([Some headers are missing for zemberek backend]) - fi +AC_MSG_CHECKING([For DBus-Glib >= 0.62]) +if pkg-config --atleast-version=0.62 dbus-glib-1; then + ZEMBEREK_CFLAGS=`pkg-config --cflags dbus-glib-1` + ZEMBEREK_LIBS=`pkg-config --libs dbus-glib-1` +else + build_zemberek=no fi -if test "x$build_zemberek" != "xno"; then - ZEMBEREK_SERVER= - if test "x$zemberek_server" != "x"; then - ZEMBEREK_SERVER="-DZEMBEREK_HOST='\"$zemberek_server\"'" - fi - - ZEMBEREK_PORT= - if test "x$zemberek_port" != "x"; then - ZEMBEREK_PORT="-DZEMBEREK_PORT=$zemberek_port" - fi +AC_SUBST(ZEMBEREK_CFLAGS) +AC_SUBST(ZEMBEREK_LIBS) - ZEMBEREK_CFLAGS="$ZEMBEREK_SERVER $ZEMBEREK_PORT "$ZEMBEREK_CFLAGS - AC_SUBST(ZEMBEREK_CFLAGS) -fi AM_CONDITIONAL(WITH_ZEMBEREK, test "x$build_zemberek" = "xyes") +zemberek_dir=${datadir}/enchant/zemberek + dnl ======================================================================================= AC_OUTPUT([ diff --git a/data/enchant.ordering b/data/enchant.ordering index 444c3d6..8e380fb 100644 --- a/data/enchant.ordering +++ b/data/enchant.ordering @@ -5,3 +5,4 @@ he:hspell,myspell he_IL:hspell,myspell yi:uspell tr:zemberek +tr_TR:zemberek diff --git a/src/zemberek/Makefile.am b/src/zemberek/Makefile.am index 321cad7..956bc5d 100644 --- a/src/zemberek/Makefile.am +++ b/src/zemberek/Makefile.am @@ -4,15 +4,18 @@ else target_lib = endif -INCLUDES=-I$(top_srcdir)/src $(ENCHANT_CFLAGS) -D_ENCHANT_BUILD=1 @ZEMBEREK_CFLAGS@ +INCLUDES=-I$(top_srcdir)/src $(ENCHANT_CFLAGS) $(ZEMBEREK_CFLAGS) -D_ENCHANT_BUILD=1 zemberek_LTLIBRARIES = $(target_lib) zemberekdir= $(libdir)/enchant libenchant_zemberek_lalibdir=$(libdir)/enchant -libenchant_zemberek_la_LIBADD= $(top_builddir)/src/libenchant.la $(SOCKET_LIBS) +libenchant_zemberek_la_LIBADD= $(ZEMBEREK_LIBS) $(top_builddir)/src/libenchant.la libenchant_zemberek_la_LDFLAGS = -avoid-version -no-undefined -libenchant_zemberek_la_SOURCES = zemberek_provider.cpp +libenchant_zemberek_la_SOURCES =\ + zemberek.cpp \ + zemberek.h \ + zemberek_provider.cpp diff --git a/src/zemberek/zemberek.cpp b/src/zemberek/zemberek.cpp new file mode 100644 index 0000000..d679de7 --- /dev/null +++ b/src/zemberek/zemberek.cpp @@ -0,0 +1,84 @@ +/* Copyright (C) 2006 Barış Metin + * Copyright (C) 2007 Serkan Kaba + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "zemberek.h" + +Zemberek::Zemberek() +{ + + GError *Error; + g_type_init (); + + Error = NULL; + connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, + &Error); + if (connection == NULL) { + //g_stpcpy(error,Error->message); + g_error_free (Error); + } + proxy = dbus_g_proxy_new_for_name (connection, + "net.zemberekserver.server.dbus", + "/net/zemberekserver/server/dbus/ZemberekDbus", + "net.zemberekserver.server.dbus.ZemberekDbusInterface"); +} + + +Zemberek::~Zemberek() +{ + if(proxy) + g_object_unref (proxy); +} + + +int Zemberek::checkWord(const char* word ) const +{ + gboolean result; + GError *Error; + Error=NULL; + if (!dbus_g_proxy_call (proxy, "kelimeDenetle", &Error, + G_TYPE_STRING,word,G_TYPE_INVALID, + G_TYPE_BOOLEAN, &result, G_TYPE_INVALID)) { + //g_stpcpy(error,Error->message); + g_error_free (Error); + return -1; + } + else { + if (result) + return 0; + else + return 1; + } +} + + +char** Zemberek::suggestWord(const char* word, size_t *out_n_suggs) +{ + char** suggs; + GError *Error; + Error=NULL; + if (!dbus_g_proxy_call (proxy, "oner", &Error, + G_TYPE_STRING,word,G_TYPE_INVALID, + G_TYPE_STRV, &suggs,G_TYPE_INVALID)) { + //g_stpcpy(error,Error->message); + g_error_free (Error); + return NULL; + } + *out_n_suggs = g_strv_length(suggs); + return suggs; +} diff --git a/src/zemberek/zemberek.h b/src/zemberek/zemberek.h new file mode 100644 index 0000000..51b71bb --- /dev/null +++ b/src/zemberek/zemberek.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2006 Barış Metin + * Copyright (C) 2007 Serkan Kaba + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef ZEMBEREK_H +#define ZEMBEREK_H + +#include +#include + +using namespace std; + +class Zemberek +{ +public: + Zemberek(); + ~Zemberek(); + + int checkWord(const char* word) const; + char** suggestWord(const char* word, size_t *out_n_suggs); + //char *error; +private: + DBusGConnection *connection; + DBusGProxy *proxy; +}; +#endif diff --git a/src/zemberek/zemberek_provider.cpp b/src/zemberek/zemberek_provider.cpp index ba277e2..ac27f92 100644 --- a/src/zemberek/zemberek_provider.cpp +++ b/src/zemberek/zemberek_provider.cpp @@ -1,4 +1,5 @@ -/** Copyright (C) 2006 Barış Metin +/* Copyright (C) 2006 Barış Metin + * Copyright (C) 2007 Serkan Kaba * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,265 +17,52 @@ * 02111-1307, USA. */ -/* Get Zemberek and Zemberek-server from - https://zemberek.dev.java.net */ - -#include -#include -#include -#include -#include #include #include "enchant.h" #include "enchant-provider.h" -#ifdef _WIN32 -#include -#define SHUT_RDWR SD_BOTH //no more receptions of transmissions -#define close closesocket -#else -#include -#include -#include -typedef int SOCKET -#ifndef INVALID_SOCKET -#define INVALID_SOCKET -1 -#endif -#ifndef SOCKET_ERROR -#define SOCKET_ERROR -1 -#endif -#endif - -#ifndef ZEMBEREK_HOST -#define ZEMBEREK_HOST "localhost" -#endif -#ifndef ZEMBEREK_PORT -#define ZEMBEREK_PORT 10444 -#endif +#include "zemberek.h" ENCHANT_PLUGIN_DECLARE("Zemberek") -using namespace std; - -/******************************/ -/* Zemberek class decleration */ -/*****************************/ - -class Zemberek -{ -public: - Zemberek(); - ~Zemberek(); - - bool checkWord(const string& str, size_t len) const; - vector suggestWord(const string& str, size_t len); - - // chek if connection is O.K. - bool connOK(void) { return !_connError; } - -private: - SOCKET _conn; - bool _connError; - string recvResult() const; -}; - -/*****************************/ -/* Zemberek class definition */ -/*****************************/ - -Zemberek::Zemberek() - : _connError(false) -{ - struct hostent *he; - struct sockaddr_in saddr; - - if ( ( he = (struct hostent *)gethostbyname(ZEMBEREK_HOST) ) == NULL ) { - perror( "gethostbyname()" ); - _connError = true; - return; - } - - if ( ( _conn = socket(AF_INET, SOCK_STREAM, 0) ) == INVALID_SOCKET ) { - perror( "socket()" ); - _connError = true; - return; - } - - saddr.sin_family = AF_INET; - saddr.sin_port = htons( ZEMBEREK_PORT ); - saddr.sin_addr = *( (struct in_addr *)he->h_addr ); - memset( &(saddr.sin_zero), '\0', 8 ); - - if ( connect(_conn, (struct sockaddr *)&saddr, sizeof(struct sockaddr)) == -1) { - perror("connect()"); - _connError = true; - return; - } -} - -Zemberek::~Zemberek() -{ - if ( _conn ) { - shutdown( _conn, SHUT_RDWR ); - close( _conn ); - } -} - -bool Zemberek::checkWord( const string& str, size_t len ) const -{ - if (_connError) - return false; - - stringstream strstream; - strstream << str.length()+2 << " * " << str; - string checkStr = strstream.str(); - if ( send(_conn, checkStr.c_str(), checkStr.length(), 0) == -1) { - perror("send()"); - return false; - } - - switch ( recvResult()[0] ) { - case '*': - return true; - break; - case '#': - return false; - break; - default: - return false; - break; - } -} - -vector Zemberek::suggestWord(const string& str, size_t size) -{ - vector suggestions; - - if (_connError) - return suggestions; - - stringstream strstream; - strstream << str.length()+2 << " & " << str; - string checkStr = strstream.str(); - if ( send( _conn, checkStr.c_str(), checkStr.length(), 0 ) == -1 ) { - perror( "send()" ); - return suggestions; - } - - string result = recvResult(); - if ( result[0] != '&' ) { - return suggestions; - } - - string::iterator it = result.begin(); - string::iterator end = result.end(); - bool start = false; - string tmp; - for ( ; it != end; ++it ) { - if ( *it == '(' ) { - start = true; - continue; - - } - - if ( !start ) continue; - - - if ( *it == ',' ) { - suggestions.push_back( tmp ); - tmp.erase(); - continue; - } else if ( *it == ')' ) { - suggestions.push_back( tmp ); - break; - } - - tmp += *it; - } - - return suggestions; -} - -string Zemberek::recvResult() const -{ - int numbytes = 0; - string buf(""); - - int size = 0; - while (true) { - char s; - numbytes = recv (_conn, &s, 1, 0); - - // how many chars do we have to read? - if (s == ' ') { - char *endptr; - size = strtol (buf.c_str() , &endptr, 0); - buf.erase(); - break; - } - - buf += s; - } - char *ret = new char[size+1]; - numbytes = recv (_conn, ret, size, 0); - ret[numbytes]='\0'; - - string result = ret; - delete ret; - - return result; -} - -/******************************/ -/* Enchant provider functions */ -/******************************/ static int -zemberek_dict_check (EnchantDict * dict, const char *const word, size_t len) +zemberek_dict_check (EnchantDict * me, const char *const word, size_t len) { Zemberek *checker; - - checker = (Zemberek *) dict->user_data; - - if (checker->checkWord(word, len)) - return 0; - return 1; + checker = (Zemberek *) me->user_data; + int result = checker->checkWord(word); + /* + if(result == -1) { + enchant_dict_set_error(me,checker->error); + g_free(checker->error); + } + */ + return result; } static char** -zemberek_dict_suggest (EnchantDict * dict, const char *const word, +zemberek_dict_suggest (EnchantDict * me, const char *const word, size_t len, size_t * out_n_suggs) { Zemberek *checker; - - checker = (Zemberek *) dict->user_data; - vector suggestions = checker->suggestWord (word, len); - *out_n_suggs = suggestions.size(); - - vector::const_iterator it = suggestions.begin(); - int suglen = suggestions.size(); - - if (suglen > 0) - { - char **sug; - sug = g_new0(char *, suglen+1); - - for (int i=0 ; i < suglen ; ++i, ++it ) - sug[i] = g_strdup(it->c_str()); - - return sug; + checker = (Zemberek *) me->user_data; + char **result = checker->suggestWord (word, out_n_suggs); + /* + if(!result) { + enchant_dict_set_error(me,checker->error); + g_free(checker->error); } - return 0; + */ + return result; } + static void zemberek_provider_dispose(EnchantProvider *me) { g_free(me); -#ifdef _WIN32 - WSACleanup(); -#endif } static EnchantDict* @@ -282,8 +70,8 @@ zemberek_provider_request_dict(EnchantProvider *me, const char *tag) { Zemberek* checker = new Zemberek(); - if (!checker || !checker->connOK()) - return NULL; + if (!checker) + return NULL; EnchantDict* dict = g_new0(EnchantDict, 1); dict->user_data = (void *) checker; @@ -302,6 +90,7 @@ zemberek_provider_dispose_dict (EnchantProvider * me, EnchantDict * dict) g_free (dict); } + static char * zemberek_provider_identify (EnchantProvider * me) { @@ -320,45 +109,18 @@ zemberek_provider_free_string_list (EnchantProvider * me, char **str_list) g_strfreev (str_list); } -static gboolean -zemberek_provider_server_is_running (void) -{ - Zemberek checker; - - return checker.connOK(); -} - static char ** zemberek_provider_list_dicts (EnchantProvider * me, size_t * out_n_dicts) { char ** out_list = NULL; - - if (zemberek_provider_server_is_running ()) { - *out_n_dicts = 1; - out_list = g_new0 (char *, 2); - out_list[0] = g_strdup ("tr"); - } - else - *out_n_dicts = 0; + *out_n_dicts = 1; + out_list = g_new0 (char *, 2); + out_list[0] = g_strdup ("tr"); return out_list; } -static int -zemberek_provider_dictionary_exists (EnchantProvider * me, - const char *const tag) -{ - EnchantDict * dict; - Zemberek * checker; - - if (!strcmp ("tr", tag)) { - return zemberek_provider_server_is_running (); - } - else { - return 0; - } -} extern "C" { @@ -366,15 +128,6 @@ ENCHANT_MODULE_EXPORT(EnchantProvider *) init_enchant_provider(void) { EnchantProvider *provider; - -#ifdef _WIN32 - WSADATA wsaData; - int iResult = WSAStartup(WINSOCK_VERSION, &wsaData); - if(iResult != NO_ERROR){ - perror( "WSAStartup()" ); - return NULL; - } -#endif provider = g_new0(EnchantProvider, 1); provider->dispose = zemberek_provider_dispose; @@ -383,7 +136,6 @@ init_enchant_provider(void) provider->identify = zemberek_provider_identify; provider->describe = zemberek_provider_describe; provider->list_dicts = zemberek_provider_list_dicts; - provider->dictionary_exists = zemberek_provider_dictionary_exists; provider->free_string_list = zemberek_provider_free_string_list; return provider; -- cgit v1.2.1