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