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

kspell2

  • kspell2
  • plugins
  • ispell
lookup.cpp
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* kspell2 - adopted from enchant
3  * Copyright (C) 2003 Dom Lachowicz
4  * Copyright (C) 2004 Zack Rusin <zack@kde.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * In addition, as a special exception, Dom Lachowicz
22  * gives permission to link the code of this program with
23  * non-LGPL Spelling Provider libraries (eg: a MSFT Office
24  * spell checker backend) and distribute linked combinations including
25  * the two. You must obey the GNU General Public License in all
26  * respects for all of the code used other than said providers. If you modify
27  * this file, you may extend this exception to your version of the
28  * file, but you are not obligated to do so. If you do not wish to
29  * do so, delete this exception statement from your version.
30  */
31 
32 /*
33  * lookup.c - see if a word appears in the dictionary
34  *
35  * Pace Willisson, 1983
36  *
37  * Copyright 1987, 1988, 1989, 1992, 1993, Geoff Kuenning, Granada Hills, CA
38  * All rights reserved.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  *
44  * 1. Redistributions of source code must retain the above copyright
45  * notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  * notice, this list of conditions and the following disclaimer in the
48  * documentation and/or other materials provided with the distribution.
49  * 3. All modifications to the source code must be clearly marked as
50  * such. Binary redistributions based on modified source code
51  * must be clearly marked as modified versions in the documentation
52  * and/or other materials provided with the distribution.
53  * 4. All advertising materials mentioning features or use of this software
54  * must display the following acknowledgment:
55  * This product includes software developed by Geoff Kuenning and
56  * other unpaid contributors.
57  * 5. The name of Geoff Kuenning may not be used to endorse or promote
58  * products derived from this software without specific prior
59  * written permission.
60  *
61  * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
62  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64  * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
65  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
70  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71  * SUCH DAMAGE.
72  */
73 
74 /*
75  * $Log$
76  * Revision 1.1 2004/01/31 16:44:12 zrusin
77  * ISpell plugin.
78  *
79  * Revision 1.7 2003/09/25 02:44:48 dom
80  * bug 5813
81  *
82  * Revision 1.6 2003/08/26 13:20:40 dom
83  * ispell crasher fix, implement enchant_dictionary_release
84  *
85  * Revision 1.5 2003/08/26 13:08:03 uwog
86  * Fix segfault when the requested dictionary couldn't be found.
87  *
88  * Revision 1.4 2003/08/14 16:27:36 dom
89  * update some documentation
90  *
91  * Revision 1.3 2003/07/28 20:40:27 dom
92  * fix up the license clause, further win32-registry proof some directory getting functions
93  *
94  * Revision 1.2 2003/07/16 22:52:47 dom
95  * LGPL + exception license
96  *
97  * Revision 1.1 2003/07/15 01:15:07 dom
98  * ispell enchant backend
99  *
100  * Revision 1.3 2003/01/29 05:50:12 hippietrail
101  *
102  * Fixed my mess in EncodingManager.
103  * Changed many C casts to C++ casts.
104  *
105  * Revision 1.2 2003/01/25 03:16:05 hippietrail
106  *
107  * An UT_ICONV_INVALID fix which escaped the last commit.
108  *
109  * Revision 1.1 2003/01/24 05:52:34 hippietrail
110  *
111  * Refactored ispell code. Old ispell global variables had been put into
112  * an allocated structure, a pointer to which was passed to many functions.
113  * I have now made all such functions and variables private members of the
114  * ISpellChecker class. It was C OO, now it's C++ OO.
115  *
116  * I've fixed the makefiles and tested compilation but am unable to test
117  * operation. Please back out my changes if they cause problems which
118  * are not obvious or easy to fix.
119  *
120  * Revision 1.12 2003/01/06 18:48:39 dom
121  * ispell cleanup, start of using new 'add' save features
122  *
123  * Revision 1.11 2002/09/19 05:31:17 hippietrail
124  *
125  * More Ispell cleanup. Conditional globals and DEREF macros are removed.
126  * K&R function declarations removed, converted to Doxygen style comments
127  * where possible. No code has been changed (I hope). Compiles for me but
128  * unable to test.
129  *
130  * Revision 1.10 2002/09/17 03:03:30 hippietrail
131  *
132  * After seeking permission on the developer list I've reformatted all the
133  * spelling source which seemed to have parts which used 2, 3, 4, and 8
134  * spaces for tabs. It should all look good with our standard 4-space
135  * tabs now.
136  * I've concentrated just on indentation in the actual code. More prettying
137  * could be done.
138  * * NO code changes were made *
139  *
140  * Revision 1.9 2002/09/13 17:20:13 mpritchett
141  * Fix more warnings for Linux build
142  *
143  * Revision 1.8 2002/05/03 09:49:43 fjfranklin
144  * o hash downloader update (Gabriel Gerhardsson)
145  * - Comment out the "Can't open <dictionary>" printf.
146  * - Make the progressbar more clean at the begining of the download.
147  * - Add support for tarballs that doesn't have the full path included
148  * - Fix copyright headers on the newly added files (*HashDownloader.*)
149  *
150  * Revision 1.7 2001/08/27 19:06:30 dom
151  * Lots of compilation fixes
152  *
153  * Revision 1.6 2001/08/10 18:32:40 dom
154  * Spelling and iconv updates. god, i hate iconv
155  *
156  * Revision 1.5 2001/08/10 09:57:49 hub
157  * Patch by sobomax@FreeBSD.org
158  * #include "iconv.h" directive is missed from src/other/spell/xp/lookup.c and
159  * src/wp/impexp/xp/ie_imp_RTF.cpp.
160  * See bug 1823
161  *
162  * Revision 1.4 2001/07/18 17:46:01 dom
163  * Module changes, and fix compiler warnings
164  *
165  * Revision 1.3 2001/06/12 21:32:49 dom
166  * More ispell work...
167  *
168  * Revision 1.2 2001/05/12 16:05:42 thomasf
169  * Big pseudo changes to ispell to make it pass around a structure rather
170  * than rely on all sorts of gloabals willy nilly here and there. Also
171  * fixed our spelling class to work with accepting suggestions once more.
172  * This code is dirty, gross and ugly (not to mention still not supporting
173  * multiple hash sized just yet) but it works on my machine and will no
174  * doubt break other machines.
175  *
176  * Revision 1.1 2001/04/15 16:01:24 tomas_f
177  * moving to spell/xp
178  *
179  * Revision 1.7 1999/09/29 23:33:32 justin
180  * Updates to the underlying ispell-based code to support suggested corrections.
181  *
182  * Revision 1.6 1999/04/13 17:12:51 jeff
183  * Applied "Darren O. Benham" <gecko@benham.net> spell check changes.
184  * Fixed crash on Win32 with the new code.
185  *
186  * Revision 1.5 1999/01/07 01:07:48 paul
187  * Fixed spell leaks.
188  *
189  * Revision 1.5 1999/01/07 01:07:48 paul
190  * Fixed spell leaks.
191  *
192  * Revision 1.4 1998/12/29 14:55:33 eric
193  *
194  * I've doctored the ispell code pretty extensively here. It is now
195  * warning-free on Win32. It also *works* on Win32 now, since I
196  * replaced all the I/O calls with ANSI standard ones.
197  *
198  * Revision 1.3 1998/12/28 23:11:30 eric
199  *
200  * modified spell code and integration to build on Windows.
201  * This is still a hack.
202  *
203  * Actually, it doesn't yet WORK on Windows. It just builds.
204  * SpellCheckInit is failing for some reason.
205  *
206  * Revision 1.2 1998/12/28 22:16:22 eric
207  *
208  * These changes begin to incorporate the spell checker into AbiWord. Most
209  * of this is a hack.
210  *
211  * 1. added other/spell to the -I list in config/abi_defs
212  * 2. replaced other/spell/Makefile with one which is more like
213  * our build system.
214  * 3. added other/spell to other/Makefile so that the build will now
215  * dive down and build the spell check library.
216  * 4. added the AbiSpell library to the Makefiles in wp/main
217  * 5. added a call to SpellCheckInit in wp/main/unix/UnixMain.cpp.
218  * This call is a HACK and should be replaced with something
219  * proper later.
220  * 6. added code to fv_View.cpp as follows:
221  * whenever you double-click on a word, the spell checker
222  * verifies that word and prints its status to stdout.
223  *
224  * Caveats:
225  * 1. This will break the Windows build. I'm going to work on fixing it
226  * now.
227  * 2. This only works if your dictionary is in /usr/lib/ispell/american.hash.
228  * The dictionary location is currently hard-coded. This will be
229  * fixed as well.
230  *
231  * Anyway, such as it is, it works.
232  *
233  * Revision 1.1 1998/12/28 18:04:43 davet
234  * Spell checker code stripped from ispell. At this point, there are
235  * two external routines... the Init routine, and a check-a-word routine
236  * which returns a boolean value, and takes a 16 bit char string.
237  * The code resembles the ispell code as much as possible still.
238  *
239  * Revision 1.42 1995/01/08 23:23:42 geoff
240  * Support MSDOS_BINARY_OPEN when opening the hash file to read it in.
241  *
242  * Revision 1.41 1994/01/25 07:11:51 geoff
243  * Get rid of all old RCS log lines in preparation for the 3.1 release.
244  *
245  */
246 
247 #include <stdlib.h>
248 #include <string.h>
249 #include <ctype.h>
250 
251 #include "ispell_checker.h"
252 #include "msgs.h"
253 
254 #ifdef INDEXDUMP
255 static void dumpindex P ((struct flagptr * indexp, int depth));
256 #endif /* INDEXDUMP */
257 
258 int gnMaskBits = 64;
259 
265 int ISpellChecker::linit (char *hashname)
266 {
267  FILE* fpHash;
268 
269  int i;
270  struct dent * dp;
271  struct flagent * entry;
272  struct flagptr * ind;
273  int nextchar, x;
274  int viazero;
275  ichar_t * cp;
276 
277  if ((fpHash = fopen (hashname, "rb")) == NULL)
278  {
279  return (-1);
280  }
281 
282  m_hashsize = fread (reinterpret_cast<char *>(&m_hashheader), 1, sizeof m_hashheader, fpHash);
283  if (m_hashsize < static_cast<int>(sizeof(m_hashheader)))
284  {
285  if (m_hashsize < 0)
286  fprintf (stderr, LOOKUP_C_CANT_READ, hashname);
287  else if (m_hashsize == 0)
288  fprintf (stderr, LOOKUP_C_NULL_HASH, hashname);
289  else
290  fprintf (stderr,
291  LOOKUP_C_SHORT_HASH (m_hashname, m_hashsize,
292  static_cast<int>(sizeof m_hashheader)));
293  return (-1);
294  }
295  else if (m_hashheader.magic != MAGIC)
296  {
297  fprintf (stderr,
298  LOOKUP_C_BAD_MAGIC (hashname, static_cast<unsigned int>(MAGIC),
299  static_cast<unsigned int>(m_hashheader.magic)));
300  return (-1);
301  }
302  else if (m_hashheader.magic2 != MAGIC)
303  {
304  fprintf (stderr,
305  LOOKUP_C_BAD_MAGIC2 (hashname, static_cast<unsigned int>(MAGIC),
306  static_cast<unsigned int>(m_hashheader.magic2)));
307  return (-1);
308  }
309 /* else if (hashheader.compileoptions != COMPILEOPTIONS*/
310  else if ( 1 != 1
311  || m_hashheader.maxstringchars != MAXSTRINGCHARS
312  || m_hashheader.maxstringcharlen != MAXSTRINGCHARLEN)
313  {
314  fprintf (stderr,
315  LOOKUP_C_BAD_OPTIONS (static_cast<unsigned int>(m_hashheader.compileoptions),
316  m_hashheader.maxstringchars, m_hashheader.maxstringcharlen,
317  static_cast<unsigned int>(COMPILEOPTIONS), MAXSTRINGCHARS, MAXSTRINGCHARLEN));
318  return (-1);
319  }
320 
321  {
322  m_hashtbl =
323  (struct dent *)
324  calloc (static_cast<unsigned>(m_hashheader.tblsize), sizeof (struct dent));
325  m_hashsize = m_hashheader.tblsize;
326  m_hashstrings = static_cast<char *>(malloc(static_cast<unsigned>(m_hashheader.stringsize)));
327  }
328  m_numsflags = m_hashheader.stblsize;
329  m_numpflags = m_hashheader.ptblsize;
330  m_sflaglist = (struct flagent *)
331  malloc ((m_numsflags + m_numpflags) * sizeof (struct flagent));
332  if (m_hashtbl == NULL || m_hashstrings == NULL || m_sflaglist == NULL)
333  {
334  fprintf (stderr, LOOKUP_C_NO_HASH_SPACE);
335  return (-1);
336  }
337  m_pflaglist = m_sflaglist + m_numsflags;
338 
339  {
340  if( fread ( m_hashstrings, 1, static_cast<unsigned>(m_hashheader.stringsize), fpHash)
341  != static_cast<size_t>(m_hashheader.stringsize) )
342  {
343  fprintf (stderr, LOOKUP_C_BAD_FORMAT);
344  fprintf (stderr, "stringsize err\n" );
345  return (-1);
346  }
347  if ( m_hashheader.compileoptions & 0x04 )
348  {
349  if( fread (reinterpret_cast<char *>(m_hashtbl), 1, static_cast<unsigned>(m_hashheader.tblsize) * sizeof(struct dent), fpHash)
350  != (static_cast<size_t>(m_hashheader.tblsize * sizeof (struct dent))))
351  {
352  fprintf (stderr, LOOKUP_C_BAD_FORMAT);
353  return (-1);
354  }
355  }
356  else
357  {
358  for( x=0; x<m_hashheader.tblsize; x++ )
359  {
360  if( fread ( reinterpret_cast<char*>(m_hashtbl+x), sizeof( struct dent)-sizeof( MASKTYPE ), 1, fpHash)
361  != 1)
362  {
363  fprintf (stderr, LOOKUP_C_BAD_FORMAT);
364  return (-1);
365  }
366  } /*for*/
367  } /*else*/
368  }
369  if (fread (reinterpret_cast<char *>(m_sflaglist), 1,
370  static_cast<unsigned>(m_numsflags+ m_numpflags) * sizeof (struct flagent), fpHash)
371  != (m_numsflags + m_numpflags) * sizeof (struct flagent))
372  {
373  fprintf (stderr, LOOKUP_C_BAD_FORMAT);
374  return (-1);
375  }
376  fclose (fpHash);
377 
378  {
379  for (i = m_hashsize, dp = m_hashtbl; --i >= 0; dp++)
380  {
381  if (dp->word == (char *) -1)
382  dp->word = NULL;
383  else
384  dp->word = &m_hashstrings [ reinterpret_cast<size_t>(dp->word) ];
385  if (dp->next == (struct dent *) -1)
386  dp->next = NULL;
387  else
388  dp->next = &m_hashtbl [ reinterpret_cast<size_t>(dp->next) ];
389  }
390  }
391 
392  for (i = m_numsflags + m_numpflags, entry = m_sflaglist; --i >= 0; entry++)
393  {
394  if (entry->stripl)
395  entry->strip = reinterpret_cast<ichar_t *>(&m_hashstrings[reinterpret_cast<size_t>(entry->strip)]);
396  else
397  entry->strip = NULL;
398  if (entry->affl)
399  entry->affix = reinterpret_cast<ichar_t *>(&m_hashstrings[reinterpret_cast<size_t>(entry->affix)]);
400  else
401  entry->affix = NULL;
402  }
403  /*
404  ** Warning - 'entry' and 'i' are reset in the body of the loop
405  ** below. Don't try to optimize it by (e.g.) moving the decrement
406  ** of i into the loop condition.
407  */
408  for (i = m_numsflags, entry = m_sflaglist; i > 0; i--, entry++)
409  {
410  if (entry->affl == 0)
411  {
412  cp = NULL;
413  ind = &m_sflagindex[0];
414  viazero = 1;
415  }
416  else
417  {
418  cp = entry->affix + entry->affl - 1;
419  ind = &m_sflagindex[*cp];
420  viazero = 0;
421  while (ind->numents == 0 && ind->pu.fp != NULL)
422  {
423  if (cp == entry->affix)
424  {
425  ind = &ind->pu.fp[0];
426  viazero = 1;
427  }
428  else
429  {
430  ind = &ind->pu.fp[*--cp];
431  viazero = 0;
432  }
433  }
434  }
435  if (ind->numents == 0)
436  ind->pu.ent = entry;
437  ind->numents++;
438  /*
439  ** If this index entry has more than MAXSEARCH flags in
440  ** it, we will split it into subentries to reduce the
441  ** searching. However, the split doesn't make sense in
442  ** two cases: (a) if we are already at the end of the
443  ** current affix, or (b) if all the entries in the list
444  ** have identical affixes. Since the list is sorted, (b)
445  ** is true if the first and last affixes in the list
446  ** are identical.
447  */
448  if (!viazero && ind->numents >= MAXSEARCH
449  && icharcmp (entry->affix, ind->pu.ent->affix) != 0)
450  {
451  /* Sneaky trick: back up and reprocess */
452  entry = ind->pu.ent - 1; /* -1 is for entry++ in loop */
453  i = m_numsflags - (entry - m_sflaglist);
454  ind->pu.fp =
455  (struct flagptr *)
456  calloc (static_cast<unsigned>(SET_SIZE + m_hashheader.nstrchars),
457  sizeof (struct flagptr));
458  if (ind->pu.fp == NULL)
459  {
460  fprintf (stderr, LOOKUP_C_NO_LANG_SPACE);
461  return (-1);
462  }
463  ind->numents = 0;
464  }
465  }
466  /*
467  ** Warning - 'entry' and 'i' are reset in the body of the loop
468  ** below. Don't try to optimize it by (e.g.) moving the decrement
469  ** of i into the loop condition.
470  */
471  for (i = m_numpflags, entry = m_pflaglist; i > 0; i--, entry++)
472  {
473  if (entry->affl == 0)
474  {
475  cp = NULL;
476  ind = &m_pflagindex[0];
477  viazero = 1;
478  }
479  else
480  {
481  cp = entry->affix;
482  ind = &m_pflagindex[*cp++];
483  viazero = 0;
484  while (ind->numents == 0 && ind->pu.fp != NULL)
485  {
486  if (*cp == 0)
487  {
488  ind = &ind->pu.fp[0];
489  viazero = 1;
490  }
491  else
492  {
493  ind = &ind->pu.fp[*cp++];
494  viazero = 0;
495  }
496  }
497  }
498  if (ind->numents == 0)
499  ind->pu.ent = entry;
500  ind->numents++;
501  /*
502  ** If this index entry has more than MAXSEARCH flags in
503  ** it, we will split it into subentries to reduce the
504  ** searching. However, the split doesn't make sense in
505  ** two cases: (a) if we are already at the end of the
506  ** current affix, or (b) if all the entries in the list
507  ** have identical affixes. Since the list is sorted, (b)
508  ** is true if the first and last affixes in the list
509  ** are identical.
510  */
511  if (!viazero && ind->numents >= MAXSEARCH
512  && icharcmp (entry->affix, ind->pu.ent->affix) != 0)
513  {
514  /* Sneaky trick: back up and reprocess */
515  entry = ind->pu.ent - 1; /* -1 is for entry++ in loop */
516  i = m_numpflags - (entry - m_pflaglist);
517  ind->pu.fp =
518  static_cast<struct flagptr *>(calloc(SET_SIZE + m_hashheader.nstrchars,
519  sizeof (struct flagptr)));
520  if (ind->pu.fp == NULL)
521  {
522  fprintf (stderr, LOOKUP_C_NO_LANG_SPACE);
523  return (-1);
524  }
525  ind->numents = 0;
526  }
527  }
528 #ifdef INDEXDUMP
529  fprintf (stderr, "Prefix index table:\n");
530  dumpindex (m_pflagindex, 0);
531  fprintf (stderr, "Suffix index table:\n");
532  dumpindex (m_sflagindex, 0);
533 #endif
534  if (m_hashheader.nstrchartype == 0)
535  m_chartypes = NULL;
536  else
537  {
538  m_chartypes = (struct strchartype *)
539  malloc (m_hashheader.nstrchartype * sizeof (struct strchartype));
540  if (m_chartypes == NULL)
541  {
542  fprintf (stderr, LOOKUP_C_NO_LANG_SPACE);
543  return (-1);
544  }
545  for (i = 0, nextchar = m_hashheader.strtypestart;
546  i < m_hashheader.nstrchartype;
547  i++)
548  {
549  m_chartypes[i].name = &m_hashstrings[nextchar];
550  nextchar += strlen (m_chartypes[i].name) + 1;
551  m_chartypes[i].deformatter = &m_hashstrings[nextchar];
552  nextchar += strlen (m_chartypes[i].deformatter) + 1;
553  m_chartypes[i].suffixes = &m_hashstrings[nextchar];
554  while (m_hashstrings[nextchar] != '\0')
555  nextchar += strlen (&m_hashstrings[nextchar]) + 1;
556  nextchar++;
557  }
558  }
559 
560  initckch(NULL);
561 
562  return (0);
563 }
564 
565 #ifndef FREEP
566 #define FREEP(p) do { if (p) free(p); } while (0)
567 #endif
568 
572 void ISpellChecker::initckch (char *wchars)
573 {
574  ichar_t c;
575  char num[4];
576 
577  for (c = 0; c < static_cast<ichar_t>(SET_SIZE+ m_hashheader.nstrchars); ++c)
578  {
579  if (iswordch (c))
580  {
581  if (!mylower (c))
582  {
583  m_Try[m_Trynum] = c;
584  ++m_Trynum;
585  }
586  }
587  else if (isboundarych (c))
588  {
589  m_Try[m_Trynum] = c;
590  ++m_Trynum;
591  }
592  }
593  if (wchars != NULL)
594  {
595  while (m_Trynum < SET_SIZE && *wchars != '\0')
596  {
597  if (*wchars != 'n' && *wchars != '\\')
598  {
599  c = *wchars;
600  ++wchars;
601  }
602  else
603  {
604  ++wchars;
605  num[0] = '\0';
606  num[1] = '\0';
607  num[2] = '\0';
608  num[3] = '\0';
609  if (isdigit (wchars[0]))
610  {
611  num[0] = wchars[0];
612  if (isdigit (wchars[1]))
613  {
614  num[1] = wchars[1];
615  if (isdigit (wchars[2]))
616  num[2] = wchars[2];
617  }
618  }
619  if (wchars[-1] == 'n')
620  {
621  wchars += strlen (num);
622  c = atoi (num);
623  }
624  else
625  {
626  wchars += strlen (num);
627  c = 0;
628  if (num[0])
629  c = num[0] - '0';
630  if (num[1])
631  {
632  c <<= 3;
633  c += num[1] - '0';
634  }
635  if (num[2])
636  {
637  c <<= 3;
638  c += num[2] - '0';
639  }
640  }
641  }
642 /* c &= NOPARITY;*/
643  if (!m_hashheader.wordchars[c])
644  {
645  m_hashheader.wordchars[c] = 1;
646  m_hashheader.sortorder[c] = m_hashheader.sortval++;
647  m_Try[m_Trynum] = c;
648  ++m_Trynum;
649  }
650  }
651  }
652 }
653 
654 /*
655  * \param indexp
656  */
657 void ISpellChecker::clearindex (struct flagptr *indexp)
658 {
659  int i;
660  for (i = 0; i < SET_SIZE + m_hashheader.nstrchars; i++, indexp++)
661  {
662  if (indexp->numents == 0 && indexp->pu.fp != NULL)
663  {
664  clearindex(indexp->pu.fp);
665  free(indexp->pu.fp);
666  }
667  }
668 }
669 
670 #ifdef INDEXDUMP
671 static void dumpindex (indexp, depth)
672  struct flagptr * indexp;
673  int depth;
674 {
675  int i;
676  int j;
677  int k;
678  char stripbuf[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4];
679 
680  for (i = 0; i < SET_SIZE + hashheader.nstrchars; i++, indexp++)
681  {
682  if (indexp->numents == 0 && indexp->pu.fp != NULL)
683  {
684  for (j = depth; --j >= 0; )
685  putc (' ', stderr);
686  if (i >= ' ' && i <= '~')
687  putc (i, stderr);
688  else
689  fprintf (stderr, "0x%x", i);
690  putc ('\n', stderr);
691  dumpindex (indexp->pu.fp, depth + 1);
692  }
693  else if (indexp->numents)
694  {
695  for (j = depth; --j >= 0; )
696  putc (' ', stderr);
697  if (i >= ' ' && i <= '~')
698  putc (i, stderr);
699  else
700  fprintf (stderr, "0x%x", i);
701  fprintf (stderr, " -> %d entries\n", indexp->numents);
702  for (k = 0; k < indexp->numents; k++)
703  {
704  for (j = depth; --j >= 0; )
705  putc (' ', stderr);
706  if (indexp->pu.ent[k].stripl)
707  {
708  ichartostr (stripbuf, indexp->pu.ent[k].strip,
709  sizeof stripbuf, 1);
710  fprintf (stderr, " entry %d (-%s,%s)\n",
711  &indexp->pu.ent[k] - sflaglist,
712  stripbuf,
713  indexp->pu.ent[k].affl
714  ? ichartosstr (indexp->pu.ent[k].affix, 1) : "-");
715  }
716  else
717  fprintf (stderr, " entry %d (%s)\n",
718  &indexp->pu.ent[k] - sflaglist,
719  ichartosstr (indexp->pu.ent[k].affix, 1));
720  }
721  }
722  }
723 }
724 #endif
725 
726 /* n is length of s */
727 
728 /*
729  * \param s
730  * \param dotree
731  *
732  * \return
733  */
734 struct dent * ISpellChecker::ispell_lookup (ichar_t *s, int dotree)
735 {
736  struct dent * dp;
737  char * s1;
738  char schar[INPUTWORDLEN + MAXAFFIXLEN];
739 
740  dp = &m_hashtbl[hash (s, m_hashsize)];
741  if (ichartostr (schar, s, sizeof schar, 1))
742  fprintf (stderr, WORD_TOO_LONG (schar));
743  for ( ; dp != NULL; dp = dp->next)
744  {
745  /* quick strcmp, but only for equality */
746  s1 = dp->word;
747  if (s1 && s1[0] == schar[0] && strcmp (s1 + 1, schar + 1) == 0)
748  return dp;
749 #ifndef NO_CAPITALIZATION_SUPPORT
750  while (dp->flagfield & MOREVARIANTS) /* Skip variations */
751  dp = dp->next;
752 #endif
753  }
754  return NULL;
755 }
756 
757 void ISpellChecker::alloc_ispell_struct()
758 {
759  m_translate_in = 0;
760 }
761 
762 void ISpellChecker::free_ispell_struct()
763 {
764 }

kspell2

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

kspell2

Skip menu "kspell2"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kspell2 by doxygen 1.8.1.2
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |