Commit bb2dc47110fe0a0a05ee2039adc1de4ddf2fb9c2
1 parent
e4822482
test
git-svn-id: http://svn.net-core.org/repos/t-engine4@4373 51575b47-30f0-44d4-a5cc-537603b46e54
Showing
13 changed files
with
4819 additions
and
2 deletions
Too many changes to show.
To preserve performance only 13 of 13+ files are displayed.
... | ... | @@ -22,7 +22,7 @@ project "TEngine" |
22 | 22 | language "C" |
23 | 23 | targetname("t-engine") |
24 | 24 | files { "../src/*.c", } |
25 | - links { "physfs", "lua".._OPTIONS.lua, "fov", "luasocket", "luaprofiler", "lualanes", "lpeg", "tcodimport", "lxp", "expatstatic", "luamd5", "luazlib", "luabitop" } | |
25 | + links { "physfs", "lua".._OPTIONS.lua, "fov", "luasocket", "luaprofiler", "lualanes", "lpeg", "tcodimport", "lxp", "expatstatic", "luamd5", "luazlib", "luabitop", "te4-bzip" } | |
26 | 26 | defines { "_DEFAULT_VIDEOMODE_FLAGS_='SDL_HWSURFACE|SDL_DOUBLEBUF'" } |
27 | 27 | defines { [[TENGINE_HOME_PATH='".t-engine"']], "TE4CORE_VERSION="..TE4CORE_VERSION } |
28 | 28 | |
... | ... | @@ -272,3 +272,10 @@ project "utf8proc" |
272 | 272 | targetname "utf8proc" |
273 | 273 | |
274 | 274 | files { "../src/utf8proc/utf8proc.c", } |
275 | + | |
276 | +project "te4-bzip" | |
277 | + kind "StaticLib" | |
278 | + language "C" | |
279 | + targetname "te4-bzip" | |
280 | + | |
281 | + files { "../src/bzip2/*.c", } | ... | ... |
... | ... | @@ -45,13 +45,19 @@ Still, this is a golden age. Civilisations are healing the wounds of thousands o |
45 | 45 | You are an adventurer, set out to discover wonders, explore old places, and venture into the unknown for wealth and glory. |
46 | 46 | ]] |
47 | 47 | starter = "mod.load" |
48 | + | |
49 | +-- List of additional team files required | |
50 | +teams = { | |
51 | + { "#name#-#version#-music.team", "optional", {"/data/music/"} }, | |
52 | + { "#name#-#version#-gfx-shockbolt.team", "optional", {"/data/gfx/shockbolt/"} }, | |
53 | +} | |
54 | + | |
48 | 55 | loading_wait_ticks = 260 |
49 | 56 | profile_stats_fields = {"artifacts", "characters", "deaths", "uniques", "scores", "lore", "escorts"} |
50 | 57 | allow_userchat = true -- We can talk to the online community |
51 | 58 | no_get_name = true -- Name setting for new characters is done by the module itself |
52 | 59 | |
53 | 60 | -- Define the fields that are sync'ed online, and how they are sync'ed |
54 | --- ' | |
55 | 61 | profile_defs = { |
56 | 62 | allow_build = { {name="index:string:30"}, receive=function(data, save) save[data.name] = true end, export=function(env) for k, _ in pairs(env) do add{name=k} end end }, |
57 | 63 | lore = { {name="index:string:30"}, receive=function(data, save) save.lore = save.lore or {} save.lore[data.name] = true end, export=function(env) for k, v in pairs(env.lore or {}) do add{name=k} end end }, |
... | ... | @@ -82,6 +88,7 @@ profile_defs = { |
82 | 88 | }, |
83 | 89 | } |
84 | 90 | |
91 | +-- Formatter for scores | |
85 | 92 | score_formatters = { |
86 | 93 | ["Maj'Eyal"] = { |
87 | 94 | alive="#LIGHT_GREEN#{score} : #BLUE#{name}#LAST# the #LIGHT_RED#level {level} {subrace} {subclass}#LAST# is still alive and well on #GREEN#{where}#LAST##WHITE#", | ... | ... |
src/bspatch.c
0 → 100644
1 | +/*- | |
2 | + * Copyright 2003-2005 Colin Percival | |
3 | + * All rights reserved | |
4 | + * | |
5 | + * Redistribution and use in source and binary forms, with or without | |
6 | + * modification, are permitted providing that the following conditions | |
7 | + * are met: | |
8 | + * 1. Redistributions of source code must retain the above copyright | |
9 | + * notice, this list of conditions and the following disclaimer. | |
10 | + * 2. Redistributions in binary form must reproduce the above copyright | |
11 | + * notice, this list of conditions and the following disclaimer in the | |
12 | + * documentation and/or other materials provided with the distribution. | |
13 | + * | |
14 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
15 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
16 | + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
17 | + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
18 | + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
19 | + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
20 | + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
21 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
22 | + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
23 | + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
24 | + * POSSIBILITY OF SUCH DAMAGE. | |
25 | + */ | |
26 | + | |
27 | +#include "bzlib.h" | |
28 | +#include <stdlib.h> | |
29 | +#include <stdio.h> | |
30 | +#include <string.h> | |
31 | +#include <unistd.h> | |
32 | +#include <fcntl.h> | |
33 | + | |
34 | +static off_t offtin(u_char *buf) | |
35 | +{ | |
36 | + off_t y; | |
37 | + | |
38 | + y=buf[7]&0x7F; | |
39 | + y=y*256;y+=buf[6]; | |
40 | + y=y*256;y+=buf[5]; | |
41 | + y=y*256;y+=buf[4]; | |
42 | + y=y*256;y+=buf[3]; | |
43 | + y=y*256;y+=buf[2]; | |
44 | + y=y*256;y+=buf[1]; | |
45 | + y=y*256;y+=buf[0]; | |
46 | + | |
47 | + if(buf[7]&0x80) y=-y; | |
48 | + | |
49 | + return y; | |
50 | +} | |
51 | + | |
52 | +#define returnerr(ret, str, f1, f2) { printf(str, f1, f2); perror("\nError in bspatch\n"); return (ret); } | |
53 | + | |
54 | +int bspatch(char *infile, char *outfile, char *patchfile) | |
55 | +{ | |
56 | + FILE * f, * cpf, * dpf, * epf; | |
57 | + BZFILE * cpfbz2, * dpfbz2, * epfbz2; | |
58 | + int cbz2err, dbz2err, ebz2err; | |
59 | + int fd; | |
60 | + ssize_t oldsize,newsize; | |
61 | + ssize_t bzctrllen,bzdatalen; | |
62 | + u_char header[32],buf[8]; | |
63 | + u_char *old, *new; | |
64 | + off_t oldpos,newpos; | |
65 | + off_t ctrl[3]; | |
66 | + off_t lenread; | |
67 | + off_t i; | |
68 | + | |
69 | + /* Open patch file */ | |
70 | + if ((f = fopen(patchfile, "r")) == NULL) | |
71 | + returnerr(1, "fopen(%s)", patchfile, 0); | |
72 | + | |
73 | + /* | |
74 | + File format: | |
75 | + 0 8 "BSDIFF40" | |
76 | + 8 8 X | |
77 | + 16 8 Y | |
78 | + 24 8 sizeof(newfile) | |
79 | + 32 X bzip2(control block) | |
80 | + 32+X Y bzip2(diff block) | |
81 | + 32+X+Y ??? bzip2(extra block) | |
82 | + with control block a set of triples (x,y,z) meaning "add x bytes | |
83 | + from oldfile to x bytes from the diff block; copy y bytes from the | |
84 | + extra block; seek forwards in oldfile by z bytes". | |
85 | + */ | |
86 | + | |
87 | + /* Read header */ | |
88 | + if (fread(header, 1, 32, f) < 32) { | |
89 | + if (feof(f)) | |
90 | + errx(1, "Corrupt patch\n"); | |
91 | + returnerr(1, "fread(%s)", patchfile, 0); | |
92 | + } | |
93 | + | |
94 | + /* Check for appropriate magic */ | |
95 | + if (memcmp(header, "BSDIFF40", 8) != 0) | |
96 | + errx(1, "Corrupt patch\n"); | |
97 | + | |
98 | + /* Read lengths from header */ | |
99 | + bzctrllen=offtin(header+8); | |
100 | + bzdatalen=offtin(header+16); | |
101 | + newsize=offtin(header+24); | |
102 | + if((bzctrllen<0) || (bzdatalen<0) || (newsize<0)) | |
103 | + errx(1,"Corrupt patch\n"); | |
104 | + | |
105 | + /* Close patch file and re-open it via libbzip2 at the right places */ | |
106 | + if (fclose(f)) | |
107 | + returnerr(1, "fclose(%s)", patchfile, 0); | |
108 | + if ((cpf = fopen(patchfile, "r")) == NULL) | |
109 | + returnerr(1, "fopen(%s)", patchfile, 0); | |
110 | + if (fseeko(cpf, 32, SEEK_SET)) | |
111 | + returnerr(1, "fseeko(%s, %lld)", patchfile, | |
112 | + (long long)32); | |
113 | + if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL) | |
114 | + errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err); | |
115 | + if ((dpf = fopen(patchfile, "r")) == NULL) | |
116 | + returnerr(1, "fopen(%s)", patchfile, 0); | |
117 | + if (fseeko(dpf, 32 + bzctrllen, SEEK_SET)) | |
118 | + returnerr(1, "fseeko(%s, %lld)", patchfile, | |
119 | + (long long)(32 + bzctrllen)); | |
120 | + if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL) | |
121 | + errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err); | |
122 | + if ((epf = fopen(patchfile, "r")) == NULL) | |
123 | + returnerr(1, "fopen(%s)", patchfile, 0); | |
124 | + if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET)) | |
125 | + returnerr(1, "fseeko(%s, %lld)", patchfile, | |
126 | + (long long)(32 + bzctrllen + bzdatalen)); | |
127 | + if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) | |
128 | + errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); | |
129 | + | |
130 | + if(((fd=open(infile,O_RDONLY,0))<0) || | |
131 | + ((oldsize=lseek(fd,0,SEEK_END))==-1) || | |
132 | + ((old=malloc(oldsize+1))==NULL) || | |
133 | + (lseek(fd,0,SEEK_SET)!=0) || | |
134 | + (read(fd,old,oldsize)!=oldsize) || | |
135 | + (close(fd)==-1)) returnerr(1,"%s",infile, 0); | |
136 | + if((new=malloc(newsize+1))==NULL) returnerr(1,"not enough memory", 0, 0); | |
137 | + | |
138 | + oldpos=0;newpos=0; | |
139 | + while(newpos<newsize) { | |
140 | + /* Read control data */ | |
141 | + for(i=0;i<=2;i++) { | |
142 | + lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8); | |
143 | + if ((lenread < 8) || ((cbz2err != BZ_OK) && | |
144 | + (cbz2err != BZ_STREAM_END))) | |
145 | + errx(1, "Corrupt patch\n"); | |
146 | + ctrl[i]=offtin(buf); | |
147 | + }; | |
148 | + | |
149 | + /* Sanity-check */ | |
150 | + if(newpos+ctrl[0]>newsize) | |
151 | + errx(1,"Corrupt patch\n"); | |
152 | + | |
153 | + /* Read diff string */ | |
154 | + lenread = BZ2_bzRead(&dbz2err, dpfbz2, new + newpos, ctrl[0]); | |
155 | + if ((lenread < ctrl[0]) || | |
156 | + ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END))) | |
157 | + errx(1, "Corrupt patch\n"); | |
158 | + | |
159 | + /* Add old data to diff string */ | |
160 | + for(i=0;i<ctrl[0];i++) | |
161 | + if((oldpos+i>=0) && (oldpos+i<oldsize)) | |
162 | + new[newpos+i]+=old[oldpos+i]; | |
163 | + | |
164 | + /* Adjust pointers */ | |
165 | + newpos+=ctrl[0]; | |
166 | + oldpos+=ctrl[0]; | |
167 | + | |
168 | + /* Sanity-check */ | |
169 | + if(newpos+ctrl[1]>newsize) | |
170 | + errx(1,"Corrupt patch\n"); | |
171 | + | |
172 | + /* Read extra string */ | |
173 | + lenread = BZ2_bzRead(&ebz2err, epfbz2, new + newpos, ctrl[1]); | |
174 | + if ((lenread < ctrl[1]) || | |
175 | + ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END))) | |
176 | + errx(1, "Corrupt patch\n"); | |
177 | + | |
178 | + /* Adjust pointers */ | |
179 | + newpos+=ctrl[1]; | |
180 | + oldpos+=ctrl[2]; | |
181 | + }; | |
182 | + | |
183 | + /* Clean up the bzip2 reads */ | |
184 | + BZ2_bzReadClose(&cbz2err, cpfbz2); | |
185 | + BZ2_bzReadClose(&dbz2err, dpfbz2); | |
186 | + BZ2_bzReadClose(&ebz2err, epfbz2); | |
187 | + if (fclose(cpf) || fclose(dpf) || fclose(epf)) | |
188 | + returnerr(1, "fclose(%s)", patchfile, 0); | |
189 | + | |
190 | + /* Write the new file */ | |
191 | + if(((fd=open(outfile,O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || | |
192 | + (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) | |
193 | + returnerr(1,"%s",outfile, 0); | |
194 | + | |
195 | + free(new); | |
196 | + free(old); | |
197 | + | |
198 | + return 0; | |
199 | +} | ... | ... |
src/bspatch.h
0 → 100644
1 | +extern int bspatch(char *infile, char *outfile, char *patchfile); | ... | ... |
src/bzip2/CHANGES
0 → 100644
1 | + ------------------------------------------------------------------ | |
2 | + This file is part of bzip2/libbzip2, a program and library for | |
3 | + lossless, block-sorting data compression. | |
4 | + | |
5 | + bzip2/libbzip2 version 1.0.6 of 6 September 2010 | |
6 | + Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> | |
7 | + | |
8 | + Please read the WARNING, DISCLAIMER and PATENTS sections in the | |
9 | + README file. | |
10 | + | |
11 | + This program is released under the terms of the license contained | |
12 | + in the file LICENSE. | |
13 | + ------------------------------------------------------------------ | |
14 | + | |
15 | + | |
16 | +0.9.0 | |
17 | +~~~~~ | |
18 | +First version. | |
19 | + | |
20 | + | |
21 | +0.9.0a | |
22 | +~~~~~~ | |
23 | +Removed 'ranlib' from Makefile, since most modern Unix-es | |
24 | +don't need it, or even know about it. | |
25 | + | |
26 | + | |
27 | +0.9.0b | |
28 | +~~~~~~ | |
29 | +Fixed a problem with error reporting in bzip2.c. This does not effect | |
30 | +the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the | |
31 | +program proper) compress and decompress correctly, but give misleading | |
32 | +error messages (internal panics) when an I/O error occurs, instead of | |
33 | +reporting the problem correctly. This shouldn't give any data loss | |
34 | +(as far as I can see), but is confusing. | |
35 | + | |
36 | +Made the inline declarations disappear for non-GCC compilers. | |
37 | + | |
38 | + | |
39 | +0.9.0c | |
40 | +~~~~~~ | |
41 | +Fixed some problems in the library pertaining to some boundary cases. | |
42 | +This makes the library behave more correctly in those situations. The | |
43 | +fixes apply only to features (calls and parameters) not used by | |
44 | +bzip2.c, so the non-fixedness of them in previous versions has no | |
45 | +effect on reliability of bzip2.c. | |
46 | + | |
47 | +In bzlib.c: | |
48 | + * made zero-length BZ_FLUSH work correctly in bzCompress(). | |
49 | + * fixed bzWrite/bzRead to ignore zero-length requests. | |
50 | + * fixed bzread to correctly handle read requests after EOF. | |
51 | + * wrong parameter order in call to bzDecompressInit in | |
52 | + bzBuffToBuffDecompress. Fixed. | |
53 | + | |
54 | +In compress.c: | |
55 | + * changed setting of nGroups in sendMTFValues() so as to | |
56 | + do a bit better on small files. This _does_ effect | |
57 | + bzip2.c. | |
58 | + | |
59 | + | |
60 | +0.9.5a | |
61 | +~~~~~~ | |
62 | +Major change: add a fallback sorting algorithm (blocksort.c) | |
63 | +to give reasonable behaviour even for very repetitive inputs. | |
64 | +Nuked --repetitive-best and --repetitive-fast since they are | |
65 | +no longer useful. | |
66 | + | |
67 | +Minor changes: mostly a whole bunch of small changes/ | |
68 | +bugfixes in the driver (bzip2.c). Changes pertaining to the | |
69 | +user interface are: | |
70 | + | |
71 | + allow decompression of symlink'd files to stdout | |
72 | + decompress/test files even without .bz2 extension | |
73 | + give more accurate error messages for I/O errors | |
74 | + when compressing/decompressing to stdout, don't catch control-C | |
75 | + read flags from BZIP2 and BZIP environment variables | |
76 | + decline to break hard links to a file unless forced with -f | |
77 | + allow -c flag even with no filenames | |
78 | + preserve file ownerships as far as possible | |
79 | + make -s -1 give the expected block size (100k) | |
80 | + add a flag -q --quiet to suppress nonessential warnings | |
81 | + stop decoding flags after --, so files beginning in - can be handled | |
82 | + resolved inconsistent naming: bzcat or bz2cat ? | |
83 | + bzip2 --help now returns 0 | |
84 | + | |
85 | +Programming-level changes are: | |
86 | + | |
87 | + fixed syntax error in GET_LL4 for Borland C++ 5.02 | |
88 | + let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC} | |
89 | + fix overshoot of mode-string end in bzopen_or_bzdopen | |
90 | + wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... } | |
91 | + close file handles under all error conditions | |
92 | + added minor mods so it compiles with DJGPP out of the box | |
93 | + fixed Makefile so it doesn't give problems with BSD make | |
94 | + fix uninitialised memory reads in dlltest.c | |
95 | + | |
96 | +0.9.5b | |
97 | +~~~~~~ | |
98 | +Open stdin/stdout in binary mode for DJGPP. | |
99 | + | |
100 | +0.9.5c | |
101 | +~~~~~~ | |
102 | +Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1 | |
103 | +version could cause the sorted order to be wrong in some extremely | |
104 | +obscure cases. Also changed setting of quadrant in blocksort.c. | |
105 | + | |
106 | +0.9.5d | |
107 | +~~~~~~ | |
108 | +The only functional change is to make bzlibVersion() in the library | |
109 | +return the correct string. This has no effect whatsoever on the | |
110 | +functioning of the bzip2 program or library. Added a couple of casts | |
111 | +so the library compiles without warnings at level 3 in MS Visual | |
112 | +Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other | |
113 | +changes are minor documentation changes. | |
114 | + | |
115 | +1.0 | |
116 | +~~~ | |
117 | +Several minor bugfixes and enhancements: | |
118 | + | |
119 | +* Large file support. The library uses 64-bit counters to | |
120 | + count the volume of data passing through it. bzip2.c | |
121 | + is now compiled with -D_FILE_OFFSET_BITS=64 to get large | |
122 | + file support from the C library. -v correctly prints out | |
123 | + file sizes greater than 4 gigabytes. All these changes have | |
124 | + been made without assuming a 64-bit platform or a C compiler | |
125 | + which supports 64-bit ints, so, except for the C library | |
126 | + aspect, they are fully portable. | |
127 | + | |
128 | +* Decompression robustness. The library/program should be | |
129 | + robust to any corruption of compressed data, detecting and | |
130 | + handling _all_ corruption, instead of merely relying on | |
131 | + the CRCs. What this means is that the program should | |
132 | + never crash, given corrupted data, and the library should | |
133 | + always return BZ_DATA_ERROR. | |
134 | + | |
135 | +* Fixed an obscure race-condition bug only ever observed on | |
136 | + Solaris, in which, if you were very unlucky and issued | |
137 | + control-C at exactly the wrong time, both input and output | |
138 | + files would be deleted. | |
139 | + | |
140 | +* Don't run out of file handles on test/decompression when | |
141 | + large numbers of files have invalid magic numbers. | |
142 | + | |
143 | +* Avoid library namespace pollution. Prefix all exported | |
144 | + symbols with BZ2_. | |
145 | + | |
146 | +* Minor sorting enhancements from my DCC2000 paper. | |
147 | + | |
148 | +* Advance the version number to 1.0, so as to counteract the | |
149 | + (false-in-this-case) impression some people have that programs | |
150 | + with version numbers less than 1.0 are in some way, experimental, | |
151 | + pre-release versions. | |
152 | + | |
153 | +* Create an initial Makefile-libbz2_so to build a shared library. | |
154 | + Yes, I know I should really use libtool et al ... | |
155 | + | |
156 | +* Make the program exit with 2 instead of 0 when decompression | |
157 | + fails due to a bad magic number (ie, an invalid bzip2 header). | |
158 | + Also exit with 1 (as the manual claims :-) whenever a diagnostic | |
159 | + message would have been printed AND the corresponding operation | |
160 | + is aborted, for example | |
161 | + bzip2: Output file xx already exists. | |
162 | + When a diagnostic message is printed but the operation is not | |
163 | + aborted, for example | |
164 | + bzip2: Can't guess original name for wurble -- using wurble.out | |
165 | + then the exit value 0 is returned, unless some other problem is | |
166 | + also detected. | |
167 | + | |
168 | + I think it corresponds more closely to what the manual claims now. | |
169 | + | |
170 | + | |
171 | +1.0.1 | |
172 | +~~~~~ | |
173 | +* Modified dlltest.c so it uses the new BZ2_ naming scheme. | |
174 | +* Modified makefile-msc to fix minor build probs on Win2k. | |
175 | +* Updated README.COMPILATION.PROBLEMS. | |
176 | + | |
177 | +There are no functionality changes or bug fixes relative to version | |
178 | +1.0.0. This is just a documentation update + a fix for minor Win32 | |
179 | +build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is | |
180 | +utterly pointless. Don't bother. | |
181 | + | |
182 | + | |
183 | +1.0.2 | |
184 | +~~~~~ | |
185 | +A bug fix release, addressing various minor issues which have appeared | |
186 | +in the 18 or so months since 1.0.1 was released. Most of the fixes | |
187 | +are to do with file-handling or documentation bugs. To the best of my | |
188 | +knowledge, there have been no data-loss-causing bugs reported in the | |
189 | +compression/decompression engine of 1.0.0 or 1.0.1. | |
190 | + | |
191 | +Note that this release does not improve the rather crude build system | |
192 | +for Unix platforms. The general plan here is to autoconfiscate/ | |
193 | +libtoolise 1.0.2 soon after release, and release the result as 1.1.0 | |
194 | +or perhaps 1.2.0. That, however, is still just a plan at this point. | |
195 | + | |
196 | +Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in | |
197 | +parentheses. | |
198 | + | |
199 | +* Fix an infinite segfault loop in 1.0.1 when a directory is | |
200 | + encountered in -f (force) mode. | |
201 | + (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt) | |
202 | + | |
203 | +* Avoid double fclose() of output file on certain I/O error paths. | |
204 | + (Solar Designer) | |
205 | + | |
206 | +* Don't fail with internal error 1007 when fed a long stream (> 48MB) | |
207 | + of byte 251. Also print useful message suggesting that 1007s may be | |
208 | + caused by bad memory. | |
209 | + (noticed by Juan Pedro Vallejo, fixed by me) | |
210 | + | |
211 | +* Fix uninitialised variable silly bug in demo prog dlltest.c. | |
212 | + (Jorj Bauer) | |
213 | + | |
214 | +* Remove 512-MB limitation on recovered file size for bzip2recover | |
215 | + on selected platforms which support 64-bit ints. At the moment | |
216 | + all GCC supported platforms, and Win32. | |
217 | + (me, Alson van der Meulen) | |
218 | + | |
219 | +* Hard-code header byte values, to give correct operation on platforms | |
220 | + using EBCDIC as their native character set (IBM's OS/390). | |
221 | + (Leland Lucius) | |
222 | + | |
223 | +* Copy file access times correctly. | |
224 | + (Marty Leisner) | |
225 | + | |
226 | +* Add distclean and check targets to Makefile. | |
227 | + (Michael Carmack) | |
228 | + | |
229 | +* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS). | |
230 | + (Rich Ireland, Bo Thorsen) | |
231 | + | |
232 | +* Pass -p (create parent dirs as needed) to mkdir during make install. | |
233 | + (Jeremy Fusco) | |
234 | + | |
235 | +* Dereference symlinks when copying file permissions in -f mode. | |
236 | + (Volker Schmidt) | |
237 | + | |
238 | +* Majorly simplify implementation of uInt64_qrm10. | |
239 | + (Bo Lindbergh) | |
240 | + | |
241 | +* Check the input file still exists before deleting the output one, | |
242 | + when aborting in cleanUpAndFail(). | |
243 | + (Joerg Prante, Robert Linden, Matthias Krings) | |
244 | + | |
245 | +Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer | |
246 | +of bzip2: | |
247 | + | |
248 | +* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore. | |
249 | + | |
250 | +* Spelling changes and minor enhancements in bzip2.1. | |
251 | + | |
252 | +* Avoid race condition between creating the output file and setting its | |
253 | + interim permissions safely, by using fopen_output_safely(). | |
254 | + No changes to bzip2recover since there is no issue with file | |
255 | + permissions there. | |
256 | + | |
257 | +* do not print senseless report with -v when compressing an empty | |
258 | + file. | |
259 | + | |
260 | +* bzcat -f works on non-bzip2 files. | |
261 | + | |
262 | +* do not try to escape shell meta-characters on unix (the shell takes | |
263 | + care of these). | |
264 | + | |
265 | +* added --fast and --best aliases for -1 -9 for gzip compatibility. | |
266 | + | |
267 | + | |
268 | +1.0.3 (15 Feb 05) | |
269 | +~~~~~~~~~~~~~~~~~ | |
270 | +Fixes some minor bugs since the last version, 1.0.2. | |
271 | + | |
272 | +* Further robustification against corrupted compressed data. | |
273 | + There are currently no known bitstreams which can cause the | |
274 | + decompressor to crash, loop or access memory which does not | |
275 | + belong to it. If you are using bzip2 or the library to | |
276 | + decompress bitstreams from untrusted sources, an upgrade | |
277 | + to 1.0.3 is recommended. This fixes CAN-2005-1260. | |
278 | + | |
279 | +* The documentation has been converted to XML, from which html | |
280 | + and pdf can be derived. | |
281 | + | |
282 | +* Various minor bugs in the documentation have been fixed. | |
283 | + | |
284 | +* Fixes for various compilation warnings with newer versions of | |
285 | + gcc, and on 64-bit platforms. | |
286 | + | |
287 | +* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2. | |
288 | + This has been fixed. | |
289 | + | |
290 | + | |
291 | +1.0.4 (20 Dec 06) | |
292 | +~~~~~~~~~~~~~~~~~ | |
293 | +Fixes some minor bugs since the last version, 1.0.3. | |
294 | + | |
295 | +* Fix file permissions race problem (CAN-2005-0953). | |
296 | + | |
297 | +* Avoid possible segfault in BZ2_bzclose. From Coverity's NetBSD | |
298 | + scan. | |
299 | + | |
300 | +* 'const'/prototype cleanups in the C code. | |
301 | + | |
302 | +* Change default install location to /usr/local, and handle multiple | |
303 | + 'make install's without error. | |
304 | + | |
305 | +* Sanitise file names more carefully in bzgrep. Fixes CAN-2005-0758 | |
306 | + to the extent that applies to bzgrep. | |
307 | + | |
308 | +* Use 'mktemp' rather than 'tempfile' in bzdiff. | |
309 | + | |
310 | +* Tighten up a couple of assertions in blocksort.c following automated | |
311 | + analysis. | |
312 | + | |
313 | +* Fix minor doc/comment bugs. | |
314 | + | |
315 | + | |
316 | +1.0.5 (10 Dec 07) | |
317 | +~~~~~~~~~~~~~~~~~ | |
318 | +Security fix only. Fixes CERT-FI 20469 as it applies to bzip2. | |
319 | + | |
320 | + | |
321 | +1.0.6 (6 Sept 10) | |
322 | +~~~~~~~~~~~~~~~~~ | |
323 | + | |
324 | +* Security fix for CVE-2010-0405. This was reported by Mikolaj | |
325 | + Izdebski. | |
326 | + | |
327 | +* Make the documentation build on Ubuntu 10.04 | ... | ... |
src/bzip2/LICENSE
0 → 100644
1 | + | |
2 | +-------------------------------------------------------------------------- | |
3 | + | |
4 | +This program, "bzip2", the associated library "libbzip2", and all | |
5 | +documentation, are copyright (C) 1996-2010 Julian R Seward. All | |
6 | +rights reserved. | |
7 | + | |
8 | +Redistribution and use in source and binary forms, with or without | |
9 | +modification, are permitted provided that the following conditions | |
10 | +are met: | |
11 | + | |
12 | +1. Redistributions of source code must retain the above copyright | |
13 | + notice, this list of conditions and the following disclaimer. | |
14 | + | |
15 | +2. The origin of this software must not be misrepresented; you must | |
16 | + not claim that you wrote the original software. If you use this | |
17 | + software in a product, an acknowledgment in the product | |
18 | + documentation would be appreciated but is not required. | |
19 | + | |
20 | +3. Altered source versions must be plainly marked as such, and must | |
21 | + not be misrepresented as being the original software. | |
22 | + | |
23 | +4. The name of the author may not be used to endorse or promote | |
24 | + products derived from this software without specific prior written | |
25 | + permission. | |
26 | + | |
27 | +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | |
28 | +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
29 | +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
31 | +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
33 | +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
34 | +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
35 | +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
36 | +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
37 | +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
38 | + | |
39 | +Julian Seward, jseward@bzip.org | |
40 | +bzip2/libbzip2 version 1.0.6 of 6 September 2010 | |
41 | + | |
42 | +-------------------------------------------------------------------------- | ... | ... |
src/bzip2/blocksort.c
0 → 100644
1 | + | |
2 | +/*-------------------------------------------------------------*/ | |
3 | +/*--- Block sorting machinery ---*/ | |
4 | +/*--- blocksort.c ---*/ | |
5 | +/*-------------------------------------------------------------*/ | |
6 | + | |
7 | +/* ------------------------------------------------------------------ | |
8 | + This file is part of bzip2/libbzip2, a program and library for | |
9 | + lossless, block-sorting data compression. | |
10 | + | |
11 | + bzip2/libbzip2 version 1.0.6 of 6 September 2010 | |
12 | + Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> | |
13 | + | |
14 | + Please read the WARNING, DISCLAIMER and PATENTS sections in the | |
15 | + README file. | |
16 | + | |
17 | + This program is released under the terms of the license contained | |
18 | + in the file LICENSE. | |
19 | + ------------------------------------------------------------------ */ | |
20 | + | |
21 | + | |
22 | +#include "bzlib_private.h" | |
23 | + | |
24 | +/*---------------------------------------------*/ | |
25 | +/*--- Fallback O(N log(N)^2) sorting ---*/ | |
26 | +/*--- algorithm, for repetitive blocks ---*/ | |
27 | +/*---------------------------------------------*/ | |
28 | + | |
29 | +/*---------------------------------------------*/ | |
30 | +static | |
31 | +__inline__ | |
32 | +void fallbackSimpleSort ( UInt32* fmap, | |
33 | + UInt32* eclass, | |
34 | + Int32 lo, | |
35 | + Int32 hi ) | |
36 | +{ | |
37 | + Int32 i, j, tmp; | |
38 | + UInt32 ec_tmp; | |
39 | + | |
40 | + if (lo == hi) return; | |
41 | + | |
42 | + if (hi - lo > 3) { | |
43 | + for ( i = hi-4; i >= lo; i-- ) { | |
44 | + tmp = fmap[i]; | |
45 | + ec_tmp = eclass[tmp]; | |
46 | + for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 ) | |
47 | + fmap[j-4] = fmap[j]; | |
48 | + fmap[j-4] = tmp; | |
49 | + } | |
50 | + } | |
51 | + | |
52 | + for ( i = hi-1; i >= lo; i-- ) { | |
53 | + tmp = fmap[i]; | |
54 | + ec_tmp = eclass[tmp]; | |
55 | + for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ ) | |
56 | + fmap[j-1] = fmap[j]; | |
57 | + fmap[j-1] = tmp; | |
58 | + } | |
59 | +} | |
60 | + | |
61 | + | |
62 | +/*---------------------------------------------*/ | |
63 | +#define fswap(zz1, zz2) \ | |
64 | + { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } | |
65 | + | |
66 | +#define fvswap(zzp1, zzp2, zzn) \ | |
67 | +{ \ | |
68 | + Int32 yyp1 = (zzp1); \ | |
69 | + Int32 yyp2 = (zzp2); \ | |
70 | + Int32 yyn = (zzn); \ | |
71 | + while (yyn > 0) { \ | |
72 | + fswap(fmap[yyp1], fmap[yyp2]); \ | |
73 | + yyp1++; yyp2++; yyn--; \ | |
74 | + } \ | |
75 | +} | |
76 | + | |
77 | + | |
78 | +#define fmin(a,b) ((a) < (b)) ? (a) : (b) | |
79 | + | |
80 | +#define fpush(lz,hz) { stackLo[sp] = lz; \ | |
81 | + stackHi[sp] = hz; \ | |
82 | + sp++; } | |
83 | + | |
84 | +#define fpop(lz,hz) { sp--; \ | |
85 | + lz = stackLo[sp]; \ | |
86 | + hz = stackHi[sp]; } | |
87 | + | |
88 | +#define FALLBACK_QSORT_SMALL_THRESH 10 | |
89 | +#define FALLBACK_QSORT_STACK_SIZE 100 | |
90 | + | |
91 | + | |
92 | +static | |
93 | +void fallbackQSort3 ( UInt32* fmap, | |
94 | + UInt32* eclass, | |
95 | + Int32 loSt, | |
96 | + Int32 hiSt ) | |
97 | +{ | |
98 | + Int32 unLo, unHi, ltLo, gtHi, n, m; | |
99 | + Int32 sp, lo, hi; | |
100 | + UInt32 med, r, r3; | |
101 | + Int32 stackLo[FALLBACK_QSORT_STACK_SIZE]; | |
102 | + Int32 stackHi[FALLBACK_QSORT_STACK_SIZE]; | |
103 | + | |
104 | + r = 0; | |
105 | + | |
106 | + sp = 0; | |
107 | + fpush ( loSt, hiSt ); | |
108 | + | |
109 | + while (sp > 0) { | |
110 | + | |
111 | + AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 ); | |
112 | + | |
113 | + fpop ( lo, hi ); | |
114 | + if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { | |
115 | + fallbackSimpleSort ( fmap, eclass, lo, hi ); | |
116 | + continue; | |
117 | + } | |
118 | + | |
119 | + /* Random partitioning. Median of 3 sometimes fails to | |
120 | + avoid bad cases. Median of 9 seems to help but | |
121 | + looks rather expensive. This too seems to work but | |
122 | + is cheaper. Guidance for the magic constants | |
123 | + 7621 and 32768 is taken from Sedgewick's algorithms | |
124 | + book, chapter 35. | |
125 | + */ | |
126 | + r = ((r * 7621) + 1) % 32768; | |
127 | + r3 = r % 3; | |
128 | + if (r3 == 0) med = eclass[fmap[lo]]; else | |
129 | + if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else | |
130 | + med = eclass[fmap[hi]]; | |
131 | + | |
132 | + unLo = ltLo = lo; | |
133 | + unHi = gtHi = hi; | |
134 | + | |
135 | + while (1) { | |
136 | + while (1) { | |
137 | + if (unLo > unHi) break; | |
138 | + n = (Int32)eclass[fmap[unLo]] - (Int32)med; | |
139 | + if (n == 0) { | |
140 | + fswap(fmap[unLo], fmap[ltLo]); | |
141 | + ltLo++; unLo++; | |
142 | + continue; | |
143 | + }; | |
144 | + if (n > 0) break; | |
145 | + unLo++; | |
146 | + } | |
147 | + while (1) { | |
148 | + if (unLo > unHi) break; | |
149 | + n = (Int32)eclass[fmap[unHi]] - (Int32)med; | |
150 | + if (n == 0) { | |
151 | + fswap(fmap[unHi], fmap[gtHi]); | |
152 | + gtHi--; unHi--; | |
153 | + continue; | |
154 | + }; | |
155 | + if (n < 0) break; | |
156 | + unHi--; | |
157 | + } | |
158 | + if (unLo > unHi) break; | |
159 | + fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; | |
160 | + } | |
161 | + | |
162 | + AssertD ( unHi == unLo-1, "fallbackQSort3(2)" ); | |
163 | + | |
164 | + if (gtHi < ltLo) continue; | |
165 | + | |
166 | + n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); | |
167 | + m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); | |
168 | + | |
169 | + n = lo + unLo - ltLo - 1; | |
170 | + m = hi - (gtHi - unHi) + 1; | |
171 | + | |
172 | + if (n - lo > hi - m) { | |
173 | + fpush ( lo, n ); | |
174 | + fpush ( m, hi ); | |
175 | + } else { | |
176 | + fpush ( m, hi ); | |
177 | + fpush ( lo, n ); | |
178 | + } | |
179 | + } | |
180 | +} | |
181 | + | |
182 | +#undef fmin | |
183 | +#undef fpush | |
184 | +#undef fpop | |
185 | +#undef fswap | |
186 | +#undef fvswap | |
187 | +#undef FALLBACK_QSORT_SMALL_THRESH | |
188 | +#undef FALLBACK_QSORT_STACK_SIZE | |
189 | + | |
190 | + | |
191 | +/*---------------------------------------------*/ | |
192 | +/* Pre: | |
193 | + nblock > 0 | |
194 | + eclass exists for [0 .. nblock-1] | |
195 | + ((UChar*)eclass) [0 .. nblock-1] holds block | |
196 | + ptr exists for [0 .. nblock-1] | |
197 | + | |
198 | + Post: | |
199 | + ((UChar*)eclass) [0 .. nblock-1] holds block | |
200 | + All other areas of eclass destroyed | |
201 | + fmap [0 .. nblock-1] holds sorted order | |
202 | + bhtab [ 0 .. 2+(nblock/32) ] destroyed | |
203 | +*/ | |
204 | + | |
205 | +#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) | |
206 | +#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) | |
207 | +#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) | |
208 | +#define WORD_BH(zz) bhtab[(zz) >> 5] | |
209 | +#define UNALIGNED_BH(zz) ((zz) & 0x01f) | |
210 | + | |
211 | +static | |
212 | +void fallbackSort ( UInt32* fmap, | |
213 | + UInt32* eclass, | |
214 | + UInt32* bhtab, | |
215 | + Int32 nblock, | |
216 | + Int32 verb ) | |
217 | +{ | |
218 | + Int32 ftab[257]; | |
219 | + Int32 ftabCopy[256]; | |
220 | + Int32 H, i, j, k, l, r, cc, cc1; | |
221 | + Int32 nNotDone; | |
222 | + Int32 nBhtab; | |
223 | + UChar* eclass8 = (UChar*)eclass; | |
224 | + | |
225 | + /*-- | |
226 | + Initial 1-char radix sort to generate | |
227 | + initial fmap and initial BH bits. | |
228 | + --*/ | |
229 | + if (verb >= 4) | |
230 | + VPrintf0 ( " bucket sorting ...\n" ); | |
231 | + for (i = 0; i < 257; i++) ftab[i] = 0; | |
232 | + for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; | |
233 | + for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; | |
234 | + for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; | |
235 | + | |
236 | + for (i = 0; i < nblock; i++) { | |
237 | + j = eclass8[i]; | |
238 | + k = ftab[j] - 1; | |
239 | + ftab[j] = k; | |
240 | + fmap[k] = i; | |
241 | + } | |
242 | + | |
243 | + nBhtab = 2 + (nblock / 32); | |
244 | + for (i = 0; i < nBhtab; i++) bhtab[i] = 0; | |
245 | + for (i = 0; i < 256; i++) SET_BH(ftab[i]); | |
246 | + | |
247 | + /*-- | |
248 | + Inductively refine the buckets. Kind-of an | |
249 | + "exponential radix sort" (!), inspired by the | |
250 | + Manber-Myers suffix array construction algorithm. | |
251 | + --*/ | |
252 | + | |
253 | + /*-- set sentinel bits for block-end detection --*/ | |
254 | + for (i = 0; i < 32; i++) { | |
255 | + SET_BH(nblock + 2*i); | |
256 | + CLEAR_BH(nblock + 2*i + 1); | |
257 | + } | |
258 | + | |
259 | + /*-- the log(N) loop --*/ | |
260 | + H = 1; | |
261 | + while (1) { | |
262 | + | |
263 | + if (verb >= 4) | |
264 | + VPrintf1 ( " depth %6d has ", H ); | |
265 | + | |
266 | + j = 0; | |
267 | + for (i = 0; i < nblock; i++) { | |
268 | + if (ISSET_BH(i)) j = i; | |
269 | + k = fmap[i] - H; if (k < 0) k += nblock; | |
270 | + eclass[k] = j; | |
271 | + } | |
272 | + | |
273 | + nNotDone = 0; | |
274 | + r = -1; | |
275 | + while (1) { | |
276 | + | |
277 | + /*-- find the next non-singleton bucket --*/ | |
278 | + k = r + 1; | |
279 | + while (ISSET_BH(k) && UNALIGNED_BH(k)) k++; | |
280 | + if (ISSET_BH(k)) { | |
281 | + while (WORD_BH(k) == 0xffffffff) k += 32; | |
282 | + while (ISSET_BH(k)) k++; | |
283 | + } | |
284 | + l = k - 1; | |
285 | + if (l >= nblock) break; | |
286 | + while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++; | |
287 | + if (!ISSET_BH(k)) { | |
288 | + while (WORD_BH(k) == 0x00000000) k += 32; | |
289 | + while (!ISSET_BH(k)) k++; | |
290 | + } | |
291 | + r = k - 1; | |
292 | + if (r >= nblock) break; | |
293 | + | |
294 | + /*-- now [l, r] bracket current bucket --*/ | |
295 | + if (r > l) { | |
296 | + nNotDone += (r - l + 1); | |
297 | + fallbackQSort3 ( fmap, eclass, l, r ); | |
298 | + | |
299 | + /*-- scan bucket and generate header bits-- */ | |
300 | + cc = -1; | |
301 | + for (i = l; i <= r; i++) { | |
302 | + cc1 = eclass[fmap[i]]; | |
303 | + if (cc != cc1) { SET_BH(i); cc = cc1; }; | |
304 | + } | |
305 | + } | |
306 | + } | |
307 | + | |
308 | + if (verb >= 4) | |
309 | + VPrintf1 ( "%6d unresolved strings\n", nNotDone ); | |
310 | + | |
311 | + H *= 2; | |
312 | + if (H > nblock || nNotDone == 0) break; | |
313 | + } | |
314 | + | |
315 | + /*-- | |
316 | + Reconstruct the original block in | |
317 | + eclass8 [0 .. nblock-1], since the | |
318 | + previous phase destroyed it. | |
319 | + --*/ | |
320 | + if (verb >= 4) | |
321 | + VPrintf0 ( " reconstructing block ...\n" ); | |
322 | + j = 0; | |
323 | + for (i = 0; i < nblock; i++) { | |
324 | + while (ftabCopy[j] == 0) j++; | |
325 | + ftabCopy[j]--; | |
326 | + eclass8[fmap[i]] = (UChar)j; | |
327 | + } | |
328 | + AssertH ( j < 256, 1005 ); | |
329 | +} | |
330 | + | |
331 | +#undef SET_BH | |
332 | +#undef CLEAR_BH | |
333 | +#undef ISSET_BH | |
334 | +#undef WORD_BH | |
335 | +#undef UNALIGNED_BH | |
336 | + | |
337 | + | |
338 | +/*---------------------------------------------*/ | |
339 | +/*--- The main, O(N^2 log(N)) sorting ---*/ | |
340 | +/*--- algorithm. Faster for "normal" ---*/ | |
341 | +/*--- non-repetitive blocks. ---*/ | |
342 | +/*---------------------------------------------*/ | |
343 | + | |
344 | +/*---------------------------------------------*/ | |
345 | +static | |
346 | +__inline__ | |
347 | +Bool mainGtU ( UInt32 i1, | |
348 | + UInt32 i2, | |
349 | + UChar* block, | |
350 | + UInt16* quadrant, | |
351 | + UInt32 nblock, | |
352 | + Int32* budget ) | |
353 | +{ | |
354 | + Int32 k; | |
355 | + UChar c1, c2; | |
356 | + UInt16 s1, s2; | |
357 | + | |
358 | + AssertD ( i1 != i2, "mainGtU" ); | |
359 | + /* 1 */ | |
360 | + c1 = block[i1]; c2 = block[i2]; | |
361 | + if (c1 != c2) return (c1 > c2); | |
362 | + i1++; i2++; | |
363 | + /* 2 */ | |
364 | + c1 = block[i1]; c2 = block[i2]; | |
365 | + if (c1 != c2) return (c1 > c2); | |
366 | + i1++; i2++; | |
367 | + /* 3 */ | |
368 | + c1 = block[i1]; c2 = block[i2]; | |
369 | + if (c1 != c2) return (c1 > c2); | |
370 | + i1++; i2++; | |
371 | + /* 4 */ | |
372 | + c1 = block[i1]; c2 = block[i2]; | |
373 | + if (c1 != c2) return (c1 > c2); | |
374 | + i1++; i2++; | |
375 | + /* 5 */ | |
376 | + c1 = block[i1]; c2 = block[i2]; | |
377 | + if (c1 != c2) return (c1 > c2); | |
378 | + i1++; i2++; | |
379 | + /* 6 */ | |
380 | + c1 = block[i1]; c2 = block[i2]; | |
381 | + if (c1 != c2) return (c1 > c2); | |
382 | + i1++; i2++; | |
383 | + /* 7 */ | |
384 | + c1 = block[i1]; c2 = block[i2]; | |
385 | + if (c1 != c2) return (c1 > c2); | |
386 | + i1++; i2++; | |
387 | + /* 8 */ | |
388 | + c1 = block[i1]; c2 = block[i2]; | |
389 | + if (c1 != c2) return (c1 > c2); | |
390 | + i1++; i2++; | |
391 | + /* 9 */ | |
392 | + c1 = block[i1]; c2 = block[i2]; | |
393 | + if (c1 != c2) return (c1 > c2); | |
394 | + i1++; i2++; | |
395 | + /* 10 */ | |
396 | + c1 = block[i1]; c2 = block[i2]; | |
397 | + if (c1 != c2) return (c1 > c2); | |
398 | + i1++; i2++; | |
399 | + /* 11 */ | |
400 | + c1 = block[i1]; c2 = block[i2]; | |
401 | + if (c1 != c2) return (c1 > c2); | |
402 | + i1++; i2++; | |
403 | + /* 12 */ | |
404 | + c1 = block[i1]; c2 = block[i2]; | |
405 | + if (c1 != c2) return (c1 > c2); | |
406 | + i1++; i2++; | |
407 | + | |
408 | + k = nblock + 8; | |
409 | + | |
410 | + do { | |
411 | + /* 1 */ | |
412 | + c1 = block[i1]; c2 = block[i2]; | |
413 | + if (c1 != c2) return (c1 > c2); | |
414 | + s1 = quadrant[i1]; s2 = quadrant[i2]; | |
415 | + if (s1 != s2) return (s1 > s2); | |
416 | + i1++; i2++; | |
417 | + /* 2 */ | |
418 | + c1 = block[i1]; c2 = block[i2]; | |
419 | + if (c1 != c2) return (c1 > c2); | |
420 | + s1 = quadrant[i1]; s2 = quadrant[i2]; | |
421 | + if (s1 != s2) return (s1 > s2); | |
422 | + i1++; i2++; | |
423 | + /* 3 */ | |
424 | + c1 = block[i1]; c2 = block[i2]; | |
425 | + if (c1 != c2) return (c1 > c2); | |
426 | + s1 = quadrant[i1]; s2 = quadrant[i2]; | |
427 | + if (s1 != s2) return (s1 > s2); | |
428 | + i1++; i2++; | |
429 | + /* 4 */ | |
430 | + c1 = block[i1]; c2 = block[i2]; | |
431 | + if (c1 != c2) return (c1 > c2); | |
432 | + s1 = quadrant[i1]; s2 = quadrant[i2]; | |
433 | + if (s1 != s2) return (s1 > s2); | |
434 | + i1++; i2++; | |
435 | + /* 5 */ | |
436 | + c1 = block[i1]; c2 = block[i2]; | |
437 | + if (c1 != c2) return (c1 > c2); | |
438 | + s1 = quadrant[i1]; s2 = quadrant[i2]; | |
439 | + if (s1 != s2) return (s1 > s2); | |
440 | + i1++; i2++; | |
441 | + /* 6 */ | |
442 | + c1 = block[i1]; c2 = block[i2]; | |
443 | + if (c1 != c2) return (c1 > c2); | |
444 | + s1 = quadrant[i1]; s2 = quadrant[i2]; | |
445 | + if (s1 != s2) return (s1 > s2); | |
446 | + i1++; i2++; | |
447 | + /* 7 */ | |
448 | + c1 = block[i1]; c2 = block[i2]; | |
449 | + if (c1 != c2) return (c1 > c2); | |
450 | + s1 = quadrant[i1]; s2 = quadrant[i2]; | |
451 | + if (s1 != s2) return (s1 > s2); | |
452 | + i1++; i2++; | |
453 | + /* 8 */ | |
454 | + c1 = block[i1]; c2 = block[i2]; | |
455 | + if (c1 != c2) return (c1 > c2); | |
456 | + s1 = quadrant[i1]; s2 = quadrant[i2]; | |
457 | + if (s1 != s2) return (s1 > s2); | |
458 | + i1++; i2++; | |
459 | + | |
460 | + if (i1 >= nblock) i1 -= nblock; | |
461 | + if (i2 >= nblock) i2 -= nblock; | |
462 | + | |
463 | + k -= 8; | |
464 | + (*budget)--; | |
465 | + } | |
466 | + while (k >= 0); | |
467 | + | |
468 | + return False; | |
469 | +} | |
470 | + | |
471 | + | |
472 | +/*---------------------------------------------*/ | |
473 | +/*-- | |
474 | + Knuth's increments seem to work better | |
475 | + than Incerpi-Sedgewick here. Possibly | |
476 | + because the number of elems to sort is | |
477 | + usually small, typically <= 20. | |
478 | +--*/ | |
479 | +static | |
480 | +Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, | |
481 | + 9841, 29524, 88573, 265720, | |
482 | + 797161, 2391484 }; | |
483 | + | |
484 | +static | |
485 | +void mainSimpleSort ( UInt32* ptr, | |
486 | + UChar* block, | |
487 | + UInt16* quadrant, | |
488 | + Int32 nblock, | |
489 | + Int32 lo, | |
490 | + Int32 hi, | |
491 | + Int32 d, | |
492 | + Int32* budget ) | |
493 | +{ | |
494 | + Int32 i, j, h, bigN, hp; | |
495 | + UInt32 v; | |
496 | + | |
497 | + bigN = hi - lo + 1; | |
498 | + if (bigN < 2) return; | |
499 | + | |
500 | + hp = 0; | |
501 | + while (incs[hp] < bigN) hp++; | |
502 | + hp--; | |
503 | + | |
504 | + for (; hp >= 0; hp--) { | |
505 | + h = incs[hp]; | |
506 | + | |
507 | + i = lo + h; | |
508 | + while (True) { | |
509 | + | |
510 | + /*-- copy 1 --*/ | |
511 | + if (i > hi) break; | |
512 | + v = ptr[i]; | |
513 | + j = i; | |
514 | + while ( mainGtU ( | |
515 | + ptr[j-h]+d, v+d, block, quadrant, nblock, budget | |
516 | + ) ) { | |
517 | + ptr[j] = ptr[j-h]; | |
518 | + j = j - h; | |
519 | + if (j <= (lo + h - 1)) break; | |
520 | + } | |
521 | + ptr[j] = v; | |
522 | + i++; | |
523 | + | |
524 | + /*-- copy 2 --*/ | |
525 | + if (i > hi) break; | |
526 | + v = ptr[i]; | |
527 | + j = i; | |
528 | + while ( mainGtU ( | |
529 | + ptr[j-h]+d, v+d, block, quadrant, nblock, budget | |
530 | + ) ) { | |
531 | + ptr[j] = ptr[j-h]; | |
532 | + j = j - h; | |
533 | + if (j <= (lo + h - 1)) break; | |
534 | + } | |
535 | + ptr[j] = v; | |
536 | + i++; | |
537 | + | |
538 | + /*-- copy 3 --*/ | |
539 | + if (i > hi) break; | |
540 | + v = ptr[i]; | |
541 | + j = i; | |
542 | + while ( mainGtU ( | |
543 | + ptr[j-h]+d, v+d, block, quadrant, nblock, budget | |
544 | + ) ) { | |
545 | + ptr[j] = ptr[j-h]; | |
546 | + j = j - h; | |
547 | + if (j <= (lo + h - 1)) break; | |
548 | + } | |
549 | + ptr[j] = v; | |
550 | + i++; | |
551 | + | |
552 | + if (*budget < 0) return; | |
553 | + } | |
554 | + } | |
555 | +} | |
556 | + | |
557 | + | |
558 | +/*---------------------------------------------*/ | |
559 | +/*-- | |
560 | + The following is an implementation of | |
561 | + an elegant 3-way quicksort for strings, | |
562 | + described in a paper "Fast Algorithms for | |
563 | + Sorting and Searching Strings", by Robert | |
564 | + Sedgewick and Jon L. Bentley. | |
565 | +--*/ | |
566 | + | |
567 | +#define mswap(zz1, zz2) \ | |
568 | + { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } | |
569 | + | |
570 | +#define mvswap(zzp1, zzp2, zzn) \ | |
571 | +{ \ | |
572 | + Int32 yyp1 = (zzp1); \ | |
573 | + Int32 yyp2 = (zzp2); \ | |
574 | + Int32 yyn = (zzn); \ | |
575 | + while (yyn > 0) { \ | |
576 | + mswap(ptr[yyp1], ptr[yyp2]); \ | |
577 | + yyp1++; yyp2++; yyn--; \ | |
578 | + } \ | |
579 | +} | |
580 | + | |
581 | +static | |
582 | +__inline__ | |
583 | +UChar mmed3 ( UChar a, UChar b, UChar c ) | |
584 | +{ | |
585 | + UChar t; | |
586 | + if (a > b) { t = a; a = b; b = t; }; | |
587 | + if (b > c) { | |
588 | + b = c; | |
589 | + if (a > b) b = a; | |
590 | + } | |
591 | + return b; | |
592 | +} | |
593 | + | |
594 | +#define mmin(a,b) ((a) < (b)) ? (a) : (b) | |
595 | + | |
596 | +#define mpush(lz,hz,dz) { stackLo[sp] = lz; \ | |
597 | + stackHi[sp] = hz; \ | |
598 | + stackD [sp] = dz; \ | |
599 | + sp++; } | |
600 | + | |
601 | +#define mpop(lz,hz,dz) { sp--; \ | |
602 | + lz = stackLo[sp]; \ | |
603 | + hz = stackHi[sp]; \ | |
604 | + dz = stackD [sp]; } | |
605 | + | |
606 | + | |
607 | +#define mnextsize(az) (nextHi[az]-nextLo[az]) | |
608 | + | |
609 | +#define mnextswap(az,bz) \ | |
610 | + { Int32 tz; \ | |
611 | + tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ | |
612 | + tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ | |
613 | + tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } | |
614 | + | |
615 | + | |
616 | +#define MAIN_QSORT_SMALL_THRESH 20 | |
617 | +#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) | |
618 | +#define MAIN_QSORT_STACK_SIZE 100 | |
619 | + | |
620 | +static | |
621 | +void mainQSort3 ( UInt32* ptr, | |
622 | + UChar* block, | |
623 | + UInt16* quadrant, | |
624 | + Int32 nblock, | |
625 | + Int32 loSt, | |
626 | + Int32 hiSt, | |
627 | + Int32 dSt, | |
628 | + Int32* budget ) | |
629 | +{ | |
630 | + Int32 unLo, unHi, ltLo, gtHi, n, m, med; | |
631 | + Int32 sp, lo, hi, d; | |
632 | + | |
633 | + Int32 stackLo[MAIN_QSORT_STACK_SIZE]; | |
634 | + Int32 stackHi[MAIN_QSORT_STACK_SIZE]; | |
635 | + Int32 stackD [MAIN_QSORT_STACK_SIZE]; | |
636 | + | |
637 | + Int32 nextLo[3]; | |
638 | + Int32 nextHi[3]; | |
639 | + Int32 nextD [3]; | |
640 | + | |
641 | + sp = 0; | |
642 | + mpush ( loSt, hiSt, dSt ); | |
643 | + | |
644 | + while (sp > 0) { | |
645 | + | |
646 | + AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 ); | |
647 | + | |
648 | + mpop ( lo, hi, d ); | |
649 | + if (hi - lo < MAIN_QSORT_SMALL_THRESH || | |
650 | + d > MAIN_QSORT_DEPTH_THRESH) { | |
651 | + mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget ); | |
652 | + if (*budget < 0) return; | |
653 | + continue; | |
654 | + } | |
655 | + | |
656 | + med = (Int32) | |
657 | + mmed3 ( block[ptr[ lo ]+d], | |
658 | + block[ptr[ hi ]+d], | |
659 | + block[ptr[ (lo+hi)>>1 ]+d] ); | |
660 | + | |
661 | + unLo = ltLo = lo; | |
662 | + unHi = gtHi = hi; | |
663 | + | |
664 | + while (True) { | |
665 | + while (True) { | |
666 | + if (unLo > unHi) break; | |
667 | + n = ((Int32)block[ptr[unLo]+d]) - med; | |
668 | + if (n == 0) { | |
669 | + mswap(ptr[unLo], ptr[ltLo]); | |
670 | + ltLo++; unLo++; continue; | |
671 | + }; | |
672 | + if (n > 0) break; | |
673 | + unLo++; | |
674 | + } | |
675 | + while (True) { | |
676 | + if (unLo > unHi) break; | |
677 | + n = ((Int32)block[ptr[unHi]+d]) - med; | |
678 | + if (n == 0) { | |
679 | + mswap(ptr[unHi], ptr[gtHi]); | |
680 | + gtHi--; unHi--; continue; | |
681 | + }; | |
682 | + if (n < 0) break; | |
683 | + unHi--; | |
684 | + } | |
685 | + if (unLo > unHi) break; | |
686 | + mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--; | |
687 | + } | |
688 | + | |
689 | + AssertD ( unHi == unLo-1, "mainQSort3(2)" ); | |
690 | + | |
691 | + if (gtHi < ltLo) { | |
692 | + mpush(lo, hi, d+1 ); | |
693 | + continue; | |
694 | + } | |
695 | + | |
696 | + n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); | |
697 | + m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); | |
698 | + | |
699 | + n = lo + unLo - ltLo - 1; | |
700 | + m = hi - (gtHi - unHi) + 1; | |
701 | + | |
702 | + nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; | |
703 | + nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; | |
704 | + nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; | |
705 | + | |
706 | + if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); | |
707 | + if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); | |
708 | + if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); | |
709 | + | |
710 | + AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" ); | |
711 | + AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" ); | |
712 | + | |
713 | + mpush (nextLo[0], nextHi[0], nextD[0]); | |
714 | + mpush (nextLo[1], nextHi[1], nextD[1]); | |
715 | + mpush (nextLo[2], nextHi[2], nextD[2]); | |
716 | + } | |
717 | +} | |
718 | + | |
719 | +#undef mswap | |
720 | +#undef mvswap | |
721 | +#undef mpush | |
722 | +#undef mpop | |
723 | +#undef mmin | |
724 | +#undef mnextsize | |
725 | +#undef mnextswap | |
726 | +#undef MAIN_QSORT_SMALL_THRESH | |
727 | +#undef MAIN_QSORT_DEPTH_THRESH | |
728 | +#undef MAIN_QSORT_STACK_SIZE | |
729 | + | |
730 | + | |
731 | +/*---------------------------------------------*/ | |
732 | +/* Pre: | |
733 | + nblock > N_OVERSHOOT | |
734 | + block32 exists for [0 .. nblock-1 +N_OVERSHOOT] | |
735 | + ((UChar*)block32) [0 .. nblock-1] holds block | |