Annotation of embedaddon/php/ext/pspell/pspell.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.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: Vlad Krupin <phpdevel@echospace.com> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: pspell.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: #define IS_EXT_MODULE
! 22:
! 23: #ifdef HAVE_CONFIG_H
! 24: #include "config.h"
! 25: #endif
! 26:
! 27: #include "php.h"
! 28:
! 29: #include <stdlib.h>
! 30: #include <ctype.h>
! 31: #include <stdio.h>
! 32:
! 33: #if HAVE_PSPELL
! 34:
! 35: /* this will enforce compatibility in .12 version (broken after .11.2) */
! 36: #define USE_ORIGINAL_MANAGER_FUNCS
! 37:
! 38: #include "php_pspell.h"
! 39: #include <pspell.h>
! 40: #include "ext/standard/info.h"
! 41:
! 42: #define PSPELL_FAST 1L
! 43: #define PSPELL_NORMAL 2L
! 44: #define PSPELL_BAD_SPELLERS 3L
! 45: #define PSPELL_SPEED_MASK_INTERNAL 3L
! 46: #define PSPELL_RUN_TOGETHER 8L
! 47:
! 48: /* Largest ignored word can be 999 characters (this seems sane enough),
! 49: * and it takes 3 bytes to represent that (see pspell_config_ignore)
! 50: */
! 51: #define PSPELL_LARGEST_WORD 3
! 52:
! 53: static PHP_MINIT_FUNCTION(pspell);
! 54: static PHP_MINFO_FUNCTION(pspell);
! 55: static PHP_FUNCTION(pspell_new);
! 56: static PHP_FUNCTION(pspell_new_personal);
! 57: static PHP_FUNCTION(pspell_new_config);
! 58: static PHP_FUNCTION(pspell_check);
! 59: static PHP_FUNCTION(pspell_suggest);
! 60: static PHP_FUNCTION(pspell_store_replacement);
! 61: static PHP_FUNCTION(pspell_add_to_personal);
! 62: static PHP_FUNCTION(pspell_add_to_session);
! 63: static PHP_FUNCTION(pspell_clear_session);
! 64: static PHP_FUNCTION(pspell_save_wordlist);
! 65: static PHP_FUNCTION(pspell_config_create);
! 66: static PHP_FUNCTION(pspell_config_runtogether);
! 67: static PHP_FUNCTION(pspell_config_mode);
! 68: static PHP_FUNCTION(pspell_config_ignore);
! 69: static PHP_FUNCTION(pspell_config_personal);
! 70: static PHP_FUNCTION(pspell_config_dict_dir);
! 71: static PHP_FUNCTION(pspell_config_data_dir);
! 72: static PHP_FUNCTION(pspell_config_repl);
! 73: static PHP_FUNCTION(pspell_config_save_repl);
! 74:
! 75: /* {{{ arginfo */
! 76: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_new, 0, 0, 1)
! 77: ZEND_ARG_INFO(0, language)
! 78: ZEND_ARG_INFO(0, spelling)
! 79: ZEND_ARG_INFO(0, jargon)
! 80: ZEND_ARG_INFO(0, encoding)
! 81: ZEND_ARG_INFO(0, mode)
! 82: ZEND_END_ARG_INFO()
! 83:
! 84: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_new_personal, 0, 0, 2)
! 85: ZEND_ARG_INFO(0, personal)
! 86: ZEND_ARG_INFO(0, language)
! 87: ZEND_ARG_INFO(0, spelling)
! 88: ZEND_ARG_INFO(0, jargon)
! 89: ZEND_ARG_INFO(0, encoding)
! 90: ZEND_ARG_INFO(0, mode)
! 91: ZEND_END_ARG_INFO()
! 92:
! 93: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_new_config, 0, 0, 1)
! 94: ZEND_ARG_INFO(0, config)
! 95: ZEND_END_ARG_INFO()
! 96:
! 97: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_check, 0, 0, 2)
! 98: ZEND_ARG_INFO(0, pspell)
! 99: ZEND_ARG_INFO(0, word)
! 100: ZEND_END_ARG_INFO()
! 101:
! 102: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_suggest, 0, 0, 2)
! 103: ZEND_ARG_INFO(0, pspell)
! 104: ZEND_ARG_INFO(0, word)
! 105: ZEND_END_ARG_INFO()
! 106:
! 107: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_store_replacement, 0, 0, 3)
! 108: ZEND_ARG_INFO(0, pspell)
! 109: ZEND_ARG_INFO(0, misspell)
! 110: ZEND_ARG_INFO(0, correct)
! 111: ZEND_END_ARG_INFO()
! 112:
! 113: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_add_to_personal, 0, 0, 2)
! 114: ZEND_ARG_INFO(0, pspell)
! 115: ZEND_ARG_INFO(0, word)
! 116: ZEND_END_ARG_INFO()
! 117:
! 118: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_add_to_session, 0, 0, 2)
! 119: ZEND_ARG_INFO(0, pspell)
! 120: ZEND_ARG_INFO(0, word)
! 121: ZEND_END_ARG_INFO()
! 122:
! 123: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_clear_session, 0, 0, 1)
! 124: ZEND_ARG_INFO(0, pspell)
! 125: ZEND_END_ARG_INFO()
! 126:
! 127: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_save_wordlist, 0, 0, 1)
! 128: ZEND_ARG_INFO(0, pspell)
! 129: ZEND_END_ARG_INFO()
! 130:
! 131: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_create, 0, 0, 1)
! 132: ZEND_ARG_INFO(0, language)
! 133: ZEND_ARG_INFO(0, spelling)
! 134: ZEND_ARG_INFO(0, jargon)
! 135: ZEND_ARG_INFO(0, encoding)
! 136: ZEND_END_ARG_INFO()
! 137:
! 138: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_runtogether, 0, 0, 2)
! 139: ZEND_ARG_INFO(0, conf)
! 140: ZEND_ARG_INFO(0, runtogether)
! 141: ZEND_END_ARG_INFO()
! 142:
! 143: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_mode, 0, 0, 2)
! 144: ZEND_ARG_INFO(0, conf)
! 145: ZEND_ARG_INFO(0, mode)
! 146: ZEND_END_ARG_INFO()
! 147:
! 148: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_ignore, 0, 0, 2)
! 149: ZEND_ARG_INFO(0, conf)
! 150: ZEND_ARG_INFO(0, ignore)
! 151: ZEND_END_ARG_INFO()
! 152:
! 153: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_personal, 0, 0, 2)
! 154: ZEND_ARG_INFO(0, conf)
! 155: ZEND_ARG_INFO(0, personal)
! 156: ZEND_END_ARG_INFO()
! 157:
! 158: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_dict_dir, 0, 0, 2)
! 159: ZEND_ARG_INFO(0, conf)
! 160: ZEND_ARG_INFO(0, directory)
! 161: ZEND_END_ARG_INFO()
! 162:
! 163: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_data_dir, 0, 0, 2)
! 164: ZEND_ARG_INFO(0, conf)
! 165: ZEND_ARG_INFO(0, directory)
! 166: ZEND_END_ARG_INFO()
! 167:
! 168: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_repl, 0, 0, 2)
! 169: ZEND_ARG_INFO(0, conf)
! 170: ZEND_ARG_INFO(0, repl)
! 171: ZEND_END_ARG_INFO()
! 172:
! 173: ZEND_BEGIN_ARG_INFO_EX(arginfo_pspell_config_save_repl, 0, 0, 2)
! 174: ZEND_ARG_INFO(0, conf)
! 175: ZEND_ARG_INFO(0, save)
! 176: ZEND_END_ARG_INFO()
! 177: /* }}} */
! 178:
! 179: /* {{{ pspell_functions[]
! 180: */
! 181: static const zend_function_entry pspell_functions[] = {
! 182: PHP_FE(pspell_new, arginfo_pspell_new)
! 183: PHP_FE(pspell_new_personal, arginfo_pspell_new_personal)
! 184: PHP_FE(pspell_new_config, arginfo_pspell_new_config)
! 185: PHP_FE(pspell_check, arginfo_pspell_check)
! 186: PHP_FE(pspell_suggest, arginfo_pspell_suggest)
! 187: PHP_FE(pspell_store_replacement, arginfo_pspell_store_replacement)
! 188: PHP_FE(pspell_add_to_personal, arginfo_pspell_add_to_personal)
! 189: PHP_FE(pspell_add_to_session, arginfo_pspell_add_to_session)
! 190: PHP_FE(pspell_clear_session, arginfo_pspell_clear_session)
! 191: PHP_FE(pspell_save_wordlist, arginfo_pspell_save_wordlist)
! 192: PHP_FE(pspell_config_create, arginfo_pspell_config_create)
! 193: PHP_FE(pspell_config_runtogether, arginfo_pspell_config_runtogether)
! 194: PHP_FE(pspell_config_mode, arginfo_pspell_config_mode)
! 195: PHP_FE(pspell_config_ignore, arginfo_pspell_config_ignore)
! 196: PHP_FE(pspell_config_personal, arginfo_pspell_config_personal)
! 197: PHP_FE(pspell_config_dict_dir, arginfo_pspell_config_dict_dir)
! 198: PHP_FE(pspell_config_data_dir, arginfo_pspell_config_data_dir)
! 199: PHP_FE(pspell_config_repl, arginfo_pspell_config_repl)
! 200: PHP_FE(pspell_config_save_repl, arginfo_pspell_config_save_repl)
! 201: PHP_FE_END
! 202: };
! 203: /* }}} */
! 204:
! 205: static int le_pspell, le_pspell_config;
! 206:
! 207: zend_module_entry pspell_module_entry = {
! 208: STANDARD_MODULE_HEADER,
! 209: "pspell", pspell_functions, PHP_MINIT(pspell), NULL, NULL, NULL, PHP_MINFO(pspell), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
! 210: };
! 211:
! 212: #ifdef COMPILE_DL_PSPELL
! 213: ZEND_GET_MODULE(pspell)
! 214: #endif
! 215:
! 216: static void php_pspell_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
! 217: {
! 218: PspellManager *manager = (PspellManager *)rsrc->ptr;
! 219:
! 220: delete_pspell_manager(manager);
! 221: }
! 222:
! 223: static void php_pspell_close_config(zend_rsrc_list_entry *rsrc TSRMLS_DC)
! 224: {
! 225: PspellConfig *config = (PspellConfig *)rsrc->ptr;
! 226:
! 227: delete_pspell_config(config);
! 228: }
! 229:
! 230: #define PSPELL_FETCH_CONFIG \
! 231: config = (PspellConfig *) zend_list_find(conf, &type); \
! 232: if (config == NULL || type != le_pspell_config) { \
! 233: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%ld is not a PSPELL config index", conf); \
! 234: RETURN_FALSE; \
! 235: } \
! 236:
! 237: #define PSPELL_FETCH_MANAGER \
! 238: manager = (PspellManager *) zend_list_find(scin, &type); \
! 239: if (!manager || type != le_pspell) { \
! 240: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%ld is not a PSPELL result index", scin); \
! 241: RETURN_FALSE; \
! 242: } \
! 243:
! 244: /* {{{ PHP_MINIT_FUNCTION
! 245: */
! 246: static PHP_MINIT_FUNCTION(pspell)
! 247: {
! 248: REGISTER_LONG_CONSTANT("PSPELL_FAST", PSPELL_FAST, CONST_PERSISTENT | CONST_CS);
! 249: REGISTER_LONG_CONSTANT("PSPELL_NORMAL", PSPELL_NORMAL, CONST_PERSISTENT | CONST_CS);
! 250: REGISTER_LONG_CONSTANT("PSPELL_BAD_SPELLERS", PSPELL_BAD_SPELLERS, CONST_PERSISTENT | CONST_CS);
! 251: REGISTER_LONG_CONSTANT("PSPELL_RUN_TOGETHER", PSPELL_RUN_TOGETHER, CONST_PERSISTENT | CONST_CS);
! 252: le_pspell = zend_register_list_destructors_ex(php_pspell_close, NULL, "pspell", module_number);
! 253: le_pspell_config = zend_register_list_destructors_ex(php_pspell_close_config, NULL, "pspell config", module_number);
! 254: return SUCCESS;
! 255: }
! 256: /* }}} */
! 257:
! 258: /* {{{ proto int pspell_new(string language [, string spelling [, string jargon [, string encoding [, int mode]]]])
! 259: Load a dictionary */
! 260: static PHP_FUNCTION(pspell_new)
! 261: {
! 262: char *language, *spelling = NULL, *jargon = NULL, *encoding = NULL;
! 263: int language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0;
! 264: long mode = 0L, speed = 0L;
! 265: int argc = ZEND_NUM_ARGS();
! 266: int ind;
! 267:
! 268: #ifdef PHP_WIN32
! 269: TCHAR aspell_dir[200];
! 270: TCHAR data_dir[220];
! 271: TCHAR dict_dir[220];
! 272: HKEY hkey;
! 273: DWORD dwType,dwLen;
! 274: #endif
! 275:
! 276: PspellCanHaveError *ret;
! 277: PspellManager *manager;
! 278: PspellConfig *config;
! 279:
! 280: if (zend_parse_parameters(argc TSRMLS_CC, "s|sssl", &language, &language_len, &spelling, &spelling_len,
! 281: &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) {
! 282: return;
! 283: }
! 284:
! 285: config = new_pspell_config();
! 286:
! 287: #ifdef PHP_WIN32
! 288: /* If aspell was installed using installer, we should have a key
! 289: * pointing to the location of the dictionaries
! 290: */
! 291: if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) {
! 292: LONG result;
! 293: dwLen = sizeof(aspell_dir) - 1;
! 294: result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen);
! 295: RegCloseKey(hkey);
! 296: if (result == ERROR_SUCCESS) {
! 297: strlcpy(data_dir, aspell_dir, sizeof(data_dir));
! 298: strlcat(data_dir, "\\data", sizeof(data_dir));
! 299: strlcpy(dict_dir, aspell_dir, sizeof(dict_dir));
! 300: strlcat(dict_dir, "\\dict", sizeof(dict_dir));
! 301:
! 302: pspell_config_replace(config, "data-dir", data_dir);
! 303: pspell_config_replace(config, "dict-dir", dict_dir);
! 304: }
! 305: }
! 306: #endif
! 307:
! 308: pspell_config_replace(config, "language-tag", language);
! 309:
! 310: if (spelling_len) {
! 311: pspell_config_replace(config, "spelling", spelling);
! 312: }
! 313:
! 314: if (jargon_len) {
! 315: pspell_config_replace(config, "jargon", jargon);
! 316: }
! 317:
! 318: if (encoding_len) {
! 319: pspell_config_replace(config, "encoding", encoding);
! 320: }
! 321:
! 322: if (argc > 4) {
! 323: speed = mode & PSPELL_SPEED_MASK_INTERNAL;
! 324:
! 325: /* First check what mode we want (how many suggestions) */
! 326: if (speed == PSPELL_FAST) {
! 327: pspell_config_replace(config, "sug-mode", "fast");
! 328: } else if (speed == PSPELL_NORMAL) {
! 329: pspell_config_replace(config, "sug-mode", "normal");
! 330: } else if (speed == PSPELL_BAD_SPELLERS) {
! 331: pspell_config_replace(config, "sug-mode", "bad-spellers");
! 332: }
! 333:
! 334: /* Then we see if run-together words should be treated as valid components */
! 335: if (mode & PSPELL_RUN_TOGETHER) {
! 336: pspell_config_replace(config, "run-together", "true");
! 337: }
! 338: }
! 339:
! 340: ret = new_pspell_manager(config);
! 341: delete_pspell_config(config);
! 342:
! 343: if (pspell_error_number(ret) != 0) {
! 344: php_error_docref(NULL TSRMLS_CC, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret));
! 345: delete_pspell_can_have_error(ret);
! 346: RETURN_FALSE;
! 347: }
! 348:
! 349: manager = to_pspell_manager(ret);
! 350: ind = zend_list_insert(manager, le_pspell);
! 351: RETURN_LONG(ind);
! 352: }
! 353: /* }}} */
! 354:
! 355: /* {{{ proto int pspell_new_personal(string personal, string language [, string spelling [, string jargon [, string encoding [, int mode]]]])
! 356: Load a dictionary with a personal wordlist*/
! 357: static PHP_FUNCTION(pspell_new_personal)
! 358: {
! 359: char *personal, *language, *spelling = NULL, *jargon = NULL, *encoding = NULL;
! 360: int personal_len, language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0;
! 361: long mode = 0L, speed = 0L;
! 362: int argc = ZEND_NUM_ARGS();
! 363: int ind;
! 364:
! 365: #ifdef PHP_WIN32
! 366: TCHAR aspell_dir[200];
! 367: TCHAR data_dir[220];
! 368: TCHAR dict_dir[220];
! 369: HKEY hkey;
! 370: DWORD dwType,dwLen;
! 371: #endif
! 372:
! 373: PspellCanHaveError *ret;
! 374: PspellManager *manager;
! 375: PspellConfig *config;
! 376:
! 377: if (zend_parse_parameters(argc TSRMLS_CC, "ss|sssl", &personal, &personal_len, &language, &language_len,
! 378: &spelling, &spelling_len, &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) {
! 379: return;
! 380: }
! 381:
! 382: config = new_pspell_config();
! 383:
! 384: #ifdef PHP_WIN32
! 385: /* If aspell was installed using installer, we should have a key
! 386: * pointing to the location of the dictionaries
! 387: */
! 388: if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) {
! 389: LONG result;
! 390: dwLen = sizeof(aspell_dir) - 1;
! 391: result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen);
! 392: RegCloseKey(hkey);
! 393: if (result == ERROR_SUCCESS) {
! 394: strlcpy(data_dir, aspell_dir, sizeof(data_dir));
! 395: strlcat(data_dir, "\\data", sizeof(data_dir));
! 396: strlcpy(dict_dir, aspell_dir, sizeof(dict_dir));
! 397: strlcat(dict_dir, "\\dict", sizeof(dict_dir));
! 398:
! 399: pspell_config_replace(config, "data-dir", data_dir);
! 400: pspell_config_replace(config, "dict-dir", dict_dir);
! 401: }
! 402: }
! 403: #endif
! 404:
! 405: if (strlen(personal) != personal_len) {
! 406: delete_pspell_config(config);
! 407: RETURN_FALSE;
! 408: }
! 409:
! 410: if (PG(safe_mode) && (!php_checkuid(personal, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
! 411: delete_pspell_config(config);
! 412: RETURN_FALSE;
! 413: }
! 414:
! 415: if (php_check_open_basedir(personal TSRMLS_CC)) {
! 416: delete_pspell_config(config);
! 417: RETURN_FALSE;
! 418: }
! 419:
! 420: pspell_config_replace(config, "personal", personal);
! 421: pspell_config_replace(config, "save-repl", "false");
! 422:
! 423: pspell_config_replace(config, "language-tag", language);
! 424:
! 425: if (spelling_len) {
! 426: pspell_config_replace(config, "spelling", spelling);
! 427: }
! 428:
! 429: if (jargon_len) {
! 430: pspell_config_replace(config, "jargon", jargon);
! 431: }
! 432:
! 433: if (encoding_len) {
! 434: pspell_config_replace(config, "encoding", encoding);
! 435: }
! 436:
! 437: if (argc > 5) {
! 438: speed = mode & PSPELL_SPEED_MASK_INTERNAL;
! 439:
! 440: /* First check what mode we want (how many suggestions) */
! 441: if (speed == PSPELL_FAST) {
! 442: pspell_config_replace(config, "sug-mode", "fast");
! 443: } else if (speed == PSPELL_NORMAL) {
! 444: pspell_config_replace(config, "sug-mode", "normal");
! 445: } else if (speed == PSPELL_BAD_SPELLERS) {
! 446: pspell_config_replace(config, "sug-mode", "bad-spellers");
! 447: }
! 448:
! 449: /* Then we see if run-together words should be treated as valid components */
! 450: if (mode & PSPELL_RUN_TOGETHER) {
! 451: pspell_config_replace(config, "run-together", "true");
! 452: }
! 453: }
! 454:
! 455: ret = new_pspell_manager(config);
! 456: delete_pspell_config(config);
! 457:
! 458: if (pspell_error_number(ret) != 0) {
! 459: php_error_docref(NULL TSRMLS_CC, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret));
! 460: delete_pspell_can_have_error(ret);
! 461: RETURN_FALSE;
! 462: }
! 463:
! 464: manager = to_pspell_manager(ret);
! 465: ind = zend_list_insert(manager, le_pspell);
! 466: RETURN_LONG(ind);
! 467: }
! 468: /* }}} */
! 469:
! 470: /* {{{ proto int pspell_new_config(int config)
! 471: Load a dictionary based on the given config */
! 472: static PHP_FUNCTION(pspell_new_config)
! 473: {
! 474: int type, ind;
! 475: long conf;
! 476: PspellCanHaveError *ret;
! 477: PspellManager *manager;
! 478: PspellConfig *config;
! 479:
! 480: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &conf) == FAILURE) {
! 481: return;
! 482: }
! 483:
! 484: PSPELL_FETCH_CONFIG;
! 485:
! 486: ret = new_pspell_manager(config);
! 487:
! 488: if (pspell_error_number(ret) != 0) {
! 489: php_error_docref(NULL TSRMLS_CC, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret));
! 490: delete_pspell_can_have_error(ret);
! 491: RETURN_FALSE;
! 492: }
! 493:
! 494: manager = to_pspell_manager(ret);
! 495: ind = zend_list_insert(manager, le_pspell);
! 496: RETURN_LONG(ind);
! 497: }
! 498: /* }}} */
! 499:
! 500: /* {{{ proto bool pspell_check(int pspell, string word)
! 501: Returns true if word is valid */
! 502: static PHP_FUNCTION(pspell_check)
! 503: {
! 504: int type, word_len;
! 505: long scin;
! 506: char *word;
! 507: PspellManager *manager;
! 508:
! 509: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &scin, &word, &word_len) == FAILURE) {
! 510: return;
! 511: }
! 512:
! 513: PSPELL_FETCH_MANAGER;
! 514:
! 515: if (pspell_manager_check(manager, word)) {
! 516: RETURN_TRUE;
! 517: } else {
! 518: RETURN_FALSE;
! 519: }
! 520: }
! 521: /* }}} */
! 522:
! 523: /* {{{ proto array pspell_suggest(int pspell, string word)
! 524: Returns array of suggestions */
! 525: static PHP_FUNCTION(pspell_suggest)
! 526: {
! 527: long scin;
! 528: char *word;
! 529: int word_len;
! 530: PspellManager *manager;
! 531: int type;
! 532: const PspellWordList *wl;
! 533: const char *sug;
! 534:
! 535: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &scin, &word, &word_len) == FAILURE) {
! 536: return;
! 537: }
! 538:
! 539: PSPELL_FETCH_MANAGER;
! 540:
! 541: array_init(return_value);
! 542:
! 543: wl = pspell_manager_suggest(manager, word);
! 544: if (wl) {
! 545: PspellStringEmulation *els = pspell_word_list_elements(wl);
! 546: while ((sug = pspell_string_emulation_next(els)) != 0) {
! 547: add_next_index_string(return_value,(char *)sug,1);
! 548: }
! 549: delete_pspell_string_emulation(els);
! 550: } else {
! 551: php_error_docref(NULL TSRMLS_CC, E_WARNING, "PSPELL had a problem. details: %s", pspell_manager_error_message(manager));
! 552: RETURN_FALSE;
! 553: }
! 554: }
! 555: /* }}} */
! 556:
! 557: /* {{{ proto bool pspell_store_replacement(int pspell, string misspell, string correct)
! 558: Notify the dictionary of a user-selected replacement */
! 559: static PHP_FUNCTION(pspell_store_replacement)
! 560: {
! 561: int type, miss_len, corr_len;
! 562: long scin;
! 563: char *miss, *corr;
! 564: PspellManager *manager;
! 565:
! 566: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lss", &scin, &miss, &miss_len, &corr, &corr_len) == FAILURE) {
! 567: return;
! 568: }
! 569:
! 570: PSPELL_FETCH_MANAGER;
! 571:
! 572: pspell_manager_store_replacement(manager, miss, corr);
! 573: if (pspell_manager_error_number(manager) == 0) {
! 574: RETURN_TRUE;
! 575: } else {
! 576: php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_store_replacement() gave error: %s", pspell_manager_error_message(manager));
! 577: RETURN_FALSE;
! 578: }
! 579: }
! 580: /* }}} */
! 581:
! 582: /* {{{ proto bool pspell_add_to_personal(int pspell, string word)
! 583: Adds a word to a personal list */
! 584: static PHP_FUNCTION(pspell_add_to_personal)
! 585: {
! 586: int type, word_len;
! 587: long scin;
! 588: char *word;
! 589: PspellManager *manager;
! 590:
! 591: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &scin, &word, &word_len) == FAILURE) {
! 592: return;
! 593: }
! 594:
! 595: PSPELL_FETCH_MANAGER;
! 596:
! 597: /*If the word is empty, we have to return; otherwise we'll segfault! ouch!*/
! 598: if (word_len == 0) {
! 599: RETURN_FALSE;
! 600: }
! 601:
! 602: pspell_manager_add_to_personal(manager, word);
! 603: if (pspell_manager_error_number(manager) == 0) {
! 604: RETURN_TRUE;
! 605: } else {
! 606: php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_add_to_personal() gave error: %s", pspell_manager_error_message(manager));
! 607: RETURN_FALSE;
! 608: }
! 609: }
! 610: /* }}} */
! 611:
! 612: /* {{{ proto bool pspell_add_to_session(int pspell, string word)
! 613: Adds a word to the current session */
! 614: static PHP_FUNCTION(pspell_add_to_session)
! 615: {
! 616: int type, word_len;
! 617: long scin;
! 618: char *word;
! 619: PspellManager *manager;
! 620:
! 621: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &scin, &word, &word_len) == FAILURE) {
! 622: return;
! 623: }
! 624:
! 625: PSPELL_FETCH_MANAGER;
! 626:
! 627: /*If the word is empty, we have to return; otherwise we'll segfault! ouch!*/
! 628: if (word_len == 0) {
! 629: RETURN_FALSE;
! 630: }
! 631:
! 632: pspell_manager_add_to_session(manager, word);
! 633: if (pspell_manager_error_number(manager) == 0) {
! 634: RETURN_TRUE;
! 635: } else {
! 636: php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_add_to_session() gave error: %s", pspell_manager_error_message(manager));
! 637: RETURN_FALSE;
! 638: }
! 639: }
! 640: /* }}} */
! 641:
! 642: /* {{{ proto bool pspell_clear_session(int pspell)
! 643: Clears the current session */
! 644: static PHP_FUNCTION(pspell_clear_session)
! 645: {
! 646: int type;
! 647: long scin;
! 648: PspellManager *manager;
! 649:
! 650: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &scin) == FAILURE) {
! 651: return;
! 652: }
! 653:
! 654: PSPELL_FETCH_MANAGER;
! 655:
! 656: pspell_manager_clear_session(manager);
! 657: if (pspell_manager_error_number(manager) == 0) {
! 658: RETURN_TRUE;
! 659: } else {
! 660: php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_clear_session() gave error: %s", pspell_manager_error_message(manager));
! 661: RETURN_FALSE;
! 662: }
! 663: }
! 664: /* }}} */
! 665:
! 666: /* {{{ proto bool pspell_save_wordlist(int pspell)
! 667: Saves the current (personal) wordlist */
! 668: static PHP_FUNCTION(pspell_save_wordlist)
! 669: {
! 670: int type;
! 671: long scin;
! 672: PspellManager *manager;
! 673:
! 674: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &scin) == FAILURE) {
! 675: return;
! 676: }
! 677:
! 678: PSPELL_FETCH_MANAGER;
! 679:
! 680: pspell_manager_save_all_word_lists(manager);
! 681:
! 682: if (pspell_manager_error_number(manager) == 0) {
! 683: RETURN_TRUE;
! 684: } else {
! 685: php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_save_wordlist() gave error: %s", pspell_manager_error_message(manager));
! 686: RETURN_FALSE;
! 687: }
! 688:
! 689: }
! 690: /* }}} */
! 691:
! 692: /* {{{ proto int pspell_config_create(string language [, string spelling [, string jargon [, string encoding]]])
! 693: Create a new config to be used later to create a manager */
! 694: static PHP_FUNCTION(pspell_config_create)
! 695: {
! 696: char *language, *spelling = NULL, *jargon = NULL, *encoding = NULL;
! 697: int language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0;
! 698: int ind;
! 699: PspellConfig *config;
! 700:
! 701: #ifdef PHP_WIN32
! 702: TCHAR aspell_dir[200];
! 703: TCHAR data_dir[220];
! 704: TCHAR dict_dir[220];
! 705: HKEY hkey;
! 706: DWORD dwType,dwLen;
! 707: #endif
! 708:
! 709: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sss", &language, &language_len, &spelling, &spelling_len,
! 710: &jargon, &jargon_len, &encoding, &encoding_len) == FAILURE) {
! 711: return;
! 712: }
! 713:
! 714: config = new_pspell_config();
! 715:
! 716: #ifdef PHP_WIN32
! 717: /* If aspell was installed using installer, we should have a key
! 718: * pointing to the location of the dictionaries
! 719: */
! 720: if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) {
! 721: LONG result;
! 722: dwLen = sizeof(aspell_dir) - 1;
! 723: result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen);
! 724: RegCloseKey(hkey);
! 725: if (result == ERROR_SUCCESS) {
! 726: strlcpy(data_dir, aspell_dir, sizeof(data_dir));
! 727: strlcat(data_dir, "\\data", sizeof(data_dir));
! 728: strlcpy(dict_dir, aspell_dir, sizeof(dict_dir));
! 729: strlcat(dict_dir, "\\dict", sizeof(dict_dir));
! 730:
! 731: pspell_config_replace(config, "data-dir", data_dir);
! 732: pspell_config_replace(config, "dict-dir", dict_dir);
! 733: }
! 734: }
! 735: #endif
! 736:
! 737: pspell_config_replace(config, "language-tag", language);
! 738:
! 739: if (spelling_len) {
! 740: pspell_config_replace(config, "spelling", spelling);
! 741: }
! 742:
! 743: if (jargon_len) {
! 744: pspell_config_replace(config, "jargon", jargon);
! 745: }
! 746:
! 747: if (encoding_len) {
! 748: pspell_config_replace(config, "encoding", encoding);
! 749: }
! 750:
! 751: /* By default I do not want to write anything anywhere because it'll try to write to $HOME
! 752: which is not what we want */
! 753: pspell_config_replace(config, "save-repl", "false");
! 754:
! 755: ind = zend_list_insert(config, le_pspell_config);
! 756: RETURN_LONG(ind);
! 757: }
! 758: /* }}} */
! 759:
! 760: /* {{{ proto bool pspell_config_runtogether(int conf, bool runtogether)
! 761: Consider run-together words as valid components */
! 762: static PHP_FUNCTION(pspell_config_runtogether)
! 763: {
! 764: int type;
! 765: long conf;
! 766: zend_bool runtogether;
! 767: PspellConfig *config;
! 768:
! 769: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb", &conf, &runtogether) == FAILURE) {
! 770: return;
! 771: }
! 772:
! 773: PSPELL_FETCH_CONFIG;
! 774:
! 775: pspell_config_replace(config, "run-together", runtogether ? "true" : "false");
! 776:
! 777: RETURN_TRUE;
! 778: }
! 779: /* }}} */
! 780:
! 781: /* {{{ proto bool pspell_config_mode(int conf, long mode)
! 782: Select mode for config (PSPELL_FAST, PSPELL_NORMAL or PSPELL_BAD_SPELLERS) */
! 783: static PHP_FUNCTION(pspell_config_mode)
! 784: {
! 785: int type;
! 786: long conf, mode;
! 787: PspellConfig *config;
! 788:
! 789: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &conf, &mode) == FAILURE) {
! 790: return;
! 791: }
! 792:
! 793: PSPELL_FETCH_CONFIG;
! 794:
! 795: /* First check what mode we want (how many suggestions) */
! 796: if (mode == PSPELL_FAST) {
! 797: pspell_config_replace(config, "sug-mode", "fast");
! 798: } else if (mode == PSPELL_NORMAL) {
! 799: pspell_config_replace(config, "sug-mode", "normal");
! 800: } else if (mode == PSPELL_BAD_SPELLERS) {
! 801: pspell_config_replace(config, "sug-mode", "bad-spellers");
! 802: }
! 803:
! 804: RETURN_TRUE;
! 805: }
! 806: /* }}} */
! 807:
! 808: /* {{{ proto bool pspell_config_ignore(int conf, int ignore)
! 809: Ignore words <= n chars */
! 810: static PHP_FUNCTION(pspell_config_ignore)
! 811: {
! 812: int type;
! 813: char ignore_str[MAX_LENGTH_OF_LONG + 1];
! 814: long conf, ignore = 0L;
! 815: PspellConfig *config;
! 816:
! 817: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &conf, &ignore) == FAILURE) {
! 818: return;
! 819: }
! 820:
! 821: PSPELL_FETCH_CONFIG;
! 822:
! 823: snprintf(ignore_str, sizeof(ignore_str), "%ld", ignore);
! 824:
! 825: pspell_config_replace(config, "ignore", ignore_str);
! 826: RETURN_TRUE;
! 827: }
! 828: /* }}} */
! 829:
! 830: static void pspell_config_path(INTERNAL_FUNCTION_PARAMETERS, char *option)
! 831: {
! 832: int type;
! 833: long conf;
! 834: char *value;
! 835: int value_len;
! 836: PspellConfig *config;
! 837:
! 838: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &conf, &value, &value_len) == FAILURE) {
! 839: return;
! 840: }
! 841:
! 842: if (strlen(value) != value_len) {
! 843: RETURN_FALSE;
! 844: }
! 845:
! 846: PSPELL_FETCH_CONFIG;
! 847:
! 848: if (PG(safe_mode) && (!php_checkuid(value, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
! 849: RETURN_FALSE;
! 850: }
! 851:
! 852: if (php_check_open_basedir(value TSRMLS_CC)) {
! 853: RETURN_FALSE;
! 854: }
! 855:
! 856: pspell_config_replace(config, option, value);
! 857:
! 858: RETURN_TRUE;
! 859: }
! 860:
! 861: /* {{{ proto bool pspell_config_personal(int conf, string personal)
! 862: Use a personal dictionary for this config */
! 863: static PHP_FUNCTION(pspell_config_personal)
! 864: {
! 865: pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "personal");
! 866: }
! 867: /* }}} */
! 868:
! 869: /* {{{ proto bool pspell_config_dict_dir(int conf, string directory)
! 870: location of the main word list */
! 871: static PHP_FUNCTION(pspell_config_dict_dir)
! 872: {
! 873: pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "dict-dir");
! 874: }
! 875: /* }}} */
! 876:
! 877: /* {{{ proto bool pspell_config_data_dir(int conf, string directory)
! 878: location of language data files */
! 879: static PHP_FUNCTION(pspell_config_data_dir)
! 880: {
! 881: pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "data-dir");
! 882: }
! 883: /* }}} */
! 884:
! 885: /* {{{ proto bool pspell_config_repl(int conf, string repl)
! 886: Use a personal dictionary with replacement pairs for this config */
! 887: static PHP_FUNCTION(pspell_config_repl)
! 888: {
! 889: int type;
! 890: long conf;
! 891: char *repl;
! 892: int repl_len;
! 893: PspellConfig *config;
! 894:
! 895: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &conf, &repl, &repl_len) == FAILURE) {
! 896: return;
! 897: }
! 898:
! 899: PSPELL_FETCH_CONFIG;
! 900:
! 901: pspell_config_replace(config, "save-repl", "true");
! 902:
! 903: if (strlen(repl) != repl_len) {
! 904: RETURN_FALSE;
! 905: }
! 906:
! 907: if (PG(safe_mode) && (!php_checkuid(repl, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
! 908: RETURN_FALSE;
! 909: }
! 910:
! 911: if (php_check_open_basedir(repl TSRMLS_CC)) {
! 912: RETURN_FALSE;
! 913: }
! 914:
! 915: pspell_config_replace(config, "repl", repl);
! 916:
! 917: RETURN_TRUE;
! 918: }
! 919: /* }}} */
! 920:
! 921: /* {{{ proto bool pspell_config_save_repl(int conf, bool save)
! 922: Save replacement pairs when personal list is saved for this config */
! 923: static PHP_FUNCTION(pspell_config_save_repl)
! 924: {
! 925: int type;
! 926: long conf;
! 927: zend_bool save;
! 928: PspellConfig *config;
! 929:
! 930: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb", &conf, &save) == FAILURE) {
! 931: return;
! 932: }
! 933:
! 934: PSPELL_FETCH_CONFIG;
! 935:
! 936: pspell_config_replace(config, "save-repl", save ? "true" : "false");
! 937:
! 938: RETURN_TRUE;
! 939: }
! 940: /* }}} */
! 941:
! 942: /* {{{ PHP_MINFO_FUNCTION
! 943: */
! 944: static PHP_MINFO_FUNCTION(pspell)
! 945: {
! 946: php_info_print_table_start();
! 947: php_info_print_table_row(2, "PSpell Support", "enabled");
! 948: php_info_print_table_end();
! 949: }
! 950: /* }}} */
! 951:
! 952: #endif
! 953:
! 954: /*
! 955: * Local variables:
! 956: * tab-width: 4
! 957: * c-basic-offset: 4
! 958: * End:
! 959: * vim600: sw=4 ts=4 fdm=marker
! 960: * vim<600: sw=4 ts=4
! 961: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>