antoine-source/appleworksgs/Spell/Src/UNFEXC.C
2023-03-04 03:45:20 +01:00

1 line
7.5 KiB
C
Executable File

/***********************************************************************\
Filename: unfexc.c
\***********************************************************************/
#include <proxio.h>
#include "thesmisc.h"
#include "th.h"
#define GETNIB() ((nb = ~nb) ? (bt = ctoi(*pdptr++)) >> 4 : bt & 0x0F)
#define PXHEADER 8
static unfbin();
/* structure to handle the inflection exceptions processing */
static struct
{
int px_rev;
int px_nlet;
int px_wbin;
int px_wlbin;
int px_nbin;
int px_nwords;
int px_nbytes;
int px_dummy;
int *px_bintab;
char *px_lettab;
char *px_data;
} Pxinfo;
unfopen(ioptr)
HANDLE ioptr;
{
char *zalloc();
long thesbit();
int i;
char *strptr;
int *pxptr;
int offset;
char str[sizeof(unsigned) * PXHEADER];
i = PXHEADER * sizeof(int);
strptr = str;
offset = i;
while (--i >= 0)
*strptr++ = thesbit(ioptr, 8);
thintmv(str, (int *) &Pxinfo, PXHEADER);
if ((Pxinfo.px_lettab = zalloc(_THID, (unsigned) Pxinfo.px_nlet)) == NULL
|| (Pxinfo.px_data = (char *) zalloc(_THID, (unsigned) Pxinfo.px_nbytes))
== NULL || (Pxinfo.px_bintab = (int *) zalloc(_THID,
(unsigned) Pxinfo.px_nbin * sizeof(int))) == NULL)
return (FALSE);
strptr = (char *) Pxinfo.px_lettab;
i = Pxinfo.px_nlet;
offset += i;
while (--i >= 0)
*strptr++ = thesbit(ioptr, 8);
offset += (i = Pxinfo.px_nbin) * sizeof(int);
pxptr = Pxinfo.px_bintab;
while (--i >= 0)
{
*pxptr = thesbit(ioptr, 8);
*pxptr |= thesbit(ioptr, 8) << 8;
++pxptr;
}
i = Pxinfo.px_nbytes;
strptr = Pxinfo.px_data;
offset += i;
while (--i >= 0)
*strptr++ = thesbit(ioptr, 8);
return (offset);
}
unfclose()
{
nzfree((char *)Pxinfo.px_data);
nzfree((char *)Pxinfo.px_bintab);
nzfree((char *)Pxinfo.px_lettab);
}
unfexc(word, excword, inftype)
char *word;
char *excword;
int inftype;
{
int nb; /* flag set when nibble-getter needs a byte.*/
int c; /* index into px_lettab[] (see environ.h) */
char *pdptr;
char *strptr; /* pointer to end of decompressed word */
char *saveptr; /* pointer to end of decompressed word */
int bt; /* latest byte read from corelex array */
int chind; /* index into px_lettab[] (see environ.h) */
int cmp;
int bs;
int bin;
int binwords;
int refcnt;
int refindex;
int refind;
int refeof;
int reftype;
int skip;
int retval;
int refiarr[MAXREF];
int reftarr[MAXREF];
char clword[MAXWORD]; /* holds word during decompression */
bin = unfbin(word);
binwords = bin < Pxinfo.px_nbin - 1 ? Pxinfo.px_wbin : Pxinfo.px_wlbin;
pdptr = Pxinfo.px_data + Pxinfo.px_bintab[bin];
strptr = clword + 1;
retval = nb = FALSE;
/* decompress until the word is found. If the decompressed word
is greater than word or if at the end of the bin return ERROR */
do
{
if (!binwords--)
return (ERROR);
bs = GETNIB() + 1;
strptr -= bs;
do
{
chind = 0;
while ((c = GETNIB()) == 0xF)
chind += 0xF;
chind += c;
}
while (*strptr++ = Pxinfo.px_lettab[chind]);
refcnt = 0;
if ((cmp = strcmp(clword, word)) > 0)
return (ERROR);
do
{
refindex = GETNIB();
refeof = refindex & 0x8;
if (cmp == 0)
{
refindex = ((refindex & 0x7) << 4) + GETNIB();
refindex = (refindex << 4) + GETNIB();
reftype = GETNIB();
reftype = ((reftype & 0x7) << 4) + GETNIB();
refiarr[refcnt] = refindex;
reftarr[refcnt++] = reftype;
}
else
{
GETNIB();
GETNIB();
GETNIB();
GETNIB();
}
}
while (!refeof);
}
while (cmp);
strptr = excword + 1;
for (refind = 0; refind < refcnt; refind++)
{
refindex = refind;
skip = FALSE;
/* If inftype is UNF_IR retain only unflection entries.
If a certain type of inflection is specified, discard
elements in reftarr that do not match inftype. */
if ((inftype == UNF_IR && reftarr[refindex] & 1)
|| (inftype != UNF_IR && reftarr[refindex] != inftype))
continue;
if (retval != 0 && retval != reftarr[refindex])
break;
if ((retval = reftarr[refindex]) <= 0)
return (retval);
saveptr = strptr;
bin = refiarr[refindex] / Pxinfo.px_wbin;
binwords = refiarr[refindex] % Pxinfo.px_wbin + 1;
pdptr = Pxinfo.px_data + Pxinfo.px_bintab[bin];
nb = FALSE;
while (binwords--)
{
bs = GETNIB() + 1;
strptr -= bs;
do
{
chind = 0;
while ((c = GETNIB()) == 0xF)
chind += 0xF;
chind += c;
}
while (*strptr++ = Pxinfo.px_lettab[chind]);
do
{
refindex = GETNIB();
refeof = refindex & 0x8;
GETNIB();
GETNIB();
GETNIB();
GETNIB();
}
while (!refeof);
}
/* Take care of multiple unflections. */
if (!skip)
{
*(strptr - 1) = UNFSEP;
*strptr++ = '\0';
}
else
strptr = saveptr;
}
if (strptr == &excword[1])
return (ERROR);
*(strptr - 2) = '\0';
return (retval);
}
static unfbin(word0)
char *word0;
{
char *word; /* actual word scanner */
char *pdptr; /* pointer into Pxinfo.px_data[] */
int bt; /* holds a byte read from px_data */
int bin; /* number of bin to be compared with input word */
int nb; /* nibble-getter flag */
int frindex; /* index into px_lettab[] for actual character */
int curindex; /* temporary index for processing hex-F sequences */
int minval;
int maxval;
minval = 0;
maxval = Pxinfo.px_nbin - 1;
while (minval < maxval)
{
bin = (minval + maxval + 1) / 2;
/* px_bintab[bin] is byte offset into corelex array
(px_data[]) of start of next bin to be checked. */
pdptr = Pxinfo.px_data + Pxinfo.px_bintab[bin];
/* Decompress the first word in the bin, comparing it with
the input word to see if the input word is in the bin. */
nb = FALSE;
/* get the backspace */
while ((curindex = GETNIB()) == 0xF)
;
word = word0 - 1;
do
{
/* read nibbles to form the character index; */
/* as in coreword(), sequence of hex-F's */
/* can be arbitrarily long */
frindex = curindex = GETNIB();
while (curindex == 0x0F)
{
curindex = GETNIB();
frindex += curindex;
}
if (*++word != Pxinfo.px_lettab[frindex])
break;
}
while (*word);
/* update the binary search limits; test depends on */
/* string terminator ('\0') being the character with the */
/* smallest value */
if (ctoi(*word) >= ctoi(Pxinfo.px_lettab[frindex]))
minval = bin;
else
maxval = bin - 1;
}
return (maxval);
}