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

tdespell2

  • tdespell2
  • plugins
  • ispell
makedent.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 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  * $Log$
70  * Revision 1.2 2004/02/01 04:46:46 zrusin
71  * Both ispell and aspell plugins are not working properly. We can start switching.
72  *
73  * Revision 1.1 2004/01/31 16:44:12 zrusin
74  * ISpell plugin.
75  *
76  * Revision 1.4 2003/08/14 17:51:28 dom
77  * update license - exception clause should be Lesser GPL
78  *
79  * Revision 1.3 2003/07/28 20:40:27 dom
80  * fix up the license clause, further win32-registry proof some directory getting functions
81  *
82  * Revision 1.2 2003/07/16 22:52:49 dom
83  * LGPL + exception license
84  *
85  * Revision 1.1 2003/07/15 01:15:08 dom
86  * ispell enchant backend
87  *
88  * Revision 1.3 2003/02/12 02:10:38 hippietrail
89  *
90  * C casts -> C++ casts
91  * Improved const-correctness due to changing casts
92  * Fixed some warnings
93  *
94  * Revision 1.2 2003/01/29 05:50:12 hippietrail
95  *
96  * Fixed my mess in EncodingManager.
97  * Changed many C casts to C++ casts.
98  *
99  * Revision 1.1 2003/01/24 05:52:35 hippietrail
100  *
101  * Refactored ispell code. Old ispell global variables had been put into
102  * an allocated structure, a pointer to which was passed to many functions.
103  * I have now made all such functions and variables private members of the
104  * ISpellChecker class. It was C OO, now it's C++ OO.
105  *
106  * I've fixed the makefiles and tested compilation but am unable to test
107  * operation. Please back out my changes if they cause problems which
108  * are not obvious or easy to fix.
109  *
110  * Revision 1.8 2003/01/06 18:48:40 dom
111  * ispell cleanup, start of using new 'add' save features
112  *
113  * Revision 1.7 2003/01/04 19:09:04 dom
114  * some tidying... bug pissing me off...
115  *
116  * Revision 1.6 2002/09/19 05:31:18 hippietrail
117  *
118  * More Ispell cleanup. Conditional globals and DEREF macros are removed.
119  * K&R function declarations removed, converted to Doxygen style comments
120  * where possible. No code has been changed (I hope). Compiles for me but
121  * unable to test.
122  *
123  * Revision 1.5 2002/09/17 03:03:30 hippietrail
124  *
125  * After seeking permission on the developer list I've reformatted all the
126  * spelling source which seemed to have parts which used 2, 3, 4, and 8
127  * spaces for tabs. It should all look good with our standard 4-space
128  * tabs now.
129  * I've concentrated just on indentation in the actual code. More prettying
130  * could be done.
131  * * NO code changes were made *
132  *
133  * Revision 1.4 2002/09/13 17:20:13 mpritchett
134  * Fix more warnings for Linux build
135  *
136  * Revision 1.3 2002/03/22 14:31:57 dom
137  * fix mg's compile problem
138  *
139  * Revision 1.2 2001/05/12 16:05:42 thomasf
140  * Big pseudo changes to ispell to make it pass around a structure rather
141  * than rely on all sorts of gloabals willy nilly here and there. Also
142  * fixed our spelling class to work with accepting suggestions once more.
143  * This code is dirty, gross and ugly (not to mention still not supporting
144  * multiple hash sized just yet) but it works on my machine and will no
145  * doubt break other machines.
146  *
147  * Revision 1.1 2001/04/15 16:01:24 tomas_f
148  * moving to spell/xp
149  *
150  * Revision 1.6 1999/12/21 18:46:29 sterwill
151  * ispell patch for non-English dictionaries by Henrik Berg <henrik@lansen.se>
152  *
153  * Revision 1.5 1999/10/20 03:19:35 paul
154  * 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.
155  *
156  * Revision 1.4 1999/04/13 17:12:51 jeff
157  * Applied "Darren O. Benham" <gecko@benham.net> spell check changes.
158  * Fixed crash on Win32 with the new code.
159  *
160  * Revision 1.3 1998/12/29 14:55:33 eric
161  *
162  * I've doctored the ispell code pretty extensively here. It is now
163  * warning-free on Win32. It also *works* on Win32 now, since I
164  * replaced all the I/O calls with ANSI standard ones.
165  *
166  * Revision 1.3 1998/12/29 14:55:33 eric
167  *
168  * I've doctored the ispell code pretty extensively here. It is now
169  * warning-free on Win32. It also *works* on Win32 now, since I
170  * replaced all the I/O calls with ANSI standard ones.
171  *
172  * Revision 1.2 1998/12/28 23:11:30 eric
173  *
174  * modified spell code and integration to build on Windows.
175  * This is still a hack.
176  *
177  * Actually, it doesn't yet WORK on Windows. It just builds.
178  * SpellCheckInit is failing for some reason.
179  *
180  * Revision 1.1 1998/12/28 18:04:43 davet
181  * Spell checker code stripped from ispell. At this point, there are
182  * two external routines... the Init routine, and a check-a-word routine
183  * which returns a boolean value, and takes a 16 bit char string.
184  * The code resembles the ispell code as much as possible still.
185  *
186  * Revision 1.45 1994/12/27 23:08:52 geoff
187  * Add code to makedent to reject words that contain non-word characters.
188  * This helps protect people who use ISO 8-bit characters when ispell
189  * isn't configured for that option.
190  *
191  * Revision 1.44 1994/10/25 05:46:20 geoff
192  * Fix some incorrect declarations in the lint versions of some routines.
193  *
194  * Revision 1.43 1994/09/16 03:32:34 geoff
195  * Issue an error message for bad affix flags
196  *
197  * Revision 1.42 1994/02/07 04:23:43 geoff
198  * Correctly identify the deformatter when changing file types
199  *
200  * Revision 1.41 1994/01/25 07:11:55 geoff
201  * Get rid of all old RCS log lines in preparation for the 3.1 release.
202  *
203  */
204 
205 #include <stdlib.h>
206 #include <string.h>
207 #include <ctype.h>
208 
209 #include "ispell_checker.h"
210 #include "msgs.h"
211 
212 int makedent P ((char * lbuf, int lbuflen, struct dent * ent));
213 /*int combinecaps P ((struct dent * hdr, struct dent * newent));
214 #ifndef NO_CAPITALIZATION_SUPPORT
215 static void forcevheader P ((struct dent * hdrp, struct dent * oldp,
216  struct dent * newp));
217 #endif / * NO_CAPITALIZATION_SUPPORT * /
218 static int combine_two_entries P ((struct dent * hdrp,
219  struct dent * oldp, struct dent * newp));
220 static int acoversb P ((struct dent * enta, struct dent * entb));
221 */
222 /*static int issubset P ((struct dent * ent1, struct dent * ent2));
223 static void combineaffixes P ((struct dent * ent1, struct dent * ent2));*/
224 
225 void toutent P ((FILE * outfile, struct dent * hent,
226  int onlykeep));
227 /*static void toutword P ((FILE * outfile, char * word,
228  struct dent * cent));
229 static void flagout P ((FILE * outfile, int flag));
230 */
231 #ifndef ICHAR_IS_CHAR
232 ichar_t * icharcpy P ((ichar_t * out, ichar_t * in));
233 int icharlen P ((ichar_t * str));
234 int icharcmp P ((ichar_t * s1, ichar_t * s2));
235 int icharncmp P ((ichar_t * s1, ichar_t * s2, int n));
236 #endif
237 
238 /*static int has_marker;*/
239 
240 /*
241  * Fill in a directory entry, including setting the capitalization flags, and
242  * allocate and initialize memory for the d->word field. Returns -1
243  * if there was trouble. The input word must be in canonical form.
244 int makedent (lbuf, lbuflen, d)
245 This function is not used by AbiWord. I don't know if it'll be needed for
246 other abi documents
247  */
248 
249 #ifndef NO_CAPITALIZATION_SUPPORT
250 
258 long
259 ISpellChecker::whatcap (ichar_t *word)
260 {
261  ichar_t * p;
262 
263  for (p = word; *p; p++)
264  {
265  if (mylower (*p))
266  break;
267  }
268  if (*p == '\0')
269  return ALLCAPS;
270  else
271  {
272  for ( ; *p; p++)
273  {
274  if (myupper (*p))
275  break;
276  }
277  if (*p == '\0')
278  {
279  /*
280  ** No uppercase letters follow the lowercase ones.
281  ** If there is more than one uppercase letter, it's
282  ** "followcase". If only the first one is capitalized,
283  ** it's "capitalize". If there are no capitals
284  ** at all, it's ANYCASE.
285  */
286  if (myupper (word[0]))
287  {
288  for (p = word + 1; *p != '\0'; p++)
289  {
290  if (myupper (*p))
291  return FOLLOWCASE;
292  }
293  return CAPITALIZED;
294  }
295  else
296  return ANYCASE;
297  }
298  else
299  return FOLLOWCASE; /* .../lower/upper */
300  }
301 }
302 
311 int ISpellChecker::addvheader ( struct dent *dp)
312 {
313  struct dent * tdent; /* Copy of entry */
314 
315  /*
316  ** Add a second entry with the correct capitalization, and then make
317  ** dp into a special dummy entry.
318  */
319  tdent = static_cast<struct dent *>(malloc(sizeof (struct dent)));
320  if (tdent == NULL)
321  {
322  fprintf (stderr, MAKEDENT_C_NO_WORD_SPACE, dp->word);
323  return -1;
324  }
325  *tdent = *dp;
326  if (captype (tdent->flagfield) != FOLLOWCASE)
327  tdent->word = NULL;
328  else
329  {
330  /* Followcase words need a copy of the capitalization */
331  tdent->word = static_cast<char *>(malloc (static_cast<unsigned int>(strlen(tdent->word)) + 1));
332  if (tdent->word == NULL)
333  {
334  fprintf (stderr, MAKEDENT_C_NO_WORD_SPACE, dp->word);
335  free (reinterpret_cast<char *>(tdent));
336  return -1;
337  }
338  strcpy (tdent->word, dp->word);
339  }
340  chupcase (dp->word);
341  dp->next = tdent;
342  dp->flagfield &= ~CAPTYPEMASK;
343  dp->flagfield |= (ALLCAPS | MOREVARIANTS);
344  return 0;
345 }
346 #endif
347 
348 /*
349 ** Combine and resolve the entries describing two capitalizations of the same
350 ** word. This may require allocating yet more entries.
351 **
352 ** Hdrp is a pointer into a hash table. If the word covered by hdrp has
353 ** variations, hdrp must point to the header. Newp is a pointer to temporary
354 ** storage, and space is malloc'ed if newp is to be kept. The newp->word
355 ** field must have been allocated with mymalloc, so that this routine may free
356 ** the space if it keeps newp but not the word.
357 **
358 ** Return value: 0 if the word was added, 1 if the word was combined
359 ** with an existing entry, and -1 if trouble occurred (e.g., malloc).
360 ** If 1 is returned, newp->word may have been be freed using myfree.
361 **
362 ** Life is made much more difficult by the KEEP flag's possibilities. We
363 ** must ensure that a !KEEP word doesn't find its way into the personal
364 ** dictionary as a result of this routine's actions. However, a !KEEP
365 ** word that has affixes must have come from the main dictionary, so it
366 ** is acceptable to combine entries in that case (got that?).
367 **
368 ** The net result of all this is a set of rules that is a bloody pain
369 ** to figure out. Basically, we want to choose one of the following actions:
370 **
371 ** (1) Add newp's affixes and KEEP flag to oldp, and discard newp.
372 ** (2) Add oldp's affixes and KEEP flag to newp, replace oldp with
373 ** newp, and discard newp.
374 #ifndef NO_CAPITALIZATION_SUPPORT
375 ** (3) Insert newp as a new entry in the variants list. If there is
376 ** currently no variant header, this requires adding one. Adding a
377 ** header splits into two sub-cases:
378 **
379 ** (3a) If oldp is ALLCAPS and the KEEP flags match, just turn it
380 ** into the header.
381 ** (3b) Otherwise, add a new entry to serve as the header.
382 ** To ease list linking, this is done by copying oldp into
383 ** the new entry, and then performing (3a).
384 **
385 ** After newp has been added as a variant, its affixes and KEEP
386 ** flag are OR-ed into the variant header.
387 #endif
388 **
389 ** So how to choose which? The default is always case (3), which adds newp
390 ** as a new entry in the variants list. Cases (1) and (2) are symmetrical
391 ** except for which entry is discarded. We can use case (1) or (2) whenever
392 ** one entry "covers" the other. "Covering" is defined as follows:
393 **
394 ** (4) For entries with matching capitalization types, A covers B
395 ** if:
396 **
397 ** (4a) B's affix flags are a subset of A's, or the KEEP flags
398 ** match, and
399 ** (4b) either the KEEP flags match, or A's KEEP flag is set.
400 ** (Since A has more suffixes, combining B with it won't
401 ** cause any extra suffixes to be added to the dictionary.)
402 ** (4c) If the words are FOLLOWCASE, the capitalizations match
403 ** exactly.
404 **
405 #ifndef NO_CAPITALIZATION_SUPPORT
406 ** (5) For entries with mismatched capitalization types, A covers B
407 ** if (4a) and (4b) are true, and:
408 **
409 ** (5a) B is ALLCAPS, or
410 ** (5b) A is ANYCASE, and B is CAPITALIZED.
411 #endif
412 **
413 ** For any "hdrp" without variants, oldp is the same as hdrp. Otherwise,
414 ** the above tests are applied using each variant in turn for oldp.
415 int combinecaps (hdrp, newp)
416 static void forcevheader (hdrp, oldp, newp)
417 static int combine_two_entries (hdrp, oldp, newp)
418 static int acoversb (enta, entb)
419 */
420 
421 /*
422  * \param s
423  */
424 void
425 ISpellChecker::upcase (ichar_t *s)
426 {
427 
428  while (*s)
429  {
430  *s = mytoupper (*s);
431  s++;
432  }
433 }
434 
435 /*
436  * \param s
437  */
438 void
439 ISpellChecker::lowcase (ichar_t *s)
440 {
441 
442  while (*s)
443  {
444  *s = mytolower (*s);
445  s++;
446  }
447 }
448 
455 void
456 ISpellChecker::chupcase (char *s)
457 {
458  ichar_t * is;
459 
460  is = strtosichar (s, 1);
461  upcase (is);
462  ichartostr (s, is, strlen (s) + 1, 1);
463 }
464 
465 /*
466 ** See if one affix field is a subset of another. Returns NZ if ent1
467 ** is a subset of ent2. The KEEP flag is not taken into consideration.
468 static int issubset (ent1, ent2)
469 static void combineaffixes (ent1, ent2)
470 */
471 
472 /*
473 ** Write out a dictionary entry, including capitalization variants.
474 ** If onlykeep is true, only those variants with KEEP set will be
475 ** written.
476 Removed -- not used by Abiword
477 void toutent_ (toutfile, hent, onlykeep)
478 static void toutword (toutfile, word, cent)
479 static void flagout (toutfile, flag)
480 */
481 
497 int
498 ISpellChecker::stringcharlen (char *bufp, int canonical)
499 {
500 #ifdef SLOWMULTIPLY
501  static char * sp[MAXSTRINGCHARS];
502  static int inited = 0;
503 #endif
504  char * bufcur;
505  char * stringcur;
506  int stringno;
507  int lowstringno;
508  int highstringno;
509  int dupwanted;
510 
511 #ifdef SLOWMULTIPLY
512  if (!inited)
513  {
514  inited = 1;
515  for (stringno = 0; stringno < MAXSTRINGCHARS; stringno++)
516  sp[stringno] = &hashheader.stringchars[stringno][0];
517  }
518 #endif
519  lowstringno = 0;
520  highstringno = m_hashheader.nstrchars - 1;
521  dupwanted = canonical ? 0 : m_defdupchar;
522  while (lowstringno <= highstringno)
523  {
524  stringno = (lowstringno + highstringno) >> 1;
525 #ifdef SLOWMULTIPLY
526  stringcur = sp[stringno];
527 #else
528  stringcur = &m_hashheader.stringchars[stringno][0];
529 #endif
530  bufcur = bufp;
531  while (*stringcur)
532  {
533 #ifdef NO8BIT
534  if (((*bufcur++ ^ *stringcur) & 0x7F) != 0)
535 #else
536  if (*bufcur++ != *stringcur)
537 #endif
538  break;
539  /*
540  ** We can't use autoincrement above because of the
541  ** test below.
542  */
543  stringcur++;
544  }
545  if (*stringcur == '\0')
546  {
547  if (m_hashheader.dupnos[stringno] == dupwanted)
548  {
549  /* We have a match */
550  m_laststringch = m_hashheader.stringdups[stringno];
551 #ifdef SLOWMULTIPLY
552  return stringcur - sp[stringno];
553 #else
554  return stringcur - &m_hashheader.stringchars[stringno][0];
555 #endif
556  }
557  else
558  --stringcur;
559  }
560  /* No match - choose which side to search on */
561 #ifdef NO8BIT
562  if ((*--bufcur & 0x7F) < (*stringcur & 0x7F))
563  highstringno = stringno - 1;
564  else if ((*bufcur & 0x7F) > (*stringcur & 0x7F))
565  lowstringno = stringno + 1;
566 #else
567  if (*--bufcur < *stringcur)
568  highstringno = stringno - 1;
569  else if (*bufcur > *stringcur)
570  lowstringno = stringno + 1;
571 #endif
572  else if (dupwanted < m_hashheader.dupnos[stringno])
573  highstringno = stringno - 1;
574  else
575  lowstringno = stringno + 1;
576  }
577  m_laststringch = static_cast<unsigned int>(-1);
578  return 0; /* Not a string character */
579 }
580 
581 /* MACROS CONVERTED TO FUNCTIONS
582 ** These macros are similar to the ones above, but they take into account
583 ** the possibility of string characters. Note well that they take a POINTER,
584 ** not a character.
585 **
586 ** The "l_" versions set "len" to the length of the string character as a
587 ** handy side effect. (Note that the global "laststringch" is also set,
588 ** and sometimes used, by these macros.)
589 **
590 ** The "l1_" versions go one step further and guarantee that the "len"
591 ** field is valid for *all* characters, being set to 1 even if the macro
592 ** returns false. This macro is a great example of how NOT to write
593 ** readable C.
594 */
595 #define isstringch(ptr, canon) (isstringstart (*(ptr)) \
596  && stringcharlen ((ptr), (canon)) > 0)
597 /*
598 int isstringch(char *ptr, int canon) {
599  return (isstringstart (*(ptr)) && (len = stringcharlen ((ptr), (canon))) > 0);
600 }
601 */
602 
603 #define l_isstringch(ptr, len, canon) \
604  (isstringstart (*(ptr)) \
605  && (len = stringcharlen ((ptr), (canon))) \
606  > 0)
607 /*
608 int l_isstringch(char *ptr, int len, int canon) {
609  return (isstringstart (*(ptr)) && (len = stringcharlen ((ptr), (canon))) > 0);
610 }
611 */
612 
613 #define l1_isstringch(ptr, len, canon) \
614  (len = 1, \
615  isstringstart ((unsigned char)(*(ptr))) \
616  && ((len = \
617  stringcharlen ((ptr), (canon))) \
618  > 0 \
619  ? 1 : (len = 1, 0)))
620 /*
621 int l1_isstringch(char *ptr, int len, int canon) {
622  return (len = 1, isstringstart ((unsigned char)(*(ptr))) &&
623  ((len = stringcharlen ((ptr), (canon))) > 0 ? 1 : (len = 1, 0)));
624 }
625 */
626 
627 /*** END MACRO CONVERSION ***/
628 
640 int
641 ISpellChecker::strtoichar (ichar_t *out, char *in, int outlen, int canonical)
642 {
643  int len = 1; /* Length of next character */
644 
645  outlen /= sizeof (ichar_t); /* Convert to an ichar_t count */
646  for ( ; --outlen > 0 && *in != '\0'; in += len)
647  {
648  if (l1_isstringch (in, len , canonical)) {
649  *out++ = SET_SIZE + m_laststringch;
650  } else {
651  *out++ = (unsigned char)( *in );
652  }
653  }
654  *out = 0;
655  return outlen <= 0;
656 }
657 
673 int
674 ISpellChecker::ichartostr ( char *out, ichar_t *in, int outlen, int canonical)
675 {
676  int ch; /* Next character to store */
677  int i; /* Index into duplicates list */
678  char * scharp; /* Pointer into a string char */
679 
680  while (--outlen > 0 && (ch = *in++) != 0)
681  {
682  if (ch < SET_SIZE)
683  *out++ = static_cast<char>(ch);
684  else
685  {
686  ch -= SET_SIZE;
687  if (!canonical)
688  {
689  for (i = m_hashheader.nstrchars; --i >= 0; )
690  {
691  if (m_hashheader.dupnos[i] == m_defdupchar
692  && (static_cast<int>(m_hashheader.stringdups[i])) == ch)
693  {
694  ch = i;
695  break;
696  }
697  }
698  }
699  scharp = m_hashheader.stringchars[static_cast<unsigned>(ch)];
700  while ((*out++ = *scharp++) != '\0')
701  ;
702  out--;
703  }
704  }
705  *out = '\0';
706  return outlen <= 0;
707 }
708 
717 ichar_t *
718 ISpellChecker::strtosichar ( char *in, int canonical)
719 {
720  static ichar_t out[STRTOSICHAR_SIZE / sizeof (ichar_t)];
721 
722  if (strtoichar (out, in, sizeof out, canonical))
723  fprintf (stderr, WORD_TOO_LONG (in));
724  return out;
725 }
726 
735 char *
736 ISpellChecker::ichartosstr (ichar_t *in, int canonical)
737 {
738  static char out[ICHARTOSSTR_SIZE];
739 
740  if (ichartostr (out, in, sizeof out, canonical))
741  fprintf (stderr, WORD_TOO_LONG (out));
742  return out;
743 }
744 
753 char *
754 ISpellChecker::printichar (int in)
755 {
756  static char out[MAXSTRINGCHARLEN + 1];
757 
758  if (in < SET_SIZE)
759  {
760  out[0] = static_cast<char>(in);
761  out[1] = '\0';
762  }
763  else
764  strcpy (out, m_hashheader.stringchars[static_cast<unsigned>(in) - SET_SIZE]);
765  return out;
766 }
767 
768 #ifndef ICHAR_IS_CHAR
769 
777 ichar_t *
778 icharcpy (ichar_t *out, ichar_t *in)
779 {
780  ichar_t * origout; /* Copy of destination for return */
781 
782  origout = out;
783  while ((*out++ = *in++) != 0)
784  ;
785  return origout;
786 }
787 
795 int
796 icharlen (ichar_t * in)
797 {
798  int len; /* Length so far */
799 
800  for (len = 0; *in++ != 0; len++)
801  ;
802  return len;
803 }
804 
813 int
814 icharcmp (ichar_t * s1, ichar_t * s2)
815 {
816 
817  while (*s1 != 0)
818  {
819  if (*s1++ != *s2++)
820  return *--s1 - *--s2;
821  }
822  return *s1 - *s2;
823 }
824 
834 int
835 icharncmp (ichar_t *s1, ichar_t *s2, int n)
836 {
837 
838  while (--n >= 0 && *s1 != 0)
839  {
840  if (*s1++ != *s2++)
841  return *--s1 - *--s2;
842  }
843  if (n < 0)
844  return 0;
845  else
846  return *s1 - *s2;
847 }
848 
849 #endif
850 
851 /*
852  * \param istate
853  * \param name
854  * \param searchnames
855  * \param deformatter
856  *
857  * \return
858  */
859 int
860 ISpellChecker::findfiletype (const char *name, int searchnames, int *deformatter)
861 {
862  char * cp; /* Pointer into suffix list */
863  int cplen; /* Length of current suffix */
864  int i; /* Index into type table */
865  int len; /* Length of the name */
866 
867  /*
868  * Note: for now, the deformatter is set to 1 for tex, 0 for nroff.
869  * Further, we assume that it's one or the other, so that a test
870  * for tex is sufficient. This needs to be generalized.
871  */
872  len = strlen (name);
873  if (searchnames)
874  {
875  for (i = 0; i < m_hashheader.nstrchartype; i++)
876  {
877  if (strcmp (name, m_chartypes[i].name) == 0)
878  {
879  if (deformatter != NULL)
880  *deformatter =
881  (strcmp (m_chartypes[i].deformatter, "tex") == 0);
882  return i;
883  }
884  }
885  }
886  for (i = 0; i < m_hashheader.nstrchartype; i++)
887  {
888  for (cp = m_chartypes[i].suffixes; *cp != '\0'; cp += cplen + 1)
889  {
890  cplen = strlen (cp);
891  if (len >= cplen && strcmp (&name[len - cplen], cp) == 0)
892  {
893  if (deformatter != NULL)
894  *deformatter =
895  (strcmp (m_chartypes[i].deformatter, "tex") == 0);
896  return i;
897  }
898  }
899  }
900  return -1;
901 }
902 
903 /*
904  HACK: macros replaced with function implementations
905  so we could do a side-effect-free check for unicode
906  characters which aren't in hashheader
907 
908  TODO: this is just a workaround to keep us from crashing.
909  more sophisticated logic needed here.
910 */
911 char ISpellChecker::myupper(ichar_t c)
912 {
913  if (c < (SET_SIZE + MAXSTRINGCHARS))
914  return m_hashheader.upperchars[c];
915  else
916  return 0;
917 }
918 
919 char ISpellChecker::mylower(ichar_t c)
920 {
921  if (c < (SET_SIZE + MAXSTRINGCHARS))
922  return m_hashheader.lowerchars[c];
923  else
924  return 0;
925 }
926 
927 int myspace(ichar_t c)
928 {
929  return ((c > 0) && (c < 0x80) && isspace(static_cast<unsigned char>(c)));
930 }
931 
932 char ISpellChecker::iswordch(ichar_t c)
933 {
934  if (c < (SET_SIZE + MAXSTRINGCHARS))
935  return m_hashheader.wordchars[c];
936  else
937  return 0;
938 }
939 
940 char ISpellChecker::isboundarych(ichar_t c)
941 {
942  if (c < (SET_SIZE + MAXSTRINGCHARS))
943  return m_hashheader.boundarychars[c];
944  else
945  return 0;
946 }
947 
948 char ISpellChecker::isstringstart(ichar_t c)
949 {
950  if (c < (SET_SIZE))
951  return m_hashheader.stringstarts[static_cast<unsigned char>(c)];
952  else
953  return 0;
954 }
955 
956 ichar_t ISpellChecker::mytolower(ichar_t c)
957 {
958  if (c < (SET_SIZE + MAXSTRINGCHARS))
959  return m_hashheader.lowerconv[c];
960  else
961  return c;
962 }
963 
964 ichar_t ISpellChecker::mytoupper (ichar_t c)
965 {
966  if (c < (SET_SIZE + MAXSTRINGCHARS))
967  return m_hashheader.upperconv[c];
968  else
969  return c;
970 }
971 

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.