Include libom in the subdirectory list.
[unix-history] / usr / src / usr.bin / compress / compress.c
CommitLineData
64d06f2f
KM
1#ifndef lint
2static char sccsid[] = "@(#)compress.c 5.1 (Berkeley) %G%";
3#endif not lint
4
5/*
6 * Set USERMEM to the maximum amount of physical user memory available
7 * in bytes. USERMEM is used to determine the maximum BITS that can be used
8 * for compression. If USERMEM is big enough, use fast compression algorithm.
9 *
10 * SACREDMEM is the amount of physical memory saved for others; compress
11 * will hog the rest.
12 */
13#ifndef SACREDMEM
14#define SACREDMEM 0
15#endif
16
17#ifdef pdp11
18# define BITS 12 /* max bits/code for 16-bit machine */
19# define NO_UCHAR /* also if "unsigned char" functions as signed char */
20# undef USERMEM
21#else !pdp11
22# ifndef USERMEM
23# define USERMEM 750000 /* default user memory */
24# endif
25#endif !pdp11
26/*
27 * Define FBITS for machines with several MB of physical memory, to use
28 * table lookup for (b <= FBITS). If FBITS is made too large, performance
29 * will decrease due to increased swapping/paging. Since the program minus
30 * the fast lookup table is about a half Meg, we can allocate the rest of
31 * available physical memory to the fast lookup table.
32 *
33 * If FBITS is set to 12, a 2 MB array is allocated, but only 1 MB is
34 * addressed for parity-free input (i.e. text).
35 *
36 * FBITS=10 yields 1/2 meg lookup table + 4K code memory
37 * FBITS=11 yields 1 meg lookup table + 8K code memory
38 * FBITS=12 yields 2 meg lookup table + 16K code memory
39 * FBITS=13 yields 4 meg lookup table + 32K code memory
40 *
41 */
42
43#ifdef USERMEM
44# if USERMEM >= (2621440+SACREDMEM)
45# if USERMEM >= (4718592+SACREDMEM)
46# define FBITS 13
47# define PBITS 16
48# else 2.5M <= USERMEM < 4.5M
49# define FBITS 12
50# define PBITS 16
51# endif USERMEM <=> 4.5M
52# else USERMEM < 2.5M
53# if USERMEM >= (1572864+SACREDMEM)
54# define FBITS 11
55# define PBITS 16
56# else USERMEM < 1.5M
57# if USERMEM >= (1048576+SACREDMEM)
58# define FBITS 10
59# define PBITS 16
60# else USERMEM < 1M
61# if USERMEM >= (631808+SACREDMEM)
62# define PBITS 16
63# else
64# if USERMEM >= (329728+SACREDMEM)
65# define PBITS 15
66# else
67# if USERMEM >= (178176+SACREDMEM)
68# define PBITS 14
69# else
70# if USERMEM >= (99328+SACREDMEM)
71# define PBITS 13
72# else
73# define PBITS 12
74# endif
75# endif
76# endif
77# endif
78# undef USERMEM
79# endif USERMEM <=> 1M
80# endif USERMEM <=> 1.5M
81# endif USERMEM <=> 2.5M
82#endif USERMEM
83
84#ifdef PBITS /* Preferred BITS for this memory size */
85# ifndef BITS
86# define BITS PBITS
87# endif BITS
88#endif PBITS
89
90#if BITS == 16
91# define HSIZE 69001 /* 95% occupancy */
92#endif
93#if BITS == 15
94# define HSIZE 35023 /* 94% occupancy */
95#endif
96#if BITS == 14
97# define HSIZE 18013 /* 91% occupancy */
98#endif
99#if BITS == 13
100# define HSIZE 9001 /* 91% occupancy */
101#endif
102#if BITS == 12
103# define HSIZE 5003 /* 80% occupancy */
104#endif
105#if BITS == 11
106# define HSIZE 2591 /* 79% occupancy */
107#endif
108#if BITS == 10
109# define HSIZE 1291 /* 79% occupancy */
110#endif
111#if BITS == 9
112# define HSIZE 691 /* 74% occupancy */
113#endif
114/* BITS < 9 will cause an error */
115
116/*
117 * a code_int must be able to hold 2**BITS values of type int, and also -1
118 */
119#if BITS > 15
120typedef long int code_int;
121#else
122typedef int code_int;
123#endif
124
125#ifdef interdata
126typedef unsigned long int count_int;
127typedef unsigned short int count_short;
128#else
129typedef long int count_int;
130#endif
131
132#ifdef NO_UCHAR
133 typedef char char_type;
134#else UCHAR
135 typedef unsigned char char_type;
136#endif UCHAR
137char_type magic_header[] = { "\037\235" }; /* 1F 9D */
138
139/* Defines for third byte of header */
140#define BIT_MASK 0x1f
141#define BLOCK_MASK 0x80
142/* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
143 a fourth header byte (for expansion).
144*/
145#define INIT_BITS 9 /* initial number of bits/code */
146
147/*
148 * compress.c - File compression ala IEEE Computer June 1984.
149 *
150 * Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
151 * Jim McKie (decvax!mcvax!jim)
152 * Steve Davies (decvax!vax135!petsd!peora!srd)
153 * Ken Turkowski (decvax!decwrl!turtlevax!ken)
154 * James A. Woods (decvax!ihnp4!ames!jaw)
155 * Joe Orost (decvax!vax135!petsd!joe)
156 *
157 * $Header: compress.c,v 3.0 84/11/27 11:50:00 joe Exp $
158 * $Log: compress.c,v $
159 * Revision 3.0 84/11/27 11:50:00 petsd!joe
160 * Set HSIZE depending on BITS. Set BITS depending on USERMEM. Unrolled
161 * loops in clear routines. Added "-C" flag for 2.0 compatability. Used
162 * unsigned compares on Perkin-Elmer. Fixed foreground check.
163 *
164 * Revision 2.7 84/11/16 19:35:39 ames!jaw
165 * Cache common hash codes based on input statistics; this improves
166 * performance for low-density raster images. Pass on #ifdef bundle
167 * from Turkowski.
168 *
169 * Revision 2.6 84/11/05 19:18:21 ames!jaw
170 * Vary size of hash tables to reduce time for small files.
171 * Tune PDP-11 hash function.
172 *
173 * Revision 2.5 84/10/30 20:15:14 ames!jaw
174 * Junk chaining; replace with the simpler (and, on the VAX, faster)
175 * double hashing, discussed within. Make block compression standard.
176 *
177 * Revision 2.4 84/10/16 11:11:11 ames!jaw
178 * Introduce adaptive reset for block compression, to boost the rate
179 * another several percent. (See mailing list notes.)
180 *
181 * Revision 2.3 84/09/22 22:00:00 petsd!joe
182 * Implemented "-B" block compress. Implemented REVERSE sorting of tab_next.
183 * Bug fix for last bits. Changed fwrite to putchar loop everywhere.
184 *
185 * Revision 2.2 84/09/18 14:12:21 ames!jaw
186 * Fold in news changes, small machine typedef from thomas,
187 * #ifdef interdata from joe.
188 *
189 * Revision 2.1 84/09/10 12:34:56 ames!jaw
190 * Configured fast table lookup for 32-bit machines.
191 * This cuts user time in half for b <= FBITS, and is useful for news batching
192 * from VAX to PDP sites. Also sped up decompress() [fwrite->putc] and
193 * added signal catcher [plus beef in writeerr()] to delete effluvia.
194 *
195 * Revision 2.0 84/08/28 22:00:00 petsd!joe
196 * Add check for foreground before prompting user. Insert maxbits into
197 * compressed file. Force file being uncompressed to end with ".Z".
198 * Added "-c" flag and "zcat". Prepared for release.
199 *
200 * Revision 1.10 84/08/24 18:28:00 turtlevax!ken
201 * Will only compress regular files (no directories), added a magic number
202 * header (plus an undocumented -n flag to handle old files without headers),
203 * added -f flag to force overwriting of possibly existing destination file,
204 * otherwise the user is prompted for a response. Will tack on a .Z to a
205 * filename if it doesn't have one when decompressing. Will only replace
206 * file if it was compressed.
207 *
208 * Revision 1.9 84/08/16 17:28:00 turtlevax!ken
209 * Removed scanargs(), getopt(), added .Z extension and unlimited number of
210 * filenames to compress. Flags may be clustered (-Ddvb12) or separated
211 * (-D -d -v -b 12), or combination thereof. Modes and other status is
212 * copied with copystat(). -O bug for 4.2 seems to have disappeared with
213 * 1.8.
214 *
215 * Revision 1.8 84/08/09 23:15:00 joe
216 * Made it compatible with vax version, installed jim's fixes/enhancements
217 *
218 * Revision 1.6 84/08/01 22:08:00 joe
219 * Sped up algorithm significantly by sorting the compress chain.
220 *
221 * Revision 1.5 84/07/13 13:11:00 srd
222 * Added C version of vax asm routines. Changed structure to arrays to
223 * save much memory. Do unsigned compares where possible (faster on
224 * Perkin-Elmer)
225 *
226 * Revision 1.4 84/07/05 03:11:11 thomas
227 * Clean up the code a little and lint it. (Lint complains about all
228 * the regs used in the asm, but I'm not going to "fix" this.)
229 *
230 * Revision 1.3 84/07/05 02:06:54 thomas
231 * Minor fixes.
232 *
233 * Revision 1.2 84/07/05 00:27:27 thomas
234 * Add variable bit length output.
235 *
236 */
237#ifndef lint
238static char rcs_ident[] = "$Header: compress.c,v 3.0 84/11/27 11:50:00 joe Exp$";
239#endif !lint
240
241#include <stdio.h>
242#include <ctype.h>
243#include <signal.h>
244#include <sys/types.h>
245#include <sys/stat.h>
246
247#define ARGVAL() (*++(*argv) || (--argc && *++argv))
248
249int n_bits; /* number of bits/code */
250int maxbits = BITS; /* user settable max # bits/code */
251code_int maxcode; /* maximum code, given n_bits */
252code_int maxmaxcode = 1 << BITS; /* should NEVER generate this code */
253#ifdef COMPATIBLE /* But wrong! */
254# define MAXCODE(n_bits) (1 << (n_bits) - 1)
255#else COMPATIBLE
256# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
257#endif COMPATIBLE
258
259/*
260 * One code could conceivably represent (1<<BITS) characters, but
261 * to get a code of length N requires an input string of at least
262 * N*(N-1)/2 characters. With 5000 chars in the stack, an input
263 * file would have to contain a 25Mb string of a single character.
264 * This seems unlikely.
265 */
266#ifdef pdp11
267# define MAXSTACK 5000 /* size of output stack */
268#else !pdp11
269# define MAXSTACK 8000 /* size of output stack */
270#endif !pdp11
271
272count_int htab [HSIZE];
273unsigned short codetab [HSIZE];
274code_int hsize = HSIZE; /* for dynamic table sizing */
275count_int fsize;
276
277#define tab_prefix codetab /* prefix code for this entry */
278char_type tab_suffix[1<<BITS]; /* last char in this entry */
279
280#ifdef USERMEM
281short ftable [(1 << FBITS) * 256];
282count_int fcodemem [1 << FBITS];
283#endif USERMEM
284
285code_int free_ent = 0; /* first unused entry */
286int exit_stat = 0;
287
288code_int getcode();
289
290Usage() {
291#ifdef DEBUG
292fprintf(stderr,"Usage: compress [-dDvqfFc] [-b maxbits] [file ...]\n");
293}
294int debug = 0;
295#else DEBUG
296fprintf(stderr,"Usage: compress [-dfFqc] [-b maxbits] [file ...]\n");
297}
298#endif DEBUG
299int nomagic = 0; /* Use a 2 byte magic number header, unless old file */
300int zcat_flg = 0; /* Write output on stdout, suppress messages */
301int quiet = 0; /* don't tell me about compression */
302
303/*
304 * block compression parameters -- after all codes are used up,
305 * and compression rate changes, start over.
306 */
307int block_compress = BLOCK_MASK;
308int clear_flg = 0;
309double ratio = 0.0; /* compression ratio for last block */
310#define CHECK_GAP 10000 /* ratio check interval */
311count_int checkpoint = CHECK_GAP;
312/*
313 * the next two codes should not be changed lightly, as they must not
314 * lie within the contiguous general code space.
315 */
316#define FIRST 257 /* first free entry */
317#define CLEAR 256 /* table clear output code */
318
319int force = 0;
320char ofname [100];
321#ifdef DEBUG
322int verbose = 0;
323#endif DEBUG
324int (*bgnd_flag)();
325
326/*****************************************************************
327 * TAG( main )
328 *
329 * Algorithm from "A Technique for High Performance Data Compression",
330 * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
331 *
332 * Usage: compress [-dfFqc] [-b bits] [file ...]
333 * Inputs:
334 * -d: If given, decompression is done instead.
335 *
336 * -c: Write output on stdout, don't remove original.
337 *
338 * -b: Parameter limits the max number of bits/code.
339 *
340 * -f: Forces output file to be generated, even if one already
341 * exists; if -f is not used, the user will be prompted if
342 * the stdin is a tty, otherwise, the output file will not
343 * be overwritten.
344 *
345 * -F: Forces output file to be generated, even if no space is
346 * saved by compressing.
347 *
348 * -q: No output, unless error
349 *
350 * file ...: Files to be compressed. If none specified, stdin
351 * is used.
352 * Outputs:
353 * file.Z: Compressed form of file with same mode, owner, and utimes
354 * or stdout (if stdin used as input)
355 *
356 * Assumptions:
357 * When filenames are given, replaces with the compressed version
358 * (.Z suffix) only if the file decreased in size.
359 * Algorithm:
360 * Modified Lempel-Ziv method (LZW). Basically finds common
361 * substrings and replaces them with a variable size code. This is
362 * deterministic, and can be done on the fly. Thus, the decompression
363 * procedure needs no input table, but tracks the way the table was
364 * built.
365 */
366
367main( argc, argv )
368register int argc; char **argv;
369{
370 int do_decomp = 0;
371 int overwrite = 0; /* Do not overwrite unless given -f flag */
372 char tempname[100];
373 char **filelist, **fileptr;
374 char *cp, *rindex();
375 struct stat statbuf;
376 extern onintr();
377
378
379 if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN )
380 signal ( SIGINT, onintr );
381
382#ifdef COMPATIBLE
383 nomagic = 1; /* Original didn't have a magic number */
384#endif COMPATIBLE
385
386 filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
387 *filelist = NULL;
388
389 if((cp = rindex(argv[0], '/')) != 0) {
390 cp++;
391 } else {
392 cp = argv[0];
393 }
394 if(strcmp(cp, "uncompress") == 0) {
395 do_decomp = 1;
396 } else if(strcmp(cp, "zcat") == 0) {
397 do_decomp = 1;
398 zcat_flg = 1;
399 }
400
401#ifdef BSD4_2
402 /* 4.2BSD dependent - take it out if not */
403 setlinebuf( stderr );
404#endif BSD4_2
405
406 /* Argument Processing
407 * All flags are optional.
408 * -D => debug
409 * -d => do_decomp
410 * -v => verbose
411 * -f => force overwrite of output file
412 * -n => no header: useful to uncompress old files
413 * -b maxbits => maxbits. If -b is specified, then maxbits MUST be
414 * given also.
415 * -c => cat all output to stdout
416 * -C => generate output compatable with compress 2.0.
417 * if a string is left, must be an input filename.
418 */
419 for (argc--, argv++; argc > 0; argc--, argv++) {
420 if (**argv == '-') { /* A flag argument */
421 while (*++(*argv)) { /* Process all flags in this arg */
422 switch (**argv) {
423#ifdef DEBUG
424 case 'D':
425 debug = 1;
426 break;
427 case 'v':
428 verbose = 1;
429 break;
430#endif DEBUG
431 case 'd':
432 do_decomp = 1;
433 break;
434 case 'f':
435 overwrite = 1;
436 break;
437 case 'n':
438 nomagic = 1;
439 break;
440 case 'C':
441 block_compress = 0;
442 break;
443 case 'b':
444 if (!ARGVAL()) {
445 fprintf(stderr, "Missing maxbits\n");
446 Usage();
447 exit(1);
448 }
449 maxbits = atoi(*argv);
450 goto nextarg;
451 case 'c':
452 zcat_flg = 1;
453 break;
454 case 'q':
455 quiet = 1;
456 break;
457 case 'F':
458 force = 1;
459 break;
460 default:
461 fprintf(stderr, "Unknown flag: '%c'; ", **argv);
462 Usage();
463 exit(1);
464 }
465 }
466 }
467 else { /* Input file name */
468 *fileptr++ = *argv; /* Build input file list */
469 *fileptr = NULL;
470 /* goto nextarg; */
471 }
472 nextarg: continue;
473 }
474
475 if(maxbits < INIT_BITS) maxbits = INIT_BITS;
476 if (maxbits > BITS) maxbits = BITS;
477 maxmaxcode = 1 << maxbits;
478
479 if (*filelist != NULL) {
480 for (fileptr = filelist; *fileptr; fileptr++) {
481 exit_stat = 0;
482 if (do_decomp != 0) { /* DECOMPRESSION */
483 /* Check for .Z suffix */
484 if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) {
485 /* No .Z: tack one on */
486 strcpy(tempname, *fileptr);
487 strcat(tempname, ".Z");
488 *fileptr = tempname;
489 }
490 /* Open input file */
491 if ((freopen(*fileptr, "r", stdin)) == NULL) {
492 perror(*fileptr); continue;
493 }
494 /* Check the magic number */
495 if (nomagic == 0) {
496 if ((getchar() != (magic_header[0] & 0xFF))
497 || (getchar() != (magic_header[1] & 0xFF))) {
498 fprintf(stderr, "%s: not in compressed format\n",
499 *fileptr);
500 continue;
501 }
502 maxbits = getchar(); /* set -b from file */
503 block_compress = maxbits & BLOCK_MASK;
504 maxbits &= BIT_MASK;
505 maxmaxcode = 1 << maxbits;
506 if(maxbits > BITS) {
507 fprintf(stderr,
508 "%s: compressed with %d bits, can only handle %d bits\n",
509 *fileptr, maxbits, BITS);
510 continue;
511 }
512 }
513 /* Generate output filename */
514 strcpy(ofname, *fileptr);
515 ofname[strlen(*fileptr) - 2] = '\0'; /* Strip off .Z */
516 } else { /* COMPRESSION */
517 if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) {
518 fprintf(stderr, "%s: already has .Z suffix -- no change\n",
519 *fileptr);
520 continue;
521 }
522 /* Open input file */
523 if ((freopen(*fileptr, "r", stdin)) == NULL) {
524 perror(*fileptr); continue;
525 }
526 stat ( *fileptr, &statbuf );
527 fsize = (long) statbuf.st_size;
528 /*
529 * tune hash table size for small files -- ad hoc
530 */
531#if HSIZE > 5003
532 if ( fsize < (1 << 12) )
533 hsize = 5003;
534#if HSIZE > 9001
535 else if ( fsize < (1 << 13) )
536 hsize = 9001;
537#if HSIZE > 18013
538 else if ( fsize < (1 << 14) )
539 hsize = 18013;
540#if HSIZE > 35023
541 else if ( fsize < (1 << 15) )
542 hsize = 35023;
543 else if ( fsize < 47000 )
544 hsize = 50021;
545#endif HSIZE > 35023
546#endif HSIZE > 18013
547#endif HSIZE > 9001
548 else
549#endif HSIZE > 5003
550 hsize = HSIZE;
551 /* Generate output filename */
552 strcpy(ofname, *fileptr);
553#ifndef BSD4_2 /* Short filenames */
554 if ((cp=rindex(ofname,'/')) != NULL) cp++;
555 else cp = ofname;
556 if (strlen(cp) > 12) {
557 fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
558 continue;
559 }
560#endif BSD4_2 /* Long filenames allowed */
561 strcat(ofname, ".Z");
562 }
563 /* Check for overwrite of existing file */
564 if (overwrite == 0 && zcat_flg == 0) {
565 if (stat(ofname, &statbuf) == 0) {
566 char response[2];
567 response[0] = 'n';
568 fprintf(stderr, "%s already exists;", ofname);
569 if (foreground()) {
570 fprintf(stderr, " do you wish to overwrite (y or n)? ",
571 ofname);
572 fflush(stderr);
573 read(2, response, 2);
574 while (response[1] != '\n') {
575 if (read(2, response+1, 1) < 0) { /* Ack! */
576 perror("stderr"); break;
577 }
578 }
579 }
580 if (response[0] != 'y') {
581 fprintf(stderr, "\tnot overwritten\n");
582 continue;
583 }
584 }
585 }
586 if(zcat_flg == 0) { /* Open output file */
587 if (freopen(ofname, "w", stdout) == NULL) {
588 perror(ofname);
589 continue;
590 }
591 if(!quiet)
592 fprintf(stderr, "%s: ", *fileptr);
593 }
594
595 /* Actually do the compression/decompression */
596 if (do_decomp == 0) compress();
597#ifndef DEBUG
598 else decompress();
599#else DEBUG
600 else if (debug == 0) decompress();
601 else printcodes();
602 if (verbose) dump_tab();
603#endif DEBUG
604 if(zcat_flg == 0) {
605 copystat(*fileptr, ofname); /* Copy stats */
606 if(exit_stat || (!quiet))
607 putc('\n', stderr);
608 }
609 }
610 } else { /* Standard input */
611 if (do_decomp == 0) {
612 compress();
613 if(!quiet)
614 putc('\n', stderr);
615 } else {
616 /* Check the magic number */
617 if (nomagic == 0) {
618 if ((getchar()!=(magic_header[0] & 0xFF))
619 || (getchar()!=(magic_header[1] & 0xFF))) {
620 fprintf(stderr, "stdin: not in compressed format\n");
621 exit(1);
622 }
623 maxbits = getchar(); /* set -b from file */
624 block_compress = maxbits & BLOCK_MASK;
625 maxbits &= BIT_MASK;
626 maxmaxcode = 1 << maxbits;
627 fsize = 100000; /* assume stdin large for USERMEM */
628 if(maxbits > BITS) {
629 fprintf(stderr,
630 "stdin: compressed with %d bits, can only handle %d bits\n",
631 maxbits, BITS);
632 exit(1);
633 }
634 }
635#ifndef DEBUG
636 decompress();
637#else DEBUG
638 if (debug == 0) decompress();
639 else printcodes();
640 if (verbose) dump_tab();
641#endif DEBUG
642 }
643 }
644 exit(exit_stat);
645}
646
647static int offset;
648long int in_count = 1; /* length of input */
649long int bytes_out; /* length of compressed output */
650long int out_count = 0; /* # of codes output (for debugging) */
651
652#define HOG_CHECK ((count_int) 2000) /* Number of chars to read b4 check */
653#define MAX_CACHE ((count_int) 1<<BITS) /* Next line is this constant too */
654unsigned short hashcache [1<<BITS]; /* common hash short circuit cache */
655count_int cfreq [256]; /* character counts */
656#ifndef vax
657 char chog; /* most common character from input */
658# define CHOG ' ' /* Assume space is most frequent */
659#else
660 int chog; /* char arith slow on VAX */
661# define CHOG (int) ' ' /* Assume space is most frequent */
662#endif
663int cstat_flg = 0; /* on after determining char hog */
664
665/*
666 * compress stdin to stdout
667 *
668 * Algorithm: on large machines, for maxbits <= FBITS, use fast direct table
669 * lookup on the prefix code / next character combination. For smaller code
670 * size, use open addressing modular division double hashing (no chaining), ala
671 * Knuth vol. 3, sec. 6.4 Algorithm D, along with G. Knott's relatively-prime
672 * secondary probe. Do block compression with an adaptive reset, whereby the
673 * code table is cleared when the compression ratio decreases, but after the
674 * table fills. The variable-length output codes are re-sized at this point,
675 * and a special CLEAR code is generated for the decompressor. For the
676 * megamemory version, the sparse array is cleared indirectly through a
677 * "shadow" output code history. Late additions: for the hashing code,
678 * construct the table according to file size for noticeable speed improvement
679 * on small files. Also detect and cache codes associated with the most
680 * common character to bypass hash calculation on these codes (a characteristic
681 * of highly-compressable raster images). Please direct questions about this
682 * implementation to ames!jaw.
683 */
684
685
686compress() {
687 register long fcode;
688 register code_int i = 0;
689 register int c;
690 register code_int ent;
691 register int disp;
692 register code_int hsize_reg;
693
694#ifndef COMPATIBLE
695 if (nomagic == 0) {
696 putchar(magic_header[0]); putchar(magic_header[1]);
697 putchar((char)(maxbits | block_compress));
698 }
699#endif COMPATIBLE
700
701 offset = 0;
702 bytes_out = 0;
703 out_count = 0;
704 clear_flg = 0;
705 ratio = 0.0;
706 in_count = 1;
707 checkpoint = CHECK_GAP;
708 maxcode = MAXCODE(n_bits = INIT_BITS);
709 free_ent = ((block_compress) ? FIRST : 256 );
710 ent = getchar ();
711
712#ifdef USERMEM
713if ( maxbits <= FBITS && (fsize >= 30000) ) { /* use hashing on small files */
714
715 while ( (c = getchar()) != (unsigned) EOF ) {
716 in_count++;
717 fcode = (long) (((long) c << maxbits) + ent);
718 if ( ftable [fcode] != 0 ) /* test for code in "string" table */
719 ent = ftable [fcode];
720 else {
721 output ( (code_int) ent );
722 out_count++;
723 ent = c;
724 if ( free_ent >= maxmaxcode ) {
725 if ( (count_int)in_count < checkpoint || (!block_compress) )
726 continue;
727 else {
728 clear ();
729 i = 0;
730 }
731 } else { /* put code in table */
732 ftable [fcode] = (short) free_ent++;
733 fcodemem [i++] = fcode; /* memorize for block compression */
734 }
735 }
736 }
737 goto fin;
738}
739#endif USERMEM
740
741 chog = CHOG; /* assumed character for the hog */
742 cstat_flg = 0;
743 hsize_reg = hsize;
744 cl_hash(hsize_reg); /* clear hash tables */
745
746 while ( (c = getchar()) != (unsigned) EOF ) {
747 in_count++;
748 if ( cstat_flg == 0 ) {
749 cfreq [c]++; /* gather frequencies at start of input */
750 if ( (count_int)in_count > HOG_CHECK ) {
751 cstat_flg = 1;
752 chog = hogtally(); /* compute char hog */
753 if(chog != CHOG) /* fixup for wrong assumption */
754 creset( (count_int) free_ent );
755 }
756 }
757 if ( c == chog )
758 if ( (i = hashcache [ent]) ) { /* cache -> code */
759 ent = i;
760 continue;
761 }
762 fcode = (long) (((long) c << maxbits) + ent);
763#ifdef pdp11
764 i = (((c + 12347) * ent) & 077777) % HSIZE; /* avoid 'lrem' call */
765#else !pdp11
766 i = fcode % hsize_reg; /* division hashing */
767#endif pdp11
768
769 if ( htab [i] == fcode ) {
770 ent = codetab [i];
771 continue;
772 } else if ( (long)htab [i] < 0 ) /* empty slot */
773 goto nomatch;
774 disp = hsize_reg - i; /* secondary hash (G. Knott) */
775 if ( i == 0 )
776 disp = 1;
777probe:
778 if ( (i -= disp) < 0 )
779 i += hsize_reg;
780
781 if ( htab [i] == fcode ) {
782 ent = codetab [i];
783 continue;
784 }
785 if ( (long)htab [i] > 0 )
786 goto probe;
787nomatch:
788 output ( (code_int) ent );
789 out_count++;
790#ifdef interdata
791 if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
792#else
793 if ( free_ent < maxmaxcode ) {
794#endif
795 if ( c == chog ) /* code -> cache */
796 hashcache [ent] = free_ent;
797 /* code -> hashtable */
798 codetab [i] = free_ent++;
799 htab [i] = fcode;
800 }
801 else if ( (count_int)in_count >= checkpoint && block_compress )
802 clear ();
803 ent = c;
804 }
805fin:
806 /*
807 * Put out the final code.
808 */
809 output( (code_int)ent );
810 out_count++;
811 output( (code_int)-1 );
812
813 /*
814 * Print out stats on stderr
815 */
816 if(zcat_flg == 0 && !quiet) {
817#ifdef DEBUG
818 fprintf( stderr,
819 "%ld chars in, %ld codes (%ld bytes) out, compression factor %g\n",
820 in_count, out_count, bytes_out,
821 (double)in_count / (double)bytes_out );
822 fprintf( stderr, "\tCompression as in compact: %5.2f%%\n",
823 100.0 * ( in_count - bytes_out ) / (double) in_count );
824 fprintf( stderr, "\tLargest code was %d (%d bits)\n", free_ent - 1, n_bits );
825#else DEBUG
826 fprintf( stderr, "Compression: %5.2f%%",
827 100.0 * ( in_count - bytes_out ) / (double) in_count );
828#endif DEBUG
829 }
830 if(bytes_out > in_count) /* exit(2) if no savings */
831 exit_stat = 2;
832 return;
833}
834
835/*****************************************************************
836 * TAG( output )
837 *
838 * Output the given code.
839 * Inputs:
840 * code: A n_bits-bit integer. If == -1, then EOF. This assumes
841 * that n_bits =< (long)wordsize - 1.
842 * Outputs:
843 * Outputs code to the file.
844 * Assumptions:
845 * Chars are 8 bits long.
846 * Algorithm:
847 * Maintain a BITS character long buffer (so that 8 codes will
848 * fit in it exactly). Use the VAX insv instruction to insert each
849 * code in turn. When the buffer fills up empty it and start over.
850 */
851
852static char buf[BITS];
853
854#ifndef vax
855char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
856char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
857#endif !vax
858
859output( code )
860code_int code;
861{
862#ifdef DEBUG
863 static int col = 0;
864#endif DEBUG
865
866 /*
867 * On the VAX, it is important to have the register declarations
868 * in exactly the order given, or the asm will break.
869 */
870 register int r_off = offset, bits= n_bits;
871 register char * bp = buf;
872
873 if ( code >= 0 ) {
874#ifdef vax
875 /* VAX DEPENDENT!! Implementation on other machines may be
876 * difficult.
877 *
878 * Translation: Insert BITS bits from the argument starting at
879 * offset bits from the beginning of buf.
880 */
881 0; /* C compiler bug ?? */
882 asm( "insv 4(ap),r11,r10,(r9)" );
883#else not a vax
884/* WARNING: byte/bit numbering on the vax is simulated by the following code
885*/
886 /*
887 * Get to the first byte.
888 */
889 bp += (r_off >> 3);
890 r_off &= 7;
891 /*
892 * Since code is always >= 8 bits, only need to mask the first
893 * hunk on the left.
894 */
895 *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
896 bp++;
897 bits -= (8 - r_off);
898 code >>= 8 - r_off;
899 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
900 if ( bits >= 8 ) {
901 *bp++ = code;
902 code >>= 8;
903 bits -= 8;
904 }
905 /* Last bits. */
906 if(bits)
907 *bp = code;
908#endif vax
909 offset += n_bits;
910 if ( offset == (n_bits << 3) ) {
911 bp = buf;
912 bits = n_bits;
913 bytes_out += bits;
914 do
915 putchar(*bp++);
916 while(--bits);
917 if (ferror(stdout))
918 writeerr();
919 offset = 0;
920 }
921#ifdef DEBUG
922 if ( verbose )
923 fprintf( stderr, "%5d%c", code,
924 (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
925#endif DEBUG
926
927 /*
928 * If the next entry is going to be too big for the code size,
929 * then increase it, if possible.
930 */
931 if ( free_ent > maxcode || (clear_flg > 0))
932 {
933 /*
934 * Write the whole buffer, because the input side won't
935 * discover the size increase until after it has read it.
936 */
937 if ( offset > 0 ) {
938 if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
939 writeerr();
940 bytes_out += n_bits;
941 }
942 offset = 0;
943
944 if ( clear_flg ) {
945 maxcode = MAXCODE (n_bits = INIT_BITS);
946 clear_flg = 0;
947 }
948 else {
949 n_bits++;
950 if ( n_bits == maxbits )
951 maxcode = maxmaxcode;
952 else
953 maxcode = MAXCODE(n_bits);
954 }
955#ifdef DEBUG
956 if ( debug ) {
957 fprintf( stderr, "\nChange to %d bits\n", n_bits );
958 col = 0;
959 }
960#endif DEBUG
961 }
962 } else {
963 /*
964 * At EOF, write the rest of the buffer.
965 */
966 if ( offset > 0 )
967 fwrite( buf, 1, (offset + 7) / 8, stdout );
968 bytes_out += (offset + 7) / 8;
969 offset = 0;
970 fflush( stdout );
971#ifdef DEBUG
972 if ( verbose )
973 fprintf( stderr, "\n" );
974#endif DEBUG
975 if( ferror( stdout ) )
976 writeerr();
977 }
978}
979
980decompress() {
981 register int stack_top = MAXSTACK;
982 register code_int code, oldcode, incode;
983 register int finchar;
984 char stack[MAXSTACK];
985
986 /*
987 * As above, initialize the first 256 entries in the table.
988 */
989 maxcode = MAXCODE(n_bits = INIT_BITS);
990 for ( code = 255; code >= 0; code-- ) {
991 tab_prefix[code] = 0;
992 tab_suffix[code] = (char_type)code;
993 }
994 free_ent = ((block_compress) ? FIRST : 256 );
995
996 finchar = oldcode = getcode();
997 putchar( (char)finchar ); /* first code must be 8 bits = char */
998
999 while ( (code = getcode()) != -1 ) {
1000
1001 if ( (code == CLEAR) && block_compress ) {
1002 for ( code = 255; code > 0; code -= 4 ) {
1003 tab_prefix [code-3] = 0;
1004 tab_prefix [code-2] = 0;
1005 tab_prefix [code-1] = 0;
1006 tab_prefix [code] = 0;
1007 }
1008 clear_flg = 1;
1009 free_ent = FIRST - 1;
1010 if ( (code = getcode ()) == -1 ) /* O, untimely death! */
1011 break;
1012 }
1013 incode = code;
1014 /*
1015 * Special case for KwKwK string.
1016 */
1017 if ( code >= free_ent ) {
1018 stack[--stack_top] = finchar;
1019 code = oldcode;
1020 }
1021
1022 /*
1023 * Generate output characters in reverse order
1024 */
1025#ifdef interdata
1026 while ( ((unsigned long)code) >= ((unsigned long)256) ) {
1027#else !interdata
1028 while ( code >= 256 ) {
1029#endif interdata
1030 stack[--stack_top] = tab_suffix[code];
1031 code = tab_prefix[code];
1032 }
1033 stack[--stack_top] = finchar = tab_suffix[code];
1034
1035 /*
1036 * And put them out in forward order
1037 */
1038 for ( ; stack_top < MAXSTACK; stack_top++ )
1039 putchar(stack[stack_top]);
1040 if (ferror(stdout))
1041 writeerr ( );
1042 stack_top = MAXSTACK;
1043
1044 /*
1045 * Generate the new entry.
1046 */
1047 if ( (code=free_ent) < maxmaxcode ) {
1048 tab_prefix[code] = (unsigned short)oldcode;
1049 tab_suffix[code] = finchar;
1050 free_ent = code+1;
1051 }
1052 /*
1053 * Remember previous code.
1054 */
1055 oldcode = incode;
1056 }
1057 fflush( stdout );
1058 if(ferror(stdout))
1059 writeerr();
1060}
1061
1062
1063/*****************************************************************
1064 * TAG( getcode )
1065 *
1066 * Read one code from the standard input. If EOF, return -1.
1067 * Inputs:
1068 * stdin
1069 * Outputs:
1070 * code or -1 is returned.
1071 */
1072
1073code_int
1074getcode() {
1075 /*
1076 * On the VAX, it is important to have the register declarations
1077 * in exactly the order given, or the asm will break.
1078 */
1079 register code_int code;
1080 static int offset = 0, size = 0;
1081 static char_type buf[BITS];
1082 register int r_off, bits;
1083 register char_type *bp = buf;
1084
1085 if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
1086 /*
1087 * If the next entry will be too big for the current code
1088 * size, then we must increase the size. This implies reading
1089 * a new buffer full, too.
1090 */
1091 if ( free_ent > maxcode ) {
1092 n_bits++;
1093 if ( n_bits == maxbits )
1094 maxcode = maxmaxcode; /* won't get any bigger now */
1095 else
1096 maxcode = MAXCODE(n_bits);
1097 }
1098 if ( clear_flg > 0) {
1099 maxcode = MAXCODE (n_bits = INIT_BITS);
1100 clear_flg = 0;
1101 }
1102 size = fread( buf, 1, n_bits, stdin );
1103 if ( size <= 0 )
1104 return -1; /* end of file */
1105 offset = 0;
1106 /* Round size down to integral number of codes */
1107 size = (size << 3) - (n_bits - 1);
1108 }
1109 r_off = offset;
1110 bits = n_bits;
1111#ifdef vax
1112 asm( "extzv r10,r9,(r8),r11" );
1113#else not a vax
1114 /*
1115 * Get to the first byte.
1116 */
1117 bp += (r_off >> 3);
1118 r_off &= 7;
1119 /* Get first part (low order bits) */
1120#ifdef NO_UCHAR
1121 code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
1122#else NO_UCHAR
1123 code = (*bp++ >> r_off);
1124#endif NO_UCHAR
1125 bits -= (8 - r_off);
1126 r_off = 8 - r_off; /* now, offset into code word */
1127 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
1128 if ( bits >= 8 ) {
1129#ifdef NO_UCHAR
1130 code |= (*bp++ & 0xff) << r_off;
1131#else NO_UCHAR
1132 code |= *bp++ << r_off;
1133#endif NO_UCHAR
1134 r_off += 8;
1135 bits -= 8;
1136 }
1137 /* high order bits. */
1138 code |= (*bp & rmask[bits]) << r_off;
1139#endif vax
1140 offset += n_bits;
1141
1142 return code;
1143}
1144
1145char *
1146rindex(s, c) /* For those who don't have it in libc.a */
1147register char *s, c;
1148{
1149 char *p;
1150 for (p = NULL; *s; s++)
1151 if (*s == c)
1152 p = s;
1153 return(p);
1154}
1155
1156#ifdef DEBUG
1157printcodes()
1158{
1159 /*
1160 * Just print out codes from input file. Mostly for debugging.
1161 */
1162 code_int code;
1163 int col = 0, bits;
1164
1165 bits = n_bits = INIT_BITS;
1166 maxcode = MAXCODE(n_bits);
1167 free_ent = ((block_compress) ? FIRST : 256 );
1168 while ( ( code = getcode() ) >= 0 ) {
1169 if ( (code == CLEAR) && block_compress ) {
1170 free_ent = FIRST - 1;
1171 clear_flg = 1;
1172 }
1173 else if ( free_ent < maxmaxcode )
1174 free_ent++;
1175 if ( bits != n_bits ) {
1176 fprintf(stderr, "\nChange to %d bits\n", n_bits );
1177 bits = n_bits;
1178 col = 0;
1179 }
1180 fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
1181 }
1182 putc( '\n', stderr );
1183 exit( 0 );
1184}
1185
1186dump_tab() /* dump string table */
1187{
1188 register int i;
1189 register ent;
1190 char stack[4 * MAXSTACK]; /* \nnn makes it 4 times bigger */
1191 int stack_top = 4 * MAXSTACK;
1192
1193 for ( i = 0; i < free_ent; i++ ) {
1194 ent = i;
1195 if ( isascii(tab_suffix[ent]) && isprint(tab_suffix[ent]) )
1196 fprintf( stderr, "%5d: %5d/'%c' \"",
1197 ent, tab_prefix[ent], tab_suffix[ent] );
1198 else
1199 fprintf( stderr, "%5d: %5d/\\%03o \"",
1200 ent, tab_prefix[ent], tab_suffix[ent] );
1201 stack[--stack_top] = '\n';
1202 stack[--stack_top] = '"';
1203 for ( ; ent != NULL;
1204 ent = (ent >= FIRST ? tab_prefix[ent] : NULL) ) {
1205 if ( isascii(tab_suffix[ent]) && isprint(tab_suffix[ent]) )
1206 stack[--stack_top] = tab_suffix[ent];
1207 else {
1208 switch( tab_suffix[ent] ) {
1209 case '\n': stack[--stack_top] = 'n'; break;
1210 case '\t': stack[--stack_top] = 't'; break;
1211 case '\b': stack[--stack_top] = 'b'; break;
1212 case '\f': stack[--stack_top] = 'f'; break;
1213 case '\r': stack[--stack_top] = 'r'; break;
1214 default:
1215 stack[--stack_top] = '0' + tab_suffix[ent] % 8;
1216 stack[--stack_top] = '0' + (tab_suffix[ent] / 8) % 8;
1217 stack[--stack_top] = '0' + tab_suffix[ent] / 64;
1218 break;
1219 }
1220 stack[--stack_top] = '\\';
1221 }
1222 }
1223 fwrite( &stack[stack_top], 1, 4 * MAXSTACK - stack_top, stderr );
1224 stack_top = 4 * MAXSTACK;
1225 }
1226}
1227#endif DEBUG
1228
1229/*****************************************************************
1230 * TAG( writeerr )
1231 *
1232 * Exits with a message. We only check for write errors often enough
1233 * to avoid a lot of "file system full" messages, not on every write.
1234 * ferror() check after fflush will catch any others (I trust).
1235 *
1236 */
1237
1238writeerr()
1239{
1240 perror ( ofname );
1241 unlink ( ofname );
1242 exit ( 1 );
1243}
1244
1245copystat(ifname, ofname)
1246char *ifname, *ofname;
1247{
1248 struct stat statbuf;
1249 int mode;
1250 time_t timep[2];
1251
1252 fclose(stdout);
1253 if (stat(ifname, &statbuf)) { /* Get stat on input file */
1254 perror(ifname);
1255 return;
1256 }
1257 if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
1258 if(quiet)
1259 fprintf(stderr, "%s: ", ifname);
1260 fprintf(stderr, " -- not a regular file: unchanged");
1261 exit_stat = 1;
1262 } else if (statbuf.st_nlink > 1) {
1263 if(quiet)
1264 fprintf(stderr, "%s: ", ifname);
1265 fprintf(stderr, " -- has %d other links: unchanged",
1266 statbuf.st_nlink - 1);
1267 exit_stat = 1;
1268 } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
1269 fprintf(stderr, " -- file unchanged");
1270 } else { /* ***** Successful Compression ***** */
1271 exit_stat = 0;
1272 mode = statbuf.st_mode & 07777;
1273 if (chmod(ofname, mode)) /* Copy modes */
1274 perror(ofname);
1275 chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */
1276 timep[0] = statbuf.st_atime;
1277 timep[1] = statbuf.st_mtime;
1278 utime(ofname, timep); /* Update last accessed and modified times */
1279 if (unlink(ifname)) /* Remove input file */
1280 perror(ifname);
1281 if(!quiet)
1282 fprintf(stderr, " -- replaced with %s", ofname);
1283 return; /* Successful return */
1284 }
1285
1286 /* Unsuccessful return -- one of the tests failed */
1287 if (unlink(ofname))
1288 perror(ofname);
1289}
1290/*
1291 * This routine returns 1 if we are running in the foreground and stderr
1292 * is a tty.
1293 */
1294foreground()
1295{
1296 if(bgnd_flag) { /* background? */
1297 return(0);
1298 } else { /* foreground */
1299 if(isatty(2)) { /* and stderr is a tty */
1300 return(1);
1301 } else {
1302 return(0);
1303 }
1304 }
1305}
1306
1307onintr ( )
1308{
1309 unlink ( ofname );
1310 exit ( 1 );
1311}
1312
1313clear () /* table clear for block compress */
1314{
1315 register code_int i;
1316 register count_int *p, *endp;
1317 register unsigned short *q;
1318
1319#ifdef DEBUG
1320 if(debug)
1321 fprintf ( stderr, "count: %ld ratio: %f\n", in_count,
1322 (double) in_count / (double) bytes_out );
1323#endif DEBUG
1324
1325 checkpoint = in_count + CHECK_GAP;
1326 if ( (double) in_count / (double) bytes_out > ratio )
1327 ratio = (double) in_count / (double) bytes_out;
1328 else {
1329 ratio = 0.0;
1330#ifdef USERMEM
1331 if ( maxbits <= FBITS ) /* sparse array clear */
1332 for ( i = (1 << maxbits) - 1; i >= 0; i-- )
1333 ftable [fcodemem [i]] = 0; /* indirect thru "shadow" */
1334 else
1335#endif USERMEM /* hash table clear */
1336 {
1337 endp = &htab [hsize];
1338 for ( p = &htab [0], q = &codetab [0]; p < endp; ) {
1339 *p++ = -1;
1340 *q++ = 0;
1341 }
1342 creset ( MAX_CACHE );
1343 }
1344 free_ent = FIRST;
1345 clear_flg = 1;
1346 output ( (code_int) CLEAR );
1347#ifdef DEBUG
1348 if(debug)
1349 fprintf ( stderr, "clear\n" );
1350#endif DEBUG
1351 }
1352}
1353
1354creset ( n ) /* clear hash cache */
1355 register count_int n; /* clear at least this many entries */
1356{
1357 register count_int i;
1358 register unsigned short *hash_p;
1359 register unsigned short zero = 0;
1360 static int nfiles = 0;
1361
1362 if ( nfiles++ == 0 ) /* No clear needed if first time */
1363 return;
1364 n = (n+15) & (-16);
1365 hash_p = hashcache + n;
1366 for ( i = n; i > 0; i -=16 ) {
1367 *(hash_p-16) = zero;
1368 *(hash_p-15) = zero;
1369 *(hash_p-14) = zero;
1370 *(hash_p-13) = zero;
1371 *(hash_p-12) = zero;
1372 *(hash_p-11) = zero;
1373 *(hash_p-10) = zero;
1374 *(hash_p-9) = zero;
1375 *(hash_p-8) = zero;
1376 *(hash_p-7) = zero;
1377 *(hash_p-6) = zero;
1378 *(hash_p-5) = zero;
1379 *(hash_p-4) = zero;
1380 *(hash_p-3) = zero;
1381 *(hash_p-2) = zero;
1382 *(hash_p-1) = zero;
1383 hash_p -= 16;
1384 }
1385}
1386
1387hogtally () /* compute character code hog */
1388{
1389 register int i, most;
1390
1391 for ( i = most = 0; i < 256; i++ )
1392 if ( cfreq [i] >= cfreq [most] )
1393 most = i;
1394 return ( most );
1395}
1396
1397cl_hash(hsize)
1398 register int hsize;
1399{
1400 register count_int *htab_p = htab+hsize;
1401 register int i;
1402 register long m1 = -1;
1403
1404 /* clear hashcache */
1405#define min(a,b) ((a>b) ? b : a)
1406 creset( min((count_int)hsize, MAX_CACHE) );
1407
1408 i = hsize - 16;
1409 do {
1410 *(htab_p-16) = m1;
1411 *(htab_p-15) = m1;
1412 *(htab_p-14) = m1;
1413 *(htab_p-13) = m1;
1414 *(htab_p-12) = m1;
1415 *(htab_p-11) = m1;
1416 *(htab_p-10) = m1;
1417 *(htab_p-9) = m1;
1418 *(htab_p-8) = m1;
1419 *(htab_p-7) = m1;
1420 *(htab_p-6) = m1;
1421 *(htab_p-5) = m1;
1422 *(htab_p-4) = m1;
1423 *(htab_p-3) = m1;
1424 *(htab_p-2) = m1;
1425 *(htab_p-1) = m1;
1426 htab_p -= 16;
1427 } while ((i -= 16) >= 0);
1428 for ( i += 16; i > 0; i-- )
1429 *--htab_p = m1;
1430}