From 5bb22757885bc69df740ce45e570d74b5aa0a167 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 6 Sep 2021 17:36:47 -0700 Subject: [PATCH] Get bzip2 to build --- Makefile | 1 + libc/nexgen32e/crc32.h | 1 + third_party/bzip2/Makefile | 217 -- third_party/bzip2/Makefile-libbz2_so | 59 - third_party/bzip2/README.COMPILATION.PROBLEMS | 58 - third_party/bzip2/README.XML.STUFF | 45 - third_party/bzip2/blocksort.c | 11 +- third_party/bzip2/bz-common.xsl | 39 - third_party/bzip2/bz-fo.xsl | 276 -- third_party/bzip2/bz-html.xsl | 23 - third_party/bzip2/bz_internal_error.c | 22 + third_party/bzip2/bzip.css | 74 - .../{bzip2.1.preformatted => bzip2.1.txt} | 260 +- third_party/bzip2/bzip2.c | 315 +- third_party/bzip2/bzip2.mk | 82 +- third_party/bzip2/bzip2recover.c | 68 +- third_party/bzip2/bzlib.c | 54 +- third_party/bzip2/bzlib.h | 321 +- .../{bzlib_private.h => bzlib_private.inc} | 44 +- third_party/bzip2/compress.c | 5 +- third_party/bzip2/crctable.c | 185 +- third_party/bzip2/decompress.c | 3 +- third_party/bzip2/dlltest.c | 175 - third_party/bzip2/huffman.c | 11 +- third_party/bzip2/libbz2.def | 27 - third_party/bzip2/manual.xml | 2964 ----------------- third_party/bzip2/mk251.c | 31 - third_party/bzip2/randtable.c | 3 +- third_party/bzip2/spewG.c | 6 +- third_party/bzip2/unzcrash.c | 141 - third_party/bzip2/xmlproc.sh | 114 - third_party/third_party.mk | 1 + third_party/zlib/README.cosmo | 3 - 33 files changed, 568 insertions(+), 5071 deletions(-) delete mode 100644 third_party/bzip2/Makefile delete mode 100644 third_party/bzip2/Makefile-libbz2_so delete mode 100644 third_party/bzip2/README.COMPILATION.PROBLEMS delete mode 100644 third_party/bzip2/README.XML.STUFF delete mode 100644 third_party/bzip2/bz-common.xsl delete mode 100644 third_party/bzip2/bz-fo.xsl delete mode 100644 third_party/bzip2/bz-html.xsl create mode 100644 third_party/bzip2/bz_internal_error.c delete mode 100644 third_party/bzip2/bzip.css rename third_party/bzip2/{bzip2.1.preformatted => bzip2.1.txt} (67%) rename third_party/bzip2/{bzlib_private.h => bzlib_private.inc} (95%) delete mode 100644 third_party/bzip2/dlltest.c delete mode 100644 third_party/bzip2/libbz2.def delete mode 100644 third_party/bzip2/manual.xml delete mode 100644 third_party/bzip2/mk251.c delete mode 100644 third_party/bzip2/unzcrash.c delete mode 100755 third_party/bzip2/xmlproc.sh delete mode 100644 third_party/zlib/README.cosmo diff --git a/Makefile b/Makefile index 61580c281..86f56355c 100644 --- a/Makefile +++ b/Makefile @@ -117,6 +117,7 @@ include libc/alg/alg.mk # │ include libc/stdio/stdio.mk # │ include net/net.mk # │ include libc/log/log.mk # │ +include third_party/bzip2/bzip2.mk # │ include dsp/core/core.mk # │ include libc/x/x.mk # │ include third_party/stb/stb.mk # │ diff --git a/libc/nexgen32e/crc32.h b/libc/nexgen32e/crc32.h index 7890f980c..678f49d37 100644 --- a/libc/nexgen32e/crc32.h +++ b/libc/nexgen32e/crc32.h @@ -6,6 +6,7 @@ COSMOPOLITAN_C_START_ extern const uint32_t kCrc32cTab[256]; void crc32init(uint32_t[hasatleast 256], uint32_t); +uint32_t crc32a(uint32_t, const void *, size_t); uint32_t crc32c(uint32_t, const void *, size_t); uint32_t crc32_z(uint32_t, const void *, size_t); uint32_t crc32c_pure(uint32_t, const void *, size_t) strlenesque hidden; diff --git a/third_party/bzip2/Makefile b/third_party/bzip2/Makefile deleted file mode 100644 index f8a17722e..000000000 --- a/third_party/bzip2/Makefile +++ /dev/null @@ -1,217 +0,0 @@ -# ------------------------------------------------------------------ -# This file is part of bzip2/libbzip2, a program and library for -# lossless, block-sorting data compression. -# -# bzip2/libbzip2 version 1.0.8 of 13 July 2019 -# Copyright (C) 1996-2019 Julian Seward -# -# Please read the WARNING, DISCLAIMER and PATENTS sections in the -# README file. -# -# This program is released under the terms of the license contained -# in the file LICENSE. -# ------------------------------------------------------------------ - -SHELL=/bin/sh - -# To assist in cross-compiling -CC=gcc -AR=ar -RANLIB=ranlib -LDFLAGS= - -BIGFILES=-D_FILE_OFFSET_BITS=64 -CFLAGS=-Wall -Winline -O2 -g $(BIGFILES) - -# Where you want it installed when you do 'make install' -PREFIX=/usr/local - - -OBJS= blocksort.o \ - huffman.o \ - crctable.o \ - randtable.o \ - compress.o \ - decompress.o \ - bzlib.o - -all: libbz2.a bzip2 bzip2recover test - -bzip2: libbz2.a bzip2.o - $(CC) $(CFLAGS) $(LDFLAGS) -o bzip2 bzip2.o -L. -lbz2 - -bzip2recover: bzip2recover.o - $(CC) $(CFLAGS) $(LDFLAGS) -o bzip2recover bzip2recover.o - -libbz2.a: $(OBJS) - rm -f libbz2.a - $(AR) cq libbz2.a $(OBJS) - @if ( test -f $(RANLIB) -o -f /usr/bin/ranlib -o \ - -f /bin/ranlib -o -f /usr/ccs/bin/ranlib ) ; then \ - echo $(RANLIB) libbz2.a ; \ - $(RANLIB) libbz2.a ; \ - fi - -check: test -test: bzip2 - @cat words1 - ./bzip2 -1 < sample1.ref > sample1.rb2 - ./bzip2 -2 < sample2.ref > sample2.rb2 - ./bzip2 -3 < sample3.ref > sample3.rb2 - ./bzip2 -d < sample1.bz2 > sample1.tst - ./bzip2 -d < sample2.bz2 > sample2.tst - ./bzip2 -ds < sample3.bz2 > sample3.tst - cmp sample1.bz2 sample1.rb2 - cmp sample2.bz2 sample2.rb2 - cmp sample3.bz2 sample3.rb2 - cmp sample1.tst sample1.ref - cmp sample2.tst sample2.ref - cmp sample3.tst sample3.ref - @cat words3 - -install: bzip2 bzip2recover - if ( test ! -d $(PREFIX)/bin ) ; then mkdir -p $(PREFIX)/bin ; fi - if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi - if ( test ! -d $(PREFIX)/man ) ; then mkdir -p $(PREFIX)/man ; fi - if ( test ! -d $(PREFIX)/man/man1 ) ; then mkdir -p $(PREFIX)/man/man1 ; fi - if ( test ! -d $(PREFIX)/include ) ; then mkdir -p $(PREFIX)/include ; fi - cp -f bzip2 $(PREFIX)/bin/bzip2 - cp -f bzip2 $(PREFIX)/bin/bunzip2 - cp -f bzip2 $(PREFIX)/bin/bzcat - cp -f bzip2recover $(PREFIX)/bin/bzip2recover - chmod a+x $(PREFIX)/bin/bzip2 - chmod a+x $(PREFIX)/bin/bunzip2 - chmod a+x $(PREFIX)/bin/bzcat - chmod a+x $(PREFIX)/bin/bzip2recover - cp -f bzip2.1 $(PREFIX)/man/man1 - chmod a+r $(PREFIX)/man/man1/bzip2.1 - cp -f bzlib.h $(PREFIX)/include - chmod a+r $(PREFIX)/include/bzlib.h - cp -f libbz2.a $(PREFIX)/lib - chmod a+r $(PREFIX)/lib/libbz2.a - cp -f bzgrep $(PREFIX)/bin/bzgrep - ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzegrep - ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzfgrep - chmod a+x $(PREFIX)/bin/bzgrep - cp -f bzmore $(PREFIX)/bin/bzmore - ln -s -f $(PREFIX)/bin/bzmore $(PREFIX)/bin/bzless - chmod a+x $(PREFIX)/bin/bzmore - cp -f bzdiff $(PREFIX)/bin/bzdiff - ln -s -f $(PREFIX)/bin/bzdiff $(PREFIX)/bin/bzcmp - chmod a+x $(PREFIX)/bin/bzdiff - cp -f bzgrep.1 bzmore.1 bzdiff.1 $(PREFIX)/man/man1 - chmod a+r $(PREFIX)/man/man1/bzgrep.1 - chmod a+r $(PREFIX)/man/man1/bzmore.1 - chmod a+r $(PREFIX)/man/man1/bzdiff.1 - echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzegrep.1 - echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzfgrep.1 - echo ".so man1/bzmore.1" > $(PREFIX)/man/man1/bzless.1 - echo ".so man1/bzdiff.1" > $(PREFIX)/man/man1/bzcmp.1 - -clean: - rm -f *.o libbz2.a bzip2 bzip2recover \ - sample1.rb2 sample2.rb2 sample3.rb2 \ - sample1.tst sample2.tst sample3.tst - -blocksort.o: blocksort.c - @cat words0 - $(CC) $(CFLAGS) -c blocksort.c -huffman.o: huffman.c - $(CC) $(CFLAGS) -c huffman.c -crctable.o: crctable.c - $(CC) $(CFLAGS) -c crctable.c -randtable.o: randtable.c - $(CC) $(CFLAGS) -c randtable.c -compress.o: compress.c - $(CC) $(CFLAGS) -c compress.c -decompress.o: decompress.c - $(CC) $(CFLAGS) -c decompress.c -bzlib.o: bzlib.c - $(CC) $(CFLAGS) -c bzlib.c -bzip2.o: bzip2.c - $(CC) $(CFLAGS) -c bzip2.c -bzip2recover.o: bzip2recover.c - $(CC) $(CFLAGS) -c bzip2recover.c - - -distclean: clean - rm -f manual.ps manual.html manual.pdf - -DISTNAME=bzip2-1.0.8 -dist: check manual - rm -f $(DISTNAME) - ln -s -f . $(DISTNAME) - tar cvf $(DISTNAME).tar \ - $(DISTNAME)/blocksort.c \ - $(DISTNAME)/huffman.c \ - $(DISTNAME)/crctable.c \ - $(DISTNAME)/randtable.c \ - $(DISTNAME)/compress.c \ - $(DISTNAME)/decompress.c \ - $(DISTNAME)/bzlib.c \ - $(DISTNAME)/bzip2.c \ - $(DISTNAME)/bzip2recover.c \ - $(DISTNAME)/bzlib.h \ - $(DISTNAME)/bzlib_private.h \ - $(DISTNAME)/Makefile \ - $(DISTNAME)/LICENSE \ - $(DISTNAME)/bzip2.1 \ - $(DISTNAME)/bzip2.1.preformatted \ - $(DISTNAME)/bzip2.txt \ - $(DISTNAME)/words0 \ - $(DISTNAME)/words1 \ - $(DISTNAME)/words2 \ - $(DISTNAME)/words3 \ - $(DISTNAME)/sample1.ref \ - $(DISTNAME)/sample2.ref \ - $(DISTNAME)/sample3.ref \ - $(DISTNAME)/sample1.bz2 \ - $(DISTNAME)/sample2.bz2 \ - $(DISTNAME)/sample3.bz2 \ - $(DISTNAME)/dlltest.c \ - $(DISTNAME)/manual.html \ - $(DISTNAME)/manual.pdf \ - $(DISTNAME)/manual.ps \ - $(DISTNAME)/README \ - $(DISTNAME)/README.COMPILATION.PROBLEMS \ - $(DISTNAME)/README.XML.STUFF \ - $(DISTNAME)/CHANGES \ - $(DISTNAME)/libbz2.def \ - $(DISTNAME)/libbz2.dsp \ - $(DISTNAME)/dlltest.dsp \ - $(DISTNAME)/makefile.msc \ - $(DISTNAME)/unzcrash.c \ - $(DISTNAME)/spewG.c \ - $(DISTNAME)/mk251.c \ - $(DISTNAME)/bzdiff \ - $(DISTNAME)/bzdiff.1 \ - $(DISTNAME)/bzmore \ - $(DISTNAME)/bzmore.1 \ - $(DISTNAME)/bzgrep \ - $(DISTNAME)/bzgrep.1 \ - $(DISTNAME)/Makefile-libbz2_so \ - $(DISTNAME)/bz-common.xsl \ - $(DISTNAME)/bz-fo.xsl \ - $(DISTNAME)/bz-html.xsl \ - $(DISTNAME)/bzip.css \ - $(DISTNAME)/entities.xml \ - $(DISTNAME)/manual.xml \ - $(DISTNAME)/format.pl \ - $(DISTNAME)/xmlproc.sh - gzip -v $(DISTNAME).tar - -# For rebuilding the manual from sources on my SuSE 9.1 box - -MANUAL_SRCS= bz-common.xsl bz-fo.xsl bz-html.xsl bzip.css \ - entities.xml manual.xml - -manual: manual.html manual.ps manual.pdf - -manual.ps: $(MANUAL_SRCS) - ./xmlproc.sh -ps manual.xml - -manual.pdf: $(MANUAL_SRCS) - ./xmlproc.sh -pdf manual.xml - -manual.html: $(MANUAL_SRCS) - ./xmlproc.sh -html manual.xml diff --git a/third_party/bzip2/Makefile-libbz2_so b/third_party/bzip2/Makefile-libbz2_so deleted file mode 100644 index fb0f2306f..000000000 --- a/third_party/bzip2/Makefile-libbz2_so +++ /dev/null @@ -1,59 +0,0 @@ - -# This Makefile builds a shared version of the library, -# libbz2.so.1.0.8, with soname libbz2.so.1.0, -# at least on x86-Linux (RedHat 7.2), -# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98). -# Please see the README file for some important info -# about building the library like this. - -# ------------------------------------------------------------------ -# This file is part of bzip2/libbzip2, a program and library for -# lossless, block-sorting data compression. -# -# bzip2/libbzip2 version 1.0.8 of 13 July 2019 -# Copyright (C) 1996-2019 Julian Seward -# -# Please read the WARNING, DISCLAIMER and PATENTS sections in the -# README file. -# -# This program is released under the terms of the license contained -# in the file LICENSE. -# ------------------------------------------------------------------ - - -SHELL=/bin/sh -CC=gcc -BIGFILES=-D_FILE_OFFSET_BITS=64 -CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES) - -OBJS= blocksort.o \ - huffman.o \ - crctable.o \ - randtable.o \ - compress.o \ - decompress.o \ - bzlib.o - -all: $(OBJS) - $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.8 $(OBJS) - $(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.8 - rm -f libbz2.so.1.0 - ln -s libbz2.so.1.0.8 libbz2.so.1.0 - -clean: - rm -f $(OBJS) bzip2.o libbz2.so.1.0.8 libbz2.so.1.0 bzip2-shared - -blocksort.o: blocksort.c - $(CC) $(CFLAGS) -c blocksort.c -huffman.o: huffman.c - $(CC) $(CFLAGS) -c huffman.c -crctable.o: crctable.c - $(CC) $(CFLAGS) -c crctable.c -randtable.o: randtable.c - $(CC) $(CFLAGS) -c randtable.c -compress.o: compress.c - $(CC) $(CFLAGS) -c compress.c -decompress.o: decompress.c - $(CC) $(CFLAGS) -c decompress.c -bzlib.o: bzlib.c - $(CC) $(CFLAGS) -c bzlib.c diff --git a/third_party/bzip2/README.COMPILATION.PROBLEMS b/third_party/bzip2/README.COMPILATION.PROBLEMS deleted file mode 100644 index fa317a50c..000000000 --- a/third_party/bzip2/README.COMPILATION.PROBLEMS +++ /dev/null @@ -1,58 +0,0 @@ ------------------------------------------------------------------- -This file is part of bzip2/libbzip2, a program and library for -lossless, block-sorting data compression. - -bzip2/libbzip2 version 1.0.8 of 13 July 2019 -Copyright (C) 1996-2019 Julian Seward - -Please read the WARNING, DISCLAIMER and PATENTS sections in the -README file. - -This program is released under the terms of the license contained -in the file LICENSE. ------------------------------------------------------------------- - -bzip2 should compile without problems on the vast majority of -platforms. Using the supplied Makefile, I've built and tested it -myself for x86-linux and amd64-linux. With makefile.msc, Visual C++ -6.0 and nmake, you can build a native Win32 version too. Large file -support seems to work correctly on at least on amd64-linux. - -When I say "large file" I mean a file of size 2,147,483,648 (2^31) -bytes or above. Many older OSs can't handle files above this size, -but many newer ones can. Large files are pretty huge -- most files -you'll encounter are not Large Files. - -Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety -of platforms without difficulty, and I hope this version will continue -in that tradition. However, in order to support large files, I've had -to include the define -D_FILE_OFFSET_BITS=64 in the Makefile. This -can cause problems. - -The technique of adding -D_FILE_OFFSET_BITS=64 to get large file -support is, as far as I know, the Recommended Way to get correct large -file support. For more details, see the Large File Support -Specification, published by the Large File Summit, at - - http://ftp.sas.com/standards/large.file - -As a general comment, if you get compilation errors which you think -are related to large file support, try removing the above define from -the Makefile, ie, delete the line - - BIGFILES=-D_FILE_OFFSET_BITS=64 - -from the Makefile, and do 'make clean ; make'. This will give you a -version of bzip2 without large file support, which, for most -applications, is probably not a problem. - -Alternatively, try some of the platform-specific hints listed below. - -You can use the spewG.c program to generate huge files to test bzip2's -large file support, if you are feeling paranoid. Be aware though that -any compilation problems which affect bzip2 will also affect spewG.c, -alas. - -AIX: I have reports that for large file support, you need to specify --D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64. I have not tested -this myself. diff --git a/third_party/bzip2/README.XML.STUFF b/third_party/bzip2/README.XML.STUFF deleted file mode 100644 index 1503476eb..000000000 --- a/third_party/bzip2/README.XML.STUFF +++ /dev/null @@ -1,45 +0,0 @@ - ---------------------------------------------------------------- - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.8 of 13 July 2019 - Copyright (C) 1996-2019 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ---------------------------------------------------------------- - -The script xmlproc.sh takes an xml file as input, -and processes it to create .pdf, .html or .ps output. -It uses format.pl, a perl script to format
 blocks nicely,
- and add CDATA tags so writers do not have to use eg. < 
-
-The file "entities.xml" must be edited to reflect current
-version, year, etc.
-
-
-Usage:
-
-  ./xmlproc.sh -v manual.xml
-  Validates an xml file to ensure no dtd-compliance errors
-
-  ./xmlproc.sh -html manual.xml
-  Output: manual.html
-
-  ./xmlproc.sh -pdf manual.xml
-  Output: manual.pdf
-
-  ./xmlproc.sh -ps manual.xml
-  Output: manual.ps
-
-
-Notum bene: 
-- pdfxmltex barfs if given a filename with an underscore in it
-
-- xmltex won't work yet - there's a bug in passivetex
-    which we are all waiting for Sebastian to fix.
-  So we are going the xml -> pdf -> ps route for the time being,
-    using pdfxmltex.
diff --git a/third_party/bzip2/blocksort.c b/third_party/bzip2/blocksort.c
index 92d81fe28..2069bd0bc 100644
--- a/third_party/bzip2/blocksort.c
+++ b/third_party/bzip2/blocksort.c
@@ -1,3 +1,4 @@
+/* clang-format off */
 
 /*-------------------------------------------------------------*/
 /*--- Block sorting machinery                               ---*/
@@ -19,7 +20,9 @@
    ------------------------------------------------------------------ */
 
 
-#include "bzlib_private.h"
+#include "libc/runtime/gc.internal.h"
+#include "libc/mem/mem.h"
+#include "third_party/bzip2/bzlib_private.inc"
 
 /*---------------------------------------------*/
 /*--- Fallback O(N log(N)^2) sorting        ---*/
@@ -757,10 +760,10 @@ void mainSort ( UInt32* ptr,
                 Int32*  budget )
 {
    Int32  i, j, k, ss, sb;
-   Int32  runningOrder[256];
    Bool   bigDone[256];
-   Int32  copyStart[256];
-   Int32  copyEnd  [256];
+   Int32  *runningOrder = gc(calloc(256,4));
+   Int32  *copyStart = gc(calloc(256,4));
+   Int32  *copyEnd = gc(calloc(256,4));
    UChar  c1;
    Int32  numQSorted;
    UInt16 s;
diff --git a/third_party/bzip2/bz-common.xsl b/third_party/bzip2/bz-common.xsl
deleted file mode 100644
index 66fcd6fe0..000000000
--- a/third_party/bzip2/bz-common.xsl
+++ /dev/null
@@ -1,39 +0,0 @@
- 
-
-
-
- 
-
-
-
- 
- 
-   
-    
-      
-     
-  
-
-
-
-
-set       toc,title
-book      toc,title,figure,table,example,equation
-chapter   toc,title
-section   toc
-sect1     toc
-sect2     toc
-sect3     toc
-sect4     nop
-sect5     nop
-qandaset  toc
-qandadiv  nop
-appendix  toc,title
-article/appendix  nop
-article   toc,title
-preface   toc,title
-reference toc,title
-
-
-
diff --git a/third_party/bzip2/bz-fo.xsl b/third_party/bzip2/bz-fo.xsl
deleted file mode 100644
index ba3e30123..000000000
--- a/third_party/bzip2/bz-fo.xsl
+++ /dev/null
@@ -1,276 +0,0 @@
- 
-
-
-
-
-
-
-
-
-
-
-
-
-      
-     
-   
-
-
-
-
- 
-
-
-
-
-
-
-  
-
-
-
-
-  blue
-
-
-
-
-  
-    
-  
-
-
-
-  
-    
-  
-
-
-
-
-  
-  
-  
-    
-      
-    
-  
-  
-    
-      
-        
-          
-          
-          
-        
-      
-    
-    
-          
-    
-  
-  
-    
-      
-        
-      
-    
-    
-      
-        
-      
-    
-  
-
-
-
-
-  
-  
-  
-    
-      
-        
-      
-    
-    
-          
-    
-  
-  
-    
-      
-        
-      
-    
-    
-      
-        
-      
-    
-  
-
-
-
-
-
-  
-    
-  
-    
-  
-  
-    
-      
-    
-  
-
-
-
-
-
-  
-  
-  
-  
-    
-      0pt
-    
-  
-  
-    
-      
-      
-      
-        
-          
-            baseline
-             
-               
-            
-          
-          
-            baseline
-            
-              
-                
-                
-                
-                
-              
-            
-          
-        
-      
-    
-  
-  
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
-
-
-
-
-  
-  
-  
-  
-    
-      0pt
-    
-  
-  
-    
-      
-        
-        
-        
-      
-      
-      
-      
-        
-          
-            baseline
-            
-               
-            
-          
-          
-            baseline
-            
-              
-                
-                
-                
-                
-              
-            
-          
-        
-      
-    
-  
-  
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
-
-
-
-
-
-  always
-  
-    
-  
-  
-    
-    pt
-  
-  
-    
-    pt
-  
-  false
-
-
-
-
diff --git a/third_party/bzip2/bz-html.xsl b/third_party/bzip2/bz-html.xsl
deleted file mode 100644
index b6000d586..000000000
--- a/third_party/bzip2/bz-html.xsl
+++ /dev/null
@@ -1,23 +0,0 @@
- 
- ]>
-
-
-
-
-
-
-
-
-
-
-
-  
-link rel="stylesheet" type="text/css" href="bzip.css" />
-  
-  
-
-
-
diff --git a/third_party/bzip2/bz_internal_error.c b/third_party/bzip2/bz_internal_error.c
new file mode 100644
index 000000000..4b0ed204c
--- /dev/null
+++ b/third_party/bzip2/bz_internal_error.c
@@ -0,0 +1,22 @@
+/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
+│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
+╞══════════════════════════════════════════════════════════════════════════════╡
+│ Copyright 2021 Justine Alexandra Roberts Tunney                              │
+│                                                                              │
+│ Permission to use, copy, modify, and/or distribute this software for         │
+│ any purpose with or without fee is hereby granted, provided that the         │
+│ above copyright notice and this permission notice appear in all copies.      │
+│                                                                              │
+│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
+│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
+│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
+│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
+│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
+│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
+│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
+│ PERFORMANCE OF THIS SOFTWARE.                                                │
+╚─────────────────────────────────────────────────────────────────────────────*/
+
+void bz_internal_error(int err) {
+  asm("hlt");
+}
diff --git a/third_party/bzip2/bzip.css b/third_party/bzip2/bzip.css
deleted file mode 100644
index 211311838..000000000
--- a/third_party/bzip2/bzip.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Colours:
-#74240f  dark brown      h1, h2, h3, h4
-#336699  medium blue     links
-#339999  turquoise       link hover colour
-#202020  almost black    general text
-#761596  purple          md5sum text
-#626262  dark gray       pre border
-#eeeeee  very light gray pre background
-#f2f2f9  very light blue nav table background
-#3366cc  medium blue     nav table border
-*/
-
-a, a:link, a:visited, a:active { color: #336699; }
-a:hover { color: #339999; }
-
-body { font: 80%/126% sans-serif; }
-h1, h2, h3, h4 { color: #74240f; }
-
-dt { color: #336699; font-weight: bold }
-dd { 
- margin-left: 1.5em; 
- padding-bottom: 0.8em;
-}
-
-/* -- ruler -- */
-div.hr_blue { 
-  height:  3px; 
-  background:#ffffff url("../images/hr_blue.png") repeat-x; }
-div.hr_blue hr { display:none; }
-
-/* release styles */
-#release p { margin-top: 0.4em; }
-#release .md5sum { color: #761596; }
-
-
-/* ------ styles for docs|manuals|howto ------ */
-/* -- lists -- */
-ul  { 
- margin:     0px 4px 16px 16px;
- padding:    0px;
- list-style: url("../images/li-blue.png"); 
-}
-ul li { 
- margin-bottom: 10px;
-}
-ul ul	{ 
- list-style-type:  none; 
- list-style-image: none; 
- margin-left:      0px; 
-}
-
-/* header / footer nav tables */
-table.nav {
- border:     solid 1px #3366cc;
- background: #f2f2f9;
- background-color: #f2f2f9;
- margin-bottom: 0.5em;
-}
-/* don't have underlined links in chunked nav menus */
-table.nav a { text-decoration: none; }
-table.nav a:hover { text-decoration: underline; }
-table.nav td { font-size: 85%; }
-
-code, tt, pre { font-size: 120%; }
-code, tt { color: #761596; }
-
-div.literallayout, pre.programlisting, pre.screen {
- color:      #000000;
- padding:    0.5em;
- background: #eeeeee;
- border:     1px solid #626262;
- background-color: #eeeeee;
- margin: 4px 0px 4px 0px; 
-}
diff --git a/third_party/bzip2/bzip2.1.preformatted b/third_party/bzip2/bzip2.1.txt
similarity index 67%
rename from third_party/bzip2/bzip2.1.preformatted
rename to third_party/bzip2/bzip2.1.txt
index 787f1c614..2a5484ad8 100644
--- a/third_party/bzip2/bzip2.1.preformatted
+++ b/third_party/bzip2/bzip2.1.txt
@@ -2,54 +2,54 @@ bzip2(1)                                                 bzip2(1)
 
 
 
-NNAAMMEE
-       bzip2, bunzip2 − a block‐sorting file compressor, v1.0.8
+𝐍𝐀𝐌𝐄
+       bzip2, bunzip2 − a block-sorting file compressor, v1.0.8
        bzcat − decompresses files to stdout
        bzip2recover − recovers data from damaged bzip2 files
 
 
-SSYYNNOOPPSSIISS
-       bbzziipp22 [ −−ccddffkkqqssttvvzzVVLL112233445566778899 ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbuunnzziipp22 [ −−ffkkvvssVVLL ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbzzccaatt [ −−ss ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbzziipp22rreeccoovveerr _f_i_l_e_n_a_m_e
+𝐒𝐘𝐍𝐎𝐏𝐒𝐈𝐒
+       𝗯𝘇𝗶𝗽𝟮 [ −𝗰𝗱𝗳𝗸𝗾𝘀𝘁𝘃𝘇𝐕𝐋𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵 ] [ f̲i̲l̲e̲n̲a̲m̲e̲s̲ .̲.̲.̲  ]
+       𝗯𝘂𝗻𝘇𝗶𝗽𝟮 [ −𝗳𝗸𝘃𝘀𝐕𝐋 ] [ f̲i̲l̲e̲n̲a̲m̲e̲s̲ .̲.̲.̲  ]
+       𝗯𝘇𝗰𝗮𝘁 [ −𝘀 ] [ f̲i̲l̲e̲n̲a̲m̲e̲s̲ .̲.̲.̲  ]
+       𝗯𝘇𝗶𝗽𝟮𝗿𝗲𝗰𝗼𝘃𝗲𝗿 f̲i̲l̲e̲n̲a̲m̲e̲
 
 
-DDEESSCCRRIIPPTTIIOONN
-       _b_z_i_p_2  compresses  files  using  the Burrows‐Wheeler block
+𝐃𝐄𝐒𝐂𝐑𝐈𝐏𝐓𝐈𝐎𝐍
+       b̲z̲i̲p̲2̲  compresses  files  using  the Burrows-Wheeler block
        sorting text compression algorithm,  and  Huffman  coding.
        Compression  is  generally  considerably  better than that
-       achieved by more conventional LZ77/LZ78‐based compressors,
-       and  approaches  the performance of the PPM family of sta­
+       achieved by more conventional LZ77/LZ78-based compressors,
+       and  approaches  the performance of the PPM family of sta-
        tistical compressors.
 
-       The command‐line options are deliberately very similar  to
-       those of _G_N_U _g_z_i_p_, but they are not identical.
+       The command-line options are deliberately very similar  to
+       those of G̲N̲U̲ g̲z̲i̲p̲,̲ but they are not identical.
 
-       _b_z_i_p_2  expects  a list of file names to accompany the com­
-       mand‐line flags.  Each file is replaced  by  a  compressed
+       b̲z̲i̲p̲2̲  expects  a list of file names to accompany the com-
+       mand-line flags.  Each file is replaced  by  a  compressed
        version  of  itself,  with  the  name "original_name.bz2".
-       Each compressed file has the same modification date,  per­
-       missions, and, when possible, ownership as the correspond­
+       Each compressed file has the same modification date,  per-
+       missions, and, when possible, ownership as the correspond-
        ing original, so that these properties  can  be  correctly
        restored  at  decompression  time.   File name handling is
-       naive in the sense that there is no mechanism for preserv­
+       naive in the sense that there is no mechanism for preserv-
        ing  original file names, permissions, ownerships or dates
        in filesystems which lack these concepts, or have  serious
-       file name length restrictions, such as MS‐DOS.
+       file name length restrictions, such as MS-DOS.
 
-       _b_z_i_p_2  and  _b_u_n_z_i_p_2 will by default not overwrite existing
+       b̲z̲i̲p̲2̲  and  b̲u̲n̲z̲i̲p̲2̲ will by default not overwrite existing
        files.  If you want this to happen, specify the −f flag.
 
-       If no file names  are  specified,  _b_z_i_p_2  compresses  from
-       standard  input  to  standard output.  In this case, _b_z_i_p_2
+       If no file names  are  specified,  b̲z̲i̲p̲2̲  compresses  from
+       standard  input  to  standard output.  In this case, b̲z̲i̲p̲2̲
        will decline to write compressed output to a terminal,  as
        this  would  be  entirely  incomprehensible  and therefore
        pointless.
 
-       _b_u_n_z_i_p_2 (or _b_z_i_p_2 _−_d_) decompresses  all  specified  files.
-       Files which were not created by _b_z_i_p_2 will be detected and
-       ignored, and a warning issued.  _b_z_i_p_2  attempts  to  guess
+       b̲u̲n̲z̲i̲p̲2̲ (or b̲z̲i̲p̲2̲ −̲d̲)̲ decompresses  all  specified  files.
+       Files which were not created by b̲z̲i̲p̲2̲ will be detected and
+       ignored, and a warning issued.  b̲z̲i̲p̲2̲  attempts  to  guess
        the  filename  for  the decompressed file from that of the
        compressed file as follows:
 
@@ -60,34 +60,34 @@ DDEESSCCRRIIPPTTIIOONN
               anyothername    becomes   anyothername.out
 
        If the file does not end in one of the recognised endings,
-       _._b_z_2_,  _._b_z_,  _._t_b_z_2 or _._t_b_z_, _b_z_i_p_2 complains that it cannot
+       .̲b̲z̲2̲,̲  .̲b̲z̲,̲  .̲t̲b̲z̲2̲ or .̲t̲b̲z̲,̲ b̲z̲i̲p̲2̲ complains that it cannot
        guess the name of the original file, and uses the original
-       name with _._o_u_t appended.
+       name with .̲o̲u̲t̲ appended.
 
-       As  with compression, supplying no filenames causes decom­
+       As  with compression, supplying no filenames causes decom-
        pression from standard input to standard output.
 
-       _b_u_n_z_i_p_2 will correctly decompress a file which is the con­
+       b̲u̲n̲z̲i̲p̲2̲ will correctly decompress a file which is the con-
        catenation of two or more compressed files.  The result is
        the concatenation of the corresponding uncompressed files.
        Integrity testing (−t) of concatenated compressed files is
        also supported.
 
        You can also compress or decompress files to the  standard
-       output  by giving the −c flag.  Multiple files may be com­
+       output  by giving the −c flag.  Multiple files may be com-
        pressed and decompressed like this.  The resulting outputs
        are  fed  sequentially to stdout.  Compression of multiple
-       files in this manner generates a stream containing  multi­
+       files in this manner generates a stream containing  multi-
        ple compressed file representations.  Such a stream can be
-       decompressed correctly only  by  _b_z_i_p_2  version  0.9.0  or
-       later.   Earlier  versions of _b_z_i_p_2 will stop after decom­
+       decompressed correctly only  by  b̲z̲i̲p̲2̲  version  0.9.0  or
+       later.   Earlier  versions of b̲z̲i̲p̲2̲ will stop after decom-
        pressing the first file in the stream.
 
-       _b_z_c_a_t (or _b_z_i_p_2 _‐_d_c_) decompresses all specified  files  to
+       b̲z̲c̲a̲t̲ (or b̲z̲i̲p̲2̲ -̲d̲c̲)̲ decompresses all specified  files  to
        the standard output.
 
-       _b_z_i_p_2  will  read arguments from the environment variables
-       _B_Z_I_P_2 and _B_Z_I_P_, in  that  order,  and  will  process  them
+       b̲z̲i̲p̲2̲  will  read arguments from the environment variables
+       B̲Z̲I̲P̲2̲ and B̲Z̲I̲P̲,̲ in  that  order,  and  will  process  them
        before  any  arguments  read  from the command line.  This
        gives a convenient way to supply default arguments.
 
@@ -99,60 +99,60 @@ DDEESSCCRRIIPPTTIIOONN
        most  file  compressors)  is  coded at about 8.05 bits per
        byte, giving an expansion of around 0.5%.
 
-       As a self‐check for your  protection,  _b_z_i_p_2  uses  32‐bit
+       As a self-check for your  protection,  b̲z̲i̲p̲2̲  uses  32-bit
        CRCs  to make sure that the decompressed version of a file
-       is identical to the original.  This guards against corrup­
+       is identical to the original.  This guards against corrup-
        tion  of  the compressed data, and against undetected bugs
-       in _b_z_i_p_2 (hopefully very unlikely).  The chances  of  data
+       in b̲z̲i̲p̲2̲ (hopefully very unlikely).  The chances  of  data
        corruption  going  undetected  is  microscopic,  about one
        chance in four billion for each file processed.  Be aware,
        though,  that  the  check occurs upon decompression, so it
        can only tell you that something is wrong.  It can’t  help
        you  recover  the original uncompressed data.  You can use
-       _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
+       b̲z̲i̲p̲2̲r̲e̲c̲o̲v̲e̲r̲ to try to recover data from damaged files.
 
        Return values: 0 for a normal exit,  1  for  environmental
        problems  (file not found, invalid flags, I/O errors, &c),
        2 to indicate a corrupt compressed file, 3 for an internal
-       consistency error (eg, bug) which caused _b_z_i_p_2 to panic.
+       consistency error (eg, bug) which caused b̲z̲i̲p̲2̲ to panic.
 
 
-OOPPTTIIOONNSS
-       −−cc ‐‐‐‐ssttddoouutt
+𝐎𝐏𝐓𝐈𝐎𝐍𝐒
+       −𝗰 --𝘀𝘁𝗱𝗼𝘂𝘁
               Compress or decompress to standard output.
 
-       −−dd ‐‐‐‐ddeeccoommpprreessss
-              Force  decompression.  _b_z_i_p_2_, _b_u_n_z_i_p_2 and _b_z_c_a_t are
+       −𝗱 --𝗱𝗲𝗰𝗼𝗺𝗽𝗿𝗲𝘀𝘀
+              Force  decompression.  b̲z̲i̲p̲2̲,̲ b̲u̲n̲z̲i̲p̲2̲ and b̲z̲c̲a̲t̲ are
               really the same program,  and  the  decision  about
               what  actions to take is done on the basis of which
               name is used.  This flag overrides that  mechanism,
-              and forces _b_z_i_p_2 to decompress.
+              and forces b̲z̲i̲p̲2̲ to decompress.
 
-       −−zz ‐‐‐‐ccoommpprreessss
+       −𝘇 --𝗰𝗼𝗺𝗽𝗿𝗲𝘀𝘀
               The   complement   to   −d:   forces   compression,
               regardless of the invocation name.
 
-       −−tt ‐‐‐‐tteesstt
+       −𝘁 --𝘁𝗲𝘀𝘁
               Check integrity of the specified file(s), but don’t
               decompress  them.   This  really  performs  a trial
               decompression and throws away the result.
 
-       −−ff ‐‐‐‐ffoorrccee
-              Force overwrite of output files.   Normally,  _b_z_i_p_2
+       −𝗳 --𝗳𝗼𝗿𝗰𝗲
+              Force overwrite of output files.   Normally,  b̲z̲i̲p̲2̲
               will  not  overwrite  existing  output files.  Also
-              forces _b_z_i_p_2 to break hard links to files, which it
+              forces b̲z̲i̲p̲2̲ to break hard links to files, which it
               otherwise wouldn’t do.
 
               bzip2  normally  declines to decompress files which
               don’t have the  correct  magic  header  bytes.   If
-              forced  (‐f),  however,  it  will  pass  such files
+              forced  (-f),  however,  it  will  pass  such files
               through unmodified.  This is how GNU gzip  behaves.
 
-       −−kk ‐‐‐‐kkeeeepp
+       −𝗸 --𝗸𝗲𝗲𝗽
               Keep  (don’t delete) input files during compression
               or decompression.
 
-       −−ss ‐‐‐‐ssmmaallll
+       −𝘀 --𝘀𝗺𝗮𝗹𝗹
               Reduce memory usage, for compression, decompression
               and  testing.   Files  are  decompressed and tested
               using a modified algorithm which only requires  2.5
@@ -167,53 +167,53 @@ OOPPTTIIOONNSS
               megabytes  or  less),  use  −s for everything.  See
               MEMORY MANAGEMENT below.
 
-       −−qq ‐‐‐‐qquuiieett
-              Suppress non‐essential warning messages.   Messages
+       −𝗾 --𝗾𝘂𝗶𝗲𝘁
+              Suppress non-essential warning messages.   Messages
               pertaining  to I/O errors and other critical events
               will not be suppressed.
 
-       −−vv ‐‐‐‐vveerrbboossee
-              Verbose mode ‐‐ show the compression ratio for each
-              file  processed.   Further  −v’s  increase the ver­
+       −𝘃 --𝘃𝗲𝗿𝗯𝗼𝘀𝗲
+              Verbose mode -- show the compression ratio for each
+              file  processed.   Further  −v’s  increase the ver-
               bosity level, spewing out lots of information which
               is primarily of interest for diagnostic purposes.
 
-       −−LL ‐‐‐‐lliicceennssee ‐‐VV ‐‐‐‐vveerrssiioonn
+       −𝐋 --𝗹𝗶𝗰𝗲𝗻𝘀𝗲 -𝐕 --𝘃𝗲𝗿𝘀𝗶𝗼𝗻
               Display  the  software  version,  license terms and
               conditions.
 
-       −−11 ((oorr −−−−ffaasstt)) ttoo −−99 ((oorr −−−−bbeesstt))
+       −𝟭 (𝗼𝗿 −−𝗳𝗮𝘀𝘁) 𝘁𝗼 −𝟵 (𝗼𝗿 −−𝗯𝗲𝘀𝘁)
               Set the block size to 100 k, 200 k ..  900  k  when
               compressing.   Has  no  effect  when decompressing.
               See MEMORY MANAGEMENT below.  The −−fast and −−best
               aliases  are  primarily for GNU gzip compatibility.
-              In particular, −−fast doesn’t make things  signifi­
+              In particular, −−fast doesn’t make things  signifi-
               cantly  faster.   And  −−best  merely  selects  the
               default behaviour.
 
-       −−‐‐     Treats all subsequent arguments as file names, even
-              if they start with a dash.  This is so you can han­
+       −-     Treats all subsequent arguments as file names, even
+              if they start with a dash.  This is so you can han-
               dle files with names beginning  with  a  dash,  for
-              example: bzip2 −‐ −myfilename.
+              example: bzip2 −- −myfilename.
 
-       −−‐‐rreeppeettiittiivvee‐‐ffaasstt ‐‐‐‐rreeppeettiittiivvee‐‐bbeesstt
+       −-𝗿𝗲𝗽𝗲𝘁𝗶𝘁𝗶𝘃𝗲-𝗳𝗮𝘀𝘁 --𝗿𝗲𝗽𝗲𝘁𝗶𝘁𝗶𝘃𝗲-𝗯𝗲𝘀𝘁
               These  flags  are  redundant  in versions 0.9.5 and
               above.  They provided some coarse control over  the
-              behaviour  of the sorting algorithm in earlier ver­
+              behaviour  of the sorting algorithm in earlier ver-
               sions, which was sometimes useful.  0.9.5 and above
               have  an  improved  algorithm  which  renders these
               flags irrelevant.
 
 
-MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
-       _b_z_i_p_2 compresses large files in blocks.   The  block  size
+𝐌𝐄𝐌𝐎𝐑𝐘 𝐌𝐀𝐍𝐀𝐆𝐄𝐌𝐄𝐍𝐓
+       b̲z̲i̲p̲2̲ compresses large files in blocks.   The  block  size
        affects  both  the  compression  ratio  achieved,  and the
        amount of memory needed for compression and decompression.
        The  flags  −1  through  −9  specify  the block size to be
-       100,000 bytes through 900,000 bytes (the default)  respec­
+       100,000 bytes through 900,000 bytes (the default)  respec-
        tively.   At  decompression  time, the block size used for
        compression is read from  the  header  of  the  compressed
-       file, and _b_u_n_z_i_p_2 then allocates itself just enough memory
+       file, and b̲u̲n̲z̲i̲p̲2̲ then allocates itself just enough memory
        to decompress the file.  Since block sizes are  stored  in
        compressed  files,  it follows that the flags −1 to −9 are
        irrelevant to and so ignored during decompression.
@@ -229,30 +229,30 @@ MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
        Larger  block  sizes  give  rapidly  diminishing  marginal
        returns.  Most of the compression comes from the first two
        or  three hundred k of block size, a fact worth bearing in
-       mind when using _b_z_i_p_2  on  small  machines.   It  is  also
+       mind when using b̲z̲i̲p̲2̲  on  small  machines.   It  is  also
        important  to  appreciate  that  the  decompression memory
        requirement is set at compression time by  the  choice  of
        block size.
 
        For  files  compressed  with  the default 900k block size,
-       _b_u_n_z_i_p_2 will require about 3700 kbytes to decompress.   To
+       b̲u̲n̲z̲i̲p̲2̲ will require about 3700 kbytes to decompress.   To
        support decompression of any file on a 4 megabyte machine,
-       _b_u_n_z_i_p_2 has an option to  decompress  using  approximately
-       half this amount of memory, about 2300 kbytes.  Decompres­
+       b̲u̲n̲z̲i̲p̲2̲ has an option to  decompress  using  approximately
+       half this amount of memory, about 2300 kbytes.  Decompres-
        sion speed is also halved, so you should use  this  option
-       only where necessary.  The relevant flag is ‐s.
+       only where necessary.  The relevant flag is -s.
 
-       In general, try and use the largest block size memory con­
+       In general, try and use the largest block size memory con-
        straints  allow,  since  that  maximises  the  compression
-       achieved.   Compression and decompression speed are virtu­
+       achieved.   Compression and decompression speed are virtu-
        ally unaffected by block size.
 
        Another significant point applies to files which fit in  a
-       single  block  ‐‐  that  means  most files you’d encounter
+       single  block  --  that  means  most files you’d encounter
        using a large block  size.   The  amount  of  real  memory
        touched is proportional to the size of the file, since the
        file is smaller than a block.  For example, compressing  a
-       file  20,000  bytes  long  with the flag ‐9 will cause the
+       file  20,000  bytes  long  with the flag -9 will cause the
        compressor to allocate around 7600k of  memory,  but  only
        touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
        decompressor will allocate 3700k but  only  touch  100k  +
@@ -260,95 +260,95 @@ MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
 
        Here  is a table which summarises the maximum memory usage
        for different block sizes.  Also  recorded  is  the  total
-       compressed  size for 14 files of the Calgary Text Compres­
+       compressed  size for 14 files of the Calgary Text Compres-
        sion Corpus totalling 3,141,622 bytes.  This column  gives
        some  feel  for  how  compression  varies with block size.
        These figures tend to understate the advantage  of  larger
-       block  sizes  for  larger files, since the Corpus is domi­
+       block  sizes  for  larger files, since the Corpus is domi-
        nated by smaller files.
 
                   Compress   Decompress   Decompress   Corpus
-           Flag     usage      usage       ‐s usage     Size
+           Flag     usage      usage       -s usage     Size
 
-            ‐1      1200k       500k         350k      914704
-            ‐2      2000k       900k         600k      877703
-            ‐3      2800k      1300k         850k      860338
-            ‐4      3600k      1700k        1100k      846899
-            ‐5      4400k      2100k        1350k      845160
-            ‐6      5200k      2500k        1600k      838626
-            ‐7      6100k      2900k        1850k      834096
-            ‐8      6800k      3300k        2100k      828642
-            ‐9      7600k      3700k        2350k      828642
+            -1      1200k       500k         350k      914704
+            -2      2000k       900k         600k      877703
+            -3      2800k      1300k         850k      860338
+            -4      3600k      1700k        1100k      846899
+            -5      4400k      2100k        1350k      845160
+            -6      5200k      2500k        1600k      838626
+            -7      6100k      2900k        1850k      834096
+            -8      6800k      3300k        2100k      828642
+            -9      7600k      3700k        2350k      828642
 
 
-RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
-       _b_z_i_p_2 compresses files in blocks, usually 900kbytes  long.
-       Each block is handled independently.  If a media or trans­
-       mission error causes a multi‐block  .bz2  file  to  become
+𝐑𝐄𝐂𝐎𝐕𝐄𝐑𝐈𝐍𝐆 𝐃𝐀𝐓𝐀 𝐅𝐑𝐎𝐌 𝐃𝐀𝐌𝐀𝐆𝐄𝐃 𝐅𝐈𝐋𝐄𝐒
+       b̲z̲i̲p̲2̲ compresses files in blocks, usually 900kbytes  long.
+       Each block is handled independently.  If a media or trans-
+       mission error causes a multi-block  .bz2  file  to  become
        damaged,  it  may  be  possible  to  recover data from the
        undamaged blocks in the file.
 
        The compressed representation of each block  is  delimited
-       by  a  48‐bit pattern, which makes it possible to find the
+       by  a  48-bit pattern, which makes it possible to find the
        block boundaries with reasonable  certainty.   Each  block
-       also  carries its own 32‐bit CRC, so damaged blocks can be
+       also  carries its own 32-bit CRC, so damaged blocks can be
        distinguished from undamaged ones.
 
-       _b_z_i_p_2_r_e_c_o_v_e_r is a  simple  program  whose  purpose  is  to
+       b̲z̲i̲p̲2̲r̲e̲c̲o̲v̲e̲r̲ is a  simple  program  whose  purpose  is  to
        search  for blocks in .bz2 files, and write each block out
-       into its own .bz2 file.  You can then use _b_z_i_p_2 −t to test
+       into its own .bz2 file.  You can then use b̲z̲i̲p̲2̲ −t to test
        the integrity of the resulting files, and decompress those
        which are undamaged.
 
-       _b_z_i_p_2_r_e_c_o_v_e_r takes a single argument, the name of the dam­
+       b̲z̲i̲p̲2̲r̲e̲c̲o̲v̲e̲r̲ takes a single argument, the name of the dam-
        aged    file,    and    writes    a    number   of   files
        "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
        the   extracted   blocks.   The   output   filenames   are
-       designed  so  that the use of wildcards in subsequent pro­
-       cessing  ‐‐ for example, "bzip2 ‐dc  rec*file.bz2 > recov­
-       ered_data" ‐‐ processes the files in the correct order.
+       designed  so  that the use of wildcards in subsequent pro-
+       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov-
+       ered_data" -- processes the files in the correct order.
 
-       _b_z_i_p_2_r_e_c_o_v_e_r should be of most use dealing with large .bz2
+       b̲z̲i̲p̲2̲r̲e̲c̲o̲v̲e̲r̲ should be of most use dealing with large .bz2
        files,  as  these will contain many blocks.  It is clearly
-       futile to use it on damaged single‐block  files,  since  a
-       damaged  block  cannot  be recovered.  If you wish to min­
-       imise any potential data loss through media  or  transmis­
+       futile to use it on damaged single-block  files,  since  a
+       damaged  block  cannot  be recovered.  If you wish to min-
+       imise any potential data loss through media  or  transmis-
        sion errors, you might consider compressing with a smaller
        block size.
 
 
-PPEERRFFOORRMMAANNCCEE NNOOTTEESS
+𝐏𝐄𝐑𝐅𝐎𝐑𝐌𝐀𝐍𝐂𝐄 𝐍𝐎𝐓𝐄𝐒
        The sorting phase of compression gathers together  similar
        strings  in  the  file.  Because of this, files containing
        very long runs of  repeated  symbols,  like  "aabaabaabaab
        ..."   (repeated  several hundred times) may compress more
        slowly than normal.  Versions 0.9.5 and  above  fare  much
        better  than previous versions in this respect.  The ratio
-       between worst‐case and average‐case compression time is in
+       between worst-case and average-case compression time is in
        the  region  of  10:1.  For previous versions, this figure
-       was more like 100:1.  You can use the −vvvv option to mon­
+       was more like 100:1.  You can use the −vvvv option to mon-
        itor progress in great detail, if you want.
 
        Decompression speed is unaffected by these phenomena.
 
-       _b_z_i_p_2  usually  allocates  several  megabytes of memory to
-       operate in, and then charges all over it in a fairly  ran­
-       dom  fashion.   This means that performance, both for com­
+       b̲z̲i̲p̲2̲  usually  allocates  several  megabytes of memory to
+       operate in, and then charges all over it in a fairly  ran-
+       dom  fashion.   This means that performance, both for com-
        pressing and decompressing, is largely determined  by  the
        speed  at  which  your  machine  can service cache misses.
        Because of this, small changes to the code to  reduce  the
        miss  rate  have  been observed to give disproportionately
-       large performance improvements.  I imagine _b_z_i_p_2 will per­
+       large performance improvements.  I imagine b̲z̲i̲p̲2̲ will per-
        form best on machines with very large caches.
 
 
-CCAAVVEEAATTSS
+𝐂𝐀𝐕𝐄𝐀𝐓𝐒
        I/O  error  messages  are not as helpful as they could be.
-       _b_z_i_p_2 tries hard to detect I/O errors  and  exit  cleanly,
+       b̲z̲i̲p̲2̲ tries hard to detect I/O errors  and  exit  cleanly,
        but  the  details  of  what  the problem is sometimes seem
        rather misleading.
 
-       This manual page pertains to version 1.0.8 of _b_z_i_p_2_.  Com­
+       This manual page pertains to version 1.0.8 of b̲z̲i̲p̲2̲.̲  Com-
        pressed  data created by this version is entirely forwards
        and  backwards  compatible  with   the   previous   public
        releases,  versions  0.1pl2,  0.9.0,  0.9.5, 1.0.0, 1.0.1, 
@@ -357,38 +357,38 @@ CCAAVVEEAATTSS
        compressed files.  0.1pl2  cannot do this;  it  will  stop 
        after  decompressing just the first file in the stream.
 
-       _b_z_i_p_2_r_e_c_o_v_e_r  versions prior to 1.0.2 used 32‐bit integers
+       b̲z̲i̲p̲2̲r̲e̲c̲o̲v̲e̲r̲  versions prior to 1.0.2 used 32-bit integers
        to represent bit positions in compressed  files,  so  they
        could  not handle compressed files more than 512 megabytes
-       long.  Versions 1.0.2 and above use 64‐bit  ints  on  some
+       long.  Versions 1.0.2 and above use 64-bit  ints  on  some
        platforms  which  support them (GNU supported targets, and
        Windows).  To establish whether or  not  bzip2recover  was
        built  with  such  a limitation, run it without arguments.
        In any event you can build yourself an  unlimited  version
        if  you  can  recompile  it  with MaybeUInt64 set to be an
-       unsigned 64‐bit integer.
+       unsigned 64-bit integer.
 
 
 
 
-AAUUTTHHOORR
+𝐀𝐔𝐓𝐇𝐎𝐑
        Julian Seward, jseward@acm.org.
 
        https://sourceware.org/bzip2/
 
-       The ideas embodied in _b_z_i_p_2 are due to (at least) the fol­
+       The ideas embodied in b̲z̲i̲p̲2̲ are due to (at least) the fol-
        lowing  people: Michael Burrows and David Wheeler (for the
        block sorting transformation), David Wheeler  (again,  for
-       the Huffman coder), Peter Fenwick (for the structured cod­
-       ing model in the original _b_z_i_p_, and many refinements), and
+       the Huffman coder), Peter Fenwick (for the structured cod-
+       ing model in the original b̲z̲i̲p̲,̲ and many refinements), and
        Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
-       arithmetic  coder  in  the  original  _b_z_i_p_)_.   I  am  much
-       indebted for their help, support and advice.  See the man­
+       arithmetic  coder  in  the  original  b̲z̲i̲p̲)̲.̲   I  am  much
+       indebted for their help, support and advice.  See the man-
        ual in the source distribution for pointers to sources  of
        documentation.  Christian von Roques encouraged me to look
-       for faster sorting algorithms, so as to speed up  compres­
-       sion.  Bela Lubkin encouraged me to improve the worst‐case
-       compression performance.  Donna Robinson XMLised the docu­
+       for faster sorting algorithms, so as to speed up  compres-
+       sion.  Bela Lubkin encouraged me to improve the worst-case
+       compression performance.  Donna Robinson XMLised the docu-
        mentation.   The bz* scripts are derived from those of GNU
        gzip.  Many people sent patches, helped  with  portability
        problems,  lent  machines,  gave advice and were generally
diff --git a/third_party/bzip2/bzip2.c b/third_party/bzip2/bzip2.c
index d95d28061..05954eb16 100644
--- a/third_party/bzip2/bzip2.c
+++ b/third_party/bzip2/bzip2.c
@@ -1,3 +1,18 @@
+#include "libc/calls/calls.h"
+#include "libc/calls/struct/stat.h"
+#include "libc/calls/struct/stat.macros.h"
+#include "libc/errno.h"
+#include "libc/log/log.h"
+#include "libc/mem/mem.h"
+#include "libc/runtime/gc.internal.h"
+#include "libc/stdio/stdio.h"
+#include "libc/str/str.h"
+#include "libc/sysv/consts/o.h"
+#include "libc/sysv/consts/s.h"
+#include "libc/time/struct/utimbuf.h"
+#include "libc/time/time.h"
+#include "third_party/bzip2/bzlib.h"
+/* clang-format off */
 
 /*-----------------------------------------------------------*/
 /*--- A block-sorting, lossless compressor        bzip2.c ---*/
@@ -17,45 +32,13 @@
    in the file LICENSE.
    ------------------------------------------------------------------ */
 
-
-/* Place a 1 beside your platform, and 0 elsewhere.
-   Generic 32-bit Unix.
-   Also works on 64-bit Unix boxes.
-   This is the default.
-*/
 #define BZ_UNIX      1
 
-/*--
-  Win32, as seen by Jacob Navia's excellent
-  port of (Chris Fraser & David Hanson)'s excellent
-  lcc compiler.  Or with MS Visual C.
-  This is selected automatically if compiled by a compiler which
-  defines _WIN32, not including the Cygwin GCC.
---*/
-#define BZ_LCCWIN32  0
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#undef  BZ_LCCWIN32
-#define BZ_LCCWIN32 1
-#undef  BZ_UNIX
-#define BZ_UNIX 0
-#endif
-
-
 /*---------------------------------------------*/
 /*--
   Some stuff for all platforms.
 --*/
 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "bzlib.h"
-
 #define ERROR_IF_EOF(i)       { if ((i) == EOF)  ioError(); }
 #define ERROR_IF_NOT_ZERO(i)  { if ((i) != 0)    ioError(); }
 #define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
@@ -67,92 +50,18 @@
 --*/
 
 #if BZ_UNIX
-#   include 
-#   include 
-#   include 
-#   include 
-#   include 
-#   include 
-
-#   define PATH_SEP    '/'
-#   define MY_LSTAT    lstat
-#   define MY_STAT     stat
-#   define MY_S_ISREG  S_ISREG
-#   define MY_S_ISDIR  S_ISDIR
-
-#   define APPEND_FILESPEC(root, name) \
+#define PATH_SEP    '/'
+#define MY_LSTAT    lstat
+#define MY_STAT     stat
+#define MY_S_ISREG  S_ISREG
+#define MY_S_ISDIR  S_ISDIR
+#define APPEND_FILESPEC(root, name) \
       root=snocString((root), (name))
-
-#   define APPEND_FLAG(root, name) \
+#define APPEND_FLAG(root, name) \
       root=snocString((root), (name))
-
-#   define SET_BINARY_MODE(fd) /**/
-
-#   ifdef __GNUC__
-#      define NORETURN __attribute__ ((noreturn))
-#   else
-#      define NORETURN /**/
-#   endif
-
-#   ifdef __DJGPP__
-#     include 
-#     include 
-#     undef MY_LSTAT
-#     undef MY_STAT
-#     define MY_LSTAT stat
-#     define MY_STAT stat
-#     undef SET_BINARY_MODE
-#     define SET_BINARY_MODE(fd)                        \
-        do {                                            \
-           int retVal = setmode ( fileno ( fd ),        \
-                                  O_BINARY );           \
-           ERROR_IF_MINUS_ONE ( retVal );               \
-        } while ( 0 )
-#   endif
-
-#   ifdef __CYGWIN__
-#     include 
-#     include 
-#     undef SET_BINARY_MODE
-#     define SET_BINARY_MODE(fd)                        \
-        do {                                            \
-           int retVal = setmode ( fileno ( fd ),        \
-                                  O_BINARY );           \
-           ERROR_IF_MINUS_ONE ( retVal );               \
-        } while ( 0 )
-#   endif
+#define SET_BINARY_MODE(fd) /**/
 #endif /* BZ_UNIX */
 
-
-
-#if BZ_LCCWIN32
-#   include 
-#   include 
-#   include 
-
-#   define NORETURN       /**/
-#   define PATH_SEP       '\\'
-#   define MY_LSTAT       _stati64
-#   define MY_STAT        _stati64
-#   define MY_S_ISREG(x)  ((x) & _S_IFREG)
-#   define MY_S_ISDIR(x)  ((x) & _S_IFDIR)
-
-#   define APPEND_FLAG(root, name) \
-      root=snocString((root), (name))
-
-#   define APPEND_FILESPEC(root, name)                \
-      root = snocString ((root), (name))
-
-#   define SET_BINARY_MODE(fd)                        \
-      do {                                            \
-         int retVal = setmode ( fileno ( fd ),        \
-                                O_BINARY );           \
-         ERROR_IF_MINUS_ONE ( retVal );               \
-      } while ( 0 )
-
-#endif /* BZ_LCCWIN32 */
-
-
 /*---------------------------------------------*/
 /*--
   Some more stuff for all platforms :-)
@@ -210,13 +119,13 @@ Char    progNameReally[FILE_NAME_LEN];
 FILE    *outputHandleJustInCase;
 Int32   workFactor;
 
-static void    panic                 ( const Char* ) NORETURN;
-static void    ioError               ( void )        NORETURN;
-static void    outOfMemory           ( void )        NORETURN;
-static void    configError           ( void )        NORETURN;
-static void    crcError              ( void )        NORETURN;
-static void    cleanUpAndFail        ( Int32 )       NORETURN;
-static void    compressedStreamEOF   ( void )        NORETURN;
+static void    panic                 ( const Char* ) wontreturn;
+static void    ioError               ( void )        wontreturn;
+static void    outOfMemory           ( void )        wontreturn;
+static void    configError           ( void )        wontreturn;
+static void    crcError              ( void )        wontreturn;
+static void    cleanUpAndFail        ( Int32 )       wontreturn;
+static void    compressedStreamEOF   ( void )        wontreturn;
 
 static void    copyFileName ( Char*, Char* );
 static void*   myMalloc     ( Int32 );
@@ -329,7 +238,7 @@ static
 void compressStream ( FILE *stream, FILE *zStream )
 {
    BZFILE* bzf = NULL;
-   UChar   ibuf[5000];
+   UChar   *ibuf = gc(malloc(5000));
    Int32   nIbuf;
    UInt32  nbytes_in_lo32, nbytes_in_hi32;
    UInt32  nbytes_out_lo32, nbytes_out_hi32;
@@ -345,7 +254,7 @@ void compressStream ( FILE *stream, FILE *zStream )
                            blockSize100k, verbosity, workFactor );   
    if (bzerr != BZ_OK) goto errhandler;
 
-   if (verbosity >= 2) fprintf ( stderr, "\n" );
+   if (verbosity >= 2) (fprintf) ( stderr, "\n" );
 
    while (True) {
 
@@ -380,7 +289,7 @@ void compressStream ( FILE *stream, FILE *zStream )
 
    if (verbosity >= 1) {
       if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
-	 fprintf ( stderr, " no data compressed.\n");
+	 (fprintf) ( stderr, " no data compressed.\n");
       } else {
 	 Char   buf_nin[32], buf_nout[32];
 	 UInt64 nbytes_in,   nbytes_out;
@@ -393,7 +302,7 @@ void compressStream ( FILE *stream, FILE *zStream )
 	 nbytes_out_d = uInt64_to_double ( &nbytes_out );
 	 uInt64_toAscii ( buf_nin, &nbytes_in );
 	 uInt64_toAscii ( buf_nout, &nbytes_out );
-	 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
+	 (fprintf) ( stderr, "%6.3f:1, %6.3f bits/byte, "
 		   "%5.2f%% saved, %s in, %s out.\n",
 		   nbytes_in_d / nbytes_out_d,
 		   (8.0 * nbytes_out_d) / nbytes_in_d,
@@ -434,8 +343,8 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
 {
    BZFILE* bzf = NULL;
    Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
-   UChar   obuf[5000];
-   UChar   unused[BZ_MAX_UNUSED];
+   UChar   *obuf = gc(malloc(5000));
+   UChar   *unused = gc(malloc(BZ_MAX_UNUSED));
    Int32   nUnused;
    void*   unusedTmpV;
    UChar*  unusedTmp;
@@ -498,7 +407,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
       if (ret == EOF) goto errhandler_io;
    }
    outputHandleJustInCase = NULL;
-   if (verbosity >= 2) fprintf ( stderr, "\n    " );
+   if (verbosity >= 2) (fprintf) ( stderr, "\n    " );
    return True;
 
    trycat: 
@@ -535,7 +444,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
             return False;
          } else {
             if (noisy)
-            fprintf ( stderr, 
+            (fprintf) ( stderr, 
                       "\n%s: %s: trailing garbage after EOF ignored\n",
                       progName, inName );
             return True;       
@@ -555,8 +464,8 @@ Bool testStream ( FILE *zStream )
 {
    BZFILE* bzf = NULL;
    Int32   bzerr, bzerr_dummy, ret, streamNo, i;
-   UChar   obuf[5000];
-   UChar   unused[BZ_MAX_UNUSED];
+   UChar   *obuf = gc(malloc(5000));
+   UChar   *unused = gc(malloc(BZ_MAX_UNUSED));
    Int32   nUnused;
    void*   unusedTmpV;
    UChar*  unusedTmp;
@@ -598,13 +507,13 @@ Bool testStream ( FILE *zStream )
    ret = fclose ( zStream );
    if (ret == EOF) goto errhandler_io;
 
-   if (verbosity >= 2) fprintf ( stderr, "\n    " );
+   if (verbosity >= 2) (fprintf) ( stderr, "\n    " );
    return True;
 
    errhandler:
    BZ2_bzReadClose ( &bzerr_dummy, bzf );
    if (verbosity == 0) 
-      fprintf ( stderr, "%s: %s: ", progName, inName );
+      (fprintf) ( stderr, "%s: %s: ", progName, inName );
    switch (bzerr) {
       case BZ_CONFIG_ERROR:
          configError(); break;
@@ -612,24 +521,24 @@ Bool testStream ( FILE *zStream )
          errhandler_io:
          ioError(); break;
       case BZ_DATA_ERROR:
-         fprintf ( stderr,
+         (fprintf) ( stderr,
                    "data integrity (CRC) error in data\n" );
          return False;
       case BZ_MEM_ERROR:
          outOfMemory();
       case BZ_UNEXPECTED_EOF:
-         fprintf ( stderr,
+         (fprintf) ( stderr,
                    "file ends unexpectedly\n" );
          return False;
       case BZ_DATA_ERROR_MAGIC:
          if (zStream != stdin) fclose(zStream);
          if (streamNo == 1) {
-          fprintf ( stderr, 
+          (fprintf) ( stderr, 
                     "bad magic number (file not created by bzip2)\n" );
             return False;
          } else {
             if (noisy)
-            fprintf ( stderr, 
+            (fprintf) ( stderr, 
                       "trailing garbage after EOF ignored\n" );
             return True;       
          }
@@ -659,7 +568,7 @@ static
 void cadvise ( void )
 {
    if (noisy)
-   fprintf (
+   (fprintf) (
       stderr,
       "\nIt is possible that the compressed file(s) have become corrupted.\n"
         "You can use the -tvv option to test integrity of such files.\n\n"
@@ -674,7 +583,7 @@ static
 void showFileNames ( void )
 {
    if (noisy)
-   fprintf (
+   (fprintf) (
       stderr,
       "\tInput file = %s, output file = %s\n",
       inName, outName 
@@ -701,28 +610,28 @@ void cleanUpAndFail ( Int32 ec )
       retVal = MY_STAT ( inName, &statBuf );
       if (retVal == 0) {
          if (noisy)
-            fprintf ( stderr, 
+            (fprintf) ( stderr, 
                       "%s: Deleting output file %s, if it exists.\n",
                       progName, outName );
          if (outputHandleJustInCase != NULL)
             fclose ( outputHandleJustInCase );
          retVal = remove ( outName );
          if (retVal != 0)
-            fprintf ( stderr,
+            (fprintf) ( stderr,
                       "%s: WARNING: deletion of output file "
                       "(apparently) failed.\n",
                       progName );
       } else {
-         fprintf ( stderr,
+         (fprintf) ( stderr,
                    "%s: WARNING: deletion of output file suppressed\n",
                     progName );
-         fprintf ( stderr,
+         (fprintf) ( stderr,
                    "%s:    since input file no longer exists.  Output file\n",
                    progName );
-         fprintf ( stderr,
+         (fprintf) ( stderr,
                    "%s:    `%s' may be incomplete.\n",
                    progName, outName );
-         fprintf ( stderr, 
+         (fprintf) ( stderr, 
                    "%s:    I suggest doing an integrity test (bzip2 -tv)"
                    " of it.\n",
                    progName );
@@ -730,7 +639,7 @@ void cleanUpAndFail ( Int32 ec )
    }
 
    if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
-      fprintf ( stderr, 
+      (fprintf) ( stderr, 
                 "%s: WARNING: some files have not been processed:\n"
                 "%s:    %d specified on command line, %d not processed yet.\n\n",
                 progName, progName,
@@ -745,7 +654,7 @@ void cleanUpAndFail ( Int32 ec )
 static 
 void panic ( const Char* s )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "\n%s: PANIC -- internal consistency error:\n"
              "\t%s\n"
              "\tThis is a BUG.  Please report it to:\n"
@@ -760,7 +669,7 @@ void panic ( const Char* s )
 static 
 void crcError ( void )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "\n%s: Data integrity error when decompressing.\n",
              progName );
    showFileNames();
@@ -774,7 +683,7 @@ static
 void compressedStreamEOF ( void )
 {
   if (noisy) {
-    fprintf ( stderr,
+    (fprintf) ( stderr,
 	      "\n%s: Compressed file ends unexpectedly;\n\t"
 	      "perhaps it is corrupted?  *Possible* reason follows.\n",
 	      progName );
@@ -790,7 +699,7 @@ void compressedStreamEOF ( void )
 static 
 void ioError ( void )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "\n%s: I/O or other error, bailing out.  "
              "Possible reason follows.\n",
              progName );
@@ -804,7 +713,7 @@ void ioError ( void )
 static 
 void mySignalCatcher ( IntNative n )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "\n%s: Control-C or similar caught, quitting.\n",
              progName );
    cleanUpAndFail(1);
@@ -816,7 +725,7 @@ static
 void mySIGSEGVorSIGBUScatcher ( IntNative n )
 {
    if (opMode == OM_Z)
-      fprintf ( 
+      (fprintf) ( 
       stderr,
       "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
       "\n"
@@ -837,7 +746,7 @@ void mySIGSEGVorSIGBUScatcher ( IntNative n )
       "\n",
       progName );
       else
-      fprintf ( 
+      (fprintf) ( 
       stderr,
       "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
       "\n"
@@ -871,7 +780,7 @@ void mySIGSEGVorSIGBUScatcher ( IntNative n )
 static 
 void outOfMemory ( void )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "\n%s: couldn't allocate enough memory\n",
              progName );
    showFileNames();
@@ -883,7 +792,7 @@ void outOfMemory ( void )
 static 
 void configError ( void )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "bzip2: I'm not configured correctly for this platform!\n"
              "\tI require Int32, Int16 and Char to have sizes\n"
              "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
@@ -910,7 +819,7 @@ void pad ( Char *s )
    Int32 i;
    if ( (Int32)strlen(s) >= longestFileName ) return;
    for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
-      fprintf ( stderr, " " );
+      (fprintf) ( stderr, " " );
 }
 
 
@@ -919,7 +828,7 @@ static
 void copyFileName ( Char* to, Char* from ) 
 {
    if ( strlen(from) > FILE_NAME_LEN-10 )  {
-      fprintf (
+      (fprintf) (
          stderr,
          "bzip2: file name\n`%s'\n"
          "is suspiciously (more than %d chars) long.\n"
@@ -1160,13 +1069,13 @@ void compress ( Char *name )
 
    if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
       if (noisy)
-      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+      (fprintf) ( stderr, "%s: There are no files matching `%s'.\n",
                 progName, inName );
       setExit(1);
       return;
    }
    if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
-      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+      (fprintf) ( stderr, "%s: Can't open input file %s: %s.\n",
                 progName, inName, strerror(errno) );
       setExit(1);
       return;
@@ -1174,7 +1083,7 @@ void compress ( Char *name )
    for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
       if (hasSuffix(inName, zSuffix[i])) {
          if (noisy)
-         fprintf ( stderr, 
+         (fprintf) ( stderr, 
                    "%s: Input file %s already has %s suffix.\n",
                    progName, inName, zSuffix[i] );
          setExit(1);
@@ -1184,7 +1093,7 @@ void compress ( Char *name )
    if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
       MY_STAT(inName, &statBuf);
       if ( MY_S_ISDIR(statBuf.st_mode) ) {
-         fprintf( stderr,
+         (fprintf)( stderr,
                   "%s: Input file %s is a directory.\n",
                   progName,inName);
          setExit(1);
@@ -1193,7 +1102,7 @@ void compress ( Char *name )
    }
    if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
       if (noisy)
-      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+      (fprintf) ( stderr, "%s: Input file %s is not a normal file.\n",
                 progName, inName );
       setExit(1);
       return;
@@ -1202,7 +1111,7 @@ void compress ( Char *name )
       if (forceOverwrite) {
 	 remove(outName);
       } else {
-	 fprintf ( stderr, "%s: Output file %s already exists.\n",
+	 (fprintf) ( stderr, "%s: Output file %s already exists.\n",
 		   progName, outName );
 	 setExit(1);
 	 return;
@@ -1210,7 +1119,7 @@ void compress ( Char *name )
    }
    if ( srcMode == SM_F2F && !forceOverwrite &&
         (n=countHardLinks ( inName )) > 0) {
-      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+      (fprintf) ( stderr, "%s: Input file %s has %d other link%s.\n",
                 progName, inName, n, n > 1 ? "s" : "" );
       setExit(1);
       return;
@@ -1228,10 +1137,10 @@ void compress ( Char *name )
          inStr = stdin;
          outStr = stdout;
          if ( isatty ( fileno ( stdout ) ) ) {
-            fprintf ( stderr,
+            (fprintf) ( stderr,
                       "%s: I won't write compressed data to a terminal.\n",
                       progName );
-            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+            (fprintf) ( stderr, "%s: For help, type: `%s --help'.\n",
                               progName, progName );
             setExit(1);
             return;
@@ -1242,17 +1151,17 @@ void compress ( Char *name )
          inStr = fopen ( inName, "rb" );
          outStr = stdout;
          if ( isatty ( fileno ( stdout ) ) ) {
-            fprintf ( stderr,
+            (fprintf) ( stderr,
                       "%s: I won't write compressed data to a terminal.\n",
                       progName );
-            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+            (fprintf) ( stderr, "%s: For help, type: `%s --help'.\n",
                               progName, progName );
             if ( inStr != NULL ) fclose ( inStr );
             setExit(1);
             return;
          };
          if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+            (fprintf) ( stderr, "%s: Can't open input file %s: %s.\n",
                       progName, inName, strerror(errno) );
             setExit(1);
             return;
@@ -1263,14 +1172,14 @@ void compress ( Char *name )
          inStr = fopen ( inName, "rb" );
          outStr = fopen_output_safely ( outName, "wb" );
          if ( outStr == NULL) {
-            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+            (fprintf) ( stderr, "%s: Can't create output file %s: %s.\n",
                       progName, outName, strerror(errno) );
             if ( inStr != NULL ) fclose ( inStr );
             setExit(1);
             return;
          }
          if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+            (fprintf) ( stderr, "%s: Can't open input file %s: %s.\n",
                       progName, inName, strerror(errno) );
             if ( outStr != NULL ) fclose ( outStr );
             setExit(1);
@@ -1284,7 +1193,7 @@ void compress ( Char *name )
    }
 
    if (verbosity >= 1) {
-      fprintf ( stderr,  "  %s: ", inName );
+      (fprintf) ( stderr,  "  %s: ", inName );
       pad ( inName );
       fflush ( stderr );
    }
@@ -1349,13 +1258,13 @@ void uncompress ( Char *name )
    zzz:
    if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
       if (noisy)
-      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+      (fprintf) ( stderr, "%s: There are no files matching `%s'.\n",
                 progName, inName );
       setExit(1);
       return;
    }
    if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
-      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+      (fprintf) ( stderr, "%s: Can't open input file %s: %s.\n",
                 progName, inName, strerror(errno) );
       setExit(1);
       return;
@@ -1363,7 +1272,7 @@ void uncompress ( Char *name )
    if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
       MY_STAT(inName, &statBuf);
       if ( MY_S_ISDIR(statBuf.st_mode) ) {
-         fprintf( stderr,
+         (fprintf)( stderr,
                   "%s: Input file %s is a directory.\n",
                   progName,inName);
          setExit(1);
@@ -1372,14 +1281,14 @@ void uncompress ( Char *name )
    }
    if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
       if (noisy)
-      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+      (fprintf) ( stderr, "%s: Input file %s is not a normal file.\n",
                 progName, inName );
       setExit(1);
       return;
    }
    if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
       if (noisy)
-      fprintf ( stderr, 
+      (fprintf) ( stderr, 
                 "%s: Can't guess original name for %s -- using %s\n",
                 progName, inName, outName );
       /* just a warning, no return */
@@ -1388,7 +1297,7 @@ void uncompress ( Char *name )
       if (forceOverwrite) {
 	remove(outName);
       } else {
-        fprintf ( stderr, "%s: Output file %s already exists.\n",
+        (fprintf) ( stderr, "%s: Output file %s already exists.\n",
                   progName, outName );
         setExit(1);
         return;
@@ -1396,7 +1305,7 @@ void uncompress ( Char *name )
    }
    if ( srcMode == SM_F2F && !forceOverwrite &&
         (n=countHardLinks ( inName ) ) > 0) {
-      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+      (fprintf) ( stderr, "%s: Input file %s has %d other link%s.\n",
                 progName, inName, n, n > 1 ? "s" : "" );
       setExit(1);
       return;
@@ -1414,10 +1323,10 @@ void uncompress ( Char *name )
          inStr = stdin;
          outStr = stdout;
          if ( isatty ( fileno ( stdin ) ) ) {
-            fprintf ( stderr,
+            (fprintf) ( stderr,
                       "%s: I won't read compressed data from a terminal.\n",
                       progName );
-            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+            (fprintf) ( stderr, "%s: For help, type: `%s --help'.\n",
                               progName, progName );
             setExit(1);
             return;
@@ -1428,7 +1337,7 @@ void uncompress ( Char *name )
          inStr = fopen ( inName, "rb" );
          outStr = stdout;
          if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+            (fprintf) ( stderr, "%s: Can't open input file %s:%s.\n",
                       progName, inName, strerror(errno) );
             if ( inStr != NULL ) fclose ( inStr );
             setExit(1);
@@ -1440,14 +1349,14 @@ void uncompress ( Char *name )
          inStr = fopen ( inName, "rb" );
          outStr = fopen_output_safely ( outName, "wb" );
          if ( outStr == NULL) {
-            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+            (fprintf) ( stderr, "%s: Can't create output file %s: %s.\n",
                       progName, outName, strerror(errno) );
             if ( inStr != NULL ) fclose ( inStr );
             setExit(1);
             return;
          }
          if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+            (fprintf) ( stderr, "%s: Can't open input file %s: %s.\n",
                       progName, inName, strerror(errno) );
             if ( outStr != NULL ) fclose ( outStr );
             setExit(1);
@@ -1461,7 +1370,7 @@ void uncompress ( Char *name )
    }
 
    if (verbosity >= 1) {
-      fprintf ( stderr, "  %s: ", inName );
+      (fprintf) ( stderr, "  %s: ", inName );
       pad ( inName );
       fflush ( stderr );
    }
@@ -1494,12 +1403,12 @@ void uncompress ( Char *name )
 
    if ( magicNumberOK ) {
       if (verbosity >= 1)
-         fprintf ( stderr, "done\n" );
+         (fprintf) ( stderr, "done\n" );
    } else {
       setExit(2);
       if (verbosity >= 1)
-         fprintf ( stderr, "not a bzip2 file.\n" ); else
-         fprintf ( stderr,
+         (fprintf) ( stderr, "not a bzip2 file.\n" ); else
+         (fprintf) ( stderr,
                    "%s: %s is not a bzip2 file.\n",
                    progName, inName );
    }
@@ -1529,13 +1438,13 @@ void testf ( Char *name )
 
    if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
       if (noisy)
-      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+      (fprintf) ( stderr, "%s: There are no files matching `%s'.\n",
                 progName, inName );
       setExit(1);
       return;
    }
    if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
-      fprintf ( stderr, "%s: Can't open input %s: %s.\n",
+      (fprintf) ( stderr, "%s: Can't open input %s: %s.\n",
                 progName, inName, strerror(errno) );
       setExit(1);
       return;
@@ -1543,7 +1452,7 @@ void testf ( Char *name )
    if ( srcMode != SM_I2O ) {
       MY_STAT(inName, &statBuf);
       if ( MY_S_ISDIR(statBuf.st_mode) ) {
-         fprintf( stderr,
+         (fprintf)( stderr,
                   "%s: Input file %s is a directory.\n",
                   progName,inName);
          setExit(1);
@@ -1555,10 +1464,10 @@ void testf ( Char *name )
 
       case SM_I2O:
          if ( isatty ( fileno ( stdin ) ) ) {
-            fprintf ( stderr,
+            (fprintf) ( stderr,
                       "%s: I won't read compressed data from a terminal.\n",
                       progName );
-            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+            (fprintf) ( stderr, "%s: For help, type: `%s --help'.\n",
                               progName, progName );
             setExit(1);
             return;
@@ -1569,7 +1478,7 @@ void testf ( Char *name )
       case SM_F2O: case SM_F2F:
          inStr = fopen ( inName, "rb" );
          if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+            (fprintf) ( stderr, "%s: Can't open input file %s:%s.\n",
                       progName, inName, strerror(errno) );
             setExit(1);
             return;
@@ -1582,7 +1491,7 @@ void testf ( Char *name )
    }
 
    if (verbosity >= 1) {
-      fprintf ( stderr, "  %s: ", inName );
+      (fprintf) ( stderr, "  %s: ", inName );
       pad ( inName );
       fflush ( stderr );
    }
@@ -1591,7 +1500,7 @@ void testf ( Char *name )
    outputHandleJustInCase = NULL;
    allOK = testStream ( inStr );
 
-   if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
+   if (allOK && verbosity >= 1) (fprintf) ( stderr, "ok\n" );
    if (!allOK) testFailsExist = True;
 }
 
@@ -1600,7 +1509,7 @@ void testf ( Char *name )
 static 
 void license ( void )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
 
     "bzip2, a block-sorting file compressor.  "
     "Version %s.\n"
@@ -1625,7 +1534,7 @@ void license ( void )
 static 
 void usage ( Char *fullProgName )
 {
-   fprintf (
+   (fprintf) (
       stderr,
       "bzip2, a block-sorting file compressor.  "
       "Version %s.\n"
@@ -1669,7 +1578,7 @@ void usage ( Char *fullProgName )
 static 
 void redundant ( Char* flag )
 {
-   fprintf ( 
+   (fprintf) ( 
       stderr, 
       "%s: %s is redundant in versions 0.9.5 and above\n",
       progName, flag );
@@ -1895,7 +1804,7 @@ IntNative main ( IntNative argc, Char *argv[] )
                case 'h': usage ( progName );
                          exit ( 0 );
                          break;
-               default:  fprintf ( stderr, "%s: Bad flag `%s'\n",
+               default:  (fprintf) ( stderr, "%s: Bad flag `%s'\n",
                                    progName, aa->name );
                          usage ( progName );
                          exit ( 1 );
@@ -1927,7 +1836,7 @@ IntNative main ( IntNative argc, Char *argv[] )
       if (ISFLAG("--help"))              { usage ( progName ); exit ( 0 ); }
          else
          if (strncmp ( aa->name, "--", 2) == 0) {
-            fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
+            (fprintf) ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
             usage ( progName );
             exit ( 1 );
          }
@@ -1938,7 +1847,7 @@ IntNative main ( IntNative argc, Char *argv[] )
       blockSize100k = 2;
 
    if (opMode == OM_TEST && srcMode == SM_F2O) {
-      fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
+      (fprintf) ( stderr, "%s: -c and -t cannot be used together.\n",
                 progName );
       exit ( 1 );
    }
@@ -2005,7 +1914,7 @@ IntNative main ( IntNative argc, Char *argv[] )
       }
       if (testFailsExist) {
 	 if (noisy) {
-            fprintf ( stderr,
+            (fprintf) ( stderr,
                "\n"
                "You can use the `bzip2recover' program to attempt to recover\n"
                "data from undamaged sections of corrupted files.\n\n"
diff --git a/third_party/bzip2/bzip2.mk b/third_party/bzip2/bzip2.mk
index 008891b3c..ca9dee805 100644
--- a/third_party/bzip2/bzip2.mk
+++ b/third_party/bzip2/bzip2.mk
@@ -7,51 +7,79 @@ THIRD_PARTY_BZIP2_ARTIFACTS += THIRD_PARTY_BZIP2_A
 THIRD_PARTY_BZIP2 = $(THIRD_PARTY_BZIP2_A_DEPS) $(THIRD_PARTY_BZIP2_A)
 THIRD_PARTY_BZIP2_A = o/$(MODE)/third_party/bzip2/bzip2.a
 THIRD_PARTY_BZIP2_A_FILES := $(wildcard third_party/bzip2/*)
-THIRD_PARTY_BZIP2_A_HDRS = third_party/bzip2/bzip2.h
-THIRD_PARTY_BZIP2_A_HDRS_ALL = $(filter %.h,$(THIRD_PARTY_BZIP2_A_FILES))
-THIRD_PARTY_BZIP2_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_BZIP2_A_FILES))
-THIRD_PARTY_BZIP2_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_BZIP2_A_FILES))
+THIRD_PARTY_BZIP2_A_HDRS = $(filter %.h,$(THIRD_PARTY_BZIP2_A_FILES))
+THIRD_PARTY_BZIP2_A_SRCS = $(filter %.c,$(THIRD_PARTY_BZIP2_A_FILES))
+THIRD_PARTY_BZIP2_A_OBJS = $(THIRD_PARTY_BZIP2_A_SRCS:%.c=o/$(MODE)/%.o)
+THIRD_PARTY_BZIP2_BINS = $(THIRD_PARTY_BZIP2_COMS) $(THIRD_PARTY_BZIP2_COMS:%=%.dbg)
 
-THIRD_PARTY_BZIP2_A_SRCS =				\
-	$(THIRD_PARTY_BZIP2_A_SRCS_S)			\
-	$(THIRD_PARTY_BZIP2_A_SRCS_C)
+THIRD_PARTY_BZIP2_COMS =					\
+	o/$(MODE)/third_party/bzip2/bzip2.com			\
+	o/$(MODE)/third_party/bzip2/bzip2recover.com
 
-THIRD_PARTY_BZIP2_A_OBJS =				\
-	$(THIRD_PARTY_BZIP2_A_SRCS_S:%.S=o/$(MODE)/%.o)	\
-	$(THIRD_PARTY_BZIP2_A_SRCS_C:%.c=o/$(MODE)/%.o)
-
-THIRD_PARTY_BZIP2_A_CHECKS =				\
-	$(THIRD_PARTY_BZIP2_A).pkg			\
-	$(THIRD_PARTY_BZIP2_A_HDRS_ALL:%=o/$(MODE)/%.ok)
+THIRD_PARTY_BZIP2_A_CHECKS =					\
+	$(THIRD_PARTY_BZIP2_A).pkg				\
+	$(THIRD_PARTY_BZIP2_A_HDRS:%=o/$(MODE)/%.ok)
 
 THIRD_PARTY_BZIP2_A_DIRECTDEPS =				\
-	LIBC_INTRIN					\
-	LIBC_NEXGEN32E					\
-	LIBC_STR					\
-	LIBC_STUBS
+	LIBC_CALLS						\
+	LIBC_FMT						\
+	LIBC_INTRIN						\
+	LIBC_LOG						\
+	LIBC_MEM						\
+	LIBC_NEXGEN32E						\
+	LIBC_RAND						\
+	LIBC_RUNTIME						\
+	LIBC_STDIO						\
+	LIBC_STR						\
+	LIBC_STUBS						\
+	LIBC_SYSV
 
-THIRD_PARTY_BZIP2_A_DEPS :=				\
+THIRD_PARTY_BZIP2_A_DEPS :=					\
 	$(call uniq,$(foreach x,$(THIRD_PARTY_BZIP2_A_DIRECTDEPS),$($(x))))
 
-$(THIRD_PARTY_BZIP2_A):					\
-		third_party/bzip2/			\
-		$(THIRD_PARTY_BZIP2_A).pkg		\
+$(THIRD_PARTY_BZIP2_A):						\
+		third_party/bzip2/				\
+		$(THIRD_PARTY_BZIP2_A).pkg			\
 		$(THIRD_PARTY_BZIP2_A_OBJS)
 
-$(THIRD_PARTY_BZIP2_A).pkg:				\
-		$(THIRD_PARTY_BZIP2_A_OBJS)		\
+$(THIRD_PARTY_BZIP2_A).pkg:					\
+		$(THIRD_PARTY_BZIP2_A_OBJS)			\
 		$(foreach x,$(THIRD_PARTY_BZIP2_A_DIRECTDEPS),$($(x)_A).pkg)
 
+o/$(MODE)/third_party/bzip2/bzip2.com.dbg:			\
+		$(THIRD_PARTY_BZIP2)				\
+		o/$(MODE)/third_party/bzip2/bzip2.o		\
+		o/$(MODE)/third_party/bzip2/bzip2.a.pkg		\
+		$(CRT)						\
+		$(APE)
+	-@$(APELINK)
+
+o/$(MODE)/third_party/bzip2/bzip2recover.com.dbg:		\
+		$(THIRD_PARTY_BZIP2)				\
+		o/$(MODE)/third_party/bzip2/bzip2recover.o	\
+		o/$(MODE)/third_party/bzip2/bzip2.a.pkg		\
+		$(CRT)						\
+		$(APE)
+	-@$(APELINK)
+
+$(THIRD_PARTY_BZIP2_A_OBJS):					\
+		OVERRIDE_CFLAGS +=				\
+			-ffunction-sections			\
+			-fdata-sections
+
 THIRD_PARTY_BZIP2_LIBS = $(foreach x,$(THIRD_PARTY_BZIP2_ARTIFACTS),$($(x)))
 THIRD_PARTY_BZIP2_SRCS = $(foreach x,$(THIRD_PARTY_BZIP2_ARTIFACTS),$($(x)_SRCS))
 THIRD_PARTY_BZIP2_HDRS = $(foreach x,$(THIRD_PARTY_BZIP2_ARTIFACTS),$($(x)_HDRS))
-THIRD_PARTY_BZIP2_HDRS_ALL = $(foreach x,$(THIRD_PARTY_BZIP2_ARTIFACTS),$($(x)_HDRS_ALL))
 THIRD_PARTY_BZIP2_BINS = $(foreach x,$(THIRD_PARTY_BZIP2_ARTIFACTS),$($(x)_BINS))
 THIRD_PARTY_BZIP2_CHECKS = $(foreach x,$(THIRD_PARTY_BZIP2_ARTIFACTS),$($(x)_CHECKS))
 THIRD_PARTY_BZIP2_OBJS = $(foreach x,$(THIRD_PARTY_BZIP2_ARTIFACTS),$($(x)_OBJS))
 $(THIRD_PARTY_BZIP2_OBJS): $(BUILD_FILES) third_party/bzip2/bzip2.mk
 
 .PHONY: o/$(MODE)/third_party/bzip2
-o/$(MODE)/third_party/bzip2:				\
-		$(THIRD_PARTY_BZIP2_A)			\
+o/$(MODE)/third_party/bzip2:					\
+		$(THIRD_PARTY_BZIP2_COMS)			\
 		$(THIRD_PARTY_BZIP2_CHECKS)
+
+# TODO(jart): write regression test
+# master jart@nightmare:~/cosmo$ o//third_party/bzip2/bzip2.com -1 a
+# master jart@nightmare:~/cosmo$ cmp -s third_party/bzip2/sample1.bz2 a
diff --git a/third_party/bzip2/bzip2recover.c b/third_party/bzip2/bzip2recover.c
index a8131e061..aeab0ccdc 100644
--- a/third_party/bzip2/bzip2recover.c
+++ b/third_party/bzip2/bzip2recover.c
@@ -1,3 +1,11 @@
+#include "libc/calls/calls.h"
+#include "libc/errno.h"
+#include "libc/fmt/fmt.h"
+#include "libc/log/log.h"
+#include "libc/runtime/runtime.h"
+#include "libc/stdio/stdio.h"
+/* clang-format off */
+
 /*-----------------------------------------------------------*/
 /*--- Block recoverer program for bzip2                   ---*/
 /*---                                      bzip2recover.c ---*/
@@ -20,12 +28,6 @@
 /* This program is a complete hack and should be rewritten properly.
 	 It isn't very complicated. */
 
-#include 
-#include 
-#include 
-#include 
-
-
 /* This program records bit locations in the file to be recovered.
    That means that if 64-bit ints are not supported, we will not
    be able to recover .bz2 files over 512MB (2^32 bits) long.
@@ -84,11 +86,11 @@ MaybeUInt64 bytesIn  = 0;
 /*---------------------------------------------*/
 static void readError ( void )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "%s: I/O error reading `%s', possible reason follows.\n",
             progName, inFileName );
    perror ( progName );
-   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+   (fprintf) ( stderr, "%s: warning: output file(s) may be incomplete.\n",
              progName );
    exit ( 1 );
 }
@@ -97,11 +99,11 @@ static void readError ( void )
 /*---------------------------------------------*/
 static void writeError ( void )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "%s: I/O error reading `%s', possible reason follows.\n",
             progName, inFileName );
    perror ( progName );
-   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+   (fprintf) ( stderr, "%s: warning: output file(s) may be incomplete.\n",
              progName );
    exit ( 1 );
 }
@@ -110,10 +112,10 @@ static void writeError ( void )
 /*---------------------------------------------*/
 static void mallocFail ( Int32 n )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "%s: malloc failed on request for %d bytes.\n",
             progName, n );
-   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+   (fprintf) ( stderr, "%s: warning: output file(s) may be incomplete.\n",
              progName );
    exit ( 1 );
 }
@@ -122,13 +124,13 @@ static void mallocFail ( Int32 n )
 /*---------------------------------------------*/
 static void tooManyBlocks ( Int32 max_handled_blocks )
 {
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "%s: `%s' appears to contain more than %d blocks\n",
             progName, inFileName, max_handled_blocks );
-   fprintf ( stderr,
+   (fprintf) ( stderr,
              "%s: and cannot be handled.  To fix, increase\n",
              progName );
-   fprintf ( stderr, 
+   (fprintf) ( stderr, 
              "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
              progName );
    exit ( 1 );
@@ -313,26 +315,26 @@ Int32 main ( Int32 argc, Char** argv )
    progName[BZ_MAX_FILENAME-1]='\0';
    inFileName[0] = outFileName[0] = 0;
 
-   fprintf ( stderr, 
+   (fprintf) ( stderr, 
              "bzip2recover 1.0.8: extracts blocks from damaged .bz2 files.\n" );
 
    if (argc != 2) {
-      fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
+      (fprintf) ( stderr, "%s: usage is `%s damaged_file_name'.\n",
                         progName, progName );
       switch (sizeof(MaybeUInt64)) {
          case 8:
-            fprintf(stderr, 
+            (fprintf)(stderr, 
                     "\trestrictions on size of recovered file: None\n");
             break;
          case 4:
-            fprintf(stderr, 
+            (fprintf)(stderr, 
                     "\trestrictions on size of recovered file: 512 MB\n");
-            fprintf(stderr, 
+            (fprintf)(stderr, 
                     "\tto circumvent, recompile with MaybeUInt64 as an\n"
                     "\tunsigned 64-bit int.\n");
             break;
          default:
-            fprintf(stderr, 
+            (fprintf)(stderr, 
                     "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
                     "configuration error.\n");
             break;
@@ -341,7 +343,7 @@ Int32 main ( Int32 argc, Char** argv )
    }
 
    if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
-      fprintf ( stderr, 
+      (fprintf) ( stderr, 
                 "%s: supplied filename is suspiciously (>= %d chars) long.  Bye!\n",
                 progName, (int)strlen(argv[1]) );
       exit(1);
@@ -351,12 +353,12 @@ Int32 main ( Int32 argc, Char** argv )
 
    inFile = fopen ( inFileName, "rb" );
    if (inFile == NULL) {
-      fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
+      (fprintf) ( stderr, "%s: can't read `%s'\n", progName, inFileName );
       exit(1);
    }
 
    bsIn = bsOpenReadStream ( inFile );
-   fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
+   (fprintf) ( stderr, "%s: searching for block boundaries ...\n", progName );
 
    bitsRead = 0;
    buffHi = buffLo = 0;
@@ -373,7 +375,7 @@ Int32 main ( Int32 argc, Char** argv )
             (bitsRead - bStart[currBlock]) >= 40) {
             bEnd[currBlock] = bitsRead-1;
             if (currBlock > 0)
-               fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
+               (fprintf) ( stderr, "   block %d runs from " MaybeUInt64_FMT 
                                  " to " MaybeUInt64_FMT " (incomplete)\n",
                          currBlock,  bStart[currBlock], bEnd[currBlock] );
          } else
@@ -395,7 +397,7 @@ Int32 main ( Int32 argc, Char** argv )
          }
          if (currBlock > 0 &&
 	     (bEnd[currBlock] - bStart[currBlock]) >= 130) {
-            fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
+            (fprintf) ( stderr, "   block %d runs from " MaybeUInt64_FMT 
                               " to " MaybeUInt64_FMT "\n",
                       rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
             rbStart[rbCtr] = bStart[currBlock];
@@ -415,17 +417,17 @@ Int32 main ( Int32 argc, Char** argv )
    /*-- identified blocks run from 1 to rbCtr inclusive. --*/
 
    if (rbCtr < 1) {
-      fprintf ( stderr,
+      (fprintf) ( stderr,
                 "%s: sorry, I couldn't find any block boundaries.\n",
                 progName );
       exit(1);
    };
 
-   fprintf ( stderr, "%s: splitting into blocks\n", progName );
+   (fprintf) ( stderr, "%s: splitting into blocks\n", progName );
 
    inFile = fopen ( inFileName, "rb" );
    if (inFile == NULL) {
-      fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
+      (fprintf) ( stderr, "%s: can't open `%s'\n", progName, inFileName );
       exit(1);
    }
    bsIn = bsOpenReadStream ( inFile );
@@ -479,18 +481,18 @@ Int32 main ( Int32 argc, Char** argv )
 	 }
 	 /* Now split points to the start of the basename. */
          ofs  = split - outFileName;
-         sprintf (split, "rec%5d", wrBlock+1);
+         (sprintf) (split, "rec%5d", wrBlock+1);
          for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
          strcat (outFileName, inFileName + ofs);
 
          if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
 
-         fprintf ( stderr, "   writing block %d to `%s' ...\n",
+         (fprintf) ( stderr, "   writing block %d to `%s' ...\n",
                            wrBlock+1, outFileName );
 
          outFile = fopen ( outFileName, "wb" );
          if (outFile == NULL) {
-            fprintf ( stderr, "%s: can't write `%s'\n",
+            (fprintf) ( stderr, "%s: can't write `%s'\n",
                       progName, outFileName );
             exit(1);
          }
@@ -505,7 +507,7 @@ Int32 main ( Int32 argc, Char** argv )
       }
    }
 
-   fprintf ( stderr, "%s: finished\n", progName );
+   (fprintf) ( stderr, "%s: finished\n", progName );
    return 0;
 }
 
diff --git a/third_party/bzip2/bzlib.c b/third_party/bzip2/bzlib.c
index 21786551b..2567c36f5 100644
--- a/third_party/bzip2/bzlib.c
+++ b/third_party/bzip2/bzlib.c
@@ -1,3 +1,4 @@
+/* clang-format off */
 
 /*-------------------------------------------------------------*/
 /*--- Library top-level functions.                          ---*/
@@ -28,7 +29,8 @@
      bzBuffToBuffDecompress.  Fixed.
 */
 
-#include "bzlib_private.h"
+#include "libc/calls/calls.h"
+#include "third_party/bzip2/bzlib_private.inc"
 
 
 /*---------------------------------------------------*/
@@ -145,7 +147,7 @@ Bool isempty_RL ( EState* s )
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressInit) 
+int BZ2_bzCompressInit 
                     ( bz_stream* strm, 
                      int        blockSize100k,
                      int        verbosity,
@@ -404,7 +406,7 @@ Bool handle_compress ( bz_stream* strm )
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+int BZ2_bzCompress ( bz_stream *strm, int action )
 {
    Bool progress;
    EState* s;
@@ -465,7 +467,7 @@ int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
+int BZ2_bzCompressEnd  ( bz_stream *strm )
 {
    EState* s;
    if (strm == NULL) return BZ_PARAM_ERROR;
@@ -489,7 +491,7 @@ int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
 /*---------------------------------------------------*/
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressInit) 
+int BZ2_bzDecompressInit 
                      ( bz_stream* strm, 
                        int        verbosity,
                        int        small )
@@ -805,7 +807,7 @@ Bool unRLE_obuf_to_output_SMALL ( DState* s )
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+int BZ2_bzDecompress ( bz_stream *strm )
 {
    Bool    corrupt;
    DState* s;
@@ -859,7 +861,7 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
+int BZ2_bzDecompressEnd  ( bz_stream *strm )
 {
    DState* s;
    if (strm == NULL) return BZ_PARAM_ERROR;
@@ -878,7 +880,6 @@ int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
 }
 
 
-#ifndef BZ_NO_STDIO
 /*---------------------------------------------------*/
 /*--- File I/O stuff                              ---*/
 /*---------------------------------------------------*/
@@ -913,7 +914,7 @@ static Bool myfeof ( FILE* f )
 
 
 /*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzWriteOpen) 
+BZFILE* BZ2_bzWriteOpen 
                     ( int*  bzerror,      
                       FILE* f, 
                       int   blockSize100k, 
@@ -961,7 +962,7 @@ BZFILE* BZ_API(BZ2_bzWriteOpen)
 
 
 /*---------------------------------------------------*/
-void BZ_API(BZ2_bzWrite)
+void BZ2_bzWrite
              ( int*    bzerror, 
                BZFILE* b, 
                void*   buf, 
@@ -1006,7 +1007,7 @@ void BZ_API(BZ2_bzWrite)
 
 
 /*---------------------------------------------------*/
-void BZ_API(BZ2_bzWriteClose)
+void BZ2_bzWriteClose
                   ( int*          bzerror, 
                     BZFILE*       b, 
                     int           abandon,
@@ -1018,7 +1019,7 @@ void BZ_API(BZ2_bzWriteClose)
 }
 
 
-void BZ_API(BZ2_bzWriteClose64)
+void BZ2_bzWriteClose64
                   ( int*          bzerror, 
                     BZFILE*       b, 
                     int           abandon,
@@ -1084,7 +1085,7 @@ void BZ_API(BZ2_bzWriteClose64)
 
 
 /*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzReadOpen) 
+BZFILE* BZ2_bzReadOpen 
                    ( int*  bzerror, 
                      FILE* f, 
                      int   verbosity,
@@ -1140,7 +1141,7 @@ BZFILE* BZ_API(BZ2_bzReadOpen)
 
 
 /*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+void BZ2_bzReadClose ( int *bzerror, BZFILE *b )
 {
    bzFile* bzf = (bzFile*)b;
 
@@ -1158,7 +1159,7 @@ void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzRead) 
+int BZ2_bzRead 
            ( int*    bzerror, 
              BZFILE* b, 
              void*   buf, 
@@ -1218,7 +1219,7 @@ int BZ_API(BZ2_bzRead)
 
 
 /*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadGetUnused) 
+void BZ2_bzReadGetUnused 
                      ( int*    bzerror, 
                        BZFILE* b, 
                        void**  unused, 
@@ -1236,7 +1237,6 @@ void BZ_API(BZ2_bzReadGetUnused)
    *nUnused = bzf->strm.avail_in;
    *unused = bzf->strm.next_in;
 }
-#endif
 
 
 /*---------------------------------------------------*/
@@ -1244,7 +1244,7 @@ void BZ_API(BZ2_bzReadGetUnused)
 /*---------------------------------------------------*/
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffCompress) 
+int BZ2_bzBuffToBuffCompress 
                          ( char*         dest, 
                            unsigned int* destLen,
                            char*         source, 
@@ -1296,7 +1296,7 @@ int BZ_API(BZ2_bzBuffToBuffCompress)
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffDecompress) 
+int BZ2_bzBuffToBuffDecompress 
                            ( char*         dest, 
                              unsigned int* destLen,
                              char*         source, 
@@ -1363,7 +1363,7 @@ int BZ_API(BZ2_bzBuffToBuffDecompress)
 /*--
    return version like "0.9.5d, 4-Sept-1999".
 --*/
-const char * BZ_API(BZ2_bzlibVersion)(void)
+const char * BZ2_bzlibVersion(void)
 {
    return BZ_VERSION;
 }
@@ -1457,7 +1457,7 @@ BZFILE * bzopen_or_bzdopen
       ex) bzopen("file","w9")
       case path="" or NULL => use stdin or stdout.
 --*/
-BZFILE * BZ_API(BZ2_bzopen)
+BZFILE * BZ2_bzopen
                ( const char *path,
                  const char *mode )
 {
@@ -1466,7 +1466,7 @@ BZFILE * BZ_API(BZ2_bzopen)
 
 
 /*---------------------------------------------------*/
-BZFILE * BZ_API(BZ2_bzdopen)
+BZFILE * BZ2_bzdopen
                ( int fd,
                  const char *mode )
 {
@@ -1475,7 +1475,7 @@ BZFILE * BZ_API(BZ2_bzdopen)
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+int BZ2_bzread (BZFILE* b, void* buf, int len )
 {
    int bzerr, nread;
    if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
@@ -1489,7 +1489,7 @@ int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+int BZ2_bzwrite (BZFILE* b, void* buf, int len )
 {
    int bzerr;
 
@@ -1503,7 +1503,7 @@ int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
 
 
 /*---------------------------------------------------*/
-int BZ_API(BZ2_bzflush) (BZFILE *b)
+int BZ2_bzflush (BZFILE *b)
 {
    /* do nothing now... */
    return 0;
@@ -1511,7 +1511,7 @@ int BZ_API(BZ2_bzflush) (BZFILE *b)
 
 
 /*---------------------------------------------------*/
-void BZ_API(BZ2_bzclose) (BZFILE* b)
+void BZ2_bzclose (BZFILE* b)
 {
    int bzerr;
    FILE *fp;
@@ -1556,7 +1556,7 @@ static const char *bzerrorstrings[] = {
 };
 
 
-const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+const char * BZ2_bzerror (BZFILE *b, int *errnum)
 {
    int err = ((bzFile *)b)->lastErr;
 
diff --git a/third_party/bzip2/bzlib.h b/third_party/bzip2/bzlib.h
index 8966a6c58..ddf252d04 100644
--- a/third_party/bzip2/bzlib.h
+++ b/third_party/bzip2/bzlib.h
@@ -1,225 +1,72 @@
-
-/*-------------------------------------------------------------*/
-/*--- Public header file for the library.                   ---*/
-/*---                                               bzlib.h ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.8 of 13 July 2019
-   Copyright (C) 1996-2019 Julian Seward 
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
 #ifndef _BZLIB_H
 #define _BZLIB_H
+#include "libc/stdio/stdio.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#define BZ_RUN    0
+#define BZ_FLUSH  1
+#define BZ_FINISH 2
 
-#define BZ_RUN               0
-#define BZ_FLUSH             1
-#define BZ_FINISH            2
+#define BZ_OK               0
+#define BZ_RUN_OK           1
+#define BZ_FLUSH_OK         2
+#define BZ_FINISH_OK        3
+#define BZ_STREAM_END       4
+#define BZ_SEQUENCE_ERROR   (-1)
+#define BZ_PARAM_ERROR      (-2)
+#define BZ_MEM_ERROR        (-3)
+#define BZ_DATA_ERROR       (-4)
+#define BZ_DATA_ERROR_MAGIC (-5)
+#define BZ_IO_ERROR         (-6)
+#define BZ_UNEXPECTED_EOF   (-7)
+#define BZ_OUTBUFF_FULL     (-8)
+#define BZ_CONFIG_ERROR     (-9)
 
-#define BZ_OK                0
-#define BZ_RUN_OK            1
-#define BZ_FLUSH_OK          2
-#define BZ_FINISH_OK         3
-#define BZ_STREAM_END        4
-#define BZ_SEQUENCE_ERROR    (-1)
-#define BZ_PARAM_ERROR       (-2)
-#define BZ_MEM_ERROR         (-3)
-#define BZ_DATA_ERROR        (-4)
-#define BZ_DATA_ERROR_MAGIC  (-5)
-#define BZ_IO_ERROR          (-6)
-#define BZ_UNEXPECTED_EOF    (-7)
-#define BZ_OUTBUFF_FULL      (-8)
-#define BZ_CONFIG_ERROR      (-9)
+#define BZ_MAX_UNUSED 5000
 
-typedef 
-   struct {
-      char *next_in;
-      unsigned int avail_in;
-      unsigned int total_in_lo32;
-      unsigned int total_in_hi32;
-
-      char *next_out;
-      unsigned int avail_out;
-      unsigned int total_out_lo32;
-      unsigned int total_out_hi32;
-
-      void *state;
-
-      void *(*bzalloc)(void *,int,int);
-      void (*bzfree)(void *,void *);
-      void *opaque;
-   } 
-   bz_stream;
-
-
-#ifndef BZ_IMPORT
-#define BZ_EXPORT
-#endif
-
-#ifndef BZ_NO_STDIO
-/* Need a definitition for FILE */
-#include 
-#endif
-
-#ifdef _WIN32
-#   include 
-#   ifdef small
-      /* windows.h define small to char */
-#      undef small
-#   endif
-#   ifdef BZ_EXPORT
-#   define BZ_API(func) WINAPI func
-#   define BZ_EXTERN extern
-#   else
-   /* import windows dll dynamically */
-#   define BZ_API(func) (WINAPI * func)
-#   define BZ_EXTERN
-#   endif
-#else
-#   define BZ_API(func) func
-#   define BZ_EXTERN extern
-#endif
+#if !(__ASSEMBLER__ + __LINKER__ + 0)
+COSMOPOLITAN_C_START_
 
+typedef struct {
+  char *next_in;
+  unsigned int avail_in;
+  unsigned int total_in_lo32;
+  unsigned int total_in_hi32;
+  char *next_out;
+  unsigned int avail_out;
+  unsigned int total_out_lo32;
+  unsigned int total_out_hi32;
+  void *state;
+  void *(*bzalloc)(void *, int, int);
+  void (*bzfree)(void *, void *);
+  void *opaque;
+} bz_stream;
 
 /*-- Core (low-level) library functions --*/
 
-BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
-      bz_stream* strm, 
-      int        blockSize100k, 
-      int        verbosity, 
-      int        workFactor 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
-      bz_stream* strm, 
-      int action 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
-      bz_stream* strm 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
-      bz_stream *strm, 
-      int       verbosity, 
-      int       small
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
-      bz_stream* strm 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
-      bz_stream *strm 
-   );
-
-
+int BZ2_bzCompressInit(bz_stream *, int, int, int);
+int BZ2_bzCompress(bz_stream *, int);
+int BZ2_bzCompressEnd(bz_stream *);
+int BZ2_bzDecompressInit(bz_stream *, int, int);
+int BZ2_bzDecompress(bz_stream *);
+int BZ2_bzDecompressEnd(bz_stream *);
 
 /*-- High(er) level library functions --*/
 
-#ifndef BZ_NO_STDIO
-#define BZ_MAX_UNUSED 5000
-
 typedef void BZFILE;
 
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
-      int*  bzerror,   
-      FILE* f, 
-      int   verbosity, 
-      int   small,
-      void* unused,    
-      int   nUnused 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
-      int*    bzerror, 
-      BZFILE* b 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
-      int*    bzerror, 
-      BZFILE* b, 
-      void**  unused,  
-      int*    nUnused 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
-      int*    bzerror, 
-      BZFILE* b, 
-      void*   buf, 
-      int     len 
-   );
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
-      int*  bzerror,      
-      FILE* f, 
-      int   blockSize100k, 
-      int   verbosity, 
-      int   workFactor 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
-      int*    bzerror, 
-      BZFILE* b, 
-      void*   buf, 
-      int     len 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
-      int*          bzerror, 
-      BZFILE*       b, 
-      int           abandon, 
-      unsigned int* nbytes_in, 
-      unsigned int* nbytes_out 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
-      int*          bzerror, 
-      BZFILE*       b, 
-      int           abandon, 
-      unsigned int* nbytes_in_lo32, 
-      unsigned int* nbytes_in_hi32, 
-      unsigned int* nbytes_out_lo32, 
-      unsigned int* nbytes_out_hi32
-   );
-#endif
-
-
-/*-- Utility functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
-      char*         dest, 
-      unsigned int* destLen,
-      char*         source, 
-      unsigned int  sourceLen,
-      int           blockSize100k, 
-      int           verbosity, 
-      int           workFactor 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
-      char*         dest, 
-      unsigned int* destLen,
-      char*         source, 
-      unsigned int  sourceLen,
-      int           small, 
-      int           verbosity 
-   );
-
+BZFILE *BZ2_bzReadOpen(int *, FILE *, int, int, void *, int);
+void BZ2_bzReadClose(int *, BZFILE *);
+void BZ2_bzReadGetUnused(int *, BZFILE *, void **, int *);
+int BZ2_bzRead(int *, BZFILE *, void *, int);
+BZFILE *BZ2_bzWriteOpen(int *, FILE *, int, int, int);
+void BZ2_bzWrite(int *, BZFILE *, void *, int);
+void BZ2_bzWriteClose(int *, BZFILE *, int, unsigned int *, unsigned int *);
+void BZ2_bzWriteClose64(int *, BZFILE *, int, unsigned int *, unsigned int *,
+                        unsigned int *, unsigned int *);
+int BZ2_bzBuffToBuffCompress(char *, unsigned int *, char *, unsigned int, int,
+                             int, int);
+int BZ2_bzBuffToBuffDecompress(char *, unsigned int *, char *, unsigned int,
+                               int, int);
 
 /*--
    Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
@@ -230,53 +77,15 @@ BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
    If this code breaks, please contact both Yoshioka and me.
 --*/
 
-BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
-      void
-   );
+const char *BZ2_bzlibVersion(void);
+BZFILE *BZ2_bzopen(const char *, const char *);
+BZFILE *BZ2_bzdopen(int, const char *);
+int BZ2_bzread(BZFILE *, void *, int);
+int BZ2_bzwrite(BZFILE *, void *, int);
+int BZ2_bzflush(BZFILE *);
+void BZ2_bzclose(BZFILE *);
+const char *BZ2_bzerror(BZFILE *, int *);
 
-#ifndef BZ_NO_STDIO
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
-      const char *path,
-      const char *mode
-   );
-
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
-      int        fd,
-      const char *mode
-   );
-         
-BZ_EXTERN int BZ_API(BZ2_bzread) (
-      BZFILE* b, 
-      void* buf, 
-      int len 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzwrite) (
-      BZFILE* b, 
-      void*   buf, 
-      int     len 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzflush) (
-      BZFILE* b
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzclose) (
-      BZFILE* b
-   );
-
-BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
-      BZFILE *b, 
-      int    *errnum
-   );
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*-------------------------------------------------------------*/
-/*--- end                                           bzlib.h ---*/
-/*-------------------------------------------------------------*/
+COSMOPOLITAN_C_END_
+#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+#endif /* _BZLIB_H */
diff --git a/third_party/bzip2/bzlib_private.h b/third_party/bzip2/bzlib_private.inc
similarity index 95%
rename from third_party/bzip2/bzlib_private.h
rename to third_party/bzip2/bzlib_private.inc
index 3755a6f70..b05920905 100644
--- a/third_party/bzip2/bzlib_private.h
+++ b/third_party/bzip2/bzlib_private.inc
@@ -1,3 +1,8 @@
+#include "third_party/bzip2/bzlib.h"
+
+#define BZ_NO_STDIO
+
+/* clang-format off */
 
 /*-------------------------------------------------------------*/
 /*--- Private header file for the library.                  ---*/
@@ -18,22 +23,6 @@
    in the file LICENSE.
    ------------------------------------------------------------------ */
 
-
-#ifndef _BZLIB_PRIVATE_H
-#define _BZLIB_PRIVATE_H
-
-#include 
-
-#ifndef BZ_NO_STDIO
-#include 
-#include 
-#include 
-#endif
-
-#include "bzlib.h"
-
-
-
 /*-- General stuff. --*/
 
 #define BZ_VERSION  "1.0.8, 13-Jul-2019"
@@ -68,7 +57,7 @@ extern void BZ2_bz__AssertH__fail ( int errcode );
    }}
 #else
 #define AssertD(cond,msg) /* */
-#endif
+#endif /* BZ_DEBUG */
 
 #define VPrintf0(zf) \
    fprintf(stderr,zf)
@@ -83,7 +72,7 @@ extern void BZ2_bz__AssertH__fail ( int errcode );
 #define VPrintf5(zf,za1,za2,za3,za4,za5) \
    fprintf(stderr,zf,za1,za2,za3,za4,za5)
 
-#else
+#else /* BZ_NO_STDIO */
 
 extern void bz_internal_error ( int errcode );
 #define AssertH(cond,errcode) \
@@ -96,7 +85,7 @@ extern void bz_internal_error ( int errcode );
 #define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
 #define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
 
-#endif
+#endif /* BZ_NO_STDIO */
 
 
 #define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
@@ -490,20 +479,3 @@ BZ2_decompress ( DState* );
 extern void 
 BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
                            Int32,  Int32, Int32 );
-
-
-#endif
-
-
-/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
-
-#ifdef BZ_NO_STDIO
-#ifndef NULL
-#define NULL 0
-#endif
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                   bzlib_private.h ---*/
-/*-------------------------------------------------------------*/
diff --git a/third_party/bzip2/compress.c b/third_party/bzip2/compress.c
index 5dfa00231..6bff8a238 100644
--- a/third_party/bzip2/compress.c
+++ b/third_party/bzip2/compress.c
@@ -1,3 +1,4 @@
+/* clang-format off */
 
 /*-------------------------------------------------------------*/
 /*--- Compression machinery (not incl block sorting)        ---*/
@@ -26,7 +27,7 @@
                 so as to do a bit better on small files
 */
 
-#include "bzlib_private.h"
+#include "third_party/bzip2/bzlib_private.inc"
 
 
 /*---------------------------------------------------*/
@@ -239,7 +240,7 @@ static
 void sendMTFValues ( EState* s )
 {
    Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
-   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+   Int32 nSelectors=0, alphaSize, minLen, maxLen, selCtr;
    Int32 nGroups, nBytes;
 
    /*--
diff --git a/third_party/bzip2/crctable.c b/third_party/bzip2/crctable.c
index 2b33c2535..c4ee9a00e 100644
--- a/third_party/bzip2/crctable.c
+++ b/third_party/bzip2/crctable.c
@@ -1,104 +1,93 @@
+/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
+│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
+╞══════════════════════════════════════════════════════════════════════════════╡
+│ Copyright 2021 Justine Alexandra Roberts Tunney                              │
+│                                                                              │
+│ Permission to use, copy, modify, and/or distribute this software for         │
+│ any purpose with or without fee is hereby granted, provided that the         │
+│ above copyright notice and this permission notice appear in all copies.      │
+│                                                                              │
+│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
+│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
+│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
+│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
+│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
+│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
+│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
+│ PERFORMANCE OF THIS SOFTWARE.                                                │
+╚─────────────────────────────────────────────────────────────────────────────*/
+#ifdef TINY
 
-/*-------------------------------------------------------------*/
-/*--- Table for doing CRCs                                  ---*/
-/*---                                            crctable.c ---*/
-/*-------------------------------------------------------------*/
+uint32_t BZ2_crc32Table[256];
 
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
+static textstartup void BZ2_crc32Table_init() {
+  unsigned i, j, u;
+  for (i = 0; i < 256; ++i) {
+    u = i << 24;
+    for (j = 8; j; --j) {
+      if ((int32_t)u < 0) {
+        u = (u << 1) ^ 0x04c11db7;
+      } else {
+        u <<= 1;
+      }
+    }
+    BZ2_crc32Table[i] = u;
+  }
+  if (BZ2_crc32Table[0] || BZ2_crc32Table[255] != 0xb1f740b4) {
+    asm("hlt");
+  }
+}
 
-   bzip2/libbzip2 version 1.0.8 of 13 July 2019
-   Copyright (C) 1996-2019 Julian Seward 
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#include "bzlib_private.h"
-
-/*--
-  I think this is an implementation of the AUTODIN-II,
-  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
-  from code by Rob Warnock, in Section 51 of the
-  comp.compression FAQ.
---*/
-
-UInt32 BZ2_crc32Table[256] = {
-
-   /*-- Ugly, innit? --*/
-
-   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
-   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
-   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
-   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
-   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
-   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
-   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
-   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
-   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
-   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
-   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
-   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
-   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
-   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
-   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
-   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
-   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
-   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
-   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
-   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
-   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
-   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
-   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
-   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
-   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
-   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
-   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
-   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
-   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
-   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
-   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
-   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
-   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
-   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
-   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
-   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
-   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
-   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
-   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
-   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
-   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
-   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
-   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
-   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
-   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
-   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
-   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
-   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
-   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
-   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
-   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
-   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
-   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
-   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
-   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
-   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
-   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
-   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
-   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
-   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
-   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
-   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
-   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
-   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+const void *const BZ2_crc32Table_ctor[] initarray = {
+    BZ2_crc32Table_init,
 };
 
+#else
 
-/*-------------------------------------------------------------*/
-/*--- end                                        crctable.c ---*/
-/*-------------------------------------------------------------*/
+const uint32_t BZ2_crc32Table[256] = {
+    0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+    0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+    0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
+    0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+    0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
+    0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
+    0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+    0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
+    0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+    0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
+    0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+    0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
+    0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+    0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
+    0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+    0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
+    0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+    0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
+    0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+    0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
+    0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+    0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
+    0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+    0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
+    0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+    0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
+    0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+    0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
+    0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+    0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
+    0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+    0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
+    0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+    0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
+    0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
+    0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+    0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
+    0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+    0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
+    0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+    0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4,
+};
+
+#endif
diff --git a/third_party/bzip2/decompress.c b/third_party/bzip2/decompress.c
index a1a0bac89..baf87d277 100644
--- a/third_party/bzip2/decompress.c
+++ b/third_party/bzip2/decompress.c
@@ -1,3 +1,4 @@
+/* clang-format off */
 
 /*-------------------------------------------------------------*/
 /*--- Decompression machinery                               ---*/
@@ -19,7 +20,7 @@
    ------------------------------------------------------------------ */
 
 
-#include "bzlib_private.h"
+#include "third_party/bzip2/bzlib_private.inc"
 
 
 /*---------------------------------------------------*/
diff --git a/third_party/bzip2/dlltest.c b/third_party/bzip2/dlltest.c
deleted file mode 100644
index 03fa14620..000000000
--- a/third_party/bzip2/dlltest.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
-   minibz2
-      libbz2.dll test program.
-      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
-      This file is Public Domain.  Welcome any email to me.
-
-   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
-*/
-
-#define BZ_IMPORT
-#include 
-#include 
-#include "bzlib.h"
-#ifdef _WIN32
-#include 
-#endif
-
-
-#ifdef _WIN32
-
-#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 
-
-#include 
-static int BZ2DLLLoaded = 0;
-static HINSTANCE BZ2DLLhLib;
-int BZ2DLLLoadLibrary(void)
-{
-   HINSTANCE hLib;
-
-   if(BZ2DLLLoaded==1){return 0;}
-   hLib=LoadLibrary(BZ2_LIBNAME);
-   if(hLib == NULL){
-      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
-      return -1;
-   }
-   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
-   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
-   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
-   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
-   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
-   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
-   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
-   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
-
-   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
-       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
-       || !BZ2_bzclose || !BZ2_bzerror) {
-      fprintf(stderr,"GetProcAddress failed.\n");
-      return -1;
-   }
-   BZ2DLLLoaded=1;
-   BZ2DLLhLib=hLib;
-   return 0;
-
-}
-int BZ2DLLFreeLibrary(void)
-{
-   if(BZ2DLLLoaded==0){return 0;}
-   FreeLibrary(BZ2DLLhLib);
-   BZ2DLLLoaded=0;
-}
-#endif /* WIN32 */
-
-void usage(void)
-{
-   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
-}
-
-int main(int argc,char *argv[])
-{
-   int decompress = 0;
-   int level = 9;
-   char *fn_r = NULL;
-   char *fn_w = NULL;
-
-#ifdef _WIN32
-   if(BZ2DLLLoadLibrary()<0){
-      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);
-      exit(1);
-   }
-   printf("Loading of %s succeeded.  Library version is %s.\n",
-          BZ2_LIBNAME, BZ2_bzlibVersion() );
-#endif
-   while(++argv,--argc){
-      if(**argv =='-' || **argv=='/'){
-         char *p;
-
-         for(p=*argv+1;*p;p++){
-            if(*p=='d'){
-               decompress = 1;
-            }else if('1'<=*p && *p<='9'){
-               level = *p - '0';
-            }else{
-               usage();
-               exit(1);
-            }
-         }
-      }else{
-         break;
-      }
-   }
-   if(argc>=1){
-      fn_r = *argv;
-      argc--;argv++;
-   }else{
-      fn_r = NULL;
-   }
-   if(argc>=1){
-      fn_w = *argv;
-      argc--;argv++;
-   }else{
-      fn_w = NULL;
-   }
-   {
-      int len;
-      char buff[0x1000];
-      char mode[10];
-
-      if(decompress){
-         BZFILE *BZ2fp_r = NULL;
-         FILE *fp_w = NULL;
-
-         if(fn_w){
-            if((fp_w = fopen(fn_w,"wb"))==NULL){
-               printf("can't open [%s]\n",fn_w);
-               perror("reason:");
-               exit(1);
-            }
-         }else{
-            fp_w = stdout;
-         }
-         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
-            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
-            printf("can't bz2openstream\n");
-            exit(1);
-         }
-         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
-            fwrite(buff,1,len,fp_w);
-         }
-         BZ2_bzclose(BZ2fp_r);
-         if(fp_w != stdout) fclose(fp_w);
-      }else{
-         BZFILE *BZ2fp_w = NULL;
-         FILE *fp_r = NULL;
-
-         if(fn_r){
-            if((fp_r = fopen(fn_r,"rb"))==NULL){
-               printf("can't open [%s]\n",fn_r);
-               perror("reason:");
-               exit(1);
-            }
-         }else{
-            fp_r = stdin;
-         }
-         mode[0]='w';
-         mode[1] = '0' + level;
-         mode[2] = '\0';
-
-         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
-            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
-            printf("can't bz2openstream\n");
-            exit(1);
-         }
-         while((len=fread(buff,1,0x1000,fp_r))>0){
-            BZ2_bzwrite(BZ2fp_w,buff,len);
-         }
-         BZ2_bzclose(BZ2fp_w);
-         if(fp_r!=stdin)fclose(fp_r);
-      }
-   }
-#ifdef _WIN32
-   BZ2DLLFreeLibrary();
-#endif
-   return 0;
-}
diff --git a/third_party/bzip2/huffman.c b/third_party/bzip2/huffman.c
index 43a1899e4..598b864e5 100644
--- a/third_party/bzip2/huffman.c
+++ b/third_party/bzip2/huffman.c
@@ -1,3 +1,4 @@
+/* clang-format off */
 
 /*-------------------------------------------------------------*/
 /*--- Huffman coding low-level stuff                        ---*/
@@ -19,7 +20,9 @@
    ------------------------------------------------------------------ */
 
 
-#include "bzlib_private.h"
+#include "libc/runtime/gc.internal.h"
+#include "libc/mem/mem.h"
+#include "third_party/bzip2/bzlib_private.inc"
 
 /*---------------------------------------------------*/
 #define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
@@ -72,9 +75,9 @@ void BZ2_hbMakeCodeLengths ( UChar *len,
    Int32 nNodes, nHeap, n1, n2, i, j, k;
    Bool  tooLong;
 
-   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
-   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
-   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
+   Int32 *heap   = gc(calloc(BZ_MAX_ALPHA_SIZE + 2, 4));
+   Int32 *weight = gc(calloc(BZ_MAX_ALPHA_SIZE * 2, 4));
+   Int32 *parent = gc(calloc(BZ_MAX_ALPHA_SIZE * 2, 4));
 
    for (i = 0; i < alphaSize; i++)
       weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
diff --git a/third_party/bzip2/libbz2.def b/third_party/bzip2/libbz2.def
deleted file mode 100644
index 2dc0dd891..000000000
--- a/third_party/bzip2/libbz2.def
+++ /dev/null
@@ -1,27 +0,0 @@
-LIBRARY			LIBBZ2
-DESCRIPTION		"libbzip2: library for data compression"
-EXPORTS
-	BZ2_bzCompressInit
-	BZ2_bzCompress
-	BZ2_bzCompressEnd
-	BZ2_bzDecompressInit
-	BZ2_bzDecompress
-	BZ2_bzDecompressEnd
-	BZ2_bzReadOpen
-	BZ2_bzReadClose
-	BZ2_bzReadGetUnused
-	BZ2_bzRead
-	BZ2_bzWriteOpen
-	BZ2_bzWrite
-	BZ2_bzWriteClose
-	BZ2_bzWriteClose64
-	BZ2_bzBuffToBuffCompress
-	BZ2_bzBuffToBuffDecompress
-	BZ2_bzlibVersion
-	BZ2_bzopen
-	BZ2_bzdopen
-	BZ2_bzread
-	BZ2_bzwrite
-	BZ2_bzflush
-	BZ2_bzclose
-	BZ2_bzerror
diff --git a/third_party/bzip2/manual.xml b/third_party/bzip2/manual.xml
deleted file mode 100644
index ea9fca2e8..000000000
--- a/third_party/bzip2/manual.xml
+++ /dev/null
@@ -1,2964 +0,0 @@
- 
-
- %common-ents;
-]>
-
-
-
- 
-  bzip2 and libbzip2, version &bz-version;
-  A program and library for data compression
-  
-   &bz-lifespan;
-   Julian Seward
-  
-  Version &bz-version; of &bz-date;
-
-  
-   
-    Julian
-    Seward
-    
-     &bz-url;
-    
-   
-  
-
-  
-
-  This program, bzip2, the
-  associated library libbzip2, and
-  all documentation, are copyright © &bz-lifespan; Julian Seward.
-  All rights reserved.
-
-  Redistribution and use in source and binary forms, with
-  or without modification, are permitted provided that the
-  following conditions are met:
-
-  
-
-   Redistributions of source code must retain the
-   above copyright notice, this list of conditions and the
-   following disclaimer.
-
-   The origin of this software must not be
-   misrepresented; you must not claim that you wrote the original
-   software.  If you use this software in a product, an
-   acknowledgment in the product documentation would be
-   appreciated but is not required.
-
-   Altered source versions must be plainly marked
-   as such, and must not be misrepresented as being the original
-   software.
-
-   The name of the author may not be used to
-   endorse or promote products derived from this software without
-   specific prior written permission.
-
-  
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY
-  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
-  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-  THE POSSIBILITY OF SUCH DAMAGE.
-
- PATENTS: To the best of my knowledge,
- bzip2 and
- libbzip2 do not use any patented
- algorithms.  However, I do not have the resources to carry
- out a patent search.  Therefore I cannot give any guarantee of
- the above statement.
- 
-
-
-
-
-
-
-
-
-Introduction
-
-bzip2 compresses files
-using the Burrows-Wheeler block-sorting text compression
-algorithm, and Huffman coding.  Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.
-
-bzip2 is built on top of
-libbzip2, a flexible library for
-handling compressed data in the
-bzip2 format.  This manual
-describes both how to use the program and how to work with the
-library interface.  Most of the manual is devoted to this
-library, not the program, which is good news if your interest is
-only in the program.
-
-
-
-  describes how to use
- bzip2; this is the only part
- you need to read if you just want to know how to operate the
- program.
-
-  describes the
- programming interfaces in detail, and
-
-  records some
- miscellaneous notes which I thought ought to be recorded
- somewhere.
-
-
-
-
-
-
-
-How to use bzip2
-
-This chapter contains a copy of the
-bzip2 man page, and nothing
-else.
-
-
-NAME
-
-
-
- bzip2,
-  bunzip2 - a block-sorting file
-  compressor, v&bz-version;
-
- bzcat -
-   decompresses files to stdout
-
- bzip2recover -
-   recovers data from damaged bzip2 files
-
-
-
-
-
-
-
-SYNOPSIS
-
-
-
- bzip2 [
-  -cdfkqstvzVL123456789 ] [ filenames ...  ]
-
- bunzip2 [
-  -fkvsVL ] [ filenames ...  ]
-
- bzcat [ -s ] [
-  filenames ...  ]
-
- bzip2recover
-  filename
-
-
-
-
-
-
-
-DESCRIPTION
-
-bzip2 compresses files
-using the Burrows-Wheeler block sorting text compression
-algorithm, and Huffman coding.  Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.
-
-The command-line options are deliberately very similar to
-those of GNU gzip, but they are
-not identical.
-
-bzip2 expects a list of
-file names to accompany the command-line flags.  Each file is
-replaced by a compressed version of itself, with the name
-original_name.bz2.  Each
-compressed file has the same modification date, permissions, and,
-when possible, ownership as the corresponding original, so that
-these properties can be correctly restored at decompression time.
-File name handling is naive in the sense that there is no
-mechanism for preserving original file names, permissions,
-ownerships or dates in filesystems which lack these concepts, or
-have serious file name length restrictions, such as
-MS-DOS.
-
-bzip2 and
-bunzip2 will by default not
-overwrite existing files.  If you want this to happen, specify
-the -f flag.
-
-If no file names are specified,
-bzip2 compresses from standard
-input to standard output.  In this case,
-bzip2 will decline to write
-compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.
-
-bunzip2 (or
-bzip2 -d) decompresses all
-specified files.  Files which were not created by
-bzip2 will be detected and
-ignored, and a warning issued.
-bzip2 attempts to guess the
-filename for the decompressed file from that of the compressed
-file as follows:
-
-
-
- filename.bz2 
-  becomes
-  filename
-
- filename.bz 
-  becomes
-  filename
-
- filename.tbz2
-  becomes
-  filename.tar
-
- filename.tbz 
-  becomes
-  filename.tar
-
- anyothername 
-  becomes
-  anyothername.out
-
-
-
-If the file does not end in one of the recognised endings,
-.bz2,
-.bz,
-.tbz2 or
-.tbz,
-bzip2 complains that it cannot
-guess the name of the original file, and uses the original name
-with .out appended.
-
-As with compression, supplying no filenames causes
-decompression from standard input to standard output.
-
-bunzip2 will correctly
-decompress a file which is the concatenation of two or more
-compressed files.  The result is the concatenation of the
-corresponding uncompressed files.  Integrity testing
-(-t) of concatenated compressed
-files is also supported.
-
-You can also compress or decompress files to the standard
-output by giving the -c flag.
-Multiple files may be compressed and decompressed like this.  The
-resulting outputs are fed sequentially to stdout.  Compression of
-multiple files in this manner generates a stream containing
-multiple compressed file representations.  Such a stream can be
-decompressed correctly only by
-bzip2 version 0.9.0 or later.
-Earlier versions of bzip2 will
-stop after decompressing the first file in the stream.
-
-bzcat (or
-bzip2 -dc) decompresses all
-specified files to the standard output.
-
-bzip2 will read arguments
-from the environment variables
-BZIP2 and
-BZIP, in that order, and will
-process them before any arguments read from the command line.
-This gives a convenient way to supply default arguments.
-
-Compression is always performed, even if the compressed
-file is slightly larger than the original.  Files of less than
-about one hundred bytes tend to get larger, since the compression
-mechanism has a constant overhead in the region of 50 bytes.
-Random data (including the output of most file compressors) is
-coded at about 8.05 bits per byte, giving an expansion of around
-0.5%.
-
-As a self-check for your protection,
-bzip2 uses 32-bit CRCs to make
-sure that the decompressed version of a file is identical to the
-original.  This guards against corruption of the compressed data,
-and against undetected bugs in
-bzip2 (hopefully very unlikely).
-The chances of data corruption going undetected is microscopic,
-about one chance in four billion for each file processed.  Be
-aware, though, that the check occurs upon decompression, so it
-can only tell you that something is wrong.  It can't help you
-recover the original uncompressed data.  You can use
-bzip2recover to try to recover
-data from damaged files.
-
-Return values: 0 for a normal exit, 1 for environmental
-problems (file not found, invalid flags, I/O errors, etc.), 2
-to indicate a corrupt compressed file, 3 for an internal
-consistency error (eg, bug) which caused
-bzip2 to panic.
-
-
-
-
-
-OPTIONS
-
-
-
- 
- -c --stdout
- Compress or decompress to standard
-  output.
- 
-
- 
- -d --decompress
- Force decompression.
-  bzip2,
-  bunzip2 and
-  bzcat are really the same
-  program, and the decision about what actions to take is done on
-  the basis of which name is used.  This flag overrides that
-  mechanism, and forces bzip2 to decompress.
- 
-
- 
- -z --compress
- The complement to
-  -d: forces compression,
-  regardless of the invokation name.
- 
-
- 
- -t --test
- Check integrity of the specified file(s), but
-  don't decompress them.  This really performs a trial
-  decompression and throws away the result.
- 
-
- 
- -f --force
- Force overwrite of output files.  Normally,
-  bzip2 will not overwrite
-  existing output files.  Also forces
-  bzip2 to break hard links to
-  files, which it otherwise wouldn't do.
-  bzip2 normally declines
-  to decompress files which don't have the correct magic header
-  bytes. If forced (-f),
-  however, it will pass such files through unmodified. This is
-  how GNU gzip behaves.
- 
- 
-
- 
- -k --keep
- Keep (don't delete) input files during
-  compression or decompression.
- 
-
- 
- -s --small
- Reduce memory usage, for compression,
-  decompression and testing.  Files are decompressed and tested
-  using a modified algorithm which only requires 2.5 bytes per
-  block byte.  This means any file can be decompressed in 2300k
-  of memory, albeit at about half the normal speed.
-  During compression, -s
-  selects a block size of 200k, which limits memory use to around
-  the same figure, at the expense of your compression ratio.  In
-  short, if your machine is low on memory (8 megabytes or less),
-  use -s for everything.  See
-   below.
- 
-
- 
- -q --quiet
- Suppress non-essential warning messages.
-  Messages pertaining to I/O errors and other critical events
-  will not be suppressed.
- 
-
- 
- -v --verbose
- Verbose mode -- show the compression ratio for
-  each file processed.  Further
-  -v's increase the verbosity
-  level, spewing out lots of information which is primarily of
-  interest for diagnostic purposes.
- 
-
- 
- -L --license -V --version
- Display the software version, license terms and
-  conditions.
- 
-
- 
- -1 (or
- --fast) to
- -9 (or
- -best)
- Set the block size to 100 k, 200 k ...  900 k
-  when compressing.  Has no effect when decompressing.  See  below.  The
-  --fast and
-  --best aliases are primarily
-  for GNU gzip compatibility.
-  In particular, --fast doesn't
-  make things significantly faster.  And
-  --best merely selects the
-  default behaviour.
- 
-
- 
- --
- Treats all subsequent arguments as file names,
-  even if they start with a dash.  This is so you can handle
-  files with names beginning with a dash, for example:
-  bzip2 --
-  -myfilename.
- 
-
- 
- --repetitive-fast
- --repetitive-best
- These flags are redundant in versions 0.9.5 and
-  above.  They provided some coarse control over the behaviour of
-  the sorting algorithm in earlier versions, which was sometimes
-  useful.  0.9.5 and above have an improved algorithm which
-  renders these flags irrelevant.
- 
-
-
-
-
-
-
-
-MEMORY MANAGEMENT
-
-bzip2 compresses large
-files in blocks.  The block size affects both the compression
-ratio achieved, and the amount of memory needed for compression
-and decompression.  The flags -1
-through -9 specify the block
-size to be 100,000 bytes through 900,000 bytes (the default)
-respectively.  At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-bunzip2 then allocates itself
-just enough memory to decompress the file.  Since block sizes are
-stored in compressed files, it follows that the flags
--1 to
--9 are irrelevant to and so
-ignored during decompression.
-
-Compression and decompression requirements, in bytes, can be
-estimated as:
-
-Compression:   400k + ( 8 x block size )
-
-Decompression: 100k + ( 4 x block size ), or
-               100k + ( 2.5 x block size )
-
-
-Larger block sizes give rapidly diminishing marginal
-returns.  Most of the compression comes from the first two or
-three hundred k of block size, a fact worth bearing in mind when
-using bzip2 on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block
-size.
-
-For files compressed with the default 900k block size,
-bunzip2 will require about 3700
-kbytes to decompress.  To support decompression of any file on a
-4 megabyte machine, bunzip2 has
-an option to decompress using approximately half this amount of
-memory, about 2300 kbytes.  Decompression speed is also halved,
-so you should use this option only where necessary.  The relevant
-flag is -s.
-
-In general, try and use the largest block size memory
-constraints allow, since that maximises the compression achieved.
-Compression and decompression speed are virtually unaffected by
-block size.
-
-Another significant point applies to files which fit in a
-single block -- that means most files you'd encounter using a
-large block size.  The amount of real memory touched is
-proportional to the size of the file, since the file is smaller
-than a block.  For example, compressing a file 20,000 bytes long
-with the flag -9 will cause the
-compressor to allocate around 7600k of memory, but only touch
-400k + 20000 * 8 = 560 kbytes of it.  Similarly, the decompressor
-will allocate 3700k but only touch 100k + 20000 * 4 = 180
-kbytes.
-
-Here is a table which summarises the maximum memory usage
-for different block sizes.  Also recorded is the total compressed
-size for 14 files of the Calgary Text Compression Corpus
-totalling 3,141,622 bytes.  This column gives some feel for how
-compression varies with block size.  These figures tend to
-understate the advantage of larger block sizes for larger files,
-since the Corpus is dominated by smaller files.
-
-
-        Compress   Decompress   Decompress   Corpus
-Flag     usage      usage       -s usage     Size
-
- -1      1200k       500k         350k      914704
- -2      2000k       900k         600k      877703
- -3      2800k      1300k         850k      860338
- -4      3600k      1700k        1100k      846899
- -5      4400k      2100k        1350k      845160
- -6      5200k      2500k        1600k      838626
- -7      6100k      2900k        1850k      834096
- -8      6800k      3300k        2100k      828642
- -9      7600k      3700k        2350k      828642
-
-
-
-
-
-
-RECOVERING DATA FROM DAMAGED FILES
-
-bzip2 compresses files in
-blocks, usually 900kbytes long.  Each block is handled
-independently.  If a media or transmission error causes a
-multi-block .bz2 file to become
-damaged, it may be possible to recover data from the undamaged
-blocks in the file.
-
-The compressed representation of each block is delimited by
-a 48-bit pattern, which makes it possible to find the block
-boundaries with reasonable certainty.  Each block also carries
-its own 32-bit CRC, so damaged blocks can be distinguished from
-undamaged ones.
-
-bzip2recover is a simple
-program whose purpose is to search for blocks in
-.bz2 files, and write each block
-out into its own .bz2 file.  You
-can then use bzip2 -t to test
-the integrity of the resulting files, and decompress those which
-are undamaged.
-
-bzip2recover takes a
-single argument, the name of the damaged file, and writes a
-number of files rec0001file.bz2,
-rec0002file.bz2, etc, containing
-the extracted blocks.  The output filenames are designed so that
-the use of wildcards in subsequent processing -- for example,
-bzip2 -dc rec*file.bz2 >
-recovered_data -- lists the files in the correct
-order.
-
-bzip2recover should be of
-most use dealing with large .bz2
-files, as these will contain many blocks.  It is clearly futile
-to use it on damaged single-block files, since a damaged block
-cannot be recovered.  If you wish to minimise any potential data
-loss through media or transmission errors, you might consider
-compressing with a smaller block size.
-
-
-
-
-
-PERFORMANCE NOTES
-
-The sorting phase of compression gathers together similar
-strings in the file.  Because of this, files containing very long
-runs of repeated symbols, like "aabaabaabaab ..."  (repeated
-several hundred times) may compress more slowly than normal.
-Versions 0.9.5 and above fare much better than previous versions
-in this respect.  The ratio between worst-case and average-case
-compression time is in the region of 10:1.  For previous
-versions, this figure was more like 100:1.  You can use the
--vvvv option to monitor progress
-in great detail, if you want.
-
-Decompression speed is unaffected by these
-phenomena.
-
-bzip2 usually allocates
-several megabytes of memory to operate in, and then charges all
-over it in a fairly random fashion.  This means that performance,
-both for compressing and decompressing, is largely determined by
-the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss
-rate have been observed to give disproportionately large
-performance improvements.  I imagine
-bzip2 will perform best on
-machines with very large caches.
-
-
-
-
-
-
-CAVEATS
-
-I/O error messages are not as helpful as they could be.
-bzip2 tries hard to detect I/O
-errors and exit cleanly, but the details of what the problem is
-sometimes seem rather misleading.
-
-This manual page pertains to version &bz-version; of
-bzip2.  Compressed data created by
-this version is entirely forwards and backwards compatible with the
-previous public releases, versions 0.1pl2, 0.9.0 and 0.9.5, 1.0.0,
-1.0.1, 1.0.2 and 1.0.3, but with the following exception: 0.9.0 and
-above can correctly decompress multiple concatenated compressed files.
-0.1pl2 cannot do this; it will stop after decompressing just the first
-file in the stream.
-
-bzip2recover versions
-prior to 1.0.2 used 32-bit integers to represent bit positions in
-compressed files, so it could not handle compressed files more
-than 512 megabytes long.  Versions 1.0.2 and above use 64-bit ints
-on some platforms which support them (GNU supported targets, and
-Windows). To establish whether or not
-bzip2recover was built with such
-a limitation, run it without arguments. In any event you can
-build yourself an unlimited version if you can recompile it with
-MaybeUInt64 set to be an
-unsigned 64-bit integer.
-
-
-
-
-
-
-AUTHOR
-
-Julian Seward,
-&bz-author;
-
-The ideas embodied in
-bzip2 are due to (at least) the
-following people: Michael Burrows and David Wheeler (for the
-block sorting transformation), David Wheeler (again, for the
-Huffman coder), Peter Fenwick (for the structured coding model in
-the original bzip, and many
-refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original
-bzip).  I am much indebted for
-their help, support and advice.  See the manual in the source
-distribution for pointers to sources of documentation.  Christian
-von Roques encouraged me to look for faster sorting algorithms,
-so as to speed up compression.  Bela Lubkin encouraged me to
-improve the worst-case compression performance.  
-Donna Robinson XMLised the documentation.
-Many people sent
-patches, helped with portability problems, lent machines, gave
-advice and were generally helpful.
-
-
-
-
-
-
-
-
-
-Programming with <computeroutput>libbzip2</computeroutput>
-
-
-This chapter describes the programming interface to
-libbzip2.
-
-For general background information, particularly about
-memory use and performance aspects, you'd be well advised to read
- as well.
-
-
-
-Top-level structure
-
-libbzip2 is a flexible
-library for compressing and decompressing data in the
-bzip2 data format.  Although
-packaged as a single entity, it helps to regard the library as
-three separate parts: the low level interface, and the high level
-interface, and some utility functions.
-
-The structure of
-libbzip2's interfaces is similar
-to that of Jean-loup Gailly's and Mark Adler's excellent
-zlib library.
-
-All externally visible symbols have names beginning
-BZ2_.  This is new in version
-1.0.  The intention is to minimise pollution of the namespaces of
-library clients.
-
-To use any part of the library, you need to
-#include <bzlib.h>
-into your sources.
-
-
-
-
-Low-level summary
-
-This interface provides services for compressing and
-decompressing data in memory.  There's no provision for dealing
-with files, streams or any other I/O mechanisms, just straight
-memory-to-memory work.  In fact, this part of the library can be
-compiled without inclusion of
-stdio.h, which may be helpful
-for embedded applications.
-
-The low-level part of the library has no global variables
-and is therefore thread-safe.
-
-Six routines make up the low level interface:
-BZ2_bzCompressInit,
-BZ2_bzCompress, and
-BZ2_bzCompressEnd for
-compression, and a corresponding trio
-BZ2_bzDecompressInit,
-BZ2_bzDecompress and
-BZ2_bzDecompressEnd for
-decompression.  The *Init
-functions allocate memory for compression/decompression and do
-other initialisations, whilst the
-*End functions close down
-operations and release memory.
-
-The real work is done by
-BZ2_bzCompress and
-BZ2_bzDecompress.  These
-compress and decompress data from a user-supplied input buffer to
-a user-supplied output buffer.  These buffers can be any size;
-arbitrary quantities of data are handled by making repeated calls
-to these functions.  This is a flexible mechanism allowing a
-consumer-pull style of activity, or producer-push, or a mixture
-of both.
-
-
-
-
-
-High-level summary
-
-This interface provides some handy wrappers around the
-low-level interface to facilitate reading and writing
-bzip2 format files
-(.bz2 files).  The routines
-provide hooks to facilitate reading files in which the
-bzip2 data stream is embedded
-within some larger-scale file structure, or where there are
-multiple bzip2 data streams
-concatenated end-to-end.
-
-For reading files,
-BZ2_bzReadOpen,
-BZ2_bzRead,
-BZ2_bzReadClose and 
-BZ2_bzReadGetUnused are
-supplied.  For writing files,
-BZ2_bzWriteOpen,
-BZ2_bzWrite and
-BZ2_bzWriteFinish are
-available.
-
-As with the low-level library, no global variables are used
-so the library is per se thread-safe.  However, if I/O errors
-occur whilst reading or writing the underlying compressed files,
-you may have to consult errno to
-determine the cause of the error.  In that case, you'd need a C
-library which correctly supports
-errno in a multithreaded
-environment.
-
-To make the library a little simpler and more portable,
-BZ2_bzReadOpen and
-BZ2_bzWriteOpen require you to
-pass them file handles (FILE*s)
-which have previously been opened for reading or writing
-respectively.  That avoids portability problems associated with
-file operations and file attributes, whilst not being much of an
-imposition on the programmer.
-
-
-
-
-
-Utility functions summary
-
-For very simple needs,
-BZ2_bzBuffToBuffCompress and
-BZ2_bzBuffToBuffDecompress are
-provided.  These compress data in memory from one buffer to
-another buffer in a single function call.  You should assess
-whether these functions fulfill your memory-to-memory
-compression/decompression requirements before investing effort in
-understanding the more general but more complex low-level
-interface.
-
-Yoshioka Tsuneo
-(tsuneo@rr.iij4u.or.jp) has
-contributed some functions to give better
-zlib compatibility.  These
-functions are BZ2_bzopen,
-BZ2_bzread,
-BZ2_bzwrite,
-BZ2_bzflush,
-BZ2_bzclose,
-BZ2_bzerror and
-BZ2_bzlibVersion.  You may find
-these functions more convenient for simple file reading and
-writing, than those in the high-level interface.  These functions
-are not (yet) officially part of the library, and are minimally
-documented here.  If they break, you get to keep all the pieces.
-I hope to document them properly when time permits.
-
-Yoshioka also contributed modifications to allow the
-library to be built as a Windows DLL.
-
-
-
-
-
-
-
-Error handling
-
-The library is designed to recover cleanly in all
-situations, including the worst-case situation of decompressing
-random data.  I'm not 100% sure that it can always do this, so
-you might want to add a signal handler to catch segmentation
-violations during decompression if you are feeling especially
-paranoid.  I would be interested in hearing more about the
-robustness of the library to corrupted compressed data.
-
-Version 1.0.3 more robust in this respect than any
-previous version.  Investigations with Valgrind (a tool for detecting
-problems with memory management) indicate
-that, at least for the few files I tested, all single-bit errors
-in the decompressed data are caught properly, with no
-segmentation faults, no uses of uninitialised data, no out of
-range reads or writes, and no infinite looping in the decompressor.
-So it's certainly pretty robust, although
-I wouldn't claim it to be totally bombproof.
-
-The file bzlib.h contains
-all definitions needed to use the library.  In particular, you
-should definitely not include
-bzlib_private.h.
-
-In bzlib.h, the various
-return values are defined.  The following list is not intended as
-an exhaustive description of the circumstances in which a given
-value may be returned -- those descriptions are given later.
-Rather, it is intended to convey the rough meaning of each return
-value.  The first five actions are normal and not intended to
-denote an error situation.
-
-
-
- 
-  BZ_OK
-  The requested action was completed
-   successfully.
- 
-
- 
-  BZ_RUN_OK, BZ_FLUSH_OK,
-    BZ_FINISH_OK
-  In 
-   BZ2_bzCompress, the requested
-   flush/finish/nothing-special action was completed
-   successfully.
- 
-
- 
-  BZ_STREAM_END
-  Compression of data was completed, or the
-   logical stream end was detected during
-   decompression.
- 
-
-
-
-The following return values indicate an error of some
-kind.
-
-
-
- 
-  BZ_CONFIG_ERROR
-  Indicates that the library has been improperly
-   compiled on your platform -- a major configuration error.
-   Specifically, it means that
-   sizeof(char),
-   sizeof(short) and
-   sizeof(int) are not 1, 2 and
-   4 respectively, as they should be.  Note that the library
-   should still work properly on 64-bit platforms which follow
-   the LP64 programming model -- that is, where
-   sizeof(long) and
-   sizeof(void*) are 8.  Under
-   LP64, sizeof(int) is still 4,
-   so libbzip2, which doesn't
-   use the long type, is
-   OK.
- 
-
- 
-  BZ_SEQUENCE_ERROR
-  When using the library, it is important to call
-   the functions in the correct sequence and with data structures
-   (buffers etc) in the correct states.
-   libbzip2 checks as much as it
-   can to ensure this is happening, and returns
-   BZ_SEQUENCE_ERROR if not.
-   Code which complies precisely with the function semantics, as
-   detailed below, should never receive this value; such an event
-   denotes buggy code which you should
-   investigate.
- 
-
- 
-  BZ_PARAM_ERROR
-  Returned when a parameter to a function call is
-   out of range or otherwise manifestly incorrect.  As with
-   BZ_SEQUENCE_ERROR, this
-   denotes a bug in the client code.  The distinction between
-   BZ_PARAM_ERROR and
-   BZ_SEQUENCE_ERROR is a bit
-   hazy, but still worth making.
- 
-
- 
-  BZ_MEM_ERROR
-  Returned when a request to allocate memory
-   failed.  Note that the quantity of memory needed to decompress
-   a stream cannot be determined until the stream's header has
-   been read.  So
-   BZ2_bzDecompress and
-   BZ2_bzRead may return
-   BZ_MEM_ERROR even though some
-   of the compressed data has been read.  The same is not true
-   for compression; once
-   BZ2_bzCompressInit or
-   BZ2_bzWriteOpen have
-   successfully completed,
-   BZ_MEM_ERROR cannot
-   occur.
- 
-
- 
-  BZ_DATA_ERROR
-  Returned when a data integrity error is
-   detected during decompression.  Most importantly, this means
-   when stored and computed CRCs for the data do not match.  This
-   value is also returned upon detection of any other anomaly in
-   the compressed data.
- 
-
- 
-  BZ_DATA_ERROR_MAGIC
-  As a special case of
-   BZ_DATA_ERROR, it is
-   sometimes useful to know when the compressed stream does not
-   start with the correct magic bytes ('B' 'Z'
-   'h').
- 
-
- 
-  BZ_IO_ERROR
-  Returned by
-   BZ2_bzRead and
-   BZ2_bzWrite when there is an
-   error reading or writing in the compressed file, and by
-   BZ2_bzReadOpen and
-   BZ2_bzWriteOpen for attempts
-   to use a file for which the error indicator (viz,
-   ferror(f)) is set.  On
-   receipt of BZ_IO_ERROR, the
-   caller should consult errno
-   and/or perror to acquire
-   operating-system specific information about the
-   problem.
- 
-
- 
-  BZ_UNEXPECTED_EOF
-  Returned by
-   BZ2_bzRead when the
-   compressed file finishes before the logical end of stream is
-   detected.
- 
-
- 
-  BZ_OUTBUFF_FULL
-  Returned by
-   BZ2_bzBuffToBuffCompress and
-   BZ2_bzBuffToBuffDecompress to
-   indicate that the output data will not fit into the output
-   buffer provided.
- 
-
-
-
-
-
-
-
-
-Low-level interface
-
-
-
-BZ2_bzCompressInit
-
-
-typedef struct {
-  char *next_in;
-  unsigned int avail_in;
-  unsigned int total_in_lo32;
-  unsigned int total_in_hi32;
-
-  char *next_out;
-  unsigned int avail_out;
-  unsigned int total_out_lo32;
-  unsigned int total_out_hi32;
-
-  void *state;
-
-  void *(*bzalloc)(void *,int,int);
-  void (*bzfree)(void *,void *);
-  void *opaque;
-} bz_stream;
-
-int BZ2_bzCompressInit ( bz_stream *strm, 
-                         int blockSize100k, 
-                         int verbosity,
-                         int workFactor );
-
-
-Prepares for compression.  The
-bz_stream structure holds all
-data pertaining to the compression activity.  A
-bz_stream structure should be
-allocated and initialised prior to the call.  The fields of
-bz_stream comprise the entirety
-of the user-visible data.  state
-is a pointer to the private data structures required for
-compression.
-
-Custom memory allocators are supported, via fields
-bzalloc,
-bzfree, and
-opaque.  The value
-opaque is passed to as the first
-argument to all calls to bzalloc
-and bzfree, but is otherwise
-ignored by the library.  The call bzalloc (
-opaque, n, m ) is expected to return a pointer
-p to n *
-m bytes of memory, and bzfree (
-opaque, p ) should free that memory.
-
-If you don't want to use a custom memory allocator, set
-bzalloc,
-bzfree and
-opaque to
-NULL, and the library will then
-use the standard malloc /
-free routines.
-
-Before calling
-BZ2_bzCompressInit, fields
-bzalloc,
-bzfree and
-opaque should be filled
-appropriately, as just described.  Upon return, the internal
-state will have been allocated and initialised, and
-total_in_lo32,
-total_in_hi32,
-total_out_lo32 and
-total_out_hi32 will have been
-set to zero.  These four fields are used by the library to inform
-the caller of the total amount of data passed into and out of the
-library, respectively.  You should not try to change them.  As of
-version 1.0, 64-bit counts are maintained, even on 32-bit
-platforms, using the _hi32
-fields to store the upper 32 bits of the count.  So, for example,
-the total amount of data in is (total_in_hi32
-<< 32) + total_in_lo32.
-
-Parameter blockSize100k
-specifies the block size to be used for compression.  It should
-be a value between 1 and 9 inclusive, and the actual block size
-used is 100000 x this figure.  9 gives the best compression but
-takes most memory.
-
-Parameter verbosity should
-be set to a number between 0 and 4 inclusive.  0 is silent, and
-greater numbers give increasingly verbose monitoring/debugging
-output.  If the library has been compiled with
--DBZ_NO_STDIO, no such output
-will appear for any verbosity setting.
-
-Parameter workFactor
-controls how the compression phase behaves when presented with
-worst case, highly repetitive, input data.  If compression runs
-into difficulties caused by repetitive data, the library switches
-from the standard sorting algorithm to a fallback algorithm.  The
-fallback is slower than the standard algorithm by perhaps a
-factor of three, but always behaves reasonably, no matter how bad
-the input.
-
-Lower values of workFactor
-reduce the amount of effort the standard algorithm will expend
-before resorting to the fallback.  You should set this parameter
-carefully; too low, and many inputs will be handled by the
-fallback algorithm and so compress rather slowly, too high, and
-your average-to-worst case compression times can become very
-large.  The default value of 30 gives reasonable behaviour over a
-wide range of circumstances.
-
-Allowable values range from 0 to 250 inclusive.  0 is a
-special case, equivalent to using the default value of 30.
-
-Note that the compressed output generated is the same
-regardless of whether or not the fallback algorithm is
-used.
-
-Be aware also that this parameter may disappear entirely in
-future versions of the library.  In principle it should be
-possible to devise a good way to automatically choose which
-algorithm to use.  Such a mechanism would render the parameter
-obsolete.
-
-Possible return values:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if strm is NULL 
-  or blockSize < 1 or blockSize > 9
-  or verbosity < 0 or verbosity > 4
-  or workFactor < 0 or workFactor > 250
-BZ_MEM_ERROR 
-  if not enough memory is available
-BZ_OK 
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzCompress
-  if BZ_OK is returned
-  no specific action needed in case of error
-
-
-
-
-
-
-BZ2_bzCompress
-
-
-int BZ2_bzCompress ( bz_stream *strm, int action );
-
-
-Provides more input and/or output buffer space for the
-library.  The caller maintains input and output buffers, and
-calls BZ2_bzCompress to transfer
-data between them.
-
-Before each call to
-BZ2_bzCompress,
-next_in should point at the data
-to be compressed, and avail_in
-should indicate how many bytes the library may read.
-BZ2_bzCompress updates
-next_in,
-avail_in and
-total_in to reflect the number
-of bytes it has read.
-
-Similarly, next_out should
-point to a buffer in which the compressed data is to be placed,
-with avail_out indicating how
-much output space is available.
-BZ2_bzCompress updates
-next_out,
-avail_out and
-total_out to reflect the number
-of bytes output.
-
-You may provide and remove as little or as much data as you
-like on each call of
-BZ2_bzCompress.  In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient.  You should always
-ensure that at least one byte of output space is available at
-each call.
-
-A second purpose of
-BZ2_bzCompress is to request a
-change of mode of the compressed stream.
-
-Conceptually, a compressed stream can be in one of four
-states: IDLE, RUNNING, FLUSHING and FINISHING.  Before
-initialisation
-(BZ2_bzCompressInit) and after
-termination (BZ2_bzCompressEnd),
-a stream is regarded as IDLE.
-
-Upon initialisation
-(BZ2_bzCompressInit), the stream
-is placed in the RUNNING state.  Subsequent calls to
-BZ2_bzCompress should pass
-BZ_RUN as the requested action;
-other actions are illegal and will result in
-BZ_SEQUENCE_ERROR.
-
-At some point, the calling program will have provided all
-the input data it wants to.  It will then want to finish up -- in
-effect, asking the library to process any data it might have
-buffered internally.  In this state,
-BZ2_bzCompress will no longer
-attempt to read data from
-next_in, but it will want to
-write data to next_out.  Because
-the output buffer supplied by the user can be arbitrarily small,
-the finishing-up operation cannot necessarily be done with a
-single call of
-BZ2_bzCompress.
-
-Instead, the calling program passes
-BZ_FINISH as an action to
-BZ2_bzCompress.  This changes
-the stream's state to FINISHING.  Any remaining input (ie,
-next_in[0 .. avail_in-1]) is
-compressed and transferred to the output buffer.  To do this,
-BZ2_bzCompress must be called
-repeatedly until all the output has been consumed.  At that
-point, BZ2_bzCompress returns
-BZ_STREAM_END, and the stream's
-state is set back to IDLE.
-BZ2_bzCompressEnd should then be
-called.
-
-Just to make sure the calling program does not cheat, the
-library makes a note of avail_in
-at the time of the first call to
-BZ2_bzCompress which has
-BZ_FINISH as an action (ie, at
-the time the program has announced its intention to not supply
-any more input).  By comparing this value with that of
-avail_in over subsequent calls
-to BZ2_bzCompress, the library
-can detect any attempts to slip in more data to compress.  Any
-calls for which this is detected will return
-BZ_SEQUENCE_ERROR.  This
-indicates a programming mistake which should be corrected.
-
-Instead of asking to finish, the calling program may ask
-BZ2_bzCompress to take all the
-remaining input, compress it and terminate the current
-(Burrows-Wheeler) compression block.  This could be useful for
-error control purposes.  The mechanism is analogous to that for
-finishing: call BZ2_bzCompress
-with an action of BZ_FLUSH,
-remove output data, and persist with the
-BZ_FLUSH action until the value
-BZ_RUN is returned.  As with
-finishing, BZ2_bzCompress
-detects any attempt to provide more input data once the flush has
-begun.
-
-Once the flush is complete, the stream returns to the
-normal RUNNING state.
-
-This all sounds pretty complex, but isn't really.  Here's a
-table which shows which actions are allowable in each state, what
-action will be taken, what the next state is, and what the
-non-error return values are.  Note that you can't explicitly ask
-what state the stream is in, but nor do you need to -- it can be
-inferred from the values returned by
-BZ2_bzCompress.
-
-
-IDLE/any
-  Illegal.  IDLE state only exists after BZ2_bzCompressEnd or
-  before BZ2_bzCompressInit.
-  Return value = BZ_SEQUENCE_ERROR
-
-RUNNING/BZ_RUN
-  Compress from next_in to next_out as much as possible.
-  Next state = RUNNING
-  Return value = BZ_RUN_OK
-
-RUNNING/BZ_FLUSH
-  Remember current value of next_in. Compress from next_in
-  to next_out as much as possible, but do not accept any more input.
-  Next state = FLUSHING
-  Return value = BZ_FLUSH_OK
-
-RUNNING/BZ_FINISH
-  Remember current value of next_in. Compress from next_in
-  to next_out as much as possible, but do not accept any more input.
-  Next state = FINISHING
-  Return value = BZ_FINISH_OK
-
-FLUSHING/BZ_FLUSH
-  Compress from next_in to next_out as much as possible, 
-  but do not accept any more input.
-  If all the existing input has been used up and all compressed
-  output has been removed
-    Next state = RUNNING; Return value = BZ_RUN_OK
-  else
-    Next state = FLUSHING; Return value = BZ_FLUSH_OK
-
-FLUSHING/other     
-  Illegal.
-  Return value = BZ_SEQUENCE_ERROR
-
-FINISHING/BZ_FINISH
-  Compress from next_in to next_out as much as possible,
-  but to not accept any more input.  
-  If all the existing input has been used up and all compressed
-  output has been removed
-    Next state = IDLE; Return value = BZ_STREAM_END
-  else
-    Next state = FINISHING; Return value = BZ_FINISH_OK
-
-FINISHING/other
-  Illegal.
-  Return value = BZ_SEQUENCE_ERROR
-
-
-
-That still looks complicated?  Well, fair enough.  The
-usual sequence of calls for compressing a load of data is:
-
-
-
- Get started with
-  BZ2_bzCompressInit.
-
- Shovel data in and shlurp out its compressed form
-  using zero or more calls of
-  BZ2_bzCompress with action =
-  BZ_RUN.
-
- Finish up. Repeatedly call
-  BZ2_bzCompress with action =
-  BZ_FINISH, copying out the
-  compressed output, until
-  BZ_STREAM_END is
-  returned. Close up and go home.  Call
-  BZ2_bzCompressEnd.
-
-
-
-If the data you want to compress fits into your input
-buffer all at once, you can skip the calls of
-BZ2_bzCompress ( ..., BZ_RUN )
-and just do the BZ2_bzCompress ( ..., BZ_FINISH
-) calls.
-
-All required memory is allocated by
-BZ2_bzCompressInit.  The
-compression library can accept any data at all (obviously).  So
-you shouldn't get any error return values from the
-BZ2_bzCompress calls.  If you
-do, they will be
-BZ_SEQUENCE_ERROR, and indicate
-a bug in your programming.
-
-Trivial other possible return values:
-
-
-BZ_PARAM_ERROR
-  if strm is NULL, or strm->s is NULL
-
-
-
-
-
-
-BZ2_bzCompressEnd
-
-
-int BZ2_bzCompressEnd ( bz_stream *strm );
-
-
-Releases all memory associated with a compression
-stream.
-
-Possible return values:
-
-
-BZ_PARAM_ERROR  if strm is NULL or strm->s is NULL
-BZ_OK           otherwise
-
-
-
-
-
-
-BZ2_bzDecompressInit
-
-
-int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
-
-
-Prepares for decompression.  As with
-BZ2_bzCompressInit, a
-bz_stream record should be
-allocated and initialised before the call.  Fields
-bzalloc,
-bzfree and
-opaque should be set if a custom
-memory allocator is required, or made
-NULL for the normal
-malloc /
-free routines.  Upon return, the
-internal state will have been initialised, and
-total_in and
-total_out will be zero.
-
-For the meaning of parameter
-verbosity, see
-BZ2_bzCompressInit.
-
-If small is nonzero, the
-library will use an alternative decompression algorithm which
-uses less memory but at the cost of decompressing more slowly
-(roughly speaking, half the speed, but the maximum memory
-requirement drops to around 2300k).  See 
-for more information on memory management.
-
-Note that the amount of memory needed to decompress a
-stream cannot be determined until the stream's header has been
-read, so even if
-BZ2_bzDecompressInit succeeds, a
-subsequent BZ2_bzDecompress
-could fail with
-BZ_MEM_ERROR.
-
-Possible return values:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if ( small != 0 && small != 1 )
-  or (verbosity <; 0 || verbosity > 4)
-BZ_MEM_ERROR
-  if insufficient memory is available
-
-
-Allowable next actions:
-
-
-BZ2_bzDecompress
-  if BZ_OK was returned
-  no specific action required in case of error
-
-
-
-
-
-
-BZ2_bzDecompress
-
-
-int BZ2_bzDecompress ( bz_stream *strm );
-
-
-Provides more input and/out output buffer space for the
-library.  The caller maintains input and output buffers, and uses
-BZ2_bzDecompress to transfer
-data between them.
-
-Before each call to
-BZ2_bzDecompress,
-next_in should point at the
-compressed data, and avail_in
-should indicate how many bytes the library may read.
-BZ2_bzDecompress updates
-next_in,
-avail_in and
-total_in to reflect the number
-of bytes it has read.
-
-Similarly, next_out should
-point to a buffer in which the uncompressed output is to be
-placed, with avail_out
-indicating how much output space is available.
-BZ2_bzCompress updates
-next_out,
-avail_out and
-total_out to reflect the number
-of bytes output.
-
-You may provide and remove as little or as much data as you
-like on each call of
-BZ2_bzDecompress.  In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient.  You should always
-ensure that at least one byte of output space is available at
-each call.
-
-Use of BZ2_bzDecompress is
-simpler than
-BZ2_bzCompress.
-
-You should provide input and remove output as described
-above, and repeatedly call
-BZ2_bzDecompress until
-BZ_STREAM_END is returned.
-Appearance of BZ_STREAM_END
-denotes that BZ2_bzDecompress
-has detected the logical end of the compressed stream.
-BZ2_bzDecompress will not
-produce BZ_STREAM_END until all
-output data has been placed into the output buffer, so once
-BZ_STREAM_END appears, you are
-guaranteed to have available all the decompressed output, and
-BZ2_bzDecompressEnd can safely
-be called.
-
-If case of an error return value, you should call
-BZ2_bzDecompressEnd to clean up
-and release memory.
-
-Possible return values:
-
-
-BZ_PARAM_ERROR
-  if strm is NULL or strm->s is NULL
-  or strm->avail_out < 1
-BZ_DATA_ERROR
-  if a data integrity error is detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
-  if the compressed stream doesn't begin with the right magic bytes
-BZ_MEM_ERROR
-  if there wasn't enough memory available
-BZ_STREAM_END
-  if the logical end of the data stream was detected and all
-  output in has been consumed, eg s-->avail_out > 0
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzDecompress
-  if BZ_OK was returned
-BZ2_bzDecompressEnd
-  otherwise
-
-
-
-
-
-
-BZ2_bzDecompressEnd
-
-
-int BZ2_bzDecompressEnd ( bz_stream *strm );
-
-
-Releases all memory associated with a decompression
-stream.
-
-Possible return values:
-
-
-BZ_PARAM_ERROR
-  if strm is NULL or strm->s is NULL
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-  None.
-
-
-
-
-
-
-
-
-High-level interface
-
-This interface provides functions for reading and writing
-bzip2 format files.  First, some
-general points.
-
-
-
- All of the functions take an
-  int* first argument,
-  bzerror.  After each call,
-  bzerror should be consulted
-  first to determine the outcome of the call.  If
-  bzerror is
-  BZ_OK, the call completed
-  successfully, and only then should the return value of the
-  function (if any) be consulted.  If
-  bzerror is
-  BZ_IO_ERROR, there was an
-  error reading/writing the underlying compressed file, and you
-  should then consult errno /
-  perror to determine the cause
-  of the difficulty.  bzerror
-  may also be set to various other values; precise details are
-  given on a per-function basis below.
-
- If bzerror indicates
-  an error (ie, anything except
-  BZ_OK and
-  BZ_STREAM_END), you should
-  immediately call
-  BZ2_bzReadClose (or
-  BZ2_bzWriteClose, depending on
-  whether you are attempting to read or to write) to free up all
-  resources associated with the stream.  Once an error has been
-  indicated, behaviour of all calls except
-  BZ2_bzReadClose
-  (BZ2_bzWriteClose) is
-  undefined.  The implication is that (1)
-  bzerror should be checked
-  after each call, and (2) if
-  bzerror indicates an error,
-  BZ2_bzReadClose
-  (BZ2_bzWriteClose) should then
-  be called to clean up.
-
- The FILE* arguments
-  passed to BZ2_bzReadOpen /
-  BZ2_bzWriteOpen should be set
-  to binary mode.  Most Unix systems will do this by default, but
-  other platforms, including Windows and Mac, will not.  If you
-  omit this, you may encounter problems when moving code to new
-  platforms.
-
- Memory allocation requests are handled by
-  malloc /
-  free.  At present there is no
-  facility for user-defined memory allocators in the file I/O
-  functions (could easily be added, though).
-
-
-
-
-
-
-BZ2_bzReadOpen
-
-
-typedef void BZFILE;
-
-BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f, 
-                        int verbosity, int small,
-                        void *unused, int nUnused );
-
-
-Prepare to read compressed data from file handle
-f.
-f should refer to a file which
-has been opened for reading, and for which the error indicator
-(ferror(f))is not set.  If
-small is 1, the library will try
-to decompress using less memory, at the expense of speed.
-
-For reasons explained below,
-BZ2_bzRead will decompress the
-nUnused bytes starting at
-unused, before starting to read
-from the file f.  At most
-BZ_MAX_UNUSED bytes may be
-supplied like this.  If this facility is not required, you should
-pass NULL and
-0 for
-unused and
-nUnused respectively.
-
-For the meaning of parameters
-small and
-verbosity, see
-BZ2_bzDecompressInit.
-
-The amount of memory needed to decompress a file cannot be
-determined until the file's header has been read.  So it is
-possible that BZ2_bzReadOpen
-returns BZ_OK but a subsequent
-call of BZ2_bzRead will return
-BZ_MEM_ERROR.
-
-Possible assignments to
-bzerror:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if f is NULL
-  or small is neither 0 nor 1
-  or ( unused == NULL && nUnused != 0 )
-  or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) )
-BZ_IO_ERROR
-  if ferror(f) is nonzero
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OK
-  otherwise.
-
-
-Possible return values:
-
-
-Pointer to an abstract BZFILE
-  if bzerror is BZ_OK
-NULL
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzRead
-  if bzerror is BZ_OK
-BZ2_bzClose
-  otherwise
-
-
-
-
-
-
-BZ2_bzRead
-
-
-int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
-
-
-Reads up to len
-(uncompressed) bytes from the compressed file
-b into the buffer
-buf.  If the read was
-successful, bzerror is set to
-BZ_OK and the number of bytes
-read is returned.  If the logical end-of-stream was detected,
-bzerror will be set to
-BZ_STREAM_END, and the number of
-bytes read is returned.  All other
-bzerror values denote an
-error.
-
-BZ2_bzRead will supply
-len bytes, unless the logical
-stream end is detected or an error occurs.  Because of this, it
-is possible to detect the stream end by observing when the number
-of bytes returned is less than the number requested.
-Nevertheless, this is regarded as inadvisable; you should instead
-check bzerror after every call
-and watch out for
-BZ_STREAM_END.
-
-Internally, BZ2_bzRead
-copies data from the compressed file in chunks of size
-BZ_MAX_UNUSED bytes before
-decompressing it.  If the file contains more bytes than strictly
-needed to reach the logical end-of-stream,
-BZ2_bzRead will almost certainly
-read some of the trailing data before signalling
-BZ_SEQUENCE_END.  To collect the
-read but unused data once
-BZ_SEQUENCE_END has appeared,
-call BZ2_bzReadGetUnused
-immediately before
-BZ2_bzReadClose.
-
-Possible assignments to
-bzerror:
-
-
-BZ_PARAM_ERROR
-  if b is NULL or buf is NULL or len < 0
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzWriteOpen
-BZ_IO_ERROR
-  if there is an error reading from the compressed file
-BZ_UNEXPECTED_EOF
-  if the compressed file ended before 
-  the logical end-of-stream was detected
-BZ_DATA_ERROR
-  if a data integrity error was detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
-  if the stream does not begin with the requisite header bytes 
-  (ie, is not a bzip2 data file).  This is really 
-  a special case of BZ_DATA_ERROR.
-BZ_MEM_ERROR
-  if insufficient memory was available
-BZ_STREAM_END
-  if the logical end of stream was detected.
-BZ_OK
-  otherwise.
-
-
-Possible return values:
-
-
-number of bytes read
-  if bzerror is BZ_OK or BZ_STREAM_END
-undefined
-  otherwise
-
-
-Allowable next actions:
-
-
-collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
-  if bzerror is BZ_OK
-collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
-  if bzerror is BZ_SEQUENCE_END
-BZ2_bzReadClose
-  otherwise
-
-
-
-
-
-
-BZ2_bzReadGetUnused
-
-
-void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b, 
-                          void** unused, int* nUnused );
-
-
-Returns data which was read from the compressed file but
-was not needed to get to the logical end-of-stream.
-*unused is set to the address of
-the data, and *nUnused to the
-number of bytes.  *nUnused will
-be set to a value between 0 and
-BZ_MAX_UNUSED inclusive.
-
-This function may only be called once
-BZ2_bzRead has signalled
-BZ_STREAM_END but before
-BZ2_bzReadClose.
-
-Possible assignments to
-bzerror:
-
-
-BZ_PARAM_ERROR
-  if b is NULL
-  or unused is NULL or nUnused is NULL
-BZ_SEQUENCE_ERROR
-  if BZ_STREAM_END has not been signalled
-  or if b was opened with BZ2_bzWriteOpen
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzReadClose
-
-
-
-
-
-
-BZ2_bzReadClose
-
-
-void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
-
-
-Releases all memory pertaining to the compressed file
-b.
-BZ2_bzReadClose does not call
-fclose on the underlying file
-handle, so you should do that yourself if appropriate.
-BZ2_bzReadClose should be called
-to clean up after all error situations.
-
-Possible assignments to
-bzerror:
-
-
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzOpenWrite
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-none
-
-
-
-
-
-
-BZ2_bzWriteOpen
-
-
-BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f, 
-                         int blockSize100k, int verbosity,
-                         int workFactor );
-
-
-Prepare to write compressed data to file handle
-f.
-f should refer to a file which
-has been opened for writing, and for which the error indicator
-(ferror(f))is not set.
-
-For the meaning of parameters
-blockSize100k,
-verbosity and
-workFactor, see
-BZ2_bzCompressInit.
-
-All required memory is allocated at this stage, so if the
-call completes successfully,
-BZ_MEM_ERROR cannot be signalled
-by a subsequent call to
-BZ2_bzWrite.
-
-Possible assignments to
-bzerror:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if f is NULL
-  or blockSize100k < 1 or blockSize100k > 9
-BZ_IO_ERROR
-  if ferror(f) is nonzero
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OK
-  otherwise
-
-
-Possible return values:
-
-
-Pointer to an abstract BZFILE
-  if bzerror is BZ_OK
-NULL
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzWrite
-  if bzerror is BZ_OK
-  (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
-BZ2_bzWriteClose
-  otherwise
-
-
-
-
-
-
-BZ2_bzWrite
-
-
-void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
-
-
-Absorbs len bytes from the
-buffer buf, eventually to be
-compressed and written to the file.
-
-Possible assignments to
-bzerror:
-
-
-BZ_PARAM_ERROR
-  if b is NULL or buf is NULL or len < 0
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
-  if there is an error writing the compressed file.
-BZ_OK
-  otherwise
-
-
-
-
-
-
-BZ2_bzWriteClose
-
-
-void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
-                       int abandon,
-                       unsigned int* nbytes_in,
-                       unsigned int* nbytes_out );
-
-void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
-                         int abandon,
-                         unsigned int* nbytes_in_lo32,
-                         unsigned int* nbytes_in_hi32,
-                         unsigned int* nbytes_out_lo32,
-                         unsigned int* nbytes_out_hi32 );
-
-
-Compresses and flushes to the compressed file all data so
-far supplied by BZ2_bzWrite.
-The logical end-of-stream markers are also written, so subsequent
-calls to BZ2_bzWrite are
-illegal.  All memory associated with the compressed file
-b is released.
-fflush is called on the
-compressed file, but it is not
-fclose'd.
-
-If BZ2_bzWriteClose is
-called to clean up after an error, the only action is to release
-the memory.  The library records the error codes issued by
-previous calls, so this situation will be detected automatically.
-There is no attempt to complete the compression operation, nor to
-fflush the compressed file.  You
-can force this behaviour to happen even in the case of no error,
-by passing a nonzero value to
-abandon.
-
-If nbytes_in is non-null,
-*nbytes_in will be set to be the
-total volume of uncompressed data handled.  Similarly,
-nbytes_out will be set to the
-total volume of compressed data written.  For compatibility with
-older versions of the library,
-BZ2_bzWriteClose only yields the
-lower 32 bits of these counts.  Use
-BZ2_bzWriteClose64 if you want
-the full 64 bit counts.  These two functions are otherwise
-absolutely identical.
-
-Possible assignments to
-bzerror:
-
-
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
-  if there is an error writing the compressed file
-BZ_OK
-  otherwise
-
-
-
-
-
-
-Handling embedded compressed data streams
-
-The high-level library facilitates use of
-bzip2 data streams which form
-some part of a surrounding, larger data stream.
-
-
-
- For writing, the library takes an open file handle,
-  writes compressed data to it,
-  fflushes it but does not
-  fclose it.  The calling
-  application can write its own data before and after the
-  compressed data stream, using that same file handle.
-
- Reading is more complex, and the facilities are not as
-  general as they could be since generality is hard to reconcile
-  with efficiency.  BZ2_bzRead
-  reads from the compressed file in blocks of size
-  BZ_MAX_UNUSED bytes, and in
-  doing so probably will overshoot the logical end of compressed
-  stream.  To recover this data once decompression has ended,
-  call BZ2_bzReadGetUnused after
-  the last call of BZ2_bzRead
-  (the one returning
-  BZ_STREAM_END) but before
-  calling
-  BZ2_bzReadClose.
-
-
-
-This mechanism makes it easy to decompress multiple
-bzip2 streams placed end-to-end.
-As the end of one stream, when
-BZ2_bzRead returns
-BZ_STREAM_END, call
-BZ2_bzReadGetUnused to collect
-the unused data (copy it into your own buffer somewhere).  That
-data forms the start of the next compressed stream.  To start
-uncompressing that next stream, call
-BZ2_bzReadOpen again, feeding in
-the unused data via the unused /
-nUnused parameters.  Keep doing
-this until BZ_STREAM_END return
-coincides with the physical end of file
-(feof(f)).  In this situation
-BZ2_bzReadGetUnused will of
-course return no data.
-
-This should give some feel for how the high-level interface
-can be used.  If you require extra flexibility, you'll have to
-bite the bullet and get to grips with the low-level
-interface.
-
-
-
-
-
-Standard file-reading/writing code
-
-Here's how you'd write data to a compressed file:
-
-
-FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "w" );
-if ( !f ) {
- /* handle error */
-}
-b = BZ2_bzWriteOpen( &bzerror, f, 9 );
-if (bzerror != BZ_OK) {
- BZ2_bzWriteClose ( b );
- /* handle error */
-}
-
-while ( /* condition */ ) {
- /* get data to write into buf, and set nBuf appropriately */
- nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
- if (bzerror == BZ_IO_ERROR) { 
-   BZ2_bzWriteClose ( &bzerror, b );
-   /* handle error */
- }
-}
-
-BZ2_bzWriteClose( &bzerror, b );
-if (bzerror == BZ_IO_ERROR) {
- /* handle error */
-}
-
-
-And to read from a compressed file:
-
-
-FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "r" );
-if ( !f ) {
-  /* handle error */
-}
-b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
-if ( bzerror != BZ_OK ) {
-  BZ2_bzReadClose ( &bzerror, b );
-  /* handle error */
-}
-
-bzerror = BZ_OK;
-while ( bzerror == BZ_OK && /* arbitrary other conditions */) {
-  nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
-  if ( bzerror == BZ_OK ) {
-    /* do something with buf[0 .. nBuf-1] */
-  }
-}
-if ( bzerror != BZ_STREAM_END ) {
-   BZ2_bzReadClose ( &bzerror, b );
-   /* handle error */
-} else {
-   BZ2_bzReadClose ( &bzerror, b );
-}
-
-
-
-
-
-
-
-
-Utility functions
-
-
-
-BZ2_bzBuffToBuffCompress
-
-
-int BZ2_bzBuffToBuffCompress( char*         dest,
-                              unsigned int* destLen,
-                              char*         source,
-                              unsigned int  sourceLen,
-                              int           blockSize100k,
-                              int           verbosity,
-                              int           workFactor );
-
-
-Attempts to compress the data in source[0
-.. sourceLen-1] into the destination buffer,
-dest[0 .. *destLen-1].  If the
-destination buffer is big enough,
-*destLen is set to the size of
-the compressed data, and BZ_OK
-is returned.  If the compressed data won't fit,
-*destLen is unchanged, and
-BZ_OUTBUFF_FULL is
-returned.
-
-Compression in this manner is a one-shot event, done with a
-single call to this function.  The resulting compressed data is a
-complete bzip2 format data
-stream.  There is no mechanism for making additional calls to
-provide extra input data.  If you want that kind of mechanism,
-use the low-level interface.
-
-For the meaning of parameters
-blockSize100k,
-verbosity and
-workFactor, see
-BZ2_bzCompressInit.
-
-To guarantee that the compressed data will fit in its
-buffer, allocate an output buffer of size 1% larger than the
-uncompressed data, plus six hundred extra bytes.
-
-BZ2_bzBuffToBuffDecompress
-will not write data at or beyond
-dest[*destLen], even in case of
-buffer overflow.
-
-Possible return values:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if dest is NULL or destLen is NULL
-  or blockSize100k < 1 or blockSize100k > 9
-  or verbosity < 0 or verbosity > 4
-  or workFactor < 0 or workFactor > 250
-BZ_MEM_ERROR
-  if insufficient memory is available 
-BZ_OUTBUFF_FULL
-  if the size of the compressed data exceeds *destLen
-BZ_OK
-  otherwise
-
-
-
-
-
-
-BZ2_bzBuffToBuffDecompress
-
-
-int BZ2_bzBuffToBuffDecompress( char*         dest,
-                                unsigned int* destLen,
-                                char*         source,
-                                unsigned int  sourceLen,
-                                int           small,
-                                int           verbosity );
-
-
-Attempts to decompress the data in source[0
-.. sourceLen-1] into the destination buffer,
-dest[0 .. *destLen-1].  If the
-destination buffer is big enough,
-*destLen is set to the size of
-the uncompressed data, and BZ_OK
-is returned.  If the compressed data won't fit,
-*destLen is unchanged, and
-BZ_OUTBUFF_FULL is
-returned.
-
-source is assumed to hold
-a complete bzip2 format data
-stream.
-BZ2_bzBuffToBuffDecompress tries
-to decompress the entirety of the stream into the output
-buffer.
-
-For the meaning of parameters
-small and
-verbosity, see
-BZ2_bzDecompressInit.
-
-Because the compression ratio of the compressed data cannot
-be known in advance, there is no easy way to guarantee that the
-output buffer will be big enough.  You may of course make
-arrangements in your code to record the size of the uncompressed
-data, but such a mechanism is beyond the scope of this
-library.
-
-BZ2_bzBuffToBuffDecompress
-will not write data at or beyond
-dest[*destLen], even in case of
-buffer overflow.
-
-Possible return values:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if dest is NULL or destLen is NULL
-  or small != 0 && small != 1
-  or verbosity < 0 or verbosity > 4
-BZ_MEM_ERROR
-  if insufficient memory is available 
-BZ_OUTBUFF_FULL
-  if the size of the compressed data exceeds *destLen
-BZ_DATA_ERROR
-  if a data integrity error was detected in the compressed data
-BZ_DATA_ERROR_MAGIC
-  if the compressed data doesn't begin with the right magic bytes
-BZ_UNEXPECTED_EOF
-  if the compressed data ends unexpectedly
-BZ_OK
-  otherwise
-
-
-
-
-
-
-
-
-zlib compatibility functions
-
-Yoshioka Tsuneo has contributed some functions to give
-better zlib compatibility.
-These functions are BZ2_bzopen,
-BZ2_bzread,
-BZ2_bzwrite,
-BZ2_bzflush,
-BZ2_bzclose,
-BZ2_bzerror and
-BZ2_bzlibVersion.  These
-functions are not (yet) officially part of the library.  If they
-break, you get to keep all the pieces.  Nevertheless, I think
-they work ok.
-
-
-typedef void BZFILE;
-
-const char * BZ2_bzlibVersion ( void );
-
-
-Returns a string indicating the library version.
-
-
-BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
-BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );
-
-
-Opens a .bz2 file for
-reading or writing, using either its name or a pre-existing file
-descriptor.  Analogous to fopen
-and fdopen.
-
-
-int BZ2_bzread  ( BZFILE* b, void* buf, int len );
-int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
-
-
-Reads/writes data from/to a previously opened
-BZFILE.  Analogous to
-fread and
-fwrite.
-
-
-int  BZ2_bzflush ( BZFILE* b );
-void BZ2_bzclose ( BZFILE* b );
-
-
-Flushes/closes a BZFILE.
-BZ2_bzflush doesn't actually do
-anything.  Analogous to fflush
-and fclose.
-
-
-const char * BZ2_bzerror ( BZFILE *b, int *errnum )
-
-
-Returns a string describing the more recent error status of
-b, and also sets
-*errnum to its numerical
-value.
-
-
-
-
-
-Using the library in a stdio-free environment
-
-
-
-Getting rid of stdio
-
-In a deeply embedded application, you might want to use
-just the memory-to-memory functions.  You can do this
-conveniently by compiling the library with preprocessor symbol
-BZ_NO_STDIO defined.  Doing this
-gives you a library containing only the following eight
-functions:
-
-BZ2_bzCompressInit,
-BZ2_bzCompress,
-BZ2_bzCompressEnd
-BZ2_bzDecompressInit,
-BZ2_bzDecompress,
-BZ2_bzDecompressEnd
-BZ2_bzBuffToBuffCompress,
-BZ2_bzBuffToBuffDecompress
-
-When compiled like this, all functions will ignore
-verbosity settings.
-
-
-
-
-
-Critical error handling
-
-libbzip2 contains a number
-of internal assertion checks which should, needless to say, never
-be activated.  Nevertheless, if an assertion should fail,
-behaviour depends on whether or not the library was compiled with
-BZ_NO_STDIO set.
-
-For a normal compile, an assertion failure yields the
-message:
-
-
-bzip2/libbzip2: internal error number N. -This is a bug in bzip2/libbzip2, &bz-version; of &bz-date;. -Please report it to: &bz-email;. If this happened -when you were using some program which uses libbzip2 as a -component, you should also report this bug to the author(s) -of that program. Please make an effort to report this bug; -timely and accurate bug reports eventually lead to higher -quality software. Thanks. -
- -where N is some error code -number. If N == 1007, it also -prints some extra text advising the reader that unreliable memory -is often associated with internal error 1007. (This is a -frequently-observed-phenomenon with versions 1.0.0/1.0.1). - -exit(3) is then -called. - -For a stdio-free library, -assertion failures result in a call to a function declared -as: - - -extern void bz_internal_error ( int errcode ); - - -The relevant code is passed as a parameter. You should -supply such a function. - -In either case, once an assertion failure has occurred, any -bz_stream records involved can -be regarded as invalid. You should not attempt to resume normal -operation with them. - -You may, of course, change critical error handling to suit -your needs. As I said above, critical errors indicate bugs in -the library and should not occur. All "normal" error situations -are indicated via error return codes from functions, and can be -recovered from. - -
- -
- - - -Making a Windows DLL - -Everything related to Windows has been contributed by -Yoshioka Tsuneo -(tsuneo@rr.iij4u.or.jp), so -you should send your queries to him (but please Cc: -&bz-email;). - -My vague understanding of what to do is: using Visual C++ -5.0, open the project file -libbz2.dsp, and build. That's -all. - -If you can't open the project file for some reason, make a -new one, naming these files: -blocksort.c, -bzlib.c, -compress.c, -crctable.c, -decompress.c, -huffman.c, -randtable.c and -libbz2.def. You will also need -to name the header files bzlib.h -and bzlib_private.h. - -If you don't use VC++, you may need to define the -proprocessor symbol -_WIN32. - -Finally, dlltest.c is a -sample program using the DLL. It has a project file, -dlltest.dsp. - -If you just want a makefile for Visual C, have a look at -makefile.msc. - -Be aware that if you compile -bzip2 itself on Win32, you must -set BZ_UNIX to 0 and -BZ_LCCWIN32 to 1, in the file -bzip2.c, before compiling. -Otherwise the resulting binary won't work correctly. - -I haven't tried any of this stuff myself, but it all looks -plausible. - - - -
- - - - -Miscellanea - -These are just some random thoughts of mine. Your mileage -may vary. - - - -Limitations of the compressed file format - -bzip2-1.0.X, -0.9.5 and -0.9.0 use exactly the same file -format as the original version, -bzip2-0.1. This decision was -made in the interests of stability. Creating yet another -incompatible compressed file format would create further -confusion and disruption for users. - -Nevertheless, this is not a painless decision. Development -work since the release of -bzip2-0.1 in August 1997 has -shown complexities in the file format which slow down -decompression and, in retrospect, are unnecessary. These -are: - - - - The run-length encoder, which is the first of the - compression transformations, is entirely irrelevant. The - original purpose was to protect the sorting algorithm from the - very worst case input: a string of repeated symbols. But - algorithm steps Q6a and Q6b in the original Burrows-Wheeler - technical report (SRC-124) show how repeats can be handled - without difficulty in block sorting. - - The randomisation mechanism doesn't really need to be - there. Udi Manber and Gene Myers published a suffix array - construction algorithm a few years back, which can be employed - to sort any block, no matter how repetitive, in O(N log N) - time. Subsequent work by Kunihiko Sadakane has produced a - derivative O(N (log N)^2) algorithm which usually outperforms - the Manber-Myers algorithm. - - I could have changed to Sadakane's algorithm, but I find - it to be slower than bzip2's - existing algorithm for most inputs, and the randomisation - mechanism protects adequately against bad cases. I didn't - think it was a good tradeoff to make. Partly this is due to - the fact that I was not flooded with email complaints about - bzip2-0.1's performance on - repetitive data, so perhaps it isn't a problem for real - inputs. - - Probably the best long-term solution, and the one I have - incorporated into 0.9.5 and above, is to use the existing - sorting algorithm initially, and fall back to a O(N (log N)^2) - algorithm if the standard algorithm gets into - difficulties. - - The compressed file format was never designed to be - handled by a library, and I have had to jump though some hoops - to produce an efficient implementation of decompression. It's - a bit hairy. Try passing - decompress.c through the C - preprocessor and you'll see what I mean. Much of this - complexity could have been avoided if the compressed size of - each block of data was recorded in the data stream. - - An Adler-32 checksum, rather than a CRC32 checksum, - would be faster to compute. - - - -It would be fair to say that the -bzip2 format was frozen before I -properly and fully understood the performance consequences of -doing so. - -Improvements which I was able to incorporate into 0.9.0, -despite using the same file format, are: - - - - Single array implementation of the inverse BWT. This - significantly speeds up decompression, presumably because it - reduces the number of cache misses. - - Faster inverse MTF transform for large MTF values. - The new implementation is based on the notion of sliding blocks - of values. - - bzip2-0.9.0 now reads - and writes files with fread - and fwrite; version 0.1 used - putc and - getc. Duh! Well, you live - and learn. - - - -Further ahead, it would be nice to be able to do random -access into files. This will require some careful design of -compressed file formats. - - - - - -Portability issues - -After some consideration, I have decided not to use GNU -autoconf to configure 0.9.5 or -1.0. - -autoconf, admirable and -wonderful though it is, mainly assists with portability problems -between Unix-like platforms. But -bzip2 doesn't have much in the -way of portability problems on Unix; most of the difficulties -appear when porting to the Mac, or to Microsoft's operating -systems. autoconf doesn't help -in those cases, and brings in a whole load of new -complexity. - -Most people should be able to compile the library and -program under Unix straight out-of-the-box, so to speak, -especially if you have a version of GNU C available. - -There are a couple of -__inline__ directives in the -code. GNU C (gcc) should be -able to handle them. If you're not using GNU C, your C compiler -shouldn't see them at all. If your compiler does, for some -reason, see them and doesn't like them, just -#define -__inline__ to be -/* */. One easy way to do this -is to compile with the flag --D__inline__=, which should be -understood by most Unix compilers. - -If you still have difficulties, try compiling with the -macro BZ_STRICT_ANSI defined. -This should enable you to build the library in a strictly ANSI -compliant environment. Building the program itself like this is -dangerous and not supported, since you remove -bzip2's checks against -compressing directories, symbolic links, devices, and other -not-really-a-file entities. This could cause filesystem -corruption! - -One other thing: if you create a -bzip2 binary for public distribution, -please consider linking it statically (gcc --static). This avoids all sorts of library-version -issues that others may encounter later on. - -If you build bzip2 on -Win32, you must set BZ_UNIX to 0 -and BZ_LCCWIN32 to 1, in the -file bzip2.c, before compiling. -Otherwise the resulting binary won't work correctly. - - - - - -Reporting bugs - -I tried pretty hard to make sure -bzip2 is bug free, both by -design and by testing. Hopefully you'll never need to read this -section for real. - -Nevertheless, if bzip2 dies -with a segmentation fault, a bus error or an internal assertion -failure, it will ask you to email me a bug report. Experience from -years of feedback of bzip2 users indicates that almost all these -problems can be traced to either compiler bugs or hardware -problems. - - - - Recompile the program with no optimisation, and - see if it works. And/or try a different compiler. I heard all - sorts of stories about various flavours of GNU C (and other - compilers) generating bad code for - bzip2, and I've run across two - such examples myself. - - 2.7.X versions of GNU C are known to generate bad code - from time to time, at high optimisation levels. If you get - problems, try using the flags - -O2 - -fomit-frame-pointer - -fno-strength-reduce. You - should specifically not use - -funroll-loops. - - You may notice that the Makefile runs six tests as part - of the build process. If the program passes all of these, it's - a pretty good (but not 100%) indication that the compiler has - done its job correctly. - - If bzip2 - crashes randomly, and the crashes are not repeatable, you may - have a flaky memory subsystem. - bzip2 really hammers your - memory hierarchy, and if it's a bit marginal, you may get these - problems. Ditto if your disk or I/O subsystem is slowly - failing. Yup, this really does happen. - - Try using a different machine of the same type, and see - if you can repeat the problem. - - This isn't really a bug, but ... If - bzip2 tells you your file is - corrupted on decompression, and you obtained the file via FTP, - there is a possibility that you forgot to tell FTP to do a - binary mode transfer. That absolutely will cause the file to - be non-decompressible. You'll have to transfer it - again. - - - -If you've incorporated -libbzip2 into your own program -and are getting problems, please, please, please, check that the -parameters you are passing in calls to the library, are correct, -and in accordance with what the documentation says is allowable. -I have tried to make the library robust against such problems, -but I'm sure I haven't succeeded. - -Finally, if the above comments don't help, you'll have to -send me a bug report. Now, it's just amazing how many people -will send me a bug report saying something like: - - -bzip2 crashed with segmentation fault on my machine - - -and absolutely nothing else. Needless to say, a such a -report is totally, utterly, completely and -comprehensively 100% useless; a waste of your time, my time, and -net bandwidth. With no details at all, there's no way -I can possibly begin to figure out what the problem is. - -The rules of the game are: facts, facts, facts. Don't omit -them because "oh, they won't be relevant". At the bare -minimum: - - -Machine type. Operating system version. -Exact version of bzip2 (do bzip2 -V). -Exact version of the compiler used. -Flags passed to the compiler. - - -However, the most important single thing that will help me -is the file that you were trying to compress or decompress at the -time the problem happened. Without that, my ability to do -anything more than speculate about the cause, is limited. - - - - - -Did you get the right package? - -bzip2 is a resource hog. -It soaks up large amounts of CPU cycles and memory. Also, it -gives very large latencies. In the worst case, you can feed many -megabytes of uncompressed data into the library before getting -any compressed output, so this probably rules out applications -requiring interactive behaviour. - -These aren't faults of my implementation, I hope, but more -an intrinsic property of the Burrows-Wheeler transform -(unfortunately). Maybe this isn't what you want. - -If you want a compressor and/or library which is faster, -uses less memory but gets pretty good compression, and has -minimal latency, consider Jean-loup Gailly's and Mark Adler's -work, zlib-1.2.1 and -gzip-1.2.4. Look for them at -http://www.zlib.org and -http://www.gzip.org -respectively. - -For something faster and lighter still, you might try Markus F -X J Oberhumer's LZO real-time -compression/decompression library, at -http://www.oberhumer.com/opensource. - - - - - - -Further Reading - -bzip2 is not research -work, in the sense that it doesn't present any new ideas. -Rather, it's an engineering exercise based on existing -ideas. - -Four documents describe essentially all the ideas behind -bzip2: - -Michael Burrows and D. J. Wheeler: - "A block-sorting lossless data compression algorithm" - 10th May 1994. - Digital SRC Research Report 124. - ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz - If you have trouble finding it, try searching at the - New Zealand Digital Library, http://www.nzdl.org. - -Daniel S. Hirschberg and Debra A. LeLewer - "Efficient Decoding of Prefix Codes" - Communications of the ACM, April 1990, Vol 33, Number 4. - You might be able to get an electronic copy of this - from the ACM Digital Library. - -David J. Wheeler - Program bred3.c and accompanying document bred3.ps. - This contains the idea behind the multi-table Huffman coding scheme. - ftp://ftp.cl.cam.ac.uk/users/djw3/ - -Jon L. Bentley and Robert Sedgewick - "Fast Algorithms for Sorting and Searching Strings" - Available from Sedgewick's web page, - www.cs.princeton.edu/~rs - - -The following paper gives valuable additional insights into -the algorithm, but is not immediately the basis of any code used -in bzip2. - -Peter Fenwick: - Block Sorting Text Compression - Proceedings of the 19th Australasian Computer Science Conference, - Melbourne, Australia. Jan 31 - Feb 2, 1996. - ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps - -Kunihiko Sadakane's sorting algorithm, mentioned above, is -available from: - -http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz - - -The Manber-Myers suffix array construction algorithm is -described in a paper available from: - -http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps - - -Finally, the following papers document some -investigations I made into the performance of sorting -and decompression algorithms: - -Julian Seward - On the Performance of BWT Sorting Algorithms - Proceedings of the IEEE Data Compression Conference 2000 - Snowbird, Utah. 28-30 March 2000. - -Julian Seward - Space-time Tradeoffs in the Inverse B-W Transform - Proceedings of the IEEE Data Compression Conference 2001 - Snowbird, Utah. 27-29 March 2001. - - - - - - -
diff --git a/third_party/bzip2/mk251.c b/third_party/bzip2/mk251.c deleted file mode 100644 index 6c5bbf935..000000000 --- a/third_party/bzip2/mk251.c +++ /dev/null @@ -1,31 +0,0 @@ - -/* Spew out a long sequence of the byte 251. When fed to bzip2 - versions 1.0.0 or 1.0.1, causes it to die with internal error - 1007 in blocksort.c. This assertion misses an extremely rare - case, which is fixed in this version (1.0.2) and above. -*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.8 of 13 July 2019 - Copyright (C) 1996-2019 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include - -int main () -{ - int i; - for (i = 0; i < 48500000 ; i++) - putchar(251); - return 0; -} diff --git a/third_party/bzip2/randtable.c b/third_party/bzip2/randtable.c index bdc6d4a4c..1b75a33e2 100644 --- a/third_party/bzip2/randtable.c +++ b/third_party/bzip2/randtable.c @@ -1,3 +1,4 @@ +/* clang-format off */ /*-------------------------------------------------------------*/ /*--- Table for randomising repetitive blocks ---*/ @@ -19,7 +20,7 @@ ------------------------------------------------------------------ */ -#include "bzlib_private.h" +#include "third_party/bzip2/bzlib_private.inc" /*---------------------------------------------*/ diff --git a/third_party/bzip2/spewG.c b/third_party/bzip2/spewG.c index 65d24c89c..2d65b8d60 100644 --- a/third_party/bzip2/spewG.c +++ b/third_party/bzip2/spewG.c @@ -1,3 +1,6 @@ +#include "libc/rand/rand.h" +#include "libc/stdio/stdio.h" +/* clang-format off */ /* spew out a thoroughly gigantic file designed so that bzip2 can compress it reasonably rapidly. This is to help test @@ -26,9 +29,6 @@ #define _FILE_OFFSET_BITS 64 -#include -#include - /* The number of megabytes of junk to spew out (roughly) */ #define MEGABYTES 5000 diff --git a/third_party/bzip2/unzcrash.c b/third_party/bzip2/unzcrash.c deleted file mode 100644 index c68f93c56..000000000 --- a/third_party/bzip2/unzcrash.c +++ /dev/null @@ -1,141 +0,0 @@ - -/* A test program written to test robustness to decompression of - corrupted data. Usage is - unzcrash filename - and the program will read the specified file, compress it (in memory), - and then repeatedly decompress it, each time with a different bit of - the compressed data inverted, so as to test all possible one-bit errors. - This should not cause any invalid memory accesses. If it does, - I want to know about it! - - PS. As you can see from the above description, the process is - incredibly slow. A file of size eg 5KB will cause it to run for - many hours. -*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.8 of 13 July 2019 - Copyright (C) 1996-2019 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include -#include -#include "bzlib.h" - -#define M_BLOCK 1000000 - -typedef unsigned char uchar; - -#define M_BLOCK_OUT (M_BLOCK + 1000000) -uchar inbuf[M_BLOCK]; -uchar outbuf[M_BLOCK_OUT]; -uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)]; - -int nIn, nOut, nZ; - -static char *bzerrorstrings[] = { - "OK" - ,"SEQUENCE_ERROR" - ,"PARAM_ERROR" - ,"MEM_ERROR" - ,"DATA_ERROR" - ,"DATA_ERROR_MAGIC" - ,"IO_ERROR" - ,"UNEXPECTED_EOF" - ,"OUTBUFF_FULL" - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ -}; - -void flip_bit ( int bit ) -{ - int byteno = bit / 8; - int bitno = bit % 8; - uchar mask = 1 << bitno; - //fprintf ( stderr, "(byte %d bit %d mask %d)", - // byteno, bitno, (int)mask ); - zbuf[byteno] ^= mask; -} - -int main ( int argc, char** argv ) -{ - FILE* f; - int r; - int bit; - int i; - - if (argc != 2) { - fprintf ( stderr, "usage: unzcrash filename\n" ); - return 1; - } - - f = fopen ( argv[1], "r" ); - if (!f) { - fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] ); - return 1; - } - - nIn = fread ( inbuf, 1, M_BLOCK, f ); - fprintf ( stderr, "%d bytes read\n", nIn ); - - nZ = M_BLOCK; - r = BZ2_bzBuffToBuffCompress ( - zbuf, &nZ, inbuf, nIn, 9, 0, 30 ); - - assert (r == BZ_OK); - fprintf ( stderr, "%d after compression\n", nZ ); - - for (bit = 0; bit < nZ*8; bit++) { - fprintf ( stderr, "bit %d ", bit ); - flip_bit ( bit ); - nOut = M_BLOCK_OUT; - r = BZ2_bzBuffToBuffDecompress ( - outbuf, &nOut, zbuf, nZ, 0, 0 ); - fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] ); - - if (r != BZ_OK) { - fprintf ( stderr, "\n" ); - } else { - if (nOut != nIn) { - fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut ); - return 1; - } else { - for (i = 0; i < nOut; i++) - if (inbuf[i] != outbuf[i]) { - fprintf(stderr, "mismatch at %d\n", i ); - return 1; - } - if (i == nOut) fprintf(stderr, "really ok!\n" ); - } - } - - flip_bit ( bit ); - } - -#if 0 - assert (nOut == nIn); - for (i = 0; i < nOut; i++) { - if (inbuf[i] != outbuf[i]) { - fprintf ( stderr, "difference at %d !\n", i ); - return 1; - } - } -#endif - - fprintf ( stderr, "all ok\n" ); - return 0; -} diff --git a/third_party/bzip2/xmlproc.sh b/third_party/bzip2/xmlproc.sh deleted file mode 100755 index 16fe72b2d..000000000 --- a/third_party/bzip2/xmlproc.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/bash -# see the README file for usage etc. -# -# ------------------------------------------------------------------ -# This file is part of bzip2/libbzip2, a program and library for -# lossless, block-sorting data compression. -# -# bzip2/libbzip2 version 1.0.8 of 13 July 2019 -# Copyright (C) 1996-2019 Julian Seward -# -# Please read the WARNING, DISCLAIMER and PATENTS sections in the -# README file. -# -# This program is released under the terms of the license contained -# in the file LICENSE. -# ---------------------------------------------------------------- - - -usage() { - echo ''; - echo 'Usage: xmlproc.sh -[option] '; - echo 'Specify a target from:'; - echo '-v verify xml file conforms to dtd'; - echo '-html output in html format (single file)'; - echo '-ps output in postscript format'; - echo '-pdf output in pdf format'; - exit; -} - -if test $# -ne 2; then - usage -fi -# assign the variable for the output type -action=$1; shift -# assign the output filename -xmlfile=$1; shift -# and check user input it correct -if !(test -f $xmlfile); then - echo "No such file: $xmlfile"; - exit; -fi -# some other stuff we will use -OUT=output -xsl_fo=bz-fo.xsl -xsl_html=bz-html.xsl - -basename=$xmlfile -basename=${basename//'.xml'/''} - -fofile="${basename}.fo" -htmlfile="${basename}.html" -pdffile="${basename}.pdf" -psfile="${basename}.ps" -xmlfmtfile="${basename}.fmt" - -# first process the xmlfile with CDATA tags -./format.pl $xmlfile $xmlfmtfile -# so the shell knows where the catalogs live -export XML_CATALOG_FILES=/etc/xml/catalog - -# post-processing tidy up -cleanup() { - echo "Cleaning up: $@" - while [ $# != 0 ] - do - arg=$1; shift; - echo " deleting $arg"; - rm $arg - done -} - -case $action in - -v) - flags='--noout --xinclude --noblanks --postvalid' - dtd='--dtdvalid http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd' - xmllint $flags $dtd $xmlfmtfile 2> $OUT - egrep 'error' $OUT - rm $OUT - ;; - - -html) - echo "Creating $htmlfile ..." - xsltproc --nonet --xinclude -o $htmlfile $xsl_html $xmlfmtfile - cleanup $xmlfmtfile - ;; - - -pdf) - echo "Creating $pdffile ..." - xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile - pdfxmltex $fofile >$OUT $OUT $OUT $OUT $OUT $OUT $OUT $OUT $OUT