home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / freeze / part01 < prev    next >
Encoding:
Text File  |  1993-02-21  |  52.7 KB  |  1,989 lines

  1. Newsgroups: comp.sources.misc
  2. From: leo@ipmce.su (Leonid A. Broukhis)
  3. Subject: v35i077:  freeze - Freeze/melt compression program, v2.5, Part01/03
  4. Message-ID: <csm-v35i077=freeze.215559@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 02948a0b5b7b526e6eadef71a02aa5b8
  6. Date: Mon, 22 Feb 1993 03:56:44 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: leo@ipmce.su (Leonid A. Broukhis)
  10. Posting-number: Volume 35, Issue 77
  11. Archive-name: freeze/part01
  12. Environment: ISC, Xenix, SunOS, MS-DOS
  13. Supersedes: freeze: Volume 25, Issue 12-13
  14.  
  15. This is version 2.5 of the Freeze/melt compression program. 
  16. The speed of melting was somewhat increased. 
  17.  
  18. Notes:
  19.  - to 64-bits architectures users: please test this version
  20. thoroughly before installing it;
  21.  
  22.  - to Borland (Turbo) C users: compile with -mc -Ff options
  23. or define TINY in config.h (prototype in config.tur).
  24.  
  25. Leonid A. Broukhis
  26. ---------------------
  27. #! /bin/sh
  28. # This is a shell archive.  Remove anything before this line, then feed it
  29. # into a shell via "sh file" or similar.  To overwrite existing files,
  30. # type "sh file -c".
  31. # Contents:  README MANIFEST configure freeze.c lz.c
  32. # Wrapped by kent@sparky on Sat Feb 20 22:49:55 1993
  33. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  34. echo If this archive is complete, you will see the following message:
  35. echo '          "shar: End of archive 1 (of 3)."'
  36. if test -f 'README' -a "${1}" != "-c" ; then 
  37.   echo shar: Will not clobber existing file \"'README'\"
  38. else
  39.   echo shar: Extracting \"'README'\" \(7052 characters\)
  40.   sed "s/^X//" >'README' <<'END_OF_FILE'
  41. X        FREEZE / MELT COMPRESSION PROGRAM
  42. X
  43. XThis version is tested under SunOS 4.1.2, Xenix 2.3.2, MS-DOS.
  44. X
  45. XThe following preprocessor symbols control the compilation of Freeze
  46. Xpackage (these can be added by hand into config.h after running ./configure):
  47. X
  48. X    o COMPAT                Turns on backwards compatibility
  49. X                with Freeze 1.0 (have you ever heard
  50. X                about it? :-) )
  51. X    o FASTHASH              Uses another hash function which gives
  52. X                some speedup, thus reducing the compression
  53. X                rate (!)
  54. X    o TEXT_DEFAULT          (For MS-DOS only!) Define, if you
  55. X                freeze text files more often than binary
  56. X                ones. In this case don't forget to use "-i"
  57. X                to freeze binary files!!
  58. X    o TINY                  For segmented architectures -
  59. X                allows to build freeze in small model
  60. X                (data segment is less than 64K).
  61. X    o SMALL                 Decreases the amount of memory
  62. X                but without 64K restriction
  63. X
  64. X    o DEFFILE               Full name of the file with freeze's
  65. X                Huffman values; it is the only
  66. X                symbol defined in the Makefile
  67. X                to allow correlation with installation place.
  68. X
  69. XOther preprocessor symbols (DEBUG, GATHER_STAT) are for internal use
  70. Xonly.
  71. X
  72. XThe format of frozen (2.X) file is incompatible with that of frozen (1.0),
  73. Xbut if this package is compiled with -DCOMPAT switch, you will able to
  74. Xunpack frozen (1.0) files, if you have them.
  75. X
  76. X------------------- COMPILING -----------------------
  77. X
  78. XType "./configure", or "sh configure". If it runs successfully,
  79. Xyou will see messages "creating config.h" and "creating Makefile".
  80. XYou should check them and probably you may have to make some corrections.
  81. XAfter that simply type "make".
  82. X
  83. X------------------- LINT ----------------------------
  84. X
  85. XSome lint's complaints about `used/declared inconsistently' are (in my
  86. Xcase) due to inconsistencies of /usr/include/* and /usr/lib/llib*ln. It
  87. Xisn't dangerous.
  88. X
  89. X------------------- BUGS ----------------------------
  90. X
  91. XPlease send descriptions of found bugs, incompatibilities, etc.  to
  92. Xleo@ipmce.su.
  93. X
  94. X------------ SPEED & COMPRESSION RATE ---------------
  95. X
  96. XCompression rate depends somewhat of the hash table size and may vary
  97. Xwith different static Huffman tables.
  98. X
  99. XNote: if you see 16-bits Compress works nearly as Freeze (on some big files),
  100. Xthis means the maximum is gained, so LHA and ARJ won't do their job better
  101. Xby more than 1-1.5%. There are some files (I have one) that freeze compresses
  102. Xbetter than ARJ 2.20.
  103. X
  104. XPlease! If your computer supports the string operations, try to write
  105. X"asm" instructions (GNU style) which realize the memory comparison
  106. X"(s1, s2, maxlength) --> matched length" in the minimum number of clock
  107. Xcycles.  If a noticeable (5% or more) speedup is gained, please send
  108. Xme a message.
  109. X
  110. X--------------- POSSIBLE IMPROVEMENTS ---------------
  111. X
  112. XThe high-level routines (freeze, melt) are almost independent from
  113. Xlow-level routines (Get_Next_Match, Insert/Delete_Node,
  114. XEncode/Decode_Char/Position), so if you want the speed and/or compression
  115. Xrate `a la vogue' you may replace the low-level routines with the homebrew
  116. X(e. g.) ones and enjoy the results.
  117. X
  118. X(I tried to implement splay trees instead of Huffman ones and instead of
  119. Xstatic table for position information, but this gives nothing, alas.)
  120. X
  121. X--------- CALGARY COMPRESSION CORPUS RESULTS --------
  122. X
  123. X  41127  bib.F
  124. X 340447  book1.F
  125. X 229188  book2.F
  126. X  68610  geo.F
  127. X 155157  news.F
  128. X  10551  obj1.F
  129. X  86216  obj2.F
  130. X  19924  paper1.F
  131. X  32439  paper2.F
  132. X  54993  pic.F
  133. X  14180  progc.F
  134. X  17136  progl.F
  135. X  11771  progp.F
  136. X  22903  trans.F
  137. X
  138. XAverage bits/byte on the standard set (except paper3-6) =
  139. X    1104642 * 8 / 3141622 = 2.813
  140. X
  141. X--------------- BACKGROUND INFORMATION -----------------
  142. X
  143. X    The format of a frozen file is as follows:
  144. X    (version 1.0 had only 2-bytes header)
  145. X
  146. Xoffset    type      value    comment
  147. X  0       byte       037     2 byte magic header
  148. X  1       byte       0237    (version 1.0 - 0236)
  149. X  2       short       X      (little endian)
  150. X  4       byte        Y
  151. X
  152. XX = 0 e e e e e d d d d c c c b b a   \
  153. X                       > [a-f] are binary digits
  154. XY = 0 0 f f f f f f                   /
  155. X
  156. Xa - number of 1-bit static Huffman codes in the `matching positions'
  157. Xtable (see freeze.1)
  158. Xbb - number of 2-bit codes,
  159. X    etc.
  160. X
  161. XThe numbers of 7- and 8-bits codes are evaluated from the
  162. Xconditions: sum(codes) = 62(dec), max code = 1111111(bin).
  163. X
  164. XE.g. values are: 0 1 1 1 4 10 27 18, what means:
  165. Xno 1-bit codes,
  166. Xone 2-bit, 3-bit and 4-bit codes, etc., so Huffman codes are:
  167. X00, 010, 0110, 01110, 01111, 10000, .... , 11111111.
  168. X
  169. XGeneral format of frozen file is:
  170. X
  171. Xmagic header - table description - stream of bits
  172. X
  173. XThe stream of bits is considered as a sequence of variable length dynamic
  174. XHuffman codes (if their values are in the range of 0-255, they mean single
  175. Xbytes, special value of 256 means EOF, and further values mean the lengths
  176. Xof matched string.) If we have the value greater than 256, we get a static
  177. XHuffman code from the stream (his value is 6 higher bits of matched
  178. Xstring's position in the buffer), and then we get 7 bits literally.
  179. X
  180. XBecause buffer length is 8192 bytes and maximum match length is 256 bytes,
  181. Xthe position of matched string cannot be greater than 8192-256, that's why
  182. Xthere is only (8192-256)/2^7 = 62 static codes.
  183. X
  184. X            *        *       *
  185. X
  186. XThe default table is tuned for both C texts and executable files (as in
  187. XLHARC). If you freeze any other files (databases, images, fonts,
  188. Xetc.) you can calculate the matching positions distribution using the
  189. X`statist' program, which calculates and displays the mentioned
  190. Xdistribution for the given file. It is useful for large (100K or more)
  191. Xfiles.
  192. X
  193. XThough the built-in position table is polyvalent, the tuning can increase
  194. Xthe compression rate up to one additional percent.  (Or even more, if the
  195. Xmatching strings distribution is very bizarre!)
  196. X
  197. XUsage: statist < sample_file ; you can also see the intermediate values
  198. Xand watch their changes by pressing INTR key when you wish.
  199. X
  200. XNote: If you use "gensample | statist", remember that INTR influence BOTH
  201. Xprocesses !!
  202. X
  203. XYou may create the /etc/default/freeze (or rather /usr/local/lib/freeze.cnf,
  204. Xwhich is now the default, NOTE IT!) file (in MS-DOS it is FREEZE.CNF in
  205. Xthe directory of FREEZE.EXE), which has the following format:  name =
  206. X``statist's output (8 numbers)'', e.g.:
  207. X
  208. X---------- cut here -----------
  209. X# This is freeze's defaults file
  210. Xgif =   0 0 0 0 2 60 0 0        # This is NOT! optimal data
  211. X                # for GIF files
  212. Xdoc=0 0 1 2 7 16 36 0           # The sample was gcc.lp
  213. Xgreedy2=0,1,1,2,5,8,11,34       # Both space- and comma-separated
  214. X                # lists are allowed
  215. X
  216. X# End of file
  217. X---------- cut here -----------
  218. X
  219. XIf you find values which are better THAN DEFAULT both for text (C
  220. Xprograms) and binary (executable) files, please send them to me.
  221. X
  222. XImportant note: statist.c is NOT a part of freeze package, it is an
  223. Xadditional feature.
  224. X
  225. X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  226. X
  227. XThere is yet another additional feature since this version:
  228. X
  229. Xshowhuf - shows Huffman table in a frozen file.
  230. XIt can be used to find files frozen with freeze 1.0, too.
  231. END_OF_FILE
  232.   if test 7052 -ne `wc -c <'README'`; then
  233.     echo shar: \"'README'\" unpacked with wrong size!
  234.   fi
  235.   # end of 'README'
  236. fi
  237. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  238.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  239. else
  240.   echo shar: Extracting \"'MANIFEST'\" \(223 characters\)
  241.   sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  242. XMANIFEST
  243. XMakefile.in
  244. XREADME
  245. Xbitio.c
  246. Xbitio.h
  247. Xcompat.h
  248. Xconfig.h.in
  249. Xconfig.msc
  250. Xconfig.tur
  251. Xconfigure
  252. Xdebug.c
  253. Xdecode.c
  254. Xdefault.c
  255. Xencode.c
  256. Xfreeze.1
  257. Xfreeze.c
  258. Xfreeze.h
  259. Xhuf.c
  260. Xhuf.h
  261. Xlz.c
  262. Xlz.h
  263. Xpatchlev.h
  264. Xshowhuf.c
  265. Xstatist.1
  266. Xstatist.c
  267. END_OF_FILE
  268.   if test 223 -ne `wc -c <'MANIFEST'`; then
  269.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  270.   fi
  271.   # end of 'MANIFEST'
  272. fi
  273. if test -f 'configure' -a "${1}" != "-c" ; then 
  274.   echo shar: Will not clobber existing file \"'configure'\"
  275. else
  276.   echo shar: Extracting \"'configure'\" \(12654 characters\)
  277.   sed "s/^X//" >'configure' <<'END_OF_FILE'
  278. X#!/bin/sh
  279. X# Guess values for system-dependent variables and create Makefiles.
  280. X# Generated automatically using autoconf.
  281. X# Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  282. X
  283. X# This program is free software; you can redistribute it and/or modify
  284. X# it under the terms of the GNU General Public License as published by
  285. X# the Free Software Foundation; either version 2, or (at your option)
  286. X# any later version.
  287. X
  288. X# This program is distributed in the hope that it will be useful,
  289. X# but WITHOUT ANY WARRANTY; without even the implied warranty of
  290. X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  291. X# GNU General Public License for more details.
  292. X
  293. X# You should have received a copy of the GNU General Public License
  294. X# along with this program; if not, write to the Free Software
  295. X# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  296. X
  297. X# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create]
  298. X#        [--prefix=PREFIX] [--exec_prefix=PREFIX] [--with-PROGRAM] [TARGET]
  299. X# Ignores all args except --srcdir, --prefix, --exec_prefix, and --no-create.
  300. X
  301. Xtrap 'rm -f conftest* core; exit 1' 1 3 15
  302. X
  303. Xfor arg
  304. Xdo
  305. X  # Handle --exec_prefix with a space before the argument.
  306. X  if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix=
  307. X  # Handle --host with a space before the argument.
  308. X  elif test x$next_host = xyes; then next_host=
  309. X  # Handle --prefix with a space before the argument.
  310. X  elif test x$next_prefix = xyes; then prefix=$arg; next_prefix=
  311. X  # Handle --srcdir with a space before the argument.
  312. X  elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir=
  313. X  else
  314. X    case $arg in
  315. X     -exec_prefix=* | --exec_prefix=* | --exec_prefi=* | --exec_pref=* | --exec_pre=* | --exec_pr=* | --exec_p=* | --exec_=* | --exec=* | --exe=* | --ex=* | --e=*)
  316. X    exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  317. X     -exec_prefix | --exec_prefix | --exec_prefi | --exec_pref | --exec_pre | --exec_pr | --exec_p | --exec_ | --exec | --exe | --ex | --e)
  318. X    next_exec_prefix=yes ;;
  319. X
  320. X     -gas | --gas | --ga | --g) ;;
  321. X
  322. X     -host=* | --host=* | --hos=* | --ho=* | --h=*) ;;
  323. X     -host | --host | --hos | --ho | --h)
  324. X    next_host=yes ;;
  325. X
  326. X     -nfp | --nfp | --nf) ;;
  327. X
  328. X     -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no)
  329. X        no_create=1 ;;
  330. X
  331. X     -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
  332. X    prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  333. X     -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
  334. X    next_prefix=yes ;;
  335. X
  336. X     -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*)
  337. X    srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;;
  338. X     -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s)
  339. X    next_srcdir=yes ;;
  340. X
  341. X     -with-* | --with-*) ;;
  342. X
  343. X     *) ;;
  344. X    esac
  345. X  fi
  346. Xdone
  347. X
  348. Xrm -f conftest*
  349. Xcompile='${CC-cc} $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1'
  350. X
  351. X# A filename unique to this package, relative to the directory that
  352. X# configure is in, which we can look for to find out if srcdir is correct.
  353. Xunique_file=freeze.h
  354. X
  355. X# Find the source files, if location was not specified.
  356. Xif test -z "$srcdir"; then
  357. X  srcdirdefaulted=yes; srcdir=.
  358. X  if test ! -r $unique_file; then srcdir=..; fi
  359. Xfi
  360. Xif test ! -r $srcdir/$unique_file; then
  361. X  if test x$srcdirdefaulted = xyes; then
  362. X    echo "configure: Can not find sources in \`.' or \`..'." 1>&2
  363. X  else
  364. X    echo "configure: Can not find sources in \`${srcdir}'." 1>&2
  365. X  fi
  366. X  exit 1
  367. Xfi
  368. X# Preserve a srcdir of `.' to avoid automounter screwups with pwd.
  369. X# But we can't avoid them for `..', to make subdirectories work.
  370. Xcase $srcdir in
  371. X  .|/*|~*) ;;
  372. X  *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute.
  373. Xesac
  374. X
  375. X
  376. Xcompile='rm -f conftest.t;
  377. X  mv conftest.c conftest.t;
  378. X  echo "$DEFS" > conftest.c;
  379. X  cat conftest.t >> conftest.c;
  380. X  rm -f conftest.t;
  381. X  ${CC-cc} conftest.c -o conftest $LIBS >/dev/null 2>&1'
  382. X
  383. Xif test -z "$CC"; then
  384. X  echo checking for gcc
  385. X  saveifs="$IFS"; IFS="${IFS}:"
  386. X  for dir in $PATH; do
  387. X    test -z "$dir" && dir=.
  388. X    if test -f $dir/gcc; then
  389. X      CC="gcc"
  390. X      break
  391. X    fi
  392. X  done
  393. X  IFS="$saveifs"
  394. Xfi
  395. Xtest -z "$CC" && CC="cc"
  396. X
  397. X# Find out if we are using GNU C, under whatever name.
  398. Xcat <<EOF > conftest.c
  399. X#ifdef __GNUC__
  400. X  yes
  401. X#endif
  402. XEOF
  403. X${CC-cc} -E conftest.c > conftest.out 2>&1
  404. Xif egrep yes conftest.out >/dev/null 2>&1; then
  405. X  GCC=1 # For later tests.
  406. X  CC="$CC -O"
  407. Xfi
  408. Xrm -f conftest*
  409. X
  410. Xecho checking how to run the C preprocessor
  411. Xif test -z "$CPP"; then
  412. X  CPP='${CC-cc} -E'
  413. X  cat <<EOF > conftest.c
  414. X$DEFS
  415. X#include <stdio.h>
  416. XEOF
  417. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  418. Xif test -z "$err"; then
  419. X  :
  420. Xelse
  421. X  CPP=/lib/cpp
  422. Xfi
  423. Xrm -f conftest*
  424. Xfi
  425. X
  426. Xecho "${DEFS}#include <signal.h>" > conftest.c
  427. Xeval "$CPP conftest.c > conftest.out 2>&1"
  428. Xif egrep "(void|sighandler_t).*signal" conftest.out >/dev/null 2>&1; then
  429. X  :
  430. Xelse 
  431. X  DEFS="${DEFS}#define RETSIGTYPE int
  432. X"
  433. Xfi
  434. Xrm -f conftest*
  435. X
  436. X
  437. Xecho checking for unaligned access
  438. Xcat <<EOF > conftest.c
  439. X#include <signal.h>
  440. XRETSIGTYPE onintr() { exit(1); }
  441. Xint x[2] = { 12345, 67890 };
  442. Xmain() { int *i;
  443. Xchar * p = (char*) x;
  444. Xsignal(SIGBUS, onintr);
  445. Xi = (int*) (p + 1);
  446. X/* invert condition, as exit(0) == true */
  447. Xexit(*i == x[0]); /* check for LSB mask on word access */
  448. X}
  449. XEOF
  450. Xeval $compile
  451. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  452. X  DEFS="${DEFS}#define ALLOW_MISALIGN 1
  453. X"
  454. Xfi
  455. Xrm -f conftest*
  456. Xecho checking integer size
  457. Xcat <<EOF > conftest.c
  458. Xmain() { exit(!(sizeof(int) == 2)); }
  459. XEOF
  460. Xeval $compile
  461. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  462. X  DEFS="${DEFS}#define INT_16_BITS 1
  463. X"
  464. Xfi
  465. Xrm -f conftest*
  466. Xcat <<EOF > conftest.c
  467. Xmain() { exit(sizeof(unsigned short) <= 2); }
  468. XEOF
  469. Xeval $compile
  470. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  471. X  DEFS="${DEFS}#define BIGSHORTS 1
  472. X"
  473. Xfi
  474. Xrm -f conftest*
  475. Xecho checking for 64K segments
  476. Xcat <<EOF > conftest.c
  477. Xchar x[69001];
  478. Xmain () {
  479. Xx[12345] = ' ';
  480. Xexit(0);
  481. X}
  482. XEOF
  483. Xeval $compile
  484. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  485. X  :
  486. Xelse
  487. X  DEFS="${DEFS}#define SEGMENTED 1
  488. X" segmented=1
  489. Xfi
  490. Xrm -f conftest*
  491. Xif test "$segmented"; then
  492. Xecho It seems that your computer supports different memory models.
  493. Xecho If it is so, you may wish to build freeze in small model
  494. Xecho in order to speed it up.
  495. Xecho To do that, you will need to additionally define TINY
  496. Xecho in config.h file you will get after the configuration.
  497. Xfi
  498. Xecho checking for long file names
  499. X(echo 1 > conftest9012345) 2>/dev/null
  500. X(echo 2 > conftest9012346) 2>/dev/null
  501. Xval=`cat conftest9012345 2>/dev/null`
  502. Xtest -f conftest9012345 && test "$val" = 1 && DEFS="${DEFS}#define HAVE_LONG_FILE_NAMES 1
  503. X"
  504. Xrm -f conftest9012345 conftest9012346
  505. X
  506. Xecho checking for directory library header
  507. Xecho checking for dirent.h
  508. Xcat <<EOF > conftest.c
  509. X$DEFS
  510. X#include <dirent.h>
  511. XEOF
  512. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  513. Xif test -z "$err"; then
  514. X  DEFS="${DEFS}#define DIRENT 1
  515. X" dirheader=dirent.h
  516. Xfi
  517. Xrm -f conftest*
  518. X
  519. Xif test -z "$dirheader"; then
  520. Xecho checking for sys/ndir.h
  521. Xcat <<EOF > conftest.c
  522. X$DEFS
  523. X#include <sys/ndir.h>
  524. XEOF
  525. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  526. Xif test -z "$err"; then
  527. X  DEFS="${DEFS}#define SYSNDIR 1
  528. X" dirheader=sys/ndir.h
  529. Xfi
  530. Xrm -f conftest*
  531. X
  532. Xfi
  533. Xif test -z "$dirheader"; then
  534. Xecho checking for sys/dir.h
  535. Xcat <<EOF > conftest.c
  536. X$DEFS
  537. X#include <sys/dir.h>
  538. XEOF
  539. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  540. Xif test -z "$err"; then
  541. X  DEFS="${DEFS}#define SYSDIR 1
  542. X" dirheader=sys/dir.h
  543. Xfi
  544. Xrm -f conftest*
  545. X
  546. Xfi
  547. X
  548. Xecho checking for closedir return value
  549. Xcat <<EOF > conftest.c
  550. X#include <sys/types.h>
  551. X#include <$dirheader>
  552. Xint closedir(); main() { exit(0); }
  553. XEOF
  554. Xeval $compile
  555. Xif test -s conftest && (./conftest 2>/dev/null) 2>/dev/null; then
  556. X  :
  557. Xelse
  558. X  DEFS="${DEFS}#define VOID_CLOSEDIR 1
  559. X"
  560. Xfi
  561. Xrm -f conftest*
  562. X
  563. Xfor hdr in sys/stdtypes.h
  564. Xdo
  565. Xtrfrom='[a-z]./' trto='[A-Z]__'
  566. Xecho checking for $hdr
  567. Xcat <<EOF > conftest.c
  568. X$DEFS
  569. X#include <$hdr>
  570. XEOF
  571. Xerr=`eval "$CPP conftest.c 2>&1 >/dev/null"`
  572. Xif test -z "$err"; then
  573. X  DEFS="${DEFS}#define HAVE_`echo $hdr|tr "$trfrom" "$trto"` 1
  574. X"
  575. Xfi
  576. Xrm -f conftest*
  577. Xdone
  578. X
  579. Xfor func in rindex setlinebuf
  580. Xdo
  581. Xtrfrom='[a-z]' trto='[A-Z]'
  582. Xecho checking for ${func}
  583. Xecho "
  584. Xmain() { exit(0); } t() { 
  585. X/* Override any gcc2 internal prototype to avoid an error.  */
  586. Xextern char ${func}(); ${func}(); }" > conftest.c
  587. Xif eval $compile; then
  588. X  DEFS="${DEFS}#define HAVE_`echo $func|tr "$trfrom" "$trto"` 1
  589. X"
  590. Xfi
  591. Xrm -f conftest*
  592. Xdone
  593. X
  594. Xecho "${DEFS}#include <utime.h>" > conftest.c
  595. Xeval "$CPP conftest.c > conftest.out 2>&1"
  596. Xif egrep "utimbuf" conftest.out >/dev/null 2>&1; then
  597. X  DEFS="${DEFS}#define UTIME 1
  598. X" utimes=1
  599. Xfi
  600. Xrm -f conftest*
  601. X
  602. Xif test -z "$utimes"; then
  603. Xecho "${DEFS}#include <sys/utime.h>" > conftest.c
  604. Xeval "$CPP conftest.c > conftest.out 2>&1"
  605. Xif egrep "utimbuf" conftest.out >/dev/null 2>&1; then
  606. X  DEFS="${DEFS}#define SYSUTIME 1
  607. X" utimes=1
  608. Xfi
  609. Xrm -f conftest*
  610. X
  611. Xfi
  612. Xif test -z "$utimes"; then
  613. Xecho "${DEFS}#include <sys/time.h>" > conftest.c
  614. Xeval "$CPP conftest.c > conftest.out 2>&1"
  615. Xif egrep "timeval" conftest.out >/dev/null 2>&1; then
  616. X  DEFS="${DEFS}#define SYSTIME 1
  617. X"
  618. Xfi
  619. Xrm -f conftest*
  620. X
  621. Xfi
  622. X# Make sure to not get the incompatible SysV /etc/install and
  623. X# /usr/sbin/install, which might be in PATH before a BSD-like install,
  624. X# or the SunOS /usr/etc/install directory.
  625. Xif test -z "$INSTALL"; then
  626. X  echo checking for install
  627. X  saveifs="$IFS"; IFS="${IFS}:"
  628. X  for dir in $PATH; do
  629. X    test -z "$dir" && dir=.
  630. X    case $dir in
  631. X    /etc|/usr/sbin|/usr/etc) ;;
  632. X    *)
  633. X      if test -f $dir/install; then
  634. X    INSTALL="$dir/install -c"
  635. X    INSTALL_PROGRAM='$(INSTALL)'
  636. X    INSTALL_DATA='$(INSTALL) -m 644'
  637. X    break
  638. X      fi
  639. X      ;;
  640. X    esac
  641. X  done
  642. X  IFS="$saveifs"
  643. Xfi
  644. XINSTALL=${INSTALL-cp}
  645. XINSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'}
  646. XINSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'}
  647. X
  648. Xecho checking for freeze to derive installation directory prefix
  649. Xif test -z "$prefix"
  650. Xthen
  651. X  saveifs="$IFS"; IFS="$IFS:"
  652. X  for dir in $PATH; do
  653. X    test -z "$dir" && dir=.
  654. X    if test $dir != . && test -f $dir/freeze; then
  655. X      # Not all systems have dirname.
  656. X      prefix=`echo $dir|sed 's,/[^/][^/]*$,,'`
  657. X      break
  658. X    fi
  659. X  done
  660. X  IFS="$saveifs"
  661. Xfi
  662. X
  663. Xif test -n "$prefix"; then
  664. X  test -z "$exec_prefix" && exec_prefix='$(prefix)'
  665. X  prsub="s,^prefix[     ]*=.*$,prefix = $prefix,"
  666. Xfi
  667. Xif test -n "$exec_prefix"; then
  668. X  prsub="$prsub
  669. Xs,^exec_prefix[     ]*=.*$,exec_prefix = $exec_prefix,"
  670. Xfi
  671. X
  672. Xtrap 'rm -f config.status; exit 1' 1 3 15
  673. Xecho creating config.status
  674. Xrm -f config.status
  675. Xcat <<EOF > config.status
  676. X#!/bin/sh
  677. X# Generated automatically by configure.
  678. X# Run this file to recreate the current configuration.
  679. X# This directory was configured as follows:
  680. X# $0 $*
  681. X
  682. Xcase "\$1" in
  683. X  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
  684. X  exec /bin/sh $0 $* ;;
  685. Xesac
  686. X
  687. Xtrap 'rm -f Makefile config.h; exit 1' 1 3 15
  688. XCC='$CC'
  689. XCPP='$CPP'
  690. XINSTALL='$INSTALL'
  691. XINSTALL_PROGRAM='$INSTALL_PROGRAM'
  692. XINSTALL_DATA='$INSTALL_DATA'
  693. XLIBS='$LIBS'
  694. Xsrcdir='$srcdir'
  695. XDEFS='$DEFS'
  696. Xprefix='$prefix'
  697. Xexec_prefix='$exec_prefix'
  698. Xprsub='$prsub'
  699. XEOF
  700. Xcat <<\EOF >> config.status
  701. X
  702. Xtop_srcdir=$srcdir
  703. Xfor file in Makefile; do
  704. X  srcdir=$top_srcdir
  705. X  # Remove last slash and all that follows it.  Not all systems have dirname.
  706. X  dir=`echo $file|sed 's,/[^/][^/]*$,,'`
  707. X  if test "$dir" != "$file"; then
  708. X    test "$top_srcdir" != . && srcdir=$top_srcdir/$dir
  709. X    test ! -d $dir && mkdir $dir
  710. X  fi
  711. X  echo creating $file
  712. X  rm -f $file
  713. X  echo "# Generated automatically from `basename $file`.in by configure." > $file
  714. X  sed -e "
  715. X$prsub
  716. Xs,@CC@,$CC,
  717. Xs,@CPP@,$CPP,
  718. Xs,@INSTALL@,$INSTALL,
  719. Xs,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,
  720. Xs,@INSTALL_DATA@,$INSTALL_DATA,
  721. Xs,@LIBS@,$LIBS,
  722. Xs,@srcdir@,$srcdir,
  723. X" $top_srcdir/${file}.in >> $file
  724. Xdone
  725. X
  726. Xecho creating config.h
  727. X# Ultrix awk loses trailing comments from the header file, but
  728. X# that's not fatal.
  729. Xrm -f conftest.h
  730. Xecho "/* config.h.  Generated automatically by configure.  */" > conftest.h
  731. Xecho "$DEFS
  732. X/* END_OF_DEFS */" |
  733. Xawk '
  734. X# The escaped newlines are to work around a bug in GNU m4 0.99
  735. X# in quoting more than 2 arguments in a single line.
  736. XBEGIN { filenum = 1 }
  737. Xfilenum == 1 && $1 == "#define" \
  738. X{ defs[$2] = $3
  739. X  for (i = 4; i <= NF; i++)
  740. X    defs[$2] = defs[$2] " " $i
  741. X}
  742. X/END_OF_DEFS/ { filenum = 2; next }
  743. Xfilenum == 2 && $1 == "#define" && \
  744. Xdefs[$2] != "" {
  745. X  $3 = defs[$2]
  746. X  print; next
  747. X}
  748. Xfilenum == 2 && $1 == "#undef" && \
  749. Xdefs[$2] != "" {
  750. X  $1 = "#define"
  751. X  $2 = $2 " " defs[$2]
  752. X  print; next
  753. X}
  754. Xfilenum == 2 { print }
  755. X' - $top_srcdir/config.h.in >> conftest.h
  756. Xif cmp -s config.h conftest.h 2>/dev/null; then
  757. X  # The file exists and we would not be changing it.
  758. X  rm -f conftest.h
  759. Xelse
  760. X  rm -f config.h
  761. X  mv conftest.h config.h
  762. Xfi
  763. X
  764. XEOF
  765. Xchmod +x config.status
  766. Xtest -n "$no_create" || ./config.status
  767. X
  768. END_OF_FILE
  769.   if test 12654 -ne `wc -c <'configure'`; then
  770.     echo shar: \"'configure'\" unpacked with wrong size!
  771.   fi
  772.   chmod +x 'configure'
  773.   # end of 'configure'
  774. fi
  775. if test -f 'freeze.c' -a "${1}" != "-c" ; then 
  776.   echo shar: Will not clobber existing file \"'freeze.c'\"
  777. else
  778.   echo shar: Extracting \"'freeze.c'\" \(24625 characters\)
  779.   sed "s/^X//" >'freeze.c' <<'END_OF_FILE'
  780. X#include "freeze.h"
  781. X#include "lz.h"
  782. X#include "bitio.h"
  783. X#include "patchlev.h"
  784. X
  785. X/*
  786. X * Freeze - data freezing program
  787. X * Version 1.0:
  788. X * This program is made from GNU compress.c and Yoshizaki/Tagawa's
  789. X * lzhuf.c. (Thanks to all of them.)
  790. X * The algorithm is modified for using in pipe
  791. X * (added ENDOF symbol in Huffman table).
  792. X * Version 1.1:
  793. X * Check for lack of bytes in frozen file when melting.
  794. X * Put the GetBit routine into DecodeChar for reduce function-
  795. X * call overhead when melting.
  796. X * Version 1.2:
  797. X * Added delayed coding a la COMIC.
  798. X * Now freeze works on Intels (*NIX, Microsoft, Turbo),
  799. X * Sun (SunOS).
  800. X * Version 2.0:
  801. X * Buffer size is now 8192 bytes, maximum match length - 256 bytes.
  802. X * Improved hash function (with tuning of hash-table)
  803. X * Version 2.1: Noticeable speedup: Insert_Node and Get_Next_Match
  804. X * are now separated. (Boyer-Moore string matching)
  805. X * Version 2.2: Tunable static Huffman table for position information,
  806. X * this info may be given in the command string now.
  807. X * Version 2.2.3: Bug fixes, 10% freezing speedup.
  808. X * Version 2.3: Minor bug fixes (DOS filenames handling, backward
  809. X * compatibility feature improved, "bits" compression ratio display,
  810. X * preventive check for special files), speedups, more comments added.
  811. X * Version 2.3.1: Typedefs cleaned, utime bug on the m88k corrected
  812. X * (pa@verano.sba.ca.us, clewis@ferret.ocunix.on.ca (Chris Lewis)),
  813. X * "chain threshold" heuristic used for speedup (in "greedy" mode) -
  814. X * a la ZIP (Jean-Loup Gailly). Max. hash bits reduced to 16.
  815. X * Version 2.3.2: Adaptation to TOS 1.04 (fifi@hiss.han.de), UTIMES
  816. X * handling (jik@athena.mit.edu).
  817. X * Version 2.3.3: More accurate adaptation for XENIX 286.
  818. X * Version 2.3.4: Minor bug fixes, HP-UX (longnames w/o BSD) handling,
  819. X * greedy_threshold added.
  820. X * Version 2.3.5: Noticeable speedup (on RISCs, don't know for sure
  821. X * about CISCs).
  822. X * Version 2.4: Yet another speedup, many general changes...
  823. X * Version 2.4.1 (unofficial): A bug is corrected.
  824. X * Version 2.5: Speedup of melting, more thorough adaptation to
  825. X * 16-bits (and 64-bits?) processors.
  826. X */
  827. X
  828. Xstatic char ident[] = "@(#) freeze.c 2.5.%d %s leo@ipmce.su\n";
  829. X
  830. Xint     exit_stat = 0;
  831. X
  832. Xvoid 
  833. XUsage()
  834. X{
  835. X#ifdef DEBUG
  836. X
  837. X# ifdef DOS
  838. X  fprintf(stderr, "Usage: freeze [-cdDfitvVg] [file | +type ...]\n");
  839. X# else
  840. X  fprintf(stderr, "Usage: freeze [-cdDfvVg] [file | +type ...]\n");
  841. X# endif                /* DOS */
  842. X
  843. X#else
  844. X
  845. X# ifdef DOS
  846. X  fprintf(stderr, "Usage: freeze [-cdfitvVg] [file | +type ...]\n");
  847. X# else
  848. X  fprintf(stderr, "Usage: freeze [-cdfvVg] [file | +type ...]\n");
  849. X# endif                /* DOS */
  850. X
  851. X#endif                /* DEBUG */
  852. X}
  853. X
  854. Xvoid    (*meltfunc) ();        /* To call something for melting */
  855. X
  856. Xint     topipe = 0,             /* Write output on stdout, suppress messages */
  857. X        precious = 1,        /* Don't unlink output file on interrupt */
  858. X        quiet = 1,        /* Don't tell me about freezing */
  859. X        do_melt = 0,        /* freeze means "freeze" */
  860. X        greedy = 0,        /* GREEDY parsing */
  861. X        force = 0;        /* "Force" flag */
  862. X
  863. Xchar    ofname[MAXNAMLEN];
  864. Xstatic struct stat statbuf;    /* Used by 'main' and 'copystat' routines */
  865. X
  866. X#ifdef DOS
  867. Xchar   *last_sep();        /* last slash, backslash, or colon */
  868. Xchar    tail[3];        /* 2nd and 3rd chars of file extension */
  869. X# ifdef TEXT_DEFAULT
  870. Xunsigned        image = O_TEXT;
  871. X# else
  872. Xunsigned        image = O_BINARY;
  873. X# endif
  874. X#else
  875. X#  define last_sep(s) strrchr((s), '/')    /* Unix always uses slashes */
  876. X#  ifndef DEFFILE
  877. X#   define DEFFILE "/usr/local/lib/freeze.cnf"
  878. X#  endif
  879. Xchar    deffile[] = DEFFILE;
  880. X#endif
  881. X
  882. X#ifdef DEBUG
  883. Xint     debug = 0, verbose = 0;
  884. Xchar   *pr_char();
  885. X#endif                /* DEBUG */
  886. X
  887. X#if defined(GATHER_STAT) || defined(DEBUG)
  888. Xlong    refers_out = 0, symbols_out = 0;
  889. X#endif
  890. X
  891. X/* Do not sleep when freeze works :-) */
  892. Xlong    indc_count, indc_threshold;
  893. Xoff_t   file_length = 0;    /* initial length of file */
  894. X
  895. XRETSIGTYPE      (*bgnd_flag)();
  896. X
  897. Xvoid    writeerr(), copystat(), version(), tune_table();
  898. X
  899. X/*****************************************************************
  900. X *
  901. X * Usage: freeze [-cdfivV] [-t] [-g...] [-x...] [type] [file ...]
  902. X * Inputs:
  903. X *
  904. X *      -c:         Write output on stdout, don't remove original.
  905. X *
  906. X *      -d:         If given, melting is done instead.
  907. X *
  908. X *      -g:         Use "greedy" parsing (1.5% worse, 40% faster).
  909. X *                  (Means nothing when melting). May be repeated.
  910. X *
  911. X *      -f:         Forces output file to be generated, even if one already
  912. X *                  exists, and even if no space is saved by freezeing.
  913. X *                  If -f is not used, the user will be prompted if stdin is
  914. X *                  a tty, otherwise, the output file will not be overwritten.
  915. X *
  916. X *      -i:         Image mode (defined only under MS-DOS).  Prevents
  917. X *                  conversion between UNIX text representation (LF line
  918. X *                  termination) in frozen form and MS-DOS text
  919. X *                  representation (CR-LF line termination) in melted
  920. X *                  form.  Useful with non-text files.  Default unless
  921. X *                  TEXT_DEFAULT specified.
  922. X *
  923. X *      -b:         Binary mode.  Synonym for -i.  MS-DOS only.
  924. X *
  925. X *      -t:         Text mode (defined only under MS-DOS).  Treat file
  926. X *                  as text (CR-LF and ^Z special) in melted form.  Default
  927. X *                  if TEXT_DEFAULT specified.
  928. X *
  929. X *      -g:         Greedy parsing - increases speed, decreases
  930. X *                  compression rate. Can be repeated.
  931. X *
  932. X *      -x:         "Anti- -g".
  933. X *
  934. X *      -v:         Write freezing statistics. -vv means "draw progress
  935. X *                  indicator".
  936. X *
  937. X *      -V:         Write version and compilation options.
  938. X *
  939. X *      file ...:   Files to be frozen.  If none specified, stdin
  940. X *            is used.
  941. X * Outputs:
  942. X *      file.F:     Frozen form of file with same mode, owner, and utimes
  943. X *    or stdout   (if stdin used as input)
  944. X *
  945. X * Assumptions:
  946. X *      When filenames are given, replaces with the frozen version
  947. X *      (.F suffix) only if the file decreases in size.
  948. X * Algorithm:
  949. X *      Modified Lempel-Ziv-SS method (LZSS), adaptive Huffman coding
  950. X *      for literal symbols and length info.
  951. X *      Static Huffman coding for position info. (Is it optimal ?)
  952. X *      Lower bits of position info are put in output
  953. X *      file without any coding because of their random distribution.
  954. X */
  955. X
  956. X/* From compress.c. Replace .Z --> .F etc */
  957. X
  958. Xvoid 
  959. Xmain(argc, argv)
  960. Xregister int argc;
  961. Xchar  **argv;
  962. X{
  963. X  short   overwrite = 0;    /* Do not overwrite unless given -f flag */
  964. X  char    tempname[100];
  965. X  char  **filelist, **fileptr;
  966. X  char   *cp;
  967. X
  968. X#ifdef TOS
  969. X
  970. X  char   *argv0 = "freeze.ttp";    /* argv[0] is not defined :-( */
  971. X
  972. X#endif
  973. X
  974. X#ifndef DOS
  975. X  char   *malloc();
  976. X#endif
  977. X
  978. X  extern RETSIGTYPE onintr();
  979. X
  980. X#ifdef DOS
  981. X  char   *sufp;
  982. X#else
  983. X  extern RETSIGTYPE oops();
  984. X#endif
  985. X
  986. X#ifndef DOS
  987. X  if ((bgnd_flag = signal(SIGINT, SIG_IGN)) != SIG_IGN)
  988. X#endif
  989. X  {
  990. X    (void) signal(SIGINT, onintr);
  991. X#ifdef __TURBOC__
  992. X
  993. X#ifndef TOS
  994. X    setcbrk(1);
  995. X
  996. X#endif
  997. X#endif
  998. X#ifndef DOS
  999. X    (void) signal(SIGSEGV, oops);
  1000. X#endif
  1001. X  }
  1002. X  filelist = fileptr = (char **) (malloc(argc * sizeof(*argv)));
  1003. X  *filelist = NULL;
  1004. X
  1005. X  if ((cp = last_sep(argv[0])) != 0) {
  1006. X    cp++;
  1007. X  } else {
  1008. X
  1009. X#ifdef TOS
  1010. X
  1011. X    cp = argv0;
  1012. X
  1013. X#else
  1014. X    cp = argv[0];
  1015. X
  1016. X#endif
  1017. X  }
  1018. X
  1019. X#ifdef DOS
  1020. X/* use case-insensitive match: parent may not be command.com */
  1021. X#ifdef MSDOS
  1022. X  if (!stricmp(cp, "unfreeze.exe") || !stricmp(cp, "melt.exe")) {
  1023. X#else                /* TOS */
  1024. X  if (!stricmp(cp, "unfreeze.ttp") || !stricmp(cp, "melt.ttp")) {
  1025. X#endif
  1026. X#else
  1027. X  if (!strcmp(cp, "unfreeze") || !strcmp(cp, "melt")) {
  1028. X#endif
  1029. X
  1030. X    do_melt = 1;
  1031. X
  1032. X#ifdef DOS
  1033. X#ifdef MSDOS
  1034. X  } else if (stricmp(cp, "fcat.exe") == 0) {
  1035. X#else                /* TOS */
  1036. X  } else if (stricmp(cp, "fcat.ttp") == 0) {
  1037. X#endif
  1038. X#else
  1039. X  } else if (strcmp(cp, "fcat") == 0) {
  1040. X#endif
  1041. X
  1042. X    do_melt = 1;
  1043. X    topipe = 1;
  1044. X
  1045. X  } else {
  1046. X  /* Freezing */
  1047. X
  1048. X#ifndef DOS
  1049. X    (void) defopen(deffile);
  1050. X#else
  1051. X    cp = strrchr(cp, '.');
  1052. X    *++cp = 'C';
  1053. X    *++cp = 'N';
  1054. X    *++cp = 'F';
  1055. X    *++cp = '\0';
  1056. X
  1057. X#ifdef TOS
  1058. X    (void) defopen(argv0);
  1059. X#else
  1060. X    (void) defopen(argv[0]);
  1061. X#endif                /* TOS */
  1062. X#endif                /* DOS */
  1063. X
  1064. X  }
  1065. X#ifdef HAVE_SETLINEBUF
  1066. X /* 4.2BSD dependent - take it out if not */
  1067. X  setlinebuf(stderr);
  1068. X#endif                /* BSD */
  1069. X
  1070. X    /* Argument Processing
  1071. X     * All flags are optional.
  1072. X     * -D => debug
  1073. X     * -V => print Version; debug verbose
  1074. X     * -d => do_melt
  1075. X     * -v => unquiet
  1076. X     * -g => greedy
  1077. X     * -f => force overwrite of output file
  1078. X     * -c => cat all output to stdout
  1079. X     * if a string is left, must be an input filename.
  1080. X     */
  1081. X
  1082. X  for (argc--, argv++; argc > 0; argc--, argv++) {
  1083. X    if (**argv == '-' && (*argv)[1] != '-') {        /* A flag argument */
  1084. X      while (*++(*argv)) {    /* Process all flags in this arg */
  1085. X    switch (**argv) {
  1086. X#ifdef DEBUG
  1087. X    case 'D':
  1088. X      debug = 1;
  1089. X      break;
  1090. X    case 'V':
  1091. X      verbose = 1;
  1092. X#else
  1093. X    case 'V':
  1094. X      version();
  1095. X#endif                /* DEBUG */
  1096. X      break;
  1097. X#ifdef DOS
  1098. X    case 'i':
  1099. X    case 'b':
  1100. X      image = O_BINARY;    /* binary (aka image) mode */
  1101. X      break;
  1102. X
  1103. X    case 't':        /* text mode */
  1104. X      image = O_TEXT;
  1105. X      break;
  1106. X#endif
  1107. X    case 'v':
  1108. X      quiet--;
  1109. X      break;
  1110. X    case 'g':
  1111. X      greedy++;
  1112. X      break;
  1113. X    case 'x':
  1114. X      greedy = -1;
  1115. X      break;
  1116. X    case 'd':
  1117. X      do_melt = 1;
  1118. X      break;
  1119. X    case 'f':
  1120. X    case 'F':
  1121. X      overwrite = 1;
  1122. X      force = 1;
  1123. X      break;
  1124. X    case 'c':
  1125. X      topipe = 1;
  1126. X      break;
  1127. X    case 'q':
  1128. X      quiet = 1;
  1129. X      break;
  1130. X    default:
  1131. X      fprintf(stderr, "Unknown flag: '%c'; ", **argv);
  1132. X      Usage();
  1133. X      exit(1);
  1134. X    }
  1135. X      }
  1136. X    } else {            /* Input file name */
  1137. X      *fileptr++ = *argv;    /* Build input file list */
  1138. X      *fileptr = NULL;
  1139. X    }
  1140. X  }
  1141. X
  1142. X#ifdef DEBUG
  1143. X  if (verbose && !debug)
  1144. X    version();
  1145. X#endif
  1146. X
  1147. X  if (do_melt) {
  1148. X    /* use all otherwise unused memory for I/O buffers */
  1149. X    setvbuf(stdin, (char*) next, _IOFBF, (size_t) WINSIZE * sizeof(hash_t));
  1150. X    setvbuf(stdout, (char*) hashtab, _IOFBF, (size_t) hash_size * sizeof(hash_t));
  1151. X  } else {
  1152. X    /* try to allocate all left memory for I/O buffers */
  1153. X    size_t i = 64;      /* 512-byte blocks */
  1154. X#ifdef SEGMENTED
  1155. X    char * p;
  1156. X    do {
  1157. X      if ((p = malloc(i << 9)) != NULL)
  1158. X    break;
  1159. X      i--;
  1160. X    } while (i >= 4);
  1161. X    free(p);
  1162. X    if (quiet < -1) fprintf(stderr, "%d blocks allocated\n", i);
  1163. X#endif
  1164. X    /* Don't check for failure - things cannot get worse than they were */
  1165. X    setvbuf(stdin, NULL, _IOFBF, (i / 2) << 9);
  1166. X    setvbuf(stdout, NULL, _IOFBF, (i - i / 2) << 9);
  1167. X  }
  1168. X
  1169. X  if (*filelist != NULL) {
  1170. X    for (fileptr = filelist; *fileptr; fileptr++) {
  1171. X      if ((**fileptr == '+' || **fileptr == '-') && do_melt == 0) {
  1172. X    tune_table(*fileptr + 1 + (**fileptr == '-'));
  1173. X    /* If a file type is given and no file names, a pipe
  1174. X     * operation is requested, but
  1175. X     * we will ignore an idiotic case of setting an resetting
  1176. X     * tables without any filename.
  1177. X     */
  1178. X    if (filelist[1] == NULL)
  1179. X      goto Pipe;
  1180. X    continue;
  1181. X      }
  1182. X      exit_stat = 0;
  1183. X      if (do_melt != 0) {    /* MELTING */
  1184. X
  1185. X#ifdef DOS
  1186. X      /* Check for .F or XF suffix; add one if necessary */
  1187. X    cp = *fileptr + strlen(*fileptr) - 2;
  1188. X    tail[0] = '\0';
  1189. X    if ((*cp != '.' && *cp != 'X' && *cp != 'x') ||
  1190. X      (*(++cp) != 'F' && *cp != 'f')) {
  1191. X      (void) strcpy(tempname, *fileptr);
  1192. X      if ((cp = strrchr(tempname, '.')) == NULL)
  1193. X        (void) strcat(tempname, ".F");
  1194. X      else if (*(++cp) == '\0')
  1195. X      /* pseudo-extension: FOOBAR. */
  1196. X        (void) strcat(tempname, "F");
  1197. X      else {
  1198. X      /* cp now points to file extension */
  1199. X        tail[0] = cp[1];    /* save two chars */
  1200. X        tail[1] = cp[2];
  1201. X        tail[2] = '\0';
  1202. X        *(++cp) = '\0';
  1203. X        (void) strcat(tempname, "XF");
  1204. X      }
  1205. X      *fileptr = tempname;
  1206. X    }
  1207. X#else
  1208. X      /* Check for .F suffix */
  1209. X    if (strcmp(*fileptr + strlen(*fileptr) - 2, ".F") != 0) {
  1210. X    /* No .F: tack one on */
  1211. X      (void) strcpy(tempname, *fileptr);
  1212. X      (void) strcat(tempname, ".F");
  1213. X      *fileptr = tempname;
  1214. X    }
  1215. X#endif                /* DOS */
  1216. X
  1217. X      /* Open input file for melting */
  1218. X
  1219. X    if (checkstat(*fileptr))
  1220. X      continue;
  1221. X
  1222. X#ifdef DOS
  1223. X    if ((freopen(*fileptr, "rb", stdin)) == NULL)
  1224. X#else
  1225. X    if ((freopen(*fileptr, "r", stdin)) == NULL)
  1226. X#endif
  1227. X    {
  1228. X      perror(*fileptr);
  1229. X      continue;
  1230. X    }
  1231. X      /* Check the magic number */
  1232. X    if (getchar() != MAGIC1)
  1233. X      goto reject;
  1234. X    switch (getchar()) {
  1235. X#ifdef COMPAT
  1236. X    case MAGIC2_1:
  1237. X      meltfunc = melt1;
  1238. X      break;
  1239. X#endif
  1240. X    case MAGIC2_2:
  1241. X      meltfunc = melt2;
  1242. X      break;
  1243. X    default:
  1244. X      reject:
  1245. X      fprintf(stderr, "%s: not in frozen format\n",
  1246. X        *fileptr);
  1247. X      continue;
  1248. X    }
  1249. X
  1250. X      /* Generate output filename */
  1251. X    precious = 1;
  1252. X    (void) strcpy(ofname, *fileptr);
  1253. X    ofname[strlen(ofname) - 2] = '\0';    /* Strip off .F */
  1254. X#ifdef DOS
  1255. X    (void) strcat(ofname, tail);
  1256. X#endif
  1257. X      } else {
  1258. X
  1259. X      /* FREEZING */
  1260. X#ifdef DOS
  1261. X    cp = *fileptr + strlen(*fileptr) - 2;
  1262. X    if ((*cp == '.' || *cp == 'X' || *cp == 'x') &&
  1263. X      (*(++cp) == 'F' || *cp == 'f')) {
  1264. X      fprintf(stderr, "%s: already has %s suffix -- no change\n",
  1265. X        *fileptr, --cp);    /* } */
  1266. X#else
  1267. X    if (strcmp(*fileptr + strlen(*fileptr) - 2, ".F") == 0) {
  1268. X      fprintf(stderr, "%s: already has .F suffix -- no change\n",
  1269. X        *fileptr);
  1270. X#endif                /* DOS */
  1271. X
  1272. X      continue;
  1273. X    }
  1274. X      /* Open input file for freezing */
  1275. X
  1276. X    if (checkstat(*fileptr))
  1277. X      continue;
  1278. X
  1279. X#ifdef DOS
  1280. X    if ((freopen(*fileptr, image == O_TEXT ? "rt" : "rb", stdin))
  1281. X      == NULL)
  1282. X#else
  1283. X    if ((freopen(*fileptr, "r", stdin)) == NULL)
  1284. X#endif
  1285. X    {
  1286. X      perror(*fileptr);
  1287. X      continue;
  1288. X    }
  1289. X      /* Generate output filename */
  1290. X    (void) strcpy(ofname, *fileptr);
  1291. X
  1292. X#ifndef HAVE_LONG_FILE_NAMES
  1293. X    if ((cp = last_sep(ofname)) != NULL)
  1294. X      cp++;
  1295. X    else
  1296. X      cp = ofname;
  1297. X# ifdef DOS
  1298. X    if (topipe == 0 && (sufp = strrchr(cp, '.')) != NULL &&
  1299. X      strlen(sufp) > 2)
  1300. X      fprintf(stderr,
  1301. X        "%s: part of filename extension will be replaced by XF\n",
  1302. X        cp);
  1303. X# else
  1304. X    if (topipe == 0 && strlen(cp) > 12) {
  1305. X      fprintf(stderr, "%s: filename too long to tack on .F\n", cp);
  1306. X      continue;
  1307. X    }
  1308. X# endif                /* DOS */
  1309. X#endif                /* LONGNAMES */
  1310. X
  1311. X#ifdef DOS
  1312. X      /* There is no difference between FOOBAR and FOOBAR. names */
  1313. X    if ((cp = strrchr(ofname, '.')) == NULL)
  1314. X      (void) strcat(ofname, ".F");
  1315. X    else if (cp[1] == '\0')
  1316. X    /* FOOBAR. case */
  1317. X      (void) strcat(ofname, "F");
  1318. X    else {
  1319. X      cp[2] = '\0';
  1320. X      (void) strcat(ofname, "XF");
  1321. X    }
  1322. X#else
  1323. X    (void) strcat(ofname, ".F");
  1324. X#endif                /* DOS */
  1325. X
  1326. X      }
  1327. X    /* Check for overwrite of existing file */
  1328. X      if (overwrite == 0 && topipe == 0) {
  1329. X    if (stat(ofname, &statbuf) == 0) {
  1330. X      char    response[2];
  1331. X      response[0] = 'n';
  1332. X      fprintf(stderr, "%s already exists;", ofname);
  1333. X#ifndef DOS
  1334. X      if (foreground()) {
  1335. X#endif
  1336. X        fprintf(stderr,
  1337. X          " do you wish to overwrite %s (y or n)? ", ofname);
  1338. X        (void) fflush(stderr);
  1339. X        (void) read(2, response, 2);
  1340. X        while (response[1] != '\n') {
  1341. X          if (read(2, response + 1, 1) < 0) {    /* Ack! */
  1342. X        perror("stderr");
  1343. X        break;
  1344. X          }
  1345. X        }
  1346. X#ifndef DOS
  1347. X      }
  1348. X#endif
  1349. X      if (response[0] != 'y') {
  1350. X        fprintf(stderr, "\tnot overwritten\n");
  1351. X        continue;
  1352. X      }
  1353. X    }
  1354. X      }
  1355. X      if (topipe == 0) {    /* Open output file */
  1356. X
  1357. X#ifdef DEBUG
  1358. X    if (do_melt == 0 || debug == 0) {
  1359. X#endif
  1360. X#ifdef DOS
  1361. X      if (freopen(ofname, do_melt && image == O_TEXT ? "wt" : "wb",
  1362. X          stdout) == NULL)
  1363. X#else
  1364. X      if (freopen(ofname, "w", stdout) == NULL)
  1365. X#endif
  1366. X      {
  1367. X        perror(ofname);
  1368. X        continue;
  1369. X      }
  1370. X#ifdef DEBUG
  1371. X    }
  1372. X#endif
  1373. X    precious = 0;
  1374. X    if (quiet != 1) {
  1375. X      fprintf(stderr, "%s:", *fileptr);
  1376. X      indc_count = 1024;
  1377. X    }
  1378. X      } else {            /* output is to stdout */
  1379. X#ifdef MSDOS
  1380. X      /* freeze output always binary; melt output is binary if image ==
  1381. X         O_BINARY */
  1382. X    if (do_melt == 0 || image == O_BINARY)
  1383. X      setmode(fileno(stdout), O_BINARY);
  1384. X#endif
  1385. X      }
  1386. X    /* Actually do the freezing/melting */
  1387. X      if (do_melt == 0)
  1388. X    freeze();
  1389. X#ifndef DEBUG
  1390. X      else
  1391. X    (*meltfunc) ();
  1392. X#else
  1393. X      else if (debug && verbose)
  1394. X    printcodes(meltfunc == (void (*) ()) melt2);
  1395. X      else
  1396. X    (*meltfunc) ();
  1397. X#endif                /* DEBUG */
  1398. X
  1399. X    /* check output status, and close to make sure data is written */
  1400. X      if (ferror(stdout) || (!topipe && fclose(stdout) < 0))
  1401. X    writeerr();
  1402. X
  1403. X      if (topipe == 0)
  1404. X    copystat(*fileptr);    /* Copy stats */
  1405. X      precious = 1;
  1406. X    }
  1407. X  } else {            /* Standard input */
  1408. XPipe:
  1409. X    if (fstat(fileno(stdin), &statbuf)) {
  1410. X      perror("stdin");
  1411. X      exit(1);
  1412. X    }
  1413. X    file_length = ((statbuf.st_mode & S_IFMT) == S_IFREG) ?
  1414. X    statbuf.st_size : 0;
  1415. X
  1416. X    indc_threshold = file_length / 100;
  1417. X    if (indc_threshold < 4096)
  1418. X      indc_threshold = 4096;
  1419. X    if (do_melt)
  1420. X      indc_threshold *= 3;
  1421. X
  1422. X    topipe = 1;
  1423. X    if (do_melt == 0) {
  1424. X#ifdef MSDOS
  1425. X    /* freeze output always binary */
  1426. X    /* freeze input controlled by -i -t -b switches */
  1427. X      setmode(fileno(stdout), O_BINARY);
  1428. X      setmode(fileno(stdin), image);
  1429. X#endif
  1430. X      freeze();
  1431. X      if (quiet != 1)
  1432. X    putc('\n', stderr);
  1433. X    } else {
  1434. X#ifdef MSDOS
  1435. X    /* melt input always binary */
  1436. X    /* melt output to stdout binary if so requested */
  1437. X      setmode(fileno(stdin), O_BINARY);
  1438. X      setmode(fileno(stdout), image);
  1439. X#endif
  1440. X    /* Check the magic number */
  1441. X      if (getchar() != MAGIC1)
  1442. X    goto badstdin;
  1443. X      switch (getchar()) {
  1444. X#ifdef COMPAT
  1445. X      case MAGIC2_1:
  1446. X    meltfunc = melt1;
  1447. X    break;
  1448. X#endif
  1449. X      case MAGIC2_2:
  1450. X    meltfunc = melt2;
  1451. X    break;
  1452. X      default:
  1453. X    badstdin:
  1454. X    fprintf(stderr, "stdin: not in frozen format\n");
  1455. X    exit(1);
  1456. X      }
  1457. X
  1458. X#ifndef DEBUG
  1459. X      (*meltfunc) ();
  1460. X#else
  1461. X      if (debug && verbose)
  1462. X    printcodes(meltfunc == (void (*) ()) melt2);
  1463. X      else
  1464. X    (*meltfunc) ();
  1465. X#endif                /* DEBUG */
  1466. X    }
  1467. X  }
  1468. X  exit(exit_stat);
  1469. X /* NOTREACHED */
  1470. X}
  1471. X
  1472. Xlong    in_count = 1;        /* length of input */
  1473. X
  1474. X/* Calculates and prints the compression ratio w/o floating point OPs */
  1475. X
  1476. Xvoid 
  1477. Xprratio(stream, was, is)
  1478. XFILE   *stream;
  1479. Xlong    was, is;
  1480. X{
  1481. X  register long q;        /* This works everywhere */
  1482. X
  1483. X  if (!is)
  1484. X    is++;
  1485. X
  1486. X  if (was > 214748L) {        /* 2147483647/10000 */
  1487. X    q = was / (is / 10000L);
  1488. X  } else {
  1489. X    q = 10000L * was / is;    /* Long calculations, though */
  1490. X  }
  1491. X  if (q < 0) {
  1492. X    putc('-', stream);
  1493. X    q = -q;
  1494. X  }
  1495. X  fprintf(stream, "%d.%02d%%", (int) (q / 100), (int) (q % 100));
  1496. X#ifdef GATHER_STAT
  1497. X  fprintf(stream, "(%ld / %ld)", was, is);
  1498. X#endif
  1499. X}
  1500. X/* Calculates and prints bits/byte compression ratio as above */
  1501. X
  1502. Xvoid 
  1503. Xprbits(stream, was, is)
  1504. XFILE   *stream;
  1505. Xlong    was, is;
  1506. X{
  1507. X  register long q;
  1508. X
  1509. X  if (!was)
  1510. X    was++;
  1511. X
  1512. X  if (is > 2684354L) {        /* 2147483647/800 */
  1513. X    q = is / (was / 800L);
  1514. X  } else {
  1515. X    q = 800L * is / was;
  1516. X  }
  1517. X  fprintf(stream, " (%d.%02d bits)", (int) (q / 100), (int) (q % 100));
  1518. X}
  1519. X/* There was an error when reading or writing files */
  1520. X
  1521. Xvoid 
  1522. Xwriteerr()
  1523. X{
  1524. X  if (!topipe) {
  1525. X    perror(ofname);
  1526. X    (void) unlink(ofname);
  1527. X  }
  1528. X  exit(1);
  1529. X}
  1530. X
  1531. Xvoid 
  1532. Xcopystat(ifname)
  1533. Xchar   *ifname;
  1534. X{
  1535. X#ifdef __TURBOC__
  1536. X  struct ftime utimbuf;
  1537. X#else
  1538. X#ifdef UTIMES
  1539. X  struct timeval timep[2];
  1540. X#else
  1541. X  struct utimbuf timep;
  1542. X#endif
  1543. X#endif
  1544. X
  1545. X  int     mode;
  1546. X
  1547. X#ifdef MSDOS
  1548. X  if (_osmajor < 3)
  1549. X    freopen("CON", "at", stdout);
  1550. X  else                /* MS-DOS 2.xx bug */
  1551. X# endif
  1552. X
  1553. X    (void) fclose(stdout);
  1554. X
  1555. X  if (exit_stat == 2 && (!force)) {    /* No freezing: remove file.F */
  1556. X
  1557. X    if (quiet != 1)
  1558. X      fprintf(stderr, "-- file unchanged\n");
  1559. X
  1560. X  } else {            /* ***** Successful Freezing ***** */
  1561. X
  1562. X    if (stat(ifname, &statbuf)) {    /* file disappeared ?! */
  1563. X      perror(ifname);
  1564. X      exit_stat = 1;
  1565. X      return;
  1566. X    }
  1567. X    exit_stat = 0;
  1568. X
  1569. X#ifdef TOS
  1570. X
  1571. X    Fattrib(ofname, 1, Fattrib(ifname, 0, 0));
  1572. X
  1573. X#else
  1574. X    mode = statbuf.st_mode & 07777;
  1575. X    if (chmod(ofname, mode))    /* Copy modes */
  1576. X      perror(ofname);
  1577. X#endif
  1578. X#ifndef DOS
  1579. X  /* Copy ownership */
  1580. X    (void) chown(ofname, (int) statbuf.st_uid, (int) statbuf.st_gid);
  1581. X#endif
  1582. X
  1583. X#ifdef __TURBOC__
  1584. X    getftime(fileno(stdin), &utimbuf);
  1585. X    freopen(ofname, "rb", stdout);
  1586. X    setftime(fileno(stdout), &utimbuf);
  1587. X    (void) fclose(stdout);
  1588. X#else
  1589. X#ifdef UTIMES
  1590. X    timep[0].tv_sec = statbuf.st_atime;
  1591. X    timep[1].tv_sec = statbuf.st_mtime;
  1592. X    timep[0].tv_usec = timep[1].tv_usec = 0;
  1593. X    (void) utimes(ofname, timep);
  1594. X#else
  1595. X    timep.actime = statbuf.st_atime;
  1596. X    timep.modtime = statbuf.st_mtime;
  1597. X
  1598. X#if defined(__m88k__)
  1599. X    timep.acusec = statbuf.st_ausec;    /* pa@verano */
  1600. X    timep.modusec = statbuf.st_musec;
  1601. X#endif                /* !m88k */
  1602. X
  1603. X  /* Update last accessed and modified times */
  1604. X    (void) utime(ofname, &timep);
  1605. X#endif                /* UTIMES */
  1606. X#endif                /* __TURBOC__ */
  1607. X    if (unlink(ifname))        /* Remove input file */
  1608. X      perror(ifname);
  1609. X    if (quiet != 1)
  1610. X      fprintf(stderr, " -- replaced with %s\n", ofname);
  1611. X    return;            /* Successful return */
  1612. X  }
  1613. X
  1614. X /* Unsuccessful return -- one of the tests failed */
  1615. X  if (unlink(ofname))
  1616. X    perror(ofname);
  1617. X}
  1618. X/* Checks status of a file, returns 0 if the file may be frozen,
  1619. X    or 1 otherwise; assigns this value to exit_stat
  1620. X*/
  1621. Xint 
  1622. Xcheckstat(ifname)
  1623. Xchar   *ifname;
  1624. X{
  1625. X  if (stat(ifname, &statbuf)) {
  1626. X    perror(ifname);
  1627. X    return exit_stat = 1;
  1628. X  }
  1629. X /* Do NOT try to freeze /dev/null or /dev/tty...   */
  1630. X /* but you may freeze or melt everything to stdout */
  1631. X
  1632. X#ifndef DOS
  1633. X  if (!topipe) {
  1634. X    if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
  1635. X      fprintf(stderr, "%s: ", ifname);
  1636. X      fprintf(stderr, " not a regular file -- unchanged\n");
  1637. X      return exit_stat = 1;
  1638. X
  1639. X    } else if (statbuf.st_nlink > 1) {
  1640. X      fprintf(stderr, "%s: ", ifname);
  1641. X      fprintf(stderr, " has %d other links -- unchanged\n",
  1642. X    statbuf.st_nlink - 1);
  1643. X      return exit_stat = 1;
  1644. X    }
  1645. X  }
  1646. X#endif                /* MSDOS */
  1647. X
  1648. X  file_length = statbuf.st_size;
  1649. X
  1650. X  indc_threshold = file_length / 100;
  1651. X  if (indc_threshold < 4096)
  1652. X    indc_threshold = 4096;
  1653. X  if (do_melt)
  1654. X    indc_threshold *= 3;
  1655. X
  1656. X  return exit_stat = 0;
  1657. X}
  1658. X#ifndef DOS
  1659. X/*
  1660. X * This routine returns 1 if we are running in the foreground and stderr
  1661. X * is a tty. (as in compress(1))
  1662. X */
  1663. Xint 
  1664. Xforeground()
  1665. X{
  1666. X  if (bgnd_flag != SIG_DFL)    /* background? */
  1667. X    return (0);
  1668. X  else {            /* foreground */
  1669. X    if (isatty(2)) {        /* and stderr is a tty */
  1670. X      return (1);
  1671. X    } else {
  1672. X      return (0);
  1673. X    }
  1674. X  }
  1675. X}
  1676. X#endif
  1677. X
  1678. X/* Exception handler (SIGINT) */
  1679. X
  1680. XRETSIGTYPE
  1681. Xonintr()
  1682. X{
  1683. X  if (!precious) {        /* topipe == 1 implies precious == 1 */
  1684. X    (void) fclose(stdout);
  1685. X    (void) unlink(ofname);
  1686. X  }
  1687. X  exit(1);
  1688. X}
  1689. X/* Exception handler (SIGSEGV) */
  1690. X
  1691. XRETSIGTYPE
  1692. Xoops()
  1693. X{                /* file is corrupt or internal error */
  1694. X  (void) fflush(stdout);
  1695. X  fprintf(stderr, "Segmentation violation occured (this shouldn't happen)\n");
  1696. X  exit(1);
  1697. X}
  1698. X/* Prints version and compilation options */
  1699. X
  1700. Xvoid 
  1701. Xversion()
  1702. X{
  1703. X  fprintf(stderr, ident, PATCHLEVEL, PATCHDATE);
  1704. X  fprintf(stderr, "LZSS 8192/256 + Huffman coding\nOptions: ");
  1705. X#ifdef COMPAT
  1706. X  fprintf(stderr, "compatible with vers. 1.0, ");
  1707. X#endif
  1708. X#ifdef DEBUG
  1709. X  fprintf(stderr, "DEBUG, ");
  1710. X#endif
  1711. X#if defined(SMALL) || defined(TINY)
  1712. X  fprintf(stderr, "SMALL, ");
  1713. X#endif
  1714. X#ifdef ALLOW_MISALIGN
  1715. X  fprintf(stderr, "ALLOW_MISALIGN, ");
  1716. X#endif
  1717. X#ifdef GATHER_STAT
  1718. X  fprintf(stderr, "GATHER_STAT, ");
  1719. X#endif
  1720. X  fprintf(stderr, "HASH: %d bits\n", BITS);
  1721. X  fprintf(stderr, "Static Huffman table: %d %d %d %d %d %d %d %d\n",
  1722. X    Table2[1], Table2[2], Table2[3], Table2[4],
  1723. X    Table2[5], Table2[6], Table2[7], Table2[8]);
  1724. X#ifdef DOS
  1725. X  fprintf(stderr, "Default melted mode: %s\n",
  1726. X    image == O_BINARY ? "binary" : "text");
  1727. X#endif
  1728. X  exit(0);
  1729. X}
  1730. X/* Deals with static Huffman table parameters.
  1731. X    Input: command line option w/o leading `+' or `--'.
  1732. X    Output: fills the array `Table2' if OK, exit(1) otherwise.
  1733. X*/
  1734. X
  1735. Xvoid 
  1736. Xtune_table(type)
  1737. Xchar   *type;
  1738. X{
  1739. X  extern char *defread();
  1740. X  register char *s = defread(type), *t;
  1741. X  static int v[8];
  1742. X  int     i, is_list = 0;
  1743. X  if (!s) {
  1744. X  /* try to consider 'type' as a list of values: n1,n2, ... */
  1745. X    if (strrchr(type, ','))
  1746. X      is_list = 1;
  1747. X    else {
  1748. X      fprintf(stderr, "\"%s\" - no such file type\n", type);
  1749. X      exit(1);
  1750. X    }
  1751. X    if (sscanf(type, "%d,%d,%d,%d,%d,%d,%d,%d",
  1752. X    v, v + 1, v + 2, v + 3, v + 4, v + 5, v + 6, v + 7) != 8) {
  1753. X      fprintf(stderr,
  1754. X    "%s - a list of 8 numbers expected\n", type);
  1755. X      exit(1);
  1756. X    }
  1757. X  }
  1758. X
  1759. X  /* both space-separated and comma-separated lists are allowed */
  1760. X
  1761. X  if (!is_list && (!(t = strrchr(s, '=')) ||
  1762. X      sscanf(++t, "%d %d %d %d %d %d %d %d",
  1763. X    v, v + 1, v + 2, v + 3, v + 4, v + 5, v + 6, v + 7) != 8 &&
  1764. X      sscanf(t, "%d,%d,%d,%d,%d,%d,%d,%d",
  1765. X    v, v + 1, v + 2, v + 3, v + 4, v + 5, v + 6, v + 7) != 8)) {
  1766. X    fprintf(stderr,
  1767. X      "\"%s\" - invalid entry\n", type);
  1768. X    exit(1);
  1769. X  }
  1770. X  for (i = 0; i < 8; i++)
  1771. X    Table2[i + 1] = v[i];
  1772. X  if (quiet < 0) {
  1773. X    if (!is_list) {
  1774. X      t = s;
  1775. X    /* make full word */
  1776. X      while (*s != '=' && *s != ' ' && *s != '\t')
  1777. X    s++;
  1778. X      *s = '\0';
  1779. X    } else
  1780. X      t = "";
  1781. X    fprintf(stderr, "Using \"%s%s\" type\n", type, t);
  1782. X  }
  1783. X}
  1784. X#ifdef DOS
  1785. X
  1786. X/* MSDOS typically has ':' and '\\' separators, but some command
  1787. X  processors (and the int 21h function handler) support '/' too.
  1788. X  Find the last of these.
  1789. X*/
  1790. X
  1791. Xchar   *
  1792. Xlast_sep(s)
  1793. Xregister char *s;
  1794. X{
  1795. X  char   *p;
  1796. X  for (p = NULL; *s; s++)
  1797. X    if (*s == '/' || *s == '\\' || *s == ':')
  1798. X      p = s;
  1799. X  return (p);
  1800. X}
  1801. X#endif                /* DOS */
  1802. END_OF_FILE
  1803.   if test 24625 -ne `wc -c <'freeze.c'`; then
  1804.     echo shar: \"'freeze.c'\" unpacked with wrong size!
  1805.   fi
  1806.   # end of 'freeze.c'
  1807. fi
  1808. if test -f 'lz.c' -a "${1}" != "-c" ; then 
  1809.   echo shar: Will not clobber existing file \"'lz.c'\"
  1810. else
  1811.   echo shar: Extracting \"'lz.c'\" \(3979 characters\)
  1812.   sed "s/^X//" >'lz.c' <<'END_OF_FILE'
  1813. X#include "freeze.h"
  1814. X#include "lz.h"
  1815. X
  1816. X/*----------------------------------------------------------------------*/
  1817. X/*                                                                      */
  1818. X/*                          LZSS ENCODING                               */
  1819. X/*                                                                      */
  1820. X/*----------------------------------------------------------------------*/
  1821. X
  1822. Xuc_t    text_buf[WINSIZE + LOOKAHEAD - 1];/* cyclic buffer with an overlay */
  1823. Xint     match_position;                 /* current position of
  1824. X                        matched pattern */
  1825. Xint     chain_length;                   /* max_chain_length ==
  1826. X                        CHAIN_THRESHOLD >> greedy */
  1827. X
  1828. X/*      next[N+1..] is used as hash table,
  1829. X    the rest of next is a link down,
  1830. X*/
  1831. X
  1832. Xhash_t hashtab[hash_size];      /* a VERY large array :-) */
  1833. Xhash_t next[WINSIZE];
  1834. X
  1835. X#ifdef GATHER_STAT
  1836. Xlong node_matches, node_compares, node_prolongations;
  1837. X#endif  /* GATHER_STAT */
  1838. X
  1839. X/* Initialize the data structures and allocate memory, if needed.
  1840. X    Although there is no more trees in the LZ algorithm
  1841. X    implementation, routine name is kept intact :-)
  1842. X*/
  1843. X
  1844. Xvoid InitTree ()
  1845. X{
  1846. X
  1847. X    unsigned i = 0;
  1848. X#ifdef GATHER_STAT
  1849. X    node_matches = node_compares = node_prolongations = 0;
  1850. X#endif  /* GATHER_STAT */
  1851. X
  1852. X    do {
  1853. X        hashtab[i] = 0;
  1854. X    } while (i++ != hash_size - 1);
  1855. X
  1856. X    if (greedy >= 0)
  1857. X        chain_length = ((CHAIN_THRESHOLD - 1) >> greedy) + 1;
  1858. X    else
  1859. X        chain_length = LOOKAHEAD * 2;
  1860. X}
  1861. X
  1862. X/* Get the longest (longer than `match_length' when entering in function)
  1863. X    nearest match of the string beginning in text_buf[r]
  1864. X    to the cyclic buffer. Result (length & position) is returned
  1865. X    as the result and in global variable
  1866. X    `match_position'). Unchanged `match_length' denotes failure and
  1867. X    `match_position' contains garbage !!
  1868. X    In order to achieve faster operation, `match_length' is shifted
  1869. X    down to LOOKAHEAD. Ideas of Andrew Cadach <kadach@isi.itfs.nsk.su>
  1870. X    have been used (lastbyte).
  1871. X*/
  1872. X
  1873. Xint get_next_match (match_length, r)
  1874. X    register hash_t r; int match_length;
  1875. X{
  1876. X    register hash_t p = r & WINMASK;
  1877. X    register int m;
  1878. X#ifdef ALLOW_MISALIGN
  1879. X    register us_t lastbyte;
  1880. X#else
  1881. X    register uc_t lastbyte;
  1882. X#endif
  1883. X    register uc_t  *key FIX_SI, *pattern FIX_DI;
  1884. X    int     chain_count = chain_length;
  1885. X
  1886. X#ifdef GATHER_STAT
  1887. X    node_matches++;
  1888. X#endif
  1889. X    key = text_buf + (r & WINMASK) + LOOKAHEAD;
  1890. X    r -= MAXDIST;           /* `r' is now a "barrier value" */
  1891. X
  1892. X    for(;;) {
  1893. X        lastbyte = FETCH(key, match_length);
  1894. X        do {
  1895. X            if(chain_count <= 0)
  1896. X                /* chain length exceeded, simple return */
  1897. X                return match_length;
  1898. X
  1899. X            pattern = text_buf + match_length + LOOKAHEAD;
  1900. X
  1901. X            do {
  1902. X                if ((p = next[p]) < r)
  1903. X                    return match_length;
  1904. X            } while (FETCH(pattern, p &= WINMASK) != lastbyte);
  1905. X
  1906. X            chain_count--;  /* successful lastbyte match, cost = 1 */
  1907. X            pattern = text_buf + p + LOOKAHEAD;
  1908. X
  1909. X#ifdef GATHER_STAT
  1910. X        node_compares++;
  1911. X#endif
  1912. X
  1913. X#ifdef ALLOW_MISALIGN
  1914. X            for (m = -LOOKAHEAD;
  1915. X            *(unsigned*)&key[m] == *(unsigned*)&pattern[m] &&
  1916. X                (m += sizeof(unsigned)) < 0;);
  1917. X#ifndef INT_16_BITS
  1918. X        /* Hope that sizeof(int) > 2 ==> sizeof(int) > sizeof(short) */
  1919. X            if (m < 0 && *(us_t*)&key[m] == *(us_t*)&pattern[m])
  1920. X                m += sizeof(us_t);
  1921. X#endif
  1922. X#ifdef BIGSHORTS
  1923. X            while
  1924. X#else
  1925. X            if
  1926. X#endif
  1927. X                (m < 0 && key[m] == pattern[m])
  1928. X                    ++m;
  1929. X#else
  1930. X            for (m = -LOOKAHEAD; key[m] == pattern[m] && ++m < 0;);
  1931. X#endif
  1932. X        } while (m < match_length);
  1933. X
  1934. X        match_position = p;     /* remember new results */
  1935. X        if (m == 0)
  1936. X            return 0;
  1937. X        match_length = m;
  1938. X
  1939. X#ifdef GATHER_STAT
  1940. X        node_prolongations++;
  1941. X#endif
  1942. X        chain_count -= 2;       /* yet another match found, cost = 2 */
  1943. X    }
  1944. X}
  1945. X
  1946. Xhash_t
  1947. Xrehash(r)
  1948. Xhash_t r;
  1949. X{
  1950. X  unsigned i = 0;
  1951. X  r += WINSIZE;
  1952. X  do {
  1953. X    /* process links; zero must remain zero */
  1954. X    if (next[i] && (next[i] += WINSIZE) > r) {
  1955. X        next[i] = 0;
  1956. X    }
  1957. X  } while(i++ != WINSIZE - 1);
  1958. X  i = 0;
  1959. X  do {
  1960. X    /* process the hash table itself; zero must remain zero */
  1961. X    if (hashtab[i] && (hashtab[i] += WINSIZE) > r)
  1962. X        hashtab[i] = 0;
  1963. X  } while (i++ != hash_size - 1);
  1964. X  return r;
  1965. X}
  1966. END_OF_FILE
  1967.   if test 3979 -ne `wc -c <'lz.c'`; then
  1968.     echo shar: \"'lz.c'\" unpacked with wrong size!
  1969.   fi
  1970.   # end of 'lz.c'
  1971. fi
  1972. echo shar: End of archive 1 \(of 3\).
  1973. cp /dev/null ark1isdone
  1974. MISSING=""
  1975. for I in 1 2 3 ; do
  1976.     if test ! -f ark${I}isdone ; then
  1977.     MISSING="${MISSING} ${I}"
  1978.     fi
  1979. done
  1980. if test "${MISSING}" = "" ; then
  1981.     echo You have unpacked all 3 archives.
  1982.     rm -f ark[1-9]isdone
  1983. else
  1984.     echo You still must unpack the following archives:
  1985.     echo "        " ${MISSING}
  1986. fi
  1987. exit 0
  1988. exit 0 # Just in case...
  1989.