From dbac4566d81c5eb71f2ce9c16259699215b080cb Mon Sep 17 00:00:00 2001 From: Ianos Gnatiuc Date: Sat, 11 Mar 2006 16:21:45 +0000 Subject: [PATCH] Added MySpell library to project --- goldlib/myspell/affentry.cxx | 393 ++++ goldlib/myspell/affentry.hxx | 86 + goldlib/myspell/affixmgr.cxx | 1233 ++++++++++ goldlib/myspell/affixmgr.hxx | 66 + goldlib/myspell/atypes.hxx | 45 + goldlib/myspell/baseaffix.hxx | 17 + goldlib/myspell/csutil.cxx | 3850 ++++++++++++++++++++++++++++++++ goldlib/myspell/csutil.hxx | 67 + goldlib/myspell/dictmgr.cxx | 127 ++ goldlib/myspell/dictmgr.hxx | 31 + goldlib/myspell/example.cxx | 89 + goldlib/myspell/hashmgr.cxx | 213 ++ goldlib/myspell/hashmgr.hxx | 27 + goldlib/myspell/htypes.hxx | 20 + goldlib/myspell/license.readme | 61 + goldlib/myspell/myspell.cxx | 302 +++ goldlib/myspell/myspell.hxx | 37 + goldlib/myspell/suggestmgr.cxx | 539 +++++ goldlib/myspell/suggestmgr.hxx | 48 + 19 files changed, 7251 insertions(+) create mode 100644 goldlib/myspell/affentry.cxx create mode 100644 goldlib/myspell/affentry.hxx create mode 100644 goldlib/myspell/affixmgr.cxx create mode 100644 goldlib/myspell/affixmgr.hxx create mode 100644 goldlib/myspell/atypes.hxx create mode 100644 goldlib/myspell/baseaffix.hxx create mode 100644 goldlib/myspell/csutil.cxx create mode 100644 goldlib/myspell/csutil.hxx create mode 100644 goldlib/myspell/dictmgr.cxx create mode 100644 goldlib/myspell/dictmgr.hxx create mode 100644 goldlib/myspell/example.cxx create mode 100644 goldlib/myspell/hashmgr.cxx create mode 100644 goldlib/myspell/hashmgr.hxx create mode 100644 goldlib/myspell/htypes.hxx create mode 100644 goldlib/myspell/license.readme create mode 100644 goldlib/myspell/myspell.cxx create mode 100644 goldlib/myspell/myspell.hxx create mode 100644 goldlib/myspell/suggestmgr.cxx create mode 100644 goldlib/myspell/suggestmgr.hxx diff --git a/goldlib/myspell/affentry.cxx b/goldlib/myspell/affentry.cxx new file mode 100644 index 0000000..b968602 --- /dev/null +++ b/goldlib/myspell/affentry.cxx @@ -0,0 +1,393 @@ +#include "license.readme" + + +#include +#include +#include +#include + +#include "affentry.hxx" + +#if !defined(_MSC_VER) +using namespace std; +#endif + +extern char * mystrdup(const char * s); +extern char * myrevstrdup(const char * s); + +PfxEntry::PfxEntry(AffixMgr* pmgr, affentry* dp) +{ + // register affix manager + pmyMgr = pmgr; + + // set up its intial values + achar = dp->achar; // char flag + strip = dp->strip; // string to strip + appnd = dp->appnd; // string to append + stripl = dp->stripl; // length of strip string + appndl = dp->appndl; // length of append string + numconds = dp->numconds; // number of conditions to match + xpflg = dp->xpflg; // cross product flag + // then copy over all of the conditions + memcpy(&conds[0],&dp->conds[0],SETSIZE*sizeof(conds[0])); + next = NULL; + nextne = NULL; + nexteq = NULL; +} + + +PfxEntry::~PfxEntry() +{ + achar = '\0'; + if (appnd) free(appnd); + if (strip)free(strip); + pmyMgr = NULL; + appnd = NULL; + strip = NULL; +} + + + +// add prefix to this word assuming conditions hold +char * PfxEntry::add(const char * word, int len) +{ + int cond; + char tword[MAXWORDLEN+1]; + + /* make sure all conditions match */ + if ((len > stripl) && (len >= numconds)) { + unsigned char * cp = (unsigned char *) word; + for (cond = 0; cond < numconds; cond++) { + if ((conds[*cp++] & (1 << cond)) == 0) + break; + } + if (cond >= numconds) { + /* we have a match so add prefix */ + int tlen = 0; + if (appndl) { + strcpy(tword,appnd); + tlen += appndl; + } + char * pp = tword + tlen; + strcpy(pp, (word + stripl)); + return mystrdup(tword); + } + } + return NULL; +} + + + + +// check if this prefix entry matches +struct hentry * PfxEntry::check(const char * word, int len) +{ + int cond; // condition number being examined + int tmpl; // length of tmpword + struct hentry * he; // hash entry of root word or NULL + unsigned char * cp; + char tmpword[MAXWORDLEN+1]; + + + // on entry prefix is 0 length or already matches the beginning of the word. + // So if the remaining root word has positive length + // and if there are enough chars in root word and added back strip chars + // to meet the number of characters conditions, then test it + + tmpl = len - appndl; + + if ((tmpl > 0) && (tmpl + stripl >= numconds)) { + + // generate new root word by removing prefix and adding + // back any characters that would have been stripped + + if (stripl) strcpy (tmpword, strip); + strcpy ((tmpword + stripl), (word + appndl)); + + // now make sure all of the conditions on characters + // are met. Please see the appendix at the end of + // this file for more info on exactly what is being + // tested + + cp = (unsigned char *)tmpword; + for (cond = 0; cond < numconds; cond++) { + if ((conds[*cp++] & (1 << cond)) == 0) break; + } + + // if all conditions are met then check if resulting + // root word in the dictionary + + if (cond >= numconds) { + tmpl += stripl; + if ((he = pmyMgr->lookup(tmpword)) != NULL) { + if (TESTAFF(he->astr, achar, he->alen)) return he; + } + + // prefix matched but no root word was found + // if XPRODUCT is allowed, try again but now + // ross checked combined with a suffix + + if (xpflg & XPRODUCT) { + he = pmyMgr->suffix_check(tmpword, tmpl, XPRODUCT, (AffEntry *)this); + if (he) return he; + } + } + } + return NULL; +} + + + +SfxEntry::SfxEntry(AffixMgr * pmgr, affentry* dp) +{ + // register affix manager + pmyMgr = pmgr; + + // set up its intial values + achar = dp->achar; // char flag + strip = dp->strip; // string to strip + appnd = dp->appnd; // string to append + stripl = dp->stripl; // length of strip string + appndl = dp->appndl; // length of append string + numconds = dp->numconds; // number of conditions to match + xpflg = dp->xpflg; // cross product flag + + // then copy over all of the conditions + memcpy(&conds[0],&dp->conds[0],SETSIZE*sizeof(conds[0])); + + rappnd = myrevstrdup(appnd); +} + + +SfxEntry::~SfxEntry() +{ + achar = '\0'; + if (appnd) free(appnd); + if (rappnd) free(rappnd); + if (strip) free(strip); + pmyMgr = NULL; + appnd = NULL; + strip = NULL; +} + + + +// add suffix to this word assuming conditions hold +char * SfxEntry::add(const char * word, int len) +{ + int cond; + char tword[MAXWORDLEN+1]; + + /* make sure all conditions match */ + if ((len > stripl) && (len >= numconds)) { + unsigned char * cp = (unsigned char *) (word + len); + for (cond = numconds; --cond >=0; ) { + if ((conds[*--cp] & (1 << cond)) == 0) + break; + } + if (cond < 0) { + /* we have a match so add suffix */ + strcpy(tword,word); + int tlen = len; + if (stripl) { + tlen -= stripl; + } + char * pp = (tword + tlen); + if (appndl) { + strcpy(pp,appnd); + tlen += appndl; + } else *pp = '\0'; + return mystrdup(tword); + } + } + return NULL; +} + + + +// see if this suffix is present in the word +struct hentry * SfxEntry::check(const char * word, int len, int optflags, AffEntry* ppfx) +{ + int tmpl; // length of tmpword + int cond; // condition beng examined + struct hentry * he; // hash entry pointer + unsigned char * cp; + char tmpword[MAXWORDLEN+1]; + PfxEntry* ep = (PfxEntry *) ppfx; + + + // if this suffix is being cross checked with a prefix + // but it does not support cross products skip it + + if ((optflags & XPRODUCT) != 0 && (xpflg & XPRODUCT) == 0) + return NULL; + + // upon entry suffix is 0 length or already matches the end of the word. + // So if the remaining root word has positive length + // and if there are enough chars in root word and added back strip chars + // to meet the number of characters conditions, then test it + + tmpl = len - appndl; + + if ((tmpl > 0) && (tmpl + stripl >= numconds)) { + + // generate new root word by removing suffix and adding + // back any characters that would have been stripped or + // or null terminating the shorter string + + strcpy (tmpword, word); + cp = (unsigned char *)(tmpword + tmpl); + if (stripl) { + strcpy ((char *)cp, strip); + tmpl += stripl; + cp = (unsigned char *)(tmpword + tmpl); + } else *cp = '\0'; + + // now make sure all of the conditions on characters + // are met. Please see the appendix at the end of + // this file for more info on exactly what is being + // tested + + for (cond = numconds; --cond >= 0; ) { + if ((conds[*--cp] & (1 << cond)) == 0) break; + } + + // if all conditions are met then check if resulting + // root word in the dictionary + + if (cond < 0) { + if ((he = pmyMgr->lookup(tmpword)) != NULL) { + if (TESTAFF(he->astr, achar , he->alen) && + ((optflags & XPRODUCT) == 0 || + TESTAFF(he->astr, ep->getFlag(), he->alen))) return he; + } + } + } + return NULL; +} + + + + +#if 0 + +Appendix: Understanding Affix Code + + +An affix is either a prefix or a suffix attached to root words to make +other words. + +Basically a Prefix or a Suffix is set of AffEntry objects +which store information about the prefix or suffix along +with supporting routines to check if a word has a particular +prefix or suffix or a combination. + +The structure affentry is defined as follows: + +struct affentry +{ + unsigned char achar; // char used to represent the affix + char * strip; // string to strip before adding affix + char * appnd; // the affix string to add + short stripl; // length of the strip string + short appndl; // length of the affix string + short numconds; // the number of conditions that must be met + short xpflg; // flag: XPRODUCT- combine both prefix and suffix + char conds[SETSIZE]; // array which encodes the conditions to be met +}; + + +Here is a suffix borrowed from the en_US.aff file. This file +is whitespace delimited. + +SFX D Y 4 +SFX D 0 e d +SFX D y ied [^aeiou]y +SFX D 0 ed [^ey] +SFX D 0 ed [aeiou]y + +This information can be interpreted as follows: + +In the first line has 4 fields + +Field +----- +1 SFX - indicates this is a suffix +2 D - is the name of the character flag which represents this suffix +3 Y - indicates it can be combined with prefixes (cross product) +4 4 - indicates that sequence of 4 affentry structures are needed to + properly store the affix information + +The remaining lines describe the unique information for the 4 SfxEntry +objects that make up this affix. Each line can be interpreted +as follows: (note fields 1 and 2 are as a check against line 1 info) + +Field +----- +1 SFX - indicates this is a suffix +2 D - is the name of the character flag for this affix +3 y - the string of chars to strip off before adding affix + (a 0 here indicates the NULL string) +4 ied - the string of affix characters to add +5 [^aeiou]y - the conditions which must be met before the affix + can be applied + +Field 5 is interesting. Since this is a suffix, field 5 tells us that +there are 2 conditions that must be met. The first condition is that +the next to the last character in the word must *NOT* be any of the +following "a", "e", "i", "o" or "u". The second condition is that +the last character of the word must end in "y". + +So how can we encode this information concisely and be able to +test for both conditions in a fast manner? The answer is found +but studying the wonderful ispell code of Geoff Kuenning, et.al. +(now available under a normal BSD license). + +If we set up a conds array of 256 bytes indexed (0 to 255) and access it +using a character (cast to an unsigned char) of a string, we have 8 bits +of information we can store about that character. Specifically we +could use each bit to say if that character is allowed in any of the +last (or first for prefixes) 8 characters of the word. + +Basically, each character at one end of the word (up to the number +of conditions) is used to index into the conds array and the resulting +value found there says whether the that character is valid for a +specific character position in the word. + +For prefixes, it does this by setting bit 0 if that char is valid +in the first position, bit 1 if valid in the second position, and so on. + +If a bit is not set, then that char is not valid for that postion in the +word. + +If working with suffixes bit 0 is used for the character closest +to the front, bit 1 for the next character towards the end, ..., +with bit numconds-1 representing the last char at the end of the string. + +Note: since entries in the conds[] are 8 bits, only 8 conditions +(read that only 8 character positions) can be examined at one +end of a word (the beginning for prefixes and the end for suffixes. + +So to make this clearer, lets encode the conds array values for the +first two affentries for the suffix D described earlier. + + + For the first affentry: + numconds = 1 (only examine the last character) + + conds['e'] = (1 << 0) (the word must end in an E) + all others are all 0 + + For the second affentry: + numconds = 2 (only examine the last two characters) + + conds[X] = conds[X] | (1 << 0) (aeiou are not allowed) + where X is all characters *but* a, e, i, o, or u + + + conds['y'] = (1 << 1) (the last char must be a y) + all other bits for all other entries in the conds array are zero + + +#endif + diff --git a/goldlib/myspell/affentry.hxx b/goldlib/myspell/affentry.hxx new file mode 100644 index 0000000..9c4713c --- /dev/null +++ b/goldlib/myspell/affentry.hxx @@ -0,0 +1,86 @@ +#ifndef _AFFIX_HXX_ +#define _AFFIX_HXX_ + +#include "atypes.hxx" +#include "baseaffix.hxx" +#include "affixmgr.hxx" + + +/* A Prefix Entry */ + +class PfxEntry : public AffEntry +{ + AffixMgr* pmyMgr; + + PfxEntry * next; + PfxEntry * nexteq; + PfxEntry * nextne; + PfxEntry * flgnxt; + +public: + + PfxEntry(AffixMgr* pmgr, affentry* dp ); + ~PfxEntry(); + + struct hentry * check(const char * word, int len); + + inline bool allowCross() { return ((xpflg & XPRODUCT) != 0); } + inline unsigned char getFlag() { return achar; } + inline const char * getKey() { return appnd; } + char * add(const char * word, int len); + + inline PfxEntry * getNext() { return next; } + inline PfxEntry * getNextNE() { return nextne; } + inline PfxEntry * getNextEQ() { return nexteq; } + inline PfxEntry * getFlgNxt() { return flgnxt; } + + inline void setNext(PfxEntry * ptr) { next = ptr; } + inline void setNextNE(PfxEntry * ptr) { nextne = ptr; } + inline void setNextEQ(PfxEntry * ptr) { nexteq = ptr; } + inline void setFlgNxt(PfxEntry * ptr) { flgnxt = ptr; } +}; + + + + +/* A Suffix Entry */ + +class SfxEntry : public AffEntry +{ + AffixMgr* pmyMgr; + char * rappnd; + + SfxEntry * next; + SfxEntry * nexteq; + SfxEntry * nextne; + SfxEntry * flgnxt; + +public: + + SfxEntry(AffixMgr* pmgr, affentry* dp ); + ~SfxEntry(); + + struct hentry * check(const char * word, int len, int optflags, + AffEntry* ppfx); + + inline bool allowCross() { return ((xpflg & XPRODUCT) != 0); } + inline unsigned char getFlag() { return achar; } + inline const char * getKey() { return rappnd; } + char * add(const char * word, int len); + + inline SfxEntry * getNext() { return next; } + inline SfxEntry * getNextNE() { return nextne; } + inline SfxEntry * getNextEQ() { return nexteq; } + inline SfxEntry * getFlgNxt() { return flgnxt; } + + inline void setNext(SfxEntry * ptr) { next = ptr; } + inline void setNextNE(SfxEntry * ptr) { nextne = ptr; } + inline void setNextEQ(SfxEntry * ptr) { nexteq = ptr; } + inline void setFlgNxt(SfxEntry * ptr) { flgnxt = ptr; } + +}; + + +#endif + + diff --git a/goldlib/myspell/affixmgr.cxx b/goldlib/myspell/affixmgr.cxx new file mode 100644 index 0000000..b5848a4 --- /dev/null +++ b/goldlib/myspell/affixmgr.cxx @@ -0,0 +1,1233 @@ +#include "license.readme" + +#include +#include +#include + +#include "affixmgr.hxx" +#include "affentry.hxx" + +#if !defined(_MSC_VER) +using namespace std; +#endif + + +// First some base level utility routines +extern void mychomp(char * s); +extern char * mystrdup(const char * s); +extern char * myrevstrdup(const char * s); +extern char * mystrsep(char ** sptr, const char delim); +extern int isSubset(const char * s1, const char * s2); + + +AffixMgr::AffixMgr(const char * affpath, HashMgr* ptr) +{ + // register hash manager and load affix data from aff file + pHMgr = ptr; + trystring = NULL; + encoding=NULL; + reptable = NULL; + numrep = 0; + maptable = NULL; + nummap = 0; + compound=NULL; + nosplitsugs= (0==1); + + cpdmin = 3; // default value + for (int i=0; i < SETSIZE; i++) { + pStart[i] = NULL; + sStart[i] = NULL; + pFlag[i] = NULL; + sFlag[i] = NULL; + } + if (parse_file(affpath)) { + fprintf(stderr,"Failure loading aff file %s\n",affpath); + fflush(stderr); + } +} + + +AffixMgr::~AffixMgr() +{ + + // pass through linked prefix entries and clean up + for (int i=0; i < SETSIZE ;i++) { + pFlag[i] = NULL; + PfxEntry * ptr = (PfxEntry *)pStart[i]; + PfxEntry * nptr = NULL; + while (ptr) { + nptr = ptr->getNext(); + delete(ptr); + ptr = nptr; + nptr = NULL; + } + } + + // pass through linked suffix entries and clean up + for (int j=0; j < SETSIZE ; j++) { + sFlag[j] = NULL; + SfxEntry * ptr = (SfxEntry *)sStart[j]; + SfxEntry * nptr = NULL; + while (ptr) { + nptr = ptr->getNext(); + delete(ptr); + ptr = nptr; + nptr = NULL; + } + } + + if (trystring) free(trystring); + trystring=NULL; + if (encoding) free(encoding); + encoding=NULL; + if (maptable) { + for (int j=0; j < nummap; j++) { + free(maptable[j].set); + maptable[j].set = NULL; + maptable[j].len = 0; + } + free(maptable); + maptable = NULL; + } + nummap = 0; + if (reptable) { + for (int j=0; j < numrep; j++) { + free(reptable[j].pattern); + free(reptable[j].replacement); + reptable[j].pattern = NULL; + reptable[j].replacement = NULL; + } + free(reptable); + reptable = NULL; + } + numrep = 0; + if (compound) free(compound); + compound=NULL; + pHMgr = NULL; + cpdmin = 0; +} + + +// read in aff file and build up prefix and suffix entry objects +int AffixMgr::parse_file(const char * affpath) +{ + + // io buffers + char line[MAXLNLEN+1]; + + // affix type + char ft; + + // open the affix file + FILE * afflst; + afflst = fopen(affpath,"r"); + if (!afflst) { + fprintf(stderr,"Error - could not open affix description file %s\n",affpath); + return 1; + } + + // step one is to parse the affix file building up the internal + // affix data structures + + + // read in each line ignoring any that do not + // start with a known line type indicator + + while (fgets(line,MAXLNLEN,afflst)) { + mychomp(line); + + /* parse in the try string */ + if (strncmp(line,"TRY",3) == 0) { + if (parse_try(line)) { + return 1; + } + } + + /* parse in the name of the character set used by the .dict and .aff */ + if (strncmp(line,"SET",3) == 0) { + if (parse_set(line)) { + return 1; + } + } + + /* parse in the flag used by the controlled compound words */ + if (strncmp(line,"COMPOUNDFLAG",12) == 0) { + if (parse_cpdflag(line)) { + return 1; + } + } + + /* parse in the flag used by the controlled compound words */ + if (strncmp(line,"COMPOUNDMIN",11) == 0) { + if (parse_cpdmin(line)) { + return 1; + } + } + + /* parse in the typical fault correcting table */ + if (strncmp(line,"REP",3) == 0) { + if (parse_reptable(line, afflst)) { + return 1; + } + } + + /* parse in the related character map table */ + if (strncmp(line,"MAP",3) == 0) { + if (parse_maptable(line, afflst)) { + return 1; + } + } + + // parse this affix: P - prefix, S - suffix + ft = ' '; + if (strncmp(line,"PFX",3) == 0) ft = 'P'; + if (strncmp(line,"SFX",3) == 0) ft = 'S'; + if (ft != ' ') { + if (parse_affix(line, ft, afflst)) { + return 1; + } + } + + // handle NOSPLITSUGS + if (strncmp(line,"NOSPLITSUGS",11) == 0) + nosplitsugs=(0==0); + + } + fclose(afflst); + + // now we can speed up performance greatly taking advantage of the + // relationship between the affixes and the idea of "subsets". + + // View each prefix as a potential leading subset of another and view + // each suffix (reversed) as a potential trailing subset of another. + + // To illustrate this relationship if we know the prefix "ab" is found in the + // word to examine, only prefixes that "ab" is a leading subset of need be examined. + // Furthermore is "ab" is not present then none of the prefixes that "ab" is + // is a subset need be examined. + // The same argument goes for suffix string that are reversed. + + // Then to top this off why not examine the first char of the word to quickly + // limit the set of prefixes to examine (i.e. the prefixes to examine must + // be leading supersets of the first character of the word (if they exist) + + // To take advantage of this "subset" relationship, we need to add two links + // from entry. One to take next if the current prefix is found (call it nexteq) + // and one to take next if the current prefix is not found (call it nextne). + + // Since we have built ordered lists, all that remains is to properly intialize + // the nextne and nexteq pointers that relate them + + process_pfx_order(); + process_sfx_order(); + + return 0; +} + +// we want to be able to quickly access prefix information +// both by prefix flag, and sorted by prefix string itself +// so we need to set up two indexes + +int AffixMgr::build_pfxlist(AffEntry* pfxptr) +{ + PfxEntry * ptr; + PfxEntry * pptr; + PfxEntry * ep = (PfxEntry*) pfxptr; + + // get the right starting points + const char * key = ep->getKey(); + const unsigned char flg = ep->getFlag(); + + // first index by flag which must exist + ptr = (PfxEntry*)pFlag[flg]; + ep->setFlgNxt(ptr); + pFlag[flg] = (AffEntry *) ep; + + + // next index by affix string + + // handle the special case of null affix string + if (strlen(key) == 0) { + // always inset them at head of list at element 0 + ptr = (PfxEntry*)pStart[0]; + ep->setNext(ptr); + pStart[0] = (AffEntry*)ep; + return 0; + } + + // now handle the general case + unsigned char sp = *((const unsigned char *)key); + ptr = (PfxEntry*)pStart[sp]; + + /* handle the insert at top of list case */ + if ((!ptr) || ( strcmp( ep->getKey() , ptr->getKey() ) <= 0)) { + ep->setNext(ptr); + pStart[sp] = (AffEntry*)ep; + return 0; + } + + /* otherwise find where it fits in order and insert it */ + pptr = NULL; + for (; ptr != NULL; ptr = ptr->getNext()) { + if (strcmp( ep->getKey() , ptr->getKey() ) <= 0) break; + pptr = ptr; + } + pptr->setNext(ep); + ep->setNext(ptr); + return 0; +} + + + +// we want to be able to quickly access suffix information +// both by suffix flag, and sorted by the reverse of the +// suffix string itself; so we need to set up two indexes +int AffixMgr::build_sfxlist(AffEntry* sfxptr) +{ + SfxEntry * ptr; + SfxEntry * pptr; + SfxEntry * ep = (SfxEntry *) sfxptr; + + /* get the right starting point */ + const char * key = ep->getKey(); + const unsigned char flg = ep->getFlag(); + + // first index by flag which must exist + ptr = (SfxEntry*)sFlag[flg]; + ep->setFlgNxt(ptr); + sFlag[flg] = (AffEntry *) ep; + + + // next index by affix string + + // handle the special case of null affix string + if (strlen(key) == 0) { + // always inset them at head of list at element 0 + ptr = (SfxEntry*)sStart[0]; + ep->setNext(ptr); + sStart[0] = (AffEntry*)ep; + return 0; + } + + // now handle the normal case + unsigned char sp = *((const unsigned char *)key); + ptr = (SfxEntry*)sStart[sp]; + + /* handle the insert at top of list case */ + if ((!ptr) || ( strcmp( ep->getKey() , ptr->getKey() ) <= 0)) { + ep->setNext(ptr); + sStart[sp] = (AffEntry*)ep; + return 0; + } + + /* otherwise find where it fits in order and insert it */ + pptr = NULL; + for (; ptr != NULL; ptr = ptr->getNext()) { + if (strcmp( ep->getKey(), ptr->getKey() ) <= 0) break; + pptr = ptr; + } + pptr->setNext(ep); + ep->setNext(ptr); + return 0; +} + + + +// initialize the PfxEntry links NextEQ and NextNE to speed searching +int AffixMgr::process_pfx_order() +{ + PfxEntry* ptr; + + // loop through each prefix list starting point + for (int i=1; i < SETSIZE; i++) { + + ptr = (PfxEntry*)pStart[i]; + + // look through the remainder of the list + // and find next entry with affix that + // the current one is not a subset of + // mark that as destination for NextNE + // use next in list that you are a subset + // of as NextEQ + + for (; ptr != NULL; ptr = ptr->getNext()) { + + PfxEntry * nptr = ptr->getNext(); + for (; nptr != NULL; nptr = nptr->getNext()) { + if (! isSubset( ptr->getKey() , nptr->getKey() )) break; + } + ptr->setNextNE(nptr); + ptr->setNextEQ(NULL); + if ((ptr->getNext()) && isSubset(ptr->getKey() , (ptr->getNext())->getKey())) + ptr->setNextEQ(ptr->getNext()); + } + + // now clean up by adding smart search termination strings: + // if you are already a superset of the previous prefix + // but not a subset of the next, search can end here + // so set NextNE properly + + ptr = (PfxEntry *) pStart[i]; + for (; ptr != NULL; ptr = ptr->getNext()) { + PfxEntry * nptr = ptr->getNext(); + PfxEntry * mptr = NULL; + for (; nptr != NULL; nptr = nptr->getNext()) { + if (! isSubset(ptr->getKey(),nptr->getKey())) break; + mptr = nptr; + } + if (mptr) mptr->setNextNE(NULL); + } + } + return 0; +} + + + +// initialize the SfxEntry links NextEQ and NextNE to speed searching +int AffixMgr::process_sfx_order() +{ + SfxEntry* ptr; + + // loop through each prefix list starting point + for (int i=1; i < SETSIZE; i++) { + + ptr = (SfxEntry *) sStart[i]; + + // look through the remainder of the list + // and find next entry with affix that + // the current one is not a subset of + // mark that as destination for NextNE + // use next in list that you are a subset + // of as NextEQ + + for (; ptr != NULL; ptr = ptr->getNext()) { + SfxEntry * nptr = ptr->getNext(); + for (; nptr != NULL; nptr = nptr->getNext()) { + if (! isSubset(ptr->getKey(),nptr->getKey())) break; + } + ptr->setNextNE(nptr); + ptr->setNextEQ(NULL); + if ((ptr->getNext()) && isSubset(ptr->getKey(),(ptr->getNext())->getKey())) + ptr->setNextEQ(ptr->getNext()); + } + + + // now clean up by adding smart search termination strings: + // if you are already a superset of the previous suffix + // but not a subset of the next, search can end here + // so set NextNE properly + + ptr = (SfxEntry *) sStart[i]; + for (; ptr != NULL; ptr = ptr->getNext()) { + SfxEntry * nptr = ptr->getNext(); + SfxEntry * mptr = NULL; + for (; nptr != NULL; nptr = nptr->getNext()) { + if (! isSubset(ptr->getKey(),nptr->getKey())) break; + mptr = nptr; + } + if (mptr) mptr->setNextNE(NULL); + } + } + return 0; +} + + + +// takes aff file condition string and creates the +// conds array - please see the appendix at the end of the +// file affentry.cxx which describes what is going on here +// in much more detail + +void AffixMgr::encodeit(struct affentry * ptr, char * cs) +{ + unsigned char c; + int i, j, k; + unsigned char mbr[MAXLNLEN]; + + // now clear the conditions array */ + for (i=0;iconds[i] = (unsigned char) 0; + + // now parse the string to create the conds array */ + int nc = strlen(cs); + int neg = 0; // complement indicator + int grp = 0; // group indicator + int n = 0; // number of conditions + int ec = 0; // end condition indicator + int nm = 0; // number of member in group + + // if no condition just return + if (strcmp(cs,".")==0) { + ptr->numconds = 0; + return; + } + + i = 0; + while (i < nc) { + c = *((unsigned char *)(cs + i)); + + // start group indicator + if (c == '[') { + grp = 1; + c = 0; + } + + // complement flag + if ((grp == 1) && (c == '^')) { + neg = 1; + c = 0; + } + + // end goup indicator + if (c == ']') { + ec = 1; + c = 0; + } + + // add character of group to list + if ((grp == 1) && (c != 0)) { + *(mbr + nm) = c; + nm++; + c = 0; + } + + // end of condition + if (c != 0) { + ec = 1; + } + + + if (ec) { + if (grp == 1) { + if (neg == 0) { + // set the proper bits in the condition array vals for those chars + for (j=0;jconds[k] = ptr->conds[k] | (1 << n); + } + } else { + // complement so set all of them and then unset indicated ones + for (j=0;jconds[j] = ptr->conds[j] | (1 << n); + for (j=0;jconds[k] = ptr->conds[k] & ~(1 << n); + } + } + neg = 0; + grp = 0; + nm = 0; + } else { + // not a group so just set the proper bit for this char + // but first handle special case of . inside condition + if (c == '.') { + // wild card character so set them all + for (j=0;jconds[j] = ptr->conds[j] | (1 << n); + } else { + ptr->conds[(unsigned int) c] = ptr->conds[(unsigned int)c] | (1 << n); + } + } + n++; + ec = 0; + } + + + i++; + } + ptr->numconds = n; + return; +} + + +// check word for prefixes +struct hentry * AffixMgr::prefix_check (const char * word, int len) +{ + struct hentry * rv= NULL; + + // first handle the special case of 0 length prefixes + PfxEntry * pe = (PfxEntry *) pStart[0]; + while (pe) { + rv = pe->check(word,len); + if (rv) return rv; + pe = pe->getNext(); + } + + // now handle the general case + unsigned char sp = *((const unsigned char *)word); + PfxEntry * pptr = (PfxEntry *)pStart[sp]; + + while (pptr) { + if (isSubset(pptr->getKey(),word)) { + rv = pptr->check(word,len); + if (rv) return rv; + pptr = pptr->getNextEQ(); + } else { + pptr = pptr->getNextNE(); + } + } + + return NULL; +} + +// check if compound word is correctly spelled +struct hentry * AffixMgr::compound_check (const char * word, int len, char compound_flag) +{ + int i; + struct hentry * rv= NULL; + char * st; + char ch; + + // handle case of string too short to be a piece of a compound word + if (len < cpdmin) return NULL; + + st = mystrdup(word); + + for (i=cpdmin; i < (len - (cpdmin-1)); i++) { + + ch = st[i]; + st[i] = '\0'; + + rv = lookup(st); + if (!rv) rv = affix_check(st,i); + + if ((rv) && (TESTAFF(rv->astr, compound_flag, rv->alen))) { + rv = lookup((word+i)); + if ((rv) && (TESTAFF(rv->astr, compound_flag, rv->alen))) { + free(st); + return rv; + } + rv = affix_check((word+i),strlen(word+i)); + if ((rv) && (TESTAFF(rv->astr, compound_flag, rv->alen))) { + free(st); + return rv; + } + rv = compound_check((word+i),strlen(word+i),compound_flag); + if (rv) { + free(st); + return rv; + } + + } + st[i] = ch; + } + free(st); + return NULL; +} + + + +// check word for suffixes +struct hentry * AffixMgr::suffix_check (const char * word, int len, + int sfxopts, AffEntry * ppfx) +{ + struct hentry * rv = NULL; + + // first handle the special case of 0 length suffixes + SfxEntry * se = (SfxEntry *) sStart[0]; + while (se) { + rv = se->check(word,len, sfxopts, ppfx); + if (rv) return rv; + se = se->getNext(); + } + + // now handle the general case + char * tmpword = myrevstrdup(word); + unsigned char sp = *((const unsigned char *)tmpword); + SfxEntry * sptr = (SfxEntry *) sStart[sp]; + + while (sptr) { + if (isSubset(sptr->getKey(),tmpword)) { + rv = sptr->check(word,len, sfxopts, ppfx); + if (rv) { + free(tmpword); + return rv; + } + sptr = sptr->getNextEQ(); + } else { + sptr = sptr->getNextNE(); + } + } + + free(tmpword); + return NULL; +} + + + +// check if word with affixes is correctly spelled +struct hentry * AffixMgr::affix_check (const char * word, int len) +{ + struct hentry * rv= NULL; + + // check all prefixes (also crossed with suffixes if allowed) + rv = prefix_check(word, len); + if (rv) return rv; + + // if still not found check all suffixes + rv = suffix_check(word, len, 0, NULL); + return rv; +} + + +int AffixMgr::expand_rootword(struct guessword * wlst, int maxn, + const char * ts, int wl, const char * ap, int al) +{ + + int nh=0; + + // first add root word to list + + if (nh < maxn) { + wlst[nh].word = mystrdup(ts); + wlst[nh].allow = (1 == 0); + nh++; + } + + // handle suffixes + for (int i = 0; i < al; i++) { + unsigned char c = (unsigned char) ap[i]; + SfxEntry * sptr = (SfxEntry *)sFlag[c]; + while (sptr) { + char * newword = sptr->add(ts, wl); + if (newword) { + if (nh < maxn) { + wlst[nh].word = newword; + wlst[nh].allow = sptr->allowCross(); + nh++; + } else { + free(newword); + } + } + sptr = (SfxEntry *)sptr ->getFlgNxt(); + } + } + + int n = nh; + + // handle cross products of prefixes and suffixes + for (int j=1;jallowCross()) { + int l1 = strlen(wlst[j].word); + char * newword = cptr->add(wlst[j].word, l1); + if (newword) { + if (nh < maxn) { + wlst[nh].word = newword; + wlst[nh].allow = cptr->allowCross(); + nh++; + } else { + free(newword); + } + } + } + cptr = (PfxEntry *)cptr ->getFlgNxt(); + } + } + } + + + // now handle pure prefixes + for (int m = 0; m < al; m ++) { + unsigned char c = (unsigned char) ap[m]; + PfxEntry * ptr = (PfxEntry *) pFlag[c]; + while (ptr) { + char * newword = ptr->add(ts, wl); + if (newword) { + if (nh < maxn) { + wlst[nh].word = newword; + wlst[nh].allow = ptr->allowCross(); + nh++; + } else { + free(newword); + } + } + ptr = (PfxEntry *)ptr ->getFlgNxt(); + } + } + + return nh; +} + + +// return length of replacing table +int AffixMgr::get_numrep() +{ + return numrep; +} + +// return replacing table +struct replentry * AffixMgr::get_reptable() +{ + if (! reptable ) return NULL; + return reptable; +} + + +// return length of character map table +int AffixMgr::get_nummap() +{ + return nummap; +} + +// return character map table +struct mapentry * AffixMgr::get_maptable() +{ + if (! maptable ) return NULL; + return maptable; +} + +// return text encoding of dictionary +char * AffixMgr::get_encoding() +{ + if (! encoding ) { + encoding = mystrdup("ISO8859-1"); + } + return mystrdup(encoding); +} + + +// return the preferred try string for suggestions +char * AffixMgr::get_try_string() +{ + if (! trystring ) return NULL; + return mystrdup(trystring); +} + +// return the compound words control flag +char * AffixMgr::get_compound() +{ + if (! compound ) return NULL; + return mystrdup(compound); +} + +// utility method to look up root words in hash table +struct hentry * AffixMgr::lookup(const char * word) +{ + if (! pHMgr) return NULL; + return pHMgr->lookup(word); +} + +// return nosplitsugs +bool AffixMgr::get_nosplitsugs(void) +{ + return nosplitsugs; +} + +/* parse in the try string */ +int AffixMgr::parse_try(char * line) +{ + if (trystring) { + fprintf(stderr,"error: duplicate TRY strings\n"); + return 1; + } + char * tp = line; + char * piece; + int i = 0; + int np = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: { np++; break; } + case 1: { trystring = mystrdup(piece); np++; break; } + default: break; + } + i++; + } + free(piece); + } + if (np != 2) { + fprintf(stderr,"error: missing TRY information\n"); + return 1; + } + return 0; +} + + +/* parse in the name of the character set used by the .dict and .aff */ +int AffixMgr::parse_set(char * line) +{ + if (encoding) { + fprintf(stderr,"error: duplicate SET strings\n"); + return 1; + } + char * tp = line; + char * piece; + int i = 0; + int np = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: { np++; break; } + case 1: { encoding = mystrdup(piece); np++; break; } + default: break; + } + i++; + } + free(piece); + } + if (np != 2) { + fprintf(stderr,"error: missing SET information\n"); + return 1; + } + return 0; +} + + +/* parse in the flag used by the controlled compound words */ +int AffixMgr::parse_cpdflag(char * line) +{ + if (compound) { + fprintf(stderr,"error: duplicate compound flags used\n"); + return 1; + } + char * tp = line; + char * piece; + int i = 0; + int np = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: { np++; break; } + case 1: { compound = mystrdup(piece); np++; break; } + default: break; + } + i++; + } + free(piece); + } + if (np != 2) { + fprintf(stderr,"error: missing compound flag information\n"); + return 1; + } + return 0; +} + + +/* parse in the min compound word length */ +int AffixMgr::parse_cpdmin(char * line) +{ + char * tp = line; + char * piece; + int i = 0; + int np = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: { np++; break; } + case 1: { cpdmin = atoi(piece); np++; break; } + default: break; + } + i++; + } + free(piece); + } + if (np != 2) { + fprintf(stderr,"error: missing compound min information\n"); + return 1; + } + if ((cpdmin < 1) || (cpdmin > 50)) cpdmin = 3; + return 0; +} + + +/* parse in the typical fault correcting table */ +int AffixMgr::parse_reptable(char * line, FILE * af) +{ + if (numrep != 0) { + fprintf(stderr,"error: duplicate REP tables used\n"); + return 1; + } + char * tp = line; + char * piece; + int i = 0; + int np = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: { np++; break; } + case 1: { + numrep = atoi(piece); + if (numrep < 1) { + fprintf(stderr,"incorrect number of entries in replacement table\n"); + free(piece); + return 1; + } + reptable = (replentry *) malloc(numrep * sizeof(struct replentry)); + np++; + break; + } + default: break; + } + i++; + } + free(piece); + } + if (np != 2) { + fprintf(stderr,"error: missing replacement table information\n"); + return 1; + } + + /* now parse the numrep lines to read in the remainder of the table */ + char * nl = line; + for (int j=0; j < numrep; j++) { + fgets(nl,MAXLNLEN,af); + mychomp(nl); + tp = nl; + i = 0; + reptable[j].pattern = NULL; + reptable[j].replacement = NULL; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: { + if (strncmp(piece,"REP",3) != 0) { + fprintf(stderr,"error: replacement table is corrupt\n"); + free(piece); + return 1; + } + break; + } + case 1: { reptable[j].pattern = mystrdup(piece); break; } + case 2: { reptable[j].replacement = mystrdup(piece); break; } + default: break; + } + i++; + } + free(piece); + } + if ((!(reptable[j].pattern)) || (!(reptable[j].replacement))) { + fprintf(stderr,"error: replacement table is corrupt\n"); + return 1; + } + } + return 0; +} + + + +/* parse in the character map table */ +int AffixMgr::parse_maptable(char * line, FILE * af) +{ + if (nummap != 0) { + fprintf(stderr,"error: duplicate MAP tables used\n"); + return 1; + } + char * tp = line; + char * piece; + int i = 0; + int np = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: { np++; break; } + case 1: { + nummap = atoi(piece); + if (nummap < 1) { + fprintf(stderr,"incorrect number of entries in map table\n"); + free(piece); + return 1; + } + maptable = (mapentry *) malloc(nummap * sizeof(struct mapentry)); + np++; + break; + } + default: break; + } + i++; + } + free(piece); + } + if (np != 2) { + fprintf(stderr,"error: missing map table information\n"); + return 1; + } + + /* now parse the nummap lines to read in the remainder of the table */ + char * nl = line; + for (int j=0; j < nummap; j++) { + fgets(nl,MAXLNLEN,af); + mychomp(nl); + tp = nl; + i = 0; + maptable[j].set = NULL; + maptable[j].len = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: { + if (strncmp(piece,"MAP",3) != 0) { + fprintf(stderr,"error: map table is corrupt\n"); + free(piece); + return 1; + } + break; + } + case 1: { maptable[j].set = mystrdup(piece); + maptable[j].len = strlen(maptable[j].set); + break; } + default: break; + } + i++; + } + free(piece); + } + if ((!(maptable[j].set)) || (!(maptable[j].len))) { + fprintf(stderr,"error: map table is corrupt\n"); + return 1; + } + } + return 0; +} + + + + +int AffixMgr::parse_affix(char * line, const char at, FILE * af) +{ + int numents = 0; // number of affentry structures to parse + char achar='\0'; // affix char identifier + short ff=0; + struct affentry * ptr= NULL; + struct affentry * nptr= NULL; + + char * tp = line; + char * nl = line; + char * piece; + int i = 0; + + // split affix header line into pieces + + int np = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + // piece 1 - is type of affix + case 0: { np++; break; } + + // piece 2 - is affix char + case 1: { np++; achar = *piece; break; } + + // piece 3 - is cross product indicator + case 2: { np++; if (*piece == 'Y') ff = XPRODUCT; break; } + + // piece 4 - is number of affentries + case 3: { + np++; + numents = atoi(piece); + ptr = (struct affentry *) malloc(numents * sizeof(struct affentry)); + ptr->xpflg = ff; + ptr->achar = achar; + break; + } + + default: break; + } + i++; + } + free(piece); + } + // check to make sure we parsed enough pieces + if (np != 4) { + fprintf(stderr, "error: affix %c header has insufficient data in line %s\n",achar,nl); + free(ptr); + return 1; + } + + // store away ptr to first affentry + nptr = ptr; + + // now parse numents affentries for this affix + for (int j=0; j < numents; j++) { + fgets(nl,MAXLNLEN,af); + mychomp(nl); + tp = nl; + i = 0; + np = 0; + + // split line into pieces + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + + // piece 1 - is type + case 0: { + np++; + if (nptr != ptr) nptr->xpflg = ptr->xpflg; + break; + } + + // piece 2 - is affix char + case 1: { + np++; + if (*piece != achar) { + fprintf(stderr, "error: affix %c is corrupt near line %s\n",achar,nl); + fprintf(stderr, "error: possible incorrect count\n"); + free(piece); + return 1; + } + if (nptr != ptr) nptr->achar = ptr->achar; + break; + } + + // piece 3 - is string to strip or 0 for null + case 2: { + np++; + nptr->strip = mystrdup(piece); + nptr->stripl = strlen(nptr->strip); + if (strcmp(nptr->strip,"0") == 0) { + free(nptr->strip); + nptr->strip=mystrdup(""); + nptr->stripl = 0; + } + break; + } + + // piece 4 - is affix string or 0 for null + case 3: { + np++; + nptr->appnd = mystrdup(piece); + nptr->appndl = strlen(nptr->appnd); + if (strcmp(nptr->appnd,"0") == 0) { + free(nptr->appnd); + nptr->appnd=mystrdup(""); + nptr->appndl = 0; + } + break; + } + + // piece 5 - is the conditions descriptions + case 4: { np++; encodeit(nptr,piece); } + + default: break; + } + i++; + } + free(piece); + } + // check to make sure we parsed enough pieces + if (np != 5) { + fprintf(stderr, "error: affix %c is corrupt near line %s\n",achar,nl); + free(ptr); + return 1; + } + nptr++; + } + + // now create SfxEntry or PfxEntry objects and use links to + // build an ordered (sorted by affix string) list + nptr = ptr; + for (int k = 0; k < numents; k++) { + if (at == 'P') { + PfxEntry * pfxptr = new PfxEntry(this,nptr); + build_pfxlist((AffEntry *)pfxptr); + } else { + SfxEntry * sfxptr = new SfxEntry(this,nptr); + build_sfxlist((AffEntry *)sfxptr); + } + nptr++; + } + free(ptr); + return 0; +} diff --git a/goldlib/myspell/affixmgr.hxx b/goldlib/myspell/affixmgr.hxx new file mode 100644 index 0000000..9640019 --- /dev/null +++ b/goldlib/myspell/affixmgr.hxx @@ -0,0 +1,66 @@ +#ifndef _AFFIXMGR_HXX_ +#define _AFFIXMGR_HXX_ + +#include "atypes.hxx" +#include "baseaffix.hxx" +#include "hashmgr.hxx" +#include + +class AffixMgr +{ + + AffEntry * pStart[SETSIZE]; + AffEntry * sStart[SETSIZE]; + AffEntry * pFlag[SETSIZE]; + AffEntry * sFlag[SETSIZE]; + HashMgr * pHMgr; + char * trystring; + char * encoding; + char * compound; + int cpdmin; + int numrep; + replentry * reptable; + int nummap; + mapentry * maptable; + bool nosplitsugs; + + +public: + + AffixMgr(const char * affpath, HashMgr * ptr); + ~AffixMgr(); + struct hentry * affix_check(const char * word, int len); + struct hentry * prefix_check(const char * word, int len); + struct hentry * suffix_check(const char * word, int len, int sfxopts, AffEntry* ppfx); + int expand_rootword(struct guessword * wlst, int maxn, + const char * ts, int wl, const char * ap, int al); + struct hentry * compound_check(const char * word, int len, char compound_flag); + struct hentry * lookup(const char * word); + int get_numrep(); + struct replentry * get_reptable(); + int get_nummap(); + struct mapentry * get_maptable(); + char * get_encoding(); + char * get_try_string(); + char * get_compound(); + bool get_nosplitsugs(); + +private: + int parse_file(const char * affpath); + int parse_try(char * line); + int parse_set(char * line); + int parse_cpdflag(char * line); + int parse_cpdmin(char * line); + int parse_reptable(char * line, FILE * af); + int parse_maptable(char * line, FILE * af); + int parse_affix(char * line, const char at, FILE * af); + + void encodeit(struct affentry * ptr, char * cs); + int build_pfxlist(AffEntry* pfxptr); + int build_sfxlist(AffEntry* sfxptr); + int process_pfx_order(); + int process_sfx_order(); +}; + +#endif + diff --git a/goldlib/myspell/atypes.hxx b/goldlib/myspell/atypes.hxx new file mode 100644 index 0000000..a10c69d --- /dev/null +++ b/goldlib/myspell/atypes.hxx @@ -0,0 +1,45 @@ +#ifndef _ATYPES_HXX_ +#define _ATYPES_HXX_ + +#define SETSIZE 256 +#define MAXAFFIXES 256 +#define MAXWORDLEN 100 +#define XPRODUCT (1 << 0) + +#define MAXLNLEN 1024 + +#define TESTAFF( a , b , c ) memchr((void *)(a), (int)(b), (size_t)(c) ) + +struct affentry +{ + char * strip; + char * appnd; + short stripl; + short appndl; + short numconds; + short xpflg; + char achar; + char conds[SETSIZE]; +}; + +struct replentry { + char * pattern; + char * replacement; +}; + +struct mapentry { + char * set; + int len; +}; + +struct guessword { + char * word; + bool allow; +}; + +#endif + + + + + diff --git a/goldlib/myspell/baseaffix.hxx b/goldlib/myspell/baseaffix.hxx new file mode 100644 index 0000000..6aa4351 --- /dev/null +++ b/goldlib/myspell/baseaffix.hxx @@ -0,0 +1,17 @@ +#ifndef _BASEAFF_HXX_ +#define _BASEAFF_HXX_ + +class AffEntry +{ +protected: + char * appnd; + char * strip; + short appndl; + short stripl; + short numconds; + short xpflg; + char achar; + char conds[SETSIZE]; +}; + +#endif diff --git a/goldlib/myspell/csutil.cxx b/goldlib/myspell/csutil.cxx new file mode 100644 index 0000000..ac25e83 --- /dev/null +++ b/goldlib/myspell/csutil.cxx @@ -0,0 +1,3850 @@ +#include +#include +#include +#include "csutil.hxx" + +#if !defined(_MSC_VER) +using namespace std; +#endif + +// strip strings into token based on single char delimiter +// acts like strsep() but only uses a delim char and not +// a delim string + +char * mystrsep(char ** stringp, const char delim) +{ + char * rv = NULL; + char * mp = *stringp; + int n = strlen(mp); + if (n > 0) { + char * dp = (char *)memchr(mp,(int)((unsigned char)delim),n); + if (dp) { + *stringp = dp+1; + int nc = (int)((unsigned long)dp - (unsigned long)mp); + rv = (char *) malloc(nc+1); + memcpy(rv,mp,nc); + *(rv+nc) = '\0'; + return rv; + } else { + rv = (char *) malloc(n+1); + memcpy(rv, mp, n); + *(rv+n) = '\0'; + *stringp = mp + n; + return rv; + } + } + return NULL; +} + + +// replaces strdup with ansi version +char * mystrdup(const char * s) +{ + char * d = NULL; + if (s) { + int sl = strlen(s); + d = (char *) malloc(((sl+1) * sizeof(char))); + if (d) memcpy(d,s,((sl+1)*sizeof(char))); + } + return d; +} + + +// remove cross-platform text line end characters +void mychomp(char * s) +{ + int k = strlen(s); + if ((k > 0) && ((*(s+k-1)=='\r') || (*(s+k-1)=='\n'))) *(s+k-1) = '\0'; + if ((k > 1) && (*(s+k-2) == '\r')) *(s+k-2) = '\0'; +} + + +// does an ansi strdup of the reverse of a string +char * myrevstrdup(const char * s) +{ + char * d = NULL; + if (s) { + int sl = strlen(s); + d = (char *) malloc((sl+1) * sizeof(char)); + if (d) { + const char * p = s + sl - 1; + char * q = d; + while (p >= s) *q++ = *p--; + *q = '\0'; + } + } + return d; +} + + +// return 1 if s1 is a leading subset of s2 +int isSubset(const char * s1, const char * s2) +{ + int l1 = strlen(s1); + int l2 = strlen(s2); + if (l1 > l2) return 0; + if (strncmp(s2,s1,l1) == 0) return 1; + return 0; +} + + + +// convert null terminated string to all caps using encoding +void enmkallcap(char * d, const char * p, const char * encoding) +{ + struct cs_info * csconv = get_current_cs(encoding); + while (*p != '\0') { + *d++ = csconv[((unsigned char) *p)].cupper; + p++; + } + *d = '\0'; +} + + +// convert null terminated string to all little using encoding +void enmkallsmall(char * d, const char * p, const char * encoding) +{ + struct cs_info * csconv = get_current_cs(encoding); + while (*p != '\0') { + *d++ = csconv[((unsigned char) *p)].clower; + p++; + } + *d = '\0'; +} + + +// convert null terminated string to have intial capital using encoding +void enmkinitcap(char * d, const char * p, const char * encoding) +{ + struct cs_info * csconv = get_current_cs(encoding); + memcpy(d,p,(strlen(p)+1)); + if (*p != '\0') *d= csconv[((unsigned char)*p)].cupper; +} + + +// convert null terminated string to all caps +void mkallcap(char * p, const struct cs_info * csconv) +{ + while (*p != '\0') { + *p = csconv[((unsigned char) *p)].cupper; + p++; + } +} + + +// convert null terminated string to all little +void mkallsmall(char * p, const struct cs_info * csconv) +{ + while (*p != '\0') { + *p = csconv[((unsigned char) *p)].clower; + p++; + } +} + + +// convert null terminated string to have intial capital +void mkinitcap(char * p, const struct cs_info * csconv) +{ + if (*p != '\0') *p = csconv[((unsigned char)*p)].cupper; +} + + + + +// these are simple character mappings for the +// encodings supported +// supplying isupper, tolower, and toupper + +struct cs_info iso1_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xb9 }, +{ 0x00, 0xba, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x00, 0xbc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xbf }, +{ 0x01, 0xe0, 0xc0 }, +{ 0x01, 0xe1, 0xc1 }, +{ 0x01, 0xe2, 0xc2 }, +{ 0x01, 0xe3, 0xc3 }, +{ 0x01, 0xe4, 0xc4 }, +{ 0x01, 0xe5, 0xc5 }, +{ 0x01, 0xe6, 0xc6 }, +{ 0x01, 0xe7, 0xc7 }, +{ 0x01, 0xe8, 0xc8 }, +{ 0x01, 0xe9, 0xc9 }, +{ 0x01, 0xea, 0xca }, +{ 0x01, 0xeb, 0xcb }, +{ 0x01, 0xec, 0xcc }, +{ 0x01, 0xed, 0xcd }, +{ 0x01, 0xee, 0xce }, +{ 0x01, 0xef, 0xcf }, +{ 0x01, 0xf0, 0xd0 }, +{ 0x01, 0xf1, 0xd1 }, +{ 0x01, 0xf2, 0xd2 }, +{ 0x01, 0xf3, 0xd3 }, +{ 0x01, 0xf4, 0xd4 }, +{ 0x01, 0xf5, 0xd5 }, +{ 0x01, 0xf6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x01, 0xf8, 0xd8 }, +{ 0x01, 0xf9, 0xd9 }, +{ 0x01, 0xfa, 0xda }, +{ 0x01, 0xfb, 0xdb }, +{ 0x01, 0xfc, 0xdc }, +{ 0x01, 0xfd, 0xdd }, +{ 0x01, 0xfe, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xc0 }, +{ 0x00, 0xe1, 0xc1 }, +{ 0x00, 0xe2, 0xc2 }, +{ 0x00, 0xe3, 0xc3 }, +{ 0x00, 0xe4, 0xc4 }, +{ 0x00, 0xe5, 0xc5 }, +{ 0x00, 0xe6, 0xc6 }, +{ 0x00, 0xe7, 0xc7 }, +{ 0x00, 0xe8, 0xc8 }, +{ 0x00, 0xe9, 0xc9 }, +{ 0x00, 0xea, 0xca }, +{ 0x00, 0xeb, 0xcb }, +{ 0x00, 0xec, 0xcc }, +{ 0x00, 0xed, 0xcd }, +{ 0x00, 0xee, 0xce }, +{ 0x00, 0xef, 0xcf }, +{ 0x00, 0xf0, 0xd0 }, +{ 0x00, 0xf1, 0xd1 }, +{ 0x00, 0xf2, 0xd2 }, +{ 0x00, 0xf3, 0xd3 }, +{ 0x00, 0xf4, 0xd4 }, +{ 0x00, 0xf5, 0xd5 }, +{ 0x00, 0xf6, 0xd6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xd8 }, +{ 0x00, 0xf9, 0xd9 }, +{ 0x00, 0xfa, 0xda }, +{ 0x00, 0xfb, 0xdb }, +{ 0x00, 0xfc, 0xdc }, +{ 0x00, 0xfd, 0xdd }, +{ 0x00, 0xfe, 0xde }, +{ 0x00, 0xff, 0xff }, +}; + + +struct cs_info iso2_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x01, 0xb1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x01, 0xb3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x01, 0xb5, 0xa5 }, +{ 0x01, 0xb6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x01, 0xb9, 0xa9 }, +{ 0x01, 0xba, 0xaa }, +{ 0x01, 0xbb, 0xab }, +{ 0x01, 0xbc, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x01, 0xbe, 0xae }, +{ 0x01, 0xbf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xa1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xa3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xa5 }, +{ 0x00, 0xb6, 0xa6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xa9 }, +{ 0x00, 0xba, 0xaa }, +{ 0x00, 0xbb, 0xab }, +{ 0x00, 0xbc, 0xac }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xae }, +{ 0x00, 0xbf, 0xaf }, +{ 0x01, 0xe0, 0xc0 }, +{ 0x01, 0xe1, 0xc1 }, +{ 0x01, 0xe2, 0xc2 }, +{ 0x01, 0xe3, 0xc3 }, +{ 0x01, 0xe4, 0xc4 }, +{ 0x01, 0xe5, 0xc5 }, +{ 0x01, 0xe6, 0xc6 }, +{ 0x01, 0xe7, 0xc7 }, +{ 0x01, 0xe8, 0xc8 }, +{ 0x01, 0xe9, 0xc9 }, +{ 0x01, 0xea, 0xca }, +{ 0x01, 0xeb, 0xcb }, +{ 0x01, 0xec, 0xcc }, +{ 0x01, 0xed, 0xcd }, +{ 0x01, 0xee, 0xce }, +{ 0x01, 0xef, 0xcf }, +{ 0x01, 0xf0, 0xd0 }, +{ 0x01, 0xf1, 0xd1 }, +{ 0x01, 0xf2, 0xd2 }, +{ 0x01, 0xf3, 0xd3 }, +{ 0x01, 0xf4, 0xd4 }, +{ 0x01, 0xf5, 0xd5 }, +{ 0x01, 0xf6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x01, 0xf8, 0xd8 }, +{ 0x01, 0xf9, 0xd9 }, +{ 0x01, 0xfa, 0xda }, +{ 0x01, 0xfb, 0xdb }, +{ 0x01, 0xfc, 0xdc }, +{ 0x01, 0xfd, 0xdd }, +{ 0x01, 0xfe, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xc0 }, +{ 0x00, 0xe1, 0xc1 }, +{ 0x00, 0xe2, 0xc2 }, +{ 0x00, 0xe3, 0xc3 }, +{ 0x00, 0xe4, 0xc4 }, +{ 0x00, 0xe5, 0xc5 }, +{ 0x00, 0xe6, 0xc6 }, +{ 0x00, 0xe7, 0xc7 }, +{ 0x00, 0xe8, 0xc8 }, +{ 0x00, 0xe9, 0xc9 }, +{ 0x00, 0xea, 0xca }, +{ 0x00, 0xeb, 0xcb }, +{ 0x00, 0xec, 0xcc }, +{ 0x00, 0xed, 0xcd }, +{ 0x00, 0xee, 0xce }, +{ 0x00, 0xef, 0xcf }, +{ 0x00, 0xf0, 0xd0 }, +{ 0x00, 0xf1, 0xd1 }, +{ 0x00, 0xf2, 0xd2 }, +{ 0x00, 0xf3, 0xd3 }, +{ 0x00, 0xf4, 0xd4 }, +{ 0x00, 0xf5, 0xd5 }, +{ 0x00, 0xf6, 0xd6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xd8 }, +{ 0x00, 0xf9, 0xd9 }, +{ 0x00, 0xfa, 0xda }, +{ 0x00, 0xfb, 0xdb }, +{ 0x00, 0xfc, 0xdc }, +{ 0x00, 0xfd, 0xdd }, +{ 0x00, 0xfe, 0xde }, +{ 0x00, 0xff, 0xff }, +}; + + +struct cs_info iso3_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x01, 0xb1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x01, 0xb6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x01, 0x69, 0xa9 }, +{ 0x01, 0xba, 0xaa }, +{ 0x01, 0xbb, 0xab }, +{ 0x01, 0xbc, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x01, 0xbf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xa1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xa6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0x49 }, +{ 0x00, 0xba, 0xaa }, +{ 0x00, 0xbb, 0xab }, +{ 0x00, 0xbc, 0xac }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xaf }, +{ 0x01, 0xe0, 0xc0 }, +{ 0x01, 0xe1, 0xc1 }, +{ 0x01, 0xe2, 0xc2 }, +{ 0x00, 0xc3, 0xc3 }, +{ 0x01, 0xe4, 0xc4 }, +{ 0x01, 0xe5, 0xc5 }, +{ 0x01, 0xe6, 0xc6 }, +{ 0x01, 0xe7, 0xc7 }, +{ 0x01, 0xe8, 0xc8 }, +{ 0x01, 0xe9, 0xc9 }, +{ 0x01, 0xea, 0xca }, +{ 0x01, 0xeb, 0xcb }, +{ 0x01, 0xec, 0xcc }, +{ 0x01, 0xed, 0xcd }, +{ 0x01, 0xee, 0xce }, +{ 0x01, 0xef, 0xcf }, +{ 0x00, 0xd0, 0xd0 }, +{ 0x01, 0xf1, 0xd1 }, +{ 0x01, 0xf2, 0xd2 }, +{ 0x01, 0xf3, 0xd3 }, +{ 0x01, 0xf4, 0xd4 }, +{ 0x01, 0xf5, 0xd5 }, +{ 0x01, 0xf6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x01, 0xf8, 0xd8 }, +{ 0x01, 0xf9, 0xd9 }, +{ 0x01, 0xfa, 0xda }, +{ 0x01, 0xfb, 0xdb }, +{ 0x01, 0xfc, 0xdc }, +{ 0x01, 0xfd, 0xdd }, +{ 0x01, 0xfe, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xc0 }, +{ 0x00, 0xe1, 0xc1 }, +{ 0x00, 0xe2, 0xc2 }, +{ 0x00, 0xe3, 0xe3 }, +{ 0x00, 0xe4, 0xc4 }, +{ 0x00, 0xe5, 0xc5 }, +{ 0x00, 0xe6, 0xc6 }, +{ 0x00, 0xe7, 0xc7 }, +{ 0x00, 0xe8, 0xc8 }, +{ 0x00, 0xe9, 0xc9 }, +{ 0x00, 0xea, 0xca }, +{ 0x00, 0xeb, 0xcb }, +{ 0x00, 0xec, 0xcc }, +{ 0x00, 0xed, 0xcd }, +{ 0x00, 0xee, 0xce }, +{ 0x00, 0xef, 0xcf }, +{ 0x00, 0xf0, 0xf0 }, +{ 0x00, 0xf1, 0xd1 }, +{ 0x00, 0xf2, 0xd2 }, +{ 0x00, 0xf3, 0xd3 }, +{ 0x00, 0xf4, 0xd4 }, +{ 0x00, 0xf5, 0xd5 }, +{ 0x00, 0xf6, 0xd6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xd8 }, +{ 0x00, 0xf9, 0xd9 }, +{ 0x00, 0xfa, 0xda }, +{ 0x00, 0xfb, 0xdb }, +{ 0x00, 0xfc, 0xdc }, +{ 0x00, 0xfd, 0xdd }, +{ 0x00, 0xfe, 0xde }, +{ 0x00, 0xff, 0xff }, +}; + +struct cs_info iso4_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x01, 0xb1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x01, 0xb3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x01, 0xb5, 0xa5 }, +{ 0x01, 0xb6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x01, 0xb9, 0xa9 }, +{ 0x01, 0xba, 0xaa }, +{ 0x01, 0xbb, 0xab }, +{ 0x01, 0xbc, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x01, 0xbe, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xa1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xa3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xa5 }, +{ 0x00, 0xb6, 0xa6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xa9 }, +{ 0x00, 0xba, 0xaa }, +{ 0x00, 0xbb, 0xab }, +{ 0x00, 0xbc, 0xac }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xae }, +{ 0x00, 0xbf, 0xbf }, +{ 0x01, 0xe0, 0xc0 }, +{ 0x01, 0xe1, 0xc1 }, +{ 0x01, 0xe2, 0xc2 }, +{ 0x01, 0xe3, 0xc3 }, +{ 0x01, 0xe4, 0xc4 }, +{ 0x01, 0xe5, 0xc5 }, +{ 0x01, 0xe6, 0xc6 }, +{ 0x01, 0xe7, 0xc7 }, +{ 0x01, 0xe8, 0xc8 }, +{ 0x01, 0xe9, 0xc9 }, +{ 0x01, 0xea, 0xca }, +{ 0x01, 0xeb, 0xcb }, +{ 0x01, 0xec, 0xcc }, +{ 0x01, 0xed, 0xcd }, +{ 0x01, 0xee, 0xce }, +{ 0x01, 0xef, 0xcf }, +{ 0x01, 0xf0, 0xd0 }, +{ 0x01, 0xf1, 0xd1 }, +{ 0x01, 0xf2, 0xd2 }, +{ 0x01, 0xf3, 0xd3 }, +{ 0x01, 0xf4, 0xd4 }, +{ 0x01, 0xf5, 0xd5 }, +{ 0x01, 0xf6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x01, 0xf8, 0xd8 }, +{ 0x01, 0xf9, 0xd9 }, +{ 0x01, 0xfa, 0xda }, +{ 0x01, 0xfb, 0xdb }, +{ 0x01, 0xfc, 0xdc }, +{ 0x01, 0xfd, 0xdd }, +{ 0x01, 0xfe, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xc0 }, +{ 0x00, 0xe1, 0xc1 }, +{ 0x00, 0xe2, 0xc2 }, +{ 0x00, 0xe3, 0xc3 }, +{ 0x00, 0xe4, 0xc4 }, +{ 0x00, 0xe5, 0xc5 }, +{ 0x00, 0xe6, 0xc6 }, +{ 0x00, 0xe7, 0xc7 }, +{ 0x00, 0xe8, 0xc8 }, +{ 0x00, 0xe9, 0xc9 }, +{ 0x00, 0xea, 0xca }, +{ 0x00, 0xeb, 0xcb }, +{ 0x00, 0xec, 0xcc }, +{ 0x00, 0xed, 0xcd }, +{ 0x00, 0xee, 0xce }, +{ 0x00, 0xef, 0xcf }, +{ 0x00, 0xf0, 0xd0 }, +{ 0x00, 0xf1, 0xd1 }, +{ 0x00, 0xf2, 0xd2 }, +{ 0x00, 0xf3, 0xd3 }, +{ 0x00, 0xf4, 0xd4 }, +{ 0x00, 0xf5, 0xd5 }, +{ 0x00, 0xf6, 0xd6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xd8 }, +{ 0x00, 0xf9, 0xd9 }, +{ 0x00, 0xfa, 0xda }, +{ 0x00, 0xfb, 0xdb }, +{ 0x00, 0xfc, 0xdc }, +{ 0x00, 0xfd, 0xdd }, +{ 0x00, 0xfe, 0xde }, +{ 0x00, 0xff, 0xff }, +}; + +struct cs_info iso5_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x01, 0xf1, 0xa1 }, +{ 0x01, 0xf2, 0xa2 }, +{ 0x01, 0xf3, 0xa3 }, +{ 0x01, 0xf4, 0xa4 }, +{ 0x01, 0xf5, 0xa5 }, +{ 0x01, 0xf6, 0xa6 }, +{ 0x01, 0xf7, 0xa7 }, +{ 0x01, 0xf8, 0xa8 }, +{ 0x01, 0xf9, 0xa9 }, +{ 0x01, 0xfa, 0xaa }, +{ 0x01, 0xfb, 0xab }, +{ 0x01, 0xfc, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x01, 0xfe, 0xae }, +{ 0x01, 0xff, 0xaf }, +{ 0x01, 0xd0, 0xb0 }, +{ 0x01, 0xd1, 0xb1 }, +{ 0x01, 0xd2, 0xb2 }, +{ 0x01, 0xd3, 0xb3 }, +{ 0x01, 0xd4, 0xb4 }, +{ 0x01, 0xd5, 0xb5 }, +{ 0x01, 0xd6, 0xb6 }, +{ 0x01, 0xd7, 0xb7 }, +{ 0x01, 0xd8, 0xb8 }, +{ 0x01, 0xd9, 0xb9 }, +{ 0x01, 0xda, 0xba }, +{ 0x01, 0xdb, 0xbb }, +{ 0x01, 0xdc, 0xbc }, +{ 0x01, 0xdd, 0xbd }, +{ 0x01, 0xde, 0xbe }, +{ 0x01, 0xdf, 0xbf }, +{ 0x01, 0xe0, 0xc0 }, +{ 0x01, 0xe1, 0xc1 }, +{ 0x01, 0xe2, 0xc2 }, +{ 0x01, 0xe3, 0xc3 }, +{ 0x01, 0xe4, 0xc4 }, +{ 0x01, 0xe5, 0xc5 }, +{ 0x01, 0xe6, 0xc6 }, +{ 0x01, 0xe7, 0xc7 }, +{ 0x01, 0xe8, 0xc8 }, +{ 0x01, 0xe9, 0xc9 }, +{ 0x01, 0xea, 0xca }, +{ 0x01, 0xeb, 0xcb }, +{ 0x01, 0xec, 0xcc }, +{ 0x01, 0xed, 0xcd }, +{ 0x01, 0xee, 0xce }, +{ 0x01, 0xef, 0xcf }, +{ 0x00, 0xd0, 0xb0 }, +{ 0x00, 0xd1, 0xb1 }, +{ 0x00, 0xd2, 0xb2 }, +{ 0x00, 0xd3, 0xb3 }, +{ 0x00, 0xd4, 0xb4 }, +{ 0x00, 0xd5, 0xb5 }, +{ 0x00, 0xd6, 0xb6 }, +{ 0x00, 0xd7, 0xb7 }, +{ 0x00, 0xd8, 0xb8 }, +{ 0x00, 0xd9, 0xb9 }, +{ 0x00, 0xda, 0xba }, +{ 0x00, 0xdb, 0xbb }, +{ 0x00, 0xdc, 0xbc }, +{ 0x00, 0xdd, 0xbd }, +{ 0x00, 0xde, 0xbe }, +{ 0x00, 0xdf, 0xbf }, +{ 0x00, 0xe0, 0xc0 }, +{ 0x00, 0xe1, 0xc1 }, +{ 0x00, 0xe2, 0xc2 }, +{ 0x00, 0xe3, 0xc3 }, +{ 0x00, 0xe4, 0xc4 }, +{ 0x00, 0xe5, 0xc5 }, +{ 0x00, 0xe6, 0xc6 }, +{ 0x00, 0xe7, 0xc7 }, +{ 0x00, 0xe8, 0xc8 }, +{ 0x00, 0xe9, 0xc9 }, +{ 0x00, 0xea, 0xca }, +{ 0x00, 0xeb, 0xcb }, +{ 0x00, 0xec, 0xcc }, +{ 0x00, 0xed, 0xcd }, +{ 0x00, 0xee, 0xce }, +{ 0x00, 0xef, 0xcf }, +{ 0x00, 0xf0, 0xf0 }, +{ 0x00, 0xf1, 0xa1 }, +{ 0x00, 0xf2, 0xa2 }, +{ 0x00, 0xf3, 0xa3 }, +{ 0x00, 0xf4, 0xa4 }, +{ 0x00, 0xf5, 0xa5 }, +{ 0x00, 0xf6, 0xa6 }, +{ 0x00, 0xf7, 0xa7 }, +{ 0x00, 0xf8, 0xa8 }, +{ 0x00, 0xf9, 0xa9 }, +{ 0x00, 0xfa, 0xaa }, +{ 0x00, 0xfb, 0xab }, +{ 0x00, 0xfc, 0xac }, +{ 0x00, 0xfd, 0xfd }, +{ 0x00, 0xfe, 0xae }, +{ 0x00, 0xff, 0xaf }, +}; + +struct cs_info iso6_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xb9 }, +{ 0x00, 0xba, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x00, 0xbc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xbf }, +{ 0x00, 0xc0, 0xc0 }, +{ 0x00, 0xc1, 0xc1 }, +{ 0x00, 0xc2, 0xc2 }, +{ 0x00, 0xc3, 0xc3 }, +{ 0x00, 0xc4, 0xc4 }, +{ 0x00, 0xc5, 0xc5 }, +{ 0x00, 0xc6, 0xc6 }, +{ 0x00, 0xc7, 0xc7 }, +{ 0x00, 0xc8, 0xc8 }, +{ 0x00, 0xc9, 0xc9 }, +{ 0x00, 0xca, 0xca }, +{ 0x00, 0xcb, 0xcb }, +{ 0x00, 0xcc, 0xcc }, +{ 0x00, 0xcd, 0xcd }, +{ 0x00, 0xce, 0xce }, +{ 0x00, 0xcf, 0xcf }, +{ 0x00, 0xd0, 0xd0 }, +{ 0x00, 0xd1, 0xd1 }, +{ 0x00, 0xd2, 0xd2 }, +{ 0x00, 0xd3, 0xd3 }, +{ 0x00, 0xd4, 0xd4 }, +{ 0x00, 0xd5, 0xd5 }, +{ 0x00, 0xd6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x00, 0xd8, 0xd8 }, +{ 0x00, 0xd9, 0xd9 }, +{ 0x00, 0xda, 0xda }, +{ 0x00, 0xdb, 0xdb }, +{ 0x00, 0xdc, 0xdc }, +{ 0x00, 0xdd, 0xdd }, +{ 0x00, 0xde, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xe0 }, +{ 0x00, 0xe1, 0xe1 }, +{ 0x00, 0xe2, 0xe2 }, +{ 0x00, 0xe3, 0xe3 }, +{ 0x00, 0xe4, 0xe4 }, +{ 0x00, 0xe5, 0xe5 }, +{ 0x00, 0xe6, 0xe6 }, +{ 0x00, 0xe7, 0xe7 }, +{ 0x00, 0xe8, 0xe8 }, +{ 0x00, 0xe9, 0xe9 }, +{ 0x00, 0xea, 0xea }, +{ 0x00, 0xeb, 0xeb }, +{ 0x00, 0xec, 0xec }, +{ 0x00, 0xed, 0xed }, +{ 0x00, 0xee, 0xee }, +{ 0x00, 0xef, 0xef }, +{ 0x00, 0xf0, 0xf0 }, +{ 0x00, 0xf1, 0xf1 }, +{ 0x00, 0xf2, 0xf2 }, +{ 0x00, 0xf3, 0xf3 }, +{ 0x00, 0xf4, 0xf4 }, +{ 0x00, 0xf5, 0xf5 }, +{ 0x00, 0xf6, 0xf6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xf8 }, +{ 0x00, 0xf9, 0xf9 }, +{ 0x00, 0xfa, 0xfa }, +{ 0x00, 0xfb, 0xfb }, +{ 0x00, 0xfc, 0xfc }, +{ 0x00, 0xfd, 0xfd }, +{ 0x00, 0xfe, 0xfe }, +{ 0x00, 0xff, 0xff }, +}; + +struct cs_info iso7_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x01, 0xdc, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x01, 0xdd, 0xb8 }, +{ 0x01, 0xde, 0xb9 }, +{ 0x01, 0xdf, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x01, 0xfc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x01, 0xfd, 0xbe }, +{ 0x01, 0xfe, 0xbf }, +{ 0x00, 0xc0, 0xc0 }, +{ 0x01, 0xe1, 0xc1 }, +{ 0x01, 0xe2, 0xc2 }, +{ 0x01, 0xe3, 0xc3 }, +{ 0x01, 0xe4, 0xc4 }, +{ 0x01, 0xe5, 0xc5 }, +{ 0x01, 0xe6, 0xc6 }, +{ 0x01, 0xe7, 0xc7 }, +{ 0x01, 0xe8, 0xc8 }, +{ 0x01, 0xe9, 0xc9 }, +{ 0x01, 0xea, 0xca }, +{ 0x01, 0xeb, 0xcb }, +{ 0x01, 0xec, 0xcc }, +{ 0x01, 0xed, 0xcd }, +{ 0x01, 0xee, 0xce }, +{ 0x01, 0xef, 0xcf }, +{ 0x01, 0xf0, 0xd0 }, +{ 0x01, 0xf1, 0xd1 }, +{ 0x00, 0xd2, 0xd2 }, +{ 0x01, 0xf3, 0xd3 }, +{ 0x01, 0xf4, 0xd4 }, +{ 0x01, 0xf5, 0xd5 }, +{ 0x01, 0xf6, 0xd6 }, +{ 0x01, 0xf7, 0xd7 }, +{ 0x01, 0xf8, 0xd8 }, +{ 0x01, 0xf9, 0xd9 }, +{ 0x01, 0xfa, 0xda }, +{ 0x01, 0xfb, 0xdb }, +{ 0x00, 0xdc, 0xb6 }, +{ 0x00, 0xdd, 0xb8 }, +{ 0x00, 0xde, 0xb9 }, +{ 0x00, 0xdf, 0xba }, +{ 0x00, 0xe0, 0xe0 }, +{ 0x00, 0xe1, 0xc1 }, +{ 0x00, 0xe2, 0xc2 }, +{ 0x00, 0xe3, 0xc3 }, +{ 0x00, 0xe4, 0xc4 }, +{ 0x00, 0xe5, 0xc5 }, +{ 0x00, 0xe6, 0xc6 }, +{ 0x00, 0xe7, 0xc7 }, +{ 0x00, 0xe8, 0xc8 }, +{ 0x00, 0xe9, 0xc9 }, +{ 0x00, 0xea, 0xca }, +{ 0x00, 0xeb, 0xcb }, +{ 0x00, 0xec, 0xcc }, +{ 0x00, 0xed, 0xcd }, +{ 0x00, 0xee, 0xce }, +{ 0x00, 0xef, 0xcf }, +{ 0x00, 0xf0, 0xd0 }, +{ 0x00, 0xf1, 0xd1 }, +{ 0x00, 0xf2, 0xd3 }, +{ 0x00, 0xf3, 0xd3 }, +{ 0x00, 0xf4, 0xd4 }, +{ 0x00, 0xf5, 0xd5 }, +{ 0x00, 0xf6, 0xd6 }, +{ 0x00, 0xf7, 0xd7 }, +{ 0x00, 0xf8, 0xd8 }, +{ 0x00, 0xf9, 0xd9 }, +{ 0x00, 0xfa, 0xda }, +{ 0x00, 0xfb, 0xdb }, +{ 0x00, 0xfc, 0xbc }, +{ 0x00, 0xfd, 0xbe }, +{ 0x00, 0xfe, 0xbf }, +{ 0x00, 0xff, 0xff }, +}; + +struct cs_info iso8_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xb9 }, +{ 0x00, 0xba, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x00, 0xbc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xbf }, +{ 0x00, 0xc0, 0xc0 }, +{ 0x00, 0xc1, 0xc1 }, +{ 0x00, 0xc2, 0xc2 }, +{ 0x00, 0xc3, 0xc3 }, +{ 0x00, 0xc4, 0xc4 }, +{ 0x00, 0xc5, 0xc5 }, +{ 0x00, 0xc6, 0xc6 }, +{ 0x00, 0xc7, 0xc7 }, +{ 0x00, 0xc8, 0xc8 }, +{ 0x00, 0xc9, 0xc9 }, +{ 0x00, 0xca, 0xca }, +{ 0x00, 0xcb, 0xcb }, +{ 0x00, 0xcc, 0xcc }, +{ 0x00, 0xcd, 0xcd }, +{ 0x00, 0xce, 0xce }, +{ 0x00, 0xcf, 0xcf }, +{ 0x00, 0xd0, 0xd0 }, +{ 0x00, 0xd1, 0xd1 }, +{ 0x00, 0xd2, 0xd2 }, +{ 0x00, 0xd3, 0xd3 }, +{ 0x00, 0xd4, 0xd4 }, +{ 0x00, 0xd5, 0xd5 }, +{ 0x00, 0xd6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x00, 0xd8, 0xd8 }, +{ 0x00, 0xd9, 0xd9 }, +{ 0x00, 0xda, 0xda }, +{ 0x00, 0xdb, 0xdb }, +{ 0x00, 0xdc, 0xdc }, +{ 0x00, 0xdd, 0xdd }, +{ 0x00, 0xde, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xe0 }, +{ 0x00, 0xe1, 0xe1 }, +{ 0x00, 0xe2, 0xe2 }, +{ 0x00, 0xe3, 0xe3 }, +{ 0x00, 0xe4, 0xe4 }, +{ 0x00, 0xe5, 0xe5 }, +{ 0x00, 0xe6, 0xe6 }, +{ 0x00, 0xe7, 0xe7 }, +{ 0x00, 0xe8, 0xe8 }, +{ 0x00, 0xe9, 0xe9 }, +{ 0x00, 0xea, 0xea }, +{ 0x00, 0xeb, 0xeb }, +{ 0x00, 0xec, 0xec }, +{ 0x00, 0xed, 0xed }, +{ 0x00, 0xee, 0xee }, +{ 0x00, 0xef, 0xef }, +{ 0x00, 0xf0, 0xf0 }, +{ 0x00, 0xf1, 0xf1 }, +{ 0x00, 0xf2, 0xf2 }, +{ 0x00, 0xf3, 0xf3 }, +{ 0x00, 0xf4, 0xf4 }, +{ 0x00, 0xf5, 0xf5 }, +{ 0x00, 0xf6, 0xf6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xf8 }, +{ 0x00, 0xf9, 0xf9 }, +{ 0x00, 0xfa, 0xfa }, +{ 0x00, 0xfb, 0xfb }, +{ 0x00, 0xfc, 0xfc }, +{ 0x00, 0xfd, 0xfd }, +{ 0x00, 0xfe, 0xfe }, +{ 0x00, 0xff, 0xff }, +}; + +struct cs_info iso9_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0xfd, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0xdd }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xb9 }, +{ 0x00, 0xba, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x00, 0xbc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xbf }, +{ 0x01, 0xe0, 0xc0 }, +{ 0x01, 0xe1, 0xc1 }, +{ 0x01, 0xe2, 0xc2 }, +{ 0x01, 0xe3, 0xc3 }, +{ 0x01, 0xe4, 0xc4 }, +{ 0x01, 0xe5, 0xc5 }, +{ 0x01, 0xe6, 0xc6 }, +{ 0x01, 0xe7, 0xc7 }, +{ 0x01, 0xe8, 0xc8 }, +{ 0x01, 0xe9, 0xc9 }, +{ 0x01, 0xea, 0xca }, +{ 0x01, 0xeb, 0xcb }, +{ 0x01, 0xec, 0xcc }, +{ 0x01, 0xed, 0xcd }, +{ 0x01, 0xee, 0xce }, +{ 0x01, 0xef, 0xcf }, +{ 0x01, 0xf0, 0xd0 }, +{ 0x01, 0xf1, 0xd1 }, +{ 0x01, 0xf2, 0xd2 }, +{ 0x01, 0xf3, 0xd3 }, +{ 0x01, 0xf4, 0xd4 }, +{ 0x01, 0xf5, 0xd5 }, +{ 0x01, 0xf6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x01, 0xf8, 0xd8 }, +{ 0x01, 0xf9, 0xd9 }, +{ 0x01, 0xfa, 0xda }, +{ 0x01, 0xfb, 0xdb }, +{ 0x01, 0xfc, 0xdc }, +{ 0x01, 0x69, 0xdd }, +{ 0x01, 0xfe, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xc0 }, +{ 0x00, 0xe1, 0xc1 }, +{ 0x00, 0xe2, 0xc2 }, +{ 0x00, 0xe3, 0xc3 }, +{ 0x00, 0xe4, 0xc4 }, +{ 0x00, 0xe5, 0xc5 }, +{ 0x00, 0xe6, 0xc6 }, +{ 0x00, 0xe7, 0xc7 }, +{ 0x00, 0xe8, 0xc8 }, +{ 0x00, 0xe9, 0xc9 }, +{ 0x00, 0xea, 0xca }, +{ 0x00, 0xeb, 0xcb }, +{ 0x00, 0xec, 0xcc }, +{ 0x00, 0xed, 0xcd }, +{ 0x00, 0xee, 0xce }, +{ 0x00, 0xef, 0xcf }, +{ 0x00, 0xf0, 0xd0 }, +{ 0x00, 0xf1, 0xd1 }, +{ 0x00, 0xf2, 0xd2 }, +{ 0x00, 0xf3, 0xd3 }, +{ 0x00, 0xf4, 0xd4 }, +{ 0x00, 0xf5, 0xd5 }, +{ 0x00, 0xf6, 0xd6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xd8 }, +{ 0x00, 0xf9, 0xd9 }, +{ 0x00, 0xfa, 0xda }, +{ 0x00, 0xfb, 0xdb }, +{ 0x00, 0xfc, 0xdc }, +{ 0x00, 0xfd, 0x49 }, +{ 0x00, 0xfe, 0xde }, +{ 0x00, 0xff, 0xff }, +}; + +struct cs_info iso10_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xb9 }, +{ 0x00, 0xba, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x00, 0xbc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xbf }, +{ 0x00, 0xc0, 0xc0 }, +{ 0x00, 0xc1, 0xc1 }, +{ 0x00, 0xc2, 0xc2 }, +{ 0x00, 0xc3, 0xc3 }, +{ 0x00, 0xc4, 0xc4 }, +{ 0x00, 0xc5, 0xc5 }, +{ 0x00, 0xc6, 0xc6 }, +{ 0x00, 0xc7, 0xc7 }, +{ 0x00, 0xc8, 0xc8 }, +{ 0x00, 0xc9, 0xc9 }, +{ 0x00, 0xca, 0xca }, +{ 0x00, 0xcb, 0xcb }, +{ 0x00, 0xcc, 0xcc }, +{ 0x00, 0xcd, 0xcd }, +{ 0x00, 0xce, 0xce }, +{ 0x00, 0xcf, 0xcf }, +{ 0x00, 0xd0, 0xd0 }, +{ 0x00, 0xd1, 0xd1 }, +{ 0x00, 0xd2, 0xd2 }, +{ 0x00, 0xd3, 0xd3 }, +{ 0x00, 0xd4, 0xd4 }, +{ 0x00, 0xd5, 0xd5 }, +{ 0x00, 0xd6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x00, 0xd8, 0xd8 }, +{ 0x00, 0xd9, 0xd9 }, +{ 0x00, 0xda, 0xda }, +{ 0x00, 0xdb, 0xdb }, +{ 0x00, 0xdc, 0xdc }, +{ 0x00, 0xdd, 0xdd }, +{ 0x00, 0xde, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xe0 }, +{ 0x00, 0xe1, 0xe1 }, +{ 0x00, 0xe2, 0xe2 }, +{ 0x00, 0xe3, 0xe3 }, +{ 0x00, 0xe4, 0xe4 }, +{ 0x00, 0xe5, 0xe5 }, +{ 0x00, 0xe6, 0xe6 }, +{ 0x00, 0xe7, 0xe7 }, +{ 0x00, 0xe8, 0xe8 }, +{ 0x00, 0xe9, 0xe9 }, +{ 0x00, 0xea, 0xea }, +{ 0x00, 0xeb, 0xeb }, +{ 0x00, 0xec, 0xec }, +{ 0x00, 0xed, 0xed }, +{ 0x00, 0xee, 0xee }, +{ 0x00, 0xef, 0xef }, +{ 0x00, 0xf0, 0xf0 }, +{ 0x00, 0xf1, 0xf1 }, +{ 0x00, 0xf2, 0xf2 }, +{ 0x00, 0xf3, 0xf3 }, +{ 0x00, 0xf4, 0xf4 }, +{ 0x00, 0xf5, 0xf5 }, +{ 0x00, 0xf6, 0xf6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xf8 }, +{ 0x00, 0xf9, 0xf9 }, +{ 0x00, 0xfa, 0xfa }, +{ 0x00, 0xfb, 0xfb }, +{ 0x00, 0xfc, 0xfc }, +{ 0x00, 0xfd, 0xfd }, +{ 0x00, 0xfe, 0xfe }, +{ 0x00, 0xff, 0xff }, +}; + +struct cs_info koi8r_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xb3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x01, 0xa3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xb9 }, +{ 0x00, 0xba, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x00, 0xbc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xbf }, +{ 0x00, 0xc0, 0xe0 }, +{ 0x00, 0xc1, 0xe1 }, +{ 0x00, 0xc2, 0xe2 }, +{ 0x00, 0xc3, 0xe3 }, +{ 0x00, 0xc4, 0xe4 }, +{ 0x00, 0xc5, 0xe5 }, +{ 0x00, 0xc6, 0xe6 }, +{ 0x00, 0xc7, 0xe7 }, +{ 0x00, 0xc8, 0xe8 }, +{ 0x00, 0xc9, 0xe9 }, +{ 0x00, 0xca, 0xea }, +{ 0x00, 0xcb, 0xeb }, +{ 0x00, 0xcc, 0xec }, +{ 0x00, 0xcd, 0xed }, +{ 0x00, 0xce, 0xee }, +{ 0x00, 0xcf, 0xef }, +{ 0x00, 0xd0, 0xf0 }, +{ 0x00, 0xd1, 0xf1 }, +{ 0x00, 0xd2, 0xf2 }, +{ 0x00, 0xd3, 0xf3 }, +{ 0x00, 0xd4, 0xf4 }, +{ 0x00, 0xd5, 0xf5 }, +{ 0x00, 0xd6, 0xf6 }, +{ 0x00, 0xd7, 0xf7 }, +{ 0x00, 0xd8, 0xf8 }, +{ 0x00, 0xd9, 0xf9 }, +{ 0x00, 0xda, 0xfa }, +{ 0x00, 0xdb, 0xfb }, +{ 0x00, 0xdc, 0xfc }, +{ 0x00, 0xdd, 0xfd }, +{ 0x00, 0xde, 0xfe }, +{ 0x00, 0xdf, 0xff }, +{ 0x01, 0xc0, 0xe0 }, +{ 0x01, 0xc1, 0xe1 }, +{ 0x01, 0xc2, 0xe2 }, +{ 0x01, 0xc3, 0xe3 }, +{ 0x01, 0xc4, 0xe4 }, +{ 0x01, 0xc5, 0xe5 }, +{ 0x01, 0xc6, 0xe6 }, +{ 0x01, 0xc7, 0xe7 }, +{ 0x01, 0xc8, 0xe8 }, +{ 0x01, 0xc9, 0xe9 }, +{ 0x01, 0xca, 0xea }, +{ 0x01, 0xcb, 0xeb }, +{ 0x01, 0xcc, 0xec }, +{ 0x01, 0xcd, 0xed }, +{ 0x01, 0xce, 0xee }, +{ 0x01, 0xcf, 0xef }, +{ 0x01, 0xd0, 0xf0 }, +{ 0x01, 0xd1, 0xf1 }, +{ 0x01, 0xd2, 0xf2 }, +{ 0x01, 0xd3, 0xf3 }, +{ 0x01, 0xd4, 0xf4 }, +{ 0x01, 0xd5, 0xf5 }, +{ 0x01, 0xd6, 0xf6 }, +{ 0x01, 0xd7, 0xf7 }, +{ 0x01, 0xd8, 0xf8 }, +{ 0x01, 0xd9, 0xf9 }, +{ 0x01, 0xda, 0xfa }, +{ 0x01, 0xdb, 0xfb }, +{ 0x01, 0xdc, 0xfc }, +{ 0x01, 0xdd, 0xfd }, +{ 0x01, 0xde, 0xfe }, +{ 0x01, 0xdf, 0xff }, +}; + +struct cs_info cp1251_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xb9 }, +{ 0x00, 0xba, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x00, 0xbc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xbf }, +{ 0x00, 0xc0, 0xc0 }, +{ 0x00, 0xc1, 0xc1 }, +{ 0x00, 0xc2, 0xc2 }, +{ 0x00, 0xc3, 0xc3 }, +{ 0x00, 0xc4, 0xc4 }, +{ 0x00, 0xc5, 0xc5 }, +{ 0x00, 0xc6, 0xc6 }, +{ 0x00, 0xc7, 0xc7 }, +{ 0x00, 0xc8, 0xc8 }, +{ 0x00, 0xc9, 0xc9 }, +{ 0x00, 0xca, 0xca }, +{ 0x00, 0xcb, 0xcb }, +{ 0x00, 0xcc, 0xcc }, +{ 0x00, 0xcd, 0xcd }, +{ 0x00, 0xce, 0xce }, +{ 0x00, 0xcf, 0xcf }, +{ 0x00, 0xd0, 0xd0 }, +{ 0x00, 0xd1, 0xd1 }, +{ 0x00, 0xd2, 0xd2 }, +{ 0x00, 0xd3, 0xd3 }, +{ 0x00, 0xd4, 0xd4 }, +{ 0x00, 0xd5, 0xd5 }, +{ 0x00, 0xd6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x00, 0xd8, 0xd8 }, +{ 0x00, 0xd9, 0xd9 }, +{ 0x00, 0xda, 0xda }, +{ 0x00, 0xdb, 0xdb }, +{ 0x00, 0xdc, 0xdc }, +{ 0x00, 0xdd, 0xdd }, +{ 0x00, 0xde, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xe0 }, +{ 0x00, 0xe1, 0xe1 }, +{ 0x00, 0xe2, 0xe2 }, +{ 0x00, 0xe3, 0xe3 }, +{ 0x00, 0xe4, 0xe4 }, +{ 0x00, 0xe5, 0xe5 }, +{ 0x00, 0xe6, 0xe6 }, +{ 0x00, 0xe7, 0xe7 }, +{ 0x00, 0xe8, 0xe8 }, +{ 0x00, 0xe9, 0xe9 }, +{ 0x00, 0xea, 0xea }, +{ 0x00, 0xeb, 0xeb }, +{ 0x00, 0xec, 0xec }, +{ 0x00, 0xed, 0xed }, +{ 0x00, 0xee, 0xee }, +{ 0x00, 0xef, 0xef }, +{ 0x00, 0xf0, 0xf0 }, +{ 0x00, 0xf1, 0xf1 }, +{ 0x00, 0xf2, 0xf2 }, +{ 0x00, 0xf3, 0xf3 }, +{ 0x00, 0xf4, 0xf4 }, +{ 0x00, 0xf5, 0xf5 }, +{ 0x00, 0xf6, 0xf6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xf8 }, +{ 0x00, 0xf9, 0xf9 }, +{ 0x00, 0xfa, 0xfa }, +{ 0x00, 0xfb, 0xfb }, +{ 0x00, 0xfc, 0xfc }, +{ 0x00, 0xfd, 0xfd }, +{ 0x00, 0xfe, 0xfe }, +{ 0x00, 0xff, 0xff }, +}; + +struct cs_info iso14_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x01, 0xa2, 0xa1 }, +{ 0x00, 0xa2, 0xa1 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x01, 0xa5, 0xa4 }, +{ 0x00, 0xa5, 0xa4 }, +{ 0x01, 0xa6, 0xab }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x01, 0xb8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x01, 0xba, 0xaa }, +{ 0x00, 0xab, 0xa6 }, +{ 0x01, 0xbc, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x01, 0xff, 0xaf }, +{ 0x01, 0xb1, 0xb0 }, +{ 0x00, 0xb1, 0xb0 }, +{ 0x01, 0xb3, 0xb2 }, +{ 0x00, 0xb3, 0xb2 }, +{ 0x01, 0xb5, 0xb4 }, +{ 0x00, 0xb5, 0xb4 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x01, 0xb9, 0xb7 }, +{ 0x00, 0xb8, 0xa8 }, +{ 0x00, 0xb9, 0xb6 }, +{ 0x00, 0xba, 0xaa }, +{ 0x01, 0xbf, 0xbb }, +{ 0x00, 0xbc, 0xac }, +{ 0x01, 0xbe, 0xbd }, +{ 0x00, 0xbe, 0xbd }, +{ 0x00, 0xbf, 0xbb }, +{ 0x01, 0xe0, 0xc0 }, +{ 0x01, 0xe1, 0xc1 }, +{ 0x01, 0xe2, 0xc2 }, +{ 0x01, 0xe3, 0xc3 }, +{ 0x01, 0xe4, 0xc4 }, +{ 0x01, 0xe5, 0xc5 }, +{ 0x01, 0xe6, 0xc6 }, +{ 0x01, 0xe7, 0xc7 }, +{ 0x01, 0xe8, 0xc8 }, +{ 0x01, 0xe9, 0xc9 }, +{ 0x01, 0xea, 0xca }, +{ 0x01, 0xeb, 0xcb }, +{ 0x01, 0xec, 0xcc }, +{ 0x01, 0xed, 0xcd }, +{ 0x01, 0xee, 0xce }, +{ 0x01, 0xef, 0xcf }, +{ 0x01, 0xf0, 0xd0 }, +{ 0x01, 0xf1, 0xd1 }, +{ 0x01, 0xf2, 0xd2 }, +{ 0x01, 0xf3, 0xd3 }, +{ 0x01, 0xf4, 0xd4 }, +{ 0x01, 0xf5, 0xd5 }, +{ 0x01, 0xf6, 0xd6 }, +{ 0x01, 0xf7, 0xd7 }, +{ 0x01, 0xf8, 0xd8 }, +{ 0x01, 0xf9, 0xd9 }, +{ 0x01, 0xfa, 0xda }, +{ 0x01, 0xfb, 0xdb }, +{ 0x01, 0xfc, 0xdc }, +{ 0x01, 0xfd, 0xdd }, +{ 0x01, 0xfe, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xc0 }, +{ 0x00, 0xe1, 0xc1 }, +{ 0x00, 0xe2, 0xc2 }, +{ 0x00, 0xe3, 0xc3 }, +{ 0x00, 0xe4, 0xc4 }, +{ 0x00, 0xe5, 0xc5 }, +{ 0x00, 0xe6, 0xc6 }, +{ 0x00, 0xe7, 0xc7 }, +{ 0x00, 0xe8, 0xc8 }, +{ 0x00, 0xe9, 0xc9 }, +{ 0x00, 0xea, 0xca }, +{ 0x00, 0xeb, 0xcb }, +{ 0x00, 0xec, 0xcc }, +{ 0x00, 0xed, 0xcd }, +{ 0x00, 0xee, 0xce }, +{ 0x00, 0xef, 0xcf }, +{ 0x00, 0xf0, 0xd0 }, +{ 0x00, 0xf1, 0xd1 }, +{ 0x00, 0xf2, 0xd2 }, +{ 0x00, 0xf3, 0xd3 }, +{ 0x00, 0xf4, 0xd4 }, +{ 0x00, 0xf5, 0xd5 }, +{ 0x00, 0xf6, 0xd6 }, +{ 0x00, 0xf7, 0xd7 }, +{ 0x00, 0xf8, 0xd8 }, +{ 0x00, 0xf9, 0xd9 }, +{ 0x00, 0xfa, 0xda }, +{ 0x00, 0xfb, 0xdb }, +{ 0x00, 0xfc, 0xdc }, +{ 0x00, 0xfd, 0xdd }, +{ 0x00, 0xfe, 0xde }, +{ 0x00, 0xff, 0xff }, +}; + + +struct cs_info iscii_devanagari_tbl[] = { +{ 0x00, 0x00, 0x00 }, +{ 0x00, 0x01, 0x01 }, +{ 0x00, 0x02, 0x02 }, +{ 0x00, 0x03, 0x03 }, +{ 0x00, 0x04, 0x04 }, +{ 0x00, 0x05, 0x05 }, +{ 0x00, 0x06, 0x06 }, +{ 0x00, 0x07, 0x07 }, +{ 0x00, 0x08, 0x08 }, +{ 0x00, 0x09, 0x09 }, +{ 0x00, 0x0a, 0x0a }, +{ 0x00, 0x0b, 0x0b }, +{ 0x00, 0x0c, 0x0c }, +{ 0x00, 0x0d, 0x0d }, +{ 0x00, 0x0e, 0x0e }, +{ 0x00, 0x0f, 0x0f }, +{ 0x00, 0x10, 0x10 }, +{ 0x00, 0x11, 0x11 }, +{ 0x00, 0x12, 0x12 }, +{ 0x00, 0x13, 0x13 }, +{ 0x00, 0x14, 0x14 }, +{ 0x00, 0x15, 0x15 }, +{ 0x00, 0x16, 0x16 }, +{ 0x00, 0x17, 0x17 }, +{ 0x00, 0x18, 0x18 }, +{ 0x00, 0x19, 0x19 }, +{ 0x00, 0x1a, 0x1a }, +{ 0x00, 0x1b, 0x1b }, +{ 0x00, 0x1c, 0x1c }, +{ 0x00, 0x1d, 0x1d }, +{ 0x00, 0x1e, 0x1e }, +{ 0x00, 0x1f, 0x1f }, +{ 0x00, 0x20, 0x20 }, +{ 0x00, 0x21, 0x21 }, +{ 0x00, 0x22, 0x22 }, +{ 0x00, 0x23, 0x23 }, +{ 0x00, 0x24, 0x24 }, +{ 0x00, 0x25, 0x25 }, +{ 0x00, 0x26, 0x26 }, +{ 0x00, 0x27, 0x27 }, +{ 0x00, 0x28, 0x28 }, +{ 0x00, 0x29, 0x29 }, +{ 0x00, 0x2a, 0x2a }, +{ 0x00, 0x2b, 0x2b }, +{ 0x00, 0x2c, 0x2c }, +{ 0x00, 0x2d, 0x2d }, +{ 0x00, 0x2e, 0x2e }, +{ 0x00, 0x2f, 0x2f }, +{ 0x00, 0x30, 0x30 }, +{ 0x00, 0x31, 0x31 }, +{ 0x00, 0x32, 0x32 }, +{ 0x00, 0x33, 0x33 }, +{ 0x00, 0x34, 0x34 }, +{ 0x00, 0x35, 0x35 }, +{ 0x00, 0x36, 0x36 }, +{ 0x00, 0x37, 0x37 }, +{ 0x00, 0x38, 0x38 }, +{ 0x00, 0x39, 0x39 }, +{ 0x00, 0x3a, 0x3a }, +{ 0x00, 0x3b, 0x3b }, +{ 0x00, 0x3c, 0x3c }, +{ 0x00, 0x3d, 0x3d }, +{ 0x00, 0x3e, 0x3e }, +{ 0x00, 0x3f, 0x3f }, +{ 0x00, 0x40, 0x40 }, +{ 0x01, 0x61, 0x41 }, +{ 0x01, 0x62, 0x42 }, +{ 0x01, 0x63, 0x43 }, +{ 0x01, 0x64, 0x44 }, +{ 0x01, 0x65, 0x45 }, +{ 0x01, 0x66, 0x46 }, +{ 0x01, 0x67, 0x47 }, +{ 0x01, 0x68, 0x48 }, +{ 0x01, 0x69, 0x49 }, +{ 0x01, 0x6a, 0x4a }, +{ 0x01, 0x6b, 0x4b }, +{ 0x01, 0x6c, 0x4c }, +{ 0x01, 0x6d, 0x4d }, +{ 0x01, 0x6e, 0x4e }, +{ 0x01, 0x6f, 0x4f }, +{ 0x01, 0x70, 0x50 }, +{ 0x01, 0x71, 0x51 }, +{ 0x01, 0x72, 0x52 }, +{ 0x01, 0x73, 0x53 }, +{ 0x01, 0x74, 0x54 }, +{ 0x01, 0x75, 0x55 }, +{ 0x01, 0x76, 0x56 }, +{ 0x01, 0x77, 0x57 }, +{ 0x01, 0x78, 0x58 }, +{ 0x01, 0x79, 0x59 }, +{ 0x01, 0x7a, 0x5a }, +{ 0x00, 0x5b, 0x5b }, +{ 0x00, 0x5c, 0x5c }, +{ 0x00, 0x5d, 0x5d }, +{ 0x00, 0x5e, 0x5e }, +{ 0x00, 0x5f, 0x5f }, +{ 0x00, 0x60, 0x60 }, +{ 0x00, 0x61, 0x41 }, +{ 0x00, 0x62, 0x42 }, +{ 0x00, 0x63, 0x43 }, +{ 0x00, 0x64, 0x44 }, +{ 0x00, 0x65, 0x45 }, +{ 0x00, 0x66, 0x46 }, +{ 0x00, 0x67, 0x47 }, +{ 0x00, 0x68, 0x48 }, +{ 0x00, 0x69, 0x49 }, +{ 0x00, 0x6a, 0x4a }, +{ 0x00, 0x6b, 0x4b }, +{ 0x00, 0x6c, 0x4c }, +{ 0x00, 0x6d, 0x4d }, +{ 0x00, 0x6e, 0x4e }, +{ 0x00, 0x6f, 0x4f }, +{ 0x00, 0x70, 0x50 }, +{ 0x00, 0x71, 0x51 }, +{ 0x00, 0x72, 0x52 }, +{ 0x00, 0x73, 0x53 }, +{ 0x00, 0x74, 0x54 }, +{ 0x00, 0x75, 0x55 }, +{ 0x00, 0x76, 0x56 }, +{ 0x00, 0x77, 0x57 }, +{ 0x00, 0x78, 0x58 }, +{ 0x00, 0x79, 0x59 }, +{ 0x00, 0x7a, 0x5a }, +{ 0x00, 0x7b, 0x7b }, +{ 0x00, 0x7c, 0x7c }, +{ 0x00, 0x7d, 0x7d }, +{ 0x00, 0x7e, 0x7e }, +{ 0x00, 0x7f, 0x7f }, +{ 0x00, 0x80, 0x80 }, +{ 0x00, 0x81, 0x81 }, +{ 0x00, 0x82, 0x82 }, +{ 0x00, 0x83, 0x83 }, +{ 0x00, 0x84, 0x84 }, +{ 0x00, 0x85, 0x85 }, +{ 0x00, 0x86, 0x86 }, +{ 0x00, 0x87, 0x87 }, +{ 0x00, 0x88, 0x88 }, +{ 0x00, 0x89, 0x89 }, +{ 0x00, 0x8a, 0x8a }, +{ 0x00, 0x8b, 0x8b }, +{ 0x00, 0x8c, 0x8c }, +{ 0x00, 0x8d, 0x8d }, +{ 0x00, 0x8e, 0x8e }, +{ 0x00, 0x8f, 0x8f }, +{ 0x00, 0x90, 0x90 }, +{ 0x00, 0x91, 0x91 }, +{ 0x00, 0x92, 0x92 }, +{ 0x00, 0x93, 0x93 }, +{ 0x00, 0x94, 0x94 }, +{ 0x00, 0x95, 0x95 }, +{ 0x00, 0x96, 0x96 }, +{ 0x00, 0x97, 0x97 }, +{ 0x00, 0x98, 0x98 }, +{ 0x00, 0x99, 0x99 }, +{ 0x00, 0x9a, 0x9a }, +{ 0x00, 0x9b, 0x9b }, +{ 0x00, 0x9c, 0x9c }, +{ 0x00, 0x9d, 0x9d }, +{ 0x00, 0x9e, 0x9e }, +{ 0x00, 0x9f, 0x9f }, +{ 0x00, 0xa0, 0xa0 }, +{ 0x00, 0xa1, 0xa1 }, +{ 0x00, 0xa2, 0xa2 }, +{ 0x00, 0xa3, 0xa3 }, +{ 0x00, 0xa4, 0xa4 }, +{ 0x00, 0xa5, 0xa5 }, +{ 0x00, 0xa6, 0xa6 }, +{ 0x00, 0xa7, 0xa7 }, +{ 0x00, 0xa8, 0xa8 }, +{ 0x00, 0xa9, 0xa9 }, +{ 0x00, 0xaa, 0xaa }, +{ 0x00, 0xab, 0xab }, +{ 0x00, 0xac, 0xac }, +{ 0x00, 0xad, 0xad }, +{ 0x00, 0xae, 0xae }, +{ 0x00, 0xaf, 0xaf }, +{ 0x00, 0xb0, 0xb0 }, +{ 0x00, 0xb1, 0xb1 }, +{ 0x00, 0xb2, 0xb2 }, +{ 0x00, 0xb3, 0xb3 }, +{ 0x00, 0xb4, 0xb4 }, +{ 0x00, 0xb5, 0xb5 }, +{ 0x00, 0xb6, 0xb6 }, +{ 0x00, 0xb7, 0xb7 }, +{ 0x00, 0xb8, 0xb8 }, +{ 0x00, 0xb9, 0xb9 }, +{ 0x00, 0xba, 0xba }, +{ 0x00, 0xbb, 0xbb }, +{ 0x00, 0xbc, 0xbc }, +{ 0x00, 0xbd, 0xbd }, +{ 0x00, 0xbe, 0xbe }, +{ 0x00, 0xbf, 0xbf }, +{ 0x00, 0xc0, 0xc0 }, +{ 0x00, 0xc1, 0xc1 }, +{ 0x00, 0xc2, 0xc2 }, +{ 0x00, 0xc3, 0xc3 }, +{ 0x00, 0xc4, 0xc4 }, +{ 0x00, 0xc5, 0xc5 }, +{ 0x00, 0xc6, 0xc6 }, +{ 0x00, 0xc7, 0xc7 }, +{ 0x00, 0xc8, 0xc8 }, +{ 0x00, 0xc9, 0xc9 }, +{ 0x00, 0xca, 0xca }, +{ 0x00, 0xcb, 0xcb }, +{ 0x00, 0xcc, 0xcc }, +{ 0x00, 0xcd, 0xcd }, +{ 0x00, 0xce, 0xce }, +{ 0x00, 0xcf, 0xcf }, +{ 0x00, 0xd0, 0xd0 }, +{ 0x00, 0xd1, 0xd1 }, +{ 0x00, 0xd2, 0xd2 }, +{ 0x00, 0xd3, 0xd3 }, +{ 0x00, 0xd4, 0xd4 }, +{ 0x00, 0xd5, 0xd5 }, +{ 0x00, 0xd6, 0xd6 }, +{ 0x00, 0xd7, 0xd7 }, +{ 0x00, 0xd8, 0xd8 }, +{ 0x00, 0xd9, 0xd9 }, +{ 0x00, 0xda, 0xda }, +{ 0x00, 0xdb, 0xdb }, +{ 0x00, 0xdc, 0xdc }, +{ 0x00, 0xdd, 0xdd }, +{ 0x00, 0xde, 0xde }, +{ 0x00, 0xdf, 0xdf }, +{ 0x00, 0xe0, 0xe0 }, +{ 0x00, 0xe1, 0xe1 }, +{ 0x00, 0xe2, 0xe2 }, +{ 0x00, 0xe3, 0xe3 }, +{ 0x00, 0xe4, 0xe4 }, +{ 0x00, 0xe5, 0xe5 }, +{ 0x00, 0xe6, 0xe6 }, +{ 0x00, 0xe7, 0xe7 }, +{ 0x00, 0xe8, 0xe8 }, +{ 0x00, 0xe9, 0xe9 }, +{ 0x00, 0xea, 0xea }, +{ 0x00, 0xeb, 0xeb }, +{ 0x00, 0xec, 0xec }, +{ 0x00, 0xed, 0xed }, +{ 0x00, 0xee, 0xee }, +{ 0x00, 0xef, 0xef }, +{ 0x00, 0xf0, 0xf0 }, +{ 0x00, 0xf1, 0xf1 }, +{ 0x00, 0xf2, 0xf2 }, +{ 0x00, 0xf3, 0xf3 }, +{ 0x00, 0xf4, 0xf4 }, +{ 0x00, 0xf5, 0xf5 }, +{ 0x00, 0xf6, 0xf6 }, +{ 0x00, 0xf7, 0xf7 }, +{ 0x00, 0xf8, 0xf8 }, +{ 0x00, 0xf9, 0xf9 }, +{ 0x00, 0xfa, 0xfa }, +{ 0x00, 0xfb, 0xfb }, +{ 0x00, 0xfc, 0xfc }, +{ 0x00, 0xfd, 0xfd }, +{ 0x00, 0xfe, 0xfe }, +{ 0x00, 0xff, 0xff }, +}; + + + +struct enc_entry encds[] = { +{"ISO8859-1",iso1_tbl}, +{"ISO8859-2",iso2_tbl}, +{"ISO8859-3",iso3_tbl}, +{"ISO8859-4",iso4_tbl}, +{"ISO8859-5",iso5_tbl}, +{"ISO8859-6",iso6_tbl}, +{"ISO8859-7",iso7_tbl}, +{"ISO8859-8",iso8_tbl}, +{"ISO8859-9",iso9_tbl}, +{"ISO8859-10",iso10_tbl}, +{"KOI8-R",koi8r_tbl}, +{"CP-1251",cp1251_tbl}, +{"ISO8859-14", iso14_tbl}, +{"ISCII-DEVANAGARI", iscii_devanagari_tbl}, +}; + + +struct cs_info * get_current_cs(const char * es) { + struct cs_info * ccs = encds[0].cs_table; + int n = sizeof(encds) / sizeof(encds[0]); + for (int i = 0; i < n; i++) { + if (strcmp(es,encds[i].enc_name) == 0) { + ccs = encds[i].cs_table; + } + } + return ccs; +}; + + + +struct lang_map lang2enc[] = { + {"ca","ISO8859-1"}, + {"cs","ISO8859-2"}, + {"da","ISO8859-1"}, + {"de","ISO8859-1"}, + {"el","ISO8859-7"}, + {"en","ISO8859-1"}, + {"es","ISO8859-1"}, + {"fr","ISO8859-1"}, + {"hr","ISO8859-2"}, + {"hu","ISO8859-2"}, + {"it","ISO8859-1"}, + {"la","ISO8859-1"}, + {"nl","ISO8859-1"}, + {"pl","ISO8859-2"}, + {"pt","ISO8859-1"}, + {"sv","ISO8859-1"}, + {"ru","KOI8-R"}, +}; + + +const char * get_default_enc(const char * lang) { + int n = sizeof(lang2enc) / sizeof(lang2enc[0]); + for (int i = 0; i < n; i++) { + if (strcmp(lang,lang2enc[i].lang) == 0) { + return lang2enc[i].def_enc; + } + } + return NULL; +}; + diff --git a/goldlib/myspell/csutil.hxx b/goldlib/myspell/csutil.hxx new file mode 100644 index 0000000..eb5be3b --- /dev/null +++ b/goldlib/myspell/csutil.hxx @@ -0,0 +1,67 @@ +#ifndef __CSUTILHXX__ +#define __CSUTILHXX__ + + +// First some base level utility routines + +// remove end of line char(s) +void mychomp(char * s); + +// duplicate string +char * mystrdup(const char * s); + +// duplicate reverse of string +char * myrevstrdup(const char * s); + +// parse into tokens with char delimiter +char * mystrsep(char ** sptr, const char delim); + +// is one string a leading subset of another +int isSubset(const char * s1, const char * s2); + + +// character encoding information + +struct cs_info { + unsigned char ccase; + unsigned char clower; + unsigned char cupper; +}; + + +struct enc_entry { + const char * enc_name; + struct cs_info * cs_table; +}; + +// language to encoding default map + +struct lang_map { + const char * lang; + const char * def_enc; +}; + +struct cs_info * get_current_cs(const char * es); + +const char * get_default_enc(const char * lang); + +// convert null terminated string to all caps using encoding +void enmkallcap(char * d, const char * p, const char * encoding); + +// convert null terminated string to all little using encoding +void enmkallsmall(char * d, const char * p, const char * encoding); + +// convert null terminated string to have intial capital using encoding +void enmkinitcap(char * d, const char * p, const char * encoding); + +// convert null terminated string to all caps +void mkallcap(char * p, const struct cs_info * csconv); + +// convert null terminated string to all little +void mkallsmall(char * p, const struct cs_info * csconv); + +// convert null terminated string to have intial capital +void mkinitcap(char * p, const struct cs_info * csconv); + + +#endif diff --git a/goldlib/myspell/dictmgr.cxx b/goldlib/myspell/dictmgr.cxx new file mode 100644 index 0000000..d3005b8 --- /dev/null +++ b/goldlib/myspell/dictmgr.cxx @@ -0,0 +1,127 @@ + +#include +#include +#include +#include + +#include "dictmgr.hxx" + +#if !defined(_MSC_VER) +using namespace std; +#endif + +// some utility functions +extern void mychomp(char * s); +extern char * mystrdup(const char * s); +extern char * mystrsep(char ** stringp, const char delim); + +DictMgr::DictMgr(const char * dictpath, const char * etype) +{ + // load list of etype entries + numdict = 0; + pdentry = (dictentry *)malloc(MAXDICTIONARIES*sizeof(struct dictentry)); + if (pdentry) { + if (parse_file(dictpath, etype)) { + numdict = 0; + // no dictionary.lst found is okay + } + } else { + numdict = 0; + } +} + + +DictMgr::~DictMgr() +{ + dictentry * pdict = NULL; + if (pdentry) { + pdict = pdentry; + for (int i=0;ilang) { + free(pdict->lang); + pdict->lang = NULL; + } + if (pdict->region) { + free(pdict->region); + pdict->region=NULL; + } + if (pdict->filename) { + free(pdict->filename); + pdict->filename = NULL; + } + pdict++; + } + free(pdentry); + pdentry = NULL; + pdict = NULL; + } + numdict = 0; +} + + +// read in list of etype entries and build up structure to describe them +int DictMgr::parse_file(const char * dictpath, const char * etype) +{ + + int i; + char line[MAXDICTENTRYLEN+1]; + dictentry * pdict = pdentry; + + // open the dictionary list file + FILE * dictlst; + dictlst = fopen(dictpath,"r"); + if (!dictlst) { + return 1; + } + + // step one is to parse the dictionary list building up the + // descriptive structures + + // read in each line ignoring any that dont start with etype + while (fgets(line,MAXDICTENTRYLEN,dictlst)) { + mychomp(line); + + /* parse in a dictionary entry */ + if (strncmp(line,etype,4) == 0) { + if (numdict < MAXDICTIONARIES) { + char * tp = line; + char * piece; + i = 0; + while ((piece=mystrsep(&tp,' '))) { + if (*piece != '\0') { + switch(i) { + case 0: break; + case 1: pdict->lang = mystrdup(piece); break; + case 2: if (strcmp (piece, "ANY") == 0) + pdict->region = mystrdup(""); + else + pdict->region = mystrdup(piece); + break; + case 3: pdict->filename = mystrdup(piece); break; + default: break; + } + i++; + } + free(piece); + } + if (i == 4) { + numdict++; + pdict++; + } else { + fprintf(stderr,"dictionary list corruption in line \"%s\"\n",line); + fflush(stderr); + } + } + } + } + fclose(dictlst); + return 0; +} + +// return text encoding of dictionary +int DictMgr::get_list(dictentry ** ppentry) +{ + *ppentry = pdentry; + return numdict; +} + diff --git a/goldlib/myspell/dictmgr.hxx b/goldlib/myspell/dictmgr.hxx new file mode 100644 index 0000000..1f5071b --- /dev/null +++ b/goldlib/myspell/dictmgr.hxx @@ -0,0 +1,31 @@ +#ifndef _DICTMGR_HXX_ +#define _DICTMGR_HXX_ + +#define MAXDICTIONARIES 100 +#define MAXDICTENTRYLEN 1024 + +struct dictentry { + char * filename; + char * lang; + char * region; +}; + + +class DictMgr +{ + + int numdict; + dictentry * pdentry; + +public: + + DictMgr(const char * dictpath, const char * etype); + ~DictMgr(); + int get_list(dictentry** ppentry); + +private: + int parse_file(const char * dictpath, const char * etype); + +}; + +#endif diff --git a/goldlib/myspell/example.cxx b/goldlib/myspell/example.cxx new file mode 100644 index 0000000..11e249d --- /dev/null +++ b/goldlib/myspell/example.cxx @@ -0,0 +1,89 @@ +#include +#include +#include + +#include "myspell.hxx" + +extern char * mystrdup(const char * s); + +using namespace std; + +int +main(int argc, char** argv) +{ + + char * af; + char * df; + char * wtc; + FILE* wtclst; + + /* first parse the command line options */ + /* arg1 - affix file, arg2 dictionary file, arg3 - file of words to check */ + + if (argv[1]) { + af = mystrdup(argv[1]); + } else { + fprintf(stderr,"correct syntax is:\n"); + fprintf(stderr,"example affix_file dictionary_file file_of_words_to_check\n"); + exit(1); + } + if (argv[2]) { + df = mystrdup(argv[2]); + } else { + fprintf(stderr,"correct syntax is:\n"); + fprintf(stderr,"example affix_file dictionary_file file_of_words_to_check\n"); + exit(1); + } + if (argv[3]) { + wtc = mystrdup(argv[3]); + } else { + fprintf(stderr,"correct syntax is:\n"); + fprintf(stderr,"example affix_file dictionary_file file_of_words_to_check\n"); + exit(1); + } + + + /* open the words to check list */ + wtclst = fopen(wtc,"r"); + if (!wtclst) { + fprintf(stderr,"Error - could not open file of words to check\n"); + exit(1); + } + + + MySpell * pMS= new MySpell(af,df); + + int k; + int dp; + char buf[101]; + + while(fgets(buf,100,wtclst)) { + k = strlen(buf); + *(buf + k - 1) = '\0'; + dp = pMS->spell(buf); + if (dp) { + fprintf(stdout,"\"%s\" is okay\n",buf); + fprintf(stdout,"\n"); + } else { + fprintf(stdout,"\"%s\" is incorrect!\n",buf); + fprintf(stdout," suggestions:\n"); + char ** wlst; + int ns = pMS->suggest(&wlst,buf); + for (int i=0; i < ns; i++) { + fprintf(stdout," ...\"%s\"\n",wlst[i]); + free(wlst[i]); + } + fprintf(stdout,"\n"); + free(wlst); + } + } + + delete pMS; + fclose(wtclst); + free(wtc); + free(df); + free(af); + + return 0; +} + diff --git a/goldlib/myspell/hashmgr.cxx b/goldlib/myspell/hashmgr.cxx new file mode 100644 index 0000000..7e34687 --- /dev/null +++ b/goldlib/myspell/hashmgr.cxx @@ -0,0 +1,213 @@ +#include "license.readme" + +#if !defined(_MSC_VER) +#include +#endif +#include +#include +#include +#include + +#include "hashmgr.hxx" + +extern void mychomp(char * s); +extern char * mystrdup(const char *); + +#if !defined(_MSC_VER) +using namespace std; +#endif + + +// build a hash table from a munched word list + +HashMgr::HashMgr(const char * tpath) +{ + tablesize = 0; + tableptr = NULL; + int ec = load_tables(tpath); + if (ec) { + /* error condition - what should we do here */ + fprintf(stderr,"Hash Manager Error : %d\n",ec); + fflush(stderr); + if (tableptr) { + free(tableptr); + } + tablesize = 0; + } +} + + +HashMgr::~HashMgr() +{ + if (tableptr) { + // now pass through hash table freeing up everything + // go through column by column of the table + for (int i=0; i < tablesize; i++) { + struct hentry * pt = &tableptr[i]; + struct hentry * nt = NULL; + if (pt) { + if (pt->word) free(pt->word); + if (pt->astr) free(pt->astr); + pt = pt->next; + } + while(pt) { + nt = pt->next; + if (pt->word) free(pt->word); + if (pt->astr) free(pt->astr); + free(pt); + pt = nt; + } + } + free(tableptr); + } + tablesize = 0; +} + + + +// lookup a root word in the hashtable + +struct hentry * HashMgr::lookup(const char *word) const +{ + struct hentry * dp; + if (tableptr) { + dp = &tableptr[hash(word)]; + if (dp->word == NULL) return NULL; + for ( ; dp != NULL; dp = dp->next) { + if (strcmp(word,dp->word) == 0) return dp; + } + } + return NULL; +} + + + +// add a word to the hash table (private) + +int HashMgr::add_word(const char * word, int wl, const char * aff, int al) +{ + int i = hash(word); + struct hentry * dp = &tableptr[i]; + struct hentry* hp; + if (dp->word == NULL) { + dp->wlen = wl; + dp->alen = al; + dp->word = mystrdup(word); + dp->astr = mystrdup(aff); + dp->next = NULL; + if ((wl) && (dp->word == NULL)) return 1; + if ((al) && (dp->astr == NULL)) return 1; + } else { + hp = (struct hentry *) malloc (sizeof(struct hentry)); + if (hp == NULL) return 1; + hp->wlen = wl; + hp->alen = al; + hp->word = mystrdup(word); + hp->astr = mystrdup(aff); + hp->next = NULL; + while (dp->next != NULL) dp=dp->next; + dp->next = hp; + if ((wl) && (hp->word == NULL)) return 1; + if ((al) && (hp->astr == NULL)) return 1; + } + return 0; +} + + + +// walk the hash table entry by entry - null at end +struct hentry * HashMgr::walk_hashtable(int &col, struct hentry * hp) const +{ + //reset to start + if ((col < 0) || (hp == NULL)) { + col = -1; + hp = NULL; + } + + if (hp && hp->next != NULL) { + hp = hp->next; + } else { + col++; + hp = (col < tablesize) ? &tableptr[col] : NULL; + // search for next non-blank column entry + while (hp && (hp->word == NULL)) { + col ++; + hp = (col < tablesize) ? &tableptr[col] : NULL; + } + if (col < tablesize) return hp; + hp = NULL; + col = -1; + } + return hp; +} + + + +// load a munched word list and build a hash table on the fly + +int HashMgr::load_tables(const char * tpath) +{ + int wl, al; + char * ap; + + // raw dictionary - munched file + FILE * rawdict = fopen(tpath, "r"); + if (rawdict == NULL) return 1; + + // first read the first line of file to get hash table size */ + char ts[MAXDELEN]; + if (! fgets(ts, MAXDELEN-1,rawdict)) return 2; + mychomp(ts); + tablesize = atoi(ts); + if (!tablesize) return 4; + tablesize = tablesize + 5; + if ((tablesize %2) == 0) tablesize++; + + // allocate the hash table + tableptr = (struct hentry *) calloc(tablesize, sizeof(struct hentry)); + if (! tableptr) return 3; + + // loop through all words on much list and add to hash + // table and create word and affix strings + + while (fgets(ts,MAXDELEN-1,rawdict)) { + mychomp(ts); + // split each line into word and affix char strings + ap = strchr(ts,'/'); + if (ap) { + *ap = '\0'; + ap++; + al = strlen(ap); + } else { + al = 0; + ap = NULL; + } + + wl = strlen(ts); + + // add the word and its index + if (add_word(ts,wl,ap,al)) + return 5;; + + } + + fclose(rawdict); + return 0; +} + + +// the hash function is a simple load and rotate +// algorithm borrowed + +int HashMgr::hash(const char * word) const +{ + long hv = 0; + for (int i=0; i < 4 && *word != 0; i++) + hv = (hv << 8) | (*word++); + while (*word != 0) { + ROTATE(hv,ROTATE_LEN); + hv ^= (*word++); + } + return (unsigned long) hv % tablesize; +} + diff --git a/goldlib/myspell/hashmgr.hxx b/goldlib/myspell/hashmgr.hxx new file mode 100644 index 0000000..e8b08c3 --- /dev/null +++ b/goldlib/myspell/hashmgr.hxx @@ -0,0 +1,27 @@ +#ifndef _HASHMGR_HXX_ +#define _HASHMGR_HXX_ + +#include "htypes.hxx" + +class HashMgr +{ + int tablesize; + struct hentry * tableptr; + +public: + HashMgr(const char * tpath); + ~HashMgr(); + + struct hentry * lookup(const char *) const; + int hash(const char *) const; + struct hentry * walk_hashtable(int & col, struct hentry * hp) const; + +private: + HashMgr( const HashMgr & ); // not implemented + HashMgr &operator=( const HashMgr & ); // not implemented + int load_tables(const char * tpath); + int add_word(const char * word, int wl, const char * ap, int al); + +}; + +#endif diff --git a/goldlib/myspell/htypes.hxx b/goldlib/myspell/htypes.hxx new file mode 100644 index 0000000..029e9f2 --- /dev/null +++ b/goldlib/myspell/htypes.hxx @@ -0,0 +1,20 @@ +#ifndef _HTYPES_HXX_ +#define _HTYPES_HXX_ + +#define MAXDELEN 256 + +#define ROTATE_LEN 5 + +#define ROTATE(v,q) \ + (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q))-1)); + +struct hentry +{ + short wlen; + short alen; + char * word; + char * astr; + struct hentry * next; +}; + +#endif diff --git a/goldlib/myspell/license.readme b/goldlib/myspell/license.readme new file mode 100644 index 0000000..2da5330 --- /dev/null +++ b/goldlib/myspell/license.readme @@ -0,0 +1,61 @@ +/* + * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada + * And Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All modifications to the source code must be clearly marked as + * such. Binary redistributions based on modified source code + * must be clearly marked as modified versions in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * NOTE: A special thanks and credit goes to Geoff Kuenning + * the creator of ispell. MySpell's affix algorithms were + * based on those of ispell which should be noted is + * copyright Geoff Kuenning et.al. and now available + * under a BSD style license. For more information on ispell + * and affix compression in general, please see: + * http://www.cs.ucla.edu/ficus-members/geoff/ispell.html + * (the home page for ispell) + * + * An almost complete rewrite of MySpell for use by + * the Mozilla project has been developed by David Einstein + * (Deinst@world.std.com). David and I are now + * working on parallel development tracks to help + * our respective projects (Mozilla and OpenOffice.org + * and we will maintain full affix file and dictionary + * file compatibility and work on merging our versions + * of MySpell back into a single tree. David has been + * a significant help in improving MySpell. + * + * Special thanks also go to La'szlo' Ne'meth + * who is the author of the + * Hungarian dictionary and who developed and contributed + * the code to support compound words in MySpell + * and fixed numerous problems with the encoding + * case conversion tables. + * + */ diff --git a/goldlib/myspell/myspell.cxx b/goldlib/myspell/myspell.cxx new file mode 100644 index 0000000..9407e86 --- /dev/null +++ b/goldlib/myspell/myspell.cxx @@ -0,0 +1,302 @@ +#include "license.readme" + +#include +#include +#include + +#include "myspell.hxx" + +#if !defined(_MSC_VER) +using namespace std; +#endif + + +MySpell::MySpell(const char * affpath, const char * dpath) +{ + encoding = NULL; + csconv = NULL; + + /* first set up the hash manager */ + pHMgr = new HashMgr(dpath); + + /* next set up the affix manager */ + /* it needs access to the hash manager lookup methods */ + pAMgr = new AffixMgr(affpath,pHMgr); + + /* get the preferred try string and the dictionary */ + /* encoding from the Affix Manager for that dictionary */ + char * try_string = pAMgr->get_try_string(); + encoding = pAMgr->get_encoding(); + csconv = get_current_cs(encoding); + + /* and finally set up the suggestion manager */ + maxSug = 100; + pSMgr = new SuggestMgr(try_string, maxSug, pAMgr); + if (try_string) free(try_string); +} + + +MySpell::~MySpell() +{ + if (pSMgr) delete pSMgr; + if (pAMgr) delete pAMgr; + if (pHMgr) delete pHMgr; + pSMgr = NULL; + pAMgr = NULL; + pHMgr = NULL; + csconv= NULL; + if (encoding) free(encoding); + encoding = NULL; +} + + +// make a copy of src at destination while removing all leading +// blanks and removing any trailing periods after recording +// their presence with the abbreviation flag +// also since already going through character by character, +// set the capitalization type +// return the length of the "cleaned" word + +int MySpell::cleanword(char * dest, const char * src, int * pcaptype, int * pabbrev) +{ + + // with the new breakiterator code this should not be needed anymore + const char * special_chars = "._#$%&()* +,-/:;<=>[]\\^`{|}~\t \x0a\x0d\x01\'\""; + + unsigned char * p = (unsigned char *) dest; + const unsigned char * q = (const unsigned char * ) src; + + // first skip over any leading special characters + while ((*q != '\0') && (strchr(special_chars,(int)(*q)))) q++; + + // now strip off any trailing special characters + // if a period comes after a normal char record its presence + *pabbrev = 0; + int nl = strlen((const char *)q); + while ((nl > 0) && (strchr(special_chars,(int)(*(q+nl-1))))) { + nl--; + } + if ( *(q+nl) == '.' ) *pabbrev = 1; + + // if no characters are left it can't be an abbreviation and can't be capitalized + if (nl <= 0) { + *pcaptype = NOCAP; + *pabbrev = 0; + *p = '\0'; + return 0; + } + + // now determine the capitalization type of the first nl letters + int ncap = 0; + int nneutral = 0; + int nc = 0; + while (nl > 0) { + nc++; + if (csconv[(*q)].ccase) ncap++; + if (csconv[(*q)].cupper == csconv[(*q)].clower) nneutral++; + *p++ = *q++; + nl--; + } + // remember to terminate the destination string + *p = '\0'; + + // now finally set the captype + if (ncap == 0) { + *pcaptype = NOCAP; + } else if ((ncap == 1) && csconv[(unsigned char)(*dest)].ccase) { + *pcaptype = INITCAP; + } else if ((ncap == nc) || ((ncap + nneutral) == nc)){ + *pcaptype = ALLCAP; + } else { + *pcaptype = HUHCAP; + } + return nc; +} + + +int MySpell::spell(const char * word) +{ + char * rv=NULL; + char cw[MAXWORDLEN+1]; + char wspace[MAXWORDLEN+1]; + + int wl = strlen(word); + if (wl > (MAXWORDLEN - 1)) return 0; + int captype = 0; + int abbv = 0; + wl = cleanword(cw, word, &captype, &abbv); + if (wl == 0) return 1; + + switch(captype) { + case HUHCAP: + case NOCAP: { + rv = check(cw); + if ((abbv) && !(rv)) { + memcpy(wspace,cw,wl); + *(wspace+wl) = '.'; + *(wspace+wl+1) = '\0'; + rv = check(wspace); + } + break; + } + + case ALLCAP: { + memcpy(wspace,cw,(wl+1)); + mkallsmall(wspace, csconv); + rv = check(wspace); + if (!rv) { + mkinitcap(wspace, csconv); + rv = check(wspace); + } + if (!rv) rv = check(cw); + if ((abbv) && !(rv)) { + memcpy(wspace,cw,wl); + *(wspace+wl) = '.'; + *(wspace+wl+1) = '\0'; + rv = check(wspace); + } + break; + } + case INITCAP: { + memcpy(wspace,cw,(wl+1)); + mkallsmall(wspace, csconv); + rv = check(wspace); + if (!rv) rv = check(cw); + if ((abbv) && !(rv)) { + memcpy(wspace,cw,wl); + *(wspace+wl) = '.'; + *(wspace+wl+1) = '\0'; + rv = check(wspace); + } + break; + } + } + if (rv) return 1; + return 0; +} + + +char * MySpell::check(const char * word) +{ + struct hentry * he = NULL; + if (pHMgr) + he = pHMgr->lookup (word); + + if ((he == NULL) && (pAMgr)) { + // try stripping off affixes */ + he = pAMgr->affix_check(word, strlen(word)); + + // try check compound word + if ((he == NULL) && (pAMgr->get_compound())) { + he = pAMgr->compound_check(word, strlen(word), (pAMgr->get_compound())[0]); + } + + } + + if (he) return he->word; + return NULL; +} + + + +int MySpell::suggest(char*** slst, const char * word) +{ + char cw[MAXWORDLEN+1]; + char wspace[MAXWORDLEN+1]; + if (! pSMgr) return 0; + int wl = strlen(word); + if (wl > (MAXWORDLEN-1)) return 0; + int captype = 0; + int abbv = 0; + wl = cleanword(cw, word, &captype, &abbv); + if (wl == 0) return 0; + + int ns = 0; + char ** wlst = (char **) calloc(maxSug, sizeof(char *)); + if (wlst == NULL) return 0; + + switch(captype) { + case NOCAP: { + ns = pSMgr->suggest(wlst, ns, cw); + break; + } + + case INITCAP: { + + memcpy(wspace,cw,(wl+1)); + mkallsmall(wspace, csconv); + ns = pSMgr->suggest(wlst, ns, wspace); + if (ns > 0) { + for (int j=0; j < ns; j++) + mkinitcap(wlst[j], csconv); + } + ns = pSMgr->suggest(wlst,ns,cw); + break; + } + + case HUHCAP: { + ns = pSMgr->suggest(wlst, ns, cw); + if (ns != -1) { + memcpy(wspace,cw,(wl+1)); + mkallsmall(wspace, csconv); + ns = pSMgr->suggest(wlst, ns, wspace); + } + break; + } + + case ALLCAP: { + memcpy(wspace,cw,(wl+1)); + mkallsmall(wspace, csconv); + ns = pSMgr->suggest(wlst, ns, wspace); + if (ns > 0) { + for (int j=0; j < ns; j++) + mkallcap(wlst[j], csconv); + } + if (ns != -1) + ns = pSMgr->suggest(wlst, ns , cw); + break; + } + } + if (ns > 0) { + *slst = wlst; + return ns; + } + // try ngram approach since found nothing + if (ns == 0) { + ns = pSMgr->ngsuggest(wlst, cw, pHMgr); + if (ns) { + switch(captype) { + case NOCAP: break; + case HUHCAP: break; + case INITCAP: { + for (int j=0; j < ns; j++) + mkinitcap(wlst[j], csconv); + } + break; + + case ALLCAP: { + for (int j=0; j < ns; j++) + mkallcap(wlst[j], csconv); + } + break; + } + *slst = wlst; + return ns; + } + } + if (ns < 0) { + // we ran out of memory - we should free up as much as possible + for (int i=0;i +#include +#include +#include + +#include "suggestmgr.hxx" + +#if !defined(_MSC_VER) +using namespace std; +#endif + +extern char * mystrdup(const char *); + + +SuggestMgr::SuggestMgr(const char * tryme, int maxn, + AffixMgr * aptr) +{ + + // register affix manager and check in string of chars to + // try when building candidate suggestions + pAMgr = aptr; + ctry = mystrdup(tryme); + ctryl = 0; + if (ctry) + ctryl = strlen(ctry); + maxSug = maxn; + nosplitsugs=(0==1); + if (pAMgr) pAMgr->get_nosplitsugs(); +} + + +SuggestMgr::~SuggestMgr() +{ + pAMgr = NULL; + if (ctry) free(ctry); + ctry = NULL; + ctryl = 0; + maxSug = 0; +} + + + +// generate suggestions for a mispelled word +// pass in address of array of char * pointers + +int SuggestMgr::suggest(char** wlst, int ns, const char * word) +{ + + int nsug = ns; + + // perhaps we made chose the wrong char from a related set + if ((nsug < maxSug) && (nsug > -1)) + nsug = mapchars(wlst, word, nsug); + + // perhaps we made a typical fault of spelling + if ((nsug < maxSug) && (nsug > -1)) + nsug = replchars(wlst, word, nsug); + + // did we forget to add a char + if ((nsug < maxSug) && (nsug > -1)) + nsug = forgotchar(wlst, word, nsug); + + // did we swap the order of chars by mistake + if ((nsug < maxSug) && (nsug > -1)) + nsug = swapchar(wlst, word, nsug); + + // did we add a char that should not be there + if ((nsug < maxSug) && (nsug > -1)) + nsug = extrachar(wlst, word, nsug); + + // did we just hit the wrong key in place of a good char + if ((nsug < maxSug) && (nsug > -1)) + nsug = badchar(wlst, word, nsug); + + // perhaps we forgot to hit space and two words ran together + if (!nosplitsugs) { + if ((nsug < maxSug) && (nsug > -1)) + nsug = twowords(wlst, word, nsug); + } + return nsug; +} + + + +// suggestions for when chose the wrong char out of a related set +int SuggestMgr::mapchars(char** wlst, const char * word, int ns) +{ + int wl = strlen(word); + if (wl < 2 || ! pAMgr) return ns; + + int nummap = pAMgr->get_nummap(); + struct mapentry* maptable = pAMgr->get_maptable(); + if (maptable==NULL) return ns; + ns = map_related(word, 0, wlst, ns, maptable, nummap); + return ns; +} + + +int SuggestMgr::map_related(const char * word, int i, char** wlst, int ns, const mapentry* maptable, int nummap) +{ + char c = *(word + i); + if (c == 0) { + int cwrd = 1; + for (int m=0; m < ns; m++) + if (strcmp(word,wlst[m]) == 0) cwrd = 0; + if ((cwrd) && check(word,strlen(word))) { + if (ns < maxSug) { + wlst[ns] = mystrdup(word); + if (wlst[ns] == NULL) return -1; + ns++; + } + } + return ns; + } + int in_map = 0; + for (int j = 0; j < nummap; j++) { + if (strchr(maptable[j].set,c) != 0) { + in_map = 1; + char * newword = strdup(word); + for (int k = 0; k < maptable[j].len; k++) { + *(newword + i) = *(maptable[j].set + k); + ns = map_related(newword, (i+1), wlst, ns, maptable, nummap); + } + free(newword); + } + } + if (!in_map) { + i++; + ns = map_related(word, i, wlst, ns, maptable, nummap); + } + return ns; +} + + + +// suggestions for a typical fault of spelling, that +// differs with more, than 1 letter from the right form. +int SuggestMgr::replchars(char** wlst, const char * word, int ns) +{ + char candidate[MAXSWL]; + const char * r; + int lenr, lenp; + int cwrd; + + int wl = strlen(word); + if (wl < 2 || ! pAMgr) return ns; + + int numrep = pAMgr->get_numrep(); + struct replentry* reptable = pAMgr->get_reptable(); + if (reptable==NULL) return ns; + + for (int i=0; i < numrep; i++ ) { + r = word; + lenr = strlen(reptable[i].replacement); + lenp = strlen(reptable[i].pattern); + // search every occurence of the pattern in the word + while ((r=strstr(r, reptable[i].pattern)) != NULL) { + strcpy(candidate, word); + if (r-word + lenr + strlen(r+lenp) >= MAXSWL) break; + strcpy(candidate+(r-word),reptable[i].replacement); + strcpy(candidate+(r-word)+lenr, r+lenp); + cwrd = 1; + for (int k=0; k < ns; k++) + if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; + if ((cwrd) && check(candidate,strlen(candidate))) { + if (ns < maxSug) { + wlst[ns] = mystrdup(candidate); + if (wlst[ns] == NULL) return -1; + ns++; + } else return ns; + } + r++; // search for the next letter + } + } + return ns; +} + + +// error is wrong char in place of correct one +int SuggestMgr::badchar(char ** wlst, const char * word, int ns) +{ + char tmpc; + char candidate[MAXSWL]; + + int wl = strlen(word); + int cwrd; + strcpy (candidate, word); + + // swap out each char one by one and try all the tryme + // chars in its place to see if that makes a good word + for (int i=0; i < wl; i++) { + tmpc = candidate[i]; + for (int j=0; j < ctryl; j++) { + if (ctry[j] == tmpc) continue; + candidate[i] = ctry[j]; + cwrd = 1; + for (int k=0; k < ns; k++) + if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; + if ((cwrd) && check(candidate,wl)) { + if (ns < maxSug) { + wlst[ns] = mystrdup(candidate); + if (wlst[ns] == NULL) return -1; + ns++; + } else return ns; + } + candidate[i] = tmpc; + } + } + return ns; +} + + +// error is word has an extra letter it does not need +int SuggestMgr::extrachar(char** wlst, const char * word, int ns) +{ + char candidate[MAXSWL]; + const char * p; + char * r; + int cwrd; + + int wl = strlen(word); + if (wl < 2) return ns; + + // try omitting one char of word at a time + strcpy (candidate, word + 1); + for (p = word, r = candidate; *p != 0; ) { + cwrd = 1; + for (int k=0; k < ns; k++) + if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; + if ((cwrd) && check(candidate,wl-1)) { + if (ns < maxSug) { + wlst[ns] = mystrdup(candidate); + if (wlst[ns] == NULL) return -1; + ns++; + } else return ns; + } + *r++ = *p++; + } + return ns; +} + + +// error is mising a letter it needs +int SuggestMgr::forgotchar(char ** wlst, const char * word, int ns) +{ + char candidate[MAXSWL]; + const char * p; + char * q; + int cwrd; + + int wl = strlen(word); + + // try inserting a tryme character before every letter + strcpy(candidate + 1, word); + for (p = word, q = candidate; *p != 0; ) { + for (int i = 0; i < ctryl; i++) { + *q = ctry[i]; + cwrd = 1; + for (int k=0; k < ns; k++) + if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; + if ((cwrd) && check(candidate,wl+1)) { + if (ns < maxSug) { + wlst[ns] = mystrdup(candidate); + if (wlst[ns] == NULL) return -1; + ns++; + } else return ns; + } + } + *q++ = *p++; + } + + // now try adding one to end */ + for (int i = 0; i < ctryl; i++) { + *q = ctry[i]; + cwrd = 1; + for (int k=0; k < ns; k++) + if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; + if ((cwrd) && check(candidate,wl+1)) { + if (ns < maxSug) { + wlst[ns] = mystrdup(candidate); + if (wlst[ns] == NULL) return -1; + ns++; + } else return ns; + } + } + return ns; +} + + +/* error is should have been two words */ +int SuggestMgr::twowords(char ** wlst, const char * word, int ns) +{ + char candidate[MAXSWL]; + char * p; + + int wl=strlen(word); + if (wl < 3) return ns; + strcpy(candidate + 1, word); + + // split the string into two pieces after every char + // if both pieces are good words make them a suggestion + for (p = candidate + 1; p[1] != '\0'; p++) { + p[-1] = *p; + *p = '\0'; + if (check(candidate,strlen(candidate))) { + if (check((p+1),strlen(p+1))) { + *p = ' '; + if (ns < maxSug) { + wlst[ns] = mystrdup(candidate); + if (wlst[ns] == NULL) return -1; + ns++; + } else return ns; + } + } + } + return ns; +} + + +// error is adjacent letter were swapped +int SuggestMgr::swapchar(char ** wlst, const char * word, int ns) +{ + char candidate[MAXSWL]; + char * p; + char tmpc; + int cwrd; + + int wl = strlen(word); + + // try swapping adjacent chars one by one + strcpy(candidate, word); + for (p = candidate; p[1] != 0; p++) { + tmpc = *p; + *p = p[1]; + p[1] = tmpc; + cwrd = 1; + for (int k=0; k < ns; k++) + if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; + if ((cwrd) && check(candidate,wl)) { + if (ns < maxSug) { + wlst[ns] = mystrdup(candidate); + if (wlst[ns] == NULL) return -1; + ns++; + } else return ns; + } + tmpc = *p; + *p = p[1]; + p[1] = tmpc; + } + return ns; +} + + +// generate a set of suggestions for very poorly spelled words +int SuggestMgr::ngsuggest(char** wlst, char * word, HashMgr* pHMgr) +{ + + int i, j; + int lval; + int sc; + int lp; + + if (! pHMgr) return 0; + + // exhaustively search through all root words + // keeping track of the MAX_ROOTS most similar root words + struct hentry * roots[MAX_ROOTS]; + int scores[MAX_ROOTS]; + for (i = 0; i < MAX_ROOTS; i++) { + roots[i] = NULL; + scores[i] = -100 * i; + } + lp = MAX_ROOTS - 1; + + int n = strlen(word); + + struct hentry* hp = NULL; + int col = -1; + while ((hp = pHMgr->walk_hashtable(col, hp))) { + sc = ngram(3, word, hp->word, NGRAM_LONGER_WORSE); + if (sc > scores[lp]) { + scores[lp] = sc; + roots[lp] = hp; + int lval = sc; + for (j=0; j < MAX_ROOTS; j++) + if (scores[j] < lval) { + lp = j; + lval = scores[j]; + } + } + } + + // find minimum threshhold for a passable suggestion + // mangle original word three differnt ways + // and score them to generate a minimum acceptable score + int thresh = 0; + char * mw = NULL; + for (int sp = 1; sp < 4; sp++) { + mw = strdup(word); + for (int k=sp; k < n; k+=4) *(mw + k) = '*'; + thresh = thresh + ngram(n, word, mw, NGRAM_ANY_MISMATCH); + free(mw); + } + mw = NULL; + thresh = thresh / 3; + thresh--; + + // now expand affixes on each of these root words and + // and use length adjusted ngram scores to select + // possible suggestions + char * guess[MAX_GUESS]; + int gscore[MAX_GUESS]; + for(i=0;iexpand_rootword(glst, MAX_WORDS, rp->word, rp->wlen, + rp->astr, rp->alen); + for (int k = 0; k < nw; k++) { + sc = ngram(n, word, glst[k].word, NGRAM_ANY_MISMATCH); + if (sc > thresh) { + if (sc > gscore[lp]) { + if (guess[lp]) free (guess[lp]); + gscore[lp] = sc; + guess[lp] = glst[k].word; + lval = sc; + for (j=0; j < MAX_GUESS; j++) + if (gscore[j] < lval) { + lp = j; + lval = gscore[j]; + } + } else { + free (glst[k].word); + } + } + } + } + } + if (glst) free(glst); + + // now we are done generating guesses + // sort in order of decreasing score and copy over + + bubblesort(&guess[0], &gscore[0], MAX_GUESS); + int ns = 0; + for (i=0; i < MAX_GUESS; i++) { + if (guess[i]) { + int unique = 1; + for (j=i+1; j < MAX_GUESS; j++) + if (guess[j]) + if (!strcmp(guess[i], guess[j])) unique = 0; + if (unique) { + wlst[ns++] = guess[i]; + } else { + free(guess[i]); + } + } + } + return ns; +} + + + + +// see if a candidate suggestion is spelled correctly +// needs to check both root words and words with affixes +int SuggestMgr::check(const char * word, int len) +{ + struct hentry * rv=NULL; + if (pAMgr) { + rv = pAMgr->lookup(word); + if (rv == NULL) rv = pAMgr->affix_check(word,len); + } + if (rv) return 1; + return 0; +} + + + +// generate an n-gram score comparing s1 and s2 +int SuggestMgr::ngram(int n, char * s1, const char * s2, int uselen) +{ + int nscore = 0; + int l1 = strlen(s1); + int l2 = strlen(s2); + int ns; + for (int j=1;j<=n;j++) { + ns = 0; + for (int i=0;i<=(l1-j);i++) { + char c = *(s1 + i + j); + *(s1 + i + j) = '\0'; + if (strstr(s2,(s1+i))) ns++; + *(s1 + i + j ) = c; + } + nscore = nscore + ns; + if (ns < 2) break; + } + ns = 0; + if (uselen == NGRAM_LONGER_WORSE) ns = (l2-l1)-2; + if (uselen == NGRAM_ANY_MISMATCH) ns = abs(l2-l1)-2; + return (nscore - ((ns > 0) ? ns : 0)); +} + + +// sort in decreasing order of score +void SuggestMgr::bubblesort(char** rword, int* rsc, int n ) +{ + int m = 1; + while (m < n) { + int j = m; + while (j > 0) { + if (rsc[j-1] < rsc[j]) { + int sctmp = rsc[j-1]; + char * wdtmp = rword[j-1]; + rsc[j-1] = rsc[j]; + rword[j-1] = rword[j]; + rsc[j] = sctmp; + rword[j] = wdtmp; + j--; + } else break; + } + m++; + } + return; +} + diff --git a/goldlib/myspell/suggestmgr.hxx b/goldlib/myspell/suggestmgr.hxx new file mode 100644 index 0000000..7c5a6e2 --- /dev/null +++ b/goldlib/myspell/suggestmgr.hxx @@ -0,0 +1,48 @@ +#ifndef _SUGGESTMGR_HXX_ +#define _SUGGESTMGR_HXX_ + +#define MAXSWL 100 +#define MAX_ROOTS 10 +#define MAX_WORDS 500 +#define MAX_GUESS 10 + +#define NGRAM_IGNORE_LENGTH 0 +#define NGRAM_LONGER_WORSE 1 +#define NGRAM_ANY_MISMATCH 2 + + +#include "atypes.hxx" +#include "affixmgr.hxx" +#include "hashmgr.hxx" + +class SuggestMgr +{ + char * ctry; + int ctryl; + AffixMgr* pAMgr; + int maxSug; + bool nosplitsugs; + +public: + SuggestMgr(const char * tryme, int maxn, AffixMgr *aptr); + ~SuggestMgr(); + + int suggest(char** wlst, int ns, const char * word); + int check(const char *, int); + int ngsuggest(char ** wlst, char * word, HashMgr* pHMgr); + +private: + int replchars(char**, const char *, int); + int mapchars(char**, const char *, int); + int map_related(const char *, int, char ** wlst, int, const mapentry*, int); + int forgotchar(char **, const char *, int); + int swapchar(char **, const char *, int); + int extrachar(char **, const char *, int); + int badchar(char **, const char *, int); + int twowords(char **, const char *, int); + int ngram(int n, char * s1, const char * s2, int uselen); + void bubblesort( char ** rwd, int * rsc, int n); +}; + +#endif +