LCOV - code coverage report
Current view: top level - src/backend/tsearch - dict_ispell.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 42 55 76.4 %
Date: 2024-11-21 09:14:53 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          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
      30         134 : dispell_init(PG_FUNCTION_ARGS)
      31             : {
      32         134 :     List       *dictoptions = (List *) PG_GETARG_POINTER(0);
      33             :     DictISpell *d;
      34         134 :     bool        affloaded = false,
      35         134 :                 dictloaded = false,
      36         134 :                 stoploaded = false;
      37             :     ListCell   *l;
      38             : 
      39         134 :     d = (DictISpell *) palloc0(sizeof(DictISpell));
      40             : 
      41         134 :     NIStartBuild(&(d->obj));
      42             : 
      43         390 :     foreach(l, dictoptions)
      44             :     {
      45         262 :         DefElem    *defel = (DefElem *) lfirst(l);
      46             : 
      47         262 :         if (strcmp(defel->defname, "dictfile") == 0)
      48             :         {
      49         128 :             if (dictloaded)
      50           0 :                 ereport(ERROR,
      51             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      52             :                          errmsg("multiple DictFile parameters")));
      53         128 :             NIImportDictionary(&(d->obj),
      54         128 :                                get_tsearch_config_filename(defGetString(defel),
      55             :                                                            "dict"));
      56         128 :             dictloaded = true;
      57             :         }
      58         134 :         else if (strcmp(defel->defname, "afffile") == 0)
      59             :         {
      60         128 :             if (affloaded)
      61           0 :                 ereport(ERROR,
      62             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      63             :                          errmsg("multiple AffFile parameters")));
      64         128 :             NIImportAffixes(&(d->obj),
      65         128 :                             get_tsearch_config_filename(defGetString(defel),
      66             :                                                         "affix"));
      67         128 :             affloaded = true;
      68             :         }
      69           6 :         else if (strcmp(defel->defname, "stopwords") == 0)
      70             :         {
      71           0 :             if (stoploaded)
      72           0 :                 ereport(ERROR,
      73             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      74             :                          errmsg("multiple StopWords parameters")));
      75           0 :             readstoplist(defGetString(defel), &(d->stoplist), lowerstr);
      76           0 :             stoploaded = true;
      77             :         }
      78             :         else
      79             :         {
      80           6 :             ereport(ERROR,
      81             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      82             :                      errmsg("unrecognized Ispell parameter: \"%s\"",
      83             :                             defel->defname)));
      84             :         }
      85             :     }
      86             : 
      87         128 :     if (affloaded && dictloaded)
      88             :     {
      89         128 :         NISortDictionary(&(d->obj));
      90         110 :         NISortAffixes(&(d->obj));
      91             :     }
      92           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             : 
     105         110 :     NIFinishBuild(&(d->obj));
     106             : 
     107         110 :     PG_RETURN_POINTER(d);
     108             : }
     109             : 
     110             : Datum
     111         750 : dispell_lexize(PG_FUNCTION_ARGS)
     112             : {
     113         750 :     DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
     114         750 :     char       *in = (char *) PG_GETARG_POINTER(1);
     115         750 :     int32       len = PG_GETARG_INT32(2);
     116             :     char       *txt;
     117             :     TSLexeme   *res;
     118             :     TSLexeme   *ptr,
     119             :                *cptr;
     120             : 
     121         750 :     if (len <= 0)
     122           0 :         PG_RETURN_POINTER(NULL);
     123             : 
     124         750 :     txt = lowerstr_with_len(in, len);
     125         750 :     res = NINormalizeWord(&(d->obj), txt);
     126             : 
     127         750 :     if (res == NULL)
     128         144 :         PG_RETURN_POINTER(NULL);
     129             : 
     130         606 :     cptr = res;
     131        1920 :     for (ptr = cptr; ptr->lexeme; ptr++)
     132             :     {
     133        1314 :         if (searchstoplist(&(d->stoplist), ptr->lexeme))
     134             :         {
     135           0 :             pfree(ptr->lexeme);
     136           0 :             ptr->lexeme = NULL;
     137             :         }
     138             :         else
     139             :         {
     140        1314 :             if (cptr != ptr)
     141           0 :                 memcpy(cptr, ptr, sizeof(TSLexeme));
     142        1314 :             cptr++;
     143             :         }
     144             :     }
     145         606 :     cptr->lexeme = NULL;
     146             : 
     147         606 :     PG_RETURN_POINTER(res);
     148             : }

Generated by: LCOV version 1.14