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: 2014-12-13 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-2014 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_resource *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_resource *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  do { \
     231             :         zval *res = zend_hash_index_find(&EG(regular_list), conf); \
     232             :         if (res == NULL || Z_RES_P(res)->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             :         config = (PspellConfig *)Z_RES_P(res)->ptr; \
     237             : } while (0)
     238             : 
     239             : #define PSPELL_FETCH_MANAGER do { \
     240             :         zval *res = zend_hash_index_find(&EG(regular_list), scin); \
     241             :         if (res == NULL || Z_RES_P(res)->type != le_pspell) { \
     242             :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%ld is not a PSPELL result index", scin); \
     243             :                 RETURN_FALSE; \
     244             :         } \
     245             :         manager = (PspellManager *)Z_RES_P(res)->ptr; \
     246             : } while (0);
     247             : 
     248             : /* {{{ PHP_MINIT_FUNCTION
     249             :  */
     250       20622 : static PHP_MINIT_FUNCTION(pspell)
     251             : {
     252       20622 :         REGISTER_LONG_CONSTANT("PSPELL_FAST", PSPELL_FAST, CONST_PERSISTENT | CONST_CS);
     253       20622 :         REGISTER_LONG_CONSTANT("PSPELL_NORMAL", PSPELL_NORMAL, CONST_PERSISTENT | CONST_CS);
     254       20622 :         REGISTER_LONG_CONSTANT("PSPELL_BAD_SPELLERS", PSPELL_BAD_SPELLERS, CONST_PERSISTENT | CONST_CS);
     255       20622 :         REGISTER_LONG_CONSTANT("PSPELL_RUN_TOGETHER", PSPELL_RUN_TOGETHER, CONST_PERSISTENT | CONST_CS);
     256       20622 :         le_pspell = zend_register_list_destructors_ex(php_pspell_close, NULL, "pspell", module_number);
     257       20622 :         le_pspell_config = zend_register_list_destructors_ex(php_pspell_close_config, NULL, "pspell config", module_number);
     258       20622 :         return SUCCESS;
     259             : }
     260             : /* }}} */
     261             : 
     262             : /* {{{ proto int pspell_new(string language [, string spelling [, string jargon [, string encoding [, int mode]]]])
     263             :    Load a dictionary */
     264           7 : static PHP_FUNCTION(pspell_new)
     265             : {
     266           7 :         char *language, *spelling = NULL, *jargon = NULL, *encoding = NULL;
     267           7 :         size_t language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0;
     268           7 :         zend_long mode = Z_L(0),  speed = Z_L(0);
     269           7 :         int argc = ZEND_NUM_ARGS();
     270             :         zval *ind;
     271             : 
     272             : #ifdef PHP_WIN32
     273             :         TCHAR aspell_dir[200];
     274             :         TCHAR data_dir[220];
     275             :         TCHAR dict_dir[220];
     276             :         HKEY hkey;
     277             :         DWORD dwType,dwLen;
     278             : #endif
     279             : 
     280             :         PspellCanHaveError *ret;
     281             :         PspellManager *manager;
     282             :         PspellConfig *config;
     283             :         
     284           7 :         if (zend_parse_parameters(argc TSRMLS_CC, "s|sssl", &language, &language_len, &spelling, &spelling_len,
     285             :                 &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) {
     286           0 :                 return;
     287             :         }
     288             : 
     289           7 :         config = new_pspell_config();
     290             : 
     291             : #ifdef PHP_WIN32
     292             :         /* If aspell was installed using installer, we should have a key
     293             :          * pointing to the location of the dictionaries
     294             :          */
     295             :         if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) {
     296             :                 LONG result;
     297             :                 dwLen = sizeof(aspell_dir) - 1;
     298             :                 result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen);
     299             :                 RegCloseKey(hkey);
     300             :                 if (result == ERROR_SUCCESS) {
     301             :                         strlcpy(data_dir, aspell_dir, sizeof(data_dir));
     302             :                         strlcat(data_dir, "\\data", sizeof(data_dir));
     303             :                         strlcpy(dict_dir, aspell_dir, sizeof(dict_dir));
     304             :                         strlcat(dict_dir, "\\dict", sizeof(dict_dir));
     305             : 
     306             :                         pspell_config_replace(config, "data-dir", data_dir);
     307             :                         pspell_config_replace(config, "dict-dir", dict_dir);
     308             :                 }
     309             :         }
     310             : #endif
     311             : 
     312           7 :         pspell_config_replace(config, "language-tag", language);
     313             : 
     314           7 :         if (spelling_len) {
     315           0 :                 pspell_config_replace(config, "spelling", spelling);
     316             :         }
     317             : 
     318           7 :         if (jargon_len) {
     319           0 :                 pspell_config_replace(config, "jargon", jargon);
     320             :         }
     321             : 
     322           7 :         if (encoding_len) {
     323           0 :                 pspell_config_replace(config, "encoding", encoding);
     324             :         }
     325             : 
     326           7 :         if (argc > 4) {
     327           2 :                 speed = mode & PSPELL_SPEED_MASK_INTERNAL;
     328             : 
     329             :                 /* First check what mode we want (how many suggestions) */
     330           2 :                 if (speed == PSPELL_FAST) {
     331           2 :                         pspell_config_replace(config, "sug-mode", "fast");
     332           0 :                 } else if (speed == PSPELL_NORMAL) {
     333           0 :                         pspell_config_replace(config, "sug-mode", "normal");
     334           0 :                 } else if (speed == PSPELL_BAD_SPELLERS) {
     335           0 :                         pspell_config_replace(config, "sug-mode", "bad-spellers");
     336             :                 }
     337             :                 
     338             :                 /* Then we see if run-together words should be treated as valid components */
     339           2 :                 if (mode & PSPELL_RUN_TOGETHER) {
     340           2 :                         pspell_config_replace(config, "run-together", "true");
     341             :                 }
     342             :         }
     343             : 
     344           7 :         ret = new_pspell_manager(config);
     345           7 :         delete_pspell_config(config);
     346             : 
     347           7 :         if (pspell_error_number(ret) != 0) {
     348           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret));
     349           0 :                 delete_pspell_can_have_error(ret);
     350           0 :                 RETURN_FALSE;
     351             :         }
     352             :         
     353           7 :         manager = to_pspell_manager(ret);
     354           7 :         ind = zend_list_insert(manager, le_pspell TSRMLS_CC);
     355           7 :         RETURN_LONG(Z_RES_HANDLE_P(ind));
     356             : }
     357             : /* }}} */
     358             : 
     359             : /* {{{ proto int pspell_new_personal(string personal, string language [, string spelling [, string jargon [, string encoding [, int mode]]]])
     360             :    Load a dictionary with a personal wordlist*/
     361           2 : static PHP_FUNCTION(pspell_new_personal)
     362             : {
     363           2 :         char *personal, *language, *spelling = NULL, *jargon = NULL, *encoding = NULL;
     364           2 :         size_t personal_len, language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0;
     365           2 :         zend_long mode = Z_L(0),  speed = Z_L(0);
     366           2 :         int argc = ZEND_NUM_ARGS();
     367             :         zval *ind;
     368             : 
     369             : #ifdef PHP_WIN32
     370             :         TCHAR aspell_dir[200];
     371             :         TCHAR data_dir[220];
     372             :         TCHAR dict_dir[220];
     373             :         HKEY hkey;
     374             :         DWORD dwType,dwLen;
     375             : #endif
     376             : 
     377             :         PspellCanHaveError *ret;
     378             :         PspellManager *manager;
     379             :         PspellConfig *config;
     380             : 
     381           2 :         if (zend_parse_parameters(argc TSRMLS_CC, "ps|sssl", &personal, &personal_len, &language, &language_len, 
     382             :                 &spelling, &spelling_len, &jargon, &jargon_len, &encoding, &encoding_len, &mode) == FAILURE) {
     383           0 :                 return;
     384             :         }
     385             : 
     386           2 :         config = new_pspell_config();
     387             : 
     388             : #ifdef PHP_WIN32
     389             :         /* If aspell was installed using installer, we should have a key
     390             :          * pointing to the location of the dictionaries
     391             :          */
     392             :         if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) {
     393             :                 LONG result;
     394             :                 dwLen = sizeof(aspell_dir) - 1;
     395             :                 result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen);
     396             :                 RegCloseKey(hkey);
     397             :                 if (result == ERROR_SUCCESS) {
     398             :                         strlcpy(data_dir, aspell_dir, sizeof(data_dir));
     399             :                         strlcat(data_dir, "\\data", sizeof(data_dir));
     400             :                         strlcpy(dict_dir, aspell_dir, sizeof(dict_dir));
     401             :                         strlcat(dict_dir, "\\dict", sizeof(dict_dir));
     402             : 
     403             :                         pspell_config_replace(config, "data-dir", data_dir);
     404             :                         pspell_config_replace(config, "dict-dir", dict_dir);
     405             :                 }
     406             :         }
     407             : #endif
     408             : 
     409           2 :         if (php_check_open_basedir(personal TSRMLS_CC)) {
     410           0 :                 delete_pspell_config(config);
     411           0 :                 RETURN_FALSE;
     412             :         }
     413             : 
     414           2 :         pspell_config_replace(config, "personal", personal);
     415           2 :         pspell_config_replace(config, "save-repl", "false");
     416             : 
     417           2 :         pspell_config_replace(config, "language-tag", language);
     418             : 
     419           2 :         if (spelling_len) {
     420           0 :                 pspell_config_replace(config, "spelling", spelling);
     421             :         }
     422             : 
     423           2 :         if (jargon_len) {
     424           0 :                 pspell_config_replace(config, "jargon", jargon);
     425             :         }
     426             : 
     427           2 :         if (encoding_len) {
     428           0 :                 pspell_config_replace(config, "encoding", encoding);
     429             :         }
     430             : 
     431           2 :         if (argc > 5) {
     432           0 :                 speed = mode & PSPELL_SPEED_MASK_INTERNAL;
     433             : 
     434             :                 /* First check what mode we want (how many suggestions) */
     435           0 :                 if (speed == PSPELL_FAST) {
     436           0 :                         pspell_config_replace(config, "sug-mode", "fast");
     437           0 :                 } else if (speed == PSPELL_NORMAL) {
     438           0 :                         pspell_config_replace(config, "sug-mode", "normal");
     439           0 :                 } else if (speed == PSPELL_BAD_SPELLERS) {
     440           0 :                         pspell_config_replace(config, "sug-mode", "bad-spellers");
     441             :                 }
     442             :                 
     443             :                 /* Then we see if run-together words should be treated as valid components */
     444           0 :                 if (mode & PSPELL_RUN_TOGETHER) {
     445           0 :                         pspell_config_replace(config, "run-together", "true");
     446             :                 }
     447             :         }
     448             : 
     449           2 :         ret = new_pspell_manager(config);
     450           2 :         delete_pspell_config(config);
     451             : 
     452           2 :         if (pspell_error_number(ret) != 0) {
     453           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret));
     454           1 :                 delete_pspell_can_have_error(ret);
     455           1 :                 RETURN_FALSE;
     456             :         }
     457             :         
     458           1 :         manager = to_pspell_manager(ret);
     459           1 :         ind = zend_list_insert(manager, le_pspell TSRMLS_CC);
     460           1 :         RETURN_LONG(Z_RES_HANDLE_P(ind));
     461             : }
     462             : /* }}} */
     463             : 
     464             : /* {{{ proto int pspell_new_config(int config)
     465             :    Load a dictionary based on the given config */
     466           6 : static PHP_FUNCTION(pspell_new_config)
     467             : {
     468             :         zend_long conf; 
     469             :         zval *ind;
     470             :         PspellCanHaveError *ret;
     471             :         PspellManager *manager;
     472             :         PspellConfig *config;
     473             :         
     474           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &conf) == FAILURE) {
     475           0 :                 return;
     476             :         }
     477             : 
     478           6 :         PSPELL_FETCH_CONFIG;
     479             : 
     480           6 :         ret = new_pspell_manager(config);
     481             : 
     482           6 :         if (pspell_error_number(ret) != 0) {
     483           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "PSPELL couldn't open the dictionary. reason: %s", pspell_error_message(ret));
     484           1 :                 delete_pspell_can_have_error(ret);
     485           1 :                 RETURN_FALSE;
     486             :         }
     487             :         
     488           5 :         manager = to_pspell_manager(ret);
     489           5 :         ind = zend_list_insert(manager, le_pspell TSRMLS_CC);
     490           5 :         RETURN_LONG(Z_RES_HANDLE_P(ind));
     491             : }
     492             : /* }}} */
     493             : 
     494             : /* {{{ proto bool pspell_check(int pspell, string word)
     495             :    Returns true if word is valid */
     496          88 : static PHP_FUNCTION(pspell_check)
     497             : {
     498             :         size_t word_len;
     499             :         zend_long scin;
     500             :         char *word;
     501             :         PspellManager *manager;
     502             : 
     503          88 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &scin, &word, &word_len) == FAILURE) {
     504           1 :                 return;
     505             :         }
     506             : 
     507          87 :         PSPELL_FETCH_MANAGER;
     508             : 
     509          86 :         if (pspell_manager_check(manager, word)) {
     510          79 :                 RETURN_TRUE;
     511             :         } else {
     512           7 :                 RETURN_FALSE;
     513             :         }
     514             : }
     515             : /* }}} */
     516             : 
     517             : /* {{{ proto array pspell_suggest(int pspell, string word)
     518             :    Returns array of suggestions */
     519           2 : static PHP_FUNCTION(pspell_suggest)
     520             : {
     521             :         zend_long scin;
     522             :         char *word;
     523             :         size_t word_len;
     524             :         PspellManager *manager;
     525             :         const PspellWordList *wl;
     526             :         const char *sug;
     527             : 
     528           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &scin, &word, &word_len) == FAILURE) {
     529           0 :                 return;
     530             :         }
     531             : 
     532           2 :         PSPELL_FETCH_MANAGER;
     533             : 
     534           2 :         array_init(return_value);
     535             : 
     536           2 :         wl = pspell_manager_suggest(manager, word);
     537           2 :         if (wl) {
     538           2 :                 PspellStringEmulation *els = pspell_word_list_elements(wl);
     539          49 :                 while ((sug = pspell_string_emulation_next(els)) != 0) {
     540          45 :                         add_next_index_string(return_value,(char *)sug);
     541             :                 }
     542           2 :                 delete_pspell_string_emulation(els);
     543             :         } else {
     544           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "PSPELL had a problem. details: %s", pspell_manager_error_message(manager));
     545           0 :                 RETURN_FALSE;
     546             :         }
     547             : }
     548             : /* }}} */
     549             : 
     550             : /* {{{ proto bool pspell_store_replacement(int pspell, string misspell, string correct)
     551             :    Notify the dictionary of a user-selected replacement */
     552           0 : static PHP_FUNCTION(pspell_store_replacement)
     553             : {
     554             :         size_t miss_len, corr_len;
     555             :         zend_long scin;
     556             :         char *miss, *corr;
     557             :         PspellManager *manager;
     558             : 
     559           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lss", &scin, &miss, &miss_len, &corr, &corr_len) == FAILURE) {
     560           0 :                 return;
     561             :         }
     562             : 
     563           0 :         PSPELL_FETCH_MANAGER;
     564             : 
     565           0 :         pspell_manager_store_replacement(manager, miss, corr);
     566           0 :         if (pspell_manager_error_number(manager) == 0) {
     567           0 :                 RETURN_TRUE;
     568             :         } else {
     569           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_store_replacement() gave error: %s", pspell_manager_error_message(manager));
     570           0 :                 RETURN_FALSE;
     571             :         }
     572             : }
     573             : /* }}} */
     574             : 
     575             : /* {{{ proto bool pspell_add_to_personal(int pspell, string word)
     576             :    Adds a word to a personal list */
     577           1 : static PHP_FUNCTION(pspell_add_to_personal)
     578             : {
     579             :         size_t word_len;
     580             :         zend_long scin;
     581             :         char *word;
     582             :         PspellManager *manager;
     583             : 
     584           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &scin, &word, &word_len) == FAILURE) {
     585           0 :                 return;
     586             :         }
     587             : 
     588           1 :         PSPELL_FETCH_MANAGER;
     589             : 
     590             :         /*If the word is empty, we have to return; otherwise we'll segfault! ouch!*/
     591           1 :         if (word_len == 0) {
     592           0 :                 RETURN_FALSE;
     593             :         }
     594             :         
     595           1 :         pspell_manager_add_to_personal(manager, word);
     596           1 :         if (pspell_manager_error_number(manager) == 0) {
     597           1 :                 RETURN_TRUE;
     598             :         } else {
     599           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_add_to_personal() gave error: %s", pspell_manager_error_message(manager));
     600           0 :                 RETURN_FALSE;
     601             :         }
     602             : }
     603             : /* }}} */
     604             : 
     605             : /* {{{ proto bool pspell_add_to_session(int pspell, string word)
     606             :    Adds a word to the current session */
     607           2 : static PHP_FUNCTION(pspell_add_to_session)
     608             : {
     609             :         size_t word_len;
     610             :         zend_long scin;
     611             :         char *word;
     612             :         PspellManager *manager;
     613             : 
     614           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &scin, &word, &word_len) == FAILURE) {
     615           0 :                 return;
     616             :         }
     617             : 
     618           2 :         PSPELL_FETCH_MANAGER;
     619             : 
     620             :         /*If the word is empty, we have to return; otherwise we'll segfault! ouch!*/
     621           2 :         if (word_len == 0) {
     622           1 :                 RETURN_FALSE;
     623             :         }
     624             : 
     625           1 :         pspell_manager_add_to_session(manager, word);
     626           1 :         if (pspell_manager_error_number(manager) == 0) {
     627           1 :                 RETURN_TRUE;
     628             :         } else {
     629           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_add_to_session() gave error: %s", pspell_manager_error_message(manager));
     630           0 :                 RETURN_FALSE;
     631             :         }
     632             : }
     633             : /* }}} */
     634             : 
     635             : /* {{{ proto bool pspell_clear_session(int pspell)
     636             :    Clears the current session */
     637           2 : static PHP_FUNCTION(pspell_clear_session)
     638             : {
     639             :         zend_long scin;
     640             :         PspellManager *manager;
     641             : 
     642           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &scin) == FAILURE) {
     643           1 :                 return;
     644             :         }
     645             :     
     646           1 :         PSPELL_FETCH_MANAGER;   
     647             : 
     648           1 :         pspell_manager_clear_session(manager);
     649           1 :         if (pspell_manager_error_number(manager) == 0) {
     650           1 :                 RETURN_TRUE;
     651             :         } else {
     652           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_clear_session() gave error: %s", pspell_manager_error_message(manager));
     653           0 :                 RETURN_FALSE;
     654             :         }
     655             : }
     656             : /* }}} */
     657             : 
     658             : /* {{{ proto bool pspell_save_wordlist(int pspell)
     659             :    Saves the current (personal) wordlist */
     660           1 : static PHP_FUNCTION(pspell_save_wordlist)
     661             : {
     662             :         zend_long scin;
     663             :         PspellManager *manager;
     664             : 
     665           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &scin) == FAILURE) {
     666           0 :                 return;
     667             :         }
     668             :     
     669           1 :         PSPELL_FETCH_MANAGER;   
     670             : 
     671           1 :         pspell_manager_save_all_word_lists(manager);
     672             : 
     673           1 :         if (pspell_manager_error_number(manager) == 0) {
     674           1 :                 RETURN_TRUE;
     675             :         } else {
     676           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "pspell_save_wordlist() gave error: %s", pspell_manager_error_message(manager));
     677           0 :                 RETURN_FALSE;
     678             :         }
     679             : 
     680             : }
     681             : /* }}} */
     682             : 
     683             : /* {{{ proto int pspell_config_create(string language [, string spelling [, string jargon [, string encoding]]])
     684             :    Create a new config to be used later to create a manager */
     685           4 : static PHP_FUNCTION(pspell_config_create)
     686             : {
     687           4 :         char *language, *spelling = NULL, *jargon = NULL, *encoding = NULL;
     688           4 :         size_t language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0;
     689             :         zval *ind;
     690             :         PspellConfig *config;
     691             : 
     692             : #ifdef PHP_WIN32
     693             :         TCHAR aspell_dir[200];
     694             :         TCHAR data_dir[220];
     695             :         TCHAR dict_dir[220];
     696             :         HKEY hkey;
     697             :         DWORD dwType,dwLen;
     698             : #endif
     699             :         
     700           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sss", &language, &language_len, &spelling, &spelling_len, 
     701             :                 &jargon, &jargon_len, &encoding, &encoding_len) == FAILURE) {
     702           0 :                 return;
     703             :         }
     704             : 
     705           4 :         config = new_pspell_config();
     706             : 
     707             : #ifdef PHP_WIN32
     708             :     /* If aspell was installed using installer, we should have a key
     709             :      * pointing to the location of the dictionaries
     710             :      */
     711             :         if (0 == RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Aspell", &hkey)) {
     712             :                 LONG result;
     713             :                 dwLen = sizeof(aspell_dir) - 1;
     714             :                 result = RegQueryValueEx(hkey, "", NULL, &dwType, (LPBYTE)&aspell_dir, &dwLen);
     715             :                 RegCloseKey(hkey);
     716             :                 if (result == ERROR_SUCCESS) {
     717             :                         strlcpy(data_dir, aspell_dir, sizeof(data_dir));
     718             :                         strlcat(data_dir, "\\data", sizeof(data_dir));
     719             :                         strlcpy(dict_dir, aspell_dir, sizeof(dict_dir));
     720             :                         strlcat(dict_dir, "\\dict", sizeof(dict_dir));
     721             : 
     722             :                         pspell_config_replace(config, "data-dir", data_dir);
     723             :                         pspell_config_replace(config, "dict-dir", dict_dir);
     724             :                 }
     725             :         }
     726             : #endif
     727             : 
     728           4 :         pspell_config_replace(config, "language-tag", language);
     729             : 
     730           4 :         if (spelling_len) {
     731           3 :                 pspell_config_replace(config, "spelling", spelling);
     732             :         }
     733             : 
     734           4 :         if (jargon_len) {
     735           0 :                 pspell_config_replace(config, "jargon", jargon);
     736             :         }
     737             : 
     738           4 :         if (encoding_len) {
     739           3 :                 pspell_config_replace(config, "encoding", encoding);
     740             :         }
     741             : 
     742             :         /* By default I do not want to write anything anywhere because it'll try to write to $HOME
     743             :         which is not what we want */
     744           4 :         pspell_config_replace(config, "save-repl", "false");
     745             : 
     746           4 :         ind = zend_list_insert(config, le_pspell_config TSRMLS_CC);
     747           4 :         RETURN_LONG(Z_RES_HANDLE_P(ind));
     748             : }
     749             : /* }}} */
     750             : 
     751             : /* {{{ proto bool pspell_config_runtogether(int conf, bool runtogether)
     752             :    Consider run-together words as valid components */
     753           3 : static PHP_FUNCTION(pspell_config_runtogether)
     754             : {
     755             :         zend_long conf;
     756             :         zend_bool runtogether;
     757             :         PspellConfig *config;
     758             :         
     759           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb", &conf, &runtogether) == FAILURE) {
     760           0 :                 return;
     761             :         }
     762             : 
     763           3 :         PSPELL_FETCH_CONFIG;    
     764             : 
     765           3 :         pspell_config_replace(config, "run-together", runtogether ? "true" : "false");
     766             :         
     767           3 :         RETURN_TRUE;
     768             : }
     769             : /* }}} */
     770             : 
     771             : /* {{{ proto bool pspell_config_mode(int conf, long mode)
     772             :    Select mode for config (PSPELL_FAST, PSPELL_NORMAL or PSPELL_BAD_SPELLERS) */
     773           1 : static PHP_FUNCTION(pspell_config_mode)
     774             : {
     775             :         zend_long conf, mode;
     776             :         PspellConfig *config;
     777             : 
     778           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &conf, &mode) == FAILURE) {
     779           0 :                 return;
     780             :         }
     781             : 
     782           1 :         PSPELL_FETCH_CONFIG;
     783             : 
     784             :         /* First check what mode we want (how many suggestions) */
     785           1 :         if (mode == PSPELL_FAST) {
     786           0 :                 pspell_config_replace(config, "sug-mode", "fast");
     787           1 :         } else if (mode == PSPELL_NORMAL) {
     788           0 :                 pspell_config_replace(config, "sug-mode", "normal");
     789           1 :         } else if (mode == PSPELL_BAD_SPELLERS) {
     790           1 :                 pspell_config_replace(config, "sug-mode", "bad-spellers");
     791             :         }
     792             : 
     793           1 :         RETURN_TRUE;
     794             : }
     795             : /* }}} */
     796             : 
     797             : /* {{{ proto bool pspell_config_ignore(int conf, int ignore)
     798             :    Ignore words <= n chars */
     799           2 : static PHP_FUNCTION(pspell_config_ignore)
     800             : {
     801             :         char ignore_str[MAX_LENGTH_OF_LONG + 1];        
     802           2 :         zend_long conf, ignore = 0L;
     803             :         PspellConfig *config;
     804             :         
     805           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &conf, &ignore) == FAILURE) {
     806           0 :                 return;
     807             :         }
     808             : 
     809           2 :         PSPELL_FETCH_CONFIG;
     810             : 
     811           2 :         snprintf(ignore_str, sizeof(ignore_str), "%ld", ignore);
     812             : 
     813           2 :         pspell_config_replace(config, "ignore", ignore_str);
     814           2 :         RETURN_TRUE;
     815             : }
     816             : /* }}} */
     817             : 
     818           1 : static void pspell_config_path(INTERNAL_FUNCTION_PARAMETERS, char *option)
     819             : {
     820             :         zend_long conf;
     821             :         char *value;
     822             :         size_t value_len;
     823             :         PspellConfig *config;
     824             :         
     825           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lp", &conf, &value, &value_len) == FAILURE) {
     826           0 :                 return;
     827             :         }
     828             : 
     829           1 :         PSPELL_FETCH_CONFIG;
     830             : 
     831           1 :         if (php_check_open_basedir(value TSRMLS_CC)) {
     832           0 :                 RETURN_FALSE;
     833             :         }
     834             : 
     835           1 :         pspell_config_replace(config, option, value);
     836             : 
     837           1 :         RETURN_TRUE;
     838             : }
     839             : 
     840             : /* {{{ proto bool pspell_config_personal(int conf, string personal)
     841             :    Use a personal dictionary for this config */
     842           1 : static PHP_FUNCTION(pspell_config_personal)
     843             : {
     844           1 :         pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "personal");
     845           1 : }
     846             : /* }}} */
     847             : 
     848             : /* {{{ proto bool pspell_config_dict_dir(int conf, string directory)
     849             :    location of the main word list */
     850           0 : static PHP_FUNCTION(pspell_config_dict_dir)
     851             : {
     852           0 :         pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "dict-dir");
     853           0 : }
     854             : /* }}} */
     855             : 
     856             : /* {{{ proto bool pspell_config_data_dir(int conf, string directory)
     857             :     location of language data files */
     858           0 : static PHP_FUNCTION(pspell_config_data_dir)
     859             : {
     860           0 :         pspell_config_path(INTERNAL_FUNCTION_PARAM_PASSTHRU, "data-dir");
     861           0 : }
     862             : /* }}} */
     863             : 
     864             : /* {{{ proto bool pspell_config_repl(int conf, string repl)
     865             :    Use a personal dictionary with replacement pairs for this config */
     866           0 : static PHP_FUNCTION(pspell_config_repl)
     867             : {
     868             :         zend_long conf;
     869             :         char *repl;
     870             :         size_t repl_len;
     871             :         PspellConfig *config;
     872             :         
     873           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lp", &conf, &repl, &repl_len) == FAILURE) {
     874           0 :                 return;
     875             :         }
     876             : 
     877           0 :         PSPELL_FETCH_CONFIG;
     878             : 
     879           0 :         pspell_config_replace(config, "save-repl", "true");
     880             : 
     881           0 :         if (php_check_open_basedir(repl TSRMLS_CC)) {
     882           0 :                 RETURN_FALSE;
     883             :         }
     884             : 
     885           0 :         pspell_config_replace(config, "repl", repl);
     886             : 
     887           0 :         RETURN_TRUE;
     888             : }
     889             : /* }}} */
     890             : 
     891             : /* {{{ proto bool pspell_config_save_repl(int conf, bool save)
     892             :    Save replacement pairs when personal list is saved for this config */
     893           0 : static PHP_FUNCTION(pspell_config_save_repl)
     894             : {
     895             :         zend_long conf;
     896             :         zend_bool save;
     897             :         PspellConfig *config;
     898             :         
     899           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb", &conf, &save) == FAILURE) {
     900           0 :                 return;
     901             :         }
     902             : 
     903           0 :         PSPELL_FETCH_CONFIG;
     904             : 
     905           0 :         pspell_config_replace(config, "save-repl", save ? "true" : "false");
     906             : 
     907           0 :         RETURN_TRUE;
     908             : }
     909             : /* }}} */
     910             : 
     911             : /* {{{ PHP_MINFO_FUNCTION
     912             :  */
     913         144 : static PHP_MINFO_FUNCTION(pspell)
     914             : {
     915         144 :         php_info_print_table_start();
     916         144 :         php_info_print_table_row(2, "PSpell Support", "enabled");
     917         144 :         php_info_print_table_end();
     918         144 : }
     919             : /* }}} */
     920             : 
     921             : #endif
     922             : 
     923             : /*
     924             :  * Local variables:
     925             :  * tab-width: 4
     926             :  * c-basic-offset: 4
     927             :  * End:
     928             :  * vim600: sw=4 ts=4 fdm=marker
     929             :  * vim<600: sw=4 ts=4
     930             :  */

Generated by: LCOV version 1.10

Generated at Sat, 13 Dec 2014 06:16:19 +0000 (5 days ago)

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