1 
2 #include <stdlib.h>
3 #include <string.h>
4 #include "../include/libstemmer.h"
5 #include "../runtime/api.h"
6 #include "modules_utf8.h"
7 
8 struct sb_stemmer {
9     struct SN_env * (*create)(void);
10     void (*close)(struct SN_env *);
11     int (*stem)(struct SN_env *);
12 
13     struct SN_env * env;
14 };
15 
16 extern const char **
sb_stemmer_list(void)17 sb_stemmer_list(void)
18 {
19     return algorithm_names;
20 }
21 
22 static stemmer_encoding_t
sb_getenc(const char * charenc)23 sb_getenc(const char * charenc)
24 {
25     const struct stemmer_encoding * encoding;
26     if (charenc == NULL) return ENC_UTF_8;
27     for (encoding = encodings; encoding->name != 0; encoding++) {
28         if (strcmp(encoding->name, charenc) == 0) break;
29     }
30     if (encoding->name == NULL) return ENC_UNKNOWN;
31     return encoding->enc;
32 }
33 
34 extern struct sb_stemmer *
sb_stemmer_new(const char * algorithm,const char * charenc)35 sb_stemmer_new(const char * algorithm, const char * charenc)
36 {
37     stemmer_encoding_t enc;
38     const struct stemmer_modules * module;
39     struct sb_stemmer * stemmer;
40 
41     enc = sb_getenc(charenc);
42     if (enc == ENC_UNKNOWN) return NULL;
43 
44     for (module = modules; module->name != 0; module++) {
45         if (strcmp(module->name, algorithm) == 0 && module->enc == enc) break;
46     }
47     if (module->name == NULL) return NULL;
48 
49     stemmer = (struct sb_stemmer *) malloc(sizeof(struct sb_stemmer));
50     if (stemmer == NULL) return NULL;
51 
52     stemmer->create = module->create;
53     stemmer->close = module->close;
54     stemmer->stem = module->stem;
55 
56     stemmer->env = stemmer->create();
57     if (stemmer->env == NULL)
58     {
59         sb_stemmer_delete(stemmer);
60         return NULL;
61     }
62 
63     return stemmer;
64 }
65 
66 void
sb_stemmer_delete(struct sb_stemmer * stemmer)67 sb_stemmer_delete(struct sb_stemmer * stemmer)
68 {
69     if (stemmer == 0) return;
70     if (stemmer->close) {
71         stemmer->close(stemmer->env);
72         stemmer->close = 0;
73     }
74     free(stemmer);
75 }
76 
77 const sb_symbol *
sb_stemmer_stem(struct sb_stemmer * stemmer,const sb_symbol * word,int size)78 sb_stemmer_stem(struct sb_stemmer * stemmer, const sb_symbol * word, int size)
79 {
80     int ret;
81     if (SN_set_current(stemmer->env, size, (const symbol *)(word)))
82     {
83         stemmer->env->l = 0;
84         return NULL;
85     }
86     ret = stemmer->stem(stemmer->env);
87     if (ret < 0) return NULL;
88     stemmer->env->p[stemmer->env->l] = 0;
89     return (const sb_symbol *)(stemmer->env->p);
90 }
91 
92 int
sb_stemmer_length(struct sb_stemmer * stemmer)93 sb_stemmer_length(struct sb_stemmer * stemmer)
94 {
95     return stemmer->env->l;
96 }
97