diff options
Diffstat (limited to 'ext/pspell/pspell.c')
-rw-r--r-- | ext/pspell/pspell.c | 309 |
1 files changed, 181 insertions, 128 deletions
diff --git a/ext/pspell/pspell.c b/ext/pspell/pspell.c index 63732b77b0..8975519955 100644 --- a/ext/pspell/pspell.c +++ b/ext/pspell/pspell.c @@ -19,6 +19,7 @@ #endif #include "php.h" +#include "zend_interfaces.h" #include <stdlib.h> #include <ctype.h> @@ -48,58 +49,139 @@ static PHP_MINIT_FUNCTION(pspell); static PHP_MINFO_FUNCTION(pspell); -static int le_pspell, le_pspell_config; +static zend_class_entry *php_pspell_ce = NULL; +static zend_object_handlers php_pspell_handlers; +static zend_class_entry *php_pspell_config_ce = NULL; +static zend_object_handlers php_pspell_config_handlers; zend_module_entry pspell_module_entry = { STANDARD_MODULE_HEADER, - "pspell", ext_functions, PHP_MINIT(pspell), NULL, NULL, NULL, PHP_MINFO(pspell), PHP_PSPELL_VERSION, STANDARD_MODULE_PROPERTIES + "pspell", + ext_functions, + PHP_MINIT(pspell), + NULL, + NULL, + NULL, + PHP_MINFO(pspell), + PHP_PSPELL_VERSION, + STANDARD_MODULE_PROPERTIES, }; #ifdef COMPILE_DL_PSPELL ZEND_GET_MODULE(pspell) #endif -static void php_pspell_close(zend_resource *rsrc) +/* class PSpell */ + +typedef struct _php_pspell_object { + PspellManager *mgr; + zend_object std; +} php_pspell_object; + +static php_pspell_object *php_pspell_object_from_zend_object(zend_object *zobj) { + return ((php_pspell_object*)(zobj + 1)) - 1; +} + +static zend_object *php_pspell_object_to_zend_object(php_pspell_object *obj) { + return ((zend_object*)(obj + 1)) - 1; +} + +static zend_function *php_pspell_object_get_constructor(zend_object *object) { - PspellManager *manager = (PspellManager *)rsrc->ptr; + zend_throw_error(NULL, "You cannot initialize a PSpell object except through helper functions"); + return NULL; +} + +static zend_object *php_pspell_object_create(zend_class_entry *ce) +{ + php_pspell_object *obj = zend_object_alloc(sizeof(php_pspell_object), ce); + zend_object *zobj = php_pspell_object_to_zend_object(obj); + + obj->mgr = NULL; + zend_object_std_init(zobj, ce); + object_properties_init(zobj, ce); + zobj->handlers = &php_pspell_handlers; + + return zobj; +} + +static void php_pspell_object_free(zend_object *zobj) { + delete_pspell_manager(php_pspell_object_from_zend_object(zobj)->mgr); +} - delete_pspell_manager(manager); +/* class PSpellConfig */ + +typedef struct _php_pspell_config_object { + PspellConfig *cfg; + zend_object std; +} php_pspell_config_object; + +static php_pspell_config_object *php_pspell_config_object_from_zend_object(zend_object *zobj) { + return ((php_pspell_config_object*)(zobj + 1)) - 1; } -static void php_pspell_close_config(zend_resource *rsrc) +static zend_object *php_pspell_config_object_to_zend_object(php_pspell_config_object *obj) { + return ((zend_object*)(obj + 1)) - 1; +} + +static zend_function *php_pspell_config_object_get_constructor(zend_object *object) { - PspellConfig *config = (PspellConfig *)rsrc->ptr; + zend_throw_error(NULL, "You cannot initialize a PSpellConfig object except through helper functions"); + return NULL; +} - delete_pspell_config(config); +static zend_object *php_pspell_config_object_create(zend_class_entry *ce) +{ + php_pspell_config_object *obj = zend_object_alloc(sizeof(php_pspell_config_object), ce); + zend_object *zobj = php_pspell_config_object_to_zend_object(obj); + + obj->cfg = NULL; + zend_object_std_init(zobj, ce); + object_properties_init(zobj, ce); + zobj->handlers = &php_pspell_config_handlers; + + return zobj; } -#define PSPELL_FETCH_CONFIG do { \ - zval *res = zend_hash_index_find(&EG(regular_list), conf); \ - if (res == NULL || Z_RES_P(res)->type != le_pspell_config) { \ - zend_throw_error(NULL, "%s(): " ZEND_LONG_FMT " is not a PSPELL config index", get_active_function_name(), conf); \ - RETURN_THROWS(); \ - } \ - config = (PspellConfig *)Z_RES_P(res)->ptr; \ -} while (0) - -#define PSPELL_FETCH_MANAGER do { \ - zval *res = zend_hash_index_find(&EG(regular_list), scin); \ - if (res == NULL || Z_RES_P(res)->type != le_pspell) { \ - zend_throw_error(NULL, "%s(): " ZEND_LONG_FMT " is not a PSPELL result index", get_active_function_name(), scin); \ - RETURN_THROWS(); \ - } \ - manager = (PspellManager *)Z_RES_P(res)->ptr; \ -} while (0); +static void php_pspell_config_object_free(zend_object *zobj) { + delete_pspell_config(php_pspell_config_object_from_zend_object(zobj)->cfg); +} /* {{{ PHP_MINIT_FUNCTION */ static PHP_MINIT_FUNCTION(pspell) { + zend_class_entry ce; + INIT_CLASS_ENTRY(ce, "PSpell", class_PSpell_methods); + php_pspell_ce = zend_register_internal_class(&ce); + php_pspell_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; + php_pspell_ce->create_object = php_pspell_object_create; + php_pspell_ce->serialize = zend_class_serialize_deny; + php_pspell_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&php_pspell_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_pspell_handlers.clone_obj = NULL; + php_pspell_handlers.free_obj = php_pspell_object_free; + php_pspell_handlers.get_constructor = php_pspell_object_get_constructor; + php_pspell_handlers.offset = XtOffsetOf(php_pspell_object, std); + + INIT_CLASS_ENTRY(ce, "PSpellConfig", class_PSpellConfig_methods); + php_pspell_config_ce = zend_register_internal_class(&ce); + php_pspell_config_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; + php_pspell_config_ce->create_object = php_pspell_config_object_create; + php_pspell_config_ce->serialize = zend_class_serialize_deny; + php_pspell_config_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&php_pspell_config_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_pspell_config_handlers.clone_obj = NULL; + php_pspell_config_handlers.free_obj = php_pspell_config_object_free; + php_pspell_config_handlers.get_constructor = php_pspell_config_object_get_constructor; + php_pspell_config_handlers.offset = XtOffsetOf(php_pspell_config_object, std); + REGISTER_LONG_CONSTANT("PSPELL_FAST", PSPELL_FAST, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("PSPELL_NORMAL", PSPELL_NORMAL, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("PSPELL_BAD_SPELLERS", PSPELL_BAD_SPELLERS, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("PSPELL_RUN_TOGETHER", PSPELL_RUN_TOGETHER, CONST_PERSISTENT | CONST_CS); - le_pspell = zend_register_list_destructors_ex(php_pspell_close, NULL, "pspell", module_number); - le_pspell_config = zend_register_list_destructors_ex(php_pspell_close_config, NULL, "pspell config", module_number); + return SUCCESS; } /* }}} */ @@ -111,7 +193,6 @@ PHP_FUNCTION(pspell_new) size_t language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0; zend_long mode = Z_L(0), speed = Z_L(0); int argc = ZEND_NUM_ARGS(); - zval *ind; #ifdef PHP_WIN32 TCHAR aspell_dir[200]; @@ -122,7 +203,6 @@ PHP_FUNCTION(pspell_new) #endif PspellCanHaveError *ret; - PspellManager *manager; PspellConfig *config; if (zend_parse_parameters(argc, "s|sssl", &language, &language_len, &spelling, &spelling_len, @@ -194,9 +274,8 @@ PHP_FUNCTION(pspell_new) RETURN_FALSE; } - manager = to_pspell_manager(ret); - ind = zend_list_insert(manager, le_pspell); - RETURN_LONG(Z_RES_HANDLE_P(ind)); + object_init_ex(return_value, php_pspell_ce); + php_pspell_object_from_zend_object(Z_OBJ_P(return_value))->mgr = to_pspell_manager(ret); } /* }}} */ @@ -207,7 +286,6 @@ PHP_FUNCTION(pspell_new_personal) size_t personal_len, language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0; zend_long mode = Z_L(0), speed = Z_L(0); int argc = ZEND_NUM_ARGS(); - zval *ind; #ifdef PHP_WIN32 TCHAR aspell_dir[200]; @@ -218,7 +296,6 @@ PHP_FUNCTION(pspell_new_personal) #endif PspellCanHaveError *ret; - PspellManager *manager; PspellConfig *config; if (zend_parse_parameters(argc, "ps|sssl", &personal, &personal_len, &language, &language_len, @@ -298,26 +375,22 @@ PHP_FUNCTION(pspell_new_personal) RETURN_FALSE; } - manager = to_pspell_manager(ret); - ind = zend_list_insert(manager, le_pspell); - RETURN_LONG(Z_RES_HANDLE_P(ind)); + object_init_ex(return_value, php_pspell_ce); + php_pspell_object_from_zend_object(Z_OBJ_P(return_value))->mgr = to_pspell_manager(ret); } /* }}} */ /* {{{ Load a dictionary based on the given config */ PHP_FUNCTION(pspell_new_config) { - zend_long conf; - zval *ind; + zval *zcfg; PspellCanHaveError *ret; - PspellManager *manager; PspellConfig *config; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &conf) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcfg, php_pspell_config_ce) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_CONFIG; + config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; ret = new_pspell_manager(config); @@ -327,27 +400,24 @@ PHP_FUNCTION(pspell_new_config) RETURN_FALSE; } - manager = to_pspell_manager(ret); - ind = zend_list_insert(manager, le_pspell); - RETURN_LONG(Z_RES_HANDLE_P(ind)); + object_init_ex(return_value, php_pspell_ce); + php_pspell_object_from_zend_object(Z_OBJ_P(return_value))->mgr = to_pspell_manager(ret); } /* }}} */ /* {{{ Returns true if word is valid */ PHP_FUNCTION(pspell_check) { - size_t word_len; - zend_long scin; - char *word; + zval *zmgr; + zend_string *word; PspellManager *manager; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &scin, &word, &word_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &zmgr, php_pspell_ce, &word) == FAILURE) { RETURN_THROWS(); } + manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; - PSPELL_FETCH_MANAGER; - - if (pspell_manager_check(manager, word)) { + if (pspell_manager_check(manager, ZSTR_VAL(word))) { RETURN_TRUE; } else { RETURN_FALSE; @@ -358,22 +428,20 @@ PHP_FUNCTION(pspell_check) /* {{{ Returns array of suggestions */ PHP_FUNCTION(pspell_suggest) { - zend_long scin; - char *word; - size_t word_len; + zval *zmgr; + zend_string *word; PspellManager *manager; const PspellWordList *wl; const char *sug; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &scin, &word, &word_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &zmgr, php_pspell_ce, &word) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_MANAGER; + manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; array_init(return_value); - wl = pspell_manager_suggest(manager, word); + wl = pspell_manager_suggest(manager, ZSTR_VAL(word)); if (wl) { PspellStringEmulation *els = pspell_word_list_elements(wl); while ((sug = pspell_string_emulation_next(els)) != 0) { @@ -390,18 +458,16 @@ PHP_FUNCTION(pspell_suggest) /* {{{ Notify the dictionary of a user-selected replacement */ PHP_FUNCTION(pspell_store_replacement) { - size_t miss_len, corr_len; - zend_long scin; - char *miss, *corr; + zval *zmgr; + zend_string *miss, *corr; PspellManager *manager; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lss", &scin, &miss, &miss_len, &corr, &corr_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OSS", &zmgr, php_pspell_ce, &miss, &corr) == FAILURE) { RETURN_THROWS(); } + manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; - PSPELL_FETCH_MANAGER; - - pspell_manager_store_replacement(manager, miss, corr); + pspell_manager_store_replacement(manager, ZSTR_VAL(miss), ZSTR_VAL(corr)); if (pspell_manager_error_number(manager) == 0) { RETURN_TRUE; } else { @@ -414,23 +480,21 @@ PHP_FUNCTION(pspell_store_replacement) /* {{{ Adds a word to a personal list */ PHP_FUNCTION(pspell_add_to_personal) { - size_t word_len; - zend_long scin; - char *word; + zval *zmgr; + zend_string *word; PspellManager *manager; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &scin, &word, &word_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &zmgr, php_pspell_ce, &word) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_MANAGER; + manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; /*If the word is empty, we have to return; otherwise we'll segfault! ouch!*/ - if (word_len == 0) { + if (ZSTR_LEN(word) == 0) { RETURN_FALSE; } - pspell_manager_add_to_personal(manager, word); + pspell_manager_add_to_personal(manager, ZSTR_VAL(word)); if (pspell_manager_error_number(manager) == 0) { RETURN_TRUE; } else { @@ -443,23 +507,21 @@ PHP_FUNCTION(pspell_add_to_personal) /* {{{ Adds a word to the current session */ PHP_FUNCTION(pspell_add_to_session) { - size_t word_len; - zend_long scin; - char *word; + zval *zmgr; + zend_string *word; PspellManager *manager; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &scin, &word, &word_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &zmgr, php_pspell_ce, &word) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_MANAGER; + manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; /*If the word is empty, we have to return; otherwise we'll segfault! ouch!*/ - if (word_len == 0) { + if (ZSTR_LEN(word) == 0) { RETURN_FALSE; } - pspell_manager_add_to_session(manager, word); + pspell_manager_add_to_session(manager, ZSTR_VAL(word)); if (pspell_manager_error_number(manager) == 0) { RETURN_TRUE; } else { @@ -472,14 +534,13 @@ PHP_FUNCTION(pspell_add_to_session) /* {{{ Clears the current session */ PHP_FUNCTION(pspell_clear_session) { - zend_long scin; + zval *zmgr; PspellManager *manager; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &scin) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zmgr, php_pspell_ce) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_MANAGER; + manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; pspell_manager_clear_session(manager); if (pspell_manager_error_number(manager) == 0) { @@ -494,14 +555,13 @@ PHP_FUNCTION(pspell_clear_session) /* {{{ Saves the current (personal) wordlist */ PHP_FUNCTION(pspell_save_wordlist) { - zend_long scin; + zval *zmgr; PspellManager *manager; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &scin) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zmgr, php_pspell_ce) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_MANAGER; + manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; pspell_manager_save_all_word_lists(manager); @@ -520,7 +580,6 @@ PHP_FUNCTION(pspell_config_create) { char *language, *spelling = NULL, *jargon = NULL, *encoding = NULL; size_t language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0; - zval *ind; PspellConfig *config; #ifdef PHP_WIN32 @@ -577,23 +636,22 @@ PHP_FUNCTION(pspell_config_create) which is not what we want */ pspell_config_replace(config, "save-repl", "false"); - ind = zend_list_insert(config, le_pspell_config); - RETURN_LONG(Z_RES_HANDLE_P(ind)); + object_init_ex(return_value, php_pspell_config_ce); + php_pspell_config_object_from_zend_object(Z_OBJ_P(return_value))->cfg = config; } /* }}} */ /* {{{ Consider run-together words as valid components */ PHP_FUNCTION(pspell_config_runtogether) { - zend_long conf; - zend_bool runtogether; + zval *zcfg; + bool runtogether; PspellConfig *config; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lb", &conf, &runtogether) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ob", &zcfg, php_pspell_config_ce, &runtogether) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_CONFIG; + config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; pspell_config_replace(config, "run-together", runtogether ? "true" : "false"); @@ -604,14 +662,14 @@ PHP_FUNCTION(pspell_config_runtogether) /* {{{ Select mode for config (PSPELL_FAST, PSPELL_NORMAL or PSPELL_BAD_SPELLERS) */ PHP_FUNCTION(pspell_config_mode) { - zend_long conf, mode; + zval *zcfg; + zend_long mode; PspellConfig *config; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &conf, &mode) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &zcfg, php_pspell_config_ce, &mode) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_CONFIG; + config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; /* First check what mode we want (how many suggestions) */ if (mode == PSPELL_FAST) { @@ -630,14 +688,14 @@ PHP_FUNCTION(pspell_config_mode) PHP_FUNCTION(pspell_config_ignore) { char ignore_str[MAX_LENGTH_OF_LONG + 1]; - zend_long conf, ignore = 0L; + zval *zcfg; + zend_long ignore = 0L; PspellConfig *config; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &conf, &ignore) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &zcfg, php_pspell_config_ce, &ignore) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_CONFIG; + config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; snprintf(ignore_str, sizeof(ignore_str), ZEND_LONG_FMT, ignore); @@ -648,22 +706,20 @@ PHP_FUNCTION(pspell_config_ignore) static void pspell_config_path(INTERNAL_FUNCTION_PARAMETERS, char *option) { - zend_long conf; - char *value; - size_t value_len; + zval *zcfg; + zend_string *value; PspellConfig *config; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lp", &conf, &value, &value_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP", &zcfg, php_pspell_config_ce, &value) == FAILURE) { RETURN_THROWS(); } + config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; - PSPELL_FETCH_CONFIG; - - if (php_check_open_basedir(value)) { + if (php_check_open_basedir(ZSTR_VAL(value))) { RETURN_FALSE; } - pspell_config_replace(config, option, value); + pspell_config_replace(config, option, ZSTR_VAL(value)); RETURN_TRUE; } @@ -692,24 +748,22 @@ PHP_FUNCTION(pspell_config_data_dir) /* {{{ Use a personal dictionary with replacement pairs for this config */ PHP_FUNCTION(pspell_config_repl) { - zend_long conf; - char *repl; - size_t repl_len; + zval *zcfg; + zend_string *repl; PspellConfig *config; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lp", &conf, &repl, &repl_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP", &zcfg, php_pspell_config_ce, &repl) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_CONFIG; + config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; pspell_config_replace(config, "save-repl", "true"); - if (php_check_open_basedir(repl)) { + if (php_check_open_basedir(ZSTR_VAL(repl))) { RETURN_FALSE; } - pspell_config_replace(config, "repl", repl); + pspell_config_replace(config, "repl", ZSTR_VAL(repl)); RETURN_TRUE; } @@ -718,15 +772,14 @@ PHP_FUNCTION(pspell_config_repl) /* {{{ Save replacement pairs when personal list is saved for this config */ PHP_FUNCTION(pspell_config_save_repl) { - zend_long conf; - zend_bool save; + zval *zcfg; + bool save; PspellConfig *config; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lb", &conf, &save) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ob", &zcfg, php_pspell_config_ce, &save) == FAILURE) { RETURN_THROWS(); } - - PSPELL_FETCH_CONFIG; + config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; pspell_config_replace(config, "save-repl", save ? "true" : "false"); |