PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/pspell - pspell.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 167 248 67.3 %
Date: 2022-01-18 Functions: 19 24 79.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Wed, 19 Jan 2022 00:14:21 +0000 (3 days ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.