diff --git a/Makefile.in b/Makefile.in
index 1981dbe..4c4adac 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -223,7 +223,7 @@ BASE_CPPFLAGS = -I. -I./lzma -I./lzfx -I./lz4 -I./rabin -I./bsdiff -DNODEFAULT_P
-I./crypto/xsalsa20 -I./archive -pedantic -Wall -I./filters -fno-strict-aliasing \
-Wno-unused-but-set-variable -Wno-enum-compare \
@COMPAT_CPPFLAGS@ @XSALSA20_DEBUG@ @LIBARCHIVE_INC@ -I./filters/packjpg
-COMMON_CPPFLAGS = $(BASE_CPPFLAGS) -std=gnu99
+COMMON_CPPFLAGS = $(BASE_CPPFLAGS) -std=gnu99
COMMON_CPPFLAGS_cpp = $(BASE_CPPFLAGS)
COMMON_VEC_FLAGS = -ftree-vectorize
COMMON_LOOP_OPTFLAGS = $(VEC_FLAGS) -floop-interchange -floop-block
diff --git a/archive/pc_arc_filter.c b/archive/pc_arc_filter.c
index d0f6aa0..bef96b2 100644
--- a/archive/pc_arc_filter.c
+++ b/archive/pc_arc_filter.c
@@ -20,7 +20,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
/*
@@ -42,23 +42,28 @@
#include "pc_arc_filter.h"
#include "pc_archive.h"
-#define PACKJPG_DEF_BUFSIZ (512 * 1024)
-#define JPG_SIZE_LIMIT (8 * 1024 * 1024)
-#define PJG_APPVERSION1 (25)
-#define PJG_APPVERSION2 (25)
+#ifndef _MPLV2_LICENSE_
+# define PACKJPG_DEF_BUFSIZ (512 * 1024)
+# define JPG_SIZE_LIMIT (8 * 1024 * 1024)
+# define PJG_APPVERSION1 (25)
+# define PJG_APPVERSION2 (25)
+#endif
struct scratch_buffer {
uchar_t *in_buff;
size_t in_bufflen;
};
+#ifndef _MPLV2_LICENSE_
extern size_t packjpg_filter_process(uchar_t *in_buf, size_t len, uchar_t **out_buf);
ssize_t packjpg_filter(struct filter_info *fi, void *filter_private);
+#endif
void
add_filters_by_type(struct type_data *typetab, struct filter_flags *ff)
{
+#ifndef _MPLV2_LICENSE_
struct scratch_buffer *sdat;
int slot;
@@ -72,6 +77,7 @@ add_filters_by_type(struct type_data *typetab, struct filter_flags *ff)
typetab[slot].filter_func = packjpg_filter;
typetab[slot].filter_name = "packJPG";
}
+#endif
}
static void
@@ -138,6 +144,7 @@ write_archive_data(struct archive *aw, uchar_t *out_buf, size_t len, int block_s
return (tot);
}
+#ifndef _MPLV2_LICENSE_
int
pjg_version_supported(char ver)
{
@@ -252,4 +259,5 @@ packjpg_filter(struct filter_info *fi, void *filter_private)
free(out);
return (rv);
}
+#endif
diff --git a/archive/pc_arc_filter.h b/archive/pc_arc_filter.h
index 211d087..d7ab33f 100644
--- a/archive/pc_arc_filter.h
+++ b/archive/pc_arc_filter.h
@@ -20,7 +20,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
#ifndef _PC_ARCHIVE_FILTER_H
@@ -67,4 +67,4 @@ void add_filters_by_type(struct type_data *typetab, struct filter_flags *ff);
}
#endif
-#endif
+#endif
diff --git a/archive/pc_archive.c b/archive/pc_archive.c
index 8ea1803..9226c46 100644
--- a/archive/pc_archive.c
+++ b/archive/pc_archive.c
@@ -20,7 +20,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
/*
diff --git a/archive/pjpg_helper.cpp b/archive/pjpg_helper.cpp
index b82c32d..ab25f72 100644
--- a/archive/pjpg_helper.cpp
+++ b/archive/pjpg_helper.cpp
@@ -20,7 +20,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
/*
@@ -32,6 +32,8 @@
#include
#include
#include
+
+#ifndef _MPLV2_LICENSE_
#include
#ifdef __cplusplus
@@ -104,3 +106,4 @@ packjpg_filter_process(uchar_t *in_buf, size_t len, uchar_t **out_buf)
#ifdef __cplusplus
}
#endif
+#endif
diff --git a/config b/config
index de7434c..08697e1 100755
--- a/config
+++ b/config
@@ -20,6 +20,8 @@
# moinakg@belenix.org, http://moinakg.wordpress.com/
#
+my_license=LGPLv3
+
usage() {
prog=$1
cat << _EOF
@@ -40,9 +42,12 @@ ${prog} []
Enable building against an alternate Bzip2 and library installation.
--with-libarchive= (Default: System)
Enable building against an alternate libarchive installation.
+--with-external-libbsc=
+ Enable building with exernal libbsc sources. Can be used to link with
+ ASLv2 libbsc when using MPLv2 licensed sources.
--no-sse-detect Do NOT attempt to probe the system's SSE capability for build flags.
Implies '--no-avx-detect' below.
---no-avx-detect Do NOT attempt to probe the system's AVX apability for build flags.
+--no-avx-detect Do NOT attempt to probe the system's AVX capability for build flags.
--no-1.3-archive-compat Disable compatibility with compressed archives created with Pcompress
version 1.3 (default: retain compatibility). Hash formats changed from
version 1.3 to 1.4 so this option is required if files created using
@@ -60,12 +65,16 @@ debug=0
allocator=1
debug_stats=0
prefix=/usr
-libbsc_dir=./bsc
-libbsc_lib=${libbsc_dir}/libbsc.a
-libbsclflags='\$\(LIBBSCLFLAGS\)'
-libbscwrapobj='\$\(LIBBSCWRAPOBJ\)'
-libbscgenopt='\$\(LIBBSCGEN_OPT\)'
-libbsccppflags='\$\(LIBBSCCPPFLAGS\)'
+
+if [ "$my_license" = "LGPLv3" ]
+then
+ libbsc_dir=./bsc
+ libbsc_lib=${libbsc_dir}/libbsc.a
+ libbsclflags='\$\(LIBBSCLFLAGS\)'
+ libbscwrapobj='\$\(LIBBSCWRAPOBJ\)'
+ libbscgenopt='\$\(LIBBSCGEN_OPT\)'
+ libbsccppflags='\$\(LIBBSCCPPFLAGS\)'
+fi
openssl_prefix=
openssl_libdir=
openssl_incdir=
@@ -195,6 +204,14 @@ do
--with-libarchive=*)
libarchive_prefix=`echo ${arg1} | cut -f2 -d"="`
;;
+ --with-external-libbsc)
+ libbsc_dir=`echo ${arg1} | cut -f2 -d"="`
+ libbsc_lib=${libbsc_dir}/libbsc.a
+ libbsclflags='\$\(LIBBSCLFLAGS\)'
+ libbscwrapobj='\$\(LIBBSCWRAPOBJ\)'
+ libbscgenopt='\$\(LIBBSCGEN_OPT\)'
+ libbsccppflags='\$\(LIBBSCCPPFLAGS\)'
+ ;;
--use-key256)
keylen='-DDEFAULT_KEYLEN=16'
;;
diff --git a/filters/lzp/lzp.c b/filters/lzp/lzp.c
index 706a20a..06dffbd 100644
--- a/filters/lzp/lzp.c
+++ b/filters/lzp/lzp.c
@@ -20,7 +20,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
/*-----------------------------------------------------------*/
diff --git a/libbsc_compress.c b/libbsc_compress.c
index 21fed2f..9658924 100644
--- a/libbsc_compress.c
+++ b/libbsc_compress.c
@@ -20,7 +20,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
#include
@@ -150,7 +150,7 @@ int
libbsc_deinit(void **data)
{
struct libbsc_params *bscdat = (struct libbsc_params *)(*data);
-
+
if (bscdat) {
slab_free(NULL, bscdat);
}
diff --git a/pcompress.c b/pcompress.c
index 8553608..c21b9f5 100644
--- a/pcompress.c
+++ b/pcompress.c
@@ -78,7 +78,8 @@ usage(pc_ctx_t *pctx)
{
fprintf(stderr,
-"\nPcompress Version %s\n\n"
+"\nPcompress Version %s\n"
+"License: %s\n\n"
"See README.md for detailed usage.\n\n"
"Standard Usage\n"
"==============\n"
@@ -144,7 +145,7 @@ usage(pc_ctx_t *pctx)
" Default output name if omitted: .out\n\n"
" If Archiving was done then this should be the name of a directory into which\n"
" extracted files are restored. Default if omitted: Current directory.\n\n",
- UTILITY_VERSION, pctx->exec_name, pctx->exec_name, pctx->exec_name);
+ UTILITY_VERSION, LICENSE_STRING, pctx->exec_name, pctx->exec_name, pctx->exec_name);
fprintf(stderr,
" Encryption\n"
" ----------\n"
@@ -187,10 +188,10 @@ show_compression_stats(pc_ctx_t *pctx)
/*
* Wrapper functions to pre-process the buffer and then call the main compression routine.
* At present only LZP pre-compression is used below. Some extra metadata is added:
- *
+ *
* Byte 0: A flag to indicate which pre-processor was used.
* Byte 1 - Byte 8: Size of buffer after pre-processing
- *
+ *
* It is possible for a buffer to be only pre-processed and not compressed by the final
* algorithm if the final one fails to compress for some reason. However the vice versa
* is not allowed.
@@ -234,6 +235,7 @@ preproc_compress(pc_ctx_t *pctx, compress_func_ptr cmp_func, void *src, uint64_t
}
}
+#ifndef _MPLV2_LICENSE_
if (pctx->lzp_preprocess && stype != TYPE_BMP && stype != TYPE_TIFF) {
int hashsize;
@@ -249,6 +251,7 @@ preproc_compress(pc_ctx_t *pctx, compress_func_ptr cmp_func, void *src, uint64_t
type |= PREPROC_TYPE_LZP;
}
}
+#endif
if (pctx->enable_delta2_encode && props->delta2_span > 0 &&
stype != TYPE_DNA_SEQ && stype != TYPE_BMP &&
@@ -349,6 +352,7 @@ preproc_decompress(pc_ctx_t *pctx, compress_func_ptr dec_func, void *src, uint64
}
if (type & PREPROC_TYPE_LZP) {
+#ifndef _MPLV2_LICENSE_
int hashsize;
hashsize = lzp_hash_size(level);
result = lzp_decompress((const uchar_t *)src, (uchar_t *)dst, srclen,
@@ -362,6 +366,10 @@ preproc_decompress(pc_ctx_t *pctx, compress_func_ptr dec_func, void *src, uint64
log_msg(LOG_ERR, 0, "LZP decompression failed.");
return (result);
}
+#else
+ log_msg(LOG_ERR, 0, "LZP feature not available in this build (MPLv2). Aborting.");
+ return (-1);
+#endif
}
if (type & PREPROC_TYPE_DISPACK) {
@@ -2960,10 +2968,12 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[])
pctx->enable_rabin_split = 0;
break;
+#ifndef _MPLV2_LICENSE_
case 'L':
pctx->advanced_opts = 1;
pctx->lzp_preprocess = 1;
break;
+#endif
case 'P':
pctx->advanced_opts = 1;
diff --git a/pcompress.h b/pcompress.h
index fcac6fc..601f5b3 100644
--- a/pcompress.h
+++ b/pcompress.h
@@ -20,7 +20,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
#ifndef _PCOMPRESS_H
@@ -49,6 +49,12 @@ extern "C" {
#define MASK_CRYPTO_ALG 0x30
#define MAX_LEVEL 14
+#ifndef _MPLV2_LICENSE_
+#define LICENSE_STRING "LGPLv3"
+#else
+#define LICENSE_STRING "MPLv2"
+#endif
+
#define COMPRESSED 1
#define UNCOMPRESSED 0
#define CHSIZE_MASK 0x80
diff --git a/rabin/global/index.c b/rabin/global/index.c
index 3e7b926..64f8d0b 100644
--- a/rabin/global/index.c
+++ b/rabin/global/index.c
@@ -76,9 +76,12 @@ init_global_db(char *configfile)
int
init_on_disk_index(archive_config_t *cfg)
{
+#if 0
if (file_exists()) {
}
+#endif
+ return (0);
}
void
diff --git a/rabin/rabin_dedup.c b/rabin/rabin_dedup.c
index ec8b775..6979cf5 100755
--- a/rabin/rabin_dedup.c
+++ b/rabin/rabin_dedup.c
@@ -1,27 +1,27 @@
/*
* The rabin polynomial computation is derived from:
* http://code.google.com/p/rabin-fingerprint-c/
- *
+ *
* originally created by Joel Lawrence Tucci on 09-March-2011.
- *
+ *
* Rabin polynomial portions Copyright (c) 2011 Joel Lawrence Tucci
* 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.
- *
+ *
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ *
* Neither the name of the project's author nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@@ -58,7 +58,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
#ifndef __STDC_FORMAT_MACROS
@@ -75,6 +75,9 @@
#include
#include
#include
+
+#define QSORT_LT(a, b) ((*a)<(*b))
+#define QSORT_TYPE uint64_t
#include
#include "rabin_dedup.h"
@@ -445,11 +448,10 @@ isort_uint64(uint64_t *ary, uint32_t nitems)
* Sort an array of 64-bit unsigned integers. The QSORT macro provides an
* inline quicksort routine that does not use a callback function.
*/
-#define int_lt(a,b) ((*a)<(*b))
static void
do_qsort(uint64_t *arr, uint32_t len)
{
- QSORT(uint64_t, arr, len, int_lt);
+ QSORT(arr, len);
}
static inline int
diff --git a/utils/qsort.h b/utils/qsort.h
index 30d55ba..4097f02 100644
--- a/utils/qsort.h
+++ b/utils/qsort.h
@@ -22,293 +22,8 @@
* moinakg@belenix.org, http://moinakg.wordpress.com/
*/
-/* $Id: qsort.h,v 1.5 2008-01-28 18:16:49 mjt Exp $
- * Adopted from GNU glibc by Mjt.
- * See stdlib/qsort.c in glibc */
-
-/* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-/* in-line qsort implementation. Differs from traditional qsort() routine
- * in that it is a macro, not a function, and instead of passing an address
- * of a comparison routine to the function, it is possible to inline
- * comparison routine, thus speeding up sorting a lot.
- *
- * Usage:
- * #include "iqsort.h"
- * #define islt(a,b) (strcmp((*a),(*b))<0)
- * char *arr[];
- * int n;
- * QSORT(char*, arr, n, islt);
- *
- * The "prototype" and 4 arguments are:
- * QSORT(TYPE,BASE,NELT,ISLT)
- * 1) type of each element, TYPE,
- * 2) address of the beginning of the array, of type TYPE*,
- * 3) number of elements in the array, and
- * 4) comparision routine.
- * Array pointer and number of elements are referenced only once.
- * This is similar to a call
- * qsort(BASE,NELT,sizeof(TYPE),ISLT)
- * with the difference in last parameter.
- * Note the islt macro/routine (it receives pointers to two elements):
- * the only condition of interest is whenever one element is less than
- * another, no other conditions (greather than, equal to etc) are tested.
- * So, for example, to define integer sort, use:
- * #define islt(a,b) ((*a)<(*b))
- * QSORT(int, arr, n, islt)
- *
- * The macro could be used to implement a sorting function (see examples
- * below), or to implement the sorting algorithm inline. That is, either
- * create a sorting function and use it whenever you want to sort something,
- * or use QSORT() macro directly instead a call to such routine. Note that
- * the macro expands to quite some code (compiled size of int qsort on x86
- * is about 700..800 bytes).
- *
- * Using this macro directly it isn't possible to implement traditional
- * qsort() routine, because the macro assumes sizeof(element) == sizeof(TYPE),
- * while qsort() allows element size to be different.
- *
- * Several ready-to-use examples:
- *
- * Sorting array of integers:
- * void int_qsort(int *arr, unsigned n) {
- * #define int_lt(a,b) ((*a)<(*b))
- * QSORT(int, arr, n, int_lt);
- * }
- *
- * Sorting array of string pointers:
- * void str_qsort(char *arr[], unsigned n) {
- * #define str_lt(a,b) (strcmp((*a),(*b)) < 0)
- * QSORT(char*, arr, n, str_lt);
- * }
- *
- * Sorting array of structures:
- *
- * struct elt {
- * int key;
- * ...
- * };
- * void elt_qsort(struct elt *arr, unsigned n) {
- * #define elt_lt(a,b) ((a)->key < (b)->key)
- * QSORT(struct elt, arr, n, elt_lt);
- * }
- *
- * And so on.
- */
-
-/* Swap two items pointed to by A and B using temporary buffer t. */
-#define _QSORT_SWAP(a, b, t) ((void)((t = *a), (*a = *b), (*b = t)))
-
-/* Discontinue quicksort algorithm when partition gets below this size.
- This particular magic number was chosen to work best on a Sun 4/260. */
-#define _QSORT_MAX_THRESH 4
-
-/* Stack node declarations used to store unfulfilled partition obligations
- * (inlined in QSORT).
-typedef struct {
- QSORT_TYPE *_lo, *_hi;
-} qsort_stack_node;
- */
-
-/* The next 4 #defines implement a very fast in-line stack abstraction. */
-/* The stack needs log (total_elements) entries (we could even subtract
- log(MAX_THRESH)). Since total_elements has type unsigned, we get as
- upper bound for log (total_elements):
- bits per byte (CHAR_BIT) * sizeof(unsigned). */
-#define _QSORT_STACK_SIZE (8 * sizeof(unsigned))
-#define _QSORT_PUSH(top, low, high) \
- (((top->_lo = (low)), (top->_hi = (high)), ++top))
-#define _QSORT_POP(low, high, top) \
- ((--top, (low = top->_lo), (high = top->_hi)))
-#define _QSORT_STACK_NOT_EMPTY (_stack < _top)
-
-
-/* Order size using quicksort. This implementation incorporates
- four optimizations discussed in Sedgewick:
-
- 1. Non-recursive, using an explicit stack of pointer that store the
- next array partition to sort. To save time, this maximum amount
- of space required to store an array of SIZE_MAX is allocated on the
- stack. Assuming a 32-bit (64 bit) integer for size_t, this needs
- only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).
- Pretty cheap, actually.
-
- 2. Chose the pivot element using a median-of-three decision tree.
- This reduces the probability of selecting a bad pivot value and
- eliminates certain extraneous comparisons.
-
- 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
- insertion sort to order the MAX_THRESH items within each partition.
- This is a big win, since insertion sort is faster for small, mostly
- sorted array segments.
-
- 4. The larger of the two sub-partitions is always pushed onto the
- stack first, with the algorithm then concentrating on the
- smaller partition. This *guarantees* no more than log (total_elems)
- stack size is needed (actually O(1) in this case)! */
-
-/* The main code starts here... */
-#define QSORT(QSORT_TYPE,QSORT_BASE,QSORT_NELT,QSORT_LT) \
-{ \
- QSORT_TYPE *const _base = (QSORT_BASE); \
- const unsigned _elems = (QSORT_NELT); \
- QSORT_TYPE _hold; \
- \
- /* Don't declare two variables of type QSORT_TYPE in a single \
- * statement: eg `TYPE a, b;', in case if TYPE is a pointer, \
- * expands to `type* a, b;' wich isn't what we want. \
- */ \
- \
- if (_elems > _QSORT_MAX_THRESH) { \
- QSORT_TYPE *_lo = _base; \
- QSORT_TYPE *_hi = _lo + _elems - 1; \
- struct { \
- QSORT_TYPE *_hi; QSORT_TYPE *_lo; \
- } _stack[_QSORT_STACK_SIZE], *_top = _stack + 1; \
- \
- while (_QSORT_STACK_NOT_EMPTY) { \
- QSORT_TYPE *_left_ptr; QSORT_TYPE *_right_ptr; \
- \
- /* Select median value from among LO, MID, and HI. Rearrange \
- LO and HI so the three values are sorted. This lowers the \
- probability of picking a pathological pivot value and \
- skips a comparison for both the LEFT_PTR and RIGHT_PTR in \
- the while loops. */ \
- \
- QSORT_TYPE *_mid = _lo + ((_hi - _lo) >> 1); \
- \
- if (QSORT_LT (_mid, _lo)) \
- _QSORT_SWAP (_mid, _lo, _hold); \
- if (QSORT_LT (_hi, _mid)) { \
- _QSORT_SWAP (_mid, _hi, _hold); \
- if (QSORT_LT (_mid, _lo)) \
- _QSORT_SWAP (_mid, _lo, _hold); \
- } \
- \
- _left_ptr = _lo + 1; \
- _right_ptr = _hi - 1; \
- \
- /* Here's the famous ``collapse the walls'' section of quicksort. \
- Gotta like those tight inner loops! They are the main reason \
- that this algorithm runs much faster than others. */ \
- do { \
- while (QSORT_LT (_left_ptr, _mid)) \
- ++_left_ptr; \
- \
- while (QSORT_LT (_mid, _right_ptr)) \
- --_right_ptr; \
- \
- if (_left_ptr < _right_ptr) { \
- _QSORT_SWAP (_left_ptr, _right_ptr, _hold); \
- if (_mid == _left_ptr) \
- _mid = _right_ptr; \
- else if (_mid == _right_ptr) \
- _mid = _left_ptr; \
- ++_left_ptr; \
- --_right_ptr; \
- } \
- else if (_left_ptr == _right_ptr) { \
- ++_left_ptr; \
- --_right_ptr; \
- break; \
- } \
- } while (_left_ptr <= _right_ptr); \
- \
- /* Set up pointers for next iteration. First determine whether \
- left and right partitions are below the threshold size. If so, \
- ignore one or both. Otherwise, push the larger partition's \
- bounds on the stack and continue sorting the smaller one. */ \
- \
- if (_right_ptr - _lo <= _QSORT_MAX_THRESH) { \
- if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \
- /* Ignore both small partitions. */ \
- _QSORT_POP (_lo, _hi, _top); \
- else \
- /* Ignore small left partition. */ \
- _lo = _left_ptr; \
- } \
- else if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \
- /* Ignore small right partition. */ \
- _hi = _right_ptr; \
- else if (_right_ptr - _lo > _hi - _left_ptr) { \
- /* Push larger left partition indices. */ \
- _QSORT_PUSH (_top, _lo, _right_ptr); \
- _lo = _left_ptr; \
- } \
- else { \
- /* Push larger right partition indices. */ \
- _QSORT_PUSH (_top, _left_ptr, _hi); \
- _hi = _right_ptr; \
- } \
- } \
- } \
- \
- /* Once the BASE array is partially sorted by quicksort the rest \
- is completely sorted using insertion sort, since this is efficient \
- for partitions below MAX_THRESH size. BASE points to the \
- beginning of the array to sort, and END_PTR points at the very \
- last element in the array (*not* one beyond it!). */ \
- \
- { \
- QSORT_TYPE *const _end_ptr = _base + _elems - 1; \
- QSORT_TYPE *_tmp_ptr = _base; \
- register QSORT_TYPE *_run_ptr; \
- QSORT_TYPE *_thresh; \
- \
- _thresh = _base + _QSORT_MAX_THRESH; \
- if (_thresh > _end_ptr) \
- _thresh = _end_ptr; \
- \
- /* Find smallest element in first threshold and place it at the \
- array's beginning. This is the smallest array element, \
- and the operation speeds up insertion sort's inner loop. */ \
- \
- for (_run_ptr = _tmp_ptr + 1; _run_ptr <= _thresh; ++_run_ptr) \
- if (QSORT_LT (_run_ptr, _tmp_ptr)) \
- _tmp_ptr = _run_ptr; \
- \
- if (_tmp_ptr != _base) \
- _QSORT_SWAP (_tmp_ptr, _base, _hold); \
- \
- /* Insertion sort, running from left-hand-side \
- * up to right-hand-side. */ \
- \
- _run_ptr = _base + 1; \
- while (++_run_ptr <= _end_ptr) { \
- _tmp_ptr = _run_ptr - 1; \
- while (QSORT_LT (_run_ptr, _tmp_ptr)) \
- --_tmp_ptr; \
- \
- ++_tmp_ptr; \
- if (_tmp_ptr != _run_ptr) { \
- QSORT_TYPE *_trav = _run_ptr + 1; \
- while (--_trav >= _run_ptr) { \
- QSORT_TYPE *_hi; QSORT_TYPE *_lo; \
- _hold = *_trav; \
- \
- for (_hi = _lo = _trav; --_lo >= _tmp_ptr; _hi = _lo) \
- *_hi = *_lo; \
- *_hi = _hold; \
- } \
- } \
- } \
- } \
- \
-}
+#ifndef _MPLV2_LICENSE_
+#include "qsort_gnu.h"
+#else
+#include "qsort_bsd.h"
+#endif
diff --git a/utils/qsort_bsd.h b/utils/qsort_bsd.h
new file mode 100644
index 0000000..da7cb57
--- /dev/null
+++ b/utils/qsort_bsd.h
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include
+/* __FBSDID("$FreeBSD: head/lib/libc/stdlib/qsort.c 175317 2008-01-14 09:21:34Z das $"); */
+
+#include
+
+static inline char *med3(char *, char *, char *);
+static inline void swapfunc(char *, char *, int, int);
+
+#define min(a, b) (a) < (b) ? a : b
+
+/*
+ * QSORT routine from Bentley & McIlroy's "Engineering a Sort Function".
+ */
+#define swapcode(TYPE, parmi, parmj, n) { \
+ long i = (n) / sizeof (TYPE); \
+ TYPE *pi = (TYPE *) (parmi); \
+ TYPE *pj = (TYPE *) (parmj); \
+ do { \
+ TYPE t = *pi; \
+ *pi++ = *pj; \
+ *pj++ = t; \
+ } while (--i > 0); \
+}
+
+#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
+ es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+
+static inline void
+swapfunc(a, b, n, swaptype)
+ char *a, *b;
+ int n, swaptype;
+{
+ if(swaptype <= 1)
+ swapcode(long, a, b, n)
+ else
+ swapcode(char, a, b, n)
+}
+
+#define swap(a, b) \
+ if (swaptype == 0) { \
+ long t = *(long *)(a); \
+ *(long *)(a) = *(long *)(b); \
+ *(long *)(b) = t; \
+ } else \
+ swapfunc(a, b, es, swaptype)
+
+#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
+
+static inline char *
+med3(char *a, char *b, char *c)
+{
+ return QSORT_LT(a, b) < 0 ?
+ (QSORT_LT(b, c) < 0 ? b : (QSORT_LT(a, c) < 0 ? c : a ))
+ :(QSORT_LT(b, c) > 0 ? b : (QSORT_LT(a, c) < 0 ? a : c ));
+}
+
+void
+QSORT(void *arr, size_t n)
+{
+ char *pa, *pb, *pc, *pd, *pl, *pm, *pn, *a;
+ size_t d, r;
+ int cmp_result;
+ int swaptype, swap_cnt;
+ size_t es = sizeof (QSORT_TYPE);
+
+ a = (char *)arr;
+loop: SWAPINIT(a, es);
+ swap_cnt = 0;
+ if (n < 7) {
+ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
+ for (pl = pm;
+ pl > (char *)a && QSORT_LT(pl - es, pl) > 0;
+ pl -= es)
+ swap(pl, pl - es);
+ return;
+ }
+ pm = (char *)a + (n / 2) * es;
+ if (n > 7) {
+ pl = a;
+ pn = (char *)a + (n - 1) * es;
+ if (n > 40) {
+ d = (n / 8) * es;
+ pl = med3(pl, pl + d, pl + 2 * d);
+ pm = med3(pm - d, pm, pm + d);
+ pn = med3(pn - 2 * d, pn - d, pn);
+ }
+ pm = med3(pl, pm, pn);
+ }
+ swap(a, pm);
+ pa = pb = (char *)a + es;
+
+ pc = pd = (char *)a + (n - 1) * es;
+ for (;;) {
+ while (pb <= pc && (cmp_result = QSORT_LT(pb, a)) <= 0) {
+ if (cmp_result == 0) {
+ swap_cnt = 1;
+ swap(pa, pb);
+ pa += es;
+ }
+ pb += es;
+ }
+ while (pb <= pc && (cmp_result = QSORT_LT(pc, a)) >= 0) {
+ if (cmp_result == 0) {
+ swap_cnt = 1;
+ swap(pc, pd);
+ pd -= es;
+ }
+ pc -= es;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc);
+ swap_cnt = 1;
+ pb += es;
+ pc -= es;
+ }
+ if (swap_cnt == 0) { /* Switch to insertion sort */
+ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
+ for (pl = pm;
+ pl > (char *)a && QSORT_LT(pl - es, pl) > 0;
+ pl -= es)
+ swap(pl, pl - es);
+ return;
+ }
+
+ pn = (char *)a + n * es;
+ r = min(pa - (char *)a, pb - pa);
+ vecswap(a, pb - r, r);
+ r = min(pd - pc, pn - pd - es);
+ vecswap(pb, pn - r, r);
+ if ((r = pb - pa) > es)
+ QSORT(a, r / es);
+ if ((r = pd - pc) > es) {
+ /* Iterate rather than recurse to save stack space */
+ a = pn - r;
+ n = r / es;
+ goto loop;
+ }
+/* QSORT(pn - r, r / es);*/
+}
+
diff --git a/utils/qsort_gnu.h b/utils/qsort_gnu.h
new file mode 100644
index 0000000..b72d19f
--- /dev/null
+++ b/utils/qsort_gnu.h
@@ -0,0 +1,314 @@
+/*
+ * This file is a part of Pcompress, a chunked parallel multi-
+ * algorithm lossless compression and decompression program.
+ *
+ * Copyright (C) 2012-2013 Moinak Ghosh. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program.
+ * If not, see .
+ *
+ * moinakg@belenix.org, http://moinakg.wordpress.com/
+ */
+
+/* $Id: qsort.h,v 1.5 2008-01-28 18:16:49 mjt Exp $
+ * Adopted from GNU glibc by Mjt.
+ * See stdlib/qsort.c in glibc */
+
+/* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* in-line qsort implementation. Differs from traditional qsort() routine
+ * in that it is a macro, not a function, and instead of passing an address
+ * of a comparison routine to the function, it is possible to inline
+ * comparison routine, thus speeding up sorting a lot.
+ *
+ * Usage:
+ * #include "iqsort.h"
+ * #define islt(a,b) (strcmp((*a),(*b))<0)
+ * char *arr[];
+ * int n;
+ * QSORT(char*, arr, n, islt);
+ *
+ * The "prototype" and 4 arguments are:
+ * QSORT(TYPE,BASE,NELT,ISLT)
+ * 1) type of each element, TYPE,
+ * 2) address of the beginning of the array, of type TYPE*,
+ * 3) number of elements in the array, and
+ * 4) comparision routine.
+ * Array pointer and number of elements are referenced only once.
+ * This is similar to a call
+ * qsort(BASE,NELT,sizeof(TYPE),ISLT)
+ * with the difference in last parameter.
+ * Note the islt macro/routine (it receives pointers to two elements):
+ * the only condition of interest is whenever one element is less than
+ * another, no other conditions (greather than, equal to etc) are tested.
+ * So, for example, to define integer sort, use:
+ * #define islt(a,b) ((*a)<(*b))
+ * QSORT(int, arr, n, islt)
+ *
+ * The macro could be used to implement a sorting function (see examples
+ * below), or to implement the sorting algorithm inline. That is, either
+ * create a sorting function and use it whenever you want to sort something,
+ * or use QSORT() macro directly instead a call to such routine. Note that
+ * the macro expands to quite some code (compiled size of int qsort on x86
+ * is about 700..800 bytes).
+ *
+ * Using this macro directly it isn't possible to implement traditional
+ * qsort() routine, because the macro assumes sizeof(element) == sizeof(TYPE),
+ * while qsort() allows element size to be different.
+ *
+ * Several ready-to-use examples:
+ *
+ * Sorting array of integers:
+ * void int_qsort(int *arr, unsigned n) {
+ * #define int_lt(a,b) ((*a)<(*b))
+ * QSORT(int, arr, n, int_lt);
+ * }
+ *
+ * Sorting array of string pointers:
+ * void str_qsort(char *arr[], unsigned n) {
+ * #define str_lt(a,b) (strcmp((*a),(*b)) < 0)
+ * QSORT(char*, arr, n, str_lt);
+ * }
+ *
+ * Sorting array of structures:
+ *
+ * struct elt {
+ * int key;
+ * ...
+ * };
+ * void elt_qsort(struct elt *arr, unsigned n) {
+ * #define elt_lt(a,b) ((a)->key < (b)->key)
+ * QSORT(struct elt, arr, n, elt_lt);
+ * }
+ *
+ * And so on.
+ */
+
+/* Swap two items pointed to by A and B using temporary buffer t. */
+#define _QSORT_SWAP(a, b, t) ((void)((t = *a), (*a = *b), (*b = t)))
+
+/* Discontinue quicksort algorithm when partition gets below this size.
+ This particular magic number was chosen to work best on a Sun 4/260. */
+#define _QSORT_MAX_THRESH 4
+
+/* Stack node declarations used to store unfulfilled partition obligations
+ * (inlined in QSORT).
+typedef struct {
+ QSORT_TYPE *_lo, *_hi;
+} qsort_stack_node;
+ */
+
+/* The next 4 #defines implement a very fast in-line stack abstraction. */
+/* The stack needs log (total_elements) entries (we could even subtract
+ log(MAX_THRESH)). Since total_elements has type unsigned, we get as
+ upper bound for log (total_elements):
+ bits per byte (CHAR_BIT) * sizeof(unsigned). */
+#define _QSORT_STACK_SIZE (8 * sizeof(unsigned))
+#define _QSORT_PUSH(top, low, high) \
+ (((top->_lo = (low)), (top->_hi = (high)), ++top))
+#define _QSORT_POP(low, high, top) \
+ ((--top, (low = top->_lo), (high = top->_hi)))
+#define _QSORT_STACK_NOT_EMPTY (_stack < _top)
+
+
+/* Order size using quicksort. This implementation incorporates
+ four optimizations discussed in Sedgewick:
+
+ 1. Non-recursive, using an explicit stack of pointer that store the
+ next array partition to sort. To save time, this maximum amount
+ of space required to store an array of SIZE_MAX is allocated on the
+ stack. Assuming a 32-bit (64 bit) integer for size_t, this needs
+ only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).
+ Pretty cheap, actually.
+
+ 2. Chose the pivot element using a median-of-three decision tree.
+ This reduces the probability of selecting a bad pivot value and
+ eliminates certain extraneous comparisons.
+
+ 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
+ insertion sort to order the MAX_THRESH items within each partition.
+ This is a big win, since insertion sort is faster for small, mostly
+ sorted array segments.
+
+ 4. The larger of the two sub-partitions is always pushed onto the
+ stack first, with the algorithm then concentrating on the
+ smaller partition. This *guarantees* no more than log (total_elems)
+ stack size is needed (actually O(1) in this case)! */
+
+/* The main code starts here... */
+#define QSORT(QSORT_BASE,QSORT_NELT) \
+{ \
+ QSORT_TYPE *const _base = (QSORT_BASE); \
+ const unsigned _elems = (QSORT_NELT); \
+ QSORT_TYPE _hold; \
+ \
+ /* Don't declare two variables of type QSORT_TYPE in a single \
+ * statement: eg `TYPE a, b;', in case if TYPE is a pointer, \
+ * expands to `type* a, b;' wich isn't what we want. \
+ */ \
+ \
+ if (_elems > _QSORT_MAX_THRESH) { \
+ QSORT_TYPE *_lo = _base; \
+ QSORT_TYPE *_hi = _lo + _elems - 1; \
+ struct { \
+ QSORT_TYPE *_hi; QSORT_TYPE *_lo; \
+ } _stack[_QSORT_STACK_SIZE], *_top = _stack + 1; \
+ \
+ while (_QSORT_STACK_NOT_EMPTY) { \
+ QSORT_TYPE *_left_ptr; QSORT_TYPE *_right_ptr; \
+ \
+ /* Select median value from among LO, MID, and HI. Rearrange \
+ LO and HI so the three values are sorted. This lowers the \
+ probability of picking a pathological pivot value and \
+ skips a comparison for both the LEFT_PTR and RIGHT_PTR in \
+ the while loops. */ \
+ \
+ QSORT_TYPE *_mid = _lo + ((_hi - _lo) >> 1); \
+ \
+ if (QSORT_LT (_mid, _lo)) \
+ _QSORT_SWAP (_mid, _lo, _hold); \
+ if (QSORT_LT (_hi, _mid)) { \
+ _QSORT_SWAP (_mid, _hi, _hold); \
+ if (QSORT_LT (_mid, _lo)) \
+ _QSORT_SWAP (_mid, _lo, _hold); \
+ } \
+ \
+ _left_ptr = _lo + 1; \
+ _right_ptr = _hi - 1; \
+ \
+ /* Here's the famous ``collapse the walls'' section of quicksort. \
+ Gotta like those tight inner loops! They are the main reason \
+ that this algorithm runs much faster than others. */ \
+ do { \
+ while (QSORT_LT (_left_ptr, _mid)) \
+ ++_left_ptr; \
+ \
+ while (QSORT_LT (_mid, _right_ptr)) \
+ --_right_ptr; \
+ \
+ if (_left_ptr < _right_ptr) { \
+ _QSORT_SWAP (_left_ptr, _right_ptr, _hold); \
+ if (_mid == _left_ptr) \
+ _mid = _right_ptr; \
+ else if (_mid == _right_ptr) \
+ _mid = _left_ptr; \
+ ++_left_ptr; \
+ --_right_ptr; \
+ } \
+ else if (_left_ptr == _right_ptr) { \
+ ++_left_ptr; \
+ --_right_ptr; \
+ break; \
+ } \
+ } while (_left_ptr <= _right_ptr); \
+ \
+ /* Set up pointers for next iteration. First determine whether \
+ left and right partitions are below the threshold size. If so, \
+ ignore one or both. Otherwise, push the larger partition's \
+ bounds on the stack and continue sorting the smaller one. */ \
+ \
+ if (_right_ptr - _lo <= _QSORT_MAX_THRESH) { \
+ if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \
+ /* Ignore both small partitions. */ \
+ _QSORT_POP (_lo, _hi, _top); \
+ else \
+ /* Ignore small left partition. */ \
+ _lo = _left_ptr; \
+ } \
+ else if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \
+ /* Ignore small right partition. */ \
+ _hi = _right_ptr; \
+ else if (_right_ptr - _lo > _hi - _left_ptr) { \
+ /* Push larger left partition indices. */ \
+ _QSORT_PUSH (_top, _lo, _right_ptr); \
+ _lo = _left_ptr; \
+ } \
+ else { \
+ /* Push larger right partition indices. */ \
+ _QSORT_PUSH (_top, _left_ptr, _hi); \
+ _hi = _right_ptr; \
+ } \
+ } \
+ } \
+ \
+ /* Once the BASE array is partially sorted by quicksort the rest \
+ is completely sorted using insertion sort, since this is efficient \
+ for partitions below MAX_THRESH size. BASE points to the \
+ beginning of the array to sort, and END_PTR points at the very \
+ last element in the array (*not* one beyond it!). */ \
+ \
+ { \
+ QSORT_TYPE *const _end_ptr = _base + _elems - 1; \
+ QSORT_TYPE *_tmp_ptr = _base; \
+ register QSORT_TYPE *_run_ptr; \
+ QSORT_TYPE *_thresh; \
+ \
+ _thresh = _base + _QSORT_MAX_THRESH; \
+ if (_thresh > _end_ptr) \
+ _thresh = _end_ptr; \
+ \
+ /* Find smallest element in first threshold and place it at the \
+ array's beginning. This is the smallest array element, \
+ and the operation speeds up insertion sort's inner loop. */ \
+ \
+ for (_run_ptr = _tmp_ptr + 1; _run_ptr <= _thresh; ++_run_ptr) \
+ if (QSORT_LT (_run_ptr, _tmp_ptr)) \
+ _tmp_ptr = _run_ptr; \
+ \
+ if (_tmp_ptr != _base) \
+ _QSORT_SWAP (_tmp_ptr, _base, _hold); \
+ \
+ /* Insertion sort, running from left-hand-side \
+ * up to right-hand-side. */ \
+ \
+ _run_ptr = _base + 1; \
+ while (++_run_ptr <= _end_ptr) { \
+ _tmp_ptr = _run_ptr - 1; \
+ while (QSORT_LT (_run_ptr, _tmp_ptr)) \
+ --_tmp_ptr; \
+ \
+ ++_tmp_ptr; \
+ if (_tmp_ptr != _run_ptr) { \
+ QSORT_TYPE *_trav = _run_ptr + 1; \
+ while (--_trav >= _run_ptr) { \
+ QSORT_TYPE *_hi; QSORT_TYPE *_lo; \
+ _hold = *_trav; \
+ \
+ for (_hi = _lo = _trav; --_lo >= _tmp_ptr; _hi = _lo) \
+ *_hi = *_lo; \
+ *_hi = _hold; \
+ } \
+ } \
+ } \
+ } \
+ \
+}
diff --git a/utils/xxhash.h b/utils/xxhash.h
index 9c45ba4..9bc1fa8 100644
--- a/utils/xxhash.h
+++ b/utils/xxhash.h
@@ -20,7 +20,7 @@
* If not, see .
*
* moinakg@belenix.org, http://moinakg.wordpress.com/
- *
+ *
*/
/*