leo@s514.ipmce.su (Leonid A. Broukhis) (03/25/91)
Submitted-by: Leonid A. Broukhis <leo@s514.ipmce.su> Posting-number: Volume 17, Issue 68 Archive-name: freeze/part02 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: Contents debug.c decode.c default.c freeze.h huf.h lz.c # lz.h makefile # Wrapped by kent@sparky on Sun Mar 24 20:41:08 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive 2 (of 2)."' if test -f 'Contents' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Contents'\" else echo shar: Extracting \"'Contents'\" \(706 characters\) sed "s/^X//" >'Contents' <<'END_OF_FILE' X This package contalns: X-rw------- 1 6234 Mar 21 21:44 README X-rw------- 1 1650 Mar 20 12:49 bitio.c X-rw------- 1 1567 Mar 20 12:49 debug.c X-rw------- 1 1023 Mar 20 12:50 decode.c X-rw-rw-r-- 1 1155 Mar 20 12:49 default.c X-rw------- 1 3800 Mar 20 13:02 encode.c X-rw-r--r-- 1 5973 Mar 21 21:56 freeze.1 X-rw------- 1 16740 Mar 21 21:56 freeze.c X-rw------- 1 2495 Mar 20 12:49 freeze.h X-rw------- 1 8291 Mar 20 12:58 huf.c X-rw------- 1 201 Mar 20 12:50 huf.h X-rw------- 1 2451 Mar 20 12:49 lz.c X-rw------- 1 1547 Mar 20 12:50 lz.h X-rw-rw-r-- 1 1248 Mar 20 12:50 makefile X-rw------- 1 4475 Mar 20 12:50 statist.c XTotal: 15 files. END_OF_FILE if test 706 -ne `wc -c <'Contents'`; then echo shar: \"'Contents'\" unpacked with wrong size! fi # end of 'Contents' fi if test -f 'debug.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'debug.c'\" else echo shar: Extracting \"'debug.c'\" \(1567 characters\) sed "s/^X//" >'debug.c' <<'END_OF_FILE' X#ifdef DEBUG X#include "freeze.h" X X /*---------------------------*/ X /* DEBUG MODULE */ X /*---------------------------*/ X Xprintcodes() X{ X /* X * Just print out codes from input file. For debugging. X */ X register short k, c, col = 0; X#ifdef COMPAT X if(new_flg) X#endif X if(read_header() == EOF) { X fprintf(stderr, "Bad header\n"); X return; X } X StartHuff(); X for (;;) { X#ifdef COMPAT X c = new_flg ? DecodeChar() : DecodeCOld(); X#else X c = DecodeChar(); X#endif X if (c == ENDOF) X break; X if (c < 256) { X fprintf(stderr, "%5d%c", c, X (col+=8) >= 74 ? (col = 0, '\n') : '\t' ); X } else { X c = c - 256 + THRESHOLD; X#ifdef COMPAT X k = new_flg ? DecodePosition() : DecodePOld(); X#else X k = DecodePosition(); X#endif X fprintf(stderr, "%2d-%d%c", c, k, X (col+=8) >= 74 ? (col = 0, '\n') : '\t' ); X } X } X putc( '\n', stderr ); X exit( 0 ); X} X X/* for pretty char printing */ X Xchar * Xpr_char(c) X register uchar c; X{ X static char buf[5]; X register i = 4; X buf[4] = '\0'; X if ( (isascii((int)c) && isprint((int)c) && c != '\\') || c == ' ' ) { X buf[--i] = c; X } else { X switch( c ) { X case '\n': buf[--i] = 'n'; break; X case '\t': buf[--i] = 't'; break; X case '\b': buf[--i] = 'b'; break; X case '\f': buf[--i] = 'f'; break; X case '\r': buf[--i] = 'r'; break; X case '\\': buf[--i] = '\\'; break; X default: X buf[--i] = '0' + c % 8; X buf[--i] = '0' + (c / 8) % 8; X buf[--i] = '0' + c / 64; X break; X } X buf[--i] = '\\'; X } X return &buf[i]; X} X#endif END_OF_FILE if test 1567 -ne `wc -c <'debug.c'`; then echo shar: \"'debug.c'\" unpacked with wrong size! fi # end of 'debug.c' fi if test -f 'decode.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'decode.c'\" else echo shar: Extracting \"'decode.c'\" \(1023 characters\) sed "s/^X//" >'decode.c' <<'END_OF_FILE' X#include "freeze.h" X X/* X * Melt stdin to stdout. X */ X Xmelt () X{ X register short i, j, k, n, r, c; X#ifdef COMPAT X if(new_flg) X#endif X if(read_header() == EOF) X return; X X StartHuff(); X n = N; X for (i = 0; i < n - F; i++) X text_buf[i] = ' '; X r = n - F; X n --; /* array size --> mask */ X for (in_count = 0;; ) { X c = X#ifdef COMPAT X new_flg ? DecodeChar() : DecodeCOld(); X#else X DecodeChar(); X#endif X if (c == ENDOF) X break; X if (c < 256) { X putchar (c); X text_buf[r++] = c; X r &= n; X in_count++; X } else { X i = (r - X#ifdef COMPAT X (new_flg ? DecodePosition() : DecodePOld()) X#else X DecodePosition() X#endif X - 1) & n; X j = c - 256 + THRESHOLD; X for (k = 0; k < j; k++) { X c = text_buf[(i + k) & n]; X putchar (c); X text_buf[r++] = c; X r &= n; X in_count++; X } X } X X if (!quiet && (in_count > indicator_count)) { X fprintf(stderr, "%5dK\b\b\b\b\b\b", in_count / 1024); X fflush (stderr); X indicator_count += indicator_threshold; X indicator_threshold += 1024; X } X } X} END_OF_FILE if test 1023 -ne `wc -c <'decode.c'`; then echo shar: \"'decode.c'\" unpacked with wrong size! fi # end of 'decode.c' fi if test -f 'default.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'default.c'\" else echo shar: Extracting \"'default.c'\" \(1155 characters\) sed "s/^X//" >'default.c' <<'END_OF_FILE' X#include <stdio.h> X X#define OK 0 X#define FAIL NULL X#define NOFILE ((FILE *) 0) X#define MAXLINE 128 X Xextern int errno; Xchar *strchr(); Xstatic FILE *defd = NOFILE; /* defaults file stream */ X Xint defopen(fname) /* open | reopen | close defaults file */ X char *fname; X{ X register FILE *fd; X X if (!fname) { X if (defd) X fclose(defd); X defd = NOFILE; X return OK; X } X X if (!(fd = fopen(fname, "r"))) X return errno; /* problems opening file */ X X defd = fd; X return OK; X} X Xstatic char defline[MAXLINE + 1]; X Xchar *defread(pattern) X register char *pattern; X{ X register sz_patt; X register char *cp; X X if (!defd) X return FAIL; /* defaults file not opened */ X X rewind(defd); X sz_patt = strlen(pattern); X X while (fgets(defline, MAXLINE, defd)) { X if (!(cp = strchr(defline, '\n'))) X return FAIL; /* line too long */ X if (cp - defline < sz_patt) X continue; /* line too short */ X *cp = '\0'; X if (!strncmp(pattern, defline, sz_patt)) X return defline + sz_patt; /* match found */ X } X X return FAIL; /* no matching lines */ X} END_OF_FILE if test 1155 -ne `wc -c <'default.c'`; then echo shar: \"'default.c'\" unpacked with wrong size! fi # end of 'default.c' fi if test -f 'freeze.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'freeze.h'\" else echo shar: Extracting \"'freeze.h'\" \(2495 characters\) sed "s/^X//" >'freeze.h' <<'END_OF_FILE' X X#include <stdio.h> X X/* for GCC */ X X#ifdef SUN4 X#include <sys/stdtypes.h> X#else X typedef int mode_t; /* for GCC */ X# ifndef getc X# define getc(p) (--(p)->_cnt < 0 ? _filbuf(p) : (int) *(p)->_ptr++) X# endif X# ifndef putc X# define putc(x, p) (--(p)->_cnt < 0 ? _flsbuf((unsigned char) (x), (p)) : (int) (*(p)->_ptr++ = (unsigned char) (x))) X# endif X typedef unsigned short u_short; X#endif X X/* end (for GCC) */ X X#include <ctype.h> X#include <signal.h> X#include <sys/types.h> X#include <sys/stat.h> X X#ifdef DEBUG X#include <assert.h> X#endif X X#ifdef __TURBOC__ X#define MSDOS X#include <io.h> X#endif X X#ifdef MSDOS X#include <stdlib.h> X#endif X Xtypedef unsigned char uchar; X X#if defined(BITS) && BITS > 14 Xtypedef unsigned long hash_t; X#else Xtypedef u_short hash_t; X#endif X X#ifdef lint X#define N 256 X#else X#define N 8192 /* buffer size */ X#endif X X#define F 256 /* pre-sence buffer size */ X#define THRESHOLD 2 X X#define _NCHAR (256 - THRESHOLD + _F + 1) /* {code : 0 .. N_CHAR-1} */ X X#define _T (_NCHAR * 2 - 1) /* size of table */ X#define _R (_T - 1) /* root position */ X#define _NN 8092 X#define _F 256 X X#ifndef COMPAT X#define N_CHAR _NCHAR X#define T _T X#define R _R X#else X#define _FO 60 X#define _NO 4096 X#define _NCHARO (256 - THRESHOLD + _FO + 1) X#define _TO (_NCHARO * 2 - 1) X#define _RO (_TO - 1) X#define N_CHAR (new_flg ? _NCHAR : _NCHARO) X#define T (new_flg ? _T : _TO) X#define R (new_flg ? _R : _RO) X#endif X X#define ENDOF 256 X Xextern uchar Table[]; X Xextern long in_count, bytes_out; X Xextern uchar text_buf[]; Xextern u_short match_position, match_length; X Xextern short quiet; X X/* Note indicator_threshold is triangle number of Kbytes */ X Xextern unsigned long indicator_threshold, indicator_count; X Xextern short do_melt, topipe; X Xextern uchar magic_header[]; X Xextern int exit_stat; X Xextern short new_flg; X X#ifdef DEBUG Xextern short debug; Xextern short verbose; Xextern char * pr_char(); Xextern long symbols_out, refers_out; X#endif /* DEBUG */ X X#ifdef GATHER_STAT Xextern long node_steps, node_matches; X#endif X Xextern short DecodeChar(), DecodePosition(), X GetByte(), GetNBits(); X X#ifdef COMPAT Xextern short DecodeCOld(), DecodePOld(); X#endif X X#if defined(BSD42) && !defined(BSD4_2) X#define BSD4_2 X#endif END_OF_FILE if test 2495 -ne `wc -c <'freeze.h'`; then echo shar: \"'freeze.h'\" unpacked with wrong size! fi # end of 'freeze.h' fi if test -f 'huf.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'huf.h'\" else echo shar: Extracting \"'huf.h'\" \(201 characters\) sed "s/^X//" >'huf.h' <<'END_OF_FILE' Xextern u_short getbuf; Xextern uchar getlen; X Xextern uchar corrupt_flag; X Xextern u_short putbuf; Xextern uchar putlen; X X#define MAX_FREQ (u_short)0x8000 /* tree update timing from frequency */ END_OF_FILE if test 201 -ne `wc -c <'huf.h'`; then echo shar: \"'huf.h'\" unpacked with wrong size! fi # end of 'huf.h' fi if test -f 'lz.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'lz.c'\" else echo shar: Extracting \"'lz.c'\" \(2451 characters\) sed "s/^X//" >'lz.c' <<'END_OF_FILE' X#include "freeze.h" X#include "lz.h" X X/*----------------------------------------------------------------------*/ X/* */ X/* LZSS ENCODING */ X/* */ X/*----------------------------------------------------------------------*/ X X#define NIL N /* term of tree */ X Xuchar text_buf[N + _F - 1]; Xu_short match_position, match_length; X X/* next[N+1..] is used as hash table, X the rest of next is a link down, X prev is a link up. X*/ X Xhash_t prev[N + 1]; X#ifndef __XENIX__ Xu_short next[array_size]; X#else X#if parts == 2 Xu_short next0[32768], next1[8193]; X#elif parts == 3 Xu_short next0[32768], next1[32768], next2[8193]; X#elif parts == 5 Xu_short next0[32768], next1[32768], next2[32768], next3[32768], next4[8193]; X#else Xu_short next0[32768], next1[32768], next2[32768], next3[32768], next4[32768], X next5[32768], next6[32768], next7[32768], next8[8193]; X#endif X Xu_short *next[parts] = { Xnext0, next1 X#if parts > 2 X,next2 X#if parts > 3 X,next3, next4 X#if parts > 5 X,next5, next6, Xnext7, next8 X#endif X#endif X#endif X}; X#endif X X X#ifdef GATHER_STAT Xlong node_steps, node_matches; X#endif X X/* Initialize Tree */ XInitTree () X{ X long i; X#ifdef GATHER_STAT X node_steps = node_matches = 0; X#endif X X for (i = N + 1; i < array_size; i++ ) X nextof(i) = NIL; X for (i = 0; i < sizeof(prev)/sizeof(*prev); i++ ) X prev[i] = NIL; X} X X/* Get next match */ XGet_Next_Match (r) X u_short r; X{ X register uchar *key; X register u_short m, i, p; X#ifdef GATHER_STAT X node_matches++; X#endif X key = &text_buf[p = r]; X m = 0; X while (m < _F) { X if ((p = nextof(p)) == NIL) { X match_length = m; X return; X } X X/* This statement is due to ideas of Boyer and Moore: */ X X if(key[m] != text_buf[p + m]) X continue; X X/* This statement is due to my ideas: :-) */ X/* It gives up to 8% speedup on files with big redundancy (text, etc.) */ X X if(key[m >> 1] != text_buf[p + (m >> 1)]) X continue; X X#ifdef GATHER_STAT X node_steps++; X#endif X X/* This statement doesn't take a lot of execution time - X about 20% (in profiling we trust) X*/ X for (i = 0; i < _F && key[i] == text_buf[p + i]; i++); X X if (i > m) { X match_position = ((r - p) & (N - 1)) - 1; X m = i; X } X } X#ifdef DEBUG X if (verbose) X fprintf(stderr, "Replacing node: %d -> %d\n", p, r); X#endif X nextof(prev[p]) = nextof(p); X prev[nextof(p)] = prev[p]; X prev[p] = NIL; /* remove p, it is further than r */ X match_length = _F; X} END_OF_FILE if test 2451 -ne `wc -c <'lz.c'`; then echo shar: \"'lz.c'\" unpacked with wrong size! fi # end of 'lz.c' fi if test -f 'lz.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'lz.h'\" else echo shar: Extracting \"'lz.h'\" \(1547 characters\) sed "s/^X//" >'lz.h' <<'END_OF_FILE' X#ifndef BITS X#define BITS 14 /* for 16-bits machines */ X#endif X X#if BITS < 13 X#undef BITS X#define BITS 13 /* 1:1 hash */ X#endif X X#if BITS > 21 X#undef BITS X#define BITS 21 /* 4 MB hash table, if sizeof(u_short) == 2 */ X#endif X X#define LEN0 (BITS/3 + (BITS%3 != 0)) X#define LEN1 (BITS/3 + (BITS%3 == 2)) X#define LEN2 (BITS/3) X X#define MASK0 ((1 << LEN0) - 1) X#define MASK1 ((1 << LEN1) - 1) X#define MASK2 ((1 << LEN2) - 1) X X#define NIL N X X#if defined(M_XENIX) && defined(I_286) && (BITS > 14) X#define __XENIX__ X#if BITS > 18 X#undef BITS X#define BITS 18 X#endif X#endif X X#define array_size (N + 1 + (1 << BITS)) X X#ifndef __XENIX__ X#define nextof(i) next[i] X#else X#define parts (array_size/32768 + 1) X#define nextof(i) next[(i) >> 15][(i) & 0x7fff] X#endif X X/* To eliminate function-call overhead */ X X#define DeleteNode(n) \ X{\ X nextof(prev[n]) = NIL;\ X prev[n] = NIL;\ X} X X#define InsertNode(r)\ X{\ X register hash_t p, first_son;\ X register uchar *key;\ X key = &text_buf[r];\ X p = N + 1 + (key[0] & MASK0) |\ X ((key[1] & MASK1) << LEN0) |\ X ((key[2] & MASK2) << (LEN0 + LEN1));\ X first_son = nextof(p);\ X nextof(r) = first_son;\ X nextof(p) = r;\ X prev[r] = p;\ X prev[first_son] = r;\ X} X X#define Next_Char()\ Xif ((c = getchar()) != EOF) {\ X text_buf[s] = c;\ X if (s < _F - 1)\ X text_buf[s + N] = c;\ X s = (s + 1) & (N - 1);\ X r = (r + 1) & (N - 1);\ X InsertNode(r);\ X in_count++;\ X} else {\ X s = (s + 1) & (N - 1);\ X r = (r + 1) & (N - 1);\ X if (--len) InsertNode(r);\ X} END_OF_FILE if test 1547 -ne `wc -c <'lz.h'`; then echo shar: \"'lz.h'\" unpacked with wrong size! fi # end of 'lz.h' fi if test -f 'makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile'\" else echo shar: Extracting \"'makefile'\" \(1248 characters\) sed "s/^X//" >'makefile' <<'END_OF_FILE' XDEST = /usr/local/bin XEXTHDRS = XHDRS = freeze.h\ X lz.h\ X huf.h XLDFLAGS = XLIBS = -lc_s # shared library X XCC = gcc X XCFLAGS = -DBITS=18 -O -DCOMPAT #-DBSD42 -DSUN4 X XLINTFLAGS = -DBITS=15 -DCOMPAT -DDEBUG -DGATHER_STAT X XMAKEFILE = makefile X XOBJS = bitio.o\ X debug.o\ X decode.o\ X encode.o\ X default.o\ X freeze.o\ X huf.o\ X lz.o X XPROGRAM = freeze X XSRCS = bitio.c\ X debug.c\ X decode.c\ X default.c\ X encode.c\ X freeze.c\ X huf.c\ X lz.c X Xall: $(PROGRAM) statist freeze.man X Xlint: $(SRCS) X lint $(LINTFLAGS) $(SRCS) $(LIBS) X X$(PROGRAM): $(OBJS) X $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) X Xstatist: statist.c freeze.h lz.h huf.h X $(CC) $(CFLAGS) -UCOMPAT $(LDFLAGS) -o statist statist.c $(LIBS) X Xclean:; rm -f *.o *.b .,* core a.out $(PROGRAM) statist X Xinstall: $(PROGRAM) X install -s -c $(PROGRAM) $(DEST) X ln -f $(DEST)/freeze $(DEST)/melt X ln -f $(DEST)/freeze $(DEST)/fcat X Xfreeze.man: freeze.1 X nroff -man < freeze.1 > freeze.man X X### Xbitio.o: freeze.h huf.h Xdebug.o: freeze.h Xdecode.o: freeze.h Xencode.o: freeze.h lz.h Xfreeze.o: freeze.h lz.h huf.h Xhuf.o: freeze.h huf.h Xlz.o: freeze.h END_OF_FILE if test 1248 -ne `wc -c <'makefile'`; then echo shar: \"'makefile'\" unpacked with wrong size! fi # end of 'makefile' fi echo shar: End of archive 2 \(of 2\). cp /dev/null ark2isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still must unpack the following archives: echo " " ${MISSING} fi exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.