mirror of
https://github.com/antoinevignau/source.git
synced 2024-10-31 22:06:40 +00:00
1 line
7.5 KiB
C
Executable File
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);
|
|
}
|