/* * \param word * \param pfxopts Options to apply to prefixes */ int ISpellChecker::compoundgood (ichar_t *word, int pfxopts) { ichar_t newword[INPUTWORDLEN + MAXAFFIXLEN]; register ichar_t * p; register ichar_t savech; long secondcap; /* Capitalization of 2nd half */ /* ** If compoundflag is COMPOUND_NEVER, compound words are never ok. */ if (m_hashheader.compoundflag == COMPOUND_NEVER) return 0; /* ** Test for a possible compound word (for languages like German that ** form lots of compounds). ** ** This is similar to missingspace, except we quit on the first hit, ** and we won't allow either member of the compound to be a single ** letter. ** ** We don't do words of length less than 2 * compoundmin, since ** both halves must at least compoundmin letters. */ if (icharlen (word) < 2 * m_hashheader.compoundmin) return 0; icharcpy (newword, word); p = newword + m_hashheader.compoundmin; for ( ; p[m_hashheader.compoundmin - 1] != 0; p++) { savech = *p; *p = 0; if (good (newword, 0, 0, pfxopts, FF_COMPOUNDONLY)) { *p = savech; if (good (p, 0, 1, FF_COMPOUNDONLY, 0) || compoundgood (p, FF_COMPOUNDONLY)) { secondcap = whatcap (p); switch (whatcap (newword)) { case ANYCASE: case CAPITALIZED: case FOLLOWCASE: /* Followcase can have l.c. suffix */ return secondcap == ANYCASE; case ALLCAPS: return secondcap == ALLCAPS; } } } else *p = savech; } return 0; }
/* * \param word * \param hit * \param len * * \return */ int ISpellChecker::cap_ok(ichar_t *word, struct success *hit, int len) { register ichar_t *dword; register ichar_t *w; register struct dent *dent; ichar_t dentword[INPUTWORDLEN + MAXAFFIXLEN]; int preadd; int prestrip; int sufadd; ichar_t *limit; long thiscap; long dentcap; thiscap = whatcap(word); /* ** All caps is always legal, regardless of affixes. */ preadd = prestrip = sufadd = 0; if(thiscap == ALLCAPS) return 1; else if(thiscap == FOLLOWCASE) { /* Set up some constants for the while(1) loop below */ if(hit->prefix) { preadd = hit->prefix->affl; prestrip = hit->prefix->stripl; } else preadd = prestrip = 0; sufadd = hit->suffix ? hit->suffix->affl : 0; } /* ** Search the variants for one that matches what we have. Note ** that thiscap can't be ALLCAPS, since we already returned ** for that case. */ dent = hit->dictent; for(;;) { dentcap = captype(dent->flagfield); if(dentcap != thiscap) { if(dentcap == ANYCASE && thiscap == CAPITALIZED && entryhasaffixes(dent, hit)) return 1; } else /* captypes match */ { if(thiscap != FOLLOWCASE) { if(entryhasaffixes(dent, hit)) return 1; } else { /* ** Make sure followcase matches exactly. ** Life is made more difficult by the ** possibility of affixes. Start with ** the prefix. */ strtoichar(dentword, dent->word, INPUTWORDLEN, 1); dword = dentword; limit = word + preadd; if(myupper(dword[prestrip])) { for(w = word; w < limit; w++) { if(mylower(*w)) goto doublecontinue; } } else { for(w = word; w < limit; w++) { if(myupper(*w)) goto doublecontinue; } } dword += prestrip; /* Do root part of word */ limit = dword + len - preadd - sufadd; while(dword < limit) { if(*dword++ != *w++) goto doublecontinue; } /* Do suffix */ dword = limit - 1; if(myupper(*dword)) { for(; *w; w++) { if(mylower(*w)) goto doublecontinue; } } else { for(; *w; w++) { if(myupper(*w)) goto doublecontinue; } } /* ** All failure paths go to "doublecontinue," ** so if we get here it must match. */ if(entryhasaffixes(dent, hit)) return 1; doublecontinue:; } } if((dent->flagfield & MOREVARIANTS) == 0) break; dent = dent->next; } /* No matches found */ return 0; }