1 /*
2   LibRCC - interface to spelling libraries used by language recognition code
3 
4   Copyright (C) 2005-2008 Suren A. Chilingaryan <csa@dside.dyndns.org>
5 
6   This library is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License version 2.1 or later
8   as published by the Free Software Foundation.
9 
10   This library is distributed in the hope that it will be useful, but WITHOUT
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
13   for more details.
14 
15   You should have received a copy of the GNU Lesser General Public License
16   along with this program; if not, write to the Free Software Foundation, Inc.,
17   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 
23 #include "internal.h"
24 #include "rccspell.h"
25 
rccSpellerCreate(const char * lang)26 rcc_speller rccSpellerCreate(const char *lang) {
27 #ifdef HAVE_ASPELL
28     rcc_speller rccspeller;
29     AspellSpeller *speller = NULL;
30     AspellConfig *config;
31     AspellCanHaveError *possible_err;
32 
33     if (!lang) return NULL;
34 
35     rccspeller = (rcc_speller)malloc(sizeof(rcc_speller_s));
36     if (!rccspeller) return rccspeller;
37 
38     config = new_aspell_config();
39 
40     if (config) {
41 	if (aspell_config_replace(config, "encoding", "utf-8")&&aspell_config_replace(config, "master", lang)) {
42 	    possible_err = new_aspell_speller(config);
43 	    if (aspell_error_number(possible_err) == 0) {
44 		speller = to_aspell_speller(possible_err);
45 	    }
46 	}
47 	delete_aspell_config(config);
48     }
49 
50     rccspeller->speller = speller;
51     rccspeller->parents[0] = NULL;
52     return rccspeller;
53 #else
54     return NULL;
55 #endif /* HAVE_ASPELL */
56 }
57 
rccSpellerFree(rcc_speller rccspeller)58 void rccSpellerFree(rcc_speller rccspeller) {
59 #ifdef HAVE_ASPELL
60     if ((rccspeller)&&(rccspeller->speller))
61 	delete_aspell_speller(rccspeller->speller);
62     free(rccspeller);
63 #endif /* HAVE_ASPELL */
64 }
65 
rccSpellerGetError(rcc_speller rccspeller)66 int rccSpellerGetError(rcc_speller rccspeller) {
67     if ((!rccspeller)||(!rccspeller->speller)) return -1;
68     return 0;
69 }
70 
rccSpellerAddParent(rcc_speller speller,rcc_speller parent)71 int rccSpellerAddParent(rcc_speller speller, rcc_speller parent) {
72     unsigned int i;
73     if ((!speller)||(!parent)) return -1;
74 
75     for (i=0;speller->parents[i];i++);
76     if (i >= RCC_MAX_LANGUAGE_PARENTS) return -1;
77     speller->parents[i++] = parent;
78     speller->parents[i] = NULL;
79 
80     return 0;
81 }
82 
rccSpellerSized(rcc_speller speller,const char * word,size_t len,int recursion)83 rcc_speller_result rccSpellerSized(rcc_speller speller, const char *word, size_t len, int recursion) {
84 #ifdef HAVE_ASPELL
85     rcc_speller_result result, saved_result = (rcc_speller_result)0;
86     unsigned int i;
87     int res;
88 
89     if (rccSpellerGetError(speller)) return (rcc_speller_result)RCC_SPELLER_INCORRECT;
90 
91     if (recursion) {
92 	for (i=0; speller->parents[i]; i++) {
93 	    result = rccSpellerSized(speller->parents[i], word, len, 0);
94 	    if ((result == RCC_SPELLER_CORRECT)||(result == RCC_SPELLER_PARENT)) return RCC_SPELLER_PARENT;
95 	    if ((result == RCC_SPELLER_ALMOST_CORRECT)||(result == RCC_SPELLER_ALMOST_PARENT)) saved_result = RCC_SPELLER_ALMOST_PARENT;
96 	}
97     }
98 
99     if (saved_result) return saved_result;
100 
101     res = aspell_speller_check(speller->speller, word, len?len:-1);
102     return res<=0?RCC_SPELLER_INCORRECT:RCC_SPELLER_CORRECT;
103 #endif /* HAVE_ASPELL */
104     return 0;
105 }
106 
rccSpeller(rcc_speller speller,const char * word)107 rcc_speller_result rccSpeller(rcc_speller speller, const char *word) {
108     return rccSpellerSized(speller, word, 0, 1);
109 }
110 
rccSpellerResultIsOwn(rcc_speller_result res)111 int rccSpellerResultIsOwn(rcc_speller_result res) {
112     if ((res == RCC_SPELLER_ALMOST_CORRECT)||(res == RCC_SPELLER_CORRECT)) return 1;
113     return 0;
114 }
115 
rccSpellerResultIsPrecise(rcc_speller_result res)116 int rccSpellerResultIsPrecise(rcc_speller_result res) {
117     if ((res == RCC_SPELLER_PARENT)||(res == RCC_SPELLER_CORRECT)) return 1;
118     return 0;
119 }
120 
rccSpellerResultIsCorrect(rcc_speller_result res)121 int rccSpellerResultIsCorrect(rcc_speller_result res) {
122     if ((res == RCC_SPELLER_ALMOST_CORRECT)||(res == RCC_SPELLER_CORRECT)) return 1;
123     if ((res == RCC_SPELLER_ALMOST_PARENT)||(res == RCC_SPELLER_PARENT)) return 1;
124     return 0;
125 }
126