Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * dict_ispell.c
4 : : * Ispell dictionary interface
5 : : *
6 : : * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7 : : *
8 : : *
9 : : * IDENTIFICATION
10 : : * src/backend/tsearch/dict_ispell.c
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 "utils/fmgrprotos.h"
21 : :
22 : :
23 : : typedef struct
24 : : {
25 : : StopList stoplist;
26 : : IspellDict obj;
27 : : } DictISpell;
28 : :
29 : : Datum
6081 tgl@sss.pgh.pa.us 30 :CBC 67 : dispell_init(PG_FUNCTION_ARGS)
31 : : {
6080 32 : 67 : List *dictoptions = (List *) PG_GETARG_POINTER(0);
33 : : DictISpell *d;
6081 34 : 67 : bool affloaded = false,
35 : 67 : dictloaded = false,
36 : 67 : stoploaded = false;
37 : : ListCell *l;
38 : :
39 : 67 : d = (DictISpell *) palloc0(sizeof(DictISpell));
40 : :
4939 41 : 67 : NIStartBuild(&(d->obj));
42 : :
6080 43 [ + - + + : 195 : foreach(l, dictoptions)
+ + ]
44 : : {
45 : 131 : DefElem *defel = (DefElem *) lfirst(l);
46 : :
2270 47 [ + + ]: 131 : if (strcmp(defel->defname, "dictfile") == 0)
48 : : {
6081 49 [ - + ]: 64 : if (dictloaded)
6081 tgl@sss.pgh.pa.us 50 [ # # ]:UBC 0 : ereport(ERROR,
51 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
52 : : errmsg("multiple DictFile parameters")));
6081 tgl@sss.pgh.pa.us 53 :CBC 64 : NIImportDictionary(&(d->obj),
2489 54 : 64 : get_tsearch_config_filename(defGetString(defel),
55 : : "dict"));
6081 56 : 64 : dictloaded = true;
57 : : }
2270 58 [ + + ]: 67 : else if (strcmp(defel->defname, "afffile") == 0)
59 : : {
6081 60 [ - + ]: 64 : if (affloaded)
6081 tgl@sss.pgh.pa.us 61 [ # # ]:UBC 0 : ereport(ERROR,
62 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
63 : : errmsg("multiple AffFile parameters")));
6081 tgl@sss.pgh.pa.us 64 :CBC 64 : NIImportAffixes(&(d->obj),
6080 65 : 64 : get_tsearch_config_filename(defGetString(defel),
66 : : "affix"));
6081 67 : 64 : affloaded = true;
68 : : }
2270 69 [ - + ]: 3 : else if (strcmp(defel->defname, "stopwords") == 0)
70 : : {
6081 tgl@sss.pgh.pa.us 71 [ # # ]:UBC 0 : if (stoploaded)
72 [ # # ]: 0 : ereport(ERROR,
73 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
74 : : errmsg("multiple StopWords parameters")));
6077 75 : 0 : readstoplist(defGetString(defel), &(d->stoplist), lowerstr);
6081 76 : 0 : stoploaded = true;
77 : : }
78 : : else
79 : : {
6081 tgl@sss.pgh.pa.us 80 [ + - ]:CBC 3 : ereport(ERROR,
81 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
82 : : errmsg("unrecognized Ispell parameter: \"%s\"",
83 : : defel->defname)));
84 : : }
85 : : }
86 : :
87 [ + - + - ]: 64 : if (affloaded && dictloaded)
88 : : {
89 : 64 : NISortDictionary(&(d->obj));
90 : 55 : NISortAffixes(&(d->obj));
91 : : }
6081 tgl@sss.pgh.pa.us 92 [ # # ]:UBC 0 : else if (!affloaded)
93 : : {
94 [ # # ]: 0 : ereport(ERROR,
95 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
96 : : errmsg("missing AffFile parameter")));
97 : : }
98 : : else
99 : : {
100 [ # # ]: 0 : ereport(ERROR,
101 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
102 : : errmsg("missing DictFile parameter")));
103 : : }
104 : :
4939 tgl@sss.pgh.pa.us 105 :CBC 55 : NIFinishBuild(&(d->obj));
106 : :
6081 107 : 55 : PG_RETURN_POINTER(d);
108 : : }
109 : :
110 : : Datum
111 : 375 : dispell_lexize(PG_FUNCTION_ARGS)
112 : : {
113 : 375 : DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
114 : 375 : char *in = (char *) PG_GETARG_POINTER(1);
5995 bruce@momjian.us 115 : 375 : int32 len = PG_GETARG_INT32(2);
116 : : char *txt;
117 : : TSLexeme *res;
118 : : TSLexeme *ptr,
119 : : *cptr;
120 : :
6081 tgl@sss.pgh.pa.us 121 [ - + ]: 375 : if (len <= 0)
6081 tgl@sss.pgh.pa.us 122 :UBC 0 : PG_RETURN_POINTER(NULL);
123 : :
6081 tgl@sss.pgh.pa.us 124 :CBC 375 : txt = lowerstr_with_len(in, len);
125 : 375 : res = NINormalizeWord(&(d->obj), txt);
126 : :
127 [ + + ]: 375 : if (res == NULL)
128 : 72 : PG_RETURN_POINTER(NULL);
129 : :
3691 heikki.linnakangas@i 130 : 303 : cptr = res;
131 [ + + ]: 960 : for (ptr = cptr; ptr->lexeme; ptr++)
132 : : {
6081 tgl@sss.pgh.pa.us 133 [ - + ]: 657 : if (searchstoplist(&(d->stoplist), ptr->lexeme))
134 : : {
6081 tgl@sss.pgh.pa.us 135 :UBC 0 : pfree(ptr->lexeme);
136 : 0 : ptr->lexeme = NULL;
137 : : }
138 : : else
139 : : {
3691 heikki.linnakangas@i 140 [ - + ]:CBC 657 : if (cptr != ptr)
3691 heikki.linnakangas@i 141 :UBC 0 : memcpy(cptr, ptr, sizeof(TSLexeme));
6081 tgl@sss.pgh.pa.us 142 :CBC 657 : cptr++;
143 : : }
144 : : }
145 : 303 : cptr->lexeme = NULL;
146 : :
147 : 303 : PG_RETURN_POINTER(res);
148 : : }
|