root/ext/enchant/enchant.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ZEND_GET_MODULE
  2. describe_dict_fn
  3. php_enchant_list_dicts_fn
  4. php_enchant_broker_free
  5. php_enchant_dict_free
  6. PHP_MINIT_FUNCTION
  7. PHP_MSHUTDOWN_FUNCTION
  8. __enumerate_providers_fn
  9. PHP_MINFO_FUNCTION
  10. PHP_FUNCTION
  11. PHP_FUNCTION
  12. PHP_FUNCTION
  13. PHP_FUNCTION
  14. PHP_FUNCTION
  15. PHP_FUNCTION
  16. PHP_FUNCTION
  17. PHP_FUNCTION
  18. PHP_FUNCTION
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. PHP_FUNCTION
  23. PHP_FUNCTION
  24. PHP_FUNCTION
  25. PHP_FUNCTION
  26. PHP_FUNCTION
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION
  31. PHP_FUNCTION
  32. PHP_FUNCTION

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 7                                                        |
   4   +----------------------------------------------------------------------+
   5   | Copyright (c) 1997-2016 The PHP Group                                |
   6   +----------------------------------------------------------------------+
   7   | This source file is subject to version 3.0 of the PHP license,       |
   8   | that is bundled with this package in the file LICENSE, and is        |
   9   | available at through the world-wide-web at                           |
  10   | http://www.php.net/license/3_0.txt.                                  |
  11   | If you did not receive a copy of the PHP license and are unable to   |
  12   | obtain it through the world-wide-web, please send a note to          |
  13   | license@php.net so we can mail you a copy immediately.               |
  14   +----------------------------------------------------------------------+
  15   | Author: Pierre-Alain Joye <paj@pearfr.org>                           |
  16   |         Ilia Alshanetsky <ilia@prohost.org>                          |
  17   +----------------------------------------------------------------------+
  18 
  19   $Id: e2428b7830f0b472b3af33bf243504d00d9b11ca $
  20 */
  21 
  22 #ifdef HAVE_CONFIG_H
  23 #include "config.h"
  24 #endif
  25 
  26 #include "php.h"
  27 #include "php_ini.h"
  28 #include "ext/standard/info.h"
  29 #include <enchant.h>
  30 #include "php_enchant.h"
  31 
  32 typedef EnchantBroker * EnchantBrokerPtr;
  33 typedef struct _broker_struct enchant_broker;
  34 typedef struct _dict_struct enchant_dict;
  35 
  36 typedef enchant_broker * enchant_brokerPtr;
  37 typedef enchant_dict * enchant_dictPtr;
  38 
  39 typedef struct _broker_struct {
  40         EnchantBroker   *pbroker;
  41         enchant_dict    **dict;
  42         unsigned int    dictcnt;
  43         zend_resource   *rsrc;
  44 } _enchant_broker;
  45 
  46 typedef struct _dict_struct {
  47         unsigned int    id;
  48         EnchantDict             *pdict;
  49         enchant_broker  *pbroker;
  50         zend_resource   *rsrc;
  51 } _enchant_dict;
  52 
  53 
  54 /* True global resources - no need for thread safety here */
  55 static int le_enchant_broker;
  56 static int le_enchant_dict;
  57 
  58 /* If you declare any globals in php_enchant.h uncomment this:*/
  59 /*ZEND_DECLARE_MODULE_GLOBALS(enchant)*/
  60 
  61 #define PHP_ENCHANT_MYSPELL 1
  62 #define PHP_ENCHANT_ISPELL 2
  63 
  64 /* {{{ arginfo */
  65 ZEND_BEGIN_ARG_INFO(arginfo_enchant_broker_init, 0)
  66 ZEND_END_ARG_INFO()
  67 
  68 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_free, 0, 0, 1)
  69         ZEND_ARG_INFO(0, broker)
  70 ZEND_END_ARG_INFO()
  71 
  72 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_set_dict_path, 0, 0, 3)
  73         ZEND_ARG_INFO(0, broker)
  74         ZEND_ARG_INFO(0, name)
  75         ZEND_ARG_INFO(0, value)
  76 ZEND_END_ARG_INFO()
  77 
  78 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_get_dict_path, 0, 0, 2)
  79         ZEND_ARG_INFO(0, broker)
  80         ZEND_ARG_INFO(0, name)
  81 ZEND_END_ARG_INFO()
  82 
  83 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_request_dict, 0, 0, 2)
  84         ZEND_ARG_INFO(0, broker)
  85         ZEND_ARG_INFO(0, tag)
  86 ZEND_END_ARG_INFO()
  87 
  88 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_request_pwl_dict, 0, 0, 2)
  89         ZEND_ARG_INFO(0, broker)
  90         ZEND_ARG_INFO(0, filename)
  91 ZEND_END_ARG_INFO()
  92 
  93 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_free_dict, 0, 0, 1)
  94         ZEND_ARG_INFO(0, dict)
  95 ZEND_END_ARG_INFO()
  96 
  97 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_set_ordering, 0, 0, 3)
  98         ZEND_ARG_INFO(0, broker)
  99         ZEND_ARG_INFO(0, tag)
 100         ZEND_ARG_INFO(0, ordering)
 101 ZEND_END_ARG_INFO()
 102 
 103 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_dict_quick_check, 0, 0, 2)
 104         ZEND_ARG_INFO(0, dict)
 105         ZEND_ARG_INFO(0, word)
 106         ZEND_ARG_INFO(1, suggestions)
 107 ZEND_END_ARG_INFO()
 108 
 109 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_dict_check, 0, 0, 2)
 110         ZEND_ARG_INFO(0, dict)
 111         ZEND_ARG_INFO(0, word)
 112 ZEND_END_ARG_INFO()
 113 
 114 ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_dict_store_replacement, 0, 0, 3)
 115         ZEND_ARG_INFO(0, dict)
 116         ZEND_ARG_INFO(0, mis)
 117         ZEND_ARG_INFO(0, cor)
 118 ZEND_END_ARG_INFO()
 119 /* }}} */
 120 
 121 /* {{{ enchant_functions[]
 122  *
 123  * Every user visible function must have an entry in enchant_functions[].
 124  */
 125 zend_function_entry enchant_functions[] = {
 126         PHP_FE(enchant_broker_init,                     arginfo_enchant_broker_init)
 127         PHP_FE(enchant_broker_free,                     arginfo_enchant_broker_free)
 128         PHP_FE(enchant_broker_get_error,                arginfo_enchant_broker_free)
 129         PHP_FE(enchant_broker_set_dict_path,    arginfo_enchant_broker_set_dict_path)
 130         PHP_FE(enchant_broker_get_dict_path,    arginfo_enchant_broker_get_dict_path)
 131         PHP_FE(enchant_broker_list_dicts,               arginfo_enchant_broker_free)
 132         PHP_FE(enchant_broker_request_dict,             arginfo_enchant_broker_request_dict)
 133         PHP_FE(enchant_broker_request_pwl_dict, arginfo_enchant_broker_request_pwl_dict)
 134         PHP_FE(enchant_broker_free_dict,                arginfo_enchant_broker_free_dict)
 135         PHP_FE(enchant_broker_dict_exists,              arginfo_enchant_broker_request_dict)
 136         PHP_FE(enchant_broker_set_ordering,     arginfo_enchant_broker_set_ordering)
 137         PHP_FE(enchant_broker_describe,                 arginfo_enchant_broker_free)
 138         PHP_FE(enchant_dict_check,                              arginfo_enchant_dict_check)
 139         PHP_FE(enchant_dict_suggest,                    arginfo_enchant_dict_check)
 140         PHP_FE(enchant_dict_add_to_personal,    arginfo_enchant_dict_check)
 141         PHP_FE(enchant_dict_add_to_session,     arginfo_enchant_dict_check)
 142         PHP_FE(enchant_dict_is_in_session,              arginfo_enchant_dict_check)
 143         PHP_FE(enchant_dict_store_replacement,  arginfo_enchant_dict_store_replacement)
 144         PHP_FE(enchant_dict_get_error,                  arginfo_enchant_broker_free_dict)
 145         PHP_FE(enchant_dict_describe,                   arginfo_enchant_broker_free_dict)
 146         PHP_FE(enchant_dict_quick_check,                arginfo_enchant_dict_quick_check)
 147         PHP_FE_END
 148 };
 149 /* }}} */
 150 
 151 /* {{{ enchant_module_entry
 152  */
 153 zend_module_entry enchant_module_entry = {
 154         STANDARD_MODULE_HEADER,
 155         "enchant",
 156         enchant_functions,
 157         PHP_MINIT(enchant),
 158         PHP_MSHUTDOWN(enchant),
 159         NULL,   /* Replace with NULL if there's nothing to do at request start */
 160         NULL,   /* Replace with NULL if there's nothing to do at request end */
 161         PHP_MINFO(enchant),
 162         PHP_ENCHANT_VERSION,
 163         STANDARD_MODULE_PROPERTIES
 164 };
 165 /* }}} */
 166 
 167 #ifdef COMPILE_DL_ENCHANT
 168 ZEND_GET_MODULE(enchant)
 169 #endif
 170 
 171 static void
 172 enumerate_providers_fn (const char * const name,
 173                         const char * const desc,
 174                         const char * const file,
 175                         void * ud) /* {{{ */
 176 {
 177         zval *zdesc = (zval *) ud;
 178         zval tmp_array;
 179 
 180         array_init(&tmp_array);
 181 
 182         add_assoc_string(&tmp_array, "name", (char *)name);
 183         add_assoc_string(&tmp_array, "desc", (char *)desc);
 184         add_assoc_string(&tmp_array, "file", (char *)file);
 185 
 186         if (Z_TYPE_P(zdesc)!=IS_ARRAY) {
 187                 array_init(zdesc);
 188         }
 189 
 190         add_next_index_zval(zdesc, &tmp_array);
 191 }
 192 /* }}} */
 193 
 194 static void
 195 describe_dict_fn (const char * const lang,
 196                   const char * const name,
 197                   const char * const desc,
 198                   const char * const file,
 199                   void * ud) /* {{{ */
 200 {
 201         zval *zdesc = (zval *) ud;
 202         array_init(zdesc);
 203         add_assoc_string(zdesc, "lang", (char *)lang);
 204         add_assoc_string(zdesc, "name", (char *)name);
 205         add_assoc_string(zdesc, "desc", (char *)desc);
 206         add_assoc_string(zdesc, "file", (char *)file);
 207 }
 208 /* }}} */
 209 
 210 static void php_enchant_list_dicts_fn( const char * const lang_tag,
 211                 const char * const provider_name, const char * const provider_desc,
 212                 const char * const provider_file, void * ud) /* {{{ */
 213 {
 214         zval *zdesc = (zval *) ud;
 215         zval tmp_array;
 216 
 217         array_init(&tmp_array);
 218         add_assoc_string(&tmp_array, "lang_tag", (char *)lang_tag);
 219         add_assoc_string(&tmp_array, "provider_name", (char *)provider_name);
 220         add_assoc_string(&tmp_array, "provider_desc", (char *)provider_desc);
 221         add_assoc_string(&tmp_array, "provider_file", (char *)provider_file);
 222 
 223         if (Z_TYPE_P(zdesc) != IS_ARRAY) {
 224                 array_init(zdesc);
 225         }
 226         add_next_index_zval(zdesc, &tmp_array);
 227 
 228 }
 229 /* }}} */
 230 
 231 static void php_enchant_broker_free(zend_resource *rsrc) /* {{{ */
 232 {
 233         if (rsrc->ptr) {
 234                 enchant_broker *broker = (enchant_broker *)rsrc->ptr;
 235                 if (broker) {
 236                         if (broker->pbroker) {
 237                                 if (broker->dictcnt && broker->dict) {
 238                                         if (broker->dict) {
 239                                                 int total;
 240                                                 total = broker->dictcnt-1;
 241                                                 do {
 242                                                         if (broker->dict[total]) {
 243                                                                 enchant_dict *pdict = broker->dict[total];
 244                                                                 broker->dict[total] = NULL;
 245                                                                 zend_list_free(pdict->rsrc);
 246                                                                 efree(pdict);
 247                                                         }
 248                                                         total--;
 249                                                 } while (total>=0);
 250                                         }
 251                                         efree(broker->dict);
 252                                         broker->dict = NULL;
 253                                 }
 254                                 enchant_broker_free(broker->pbroker);
 255                         }
 256                         efree(broker);
 257                 }
 258         }
 259 }
 260 /* }}} */
 261 
 262 static void php_enchant_dict_free(zend_resource *rsrc) /* {{{ */
 263 
 264 {
 265         if (rsrc->ptr) {
 266                 enchant_dict *pdict = (enchant_dict *)rsrc->ptr;
 267                 if (pdict) {
 268                         enchant_broker *pbroker = pdict->pbroker;
 269 
 270                         if (pdict->pdict && pbroker) {
 271                                 enchant_broker_free_dict(pbroker->pbroker, pdict->pdict);
 272                         }
 273 
 274                         pbroker->dict[pdict->id] = NULL;
 275                         efree(pdict);
 276                         zend_list_delete(pbroker->rsrc);
 277                 }
 278         }
 279 }
 280 /* }}} */
 281 
 282 /* {{{ PHP_MINIT_FUNCTION
 283  */
 284 PHP_MINIT_FUNCTION(enchant)
 285 {
 286         le_enchant_broker = zend_register_list_destructors_ex(php_enchant_broker_free, NULL, "enchant_broker", module_number);
 287         le_enchant_dict = zend_register_list_destructors_ex(php_enchant_dict_free, NULL, "enchant_dict", module_number);
 288         REGISTER_LONG_CONSTANT("ENCHANT_MYSPELL", PHP_ENCHANT_MYSPELL, CONST_CS | CONST_PERSISTENT);
 289         REGISTER_LONG_CONSTANT("ENCHANT_ISPELL", PHP_ENCHANT_ISPELL, CONST_CS | CONST_PERSISTENT);
 290         return SUCCESS;
 291 }
 292 /* }}} */
 293 
 294 /* {{{ PHP_MSHUTDOWN_FUNCTION
 295  */
 296 PHP_MSHUTDOWN_FUNCTION(enchant)
 297 {
 298         return SUCCESS;
 299 }
 300 /* }}} */
 301 
 302 static void __enumerate_providers_fn (const char * const name,
 303                         const char * const desc,
 304                         const char * const file,
 305                         void * ud) /* {{{ */
 306 {
 307         php_info_print_table_row(3, name, desc, file);
 308 }
 309 /* }}} */
 310 
 311 /* {{{ PHP_MINFO_FUNCTION
 312  */
 313 PHP_MINFO_FUNCTION(enchant)
 314 {
 315         EnchantBroker *pbroker;
 316 
 317         pbroker = enchant_broker_init();
 318         php_info_print_table_start();
 319         php_info_print_table_header(2, "enchant support", "enabled");
 320         php_info_print_table_row(2, "Version", PHP_ENCHANT_VERSION);
 321 #ifdef ENCHANT_VERSION_STRING
 322         php_info_print_table_row(2, "Libenchant Version", ENCHANT_VERSION_STRING);
 323 #elif defined(HAVE_ENCHANT_BROKER_SET_PARAM)
 324         php_info_print_table_row(2, "Libenchant Version", "1.5.0 or later");
 325 #endif
 326         php_info_print_table_row(2, "Revision", "$Id: e2428b7830f0b472b3af33bf243504d00d9b11ca $");
 327         php_info_print_table_end();
 328 
 329         php_info_print_table_start();
 330         enchant_broker_describe(pbroker, __enumerate_providers_fn, NULL);
 331         php_info_print_table_end();
 332         enchant_broker_free(pbroker);
 333 }
 334 /* }}} */
 335 
 336 #define PHP_ENCHANT_GET_BROKER  \
 337         pbroker = (enchant_broker *)zend_fetch_resource(Z_RES_P(broker), "enchant_broker", le_enchant_broker); \
 338         if (!pbroker || !pbroker->pbroker) {    \
 339                 php_error_docref(NULL, E_WARNING, "%s", "Resource broker invalid");     \
 340                 RETURN_FALSE;   \
 341         }
 342 
 343 #define PHP_ENCHANT_GET_DICT    \
 344         pdict = (enchant_dict *)zend_fetch_resource(Z_RES_P(dict), "enchant_dict", le_enchant_dict); \
 345         if (!pdict || !pdict->pdict) {  \
 346                 php_error_docref(NULL, E_WARNING, "%s", "Invalid dictionary resource.");        \
 347                 RETURN_FALSE;   \
 348         }
 349 
 350 /* {{{ proto resource enchant_broker_init()
 351    create a new broker object capable of requesting */
 352 PHP_FUNCTION(enchant_broker_init)
 353 {
 354         enchant_broker *broker;
 355         EnchantBroker *pbroker;
 356 
 357         if (zend_parse_parameters_none() == FAILURE) {
 358                 return;
 359         }
 360 
 361         pbroker = enchant_broker_init();
 362 
 363         if (pbroker) {
 364                 broker = (enchant_broker *) emalloc(sizeof(enchant_broker));
 365                 broker->pbroker = pbroker;
 366                 broker->dict = NULL;
 367                 broker->dictcnt = 0;
 368                 broker->rsrc = zend_register_resource(broker, le_enchant_broker);
 369                 RETURN_RES(broker->rsrc);
 370         } else {
 371                 RETURN_FALSE;
 372         }
 373 }
 374 /* }}} */
 375 
 376 /* {{{ proto boolean enchant_broker_free(resource broker)
 377    Destroys the broker object and its dictionnaries */
 378 PHP_FUNCTION(enchant_broker_free)
 379 {
 380         zval *broker;
 381         enchant_broker *pbroker;
 382 
 383         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &broker) == FAILURE) {
 384                 RETURN_FALSE;
 385         }
 386         PHP_ENCHANT_GET_BROKER;
 387 
 388         zend_list_close(Z_RES_P(broker));
 389         RETURN_TRUE;
 390 }
 391 /* }}} */
 392 
 393 /* {{{ proto string enchant_broker_get_error(resource broker)
 394    Returns the last error of the broker */
 395 PHP_FUNCTION(enchant_broker_get_error)
 396 {
 397         zval *broker;
 398         enchant_broker *pbroker;
 399         char *msg;
 400 
 401         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &broker) == FAILURE) {
 402                 RETURN_FALSE;
 403         }
 404 
 405         PHP_ENCHANT_GET_BROKER;
 406 
 407         msg = enchant_broker_get_error(pbroker->pbroker);
 408         if (msg) {
 409                 RETURN_STRING((char *)msg);
 410         }
 411         RETURN_FALSE;
 412 }
 413 /* }}} */
 414 
 415 #if HAVE_ENCHANT_BROKER_SET_PARAM
 416 /* {{{ proto bool enchant_broker_set_dict_path(resource broker, int dict_type, string value)
 417         Set the directory path for a given backend, works with ispell and myspell */
 418 PHP_FUNCTION(enchant_broker_set_dict_path)
 419 {
 420         zval *broker;
 421         enchant_broker *pbroker;
 422         zend_long dict_type;
 423         char *value;
 424         size_t value_len;
 425 
 426         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rls", &broker, &dict_type, &value, &value_len) == FAILURE) {
 427                 RETURN_FALSE;
 428         }
 429 
 430         if (!value_len) {
 431                 RETURN_FALSE;
 432         }
 433 
 434         PHP_ENCHANT_GET_BROKER;
 435 
 436         switch (dict_type) {
 437                 case PHP_ENCHANT_MYSPELL:
 438                         PHP_ENCHANT_GET_BROKER;
 439                         enchant_broker_set_param(pbroker->pbroker, "enchant.myspell.dictionary.path", (const char *)value);
 440                         RETURN_TRUE;
 441                         break;
 442 
 443                 case PHP_ENCHANT_ISPELL:
 444                         PHP_ENCHANT_GET_BROKER;
 445                         enchant_broker_set_param(pbroker->pbroker, "enchant.ispell.dictionary.path", (const char *)value);
 446                         RETURN_TRUE;
 447                         break;
 448 
 449                 default:
 450                         RETURN_FALSE;
 451         }
 452 }
 453 /* }}} */
 454 
 455 
 456 /* {{{ proto string enchant_broker_get_dict_path(resource broker, int dict_type)
 457         Get the directory path for a given backend, works with ispell and myspell */
 458 PHP_FUNCTION(enchant_broker_get_dict_path)
 459 {
 460         zval *broker;
 461         enchant_broker *pbroker;
 462         zend_long dict_type;
 463         char *value;
 464 
 465         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &broker, &dict_type) == FAILURE) {
 466                 RETURN_FALSE;
 467         }
 468 
 469         PHP_ENCHANT_GET_BROKER;
 470 
 471         switch (dict_type) {
 472                 case PHP_ENCHANT_MYSPELL:
 473                         PHP_ENCHANT_GET_BROKER;
 474                         value = enchant_broker_get_param(pbroker->pbroker, "enchant.myspell.dictionary.path");
 475                         break;
 476 
 477                 case PHP_ENCHANT_ISPELL:
 478                         PHP_ENCHANT_GET_BROKER;
 479                         value = enchant_broker_get_param(pbroker->pbroker, "enchant.ispell.dictionary.path");
 480                         break;
 481 
 482                 default:
 483                         RETURN_FALSE;
 484         }
 485 
 486         RETURN_STRING(value);
 487 }
 488 /* }}} */
 489 #else
 490 /* {{{ proto bool enchant_broker_set_dict_path(resource broker, int dict_type, string value)
 491         Set the directory path for a given backend, works with ispell and myspell */
 492 PHP_FUNCTION(enchant_broker_set_dict_path)
 493 {
 494         RETURN_FALSE;
 495 }
 496 /* }}} */
 497 
 498 
 499 /* {{{ proto string enchant_broker_get_dict_path(resource broker, int dict_type)
 500         Get the directory path for a given backend, works with ispell and myspell */
 501 PHP_FUNCTION(enchant_broker_get_dict_path)
 502 {
 503         RETURN_FALSE;
 504 }
 505 /* }}} */
 506 #endif
 507 
 508 /* {{{ proto string enchant_broker_list_dicts(resource broker)
 509    Lists the dictionaries available for the given broker */
 510 PHP_FUNCTION(enchant_broker_list_dicts)
 511 {
 512         zval *broker;
 513         enchant_broker *pbroker;
 514 
 515         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &broker) == FAILURE) {
 516                 RETURN_FALSE;
 517         }
 518 
 519         PHP_ENCHANT_GET_BROKER;
 520 
 521         enchant_broker_list_dicts(pbroker->pbroker, php_enchant_list_dicts_fn, (void *)return_value);
 522 }
 523 /* }}} */
 524 
 525 /* {{{ proto resource enchant_broker_request_dict(resource broker, string tag)
 526         create a new dictionary using tag, the non-empty language tag you wish to request
 527         a dictionary for ("en_US", "de_DE", ...) */
 528 PHP_FUNCTION(enchant_broker_request_dict)
 529 {
 530         zval *broker;
 531         enchant_broker *pbroker;
 532         enchant_dict *dict;
 533         EnchantDict *d;
 534         char *tag;
 535         size_t taglen;
 536         int pos;
 537 
 538         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &broker, &tag, &taglen) == FAILURE) {
 539                 RETURN_FALSE;
 540         }
 541 
 542         PHP_ENCHANT_GET_BROKER;
 543 
 544         if (taglen == 0) {
 545                 php_error_docref(NULL, E_WARNING, "Tag cannot be empty");
 546                 RETURN_FALSE;
 547         }
 548 
 549         d = enchant_broker_request_dict(pbroker->pbroker, (const char *)tag);
 550         if (d) {
 551                 pos = pbroker->dictcnt++;
 552                 if (pbroker->dictcnt) {
 553                         pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
 554                 } else {
 555                         pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
 556                         pos = 0;
 557                 }
 558 
 559                 dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
 560                 dict->id = pos;
 561                 dict->pbroker = pbroker;
 562                 dict->pdict = d;
 563                 pbroker->dict[pos] = dict;
 564 
 565                 dict->rsrc = zend_register_resource(dict, le_enchant_dict);
 566                 pbroker->rsrc->gc.refcount++;
 567                 RETURN_RES(dict->rsrc);
 568         } else {
 569                 RETURN_FALSE;
 570         }
 571 }
 572 /* }}} */
 573 
 574 /* {{{ proto resource enchant_broker_request_pwl_dict(resource broker, string filename)
 575    creates a dictionary using a PWL file. A PWL file is personal word file one word per line. It must exist before the call.*/
 576 PHP_FUNCTION(enchant_broker_request_pwl_dict)
 577 {
 578         zval *broker;
 579         enchant_broker *pbroker;
 580         enchant_dict *dict;
 581         EnchantDict *d;
 582         char *pwl;
 583         size_t pwllen;
 584         int pos;
 585 
 586         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp", &broker, &pwl, &pwllen) == FAILURE) {
 587                 RETURN_FALSE;
 588         }
 589 
 590 #if PHP_API_VERSION < 20100412
 591         if ((PG(safe_mode) && (!php_checkuid(pwl, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(pwl)) {
 592 #else
 593         if (php_check_open_basedir(pwl)) {
 594 #endif
 595                 RETURN_FALSE;
 596         }
 597 
 598         PHP_ENCHANT_GET_BROKER;
 599 
 600         d = enchant_broker_request_pwl_dict(pbroker->pbroker, (const char *)pwl);
 601         if (d) {
 602                 pos = pbroker->dictcnt++;
 603                 if (pbroker->dictcnt) {
 604                         pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
 605                 } else {
 606                         pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
 607                         pos = 0;
 608                 }
 609 
 610                 dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
 611                 dict->id = pos;
 612                 dict->pbroker = pbroker;
 613                 dict->pdict = d;
 614                 pbroker->dict[pos] = dict;
 615 
 616                 dict->rsrc = zend_register_resource(dict, le_enchant_dict);
 617                 pbroker->rsrc->gc.refcount++;
 618                 RETURN_RES(dict->rsrc);
 619         } else {
 620                 RETURN_FALSE;
 621         }
 622 }
 623 /* }}} */
 624 
 625 /* {{{ proto resource enchant_broker_free_dict(resource dict)
 626    Free the dictionary resource */
 627 PHP_FUNCTION(enchant_broker_free_dict)
 628 {
 629         zval *dict;
 630         enchant_dict *pdict;
 631 
 632         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &dict) == FAILURE) {
 633                 RETURN_FALSE;
 634         }
 635 
 636         PHP_ENCHANT_GET_DICT;
 637 
 638         zend_list_close(Z_RES_P(dict));
 639         RETURN_TRUE;
 640 }
 641 /* }}} */
 642 
 643 /* {{{ proto bool enchant_broker_dict_exists(resource broker, string tag)
 644    Whether a dictionary exists or not. Using non-empty tag */
 645 PHP_FUNCTION(enchant_broker_dict_exists)
 646 {
 647         zval *broker;
 648         char *tag;
 649         size_t taglen;
 650         enchant_broker * pbroker;
 651 
 652         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &broker, &tag, &taglen) == FAILURE) {
 653                 RETURN_FALSE;
 654         }
 655 
 656         PHP_ENCHANT_GET_BROKER;
 657 
 658         RETURN_BOOL(enchant_broker_dict_exists(pbroker->pbroker, tag));
 659 }
 660 /* }}} */
 661 
 662 /* {{{ proto bool enchant_broker_set_ordering(resource broker, string tag, string ordering)
 663         Declares a preference of dictionaries to use for the language
 664         described/referred to by 'tag'. The ordering is a comma delimited
 665         list of provider names. As a special exception, the "*" tag can
 666         be used as a language tag to declare a default ordering for any
 667         language that does not explicitly declare an ordering. */
 668 
 669 PHP_FUNCTION(enchant_broker_set_ordering)
 670 {
 671         zval *broker;
 672         char *pordering;
 673         size_t porderinglen;
 674         char *ptag;
 675         size_t ptaglen;
 676         enchant_broker * pbroker;
 677 
 678         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &broker, &ptag, &ptaglen, &pordering, &porderinglen) == FAILURE) {
 679                 RETURN_FALSE;
 680         }
 681 
 682         PHP_ENCHANT_GET_BROKER;
 683 
 684         enchant_broker_set_ordering(pbroker->pbroker, ptag, pordering);
 685         RETURN_TRUE;
 686 }
 687 /* }}} */
 688 
 689 /* {{{ proto array enchant_broker_describe(resource broker)
 690         Enumerates the Enchant providers and tells you some rudimentary information about them. The same info is provided through phpinfo() */
 691 PHP_FUNCTION(enchant_broker_describe)
 692 {
 693         EnchantBrokerDescribeFn describetozval = enumerate_providers_fn;
 694         zval *broker;
 695         enchant_broker * pbroker;
 696 
 697         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &broker) == FAILURE) {
 698                 RETURN_FALSE;
 699         }
 700 
 701         PHP_ENCHANT_GET_BROKER;
 702 
 703         enchant_broker_describe(pbroker->pbroker, describetozval, (void *)return_value);
 704 }
 705 /* }}} */
 706 
 707 /* {{{ proto bool enchant_dict_quick_check(resource dict, string word [, array &suggestions])
 708     If the word is correctly spelled return true, otherwise return false, if suggestions variable
 709     is provided, fill it with spelling alternatives. */
 710 PHP_FUNCTION(enchant_dict_quick_check)
 711 {
 712         zval *dict, *sugg = NULL;
 713         char *word;
 714         size_t wordlen;
 715         enchant_dict *pdict;
 716 
 717         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|z/", &dict, &word, &wordlen, &sugg) == FAILURE) {
 718                 RETURN_FALSE;
 719         }
 720 
 721         if (sugg) {
 722                 zval_dtor(sugg);
 723                 array_init(sugg);
 724         }
 725 
 726         PHP_ENCHANT_GET_DICT;
 727 
 728         if (enchant_dict_check(pdict->pdict, word, wordlen) > 0) {
 729                 int n_sugg;
 730                 size_t n_sugg_st;
 731                 char **suggs;
 732 
 733                 if (!sugg && ZEND_NUM_ARGS() == 2) {
 734                         RETURN_FALSE;
 735                 }
 736 
 737                 suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg_st);
 738                 memcpy(&n_sugg, &n_sugg_st, sizeof(n_sugg));
 739                 if (suggs && n_sugg) {
 740                         int i;
 741                         for (i = 0; i < n_sugg; i++) {
 742                                 add_next_index_string(sugg, suggs[i]);
 743                         }
 744                         enchant_dict_free_suggestions(pdict->pdict, suggs);
 745                 }
 746 
 747 
 748                 RETURN_FALSE;
 749         }
 750         RETURN_TRUE;
 751 }
 752 /* }}} */
 753 
 754 /* {{{ proto bool enchant_dict_check(resource dict, string word)
 755     If the word is correctly spelled return true, otherwise return false */
 756 PHP_FUNCTION(enchant_dict_check)
 757 {
 758         zval *dict;
 759         char *word;
 760         size_t wordlen;
 761         enchant_dict *pdict;
 762 
 763         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &dict, &word, &wordlen) == FAILURE) {
 764                 RETURN_FALSE;
 765         }
 766 
 767         PHP_ENCHANT_GET_DICT;
 768 
 769         RETURN_BOOL(!enchant_dict_check(pdict->pdict, word, wordlen));
 770 }
 771 /* }}} */
 772 
 773 /* {{{ proto array enchant_dict_suggest(resource dict, string word)
 774     Will return a list of values if any of those pre-conditions are not met.*/
 775 PHP_FUNCTION(enchant_dict_suggest)
 776 {
 777         zval *dict;
 778         char *word;
 779         size_t wordlen;
 780         char **suggs;
 781         enchant_dict *pdict;
 782         int n_sugg;
 783         size_t n_sugg_st;
 784 
 785         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &dict, &word, &wordlen) == FAILURE) {
 786                 RETURN_FALSE;
 787         }
 788 
 789         PHP_ENCHANT_GET_DICT;
 790 
 791         suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg_st);
 792         memcpy(&n_sugg, &n_sugg_st, sizeof(n_sugg));
 793         if (suggs && n_sugg) {
 794                 int i;
 795 
 796                 array_init(return_value);
 797                 for (i = 0; i < n_sugg; i++) {
 798                         add_next_index_string(return_value, suggs[i]);
 799                 }
 800 
 801                 enchant_dict_free_suggestions(pdict->pdict, suggs);
 802         }
 803 }
 804 /* }}} */
 805 
 806 /* {{{ proto void enchant_dict_add_to_personal(resource dict, string word)
 807      add 'word' to personal word list */
 808 PHP_FUNCTION(enchant_dict_add_to_personal)
 809 {
 810         zval *dict;
 811         char *word;
 812         size_t wordlen;
 813         enchant_dict *pdict;
 814 
 815         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &dict, &word, &wordlen) == FAILURE) {
 816                 RETURN_FALSE;
 817         }
 818 
 819         PHP_ENCHANT_GET_DICT;
 820 
 821         enchant_dict_add_to_personal(pdict->pdict, word, wordlen);
 822 }
 823 /* }}} */
 824 
 825 /* {{{ proto void enchant_dict_add_to_session(resource dict, string word)
 826    add 'word' to this spell-checking session */
 827 PHP_FUNCTION(enchant_dict_add_to_session)
 828 {
 829         zval *dict;
 830         char *word;
 831         size_t wordlen;
 832         enchant_dict *pdict;
 833 
 834         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &dict, &word, &wordlen) == FAILURE) {
 835                 RETURN_FALSE;
 836         }
 837 
 838         PHP_ENCHANT_GET_DICT;
 839 
 840         enchant_dict_add_to_session(pdict->pdict, word, wordlen);
 841 }
 842 /* }}} */
 843 
 844 /* {{{ proto bool enchant_dict_is_in_session(resource dict, string word)
 845    whether or not 'word' exists in this spelling-session */
 846 PHP_FUNCTION(enchant_dict_is_in_session)
 847 {
 848         zval *dict;
 849         char *word;
 850         size_t wordlen;
 851         enchant_dict *pdict;
 852 
 853         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &dict, &word, &wordlen) == FAILURE) {
 854                 RETURN_FALSE;
 855         }
 856 
 857         PHP_ENCHANT_GET_DICT;
 858 
 859         RETURN_BOOL(enchant_dict_is_in_session(pdict->pdict, word, wordlen));
 860 }
 861 /* }}} */
 862 
 863 /* {{{ proto void enchant_dict_store_replacement(resource dict, string mis, string cor)
 864         add a correction for 'mis' using 'cor'.
 865         Notes that you replaced @mis with @cor, so it's possibly more likely
 866         that future occurrences of @mis will be replaced with @cor. So it might
 867         bump @cor up in the suggestion list.*/
 868 PHP_FUNCTION(enchant_dict_store_replacement)
 869 {
 870         zval *dict;
 871         char *mis, *cor;
 872         size_t mislen, corlen;
 873 
 874         enchant_dict *pdict;
 875 
 876         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &dict, &mis, &mislen, &cor, &corlen) == FAILURE) {
 877                 RETURN_FALSE;
 878         }
 879 
 880         PHP_ENCHANT_GET_DICT;
 881 
 882         enchant_dict_store_replacement(pdict->pdict, mis, mislen, cor, corlen);
 883 }
 884 /* }}} */
 885 
 886 /* {{{ proto string enchant_dict_get_error(resource dict)
 887    Returns the last error of the current spelling-session */
 888 PHP_FUNCTION(enchant_dict_get_error)
 889 {
 890         zval *dict;
 891         enchant_dict *pdict;
 892         char *msg;
 893 
 894         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &dict) == FAILURE) {
 895                 RETURN_FALSE;
 896         }
 897 
 898         PHP_ENCHANT_GET_DICT;
 899 
 900         msg = enchant_dict_get_error(pdict->pdict);
 901         if (msg) {
 902                 RETURN_STRING((char *)msg);
 903         }
 904 
 905         RETURN_FALSE;
 906 }
 907 /* }}} */
 908 
 909 /* {{{ proto array enchant_dict_describe(resource dict)
 910    Describes an individual dictionary 'dict' */
 911 PHP_FUNCTION(enchant_dict_describe)
 912 {
 913         zval *dict;
 914         enchant_dict *pdict;
 915 
 916         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &dict) == FAILURE) {
 917                 RETURN_FALSE;
 918         }
 919 
 920         PHP_ENCHANT_GET_DICT;
 921 
 922         enchant_dict_describe(pdict->pdict, describe_dict_fn, (void *)return_value);
 923 }
 924 /* }}} */
 925 
 926 /*
 927  * Local variables:
 928  * tab-width: 4
 929  * c-basic-offset: 4
 930  * End:
 931  * vim600: noet sw=4 ts=4 fdm=marker
 932  * vim<600: noet sw=4 ts=4
 933  */

/* [<][>][^][v][top][bottom][index][help] */