Return to pspell.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / pspell |
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: */