]> granicus.if.org Git - postgresql/blob - src/backend/tsearch/dict_ispell.c
Update copyrights in source tree to 2008.
[postgresql] / src / backend / tsearch / dict_ispell.c
1 /*-------------------------------------------------------------------------
2  *
3  * dict_ispell.c
4  *              Ispell dictionary interface
5  *
6  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7  *
8  *
9  * IDENTIFICATION
10  *        $PostgreSQL: pgsql/src/backend/tsearch/dict_ispell.c,v 1.7 2008/01/01 19:45:52 momjian Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15
16 #include "commands/defrem.h"
17 #include "tsearch/dicts/spell.h"
18 #include "tsearch/ts_locale.h"
19 #include "tsearch/ts_public.h"
20 #include "tsearch/ts_utils.h"
21 #include "utils/builtins.h"
22 #include "utils/memutils.h"
23
24
25 typedef struct
26 {
27         StopList        stoplist;
28         IspellDict      obj;
29 } DictISpell;
30
31 Datum
32 dispell_init(PG_FUNCTION_ARGS)
33 {
34         List       *dictoptions = (List *) PG_GETARG_POINTER(0);
35         DictISpell *d;
36         bool            affloaded = false,
37                                 dictloaded = false,
38                                 stoploaded = false;
39         ListCell   *l;
40
41         d = (DictISpell *) palloc0(sizeof(DictISpell));
42
43         foreach(l, dictoptions)
44         {
45                 DefElem    *defel = (DefElem *) lfirst(l);
46
47                 if (pg_strcasecmp(defel->defname, "DictFile") == 0)
48                 {
49                         if (dictloaded)
50                                 ereport(ERROR,
51                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
52                                                  errmsg("multiple DictFile parameters")));
53                         NIImportDictionary(&(d->obj),
54                                                          get_tsearch_config_filename(defGetString(defel),
55                                                                                                                  "dict"));
56                         dictloaded = true;
57                 }
58                 else if (pg_strcasecmp(defel->defname, "AffFile") == 0)
59                 {
60                         if (affloaded)
61                                 ereport(ERROR,
62                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
63                                                  errmsg("multiple AffFile parameters")));
64                         NIImportAffixes(&(d->obj),
65                                                         get_tsearch_config_filename(defGetString(defel),
66                                                                                                                 "affix"));
67                         affloaded = true;
68                 }
69                 else if (pg_strcasecmp(defel->defname, "StopWords") == 0)
70                 {
71                         if (stoploaded)
72                                 ereport(ERROR,
73                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
74                                                  errmsg("multiple StopWords parameters")));
75                         readstoplist(defGetString(defel), &(d->stoplist), lowerstr);
76                         stoploaded = true;
77                 }
78                 else
79                 {
80                         ereport(ERROR,
81                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
82                                          errmsg("unrecognized Ispell parameter: \"%s\"",
83                                                         defel->defname)));
84                 }
85         }
86
87         if (affloaded && dictloaded)
88         {
89                 NISortDictionary(&(d->obj));
90                 NISortAffixes(&(d->obj));
91         }
92         else if (!affloaded)
93         {
94                 ereport(ERROR,
95                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
96                                  errmsg("missing AffFile parameter")));
97         }
98         else
99         {
100                 ereport(ERROR,
101                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
102                                  errmsg("missing DictFile parameter")));
103         }
104
105         MemoryContextDeleteChildren(CurrentMemoryContext);
106
107         PG_RETURN_POINTER(d);
108 }
109
110 Datum
111 dispell_lexize(PG_FUNCTION_ARGS)
112 {
113         DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
114         char       *in = (char *) PG_GETARG_POINTER(1);
115         int32           len = PG_GETARG_INT32(2);
116         char       *txt;
117         TSLexeme   *res;
118         TSLexeme   *ptr,
119                            *cptr;
120
121         if (len <= 0)
122                 PG_RETURN_POINTER(NULL);
123
124         txt = lowerstr_with_len(in, len);
125         res = NINormalizeWord(&(d->obj), txt);
126
127         if (res == NULL)
128                 PG_RETURN_POINTER(NULL);
129
130         ptr = cptr = res;
131         while (ptr->lexeme)
132         {
133                 if (searchstoplist(&(d->stoplist), ptr->lexeme))
134                 {
135                         pfree(ptr->lexeme);
136                         ptr->lexeme = NULL;
137                         ptr++;
138                 }
139                 else
140                 {
141                         memcpy(cptr, ptr, sizeof(TSLexeme));
142                         cptr++;
143                         ptr++;
144                 }
145         }
146         cptr->lexeme = NULL;
147
148         PG_RETURN_POINTER(res);
149 }