00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 #include <stdlib.h>
00248 #include <string.h>
00249 #include <ctype.h>
00250
00251 #include "ispell_checker.h"
00252 #include "msgs.h"
00253
00254 #ifdef INDEXDUMP
00255 static void dumpindex P ((struct flagptr * indexp, int depth));
00256 #endif
00257
00258 int gnMaskBits = 64;
00259
00265 int ISpellChecker::linit (char *hashname)
00266 {
00267 FILE* fpHash;
00268
00269 register int i;
00270 register struct dent * dp;
00271 struct flagent * entry;
00272 struct flagptr * ind;
00273 int nextchar, x;
00274 int viazero;
00275 register ichar_t * cp;
00276
00277 if ((fpHash = fopen (hashname, "rb")) == NULL)
00278 {
00279 return (-1);
00280 }
00281
00282 m_hashsize = fread (reinterpret_cast<char *>(&m_hashheader), 1, sizeof m_hashheader, fpHash);
00283 if (m_hashsize < static_cast<int>(sizeof(m_hashheader)))
00284 {
00285 if (m_hashsize < 0)
00286 fprintf (stderr, LOOKUP_C_CANT_READ, hashname);
00287 else if (m_hashsize == 0)
00288 fprintf (stderr, LOOKUP_C_NULL_HASH, hashname);
00289 else
00290 fprintf (stderr,
00291 LOOKUP_C_SHORT_HASH (m_hashname, m_hashsize,
00292 static_cast<int>(sizeof m_hashheader)));
00293 return (-1);
00294 }
00295 else if (m_hashheader.magic != MAGIC)
00296 {
00297 fprintf (stderr,
00298 LOOKUP_C_BAD_MAGIC (hashname, static_cast<unsigned int>(MAGIC),
00299 static_cast<unsigned int>(m_hashheader.magic)));
00300 return (-1);
00301 }
00302 else if (m_hashheader.magic2 != MAGIC)
00303 {
00304 fprintf (stderr,
00305 LOOKUP_C_BAD_MAGIC2 (hashname, static_cast<unsigned int>(MAGIC),
00306 static_cast<unsigned int>(m_hashheader.magic2)));
00307 return (-1);
00308 }
00309
00310 else if ( 1 != 1
00311 || m_hashheader.maxstringchars != MAXSTRINGCHARS
00312 || m_hashheader.maxstringcharlen != MAXSTRINGCHARLEN)
00313 {
00314 fprintf (stderr,
00315 LOOKUP_C_BAD_OPTIONS (static_cast<unsigned int>(m_hashheader.compileoptions),
00316 m_hashheader.maxstringchars, m_hashheader.maxstringcharlen,
00317 static_cast<unsigned int>(COMPILEOPTIONS), MAXSTRINGCHARS, MAXSTRINGCHARLEN));
00318 return (-1);
00319 }
00320
00321 {
00322 m_hashtbl =
00323 (struct dent *)
00324 calloc (static_cast<unsigned>(m_hashheader.tblsize), sizeof (struct dent));
00325 m_hashsize = m_hashheader.tblsize;
00326 m_hashstrings = static_cast<char *>(malloc(static_cast<unsigned>(m_hashheader.stringsize)));
00327 }
00328 m_numsflags = m_hashheader.stblsize;
00329 m_numpflags = m_hashheader.ptblsize;
00330 m_sflaglist = (struct flagent *)
00331 malloc ((m_numsflags + m_numpflags) * sizeof (struct flagent));
00332 if (m_hashtbl == NULL || m_hashstrings == NULL || m_sflaglist == NULL)
00333 {
00334 fprintf (stderr, LOOKUP_C_NO_HASH_SPACE);
00335 return (-1);
00336 }
00337 m_pflaglist = m_sflaglist + m_numsflags;
00338
00339 {
00340 if( fread ( m_hashstrings, 1, static_cast<unsigned>(m_hashheader.stringsize), fpHash)
00341 != static_cast<size_t>(m_hashheader.stringsize) )
00342 {
00343 fprintf (stderr, LOOKUP_C_BAD_FORMAT);
00344 fprintf (stderr, "stringsize err\n" );
00345 return (-1);
00346 }
00347 if ( m_hashheader.compileoptions & 0x04 )
00348 {
00349 if( fread (reinterpret_cast<char *>(m_hashtbl), 1, static_cast<unsigned>(m_hashheader.tblsize) * sizeof(struct dent), fpHash)
00350 != (static_cast<size_t>(m_hashheader.tblsize * sizeof (struct dent))))
00351 {
00352 fprintf (stderr, LOOKUP_C_BAD_FORMAT);
00353 return (-1);
00354 }
00355 }
00356 else
00357 {
00358 for( x=0; x<m_hashheader.tblsize; x++ )
00359 {
00360 if( fread ( reinterpret_cast<char*>(m_hashtbl+x), sizeof( struct dent)-sizeof( MASKTYPE ), 1, fpHash)
00361 != 1)
00362 {
00363 fprintf (stderr, LOOKUP_C_BAD_FORMAT);
00364 return (-1);
00365 }
00366 }
00367 }
00368 }
00369 if (fread (reinterpret_cast<char *>(m_sflaglist), 1,
00370 static_cast<unsigned>(m_numsflags+ m_numpflags) * sizeof (struct flagent), fpHash)
00371 != (m_numsflags + m_numpflags) * sizeof (struct flagent))
00372 {
00373 fprintf (stderr, LOOKUP_C_BAD_FORMAT);
00374 return (-1);
00375 }
00376 fclose (fpHash);
00377
00378 {
00379 for (i = m_hashsize, dp = m_hashtbl; --i >= 0; dp++)
00380 {
00381 if (dp->word == (char *) -1)
00382 dp->word = NULL;
00383 else
00384 dp->word = &m_hashstrings [ reinterpret_cast<size_t>(dp->word) ];
00385 if (dp->next == (struct dent *) -1)
00386 dp->next = NULL;
00387 else
00388 dp->next = &m_hashtbl [ reinterpret_cast<size_t>(dp->next) ];
00389 }
00390 }
00391
00392 for (i = m_numsflags + m_numpflags, entry = m_sflaglist; --i >= 0; entry++)
00393 {
00394 if (entry->stripl)
00395 entry->strip = reinterpret_cast<ichar_t *>(&m_hashstrings[reinterpret_cast<size_t>(entry->strip)]);
00396 else
00397 entry->strip = NULL;
00398 if (entry->affl)
00399 entry->affix = reinterpret_cast<ichar_t *>(&m_hashstrings[reinterpret_cast<size_t>(entry->affix)]);
00400 else
00401 entry->affix = NULL;
00402 }
00403
00404
00405
00406
00407
00408 for (i = m_numsflags, entry = m_sflaglist; i > 0; i--, entry++)
00409 {
00410 if (entry->affl == 0)
00411 {
00412 cp = NULL;
00413 ind = &m_sflagindex[0];
00414 viazero = 1;
00415 }
00416 else
00417 {
00418 cp = entry->affix + entry->affl - 1;
00419 ind = &m_sflagindex[*cp];
00420 viazero = 0;
00421 while (ind->numents == 0 && ind->pu.fp != NULL)
00422 {
00423 if (cp == entry->affix)
00424 {
00425 ind = &ind->pu.fp[0];
00426 viazero = 1;
00427 }
00428 else
00429 {
00430 ind = &ind->pu.fp[*--cp];
00431 viazero = 0;
00432 }
00433 }
00434 }
00435 if (ind->numents == 0)
00436 ind->pu.ent = entry;
00437 ind->numents++;
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 if (!viazero && ind->numents >= MAXSEARCH
00449 && icharcmp (entry->affix, ind->pu.ent->affix) != 0)
00450 {
00451
00452 entry = ind->pu.ent - 1;
00453 i = m_numsflags - (entry - m_sflaglist);
00454 ind->pu.fp =
00455 (struct flagptr *)
00456 calloc (static_cast<unsigned>(SET_SIZE + m_hashheader.nstrchars),
00457 sizeof (struct flagptr));
00458 if (ind->pu.fp == NULL)
00459 {
00460 fprintf (stderr, LOOKUP_C_NO_LANG_SPACE);
00461 return (-1);
00462 }
00463 ind->numents = 0;
00464 }
00465 }
00466
00467
00468
00469
00470
00471 for (i = m_numpflags, entry = m_pflaglist; i > 0; i--, entry++)
00472 {
00473 if (entry->affl == 0)
00474 {
00475 cp = NULL;
00476 ind = &m_pflagindex[0];
00477 viazero = 1;
00478 }
00479 else
00480 {
00481 cp = entry->affix;
00482 ind = &m_pflagindex[*cp++];
00483 viazero = 0;
00484 while (ind->numents == 0 && ind->pu.fp != NULL)
00485 {
00486 if (*cp == 0)
00487 {
00488 ind = &ind->pu.fp[0];
00489 viazero = 1;
00490 }
00491 else
00492 {
00493 ind = &ind->pu.fp[*cp++];
00494 viazero = 0;
00495 }
00496 }
00497 }
00498 if (ind->numents == 0)
00499 ind->pu.ent = entry;
00500 ind->numents++;
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 if (!viazero && ind->numents >= MAXSEARCH
00512 && icharcmp (entry->affix, ind->pu.ent->affix) != 0)
00513 {
00514
00515 entry = ind->pu.ent - 1;
00516 i = m_numpflags - (entry - m_pflaglist);
00517 ind->pu.fp =
00518 static_cast<struct flagptr *>(calloc(SET_SIZE + m_hashheader.nstrchars,
00519 sizeof (struct flagptr)));
00520 if (ind->pu.fp == NULL)
00521 {
00522 fprintf (stderr, LOOKUP_C_NO_LANG_SPACE);
00523 return (-1);
00524 }
00525 ind->numents = 0;
00526 }
00527 }
00528 #ifdef INDEXDUMP
00529 fprintf (stderr, "Prefix index table:\n");
00530 dumpindex (m_pflagindex, 0);
00531 fprintf (stderr, "Suffix index table:\n");
00532 dumpindex (m_sflagindex, 0);
00533 #endif
00534 if (m_hashheader.nstrchartype == 0)
00535 m_chartypes = NULL;
00536 else
00537 {
00538 m_chartypes = (struct strchartype *)
00539 malloc (m_hashheader.nstrchartype * sizeof (struct strchartype));
00540 if (m_chartypes == NULL)
00541 {
00542 fprintf (stderr, LOOKUP_C_NO_LANG_SPACE);
00543 return (-1);
00544 }
00545 for (i = 0, nextchar = m_hashheader.strtypestart;
00546 i < m_hashheader.nstrchartype;
00547 i++)
00548 {
00549 m_chartypes[i].name = &m_hashstrings[nextchar];
00550 nextchar += strlen (m_chartypes[i].name) + 1;
00551 m_chartypes[i].deformatter = &m_hashstrings[nextchar];
00552 nextchar += strlen (m_chartypes[i].deformatter) + 1;
00553 m_chartypes[i].suffixes = &m_hashstrings[nextchar];
00554 while (m_hashstrings[nextchar] != '\0')
00555 nextchar += strlen (&m_hashstrings[nextchar]) + 1;
00556 nextchar++;
00557 }
00558 }
00559
00560 initckch(NULL);
00561
00562 return (0);
00563 }
00564
00565 #ifndef FREEP
00566 #define FREEP(p) do { if (p) free(p); } while (0)
00567 #endif
00568
00572 void ISpellChecker::initckch (char *wchars)
00573 {
00574 register ichar_t c;
00575 char num[4];
00576
00577 for (c = 0; c < static_cast<ichar_t>(SET_SIZE+ m_hashheader.nstrchars); ++c)
00578 {
00579 if (iswordch (c))
00580 {
00581 if (!mylower (c))
00582 {
00583 m_Try[m_Trynum] = c;
00584 ++m_Trynum;
00585 }
00586 }
00587 else if (isboundarych (c))
00588 {
00589 m_Try[m_Trynum] = c;
00590 ++m_Trynum;
00591 }
00592 }
00593 if (wchars != NULL)
00594 {
00595 while (m_Trynum < SET_SIZE && *wchars != '\0')
00596 {
00597 if (*wchars != 'n' && *wchars != '\\')
00598 {
00599 c = *wchars;
00600 ++wchars;
00601 }
00602 else
00603 {
00604 ++wchars;
00605 num[0] = '\0';
00606 num[1] = '\0';
00607 num[2] = '\0';
00608 num[3] = '\0';
00609 if (isdigit (wchars[0]))
00610 {
00611 num[0] = wchars[0];
00612 if (isdigit (wchars[1]))
00613 {
00614 num[1] = wchars[1];
00615 if (isdigit (wchars[2]))
00616 num[2] = wchars[2];
00617 }
00618 }
00619 if (wchars[-1] == 'n')
00620 {
00621 wchars += strlen (num);
00622 c = atoi (num);
00623 }
00624 else
00625 {
00626 wchars += strlen (num);
00627 c = 0;
00628 if (num[0])
00629 c = num[0] - '0';
00630 if (num[1])
00631 {
00632 c <<= 3;
00633 c += num[1] - '0';
00634 }
00635 if (num[2])
00636 {
00637 c <<= 3;
00638 c += num[2] - '0';
00639 }
00640 }
00641 }
00642
00643 if (!m_hashheader.wordchars[c])
00644 {
00645 m_hashheader.wordchars[c] = 1;
00646 m_hashheader.sortorder[c] = m_hashheader.sortval++;
00647 m_Try[m_Trynum] = c;
00648 ++m_Trynum;
00649 }
00650 }
00651 }
00652 }
00653
00654
00655
00656
00657 void ISpellChecker::clearindex (struct flagptr *indexp)
00658 {
00659 register int i;
00660 for (i = 0; i < SET_SIZE + m_hashheader.nstrchars; i++, indexp++)
00661 {
00662 if (indexp->numents == 0 && indexp->pu.fp != NULL)
00663 {
00664 clearindex(indexp->pu.fp);
00665 free(indexp->pu.fp);
00666 }
00667 }
00668 }
00669
00670 #ifdef INDEXDUMP
00671 static void dumpindex (indexp, depth)
00672 register struct flagptr * indexp;
00673 register int depth;
00674 {
00675 register int i;
00676 int j;
00677 int k;
00678 char stripbuf[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4];
00679
00680 for (i = 0; i < SET_SIZE + hashheader.nstrchars; i++, indexp++)
00681 {
00682 if (indexp->numents == 0 && indexp->pu.fp != NULL)
00683 {
00684 for (j = depth; --j >= 0; )
00685 putc (' ', stderr);
00686 if (i >= ' ' && i <= '~')
00687 putc (i, stderr);
00688 else
00689 fprintf (stderr, "0x%x", i);
00690 putc ('\n', stderr);
00691 dumpindex (indexp->pu.fp, depth + 1);
00692 }
00693 else if (indexp->numents)
00694 {
00695 for (j = depth; --j >= 0; )
00696 putc (' ', stderr);
00697 if (i >= ' ' && i <= '~')
00698 putc (i, stderr);
00699 else
00700 fprintf (stderr, "0x%x", i);
00701 fprintf (stderr, " -> %d entries\n", indexp->numents);
00702 for (k = 0; k < indexp->numents; k++)
00703 {
00704 for (j = depth; --j >= 0; )
00705 putc (' ', stderr);
00706 if (indexp->pu.ent[k].stripl)
00707 {
00708 ichartostr (stripbuf, indexp->pu.ent[k].strip,
00709 sizeof stripbuf, 1);
00710 fprintf (stderr, " entry %d (-%s,%s)\n",
00711 &indexp->pu.ent[k] - sflaglist,
00712 stripbuf,
00713 indexp->pu.ent[k].affl
00714 ? ichartosstr (indexp->pu.ent[k].affix, 1) : "-");
00715 }
00716 else
00717 fprintf (stderr, " entry %d (%s)\n",
00718 &indexp->pu.ent[k] - sflaglist,
00719 ichartosstr (indexp->pu.ent[k].affix, 1));
00720 }
00721 }
00722 }
00723 }
00724 #endif
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 struct dent * ISpellChecker::ispell_lookup (ichar_t *s, int dotree)
00735 {
00736 register struct dent * dp;
00737 register char * s1;
00738 char schar[INPUTWORDLEN + MAXAFFIXLEN];
00739
00740 dp = &m_hashtbl[hash (s, m_hashsize)];
00741 if (ichartostr (schar, s, sizeof schar, 1))
00742 fprintf (stderr, WORD_TOO_LONG (schar));
00743 for ( ; dp != NULL; dp = dp->next)
00744 {
00745
00746 s1 = dp->word;
00747 if (s1 && s1[0] == schar[0] && strcmp (s1 + 1, schar + 1) == 0)
00748 return dp;
00749 #ifndef NO_CAPITALIZATION_SUPPORT
00750 while (dp->flagfield & MOREVARIANTS)
00751 dp = dp->next;
00752 #endif
00753 }
00754 return NULL;
00755 }
00756
00757 void ISpellChecker::alloc_ispell_struct()
00758 {
00759 m_translate_in = 0;
00760 }
00761
00762 void ISpellChecker::free_ispell_struct()
00763 {
00764 }