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: 171 262 65.3 %
Date: 2014-07-27 Functions: 19 24 79.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sun, 27 Jul 2014 12:58:34 +0000 (31 hours ago)

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