PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
dict_ispell.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * dict_ispell.c
4  * Ispell dictionary interface
5  *
6  * Portions Copyright (c) 1996-2017, 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_utils.h"
20 #include "utils/builtins.h"
21 
22 
23 typedef struct
24 {
27 } DictISpell;
28 
29 Datum
31 {
32  List *dictoptions = (List *) PG_GETARG_POINTER(0);
33  DictISpell *d;
34  bool affloaded = false,
35  dictloaded = false,
36  stoploaded = false;
37  ListCell *l;
38 
39  d = (DictISpell *) palloc0(sizeof(DictISpell));
40 
41  NIStartBuild(&(d->obj));
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),
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),
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")));
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  NIFinishBuild(&(d->obj));
106 
108 }
109 
110 Datum
112 {
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  cptr = res;
131  for (ptr = cptr; ptr->lexeme; ptr++)
132  {
133  if (searchstoplist(&(d->stoplist), ptr->lexeme))
134  {
135  pfree(ptr->lexeme);
136  ptr->lexeme = NULL;
137  }
138  else
139  {
140  if (cptr != ptr)
141  memcpy(cptr, ptr, sizeof(TSLexeme));
142  cptr++;
143  }
144  }
145  cptr->lexeme = NULL;
146 
147  PG_RETURN_POINTER(res);
148 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
StopList stoplist
Definition: dict_ispell.c:25
char * lowerstr_with_len(const char *str, int len)
Definition: ts_locale.c:241
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
char * lowerstr(const char *str)
Definition: ts_locale.c:228
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void NIImportAffixes(IspellDict *Conf, const char *filename)
Definition: spell.c:1408
signed int int32
Definition: c.h:246
void pfree(void *pointer)
Definition: mcxt.c:949
#define ERROR
Definition: elog.h:43
char * get_tsearch_config_filename(const char *basename, const char *extension)
Definition: ts_utils.c:33
char * defGetString(DefElem *def)
Definition: define.c:49
char * lexeme
Definition: ts_public.h:111
void NIStartBuild(IspellDict *Conf)
Definition: spell.c:87
#define ereport(elevel, rest)
Definition: elog.h:122
void readstoplist(const char *fname, StopList *s, char *(*wordop)(const char *))
Definition: ts_utils.c:68
void * palloc0(Size size)
Definition: mcxt.c:877
uintptr_t Datum
Definition: postgres.h:372
void NIImportDictionary(IspellDict *Conf, const char *filename)
Definition: spell.c:514
void NIFinishBuild(IspellDict *Conf)
Definition: spell.c:102
IspellDict obj
Definition: dict_ispell.c:26
void NISortAffixes(IspellDict *Conf)
Definition: spell.c:1941
#define lfirst(lc)
Definition: pg_list.h:106
bool searchstoplist(StopList *s, char *key)
Definition: ts_utils.c:141
int errmsg(const char *fmt,...)
Definition: elog.c:797
TSLexeme * NINormalizeWord(IspellDict *Conf, char *word)
Definition: spell.c:2500
void NISortDictionary(IspellDict *Conf)
Definition: spell.c:1697
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
char * defname
Definition: parsenodes.h:719
Datum dispell_init(PG_FUNCTION_ARGS)
Definition: dict_ispell.c:30
Definition: pg_list.h:45
Datum dispell_lexize(PG_FUNCTION_ARGS)
Definition: dict_ispell.c:111