• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdespell2
 

tdespell2

  • tdespell2
  • plugins
  • ispell
tgood.cpp
1 /* enchant
2  * Copyright (C) 2003 Dom Lachowicz
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  * In addition, as a special exception, Dom Lachowicz
20  * gives permission to link the code of this program with
21  * non-LGPL Spelling Provider libraries (eg: a MSFT Office
22  * spell checker backend) and distribute linked combinations including
23  * the two. You must obey the GNU Lesser General Public License in all
24  * respects for all of the code used other than said providers. If you modify
25  * this file, you may extend this exception to your version of the
26  * file, but you are not obligated to do so. If you do not wish to
27  * do so, delete this exception statement from your version.
28  */
29 
30 /*
31  * Copyright 1987, 1988, 1989, 1992, 1993, Geoff Kuenning, Granada Hills, CA
32  * All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions
36  * are met:
37  *
38  * 1. Redistributions of source code must retain the above copyright
39  * notice, this list of conditions and the following disclaimer.
40  * 2. Redistributions in binary form must reproduce the above copyright
41  * notice, this list of conditions and the following disclaimer in the
42  * documentation and/or other materials provided with the distribution.
43  * 3. All modifications to the source code must be clearly marked as
44  * such. Binary redistributions based on modified source code
45  * must be clearly marked as modified versions in the documentation
46  * and/or other materials provided with the distribution.
47  * 4. All advertising materials mentioning features or use of this software
48  * must display the following acknowledgment:
49  * This product includes software developed by Geoff Kuenning and
50  * other unpaid contributors.
51  * 5. The name of Geoff Kuenning may not be used to endorse or promote
52  * products derived from this software without specific prior
53  * written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58  * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65  * SUCH DAMAGE.
66  */
67 
68 /*
69  * Table-driven version of good.c.
70  *
71  * Geoff Kuenning, July 1987
72  */
73 
74 /*
75  * $Log$
76  * Revision 1.1 2004/01/31 16:44:12 zrusin
77  * ISpell plugin.
78  *
79  * Revision 1.4 2003/08/14 17:51:29 dom
80  * update license - exception clause should be Lesser GPL
81  *
82  * Revision 1.3 2003/07/28 20:40:28 dom
83  * fix up the license clause, further win32-registry proof some directory getting functions
84  *
85  * Revision 1.2 2003/07/16 22:52:56 dom
86  * LGPL + exception license
87  *
88  * Revision 1.1 2003/07/15 01:15:09 dom
89  * ispell enchant backend
90  *
91  * Revision 1.2 2003/01/29 05:50:12 hippietrail
92  *
93  * Fixed my mess in EncodingManager.
94  * Changed many C casts to C++ casts.
95  *
96  * Revision 1.1 2003/01/24 05:52:36 hippietrail
97  *
98  * Refactored ispell code. Old ispell global variables had been put into
99  * an allocated structure, a pointer to which was passed to many functions.
100  * I have now made all such functions and variables private members of the
101  * ISpellChecker class. It was C OO, now it's C++ OO.
102  *
103  * I've fixed the makefiles and tested compilation but am unable to test
104  * operation. Please back out my changes if they cause problems which
105  * are not obvious or easy to fix.
106  *
107  * Revision 1.6 2003/01/06 18:48:42 dom
108  * ispell cleanup, start of using new 'add' save features
109  *
110  * Revision 1.5 2002/09/19 05:31:20 hippietrail
111  *
112  * More Ispell cleanup. Conditional globals and DEREF macros are removed.
113  * K&R function declarations removed, converted to Doxygen style comments
114  * where possible. No code has been changed (I hope). Compiles for me but
115  * unable to test.
116  *
117  * Revision 1.4 2002/09/17 03:03:31 hippietrail
118  *
119  * After seeking permission on the developer list I've reformatted all the
120  * spelling source which seemed to have parts which used 2, 3, 4, and 8
121  * spaces for tabs. It should all look good with our standard 4-space
122  * tabs now.
123  * I've concentrated just on indentation in the actual code. More prettying
124  * could be done.
125  * * NO code changes were made *
126  *
127  * Revision 1.3 2002/09/13 17:20:14 mpritchett
128  * Fix more warnings for Linux build
129  *
130  * Revision 1.2 2001/05/12 16:05:42 thomasf
131  * Big pseudo changes to ispell to make it pass around a structure rather
132  * than rely on all sorts of gloabals willy nilly here and there. Also
133  * fixed our spelling class to work with accepting suggestions once more.
134  * This code is dirty, gross and ugly (not to mention still not supporting
135  * multiple hash sized just yet) but it works on my machine and will no
136  * doubt break other machines.
137  *
138  * Revision 1.1 2001/04/15 16:01:24 tomas_f
139  * moving to spell/xp
140  *
141  * Revision 1.7 1999/10/20 06:03:56 sterwill
142  * Changed C++-style comments to C-style comments in C code.
143  *
144  * Revision 1.6 1999/10/20 03:19:35 paul
145  * Hacked ispell code to ignore any characters that don't fit in the lookup tables loaded from the dictionary. It ain't pretty, but at least we don't crash there any more.
146  *
147  * Revision 1.5 1999/04/13 17:12:51 jeff
148  * Applied "Darren O. Benham" <gecko@benham.net> spell check changes.
149  * Fixed crash on Win32 with the new code.
150  *
151  * Revision 1.4 1998/12/29 14:55:33 eric
152  *
153  * I've doctored the ispell code pretty extensively here. It is now
154  * warning-free on Win32. It also *works* on Win32 now, since I
155  * replaced all the I/O calls with ANSI standard ones.
156  *
157  * Revision 1.4 1998/12/29 14:55:33 eric
158  *
159  * I've doctored the ispell code pretty extensively here. It is now
160  * warning-free on Win32. It also *works* on Win32 now, since I
161  * replaced all the I/O calls with ANSI standard ones.
162  *
163  * Revision 1.3 1998/12/28 23:11:30 eric
164  *
165  * modified spell code and integration to build on Windows.
166  * This is still a hack.
167  *
168  * Actually, it doesn't yet WORK on Windows. It just builds.
169  * SpellCheckInit is failing for some reason.
170  *
171  * Revision 1.2 1998/12/28 22:16:22 eric
172  *
173  * These changes begin to incorporate the spell checker into AbiWord. Most
174  * of this is a hack.
175  *
176  * 1. added other/spell to the -I list in config/abi_defs
177  * 2. replaced other/spell/Makefile with one which is more like
178  * our build system.
179  * 3. added other/spell to other/Makefile so that the build will now
180  * dive down and build the spell check library.
181  * 4. added the AbiSpell library to the Makefiles in wp/main
182  * 5. added a call to SpellCheckInit in wp/main/unix/UnixMain.cpp.
183  * This call is a HACK and should be replaced with something
184  * proper later.
185  * 6. added code to fv_View.cpp as follows:
186  * whenever you double-click on a word, the spell checker
187  * verifies that word and prints its status to stdout.
188  *
189  * Caveats:
190  * 1. This will break the Windows build. I'm going to work on fixing it
191  * now.
192  * 2. This only works if your dictionary is in /usr/lib/ispell/american.hash.
193  * The dictionary location is currently hard-coded. This will be
194  * fixed as well.
195  *
196  * Anyway, such as it is, it works.
197  *
198  * Revision 1.1 1998/12/28 18:04:43 davet
199  * Spell checker code stripped from ispell. At this point, there are
200  * two external routines... the Init routine, and a check-a-word routine
201  * which returns a boolean value, and takes a 16 bit char string.
202  * The code resembles the ispell code as much as possible still.
203  *
204  * Revision 1.32 1994/11/02 06:56:16 geoff
205  * Remove the anyword feature, which I've decided is a bad idea.
206  *
207  * Revision 1.31 1994/10/25 05:46:25 geoff
208  * Add support for the FF_ANYWORD (affix applies to all words, even if
209  * flag bit isn't set) flag option.
210  *
211  * Revision 1.30 1994/05/24 06:23:08 geoff
212  * Don't create a hit if "allhits" is clear and capitalization
213  * mismatches. This cures a bug where a word could be in the dictionary
214  * and yet not found.
215  *
216  * Revision 1.29 1994/05/17 06:44:21 geoff
217  * Add support for controlled compound formation and the COMPOUNDONLY
218  * option to affix flags.
219  *
220  * Revision 1.28 1994/01/25 07:12:13 geoff
221  * Get rid of all old RCS log lines in preparation for the 3.1 release.
222  *
223  */
224 
225 #include <ctype.h>
226 #include <stdlib.h>
227 #include <string.h>
228 
229 #include "ispell_checker.h"
230 
242 void ISpellChecker::chk_aff (ichar_t *word, ichar_t *ucword,
243  int len, int ignoreflagbits, int allhits, int pfxopts, int sfxopts)
244 {
245  ichar_t * cp; /* Pointer to char to index on */
246  struct flagptr * ind; /* Flag index table to test */
247 
248  pfx_list_chk (word, ucword, len, pfxopts, sfxopts, &m_pflagindex[0],
249  ignoreflagbits, allhits);
250  cp = ucword;
251  /* HACK: bail on unrecognized chars */
252  if (*cp >= (SET_SIZE + MAXSTRINGCHARS))
253  return;
254  ind = &m_pflagindex[*cp++];
255  while (ind->numents == 0 && ind->pu.fp != NULL)
256  {
257  if (*cp == 0)
258  return;
259  if (ind->pu.fp[0].numents)
260  {
261  pfx_list_chk (word, ucword, len, pfxopts, sfxopts, &ind->pu.fp[0],
262  ignoreflagbits, allhits);
263  if (m_numhits && !allhits && /* !cflag && */ !ignoreflagbits)
264  return;
265  }
266  /* HACK: bail on unrecognized chars */
267  if (*cp >= (SET_SIZE + MAXSTRINGCHARS))
268  return;
269  ind = &ind->pu.fp[*cp++];
270  }
271  pfx_list_chk (word, ucword, len, pfxopts, sfxopts, ind, ignoreflagbits,
272  allhits);
273  if (m_numhits && !allhits && /* !cflag &&*/ !ignoreflagbits)
274  return;
275  chk_suf (word, ucword, len, sfxopts, static_cast<struct flagent *>(NULL),
276  ignoreflagbits, allhits);
277 }
278 
291 void ISpellChecker::pfx_list_chk (ichar_t *word, ichar_t *ucword, int len, int optflags,
292  int sfxopts, struct flagptr * ind, int ignoreflagbits, int allhits)
293 {
294  int cond; /* Condition number */
295  ichar_t * cp; /* Pointer into end of ucword */
296  struct dent * dent; /* Dictionary entry we found */
297  int entcount; /* Number of entries to process */
298  struct flagent *
299  flent; /* Current table entry */
300  int preadd; /* Length added to tword2 as prefix */
301  int tlen; /* Length of tword */
302  ichar_t tword[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4]; /* Tmp cpy */
303  ichar_t tword2[sizeof tword]; /* 2nd copy for ins_root_cap */
304 
305  for (flent = ind->pu.ent, entcount = ind->numents;
306  entcount > 0;
307  flent++, entcount--)
308  {
309  /*
310  * If this is a compound-only affix, ignore it unless we're
311  * looking for that specific thing.
312  */
313  if ((flent->flagflags & FF_COMPOUNDONLY) != 0
314  && (optflags & FF_COMPOUNDONLY) == 0)
315  continue;
316 
317  /*
318  * See if the prefix matches.
319  */
320  tlen = len - flent->affl;
321  if (tlen > 0
322  && (flent->affl == 0
323  || icharncmp (flent->affix, ucword, flent->affl) == 0)
324  && tlen + flent->stripl >= flent->numconds)
325  {
326  /*
327  * The prefix matches. Remove it, replace it by the "strip"
328  * string (if any), and check the original conditions.
329  */
330  if (flent->stripl)
331  icharcpy (tword, flent->strip);
332  icharcpy (tword + flent->stripl, ucword + flent->affl);
333  cp = tword;
334  for (cond = 0; cond < flent->numconds; cond++)
335  {
336  if ((flent->conds[*cp++] & (1 << cond)) == 0)
337  break;
338  }
339  if (cond >= flent->numconds)
340  {
341  /*
342  * The conditions match. See if the word is in the
343  * dictionary.
344  */
345  tlen += flent->stripl;
346 
347  if (ignoreflagbits)
348  {
349  if ((dent = ispell_lookup (tword, 1)) != NULL)
350  {
351  cp = tword2;
352  if (flent->affl)
353  {
354  icharcpy (cp, flent->affix);
355  cp += flent->affl;
356  *cp++ = '+';
357  }
358  preadd = cp - tword2;
359  icharcpy (cp, tword);
360  cp += tlen;
361  if (flent->stripl)
362  {
363  *cp++ = '-';
364  icharcpy (cp, flent->strip);
365  }
366  }
367  }
368  else if ((dent = ispell_lookup (tword, 1)) != NULL
369  && TSTMASKBIT (dent->mask, flent->flagbit))
370  {
371  if (m_numhits < MAX_HITS)
372  {
373  m_hits[m_numhits].dictent = dent;
374  m_hits[m_numhits].prefix = flent;
375  m_hits[m_numhits].suffix = NULL;
376  m_numhits++;
377  }
378  if (!allhits)
379  {
380 #ifndef NO_CAPITALIZATION_SUPPORT
381  if (cap_ok (word, &m_hits[0], len))
382  return;
383  m_numhits = 0;
384 #else /* NO_CAPITALIZATION_SUPPORT */
385  return;
386 #endif /* NO_CAPITALIZATION_SUPPORT */
387  }
388  }
389  /*
390  * Handle cross-products.
391  */
392  if (flent->flagflags & FF_CROSSPRODUCT)
393  chk_suf (word, tword, tlen, sfxopts | FF_CROSSPRODUCT,
394  flent, ignoreflagbits, allhits);
395  }
396  }
397  }
398 }
399 
411 void
412 ISpellChecker::chk_suf (ichar_t *word, ichar_t *ucword,
413  int len, int optflags, struct flagent *pfxent,
414  int ignoreflagbits, int allhits)
415 {
416  ichar_t * cp; /* Pointer to char to index on */
417  struct flagptr * ind; /* Flag index table to test */
418 
419  suf_list_chk (word, ucword, len, &m_sflagindex[0], optflags, pfxent,
420  ignoreflagbits, allhits);
421  cp = ucword + len - 1;
422  /* HACK: bail on unrecognized chars */
423  if (*cp >= (SET_SIZE + MAXSTRINGCHARS))
424  return;
425  ind = &m_sflagindex[*cp];
426  while (ind->numents == 0 && ind->pu.fp != NULL)
427  {
428  if (cp == ucword)
429  return;
430  if (ind->pu.fp[0].numents)
431  {
432  suf_list_chk (word, ucword, len, &ind->pu.fp[0],
433  optflags, pfxent, ignoreflagbits, allhits);
434  if (m_numhits != 0 && !allhits && /* !cflag && */ !ignoreflagbits)
435  return;
436  }
437  /* HACK: bail on unrecognized chars */
438  if (*(cp-1) >= (SET_SIZE + MAXSTRINGCHARS))
439  return;
440  ind = &ind->pu.fp[*--cp];
441  }
442  suf_list_chk (word, ucword, len, ind, optflags, pfxent,
443  ignoreflagbits, allhits);
444 }
445 
456 void ISpellChecker::suf_list_chk (ichar_t *word, ichar_t *ucword,
457  int len, struct flagptr *ind, int optflags,
458  struct flagent *pfxent, int ignoreflagbits, int allhits)
459 {
460  ichar_t * cp; /* Pointer into end of ucword */
461  int cond; /* Condition number */
462  struct dent * dent; /* Dictionary entry we found */
463  int entcount; /* Number of entries to process */
464  struct flagent *
465  flent; /* Current table entry */
466  int preadd; /* Length added to tword2 as prefix */
467  int tlen; /* Length of tword */
468  ichar_t tword[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4]; /* Tmp cpy */
469  ichar_t tword2[sizeof tword]; /* 2nd copy for ins_root_cap */
470 
471  icharcpy (tword, ucword);
472  for (flent = ind->pu.ent, entcount = ind->numents;
473  entcount > 0;
474  flent++, entcount--)
475  {
476  if ((optflags & FF_CROSSPRODUCT) != 0
477  && (flent->flagflags & FF_CROSSPRODUCT) == 0)
478  continue;
479  /*
480  * If this is a compound-only affix, ignore it unless we're
481  * looking for that specific thing.
482  */
483  if ((flent->flagflags & FF_COMPOUNDONLY) != 0
484  && (optflags & FF_COMPOUNDONLY) == 0)
485  continue;
486 
487  /*
488  * See if the suffix matches.
489  */
490  tlen = len - flent->affl;
491  if (tlen > 0
492  && (flent->affl == 0
493  || icharcmp (flent->affix, ucword + tlen) == 0)
494  && tlen + flent->stripl >= flent->numconds)
495  {
496  /*
497  * The suffix matches. Remove it, replace it by the "strip"
498  * string (if any), and check the original conditions.
499  */
500  icharcpy (tword, ucword);
501  cp = tword + tlen;
502  if (flent->stripl)
503  {
504  icharcpy (cp, flent->strip);
505  tlen += flent->stripl;
506  cp = tword + tlen;
507  }
508  else
509  *cp = '\0';
510  for (cond = flent->numconds; --cond >= 0; )
511  {
512  if ((flent->conds[*--cp] & (1 << cond)) == 0)
513  break;
514  }
515  if (cond < 0)
516  {
517  /*
518  * The conditions match. See if the word is in the
519  * dictionary.
520  */
521  if (ignoreflagbits)
522  {
523  if ((dent = ispell_lookup (tword, 1)) != NULL)
524  {
525  cp = tword2;
526  if ((optflags & FF_CROSSPRODUCT)
527  && pfxent->affl != 0)
528  {
529  icharcpy (cp, pfxent->affix);
530  cp += pfxent->affl;
531  *cp++ = '+';
532  }
533  preadd = cp - tword2;
534  icharcpy (cp, tword);
535  cp += tlen;
536  if ((optflags & FF_CROSSPRODUCT)
537  && pfxent->stripl != 0)
538  {
539  *cp++ = '-';
540  icharcpy (cp, pfxent->strip);
541  cp += pfxent->stripl;
542  }
543  if (flent->stripl)
544  {
545  *cp++ = '-';
546  icharcpy (cp, flent->strip);
547  cp += flent->stripl;
548  }
549  if (flent->affl)
550  {
551  *cp++ = '+';
552  icharcpy (cp, flent->affix);
553  cp += flent->affl;
554  }
555  }
556  }
557  else if ((dent = ispell_lookup (tword, 1)) != NULL
558  && TSTMASKBIT (dent->mask, flent->flagbit)
559  && ((optflags & FF_CROSSPRODUCT) == 0
560  || TSTMASKBIT (dent->mask, pfxent->flagbit)))
561  {
562  if (m_numhits < MAX_HITS)
563  {
564  m_hits[m_numhits].dictent = dent;
565  m_hits[m_numhits].prefix = pfxent;
566  m_hits[m_numhits].suffix = flent;
567  m_numhits++;
568  }
569  if (!allhits)
570  {
571 #ifndef NO_CAPITALIZATION_SUPPORT
572  if (cap_ok (word, &m_hits[0], len))
573  return;
574  m_numhits = 0;
575 #else /* NO_CAPITALIZATION_SUPPORT */
576  return;
577 #endif /* NO_CAPITALIZATION_SUPPORT */
578  }
579  }
580  }
581  }
582  }
583 }
584 
596 int ISpellChecker::expand_pre (char *croot, ichar_t *rootword, MASKTYPE mask[],
597  int option, char *extra)
598 {
599  int entcount; /* No. of entries to process */
600  int explength; /* Length of expansions */
601  struct flagent *
602  flent; /* Current table entry */
603 
604  for (flent = m_pflaglist, entcount = m_numpflags, explength = 0;
605  entcount > 0;
606  flent++, entcount--)
607  {
608  if (TSTMASKBIT (mask, flent->flagbit))
609  explength +=
610  pr_pre_expansion (croot, rootword, flent, mask, option, extra);
611  }
612  return explength;
613 }
614 
627 int ISpellChecker::pr_pre_expansion ( char *croot, ichar_t *rootword,
628  struct flagent *flent, MASKTYPE mask[], int option,
629  char *extra)
630 {
631  int cond; /* Current condition number */
632  ichar_t * nextc; /* Next case choice */
633  int tlen; /* Length of tword */
634  ichar_t tword[INPUTWORDLEN + MAXAFFIXLEN]; /* Temp */
635 
636  tlen = icharlen (rootword);
637  if (flent->numconds > tlen)
638  return 0;
639  tlen -= flent->stripl;
640  if (tlen <= 0)
641  return 0;
642  tlen += flent->affl;
643  for (cond = 0, nextc = rootword; cond < flent->numconds; cond++)
644  {
645  if ((flent->conds[mytoupper (*nextc++)] & (1 << cond)) == 0)
646  return 0;
647  }
648  /*
649  * The conditions are satisfied. Copy the word, add the prefix,
650  * and make it the proper case. This code is carefully written
651  * to match that ins_cap and cap_ok. Note that the affix, as
652  * inserted, is uppercase.
653  *
654  * There is a tricky bit here: if the root is capitalized, we
655  * want a capitalized result. If the root is followcase, however,
656  * we want to duplicate the case of the first remaining letter
657  * of the root. In other words, "Loved/U" should generate "Unloved",
658  * but "LOved/U" should generate "UNLOved" and "lOved/U" should
659  * produce "unlOved".
660  */
661  if (flent->affl)
662  {
663  icharcpy (tword, flent->affix);
664  nextc = tword + flent->affl;
665  }
666  icharcpy (nextc, rootword + flent->stripl);
667  if (myupper (rootword[0]))
668  {
669  /* We must distinguish followcase from capitalized and all-upper */
670  for (nextc = rootword + 1; *nextc; nextc++)
671  {
672  if (!myupper (*nextc))
673  break;
674  }
675  if (*nextc)
676  {
677  /* It's a followcase or capitalized word. Figure out which. */
678  for ( ; *nextc; nextc++)
679  {
680  if (myupper (*nextc))
681  break;
682  }
683  if (*nextc)
684  {
685  /* It's followcase. */
686  if (!myupper (tword[flent->affl]))
687  forcelc (tword, flent->affl);
688  }
689  else
690  {
691  /* It's capitalized */
692  forcelc (tword + 1, tlen - 1);
693  }
694  }
695  }
696  else
697  {
698  /* Followcase or all-lower, we don't care which */
699  if (!myupper (*nextc))
700  forcelc (tword, flent->affl);
701  }
702  if (option == 3)
703  printf ("\n%s", croot);
704  if (option != 4)
705  printf (" %s%s", ichartosstr (tword, 1), extra);
706  if (flent->flagflags & FF_CROSSPRODUCT)
707  return tlen
708  + expand_suf (croot, tword, mask, FF_CROSSPRODUCT, option, extra);
709  else
710  return tlen;
711 }
712 
725 int ISpellChecker::expand_suf (char *croot, ichar_t *rootword, MASKTYPE mask[],
726  int optflags, int option, char *extra)
727 {
728  int entcount; /* No. of entries to process */
729  int explength; /* Length of expansions */
730  struct flagent *
731  flent; /* Current table entry */
732 
733  for (flent = m_sflaglist, entcount = m_numsflags, explength = 0;
734  entcount > 0;
735  flent++, entcount--)
736  {
737  if (TSTMASKBIT (mask, flent->flagbit))
738  {
739  if ((optflags & FF_CROSSPRODUCT) == 0
740  || (flent->flagflags & FF_CROSSPRODUCT))
741  explength +=
742  pr_suf_expansion (croot, rootword, flent, option, extra);
743  }
744  }
745  return explength;
746 }
747 
759 int ISpellChecker::pr_suf_expansion (char *croot, ichar_t *rootword,
760  struct flagent *flent, int option, char *extra)
761 {
762  int cond; /* Current condition number */
763  ichar_t * nextc; /* Next case choice */
764  int tlen; /* Length of tword */
765  ichar_t tword[INPUTWORDLEN + MAXAFFIXLEN]; /* Temp */
766 
767  tlen = icharlen (rootword);
768  cond = flent->numconds;
769  if (cond > tlen)
770  return 0;
771  if (tlen - flent->stripl <= 0)
772  return 0;
773  for (nextc = rootword + tlen; --cond >= 0; )
774  {
775  if ((flent->conds[mytoupper (*--nextc)] & (1 << cond)) == 0)
776  return 0;
777  }
778  /*
779  * The conditions are satisfied. Copy the word, add the suffix,
780  * and make it match the case of the last remaining character of the
781  * root. Again, this code carefully matches ins_cap and cap_ok.
782  */
783  icharcpy (tword, rootword);
784  nextc = tword + tlen - flent->stripl;
785  if (flent->affl)
786  {
787  icharcpy (nextc, flent->affix);
788  if (!myupper (nextc[-1]))
789  forcelc (nextc, flent->affl);
790  }
791  else
792  *nextc = 0;
793  if (option == 3)
794  printf ("\n%s", croot);
795  if (option != 4)
796  printf (" %s%s", ichartosstr (tword, 1), extra);
797  return tlen + flent->affl - flent->stripl;
798 }
799 
804 void ISpellChecker::forcelc (ichar_t *dst, int len) /* Force to lowercase */
805 {
806 
807  for ( ; --len >= 0; dst++)
808  *dst = mytolower (*dst);
809 }

tdespell2

Skip menu "tdespell2"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

tdespell2

Skip menu "tdespell2"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdespell2 by doxygen 1.8.8
This website is maintained by Timothy Pearson.