📄 compress.c
字号:
while ( ((unsigned long)code) >= ((unsigned long)256) ) {#else while ( code >= 256 ) {#endif *stackp++ = tab_suffixof(code); code = tab_prefixof(code); } *stackp++ = finchar = tab_suffixof(code); /* * And put them out in forward order */ do putc ( *--stackp ,stdout); while ( stackp > de_stack ); /* * Generate the new entry. */ if ( (code=free_ent) < maxmaxcode ) { tab_prefixof(code) = (unsigned short)oldcode; tab_suffixof(code) = finchar; free_ent = code+1; } /* * Remember previous code. */ oldcode = incode; } fflush( stdout ); if(ferror(stdout)) writeerr();}/***************************************************************** * TAG( getcode ) * * Read one code from the standard input. If EOF, return -1. * Inputs: * stdin * Outputs: * code or -1 is returned. */code_intgetcode() { /* * On the VAX, it is important to have the REGISTER declarations * in exactly the order given, or the asm will break. */ REGISTER code_int code; static int offset = 0, size = 0; static char_type buf[BITS]; REGISTER int r_off, bits; REGISTER char_type *bp = buf; if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) { /* * If the next entry will be too big for the current code * size, then we must increase the size. This implies reading * a new buffer full, too. */ if ( free_ent > maxcode ) { n_bits++; if ( n_bits == maxbits ) maxcode = maxmaxcode; /* won't get any bigger now */ else maxcode = MAXCODE(n_bits); } if ( clear_flg > 0) { maxcode = MAXCODE (n_bits = INIT_BITS); clear_flg = 0; } size = fread( buf, (size_t)1, (size_t)n_bits, stdin ); if ( size <= 0 ) return -1; /* end of file */ offset = 0; /* Round size down to integral number of codes */ size = (size << 3) - (n_bits - 1); } r_off = offset; bits = n_bits;#ifdef vax asm( "extzv r10,r9,(r8),r11" );#else /* not a vax */ /* * Get to the first byte. */ bp += (r_off >> 3); r_off &= 7; /* Get first part (low order bits) */#ifdef NO_UCHAR code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;#else code = (*bp++ >> r_off);#endif /* NO_UCHAR */ bits -= (8 - r_off); r_off = 8 - r_off; /* now, offset into code word */ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ if ( bits >= 8 ) {#ifdef NO_UCHAR code |= (*bp++ & 0xff) << r_off;#else code |= *bp++ << r_off;#endif /* NO_UCHAR */ r_off += 8; bits -= 8; } /* high order bits. */ code |= (*bp & rmask[bits]) << r_off;#endif /* vax */ offset += n_bits; return code;}#ifndef AZTEC86char *strrchr(s, c) /* For those who don't have it in libc.a */REGISTER char *s, c;{ char *p; for (p = NULL; *s; s++) if (*s == c) p = s; return(p);}#endif#ifndef METAWARE#ifdef DEBUGprintcodes(){ /* * Just print out codes from input file. For debugging. */ code_int code; int col = 0, bits; bits = n_bits = INIT_BITS; maxcode = MAXCODE(n_bits); free_ent = ((block_compress) ? FIRST : 256 ); while ( ( code = getcode() ) >= 0 ) { if ( (code == CLEAR) && block_compress ) { free_ent = FIRST - 1; clear_flg = 1; } else if ( free_ent < maxmaxcode ) free_ent++; if ( bits != n_bits ) { fprintf(stderr, "\nChange to %d bits\n", n_bits ); bits = n_bits; col = 0; } fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' ); } putc( '\n', stderr ); exit( 0 );}#ifdef DEBUG2code_int sorttab[1<<BITS]; /* sorted pointers into htab */#define STACK_SIZE 500static char stack[STACK_SIZE];/* dumptab doesn't use main stack now -prevents distressing crashes */dump_tab() /* dump string table */{ REGISTER int i, first; REGISTER ent; int stack_top = STACK_SIZE; REGISTER c; if(do_decomp == 0) { /* compressing */ REGISTER int flag = 1; for(i=0; i<hsize; i++) { /* build sort pointers */ if((long)htabof(i) >= 0) { sorttab[codetabof(i)] = i; } } first = block_compress ? FIRST : 256; for(i = first; i < free_ent; i++) { fprintf(stderr, "%5d: \"", i); stack[--stack_top] = '\n'; stack[--stack_top] = '"'; /* " */ stack_top = in_stack((int)(htabof(sorttab[i])>>maxbits)&0xff, stack_top); for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1); ent > 256; ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) { stack_top = in_stack((int)(htabof(sorttab[ent]) >> maxbits), stack_top); } stack_top = in_stack(ent, stack_top); fwrite( &stack[stack_top], (size_t)1, (size_t)(STACK_SIZE-stack_top), stderr); stack_top = STACK_SIZE; } } else if(!debug) { /* decompressing */ for ( i = 0; i < free_ent; i++ ) { ent = i; c = tab_suffixof(ent); if ( isascii(c) && isprint(c) ) fprintf( stderr, "%5d: %5d/'%c' \"", ent, tab_prefixof(ent), c ); else fprintf( stderr, "%5d: %5d/\\%03o \"", ent, tab_prefixof(ent), c ); stack[--stack_top] = '\n'; stack[--stack_top] = '"'; /* " */ for ( ; ent != NULL; ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) { stack_top = in_stack(tab_suffixof(ent), stack_top); } fwrite( &stack[stack_top], (size_t)1, (size_t)(STACK_SIZE - stack_top), stderr ); stack_top = STACK_SIZE; } }}intin_stack(c, stack_top) REGISTER int c, stack_top;{ if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) { stack[--stack_top] = c; } else { switch( c ) { case '\n': stack[--stack_top] = 'n'; break; case '\t': stack[--stack_top] = 't'; break; case '\b': stack[--stack_top] = 'b'; break; case '\f': stack[--stack_top] = 'f'; break; case '\r': stack[--stack_top] = 'r'; break; case '\\': stack[--stack_top] = '\\'; break; default: stack[--stack_top] = '0' + c % 8; stack[--stack_top] = '0' + (c / 8) % 8; stack[--stack_top] = '0' + c / 64; break; } stack[--stack_top] = '\\'; } if (stack_top<0) { fprintf(stderr,"dump_tab stack overflow!!!\n"); exit(1); } return stack_top;}#elsedump_tab() {}#endif /* DEBUG2 */#endif /* DEBUG */#endif /* METAWARE */void writeerr(){ perror ( ofname ); unlink ( ofname ); exit ( 1 );}void copystat(ifname, ofname)char *ifname, *ofname;{ struct stat statbuf; int mode;#ifndef AZTEC86 time_t timep[2];#else unsigned long timep[2];#endif fflush(stdout); close(fileno(stdout)); if (stat(ifname, &statbuf)) { /* Get stat on input file */ perror(ifname); return; }#ifndef PCDOS /* meddling with UNIX-style file modes */ if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) { if(quiet) fprintf(stderr, "%s: ", ifname); fprintf(stderr, " -- not a regular file: unchanged"); exit_stat = 1; } else if (statbuf.st_nlink > 1) { if(quiet) fprintf(stderr, "%s: ", ifname); fprintf(stderr, " -- has %d other links: unchanged", statbuf.st_nlink - 1); exit_stat = 1; } else #endif if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */ if(!quiet) fprintf(stderr, " -- file unchanged"); } else { /* ***** Successful Compression ***** */ exit_stat = 0;#ifndef PCDOS mode = statbuf.st_mode & 07777;#else mode = statbuf.st_attr & 07777;#endif if (chmod(ofname, mode)) /* Copy modes */ perror(ofname);#ifndef PCDOS chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */ timep[0] = statbuf.st_atime; timep[1] = statbuf.st_mtime;#else timep[0] = statbuf.st_mtime; timep[1] = statbuf.st_mtime;#endif utime(ofname, (struct utimbuf *)timep); /* Update last accessed and modified times *//* if (unlink(ifname)) perror(ifname);*/ if(!quiet) if(do_decomp == 0) fprintf(stderr, " -- compressed to %s", ofname); else fprintf(stderr, " -- decompressed to %s", ofname); return; /* Successful return */ } /* Unsuccessful return -- one of the tests failed */ if (unlink(ofname)) perror(ofname);}/* * This routine returns 1 if we are running in the foreground and stderr * is a tty. */int foreground(){#ifndef METAWARE if(bgnd_flag) { /* background? */ return(0); } else { /* foreground */#endif if(isatty(2)) { /* and stderr is a tty */ return(1); } else { return(0); }#ifndef METAWARE }#endif}#ifndef METAWAREvoid onintr (dummy)int dummy; /* to keep the compiler happy */{ (void)signal(SIGINT,SIG_IGN); unlink ( ofname ); exit ( 1 );}void oops (dummy) /* wild pointer -- assume bad input */int dummy; /* to keep the compiler happy */{ (void)signal(SIGSEGV,SIG_IGN); if ( do_decomp == 1 ) fprintf ( stderr, "uncompress: corrupt input\n" ); unlink ( ofname ); exit ( 1 );}#endifvoid cl_block () /* table clear for block compress */{ REGISTER long int rat; checkpoint = in_count + CHECK_GAP;#ifdef DEBUG if ( debug ) { fprintf ( stderr, "count: %ld, ratio: ", in_count ); prratio ( stderr, in_count, bytes_out ); fprintf ( stderr, "\n"); }#endif /* DEBUG */ if(in_count > 0x007fffff) { /* shift will overflow */ rat = bytes_out >> 8; if(rat == 0) { /* Don't divide by zero */ rat = 0x7fffffff; } else { rat = in_count / rat; } } else { rat = (in_count << 8) / bytes_out; /* 8 fractional bits */ } if ( rat > ratio ) { ratio = rat; } else { ratio = 0;#ifdef DEBUG if(verbose) dump_tab(); /* dump string table */#endif cl_hash ( (count_int) hsize ); free_ent = FIRST; clear_flg = 1; output ( (code_int) CLEAR );#ifdef DEBUG if(debug) fprintf ( stderr, "clear\n" );#endif /* DEBUG */ }}void cl_hash(hsize) /* reset code table */ REGISTER count_int hsize;{#ifdef AZTEC86#ifdef PCDOS /* This function only in PC-DOS lib, not in MINIX lib */ memset(htab,-1, hsize * sizeof(count_int));#else/* MINIX and all non-PC machines do it this way */ #ifndef XENIX_16 /* Normal machine */ REGISTER count_int *htab_p = htab+hsize;#else REGISTER j; REGISTER long k = hsize; REGISTER count_int *htab_p;#endif REGISTER long i; REGISTER long m1 = -1;#ifdef XENIX_16 for(j=0; j<=8 && k>=0; j++,k-=8192) { i = 8192; if(k < 8192) { i = k; } htab_p = &(htab[j][i]); i -= 16; if(i > 0) {#else i = hsize - 16;#endif do { /* might use Sys V memset(3) here */ *(htab_p-16) = m1; *(htab_p-15) = m1; *(htab_p-14) = m1; *(htab_p-13) = m1; *(htab_p-12) = m1; *(htab_p-11) = m1; *(htab_p-10) = m1; *(htab_p-9) = m1; *(htab_p-8) = m1; *(htab_p-7) = m1; *(htab_p-6) = m1; *(htab_p-5) = m1; *(htab_p-4) = m1; *(htab_p-3) = m1; *(htab_p-2) = m1; *(htab_p-1) = m1; htab_p -= 16; } while ((i -= 16) >= 0);#ifdef XENIX_16 } }#endif for ( i += 16; i > 0; i-- ) *--htab_p = m1;#endif#endif}void prratio(stream, num, den)FILE *stream;long int num;long int den;{ REGISTER int q; /* Doesn't need to be long */ if(num > 214748L) { /* 2147483647/10000 */ q = (int)(num / (den / 10000L)); } else { q = (int)(10000L * num / den); /* Long calculations, though */ } if (q < 0) { putc('-', stream); q = -q; } fprintf(stream, "%d.%02d%c", q / 100, q % 100, '%');}void version(){ fprintf(stderr, "compress 4.1\n"); fprintf(stderr, "Options: ");#ifdef vax fprintf(stderr, "vax, ");#endif#ifdef _MINIX fprintf(stderr, "MINIX, ");#endif#ifdef NO_UCHAR fprintf(stderr, "NO_UCHAR, ");#endif#ifdef SIGNED_COMPARE_SLOW fprintf(stderr, "SIGNED_COMPARE_SLOW, ");#endif#ifdef XENIX_16 fprintf(stderr, "XENIX_16, ");#endif#ifdef COMPATIBLE fprintf(stderr, "COMPATIBLE, ");#endif#ifdef DEBUG fprintf(stderr, "DEBUG, ");#endif#ifdef BSD4_2 fprintf(stderr, "BSD4_2, ");#endif fprintf(stderr, "BITS = %d\n", BITS);}/* End of text from uok.UUCP:net.sources */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -