• 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
212int makedent P ((char * lbuf, int lbuflen, struct dent * ent));
213/*int combinecaps P ((struct dent * hdr, struct dent * newent));
214#ifndef NO_CAPITALIZATION_SUPPORT
215static void forcevheader P ((struct dent * hdrp, struct dent * oldp,
216 struct dent * newp));
217#endif / * NO_CAPITALIZATION_SUPPORT * /
218static int combine_two_entries P ((struct dent * hdrp,
219 struct dent * oldp, struct dent * newp));
220static int acoversb P ((struct dent * enta, struct dent * entb));
221*/
222/*static int issubset P ((struct dent * ent1, struct dent * ent2));
223static void combineaffixes P ((struct dent * ent1, struct dent * ent2));*/
224
225void toutent P ((FILE * outfile, struct dent * hent,
226 int onlykeep));
227/*static void toutword P ((FILE * outfile, char * word,
228 struct dent * cent));
229static void flagout P ((FILE * outfile, int flag));
230*/
231#ifndef ICHAR_IS_CHAR
232ichar_t * icharcpy P ((ichar_t * out, ichar_t * in));
233int icharlen P ((ichar_t * str));
234int icharcmp P ((ichar_t * s1, ichar_t * s2));
235int 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.
244int makedent (lbuf, lbuflen, d)
245This function is not used by AbiWord. I don't know if it'll be needed for
246other abi documents
247 */
248
249#ifndef NO_CAPITALIZATION_SUPPORT
258long
259ISpellChecker::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
311int 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.
415int combinecaps (hdrp, newp)
416static void forcevheader (hdrp, oldp, newp)
417static int combine_two_entries (hdrp, oldp, newp)
418static int acoversb (enta, entb)
419*/
420
421/*
422 * \param s
423 */
424void
425ISpellChecker::upcase (ichar_t *s)
426{
427
428 while (*s)
429 {
430 *s = mytoupper (*s);
431 s++;
432 }
433}
434
435/*
436 * \param s
437 */
438void
439ISpellChecker::lowcase (ichar_t *s)
440{
441
442 while (*s)
443 {
444 *s = mytolower (*s);
445 s++;
446 }
447}
448
455void
456ISpellChecker::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.
468static int issubset (ent1, ent2)
469static 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.
476Removed -- not used by Abiword
477void toutent_ (toutfile, hent, onlykeep)
478static void toutword (toutfile, word, cent)
479static void flagout (toutfile, flag)
480*/
481
497int
498ISpellChecker::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/*
598int 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/*
608int 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/*
621int 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
640int
641ISpellChecker::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
673int
674ISpellChecker::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
717ichar_t *
718ISpellChecker::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
735char *
736ISpellChecker::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
753char *
754ISpellChecker::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
777ichar_t *
778icharcpy (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
795int
796icharlen (ichar_t * in)
797{
798 int len; /* Length so far */
799
800 for (len = 0; *in++ != 0; len++)
801 ;
802 return len;
803}
804
813int
814icharcmp (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
834int
835icharncmp (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 */
859int
860ISpellChecker::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*/
911char 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
919char 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
927int myspace(ichar_t c)
928{
929 return ((c > 0) && (c < 0x80) && isspace(static_cast<unsigned char>(c)));
930}
931
932char 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
940char 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
948char 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
956ichar_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
964ichar_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
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdespell2 by doxygen 1.9.4
This website is maintained by Timothy Pearson.