package.xml0000644000175000017500000000507414527616235012500 0ustar derickderick pspell pecl.php.net This extension allows you to check the spelling of a word and offer suggestions. This extension allows you to check the spelling of a word and offer suggestions. Derick Rethans derick derick@php.net yes 2023-11-23 1.0.1 1.0.0 stable stable PHP 3.01 - Fixed version (don't use PHP version) and tests. 8.1.0 1.4.0b1 pspell pspell-1.0.1/tests/001.phpt0000644000175000017500000000442514527616235014653 0ustar derickderick--TEST-- pspell basic tests (warning: may fail with pspell/aspell < GNU Aspell 0.50.3) --EXTENSIONS-- pspell --SKIPIF-- --FILE-- --EXPECTF-- I : true will : true not : true buy : true this : true record : true it : true is : true scratched : true Sorry : true I : true will : true not : true buy : true this : true record : true it : true is : true scratched : true Uh : true no : true no : true no : true This : true is : true a : true tobacconists : true Ah : true I : true will : true not : true buy : true this : true tobacconists : true it : true is : true scratched : true No : true no : true no : true no : true Tobacco : true um : true cigarettes : true holds : true up : true a : true pack : true Ya : true Seegarets : ..false Possible spellings:%s,Regrets,%s,Cigarettes,%s Ya : true Uh : true My : true hovercraft : true is : true full : true of : true eels : true Sorry : true My : true hovercraft : true pantomimes : true puffing : true a : true cigarette : true is : true full : true of : true eels : true pretends : true to : true strike : true a : true match : true Ahh : ..false Possible spellings:%sAh,Aha,%s matches : true pspell-1.0.1/tests/002.phpt0000644000175000017500000000116214527616235014647 0ustar derickderick--TEST-- pspell session --EXTENSIONS-- pspell --SKIPIF-- --FILE-- --EXPECT-- bool(false) bool(false) bool(true) bool(true) bool(true) bool(false) pspell-1.0.1/tests/003.phpt0000644000175000017500000000205114527616235014646 0ustar derickderick--TEST-- pspell_config_ignore --EXTENSIONS-- pspell --SKIPIF-- --FILE-- getMessage() . "\n"; } echo "---\n"; var_dump(pspell_config_ignore($cfg, 2)); $p = pspell_new_config($cfg); var_dump(pspell_check($p, 'yy')); // segfault it? var_dump(pspell_config_ignore($cfg, PHP_INT_MAX)); ?> --EXPECTF-- bool(false) Warning: pspell_new_config(): PSPELL couldn't open the dictionary. reason: The encoding "b0rked" is not known. This could also mean that the file "%sb0rked.%s" could not be opened for reading or does not exist. in %s003.php on line 9 pspell_check(): Argument #1 ($dictionary) must be of type PSpell\Dictionary, %s given --- bool(true) bool(true) bool(true) pspell-1.0.1/tests/004.phpt0000644000175000017500000000116414527616235014653 0ustar derickderick--TEST-- pspell configs --EXTENSIONS-- pspell --SKIPIF-- --FILE-- --EXPECT-- bool(true) bool(true) bool(false) --- bool(true) bool(true) pspell-1.0.1/tests/005.phpt0000644000175000017500000000212614527616235014653 0ustar derickderick--TEST-- pspell configs --EXTENSIONS-- pspell --SKIPIF-- --FILE-- --EXPECTF-- Warning: pspell_new_personal(): PSPELL couldn't open the dictionary. reason: The file "%s005.php" is not in the proper format. in %s005.php on line 5 bool(false) bool(true) -- bool(true) bool(false) bool(true) bool(true) -- bool(true) bool(true) pspell-1.0.1/tests/wordlist.txt0000644000175000017500000000007014527616235016056 0ustar derickderickpersonal_ws-1.1 en 4 dfnvnsafksfksf fg iufrsn jsksjfsjf pspell-1.0.1/config.m40000644000175000017500000000222714527616235014021 0ustar derickderickPHP_ARG_WITH([pspell], [for PSPELL support], [AS_HELP_STRING([[--with-pspell[=DIR]]], [Include PSPELL support. GNU Aspell version 0.50.0 or higher required])]) if test "$PHP_PSPELL" != "no"; then dnl Add -Wno-strict-prototypes as depends on user libs PHP_NEW_EXTENSION(pspell, pspell.c, $ext_shared, , "-Wno-strict-prototypes") if test "$PHP_PSPELL" != "yes"; then PSPELL_SEARCH_DIRS=$PHP_PSPELL else PSPELL_SEARCH_DIRS="/usr/local /usr" fi for i in $PSPELL_SEARCH_DIRS; do if test -f $i/include/pspell/pspell.h; then PSPELL_DIR=$i PSPELL_INCDIR=$i/include/pspell elif test -f $i/include/pspell.h; then PSPELL_DIR=$i PSPELL_INCDIR=$i/include fi done if test -z "$PSPELL_DIR"; then AC_MSG_ERROR(Cannot find pspell) fi PSPELL_LIBDIR=$PSPELL_DIR/$PHP_LIBDIR PHP_ADD_LIBRARY_WITH_PATH(pspell, $PSPELL_LIBDIR, PSPELL_SHARED_LIBADD) dnl Add -laspell to LIBS if it exists PHP_CHECK_LIBRARY(aspell,new_aspell_config, [ PHP_ADD_LIBRARY_WITH_PATH(aspell, $PSPELL_LIBDIR, PSPELL_SHARED_LIBADD) ], [], [ -L$PSPELL_LIBDIR ]) PHP_ADD_INCLUDE($PSPELL_INCDIR) PHP_SUBST(PSPELL_SHARED_LIBADD) AC_DEFINE(HAVE_PSPELL,1,[ ]) fi pspell-1.0.1/config.w320000644000175000017500000000070014527616235014106 0ustar derickderick// vim:ft=javascript ARG_WITH("pspell", "pspell/aspell (whatever it's called this month) support", "no"); if (PHP_PSPELL != "no") { if (CHECK_HEADER_ADD_INCLUDE("pspell.h", "CFLAGS_PSPELL", PHP_PHP_BUILD + "\\include\\pspell;" + PHP_PSPELL) && CHECK_LIB("aspell*.lib", "pspell", PHP_PSPELL)) { EXTENSION('pspell', 'pspell.c'); AC_DEFINE('HAVE_PSPELL', 1); } else { WARNING("pspell not enabled; libraries and headers not found"); } } pspell-1.0.1/CREDITS0000644000175000017500000000002314527616235013322 0ustar derickderickPspell Vlad Krupin pspell-1.0.1/LICENSE0000644000175000017500000000620414527616235013316 0ustar derickderick-------------------------------------------------------------------- The PHP License, version 3.01 Copyright (c) 1999 - 2023 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, is permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name "PHP" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact group@php.net. 4. Products derived from this software may not be called "PHP", nor may "PHP" appear in their name, without prior written permission from group@php.net. You may indicate that your software works in conjunction with PHP by saying "Foo for PHP" instead of calling it "PHP Foo" or "phpfoo" 5. The PHP Group may publish revised and/or new versions of the license from time to time. Each version will be given a distinguishing version number. Once covered code has been published under a particular version of the license, you may always continue to use it under the terms of that version. You may also choose to use such covered code under the terms of any subsequent version of the license published by the PHP Group. No one other than the PHP Group has the right to modify the terms applicable to covered code created under this License. 6. Redistributions of any form whatsoever must retain the following acknowledgment: "This product includes PHP software, freely available from ". THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------- This software consists of voluntary contributions made by many individuals on behalf of the PHP Group. The PHP Group can be contacted via Email at group@php.net. For more information on the PHP Group and the PHP project, please see . PHP includes the Zend Engine, freely available at . pspell-1.0.1/php_pspell.h0000644000175000017500000000244614527616235014634 0ustar derickderick/* +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | https://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Vlad Krupin | +----------------------------------------------------------------------+ */ #ifndef _PSPELL_H #define _PSPELL_H #ifdef HAVE_PSPELL extern zend_module_entry pspell_module_entry; #define pspell_module_ptr &pspell_module_entry #include "php_version.h" #define PHP_PSPELL_VERSION "1.0.1" #else #define pspell_module_ptr NULL #endif #define phpext_pspell_ptr pspell_module_ptr #endif /* _PSPELL_H */ pspell-1.0.1/pspell_arginfo.h0000644000175000017500000001611614527616235015471 0ustar derickderick/* This is a generated file, edit the .stub.php file instead. * Stub hash: 8d35f61a0b48c5422b31e78f587d9258fd3e8e37 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pspell_new, 0, 1, PSpell\\Dictionary, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, language, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, spelling, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, jargon, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pspell_new_personal, 0, 2, PSpell\\Dictionary, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, language, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, spelling, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, jargon, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pspell_new_config, 0, 1, PSpell\\Dictionary, MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, config, PSpell\\Config, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_check, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, dictionary, PSpell\\Dictionary, 0) ZEND_ARG_TYPE_INFO(0, word, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pspell_suggest, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, dictionary, PSpell\\Dictionary, 0) ZEND_ARG_TYPE_INFO(0, word, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_store_replacement, 0, 3, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, dictionary, PSpell\\Dictionary, 0) ZEND_ARG_TYPE_INFO(0, misspelled, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, correct, IS_STRING, 0) ZEND_END_ARG_INFO() #define arginfo_pspell_add_to_personal arginfo_pspell_check #define arginfo_pspell_add_to_session arginfo_pspell_check ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_clear_session, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, dictionary, PSpell\\Dictionary, 0) ZEND_END_ARG_INFO() #define arginfo_pspell_save_wordlist arginfo_pspell_clear_session ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_pspell_config_create, 0, 1, PSpell\\Config, 0) ZEND_ARG_TYPE_INFO(0, language, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, spelling, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, jargon, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_config_runtogether, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, config, PSpell\\Config, 0) ZEND_ARG_TYPE_INFO(0, allow, _IS_BOOL, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_config_mode, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, config, PSpell\\Config, 0) ZEND_ARG_TYPE_INFO(0, mode, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_config_ignore, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, config, PSpell\\Config, 0) ZEND_ARG_TYPE_INFO(0, min_length, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_config_personal, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, config, PSpell\\Config, 0) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_config_dict_dir, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, config, PSpell\\Config, 0) ZEND_ARG_TYPE_INFO(0, directory, IS_STRING, 0) ZEND_END_ARG_INFO() #define arginfo_pspell_config_data_dir arginfo_pspell_config_dict_dir #define arginfo_pspell_config_repl arginfo_pspell_config_personal ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_config_save_repl, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, config, PSpell\\Config, 0) ZEND_ARG_TYPE_INFO(0, save, _IS_BOOL, 0) ZEND_END_ARG_INFO() ZEND_FUNCTION(pspell_new); ZEND_FUNCTION(pspell_new_personal); ZEND_FUNCTION(pspell_new_config); ZEND_FUNCTION(pspell_check); ZEND_FUNCTION(pspell_suggest); ZEND_FUNCTION(pspell_store_replacement); ZEND_FUNCTION(pspell_add_to_personal); ZEND_FUNCTION(pspell_add_to_session); ZEND_FUNCTION(pspell_clear_session); ZEND_FUNCTION(pspell_save_wordlist); ZEND_FUNCTION(pspell_config_create); ZEND_FUNCTION(pspell_config_runtogether); ZEND_FUNCTION(pspell_config_mode); ZEND_FUNCTION(pspell_config_ignore); ZEND_FUNCTION(pspell_config_personal); ZEND_FUNCTION(pspell_config_dict_dir); ZEND_FUNCTION(pspell_config_data_dir); ZEND_FUNCTION(pspell_config_repl); ZEND_FUNCTION(pspell_config_save_repl); static const zend_function_entry ext_functions[] = { ZEND_FE(pspell_new, arginfo_pspell_new) ZEND_FE(pspell_new_personal, arginfo_pspell_new_personal) ZEND_FE(pspell_new_config, arginfo_pspell_new_config) ZEND_FE(pspell_check, arginfo_pspell_check) ZEND_FE(pspell_suggest, arginfo_pspell_suggest) ZEND_FE(pspell_store_replacement, arginfo_pspell_store_replacement) ZEND_FE(pspell_add_to_personal, arginfo_pspell_add_to_personal) ZEND_FE(pspell_add_to_session, arginfo_pspell_add_to_session) ZEND_FE(pspell_clear_session, arginfo_pspell_clear_session) ZEND_FE(pspell_save_wordlist, arginfo_pspell_save_wordlist) ZEND_FE(pspell_config_create, arginfo_pspell_config_create) ZEND_FE(pspell_config_runtogether, arginfo_pspell_config_runtogether) ZEND_FE(pspell_config_mode, arginfo_pspell_config_mode) ZEND_FE(pspell_config_ignore, arginfo_pspell_config_ignore) ZEND_FE(pspell_config_personal, arginfo_pspell_config_personal) ZEND_FE(pspell_config_dict_dir, arginfo_pspell_config_dict_dir) ZEND_FE(pspell_config_data_dir, arginfo_pspell_config_data_dir) ZEND_FE(pspell_config_repl, arginfo_pspell_config_repl) ZEND_FE(pspell_config_save_repl, arginfo_pspell_config_save_repl) ZEND_FE_END }; static const zend_function_entry class_PSpell_Dictionary_methods[] = { ZEND_FE_END }; static const zend_function_entry class_PSpell_Config_methods[] = { ZEND_FE_END }; static void register_pspell_symbols(int module_number) { REGISTER_LONG_CONSTANT("PSPELL_FAST", PSPELL_FAST, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PSPELL_NORMAL", PSPELL_NORMAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PSPELL_BAD_SPELLERS", PSPELL_BAD_SPELLERS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PSPELL_RUN_TOGETHER", PSPELL_RUN_TOGETHER, CONST_PERSISTENT); } static zend_class_entry *register_class_PSpell_Dictionary(void) { zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "PSpell", "Dictionary", class_PSpell_Dictionary_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } static zend_class_entry *register_class_PSpell_Config(void) { zend_class_entry ce, *class_entry; INIT_NS_CLASS_ENTRY(ce, "PSpell", "Config", class_PSpell_Config_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; return class_entry; } pspell-1.0.1/pspell.c0000644000175000017500000005361414527616235013763 0ustar derickderick/* +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | https://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Vlad Krupin | +----------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include #include #include #ifdef HAVE_PSPELL /* this will enforce compatibility in .12 version (broken after .11.2) */ #define USE_ORIGINAL_MANAGER_FUNCS #include "php_pspell.h" #include #include "ext/standard/info.h" #define PSPELL_FAST 1L #define PSPELL_NORMAL 2L #define PSPELL_BAD_SPELLERS 3L #define PSPELL_SPEED_MASK_INTERNAL 3L #define PSPELL_RUN_TOGETHER 8L #include "pspell_arginfo.h" /* Largest ignored word can be 999 characters (this seems sane enough), * and it takes 3 bytes to represent that (see pspell_config_ignore) */ #define PSPELL_LARGEST_WORD 3 static PHP_MINIT_FUNCTION(pspell); static PHP_MINFO_FUNCTION(pspell); 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, }; #ifdef COMPILE_DL_PSPELL ZEND_GET_MODULE(pspell) #endif /* 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) { zend_throw_error(NULL, "You cannot initialize a PSpell\\Dictionary 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); } /* 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 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) { zend_throw_error(NULL, "You cannot initialize a PSpell\\Config object except through helper functions"); return NULL; } 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; } 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) { php_pspell_ce = register_class_PSpell_Dictionary(); php_pspell_ce->create_object = php_pspell_object_create; 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); php_pspell_config_ce = register_class_PSpell_Config(); php_pspell_config_ce->create_object = php_pspell_config_object_create; 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_pspell_symbols(module_number); return SUCCESS; } /* }}} */ /* {{{ Load a dictionary */ PHP_FUNCTION(pspell_new) { char *language, *spelling = NULL, *jargon = NULL, *encoding = NULL; 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(); #ifdef PHP_WIN32 TCHAR aspell_dir[200]; TCHAR data_dir[220]; TCHAR dict_dir[220]; HKEY hkey; DWORD dwType,dwLen; #endif PspellCanHaveError *ret; PspellConfig *config; if (zend_parse_parameters(argc, "s|sssl", &language, &language_len, &spelling, &spelling_len, &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) { RETURN_THROWS(); } config = new_pspell_config(); #ifdef PHP_WIN32 /* If aspell was installed using installer, we should have a key * pointing to the location of the dictionaries */ if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) { LONG result; dwLen = sizeof(aspell_dir) - 1; result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen); RegCloseKey(hkey); if (result == ERROR_SUCCESS) { strlcpy(data_dir, aspell_dir, sizeof(data_dir)); strlcat(data_dir, "\\data", sizeof(data_dir)); strlcpy(dict_dir, aspell_dir, sizeof(dict_dir)); strlcat(dict_dir, "\\dict", sizeof(dict_dir)); pspell_config_replace(config, "data-dir", data_dir); pspell_config_replace(config, "dict-dir", dict_dir); } } #endif pspell_config_replace(config, "language-tag", language); if (spelling_len) { pspell_config_replace(config, "spelling", spelling); } if (jargon_len) { pspell_config_replace(config, "jargon", jargon); } if (encoding_len) { pspell_config_replace(config, "encoding", encoding); } if (mode) { speed = mode & PSPELL_SPEED_MASK_INTERNAL; /* First check what mode we want (how many suggestions) */ if (speed == PSPELL_FAST) { pspell_config_replace(config, "sug-mode", "fast"); } else if (speed == PSPELL_NORMAL) { pspell_config_replace(config, "sug-mode", "normal"); } else if (speed == PSPELL_BAD_SPELLERS) { pspell_config_replace(config, "sug-mode", "bad-spellers"); } /* Then we see if run-together words should be treated as valid components */ if (mode & PSPELL_RUN_TOGETHER) { pspell_config_replace(config, "run-together", "true"); } } ret = new_pspell_manager(config); delete_pspell_config(config); if (pspell_error_number(ret) != 0) { php_error_docref(NULL, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret)); delete_pspell_can_have_error(ret); RETURN_FALSE; } 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 with a personal wordlist*/ PHP_FUNCTION(pspell_new_personal) { char *personal, *language, *spelling = NULL, *jargon = NULL, *encoding = NULL; 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(); #ifdef PHP_WIN32 TCHAR aspell_dir[200]; TCHAR data_dir[220]; TCHAR dict_dir[220]; HKEY hkey; DWORD dwType,dwLen; #endif PspellCanHaveError *ret; PspellConfig *config; if (zend_parse_parameters(argc, "ps|sssl", &personal, &personal_len, &language, &language_len, &spelling, &spelling_len, &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) { RETURN_THROWS(); } config = new_pspell_config(); #ifdef PHP_WIN32 /* If aspell was installed using installer, we should have a key * pointing to the location of the dictionaries */ if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) { LONG result; dwLen = sizeof(aspell_dir) - 1; result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen); RegCloseKey(hkey); if (result == ERROR_SUCCESS) { strlcpy(data_dir, aspell_dir, sizeof(data_dir)); strlcat(data_dir, "\\data", sizeof(data_dir)); strlcpy(dict_dir, aspell_dir, sizeof(dict_dir)); strlcat(dict_dir, "\\dict", sizeof(dict_dir)); pspell_config_replace(config, "data-dir", data_dir); pspell_config_replace(config, "dict-dir", dict_dir); } } #endif if (php_check_open_basedir(personal)) { delete_pspell_config(config); RETURN_FALSE; } pspell_config_replace(config, "personal", personal); pspell_config_replace(config, "save-repl", "false"); pspell_config_replace(config, "language-tag", language); if (spelling_len) { pspell_config_replace(config, "spelling", spelling); } if (jargon_len) { pspell_config_replace(config, "jargon", jargon); } if (encoding_len) { pspell_config_replace(config, "encoding", encoding); } if (mode) { speed = mode & PSPELL_SPEED_MASK_INTERNAL; /* First check what mode we want (how many suggestions) */ if (speed == PSPELL_FAST) { pspell_config_replace(config, "sug-mode", "fast"); } else if (speed == PSPELL_NORMAL) { pspell_config_replace(config, "sug-mode", "normal"); } else if (speed == PSPELL_BAD_SPELLERS) { pspell_config_replace(config, "sug-mode", "bad-spellers"); } /* Then we see if run-together words should be treated as valid components */ if (mode & PSPELL_RUN_TOGETHER) { pspell_config_replace(config, "run-together", "true"); } } ret = new_pspell_manager(config); delete_pspell_config(config); if (pspell_error_number(ret) != 0) { php_error_docref(NULL, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret)); delete_pspell_can_have_error(ret); RETURN_FALSE; } 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) { zval *zcfg; PspellCanHaveError *ret; PspellConfig *config; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zcfg, php_pspell_config_ce) == FAILURE) { RETURN_THROWS(); } config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; ret = new_pspell_manager(config); if (pspell_error_number(ret) != 0) { php_error_docref(NULL, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret)); delete_pspell_can_have_error(ret); RETURN_FALSE; } 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) { zval *zmgr; zend_string *word; PspellManager *manager; 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; if (pspell_manager_check(manager, ZSTR_VAL(word))) { RETURN_TRUE; } else { RETURN_FALSE; } } /* }}} */ /* {{{ Returns array of suggestions */ PHP_FUNCTION(pspell_suggest) { zval *zmgr; zend_string *word; PspellManager *manager; const PspellWordList *wl; const char *sug; 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; array_init(return_value); 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) { add_next_index_string(return_value,(char *)sug); } delete_pspell_string_emulation(els); } else { php_error_docref(NULL, E_WARNING, "PSPELL had a problem. details: %s", pspell_manager_error_message(manager)); RETURN_FALSE; } } /* }}} */ /* {{{ Notify the dictionary of a user-selected replacement */ PHP_FUNCTION(pspell_store_replacement) { zval *zmgr; zend_string *miss, *corr; PspellManager *manager; 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_manager_store_replacement(manager, ZSTR_VAL(miss), ZSTR_VAL(corr)); if (pspell_manager_error_number(manager) == 0) { RETURN_TRUE; } else { php_error_docref(NULL, E_WARNING, "pspell_store_replacement() gave error: %s", pspell_manager_error_message(manager)); RETURN_FALSE; } } /* }}} */ /* {{{ Adds a word to a personal list */ PHP_FUNCTION(pspell_add_to_personal) { zval *zmgr; zend_string *word; PspellManager *manager; 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; /*If the word is empty, we have to return; otherwise we'll segfault! ouch!*/ if (ZSTR_LEN(word) == 0) { RETURN_FALSE; } pspell_manager_add_to_personal(manager, ZSTR_VAL(word)); if (pspell_manager_error_number(manager) == 0) { RETURN_TRUE; } else { php_error_docref(NULL, E_WARNING, "pspell_add_to_personal() gave error: %s", pspell_manager_error_message(manager)); RETURN_FALSE; } } /* }}} */ /* {{{ Adds a word to the current session */ PHP_FUNCTION(pspell_add_to_session) { zval *zmgr; zend_string *word; PspellManager *manager; 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; /*If the word is empty, we have to return; otherwise we'll segfault! ouch!*/ if (ZSTR_LEN(word) == 0) { RETURN_FALSE; } pspell_manager_add_to_session(manager, ZSTR_VAL(word)); if (pspell_manager_error_number(manager) == 0) { RETURN_TRUE; } else { php_error_docref(NULL, E_WARNING, "pspell_add_to_session() gave error: %s", pspell_manager_error_message(manager)); RETURN_FALSE; } } /* }}} */ /* {{{ Clears the current session */ PHP_FUNCTION(pspell_clear_session) { zval *zmgr; PspellManager *manager; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zmgr, php_pspell_ce) == FAILURE) { RETURN_THROWS(); } manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; pspell_manager_clear_session(manager); if (pspell_manager_error_number(manager) == 0) { RETURN_TRUE; } else { php_error_docref(NULL, E_WARNING, "pspell_clear_session() gave error: %s", pspell_manager_error_message(manager)); RETURN_FALSE; } } /* }}} */ /* {{{ Saves the current (personal) wordlist */ PHP_FUNCTION(pspell_save_wordlist) { zval *zmgr; PspellManager *manager; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zmgr, php_pspell_ce) == FAILURE) { RETURN_THROWS(); } manager = php_pspell_object_from_zend_object(Z_OBJ_P(zmgr))->mgr; pspell_manager_save_all_word_lists(manager); if (pspell_manager_error_number(manager) == 0) { RETURN_TRUE; } else { php_error_docref(NULL, E_WARNING, "pspell_save_wordlist() gave error: %s", pspell_manager_error_message(manager)); RETURN_FALSE; } } /* }}} */ /* {{{ Create a new config to be used later to create a manager */ 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; PspellConfig *config; #ifdef PHP_WIN32 TCHAR aspell_dir[200]; TCHAR data_dir[220]; TCHAR dict_dir[220]; HKEY hkey; DWORD dwType,dwLen; #endif if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|sss", &language, &language_len, &spelling, &spelling_len, &jargon, &jargon_len, &encoding, &encoding_len) == FAILURE) { RETURN_THROWS(); } config = new_pspell_config(); #ifdef PHP_WIN32 /* If aspell was installed using installer, we should have a key * pointing to the location of the dictionaries */ if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) { LONG result; dwLen = sizeof(aspell_dir) - 1; result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen); RegCloseKey(hkey); if (result == ERROR_SUCCESS) { strlcpy(data_dir, aspell_dir, sizeof(data_dir)); strlcat(data_dir, "\\data", sizeof(data_dir)); strlcpy(dict_dir, aspell_dir, sizeof(dict_dir)); strlcat(dict_dir, "\\dict", sizeof(dict_dir)); pspell_config_replace(config, "data-dir", data_dir); pspell_config_replace(config, "dict-dir", dict_dir); } } #endif pspell_config_replace(config, "language-tag", language); if (spelling_len) { pspell_config_replace(config, "spelling", spelling); } if (jargon_len) { pspell_config_replace(config, "jargon", jargon); } if (encoding_len) { pspell_config_replace(config, "encoding", encoding); } /* By default I do not want to write anything anywhere because it'll try to write to $HOME which is not what we want */ pspell_config_replace(config, "save-repl", "false"); 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) { zval *zcfg; bool runtogether; PspellConfig *config; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ob", &zcfg, php_pspell_config_ce, &runtogether) == FAILURE) { RETURN_THROWS(); } config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; pspell_config_replace(config, "run-together", runtogether ? "true" : "false"); RETURN_TRUE; } /* }}} */ /* {{{ Select mode for config (PSPELL_FAST, PSPELL_NORMAL or PSPELL_BAD_SPELLERS) */ PHP_FUNCTION(pspell_config_mode) { zval *zcfg; zend_long mode; PspellConfig *config; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &zcfg, php_pspell_config_ce, &mode) == FAILURE) { RETURN_THROWS(); } 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) { pspell_config_replace(config, "sug-mode", "fast"); } else if (mode == PSPELL_NORMAL) { pspell_config_replace(config, "sug-mode", "normal"); } else if (mode == PSPELL_BAD_SPELLERS) { pspell_config_replace(config, "sug-mode", "bad-spellers"); } RETURN_TRUE; } /* }}} */ /* {{{ Ignore words <= n chars */ PHP_FUNCTION(pspell_config_ignore) { char ignore_str[MAX_LENGTH_OF_LONG + 1]; zval *zcfg; zend_long ignore = 0L; PspellConfig *config; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &zcfg, php_pspell_config_ce, &ignore) == FAILURE) { RETURN_THROWS(); } config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; snprintf(ignore_str, sizeof(ignore_str), ZEND_LONG_FMT, ignore); pspell_config_replace(config, "ignore", ignore_str); RETURN_TRUE; } /* }}} */ static void pspell_config_path(INTERNAL_FUNCTION_PARAMETERS, char *option) { zval *zcfg; zend_string *value; PspellConfig *config; 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; if (php_check_open_basedir(ZSTR_VAL(value))) { RETURN_FALSE; } pspell_config_replace(config, option, ZSTR_VAL(value)); RETURN_TRUE; } /* {{{ Use a personal dictionary for this config */ PHP_FUNCTION(pspell_config_personal) { pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "personal"); } /* }}} */ /* {{{ location of the main word list */ PHP_FUNCTION(pspell_config_dict_dir) { pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "dict-dir"); } /* }}} */ /* {{{ location of language data files */ PHP_FUNCTION(pspell_config_data_dir) { pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "data-dir"); } /* }}} */ /* {{{ Use a personal dictionary with replacement pairs for this config */ PHP_FUNCTION(pspell_config_repl) { zval *zcfg; zend_string *repl; PspellConfig *config; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP", &zcfg, php_pspell_config_ce, &repl) == FAILURE) { RETURN_THROWS(); } 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(ZSTR_VAL(repl))) { RETURN_FALSE; } pspell_config_replace(config, "repl", ZSTR_VAL(repl)); RETURN_TRUE; } /* }}} */ /* {{{ Save replacement pairs when personal list is saved for this config */ PHP_FUNCTION(pspell_config_save_repl) { zval *zcfg; bool save; PspellConfig *config; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ob", &zcfg, php_pspell_config_ce, &save) == FAILURE) { RETURN_THROWS(); } config = php_pspell_config_object_from_zend_object(Z_OBJ_P(zcfg))->cfg; pspell_config_replace(config, "save-repl", save ? "true" : "false"); RETURN_TRUE; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ static PHP_MINFO_FUNCTION(pspell) { php_info_print_table_start(); php_info_print_table_row(2, "PSpell Support", "enabled"); php_info_print_table_row(2, "PSpell extension version", PHP_PSPELL_VERSION); php_info_print_table_end(); } /* }}} */ #endif pspell-1.0.1/pspell.stub.php0000644000175000017500000000511014527616235015270 0ustar derickderick|false * @refcount 1 */ function pspell_suggest(PSpell\Dictionary $dictionary, string $word): array|false {} function pspell_store_replacement(PSpell\Dictionary $dictionary, string $misspelled, string $correct): bool {} function pspell_add_to_personal(PSpell\Dictionary $dictionary, string $word): bool {} function pspell_add_to_session(PSpell\Dictionary $dictionary, string $word): bool {} function pspell_clear_session(PSpell\Dictionary $dictionary): bool {} function pspell_save_wordlist(PSpell\Dictionary $dictionary): bool {} function pspell_config_create(string $language, string $spelling = "", string $jargon = "", string $encoding = ""): PSpell\Config {} function pspell_config_runtogether(PSpell\Config $config, bool $allow): bool {} function pspell_config_mode(PSpell\Config $config, int $mode): bool {} function pspell_config_ignore(PSpell\Config $config, int $min_length): bool {} function pspell_config_personal(PSpell\Config $config, string $filename): bool {} function pspell_config_dict_dir(PSpell\Config $config, string $directory): bool {} function pspell_config_data_dir(PSpell\Config $config, string $directory): bool {} function pspell_config_repl(PSpell\Config $config, string $filename): bool {} function pspell_config_save_repl(PSpell\Config $config, bool $save): bool {} }