18
18
#define GETWCHAR (W ,L ,N ,T ) ( ((uint8*)(W))[ ((T)==FF_PREFIX) ? (N) : ( (L) - 1 - (N) ) ] )
19
19
#define GETCHAR (A ,N ,T ) GETWCHAR( (A)->repl, (A)->replen, N, T )
20
20
21
+ static char * VoidString = "" ;
21
22
22
23
#define MEMOUT (X ) if ( !(X) ) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory")))
23
24
24
25
static int
25
26
cmpspell (const void * s1 ,const void * s2 )
26
27
{
27
- return (strcmp (((const SPELL * )s1 )-> word , ((const SPELL * )s2 )-> word ));
28
+ return (strcmp ((* (const SPELL * * )s1 )-> word , (* (const SPELL * * )s2 )-> word ));
28
29
}
29
30
static int
30
31
cmpspellaffix (const void * s1 ,const void * s2 )
31
32
{
32
- return (strcmp (((const SPELL * )s1 )-> p .flag , ((const SPELL * )s2 )-> p .flag ));
33
+ return (strcmp ((* (const SPELL * * )s1 )-> p .flag , (* (const SPELL * * )s2 )-> p .flag ));
33
34
}
34
35
35
36
static char *
@@ -128,18 +129,17 @@ NIAddSpell(IspellDict * Conf, const char *word, const char *flag)
128
129
if (Conf -> mspell )
129
130
{
130
131
Conf -> mspell += 1024 * 20 ;
131
- Conf -> Spell = (SPELL * ) realloc (Conf -> Spell ,Conf -> mspell * sizeof (SPELL ));
132
+ Conf -> Spell = (SPELL * * ) repalloc (Conf -> Spell ,Conf -> mspell * sizeof (SPELL * ));
132
133
}
133
134
else
134
135
{
135
136
Conf -> mspell = 1024 * 20 ;
136
- Conf -> Spell = (SPELL * ) malloc (Conf -> mspell * sizeof (SPELL ));
137
+ Conf -> Spell = (SPELL * * ) palloc (Conf -> mspell * sizeof (SPELL * ));
137
138
}
138
- MEMOUT (Conf -> Spell );
139
139
}
140
- Conf -> Spell [Conf -> nspell ]. word = strdup ( word );
141
- MEMOUT ( Conf -> Spell [Conf -> nspell ]. word );
142
- strncpy (Conf -> Spell [Conf -> nspell ]. p .flag ,flag ,16 );
140
+ Conf -> Spell [Conf -> nspell ]= ( SPELL * ) palloc ( SPELLHDRSZ + strlen ( word ) + 1 );
141
+ strcpy ( Conf -> Spell [Conf -> nspell ]-> word , word );
142
+ strncpy (Conf -> Spell [Conf -> nspell ]-> p .flag ,flag ,16 );
143
143
Conf -> nspell ++ ;
144
144
return (0 );
145
145
}
@@ -261,13 +261,13 @@ NIAddAffix(IspellDict * Conf, int flag, char flagflags, const char *mask, const
261
261
{
262
262
Conf -> Affix [Conf -> naffixes ].issimple = 1 ;
263
263
Conf -> Affix [Conf -> naffixes ].isregis = 0 ;
264
- Conf -> Affix [Conf -> naffixes ].mask = strdup ( "" ) ;
264
+ Conf -> Affix [Conf -> naffixes ].mask = VoidString ;
265
265
}
266
266
else if (RS_isRegis (mask ))
267
267
{
268
268
Conf -> Affix [Conf -> naffixes ].issimple = 0 ;
269
269
Conf -> Affix [Conf -> naffixes ].isregis = 1 ;
270
- Conf -> Affix [Conf -> naffixes ].mask = strdup (mask );
270
+ Conf -> Affix [Conf -> naffixes ].mask = ( mask && * mask ) ? strdup (mask ) : VoidString ;
271
271
}
272
272
else
273
273
{
@@ -287,11 +287,13 @@ NIAddAffix(IspellDict * Conf, int flag, char flagflags, const char *mask, const
287
287
Conf -> Affix [Conf -> naffixes ].flag = flag ;
288
288
Conf -> Affix [Conf -> naffixes ].type = type ;
289
289
290
- Conf -> Affix [Conf -> naffixes ].find = strdup (find );
290
+ Conf -> Affix [Conf -> naffixes ].find = ( find && * find ) ? strdup (find ) : VoidString ;
291
291
MEMOUT (Conf -> Affix [Conf -> naffixes ].find );
292
- Conf -> Affix [Conf -> naffixes ].repl = strdup (repl );
293
- MEMOUT (Conf -> Affix [Conf -> naffixes ].repl );
294
- Conf -> Affix [Conf -> naffixes ].replen = strlen (repl );
292
+ if ( (Conf -> Affix [Conf -> naffixes ].replen = strlen (repl ))> 0 ) {
293
+ Conf -> Affix [Conf -> naffixes ].repl = strdup (repl );
294
+ MEMOUT (Conf -> Affix [Conf -> naffixes ].repl );
295
+ }else
296
+ Conf -> Affix [Conf -> naffixes ].repl = VoidString ;
295
297
Conf -> naffixes ++ ;
296
298
return (0 );
297
299
}
@@ -506,10 +508,10 @@ mkSPNode(IspellDict * Conf, int low, int high, int level)
506
508
int lownew = low ;
507
509
508
510
for (i = low ;i < high ;i ++ )
509
- if (Conf -> Spell [i ]. p .d .len > level && lastchar != Conf -> Spell [i ]. word [level ])
511
+ if (Conf -> Spell [i ]-> p .d .len > level && lastchar != Conf -> Spell [i ]-> word [level ])
510
512
{
511
513
nchar ++ ;
512
- lastchar = Conf -> Spell [i ]. word [level ];
514
+ lastchar = Conf -> Spell [i ]-> word [level ];
513
515
}
514
516
515
517
if (!nchar )
@@ -523,34 +525,34 @@ mkSPNode(IspellDict * Conf, int low, int high, int level)
523
525
524
526
lastchar = '\0' ;
525
527
for (i = low ;i < high ;i ++ )
526
- if (Conf -> Spell [i ]. p .d .len > level )
528
+ if (Conf -> Spell [i ]-> p .d .len > level )
527
529
{
528
- if (lastchar != Conf -> Spell [i ]. word [level ])
530
+ if (lastchar != Conf -> Spell [i ]-> word [level ])
529
531
{
530
532
if (lastchar )
531
533
{
532
534
data -> node = mkSPNode (Conf ,lownew ,i ,level + 1 );
533
535
lownew = i ;
534
536
data ++ ;
535
537
}
536
- lastchar = Conf -> Spell [i ]. word [level ];
538
+ lastchar = Conf -> Spell [i ]-> word [level ];
537
539
}
538
- data -> val = ((uint8 * ) (Conf -> Spell [i ]. word ))[level ];
539
- if (Conf -> Spell [i ]. p .d .len == level + 1 )
540
+ data -> val = ((uint8 * ) (Conf -> Spell [i ]-> word ))[level ];
541
+ if (Conf -> Spell [i ]-> p .d .len == level + 1 )
540
542
{
541
- if (data -> isword && data -> affix != Conf -> Spell [i ]. p .d .affix )
543
+ if (data -> isword && data -> affix != Conf -> Spell [i ]-> p .d .affix )
542
544
{
543
545
/*
544
546
* fprintf(stderr,"Word already exists: %s (affixes: '%s'
545
- * and '%s')\n", Conf->Spell[i]. word,
547
+ * and '%s')\n", Conf->Spell[i]-> word,
546
548
* Conf->AffixData[data->affix],
547
- * Conf->AffixData[Conf->Spell[i]. p.d.affix] );
549
+ * Conf->AffixData[Conf->Spell[i]-> p.d.affix] );
548
550
*/
549
551
/* MergeAffix called a few times */
550
- data -> affix = MergeAffix (Conf ,data -> affix ,Conf -> Spell [i ]. p .d .affix );
552
+ data -> affix = MergeAffix (Conf ,data -> affix ,Conf -> Spell [i ]-> p .d .affix );
551
553
}
552
554
else
553
- data -> affix = Conf -> Spell [i ]. p .d .affix ;
555
+ data -> affix = Conf -> Spell [i ]-> p .d .affix ;
554
556
data -> isword = 1 ;
555
557
if (strchr (Conf -> AffixData [data -> affix ],Conf -> compoundcontrol ))
556
558
data -> compoundallow = 1 ;
@@ -562,18 +564,16 @@ mkSPNode(IspellDict * Conf, int low, int high, int level)
562
564
return rs ;
563
565
}
564
566
565
-
566
-
567
567
void
568
568
NISortDictionary (IspellDict * Conf )
569
569
{
570
570
size_t i ;
571
571
int naffix = 3 ;
572
572
573
573
/* compress affixes */
574
- qsort ((void * )Conf -> Spell ,Conf -> nspell ,sizeof (SPELL ),cmpspellaffix );
574
+ qsort ((void * )Conf -> Spell ,Conf -> nspell ,sizeof (SPELL * ),cmpspellaffix );
575
575
for (i = 1 ;i < Conf -> nspell ;i ++ )
576
- if (strcmp (Conf -> Spell [i ]. p .flag ,Conf -> Spell [i - 1 ]. p .flag ))
576
+ if (strcmp (Conf -> Spell [i ]-> p .flag ,Conf -> Spell [i - 1 ]-> p .flag ))
577
577
naffix ++ ;
578
578
579
579
Conf -> AffixData = (char * * )malloc (naffix * sizeof (char * ));
@@ -582,28 +582,28 @@ NISortDictionary(IspellDict * Conf)
582
582
naffix = 1 ;
583
583
Conf -> AffixData [0 ]= strdup ("" );
584
584
MEMOUT (Conf -> AffixData [0 ]);
585
- Conf -> AffixData [1 ]= strdup (Conf -> Spell [0 ]. p .flag );
585
+ Conf -> AffixData [1 ]= strdup (Conf -> Spell [0 ]-> p .flag );
586
586
MEMOUT (Conf -> AffixData [1 ]);
587
- Conf -> Spell [0 ]. p .d .affix = 1 ;
588
- Conf -> Spell [0 ]. p .d .len = strlen (Conf -> Spell [0 ]. word );
587
+ Conf -> Spell [0 ]-> p .d .affix = 1 ;
588
+ Conf -> Spell [0 ]-> p .d .len = strlen (Conf -> Spell [0 ]-> word );
589
589
for (i = 1 ;i < Conf -> nspell ;i ++ )
590
590
{
591
- if (strcmp (Conf -> Spell [i ]. p .flag ,Conf -> AffixData [naffix ]))
591
+ if (strcmp (Conf -> Spell [i ]-> p .flag ,Conf -> AffixData [naffix ]))
592
592
{
593
593
naffix ++ ;
594
- Conf -> AffixData [naffix ]= strdup (Conf -> Spell [i ]. p .flag );
594
+ Conf -> AffixData [naffix ]= strdup (Conf -> Spell [i ]-> p .flag );
595
595
MEMOUT (Conf -> AffixData [naffix ]);
596
596
}
597
- Conf -> Spell [i ]. p .d .affix = naffix ;
598
- Conf -> Spell [i ]. p .d .len = strlen (Conf -> Spell [i ]. word );
597
+ Conf -> Spell [i ]-> p .d .affix = naffix ;
598
+ Conf -> Spell [i ]-> p .d .len = strlen (Conf -> Spell [i ]-> word );
599
599
}
600
600
601
- qsort ((void * )Conf -> Spell ,Conf -> nspell ,sizeof (SPELL ),cmpspell );
601
+ qsort ((void * )Conf -> Spell ,Conf -> nspell ,sizeof (SPELL * ),cmpspell );
602
602
Conf -> Dictionary = mkSPNode (Conf ,0 ,Conf -> nspell ,0 );
603
603
604
604
for (i = 0 ;i < Conf -> nspell ;i ++ )
605
- free (Conf -> Spell [i ]. word );
606
- free (Conf -> Spell );
605
+ pfree (Conf -> Spell [i ]);
606
+ pfree (Conf -> Spell );
607
607
Conf -> Spell = NULL ;
608
608
}
609
609
@@ -724,7 +724,6 @@ NISortAffixes(IspellDict * Conf)
724
724
725
725
if (Conf -> naffixes > 1 )
726
726
qsort ((void * )Conf -> Affix ,Conf -> naffixes ,sizeof (AFFIX ),cmpaffix );
727
-
728
727
Conf -> CompoundAffix = ptr = (CMPDAffix * )malloc (sizeof (CMPDAffix )* Conf -> naffixes );
729
728
MEMOUT (Conf -> CompoundAffix );
730
729
ptr -> affix = NULL ;
@@ -803,7 +802,7 @@ FinfAffixes(AffixNode * node, const char *word, int wrdlen, int *level, int type
803
802
}
804
803
805
804
static char *
806
- CheckAffix (const char * word ,size_t len ,AFFIX * Affix ,char flagflags ,char * newword )
805
+ CheckAffix (const char * word ,size_t len ,AFFIX * Affix ,char flagflags ,char * newword , int * baselen )
807
806
{
808
807
809
808
if (flagflags & FF_COMPOUNDONLYAFX )
@@ -821,9 +820,15 @@ CheckAffix(const char *word, size_t len, AFFIX * Affix, char flagflags, char *ne
821
820
{
822
821
strcpy (newword ,word );
823
822
strcpy (newword + len - Affix -> replen ,Affix -> find );
823
+ if (baselen )/* store length of non-changed part of word */
824
+ * baselen = len - Affix -> replen ;
824
825
}
825
826
else
826
827
{
828
+ /* if prefix is a all non-chaged part's length then all word contains only prefix and suffix,
829
+ so out */
830
+ if (baselen && * baselen + strlen (Affix -> find ) <=Affix -> replen )
831
+ return NULL ;
827
832
strcpy (newword ,Affix -> find );
828
833
strcat (newword ,word + Affix -> replen );
829
834
}
@@ -927,7 +932,7 @@ NormalizeSubWord(IspellDict * Conf, char *word, char flag)
927
932
break ;
928
933
for (j = 0 ;j < prefix -> naff ;j ++ )
929
934
{
930
- if (CheckAffix (word ,wrdlen ,prefix -> aff [j ],flag ,newword ))
935
+ if (CheckAffix (word ,wrdlen ,prefix -> aff [j ],flag ,newword , NULL ))
931
936
{
932
937
/* prefix success */
933
938
if (FindWord (Conf ,newword ,prefix -> aff [j ]-> flag ,flag & FF_COMPOUNDWORD )&& (cur - forms )< (MAX_NORM - 1 ))
@@ -948,14 +953,16 @@ NormalizeSubWord(IspellDict * Conf, char *word, char flag)
948
953
*/
949
954
while (snode )
950
955
{
956
+ int baselen = 0 ;
957
+
951
958
/* find possible suffix */
952
959
suffix = FinfAffixes (snode ,word ,wrdlen ,& slevel ,FF_SUFFIX );
953
960
if (!suffix )
954
961
break ;
955
962
/* foreach suffix check affix */
956
963
for (i = 0 ;i < suffix -> naff ;i ++ )
957
964
{
958
- if (CheckAffix (word ,wrdlen ,suffix -> aff [i ],flag ,newword ))
965
+ if (CheckAffix (word ,wrdlen ,suffix -> aff [i ],flag ,newword , & baselen ))
959
966
{
960
967
/* suffix success */
961
968
if (FindWord (Conf ,newword ,suffix -> aff [i ]-> flag ,flag & FF_COMPOUNDWORD )&& (cur - forms )< (MAX_NORM - 1 ))
@@ -976,7 +983,7 @@ NormalizeSubWord(IspellDict * Conf, char *word, char flag)
976
983
break ;
977
984
for (j = 0 ;j < prefix -> naff ;j ++ )
978
985
{
979
- if (CheckAffix (newword ,swrdlen ,prefix -> aff [j ],flag ,pnewword ))
986
+ if (CheckAffix (newword ,swrdlen ,prefix -> aff [j ],flag ,pnewword , & baselen ))
980
987
{
981
988
/* prefix success */
982
989
int ff = (prefix -> aff [j ]-> flagflags & suffix -> aff [i ]-> flagflags & FF_CROSSPRODUCT ) ?
@@ -1323,15 +1330,15 @@ NIFree(IspellDict * Conf)
1323
1330
else
1324
1331
pg_regfree (& (Affix [i ].reg .regex ));
1325
1332
}
1326
- free (Affix [i ].mask );
1327
- free (Affix [i ].find );
1328
- free (Affix [i ].repl );
1333
+ if ( Affix [ i ]. mask != VoidString ) free (Affix [i ].mask );
1334
+ if ( Affix [ i ]. find != VoidString ) free (Affix [i ].find );
1335
+ if ( Affix [ i ]. repl != VoidString ) free (Affix [i ].repl );
1329
1336
}
1330
1337
if (Conf -> Spell )
1331
1338
{
1332
1339
for (i = 0 ;i < Conf -> nspell ;i ++ )
1333
- free (Conf -> Spell [i ]. word );
1334
- free (Conf -> Spell );
1340
+ pfree (Conf -> Spell [i ]-> word );
1341
+ pfree (Conf -> Spell );
1335
1342
}
1336
1343
1337
1344
if (Conf -> Affix )