mirror of
https://github.com/antoinevignau/source.git
synced 2024-08-11 15:28:58 +00:00
1 line
21 KiB
C++
1 line
21 KiB
C++
|
/***********************************************************************\
Filename: clam.c
\***********************************************************************/
#include <memory.h>
#include <intmath.h>
#include "string.h"
#include "language.h"
#include "spmemory.h"
#include "clam.h"
#include "environ.h"
#include "sp.h"
#include "spdef.h"
#include <prodos.h>
unsigned clamfree();
static int clfetch();
static int clbinret();
/* storage structure for one word in a CLAM */
typedef struct
{
short ib_info; /* flags, or "block to descend to" */
char ib_bs; /* backspace of word from last word */
char ib_delta[1]; /* delta of word */
} INFOBSD;
#define ib(x) ((INFOBSD *)(x))
/* block information structure, at top of every block */
typedef struct
{
short st_nextb; /* index of next block on this level */
short st_used; /* bytes occupied by BLKSTATS and INFOBSDs */
} BLKSTATS;
#define bs(x) ((BLKSTATS *)(x))
char Cldecomp[LONGWORD+2]; /* The CLAM decompression buffer. */
static int Clinfo; /* The info for the CLAM word. */
static int Clused; /* The amount of space in the block. */
static char *Clwsave; /* The start of the current word. */
static char Clbin[3]; /* The bin characters */
#define Curclam ((CLAM *)Sccurlist) /* The current CLAM. */
#define CL_DATABIT 0x8000 /* bit for a data block. */
#define CL_NOBLK (-1) /* "no next block" indicator */
#define MAXDEPTH 6 /* maximum CLAM depth */
/* Read a block from the CLAM. */
static int clblock(block, flags)
int block; /* The block number to read. */
int flags;
{
extern char *memread();
register CLAM *cp = Curclam;
/* Read the block. */
if ((cp->cl_blk0 = memread(block, cp->cl_file, flags +
(block ? MM_PR1 : MM_PR0))) == NULL)
{
Scerror = ERR_CLAM | ERR_IO;
return (FALSE);
}
/* Initialize the decompression variables. */
Clused = bs(cp->cl_blk0)->st_used & (CL_DATABIT - 1);
cp->cl_blkptr = cp->cl_blk0 + sizeof(BLKSTATS);
Scendptr = Cldecomp;
return (TRUE);
}
/* Decompress the next word from a CLAM block. */
static int clgetword()
{
register char *ptr;
register char *dest;
register CLAM *cp = Curclam;
char *ptr0;
ptr = cp->cl_blkptr;
Clwsave = ptr;
/* If at end, set Clinfo to zero so clfindbin() will go to the
next. */
if (ptr - cp->cl_blk0 >= Clused)
{
Clinfo = 0;
return (FALSE);
}
Clinfo = ib(ptr)->ib_info;
dest = Scendptr - ib(ptr)->ib_bs;
ptr0 = ptr = ib(ptr)->ib_delta;
while (*dest++ = *ptr++)
;
Scendptr = dest - 1;
if (((ptr - ptr0) & 1) == 0) {
++ptr;
}
cp->cl_blkptr = ptr;
return (TRUE);
}
/* Advance the CLAM to the next word with non-zero flags. */
static int cladvance()
{
while (1) {
/* Decompress one word. */
while (clgetword()) {
if (Clinfo) {
return (TRUE);
}
}
/* Link to the next block. */
if (Sccurblk == 0 || (Sccurblk = bs(Curclam->cl_blk0)->st_nextb)
== CL_NOBLK)
return (FALSE);
/* And read it. */
if (!clblock(Sccurblk, MM_READ))
return (FALSE);
}
}
/* Return non-zero if the current block is a data block. */
static int clisdata()
{
return (bs(Curclam->cl_blk0)->st_used & CL_DATABIT);
}
/* Encode a word for CLAM lookup. */
static int clencode(word, peword)
char *word; /* The word to encode */
char *peword; /* The encoded word */
{
extern VOID phfull();
/* Check the word length. */
if (!word[0] || strlen((char *) word) >= LONGWORD)
{
Scerror = ERR_CLAM | ERR_WLEN;
return (FALSE);
}
/* Phoneticallly encode the word. */
phfull(word, peword, FALSE);
return (TRUE);
}
/* Form an INFOBSD out of the arguments and write it to ibptr. */
static char *
makeib(ibptr,
|