Back to index

php5  5.3.10
enchant.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.0 of the PHP license,       |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available at through the world-wide-web at                           |
00010   | http://www.php.net/license/3_0.txt.                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Author: Pierre-Alain Joye <paj@pearfr.org>                           |
00016   |         Ilia Alshanetsky <ilia@prohost.org>                          |
00017   +----------------------------------------------------------------------+
00018 
00019   $Id: enchant.c 321634 2012-01-01 13:15:04Z felipe $
00020 */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025 
00026 #include <enchant.h>
00027 #include "php.h"
00028 #include "php_ini.h"
00029 #include "ext/standard/info.h"
00030 #include "php_enchant.h"
00031 
00032 typedef EnchantBroker * EnchantBrokerPtr;
00033 typedef struct _broker_struct enchant_broker;
00034 typedef struct _dict_struct enchant_dict;
00035 
00036 typedef enchant_broker * enchant_brokerPtr;
00037 typedef enchant_dict * enchant_dictPtr;
00038 
00039 typedef struct _broker_struct {
00040        EnchantBroker *pbroker;
00041        enchant_dict  **dict;
00042        unsigned int  dictcnt;
00043        long                 rsrc_id;
00044 } _enchant_broker;
00045 
00046 typedef struct _dict_struct {
00047        unsigned int  id;
00048        EnchantDict          *pdict;
00049        enchant_broker       *pbroker;
00050        long                 rsrc_id;
00051        enchant_dict  *next;
00052        enchant_dict  *prev;
00053 } _enchant_dict;
00054 
00055 
00056 /* True global resources - no need for thread safety here */
00057 static int le_enchant_broker;
00058 static int le_enchant_dict;
00059 
00060 /* If you declare any globals in php_enchant.h uncomment this:*/
00061 /*ZEND_DECLARE_MODULE_GLOBALS(enchant)*/
00062 
00063 #define PHP_ENCHANT_MYSPELL 1
00064 #define PHP_ENCHANT_ISPELL 2
00065 
00066 /* {{{ arginfo */
00067 ZEND_BEGIN_ARG_INFO(arginfo_enchant_broker_init, 0)
00068 ZEND_END_ARG_INFO()
00069 
00070 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_free, 0, 0, 1)
00071        ZEND_ARG_INFO(0, broker)
00072 ZEND_END_ARG_INFO()
00073 
00074 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_set_dict_path, 0, 0, 3)
00075        ZEND_ARG_INFO(0, broker)
00076        ZEND_ARG_INFO(0, name)
00077        ZEND_ARG_INFO(0, value)
00078 ZEND_END_ARG_INFO()
00079 
00080 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_get_dict_path, 0, 0, 2)
00081        ZEND_ARG_INFO(0, broker)
00082        ZEND_ARG_INFO(0, name)
00083 ZEND_END_ARG_INFO()
00084 
00085 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_request_dict, 0, 0, 2)
00086        ZEND_ARG_INFO(0, broker)
00087        ZEND_ARG_INFO(0, tag)
00088 ZEND_END_ARG_INFO()
00089 
00090 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_request_pwl_dict, 0, 0, 2)
00091        ZEND_ARG_INFO(0, broker)
00092        ZEND_ARG_INFO(0, filename)
00093 ZEND_END_ARG_INFO()
00094 
00095 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_free_dict, 0, 0, 1)
00096        ZEND_ARG_INFO(0, dict)
00097 ZEND_END_ARG_INFO()
00098 
00099 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_set_ordering, 0, 0, 3)
00100        ZEND_ARG_INFO(0, broker)
00101        ZEND_ARG_INFO(0, tag)
00102        ZEND_ARG_INFO(0, ordering)
00103 ZEND_END_ARG_INFO()
00104 
00105 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_dict_quick_check, 0, 0, 2)
00106        ZEND_ARG_INFO(0, dict)
00107        ZEND_ARG_INFO(0, word)
00108        ZEND_ARG_INFO(1, suggestions)
00109 ZEND_END_ARG_INFO()
00110 
00111 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_dict_check, 0, 0, 2)
00112        ZEND_ARG_INFO(0, dict)
00113        ZEND_ARG_INFO(0, word)
00114 ZEND_END_ARG_INFO()
00115 
00116 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_dict_store_replacement, 0, 0, 3)
00117        ZEND_ARG_INFO(0, dict)
00118        ZEND_ARG_INFO(0, mis)
00119        ZEND_ARG_INFO(0, cor)
00120 ZEND_END_ARG_INFO()
00121 /* }}} */
00122 
00123 /* {{{ enchant_functions[]
00124  *
00125  * Every user visible function must have an entry in enchant_functions[].
00126  */
00127 function_entry enchant_functions[] = {
00128        PHP_FE(enchant_broker_init,                      arginfo_enchant_broker_init)
00129        PHP_FE(enchant_broker_free,                      arginfo_enchant_broker_free)
00130        PHP_FE(enchant_broker_get_error,          arginfo_enchant_broker_free)
00131        PHP_FE(enchant_broker_set_dict_path,      arginfo_enchant_broker_set_dict_path)
00132        PHP_FE(enchant_broker_get_dict_path,      arginfo_enchant_broker_get_dict_path)
00133        PHP_FE(enchant_broker_list_dicts,         arginfo_enchant_broker_free)
00134        PHP_FE(enchant_broker_request_dict,              arginfo_enchant_broker_request_dict)
00135        PHP_FE(enchant_broker_request_pwl_dict, arginfo_enchant_broker_request_pwl_dict)
00136        PHP_FE(enchant_broker_free_dict,          arginfo_enchant_broker_free_dict)
00137        PHP_FE(enchant_broker_dict_exists,               arginfo_enchant_broker_request_dict)
00138        PHP_FE(enchant_broker_set_ordering,       arginfo_enchant_broker_set_ordering)
00139        PHP_FE(enchant_broker_describe,           arginfo_enchant_broker_free)
00140        PHP_FE(enchant_dict_check,                       arginfo_enchant_dict_check)
00141        PHP_FE(enchant_dict_suggest,                     arginfo_enchant_dict_check)
00142        PHP_FE(enchant_dict_add_to_personal,      arginfo_enchant_dict_check)
00143        PHP_FE(enchant_dict_add_to_session,       arginfo_enchant_dict_check)
00144        PHP_FE(enchant_dict_is_in_session,               arginfo_enchant_dict_check)
00145        PHP_FE(enchant_dict_store_replacement,    arginfo_enchant_dict_store_replacement)
00146        PHP_FE(enchant_dict_get_error,                   arginfo_enchant_broker_free_dict)
00147        PHP_FE(enchant_dict_describe,                    arginfo_enchant_broker_free_dict)
00148        PHP_FE(enchant_dict_quick_check,          arginfo_enchant_dict_quick_check)
00149        PHP_FE_END
00150 };
00151 /* }}} */
00152 
00153 /* {{{ enchant_module_entry
00154  */
00155 zend_module_entry enchant_module_entry = {
00156 #if ZEND_MODULE_API_NO >= 20010901
00157        STANDARD_MODULE_HEADER,
00158 #endif
00159        "enchant",
00160        enchant_functions,
00161        PHP_MINIT(enchant),
00162        PHP_MSHUTDOWN(enchant),
00163        NULL,  /* Replace with NULL if there's nothing to do at request start */
00164        NULL,  /* Replace with NULL if there's nothing to do at request end */
00165        PHP_MINFO(enchant),
00166 #if ZEND_MODULE_API_NO >= 20010901
00167        PHP_ENCHANT_VERSION,
00168 #endif
00169        STANDARD_MODULE_PROPERTIES
00170 };
00171 /* }}} */
00172 
00173 #ifdef COMPILE_DL_ENCHANT
00174 ZEND_GET_MODULE(enchant)
00175 #endif
00176 
00177 static void
00178 enumerate_providers_fn (const char * const name,
00179                         const char * const desc,
00180                         const char * const file,
00181                         void * ud) /* {{{ */
00182 {
00183        zval *zdesc = (zval *) ud;
00184        zval *tmp_array;
00185 
00186        MAKE_STD_ZVAL(tmp_array);
00187        array_init(tmp_array);
00188 
00189        add_assoc_string(tmp_array, "name", (char *)name, 1);
00190        add_assoc_string(tmp_array, "desc", (char *)desc, 1);
00191        add_assoc_string(tmp_array, "file", (char *)file, 1);
00192 
00193        if (Z_TYPE_P(zdesc)!=IS_ARRAY) {
00194               array_init(zdesc);
00195        }
00196 
00197        add_next_index_zval(zdesc, tmp_array);
00198 }
00199 /* }}} */
00200 
00201 static void
00202 describe_dict_fn (const char * const lang,
00203                   const char * const name,
00204                   const char * const desc,
00205                   const char * const file,
00206                   void * ud) /* {{{ */
00207 {
00208        zval *zdesc = (zval *) ud;
00209        array_init(zdesc);
00210        add_assoc_string(zdesc, "lang", (char *)lang, 1);
00211        add_assoc_string(zdesc, "name", (char *)name, 1);
00212        add_assoc_string(zdesc, "desc", (char *)desc, 1);
00213        add_assoc_string(zdesc, "file", (char *)file, 1);
00214 }
00215 /* }}} */
00216 
00217 static void php_enchant_list_dicts_fn( const char * const lang_tag,
00218               const char * const provider_name, const char * const provider_desc,
00219               const char * const provider_file, void * ud) /* {{{ */
00220 {
00221        zval *zdesc = (zval *) ud;
00222        zval *tmp_array;
00223 
00224        MAKE_STD_ZVAL(tmp_array);
00225        array_init(tmp_array);
00226        add_assoc_string(tmp_array, "lang_tag", (char *)lang_tag, 1);
00227        add_assoc_string(tmp_array, "provider_name", (char *)provider_name, 1);
00228        add_assoc_string(tmp_array, "provider_desc", (char *)provider_desc, 1);
00229        add_assoc_string(tmp_array, "provider_file", (char *)provider_file, 1);
00230 
00231        if (Z_TYPE_P(zdesc) != IS_ARRAY) {
00232               array_init(zdesc);
00233        }
00234        add_next_index_zval(zdesc, tmp_array);
00235 
00236 }
00237 /* }}} */
00238 
00239 static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
00240 {
00241        if (rsrc->ptr) {
00242               enchant_broker *broker = (enchant_broker *)rsrc->ptr;
00243               if (broker) {
00244                      if (broker->pbroker) {
00245                             if (broker->dictcnt && broker->dict) {
00246                                    if (broker->dict) {
00247                                           int total, tofree;
00248                                           tofree = total = broker->dictcnt-1;
00249                                           do {
00250                                                  zend_list_delete(broker->dict[total]->rsrc_id);
00251                                                  efree(broker->dict[total]);
00252                                                  total--;
00253                                           } while (total>=0);
00254                                    }
00255                                    efree(broker->dict);
00256                                    broker->dict = NULL;
00257                             }
00258                             enchant_broker_free(broker->pbroker);
00259                      }
00260                      efree(broker);
00261               }
00262        }
00263 }
00264 /* }}} */
00265 
00266 static void php_enchant_dict_free(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
00267 
00268 {
00269        if (rsrc->ptr) {
00270               enchant_dict *pdict = (enchant_dict *)rsrc->ptr;
00271               if (pdict) {
00272                      if (pdict->pdict && pdict->pbroker) {
00273                             enchant_broker_free_dict(pdict->pbroker->pbroker, pdict->pdict);
00274                             if (pdict->id) {
00275                                    pdict->pbroker->dict[pdict->id-1]->next = NULL;
00276                             }
00277                             zend_list_delete(pdict->pbroker->rsrc_id);
00278                      }
00279 
00280               }
00281        }
00282 }
00283 /* }}} */
00284 
00285 /* {{{ PHP_MINIT_FUNCTION
00286  */
00287 PHP_MINIT_FUNCTION(enchant)
00288 {
00289        le_enchant_broker = zend_register_list_destructors_ex(php_enchant_broker_free, NULL, "enchant_broker", module_number);
00290        le_enchant_dict = zend_register_list_destructors_ex(php_enchant_dict_free, NULL, "enchant_dict", module_number);
00291        REGISTER_LONG_CONSTANT("ENCHANT_MYSPELL", PHP_ENCHANT_MYSPELL, CONST_CS | CONST_PERSISTENT);
00292        REGISTER_LONG_CONSTANT("ENCHANT_ISPELL", PHP_ENCHANT_ISPELL, CONST_CS | CONST_PERSISTENT);
00293        return SUCCESS;
00294 }
00295 /* }}} */
00296 
00297 /* {{{ PHP_MSHUTDOWN_FUNCTION
00298  */
00299 PHP_MSHUTDOWN_FUNCTION(enchant)
00300 {
00301        return SUCCESS;
00302 }
00303 /* }}} */
00304 
00305 static void __enumerate_providers_fn (const char * const name,
00306                         const char * const desc,
00307                         const char * const file,
00308                         void * ud) /* {{{ */
00309 {
00310        php_info_print_table_row(3, name, desc, file);
00311 }
00312 /* }}} */
00313 
00314 /* {{{ PHP_MINFO_FUNCTION
00315  */
00316 PHP_MINFO_FUNCTION(enchant)
00317 {
00318        EnchantBroker *pbroker;
00319 
00320        pbroker = enchant_broker_init();
00321        php_info_print_table_start();
00322        php_info_print_table_header(2, "enchant support", "enabled");
00323        php_info_print_table_row(2, "Version", PHP_ENCHANT_VERSION);
00324 #ifdef ENCHANT_VERSION_STRING
00325        php_info_print_table_row(2, "Libenchant Version", ENCHANT_VERSION_STRING);
00326 #elif defined(HAVE_ENCHANT_BROKER_SET_PARAM)
00327        php_info_print_table_row(2, "Libenchant Version", "1.5.0 or later");
00328 #endif
00329        php_info_print_table_row(2, "Revision", "$Revision: 321634 $");
00330        php_info_print_table_end();
00331 
00332        php_info_print_table_start();
00333        enchant_broker_describe(pbroker, __enumerate_providers_fn, NULL);
00334        php_info_print_table_end();
00335        enchant_broker_free(pbroker);
00336 }
00337 /* }}} */
00338 
00339 #define PHP_ENCHANT_GET_BROKER     \
00340        ZEND_FETCH_RESOURCE(pbroker, enchant_broker *, &broker, -1, "enchant_broker", le_enchant_broker); \
00341        if (!pbroker || !pbroker->pbroker) {      \
00342               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Resource broker invalid");       \
00343               RETURN_FALSE; \
00344        }
00345 
00346 #define PHP_ENCHANT_GET_DICT       \
00347        ZEND_FETCH_RESOURCE(pdict, enchant_dict *, &dict, -1, "enchant_dict", le_enchant_dict);    \
00348        if (!pdict || !pdict->pdict) {     \
00349               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Invalid dictionary resource.");  \
00350               RETURN_FALSE; \
00351        }
00352 
00353 /* {{{ proto resource enchant_broker_init()
00354    create a new broker object capable of requesting */
00355 PHP_FUNCTION(enchant_broker_init)
00356 {
00357        enchant_broker *broker;
00358        EnchantBroker *pbroker;
00359 
00360        if (ZEND_NUM_ARGS()) {
00361               ZEND_WRONG_PARAM_COUNT();
00362        }
00363 
00364        pbroker = enchant_broker_init();
00365 
00366        if (pbroker) {
00367               broker = (enchant_broker *) emalloc(sizeof(enchant_broker));
00368               broker->pbroker = pbroker;
00369               broker->dict = NULL;
00370               broker->dictcnt = 0;
00371               broker->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, broker, le_enchant_broker);
00372        } else {
00373               RETURN_FALSE;
00374        }
00375 }
00376 /* }}} */
00377 
00378 /* {{{ proto boolean enchant_broker_free(resource broker)
00379    Destroys the broker object and its dictionnaries */
00380 PHP_FUNCTION(enchant_broker_free)
00381 {
00382        zval *broker;
00383        enchant_broker *pbroker;
00384 
00385        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
00386               RETURN_FALSE;
00387        }
00388        PHP_ENCHANT_GET_BROKER;
00389 
00390        zend_list_delete(Z_RESVAL_P(broker));
00391        RETURN_TRUE;
00392 }
00393 /* }}} */
00394 
00395 /* {{{ proto string enchant_broker_get_error(resource broker)
00396    Returns the last error of the broker */
00397 PHP_FUNCTION(enchant_broker_get_error)
00398 {
00399        zval *broker;
00400        enchant_broker *pbroker;
00401        char *msg;
00402 
00403        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
00404               RETURN_FALSE;
00405        }
00406 
00407        PHP_ENCHANT_GET_BROKER;
00408 
00409        msg = enchant_broker_get_error(pbroker->pbroker);
00410        if (msg) {
00411               RETURN_STRING((char *)msg, 1);
00412        }
00413        RETURN_FALSE;
00414 }
00415 /* }}} */
00416 
00417 #if HAVE_ENCHANT_BROKER_SET_PARAM
00418 /* {{{ proto bool enchant_broker_set_dict_path(resource broker, int dict_type, string value)
00419        Set the directory path for a given backend, works with ispell and myspell */
00420 PHP_FUNCTION(enchant_broker_set_dict_path)
00421 {
00422        zval *broker;
00423        enchant_broker *pbroker;
00424        long dict_type;
00425        char *value;
00426        int value_len;
00427 
00428        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls", &broker, &dict_type, &value, &value_len) == FAILURE) {
00429               RETURN_FALSE;
00430        }
00431 
00432        if (!value_len) {
00433               RETURN_FALSE;
00434        }
00435        
00436        PHP_ENCHANT_GET_BROKER;
00437 
00438        switch (dict_type) {
00439               case PHP_ENCHANT_MYSPELL:
00440                      PHP_ENCHANT_GET_BROKER;
00441                      enchant_broker_set_param(pbroker->pbroker, "enchant.myspell.dictionary.path", (const char *)value);
00442                      RETURN_TRUE;
00443                      break;
00444 
00445               case PHP_ENCHANT_ISPELL:
00446                      PHP_ENCHANT_GET_BROKER;
00447                      enchant_broker_set_param(pbroker->pbroker, "enchant.ispell.dictionary.path", (const char *)value);
00448                      RETURN_TRUE;
00449                      break;
00450 
00451               default:
00452                      RETURN_FALSE;
00453        }
00454 }
00455 /* }}} */
00456 
00457 
00458 /* {{{ proto string enchant_broker_get_dict_path(resource broker, int dict_type)
00459        Get the directory path for a given backend, works with ispell and myspell */
00460 PHP_FUNCTION(enchant_broker_get_dict_path)
00461 {
00462        zval *broker;
00463        enchant_broker *pbroker;
00464        long dict_type;
00465        char *value;
00466 
00467        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &broker, &dict_type) == FAILURE) {
00468               RETURN_FALSE;
00469        }
00470        
00471        PHP_ENCHANT_GET_BROKER;
00472 
00473        switch (dict_type) {
00474               case PHP_ENCHANT_MYSPELL:
00475                      PHP_ENCHANT_GET_BROKER;
00476                      value = enchant_broker_get_param(pbroker->pbroker, "enchant.myspell.dictionary.path");
00477                      break;
00478 
00479               case PHP_ENCHANT_ISPELL:
00480                      PHP_ENCHANT_GET_BROKER;
00481                      value = enchant_broker_get_param(pbroker->pbroker, "enchant.ispell.dictionary.path");
00482                      break;
00483 
00484               default:
00485                      RETURN_FALSE;
00486        }
00487 
00488        RETURN_STRING(value, 1);
00489 }
00490 /* }}} */
00491 #else
00492 /* {{{ proto bool enchant_broker_set_dict_path(resource broker, int dict_type, string value)
00493        Set the directory path for a given backend, works with ispell and myspell */
00494 PHP_FUNCTION(enchant_broker_set_dict_path)
00495 {
00496        RETURN_FALSE;
00497 }
00498 /* }}} */
00499 
00500 
00501 /* {{{ proto string enchant_broker_get_dict_path(resource broker, int dict_type)
00502        Get the directory path for a given backend, works with ispell and myspell */
00503 PHP_FUNCTION(enchant_broker_get_dict_path)
00504 {
00505        RETURN_FALSE;
00506 }
00507 /* }}} */
00508 #endif
00509 
00510 /* {{{ proto string enchant_broker_list_dicts(resource broker)
00511    Lists the dictionaries available for the given broker */
00512 PHP_FUNCTION(enchant_broker_list_dicts)
00513 {
00514        zval *broker;
00515        enchant_broker *pbroker;
00516 
00517        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
00518               RETURN_FALSE;
00519        }
00520 
00521        PHP_ENCHANT_GET_BROKER;
00522 
00523        enchant_broker_list_dicts(pbroker->pbroker, php_enchant_list_dicts_fn, (void *)return_value);
00524 }
00525 /* }}} */
00526 
00527 /* {{{ proto resource enchant_broker_request_dict(resource broker, string tag)
00528        create a new dictionary using tag, the non-empty language tag you wish to request
00529        a dictionary for ("en_US", "de_DE", ...) */
00530 PHP_FUNCTION(enchant_broker_request_dict)
00531 {
00532        zval *broker;
00533        enchant_broker *pbroker;
00534        enchant_dict *dict;
00535        EnchantDict *d;
00536        char *tag;
00537        int taglen;
00538        int pos;
00539 
00540        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &tag, &taglen) == FAILURE) {
00541               RETURN_FALSE;
00542        }
00543 
00544        PHP_ENCHANT_GET_BROKER;
00545 
00546        d = enchant_broker_request_dict(pbroker->pbroker, (const char *)tag);
00547        if (d) {
00548               if (pbroker->dictcnt) {
00549                      pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
00550                      pos = pbroker->dictcnt++;
00551               } else {
00552                      pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
00553                      pos = 0;
00554                      pbroker->dictcnt++;
00555               }
00556 
00557               dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
00558               dict->id = pos;
00559               dict->pbroker = pbroker;
00560               dict->pdict = d;
00561               dict->prev = pos ? pbroker->dict[pos-1] : NULL;
00562               dict->next = NULL;
00563               pbroker->dict[pos] = dict;
00564 
00565               if (pos) {
00566                      pbroker->dict[pos-1]->next = dict;
00567               }
00568 
00569               dict->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
00570               zend_list_addref(pbroker->rsrc_id);
00571        } else {
00572               RETURN_FALSE;
00573        }
00574 }
00575 /* }}} */
00576 
00577 /* {{{ proto resource enchant_broker_request_pwl_dict(resource broker, string filename)
00578    creates a dictionary using a PWL file. A PWL file is personal word file one word per line. It must exist before the call.*/
00579 PHP_FUNCTION(enchant_broker_request_pwl_dict)
00580 {
00581        zval *broker;
00582        enchant_broker *pbroker;
00583        enchant_dict *dict;
00584        EnchantDict *d;
00585        char *pwl;
00586        int pwllen;
00587        int pos;
00588 
00589        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &pwl, &pwllen) == FAILURE) {
00590               RETURN_FALSE;
00591        }
00592 
00593        if (strlen(pwl) != pwllen) {
00594               RETURN_FALSE;
00595        }
00596 
00597 #if PHP_API_VERSION < 20100412
00598        if ((PG(safe_mode) && (!php_checkuid(pwl, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(pwl TSRMLS_CC)) {
00599 #else
00600        if (php_check_open_basedir(pwl TSRMLS_CC)) {
00601 #endif
00602               RETURN_FALSE;
00603        }
00604 
00605        PHP_ENCHANT_GET_BROKER;
00606 
00607        d = enchant_broker_request_pwl_dict(pbroker->pbroker, (const char *)pwl);
00608        if (d) {
00609               if (pbroker->dictcnt) {
00610                      pos = pbroker->dictcnt++;
00611                      pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
00612               } else {
00613                      pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
00614                      pos = 0;
00615                      pbroker->dictcnt++;
00616               }
00617               dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
00618               dict->id = pos;
00619               dict->pbroker = pbroker;
00620               dict->pdict = d;
00621               dict->prev = pos?pbroker->dict[pos-1]:NULL;
00622               dict->next = NULL;
00623               pbroker->dict[pos] = dict;
00624               if (pos) {
00625                      pbroker->dict[pos-1]->next = dict;
00626               }
00627               dict->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
00628        } else {
00629               RETURN_FALSE;
00630        }
00631 }
00632 /* }}} */
00633 
00634 /* {{{ proto resource enchant_broker_free_dict(resource dict)
00635    Free the dictionary resource */
00636 PHP_FUNCTION(enchant_broker_free_dict)
00637 {
00638        zval *dict;
00639        enchant_dict *pdict;
00640 
00641        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
00642               RETURN_FALSE;
00643        }
00644 
00645        PHP_ENCHANT_GET_DICT;
00646 
00647        zend_list_delete(Z_RESVAL_P(dict));
00648        RETURN_TRUE;
00649 }
00650 /* }}} */
00651 
00652 /* {{{ proto bool enchant_broker_dict_exists(resource broker, string tag)
00653    Wether a dictionary exists or not. Using non-empty tag */
00654 PHP_FUNCTION(enchant_broker_dict_exists)
00655 {
00656        zval *broker;
00657        char *tag;
00658        int taglen;
00659        enchant_broker * pbroker;
00660 
00661        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &tag, &taglen) == FAILURE) {
00662               RETURN_FALSE;
00663        }
00664 
00665        PHP_ENCHANT_GET_BROKER;
00666 
00667        RETURN_BOOL(enchant_broker_dict_exists(pbroker->pbroker, tag));
00668 }
00669 /* }}} */
00670 
00671 /* {{{ proto bool enchant_broker_set_ordering(resource broker, string tag, string ordering)
00672        Declares a preference of dictionaries to use for the language
00673        described/referred to by 'tag'. The ordering is a comma delimited
00674        list of provider names. As a special exception, the "*" tag can
00675        be used as a language tag to declare a default ordering for any
00676        language that does not explictly declare an ordering. */
00677 
00678 PHP_FUNCTION(enchant_broker_set_ordering)
00679 {
00680        zval *broker;
00681        char *pordering;
00682        int porderinglen;
00683        char *ptag;
00684        int ptaglen;
00685        enchant_broker * pbroker;
00686 
00687        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &broker, &ptag, &ptaglen, &pordering, &porderinglen) == FAILURE) {
00688               RETURN_FALSE;
00689        }
00690 
00691        PHP_ENCHANT_GET_BROKER;
00692 
00693        enchant_broker_set_ordering(pbroker->pbroker, ptag, pordering);
00694        RETURN_TRUE;
00695 }
00696 /* }}} */
00697 
00698 /* {{{ proto array enchant_broker_describe(resource broker)
00699        Enumerates the Enchant providers and tells you some rudimentary information about them. The same info is provided through phpinfo() */
00700 PHP_FUNCTION(enchant_broker_describe)
00701 {
00702        EnchantBrokerDescribeFn describetozval = enumerate_providers_fn;
00703        zval *broker;
00704        enchant_broker * pbroker;
00705 
00706        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
00707               RETURN_FALSE;
00708        }
00709 
00710        PHP_ENCHANT_GET_BROKER;
00711 
00712        enchant_broker_describe(pbroker->pbroker, describetozval, (void *)return_value);
00713 }
00714 /* }}} */
00715 
00716 /* {{{ proto bool enchant_dict_quick_check(resource dict, string word [, array &suggestions])
00717     If the word is correctly spelled return true, otherwise return false, if suggestions variable
00718     is provided, fill it with spelling alternatives. */
00719 PHP_FUNCTION(enchant_dict_quick_check)
00720 {
00721        zval *dict, *sugg = NULL;
00722        char *word;
00723        int wordlen;
00724        enchant_dict *pdict;
00725 
00726        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z/", &dict, &word, &wordlen, &sugg) == FAILURE) {
00727               RETURN_FALSE;
00728        }
00729 
00730        if (sugg) {
00731               zval_dtor(sugg);
00732        }
00733 
00734        PHP_ENCHANT_GET_DICT;
00735 
00736        if (enchant_dict_check(pdict->pdict, word, wordlen) > 0) {
00737               int n_sugg;
00738               size_t n_sugg_st;
00739               char **suggs;
00740 
00741               if (!sugg && ZEND_NUM_ARGS() == 2) {
00742                      RETURN_FALSE;
00743               }
00744 
00745               array_init(sugg);
00746 
00747               suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg_st);
00748               memcpy(&n_sugg, &n_sugg_st, sizeof(n_sugg));
00749               if (suggs && n_sugg) {
00750                      int i;
00751                      for (i = 0; i < n_sugg; i++) {
00752                             add_next_index_string(sugg, suggs[i], 1);
00753                      }
00754                      enchant_dict_free_suggestions(pdict->pdict, suggs);
00755               }
00756 
00757 
00758               RETURN_FALSE;
00759        }
00760        RETURN_TRUE;
00761 }
00762 /* }}} */
00763 
00764 /* {{{ proto bool enchant_dict_check(resource dict, string word)
00765     If the word is correctly spelled return true, otherwise return false */
00766 PHP_FUNCTION(enchant_dict_check)
00767 {
00768        zval *dict;
00769        char *word;
00770        int wordlen;
00771        enchant_dict *pdict;
00772 
00773        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
00774               RETURN_FALSE;
00775        }
00776 
00777        PHP_ENCHANT_GET_DICT;
00778 
00779        RETURN_BOOL(!enchant_dict_check(pdict->pdict, word, wordlen));
00780 }
00781 /* }}} */
00782 
00783 /* {{{ proto array enchant_dict_suggest(resource dict, string word)
00784     Will return a list of values if any of those pre-conditions are not met.*/
00785 PHP_FUNCTION(enchant_dict_suggest)
00786 {
00787        zval *dict;
00788        char *word;
00789        int wordlen;
00790        char **suggs;
00791        enchant_dict *pdict;
00792        int n_sugg;
00793        size_t n_sugg_st;
00794 
00795        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
00796               RETURN_FALSE;
00797        }
00798 
00799        PHP_ENCHANT_GET_DICT;
00800 
00801        suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg_st);
00802        memcpy(&n_sugg, &n_sugg_st, sizeof(n_sugg));
00803        if (suggs && n_sugg) {
00804               int i;
00805 
00806               array_init(return_value);
00807               for (i = 0; i < n_sugg; i++) {
00808                      add_next_index_string(return_value, suggs[i], 1);
00809               }
00810 
00811               enchant_dict_free_suggestions(pdict->pdict, suggs);
00812        }
00813 }
00814 /* }}} */
00815 
00816 /* {{{ proto void enchant_dict_add_to_personal(resource dict, string word)
00817      add 'word' to personal word list */
00818 PHP_FUNCTION(enchant_dict_add_to_personal)
00819 {
00820        zval *dict;
00821        char *word;
00822        int wordlen;
00823        enchant_dict *pdict;
00824 
00825        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
00826               RETURN_FALSE;
00827        }
00828 
00829        PHP_ENCHANT_GET_DICT;
00830 
00831        enchant_dict_add_to_personal(pdict->pdict, word, wordlen);
00832 }
00833 /* }}} */
00834 
00835 /* {{{ proto void enchant_dict_add_to_session(resource dict, string word)
00836    add 'word' to this spell-checking session */
00837 PHP_FUNCTION(enchant_dict_add_to_session)
00838 {
00839        zval *dict;
00840        char *word;
00841        int wordlen;
00842        enchant_dict *pdict;
00843 
00844        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
00845               RETURN_FALSE;
00846        }
00847 
00848        PHP_ENCHANT_GET_DICT;
00849 
00850        enchant_dict_add_to_session(pdict->pdict, word, wordlen);
00851 }
00852 /* }}} */
00853 
00854 /* {{{ proto bool enchant_dict_is_in_session(resource dict, string word)
00855    whether or not 'word' exists in this spelling-session */
00856 PHP_FUNCTION(enchant_dict_is_in_session)
00857 {
00858        zval *dict;
00859        char *word;
00860        int wordlen;
00861        enchant_dict *pdict;
00862 
00863        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
00864               RETURN_FALSE;
00865        }
00866 
00867        PHP_ENCHANT_GET_DICT;
00868 
00869        RETURN_BOOL(enchant_dict_is_in_session(pdict->pdict, word, wordlen));
00870 }
00871 /* }}} */
00872 
00873 /* {{{ proto void enchant_dict_store_replacement(resource dict, string mis, string cor)
00874        add a correction for 'mis' using 'cor'.
00875        Notes that you replaced @mis with @cor, so it's possibly more likely
00876        that future occurrences of @mis will be replaced with @cor. So it might
00877        bump @cor up in the suggestion list.*/
00878 PHP_FUNCTION(enchant_dict_store_replacement)
00879 {
00880        zval *dict;
00881        char *mis, *cor;
00882        int mislen, corlen;
00883 
00884        enchant_dict *pdict;
00885 
00886        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &dict, &mis, &mislen, &cor, &corlen) == FAILURE) {
00887               RETURN_FALSE;
00888        }
00889 
00890        PHP_ENCHANT_GET_DICT;
00891 
00892        enchant_dict_store_replacement(pdict->pdict, mis, mislen, cor, corlen);
00893 }
00894 /* }}} */
00895 
00896 /* {{{ proto string enchant_dict_get_error(resource dict)
00897    Returns the last error of the current spelling-session */
00898 PHP_FUNCTION(enchant_dict_get_error)
00899 {
00900        zval *dict;
00901        enchant_dict *pdict;
00902        char *msg;
00903 
00904        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
00905               RETURN_FALSE;
00906        }
00907 
00908        PHP_ENCHANT_GET_DICT;
00909 
00910        msg = enchant_dict_get_error(pdict->pdict);
00911        if (msg) {
00912               RETURN_STRING((char *)msg, 1);
00913        }
00914 
00915        RETURN_FALSE;
00916 }
00917 /* }}} */
00918 
00919 /* {{{ proto array enchant_dict_describe(resource dict)
00920    Describes an individual dictionary 'dict' */
00921 PHP_FUNCTION(enchant_dict_describe)
00922 {
00923        zval *dict;
00924        enchant_dict *pdict;
00925 
00926        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
00927               RETURN_FALSE;
00928        }
00929 
00930        PHP_ENCHANT_GET_DICT;
00931 
00932        enchant_dict_describe(pdict->pdict, describe_dict_fn, (void *)return_value);
00933 }
00934 /* }}} */
00935 
00936 /*
00937  * Local variables:
00938  * tab-width: 4
00939  * c-basic-offset: 4
00940  * End:
00941  * vim600: noet sw=4 ts=4 fdm=marker
00942  * vim<600: noet sw=4 ts=4
00943  */