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