#define GETWCHAR(W,L,N,T) ( ((uint8*)(W))[ ((T)==FF_PREFIX) ? (N) : ( (L) - 1 - (N) ) ] )
#define GETCHAR(A,N,T) GETWCHAR( (A)->repl, (A)->replen, N, T )
+static char *VoidString = "";
#define MEMOUT(X) if ( !(X) ) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory")))
static int
cmpspell(const void *s1, const void *s2)
{
- return (strcmp(((const SPELL *) s1)->word, ((const SPELL *) s2)->word));
+ return (strcmp((*(const SPELL **) s1)->word, (*(const SPELL **) s2)->word));
}
static int
cmpspellaffix(const void *s1, const void *s2)
{
- return (strcmp(((const SPELL *) s1)->p.flag, ((const SPELL *) s2)->p.flag));
+ return (strcmp((*(const SPELL **) s1)->p.flag, (*(const SPELL **) s2)->p.flag));
}
static char *
if (Conf->mspell)
{
Conf->mspell += 1024 * 20;
- Conf->Spell = (SPELL *) realloc(Conf->Spell, Conf->mspell * sizeof(SPELL));
+ Conf->Spell = (SPELL **) repalloc(Conf->Spell, Conf->mspell * sizeof(SPELL*));
}
else
{
Conf->mspell = 1024 * 20;
- Conf->Spell = (SPELL *) malloc(Conf->mspell * sizeof(SPELL));
+ Conf->Spell = (SPELL **) palloc(Conf->mspell * sizeof(SPELL*));
}
- MEMOUT(Conf->Spell);
}
- Conf->Spell[Conf->nspell].word = strdup(word);
- MEMOUT(Conf->Spell[Conf->nspell].word);
- strncpy(Conf->Spell[Conf->nspell].p.flag, flag, 16);
+ Conf->Spell[Conf->nspell] = (SPELL*)palloc(SPELLHDRSZ + strlen(word) + 1);
+ strcpy( Conf->Spell[Conf->nspell]->word ,word );
+ strncpy(Conf->Spell[Conf->nspell]->p.flag, flag, 16);
Conf->nspell++;
return (0);
}
{
Conf->Affix[Conf->naffixes].issimple = 1;
Conf->Affix[Conf->naffixes].isregis = 0;
- Conf->Affix[Conf->naffixes].mask = strdup("");
+ Conf->Affix[Conf->naffixes].mask = VoidString;
}
else if (RS_isRegis(mask))
{
Conf->Affix[Conf->naffixes].issimple = 0;
Conf->Affix[Conf->naffixes].isregis = 1;
- Conf->Affix[Conf->naffixes].mask = strdup(mask);
+ Conf->Affix[Conf->naffixes].mask = (mask && *mask) ? strdup(mask) : VoidString;
}
else
{
Conf->Affix[Conf->naffixes].flag = flag;
Conf->Affix[Conf->naffixes].type = type;
- Conf->Affix[Conf->naffixes].find = strdup(find);
+ Conf->Affix[Conf->naffixes].find = (find && *find) ? strdup(find) : VoidString;
MEMOUT(Conf->Affix[Conf->naffixes].find);
- Conf->Affix[Conf->naffixes].repl = strdup(repl);
- MEMOUT(Conf->Affix[Conf->naffixes].repl);
- Conf->Affix[Conf->naffixes].replen = strlen(repl);
+ if ( (Conf->Affix[Conf->naffixes].replen = strlen(repl)) > 0 ) {
+ Conf->Affix[Conf->naffixes].repl = strdup(repl);
+ MEMOUT(Conf->Affix[Conf->naffixes].repl);
+ } else
+ Conf->Affix[Conf->naffixes].repl = VoidString;
Conf->naffixes++;
return (0);
}
int lownew = low;
for (i = low; i < high; i++)
- if (Conf->Spell[i].p.d.len > level && lastchar != Conf->Spell[i].word[level])
+ if (Conf->Spell[i]->p.d.len > level && lastchar != Conf->Spell[i]->word[level])
{
nchar++;
- lastchar = Conf->Spell[i].word[level];
+ lastchar = Conf->Spell[i]->word[level];
}
if (!nchar)
lastchar = '\0';
for (i = low; i < high; i++)
- if (Conf->Spell[i].p.d.len > level)
+ if (Conf->Spell[i]->p.d.len > level)
{
- if (lastchar != Conf->Spell[i].word[level])
+ if (lastchar != Conf->Spell[i]->word[level])
{
if (lastchar)
{
lownew = i;
data++;
}
- lastchar = Conf->Spell[i].word[level];
+ lastchar = Conf->Spell[i]->word[level];
}
- data->val = ((uint8 *) (Conf->Spell[i].word))[level];
- if (Conf->Spell[i].p.d.len == level + 1)
+ data->val = ((uint8 *) (Conf->Spell[i]->word))[level];
+ if (Conf->Spell[i]->p.d.len == level + 1)
{
- if (data->isword && data->affix != Conf->Spell[i].p.d.affix)
+ if (data->isword && data->affix != Conf->Spell[i]->p.d.affix)
{
/*
* fprintf(stderr,"Word already exists: %s (affixes: '%s'
- * and '%s')\n", Conf->Spell[i].word,
+ * and '%s')\n", Conf->Spell[i]->word,
* Conf->AffixData[data->affix],
- * Conf->AffixData[Conf->Spell[i].p.d.affix] );
+ * Conf->AffixData[Conf->Spell[i]->p.d.affix] );
*/
/* MergeAffix called a few times */
- data->affix = MergeAffix(Conf, data->affix, Conf->Spell[i].p.d.affix);
+ data->affix = MergeAffix(Conf, data->affix, Conf->Spell[i]->p.d.affix);
}
else
- data->affix = Conf->Spell[i].p.d.affix;
+ data->affix = Conf->Spell[i]->p.d.affix;
data->isword = 1;
if (strchr(Conf->AffixData[data->affix], Conf->compoundcontrol))
data->compoundallow = 1;
return rs;
}
-
-
void
NISortDictionary(IspellDict * Conf)
{
int naffix = 3;
/* compress affixes */
- qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL), cmpspellaffix);
+ qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL*), cmpspellaffix);
for (i = 1; i < Conf->nspell; i++)
- if (strcmp(Conf->Spell[i].p.flag, Conf->Spell[i - 1].p.flag))
+ if (strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag))
naffix++;
Conf->AffixData = (char **) malloc(naffix * sizeof(char *));
naffix = 1;
Conf->AffixData[0] = strdup("");
MEMOUT(Conf->AffixData[0]);
- Conf->AffixData[1] = strdup(Conf->Spell[0].p.flag);
+ Conf->AffixData[1] = strdup(Conf->Spell[0]->p.flag);
MEMOUT(Conf->AffixData[1]);
- Conf->Spell[0].p.d.affix = 1;
- Conf->Spell[0].p.d.len = strlen(Conf->Spell[0].word);
+ Conf->Spell[0]->p.d.affix = 1;
+ Conf->Spell[0]->p.d.len = strlen(Conf->Spell[0]->word);
for (i = 1; i < Conf->nspell; i++)
{
- if (strcmp(Conf->Spell[i].p.flag, Conf->AffixData[naffix]))
+ if (strcmp(Conf->Spell[i]->p.flag, Conf->AffixData[naffix]))
{
naffix++;
- Conf->AffixData[naffix] = strdup(Conf->Spell[i].p.flag);
+ Conf->AffixData[naffix] = strdup(Conf->Spell[i]->p.flag);
MEMOUT(Conf->AffixData[naffix]);
}
- Conf->Spell[i].p.d.affix = naffix;
- Conf->Spell[i].p.d.len = strlen(Conf->Spell[i].word);
+ Conf->Spell[i]->p.d.affix = naffix;
+ Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
}
- qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL), cmpspell);
+ qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL*), cmpspell);
Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
for (i = 0; i < Conf->nspell; i++)
- free(Conf->Spell[i].word);
- free(Conf->Spell);
+ pfree(Conf->Spell[i]);
+ pfree(Conf->Spell);
Conf->Spell = NULL;
}
if (Conf->naffixes > 1)
qsort((void *) Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
-
Conf->CompoundAffix = ptr = (CMPDAffix *) malloc(sizeof(CMPDAffix) * Conf->naffixes);
MEMOUT(Conf->CompoundAffix);
ptr->affix = NULL;
}
static char *
-CheckAffix(const char *word, size_t len, AFFIX * Affix, char flagflags, char *newword)
+CheckAffix(const char *word, size_t len, AFFIX * Affix, char flagflags, char *newword, int *baselen)
{
if (flagflags & FF_COMPOUNDONLYAFX)
{
strcpy(newword, word);
strcpy(newword + len - Affix->replen, Affix->find);
+ if ( baselen ) /* store length of non-changed part of word */
+ *baselen = len - Affix->replen;
}
else
{
+ /* if prefix is a all non-chaged part's length then all word contains only prefix and suffix,
+ so out */
+ if ( baselen && *baselen + strlen(Affix->find) <= Affix->replen )
+ return NULL;
strcpy(newword, Affix->find);
strcat(newword, word + Affix->replen);
}
break;
for (j = 0; j < prefix->naff; j++)
{
- if (CheckAffix(word, wrdlen, prefix->aff[j], flag, newword))
+ if (CheckAffix(word, wrdlen, prefix->aff[j], flag, newword, NULL))
{
/* prefix success */
if (FindWord(Conf, newword, prefix->aff[j]->flag, flag & FF_COMPOUNDWORD) && (cur - forms) < (MAX_NORM - 1))
*/
while (snode)
{
+ int baselen=0;
+
/* find possible suffix */
suffix = FinfAffixes(snode, word, wrdlen, &slevel, FF_SUFFIX);
if (!suffix)
/* foreach suffix check affix */
for (i = 0; i < suffix->naff; i++)
{
- if (CheckAffix(word, wrdlen, suffix->aff[i], flag, newword))
+ if (CheckAffix(word, wrdlen, suffix->aff[i], flag, newword, &baselen))
{
/* suffix success */
if (FindWord(Conf, newword, suffix->aff[i]->flag, flag & FF_COMPOUNDWORD) && (cur - forms) < (MAX_NORM - 1))
break;
for (j = 0; j < prefix->naff; j++)
{
- if (CheckAffix(newword, swrdlen, prefix->aff[j], flag, pnewword))
+ if (CheckAffix(newword, swrdlen, prefix->aff[j], flag, pnewword, &baselen))
{
/* prefix success */
int ff = (prefix->aff[j]->flagflags & suffix->aff[i]->flagflags & FF_CROSSPRODUCT) ?
else
pg_regfree(&(Affix[i].reg.regex));
}
- free(Affix[i].mask);
- free(Affix[i].find);
- free(Affix[i].repl);
+ if ( Affix[i].mask != VoidString ) free(Affix[i].mask);
+ if ( Affix[i].find != VoidString ) free(Affix[i].find);
+ if ( Affix[i].repl != VoidString ) free(Affix[i].repl);
}
if (Conf->Spell)
{
for (i = 0; i < Conf->nspell; i++)
- free(Conf->Spell[i].word);
- free(Conf->Spell);
+ pfree(Conf->Spell[i]->word);
+ pfree(Conf->Spell);
}
if (Conf->Affix)