kusano 7d535a
/* lzotest.c -- very comprehensive test driver for the LZO library
kusano 7d535a
kusano 7d535a
   This file is part of the LZO real-time data compression library.
kusano 7d535a
kusano 7d535a
   Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
kusano 7d535a
   All Rights Reserved.
kusano 7d535a
kusano 7d535a
   The LZO library is free software; you can redistribute it and/or
kusano 7d535a
   modify it under the terms of the GNU General Public License as
kusano 7d535a
   published by the Free Software Foundation; either version 2 of
kusano 7d535a
   the License, or (at your option) any later version.
kusano 7d535a
kusano 7d535a
   The LZO library is distributed in the hope that it will be useful,
kusano 7d535a
   but WITHOUT ANY WARRANTY; without even the implied warranty of
kusano 7d535a
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
kusano 7d535a
   GNU General Public License for more details.
kusano 7d535a
kusano 7d535a
   You should have received a copy of the GNU General Public License
kusano 7d535a
   along with the LZO library; see the file COPYING.
kusano 7d535a
   If not, write to the Free Software Foundation, Inc.,
kusano 7d535a
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
kusano 7d535a
kusano 7d535a
   Markus F.X.J. Oberhumer
kusano 7d535a
   <markus@oberhumer.com></markus@oberhumer.com>
kusano 7d535a
   http://www.oberhumer.com/opensource/lzo/
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
kusano 7d535a
#include "lzo/lzoconf.h"
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// util
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
/* portability layer */
kusano 7d535a
#define WANT_LZO_MALLOC 1
kusano 7d535a
#define WANT_LZO_FREAD 1
kusano 7d535a
#define WANT_LZO_WILDARGV 1
kusano 7d535a
#define WANT_LZO_UCLOCK 1
kusano 7d535a
#include "examples/portab.h"
kusano 7d535a
kusano 7d535a
#if defined(HAVE_STRNICMP) && !defined(HAVE_STRNCASECMP)
kusano 7d535a
#  define strncasecmp(a,b,c) strnicmp(a,b,c)
kusano 7d535a
#  define HAVE_STRNCASECMP 1
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#if 0
kusano 7d535a
#  define is_digit(x)   (isdigit((unsigned char)(x)))
kusano 7d535a
#  define is_space(x)   (isspace((unsigned char)(x)))
kusano 7d535a
#else
kusano 7d535a
#  define is_digit(x)   ((unsigned)(x) - '0' <= 9)
kusano 7d535a
#  define is_space(x)   ((x)==' ' || (x)=='\t' || (x)=='\r' || (x)=='\n')
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#include "mygetopt.h"
kusano 7d535a
#include "mygetopt.ch"
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// compression include section
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
#define HAVE_LZO1_H 1
kusano 7d535a
#define HAVE_LZO1A_H 1
kusano 7d535a
#define HAVE_LZO1B_H 1
kusano 7d535a
#define HAVE_LZO1C_H 1
kusano 7d535a
#define HAVE_LZO1F_H 1
kusano 7d535a
#define HAVE_LZO1X_H 1
kusano 7d535a
#define HAVE_LZO1Y_H 1
kusano 7d535a
#define HAVE_LZO1Z_H 1
kusano 7d535a
#define HAVE_LZO2A_H 1
kusano 7d535a
kusano 7d535a
#if defined(NO_ZLIB_H) || (SIZEOF_INT < 4)
kusano 7d535a
#undef HAVE_ZLIB_H
kusano 7d535a
#endif
kusano 7d535a
#if defined(NO_BZLIB_H) || (SIZEOF_INT != 4)
kusano 7d535a
#undef HAVE_BZLIB_H
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#if 0 && defined(LZO_OS_DOS16)
kusano 7d535a
/* don't make this test program too big */
kusano 7d535a
#undef HAVE_LZO1_H
kusano 7d535a
#undef HAVE_LZO1A_H
kusano 7d535a
#undef HAVE_LZO1C_H
kusano 7d535a
#undef HAVE_LZO1Z_H
kusano 7d535a
#undef HAVE_LZO2A_H
kusano 7d535a
#undef HAVE_LZO2B_H
kusano 7d535a
#undef HAVE_ZLIB_H
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
/* LZO algorithms */
kusano 7d535a
#if defined(HAVE_LZO1_H)
kusano 7d535a
#  include "lzo/lzo1.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO1A_H)
kusano 7d535a
#  include "lzo/lzo1a.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO1B_H)
kusano 7d535a
#  include "lzo/lzo1b.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO1C_H)
kusano 7d535a
#  include "lzo/lzo1c.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO1F_H)
kusano 7d535a
#  include "lzo/lzo1f.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO1X_H)
kusano 7d535a
#  include "lzo/lzo1x.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO1Y_H)
kusano 7d535a
#  include "lzo/lzo1y.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO1Z_H)
kusano 7d535a
#  include "lzo/lzo1z.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO2A_H)
kusano 7d535a
#  include "lzo/lzo2a.h"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_LZO2B_H)
kusano 7d535a
#  include "lzo/lzo2b.h"
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
/* other compressors */
kusano 7d535a
#if defined(__LZO_PROFESSIONAL__)
kusano 7d535a
#  include "lzopro/t_config.ch"
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_ZLIB_H)
kusano 7d535a
#  include <zlib.h></zlib.h>
kusano 7d535a
#  define ALG_ZLIB
kusano 7d535a
#endif
kusano 7d535a
#if defined(HAVE_BZLIB_H)
kusano 7d535a
#  include <bzlib.h></bzlib.h>
kusano 7d535a
#  define ALG_BZIP2
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// enumerate all methods
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
enum {
kusano 7d535a
/* compression algorithms */
kusano 7d535a
    M_LZO1B_1     =     1,
kusano 7d535a
    M_LZO1B_2, M_LZO1B_3, M_LZO1B_4, M_LZO1B_5,
kusano 7d535a
    M_LZO1B_6, M_LZO1B_7, M_LZO1B_8, M_LZO1B_9,
kusano 7d535a
kusano 7d535a
    M_LZO1C_1     =    11,
kusano 7d535a
    M_LZO1C_2, M_LZO1C_3, M_LZO1C_4, M_LZO1C_5,
kusano 7d535a
    M_LZO1C_6, M_LZO1C_7, M_LZO1C_8, M_LZO1C_9,
kusano 7d535a
kusano 7d535a
    M_LZO1        =    21,
kusano 7d535a
    M_LZO1A       =    31,
kusano 7d535a
kusano 7d535a
    M_LZO1B_99    =   901,
kusano 7d535a
    M_LZO1B_999   =   902,
kusano 7d535a
    M_LZO1C_99    =   911,
kusano 7d535a
    M_LZO1C_999   =   912,
kusano 7d535a
    M_LZO1_99     =   921,
kusano 7d535a
    M_LZO1A_99    =   931,
kusano 7d535a
kusano 7d535a
    M_LZO1F_1     =    61,
kusano 7d535a
    M_LZO1F_999   =   962,
kusano 7d535a
    M_LZO1X_1     =    71,
kusano 7d535a
    M_LZO1X_1_11  =   111,
kusano 7d535a
    M_LZO1X_1_12  =   112,
kusano 7d535a
    M_LZO1X_1_15  =   115,
kusano 7d535a
    M_LZO1X_999   =   972,
kusano 7d535a
    M_LZO1Y_1     =    81,
kusano 7d535a
    M_LZO1Y_999   =   982,
kusano 7d535a
    M_LZO1Z_999   =   992,
kusano 7d535a
kusano 7d535a
    M_LZO2A_999   =   942,
kusano 7d535a
    M_LZO2B_999   =   952,
kusano 7d535a
kusano 7d535a
    M_LAST_LZO_COMPRESSOR = 998,
kusano 7d535a
kusano 7d535a
/* other compressors */
kusano 7d535a
#if defined(ALG_ZLIB)
kusano 7d535a
    M_ZLIB_8_1 =  1101,
kusano 7d535a
    M_ZLIB_8_2, M_ZLIB_8_3, M_ZLIB_8_4, M_ZLIB_8_5,
kusano 7d535a
    M_ZLIB_8_6, M_ZLIB_8_7, M_ZLIB_8_8, M_ZLIB_8_9,
kusano 7d535a
#endif
kusano 7d535a
#if defined(ALG_BZIP2)
kusano 7d535a
    M_BZIP2_1  =  1201,
kusano 7d535a
    M_BZIP2_2, M_BZIP2_3, M_BZIP2_4, M_BZIP2_5,
kusano 7d535a
    M_BZIP2_6, M_BZIP2_7, M_BZIP2_8, M_BZIP2_9,
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
/* dummy compressor - for benchmarking */
kusano 7d535a
    M_MEMCPY      =   999,
kusano 7d535a
kusano 7d535a
    M_LAST_COMPRESSOR = 4999,
kusano 7d535a
kusano 7d535a
/* dummy algorithms - for benchmarking */
kusano 7d535a
    M_MEMSET      =  5001,
kusano 7d535a
kusano 7d535a
/* checksum algorithms - for benchmarking */
kusano 7d535a
    M_ADLER32     =  6001,
kusano 7d535a
    M_CRC32       =  6002,
kusano 7d535a
#if defined(ALG_ZLIB)
kusano 7d535a
    M_Z_ADLER32   =  6011,
kusano 7d535a
    M_Z_CRC32     =  6012,
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    M_UNUSED
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// command line options
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
struct corpus_entry_t;
kusano 7d535a
kusano 7d535a
int opt_verbose = 2;
kusano 7d535a
kusano 7d535a
long opt_c_loops = 0;
kusano 7d535a
long opt_d_loops = 0;
kusano 7d535a
const struct corpus_entry_t *opt_corpus = NULL;
kusano 7d535a
const char *opt_corpus_path = NULL;
kusano 7d535a
const char *opt_dump_compressed_data = NULL;
kusano 7d535a
kusano 7d535a
lzo_bool opt_use_safe_decompressor = 0;
kusano 7d535a
lzo_bool opt_use_asm_decompressor = 0;
kusano 7d535a
lzo_bool opt_use_asm_fast_decompressor = 0;
kusano 7d535a
lzo_bool opt_optimize_compressed_data = 0;
kusano 7d535a
kusano 7d535a
int opt_dict = 0;
kusano 7d535a
lzo_uint opt_max_dict_len = LZO_UINT_MAX;
kusano 7d535a
const char *opt_dictionary_file = NULL;
kusano 7d535a
kusano 7d535a
lzo_bool opt_read_from_stdin = 0;
kusano 7d535a
kusano 7d535a
/* set these to 1 to measure the speed impact of a checksum */
kusano 7d535a
lzo_bool opt_compute_adler32 = 0;
kusano 7d535a
lzo_bool opt_compute_crc32 = 0;
kusano 7d535a
static lzo_uint32 adler_in, adler_out;
kusano 7d535a
static lzo_uint32 crc_in, crc_out;
kusano 7d535a
kusano 7d535a
lzo_bool opt_execution_time = 0;
kusano 7d535a
int opt_uclock = -1;
kusano 7d535a
lzo_bool opt_clear_wrkmem = 0;
kusano 7d535a
kusano 7d535a
static const lzo_bool opt_try_to_compress_0_bytes = 1;
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// misc globals
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static const char *progname = "";
kusano 7d535a
static lzo_uclock_handle_t uch;
kusano 7d535a
kusano 7d535a
/* for statistics and benchmark */
kusano 7d535a
int opt_totals = 0;
kusano 7d535a
static unsigned long total_n = 0;
kusano 7d535a
static unsigned long total_c_len = 0;
kusano 7d535a
static unsigned long total_d_len = 0;
kusano 7d535a
static unsigned long total_blocks = 0;
kusano 7d535a
static double total_perc = 0.0;
kusano 7d535a
static const char *total_method_name = NULL;
kusano 7d535a
static unsigned total_method_names = 0;
kusano 7d535a
/* Note: the average value of a rate (e.g. compression speed) is defined
kusano 7d535a
 * by the Harmonic Mean (and _not_ by the Arithmethic Mean ) */
kusano 7d535a
static unsigned long total_c_mbs_n = 0;
kusano 7d535a
static unsigned long total_d_mbs_n = 0;
kusano 7d535a
static double total_c_mbs_harmonic = 0.0;
kusano 7d535a
static double total_d_mbs_harmonic = 0.0;
kusano 7d535a
static double total_c_mbs_sum = 0.0;
kusano 7d535a
static double total_d_mbs_sum = 0.0;
kusano 7d535a
kusano 7d535a
kusano 7d535a
#if defined(HAVE_LZO1X_H)
kusano 7d535a
int default_method = M_LZO1X_1;
kusano 7d535a
#elif defined(HAVE_LZO1B_H)
kusano 7d535a
int default_method = M_LZO1B_1;
kusano 7d535a
#elif defined(HAVE_LZO1C_H)
kusano 7d535a
int default_method = M_LZO1C_1;
kusano 7d535a
#elif defined(HAVE_LZO1F_H)
kusano 7d535a
int default_method = M_LZO1F_1;
kusano 7d535a
#elif defined(HAVE_LZO1Y_H)
kusano 7d535a
int default_method = M_LZO1Y_1;
kusano 7d535a
#else
kusano 7d535a
int default_method = M_MEMCPY;
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
static const int benchmark_methods[] = {
kusano 7d535a
    M_LZO1B_1, M_LZO1B_9,
kusano 7d535a
    M_LZO1C_1, M_LZO1C_9,
kusano 7d535a
    M_LZO1F_1,
kusano 7d535a
    M_LZO1X_1,
kusano 7d535a
    0
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
static const int x1_methods[] = {
kusano 7d535a
    M_LZO1, M_LZO1A, M_LZO1B_1, M_LZO1C_1, M_LZO1F_1, M_LZO1X_1, M_LZO1Y_1,
kusano 7d535a
    0
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
static const int x99_methods[] = {
kusano 7d535a
    M_LZO1_99, M_LZO1A_99, M_LZO1B_99, M_LZO1C_99,
kusano 7d535a
    0
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
static const int x999_methods[] = {
kusano 7d535a
    M_LZO1B_999, M_LZO1C_999, M_LZO1F_999, M_LZO1X_999, M_LZO1Y_999,
kusano 7d535a
    M_LZO1Z_999,
kusano 7d535a
    M_LZO2A_999,
kusano 7d535a
    0
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
kusano 7d535a
/* exit codes of this test program */
kusano 7d535a
#define EXIT_OK         0
kusano 7d535a
#define EXIT_USAGE      1
kusano 7d535a
#define EXIT_FILE       2
kusano 7d535a
#define EXIT_MEM        3
kusano 7d535a
#define EXIT_ADLER      4
kusano 7d535a
#define EXIT_LZO_ERROR  5
kusano 7d535a
#define EXIT_LZO_INIT   6
kusano 7d535a
#define EXIT_INTERNAL   7
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// memory setup
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static lzo_uint opt_block_size;
kusano 7d535a
static lzo_uint opt_max_data_len;
kusano 7d535a
kusano 7d535a
typedef struct {
kusano 7d535a
    lzo_bytep   ptr;
kusano 7d535a
    lzo_uint    len;
kusano 7d535a
    lzo_uint32  adler;
kusano 7d535a
    lzo_uint32  crc;
kusano 7d535a
    lzo_bytep   alloc_ptr;
kusano 7d535a
    lzo_uint    alloc_len;
kusano 7d535a
    lzo_uint    saved_len;
kusano 7d535a
} mblock_t;
kusano 7d535a
kusano 7d535a
static mblock_t file_data;
kusano 7d535a
static mblock_t block1;
kusano 7d535a
static mblock_t block2;
kusano 7d535a
static mblock_t wrkmem;
kusano 7d535a
static mblock_t dict;
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void mb_alloc_extra(mblock_t *mb, lzo_uint len, lzo_uint extra_bottom, lzo_uint extra_top)
kusano 7d535a
{
kusano 7d535a
    mb->alloc_ptr = mb->ptr = NULL;
kusano 7d535a
    mb->alloc_len = mb->len = 0;
kusano 7d535a
kusano 7d535a
    mb->alloc_len = extra_bottom + len + extra_top;
kusano 7d535a
    if (mb->alloc_len == 0) mb->alloc_len = 1;
kusano 7d535a
    mb->alloc_ptr = (lzo_bytep) lzo_malloc(mb->alloc_len);
kusano 7d535a
kusano 7d535a
    if (mb->alloc_ptr == NULL) {
kusano 7d535a
        fprintf(stderr, "%s: out of memory (wanted %lu bytes)\n", progname, (unsigned long)mb->alloc_len);
kusano 7d535a
        exit(EXIT_MEM);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    mb->ptr = mb->alloc_ptr + extra_bottom;
kusano 7d535a
    mb->len = mb->saved_len = len;
kusano 7d535a
    mb->adler = 1;
kusano 7d535a
    mb->crc = 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void mb_alloc(mblock_t *mb, lzo_uint len)
kusano 7d535a
{
kusano 7d535a
    mb_alloc_extra(mb, len, 0, 0);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void mb_free(mblock_t *mb)
kusano 7d535a
{
kusano 7d535a
    if (!mb) return;
kusano 7d535a
    if (mb->alloc_ptr) lzo_free(mb->alloc_ptr);
kusano 7d535a
    mb->alloc_ptr = mb->ptr = NULL;
kusano 7d535a
    mb->alloc_len = mb->len = 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static lzo_uint get_max_compression_expansion(int m, lzo_uint bl)
kusano 7d535a
{
kusano 7d535a
    if (m == M_MEMCPY || m >= M_LAST_COMPRESSOR)
kusano 7d535a
        return 0;
kusano 7d535a
    if (m == M_LZO2A_999 || m == M_LZO2B_999)
kusano 7d535a
        return bl / 8 + 256;
kusano 7d535a
    if (m > 0  && m < M_LAST_LZO_COMPRESSOR)
kusano 7d535a
        return bl / 16 +  64 + 3;
kusano 7d535a
    return bl / 8 + 256;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static lzo_uint get_max_decompression_overrun(int m, lzo_uint bl)
kusano 7d535a
{
kusano 7d535a
    LZO_UNUSED(m);
kusano 7d535a
    LZO_UNUSED(bl);
kusano 7d535a
    /* may overwrite 3 bytes past the end of the decompressed block */
kusano 7d535a
    if (opt_use_asm_fast_decompressor)
kusano 7d535a
        return  (lzo_uint) sizeof(lzo_voidp) - 1;
kusano 7d535a
    return 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// dictionary support
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static void dict_alloc(lzo_uint max_dict_len)
kusano 7d535a
{
kusano 7d535a
    lzo_uint l = 0xbfff;    /* MAX_DICT_LEN */
kusano 7d535a
    if (max_dict_len > 0 && l > max_dict_len)
kusano 7d535a
        l = max_dict_len;
kusano 7d535a
    mb_alloc(&dict, l);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/* this default dictionary does not provide good contexts... */
kusano 7d535a
static void dict_set_default(void)
kusano 7d535a
{
kusano 7d535a
    lzo_uint d = 0;
kusano 7d535a
    unsigned i, j;
kusano 7d535a
kusano 7d535a
    dict.len = 16 * 256;
kusano 7d535a
    if (dict.len > dict.alloc_len)
kusano 7d535a
        dict.len = dict.alloc_len;
kusano 7d535a
kusano 7d535a
    lzo_memset(dict.ptr, 0, dict.len);
kusano 7d535a
kusano 7d535a
    for (i = 0; i < 256; i++)
kusano 7d535a
        for (j = 0; j < 16; j++) {
kusano 7d535a
            if (d >= dict.len)
kusano 7d535a
                goto done;
kusano 7d535a
            dict.ptr[d++] = (unsigned char) i;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
done:
kusano 7d535a
    dict.adler = lzo_adler32(1, dict.ptr, dict.len);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void dict_load(const char *file_name)
kusano 7d535a
{
kusano 7d535a
    FILE *fp;
kusano 7d535a
kusano 7d535a
    dict.len = 0;
kusano 7d535a
    fp = fopen(file_name,"rb");
kusano 7d535a
    if (fp)
kusano 7d535a
    {
kusano 7d535a
        dict.len = (lzo_uint) lzo_fread(fp, dict.ptr, dict.alloc_len);
kusano 7d535a
        fclose(fp);
kusano 7d535a
        dict.adler = lzo_adler32(1, dict.ptr, dict.len);
kusano 7d535a
    }
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// compression database
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
typedef struct
kusano 7d535a
{
kusano 7d535a
    const char *            name;
kusano 7d535a
    int                     id;
kusano 7d535a
    lzo_uint32              mem_compress;
kusano 7d535a
    lzo_uint32              mem_decompress;
kusano 7d535a
    lzo_compress_t          compress;
kusano 7d535a
    lzo_optimize_t          optimize;
kusano 7d535a
    lzo_decompress_t        decompress;
kusano 7d535a
    lzo_decompress_t        decompress_safe;
kusano 7d535a
    lzo_decompress_t        decompress_asm;
kusano 7d535a
    lzo_decompress_t        decompress_asm_safe;
kusano 7d535a
    lzo_decompress_t        decompress_asm_fast;
kusano 7d535a
    lzo_decompress_t        decompress_asm_fast_safe;
kusano 7d535a
    lzo_compress_dict_t     compress_dict;
kusano 7d535a
    lzo_decompress_dict_t   decompress_dict_safe;
kusano 7d535a
}
kusano 7d535a
compress_t;
kusano 7d535a
kusano 7d535a
#include "asm.h"
kusano 7d535a
kusano 7d535a
#include "wrap.h"
kusano 7d535a
#define M_PRIVATE       LZO_PRIVATE
kusano 7d535a
#define m_uint          lzo_uint
kusano 7d535a
#define m_uint32        lzo_uint32
kusano 7d535a
#define m_voidp         lzo_voidp
kusano 7d535a
#define m_bytep         lzo_bytep
kusano 7d535a
#define m_uintp         lzo_uintp
kusano 7d535a
#include "wrapmisc.h"
kusano 7d535a
kusano 7d535a
static const compress_t compress_database[] = {
kusano 7d535a
#include "db.h"
kusano 7d535a
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/db.ch"
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// method info
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
lzo_decompress_t get_decomp_info ( const compress_t *c, const char **nn )
kusano 7d535a
{
kusano 7d535a
    lzo_decompress_t d = 0;
kusano 7d535a
    const char *n = NULL;
kusano 7d535a
kusano 7d535a
    /* safe has priority over asm/fast */
kusano 7d535a
    if (!d && opt_use_safe_decompressor && opt_use_asm_fast_decompressor)
kusano 7d535a
    {
kusano 7d535a
        d = c->decompress_asm_fast_safe;
kusano 7d535a
        n = " [fs]";
kusano 7d535a
    }
kusano 7d535a
    if (!d && opt_use_safe_decompressor && opt_use_asm_decompressor)
kusano 7d535a
    {
kusano 7d535a
        d = c->decompress_asm_safe;
kusano 7d535a
        n = " [as]";
kusano 7d535a
    }
kusano 7d535a
    if (!d && opt_use_safe_decompressor)
kusano 7d535a
    {
kusano 7d535a
        d = c->decompress_safe;
kusano 7d535a
        n = " [s]";
kusano 7d535a
    }
kusano 7d535a
    if (!d && opt_use_asm_fast_decompressor)
kusano 7d535a
    {
kusano 7d535a
        d = c->decompress_asm_fast;
kusano 7d535a
        n = " [f]";
kusano 7d535a
    }
kusano 7d535a
    if (!d && opt_use_asm_decompressor)
kusano 7d535a
    {
kusano 7d535a
        d = c->decompress_asm;
kusano 7d535a
        n = " [a]";
kusano 7d535a
    }
kusano 7d535a
    if (!d)
kusano 7d535a
    {
kusano 7d535a
        d = c->decompress;
kusano 7d535a
        n = "";
kusano 7d535a
    }
kusano 7d535a
    if (!d)
kusano 7d535a
        n = "(null)";
kusano 7d535a
kusano 7d535a
    if (opt_dict && c->decompress_dict_safe)
kusano 7d535a
        n = "";
kusano 7d535a
kusano 7d535a
    if (nn)
kusano 7d535a
        *nn = n;
kusano 7d535a
    return d;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
const compress_t *find_method_by_id ( int method )
kusano 7d535a
{
kusano 7d535a
    const compress_t *db;
kusano 7d535a
    size_t size = sizeof(compress_database) / sizeof(*(compress_database));
kusano 7d535a
    size_t i;
kusano 7d535a
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/find_id.ch"
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    db = compress_database;
kusano 7d535a
    for (i = 0; i < size && db->name != NULL; i++, db++)
kusano 7d535a
    {
kusano 7d535a
        if (method == db->id)
kusano 7d535a
            return db;
kusano 7d535a
    }
kusano 7d535a
    return NULL;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
const compress_t *find_method_by_name ( const char *name )
kusano 7d535a
{
kusano 7d535a
    const compress_t *db;
kusano 7d535a
    size_t size = sizeof(compress_database) / sizeof(*(compress_database));
kusano 7d535a
    size_t i;
kusano 7d535a
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/find_name.ch"
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    db = compress_database;
kusano 7d535a
    for (i = 0; i < size && db->name != NULL; i++, db++)
kusano 7d535a
    {
kusano 7d535a
        size_t n = strlen(db->name);
kusano 7d535a
kusano 7d535a
#if defined(HAVE_STRNCASECMP)
kusano 7d535a
        if (strncasecmp(name,db->name,n) == 0 && (!name[n] || name[n] == ','))
kusano 7d535a
            return db;
kusano 7d535a
#else
kusano 7d535a
        if (strncmp(name,db->name,n) == 0 && (!name[n] || name[n] == ','))
kusano 7d535a
            return db;
kusano 7d535a
#endif
kusano 7d535a
    }
kusano 7d535a
    return NULL;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
lzo_bool is_compressor ( const compress_t *c )
kusano 7d535a
{
kusano 7d535a
    return (c->id <= M_LAST_COMPRESSOR || c->id >= 9721);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// check that memory gets accessed within bounds
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
void memchecker_init ( mblock_t *mb, lzo_xint l, unsigned char random_byte )
kusano 7d535a
{
kusano 7d535a
    lzo_uint i;
kusano 7d535a
    lzo_uint len = (lzo_uint) l;
kusano 7d535a
    lzo_bytep p;
kusano 7d535a
kusano 7d535a
    assert(len <= mb->len);
kusano 7d535a
kusano 7d535a
    /* bottom */
kusano 7d535a
    p = mb->ptr;
kusano 7d535a
    for (i = 0; i < 16 && p > mb->alloc_ptr; i++)
kusano 7d535a
        *--p = random_byte++;
kusano 7d535a
    /* top */
kusano 7d535a
    p = mb->ptr + len;
kusano 7d535a
    for (i = 0; i < 16 && p < mb->alloc_ptr + mb->alloc_len; i++)
kusano 7d535a
        *p++ = random_byte++;
kusano 7d535a
#if 0 || defined(LZO_DEBUG)
kusano 7d535a
    /* fill in garbage */
kusano 7d535a
    p = mb->ptr;
kusano 7d535a
    random_byte |= 1;
kusano 7d535a
    for (i = 0; i < len; i++, random_byte += 2)
kusano 7d535a
        *p++ = random_byte;
kusano 7d535a
#endif
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
int memchecker_check ( mblock_t *mb, lzo_xint l, unsigned char random_byte )
kusano 7d535a
{
kusano 7d535a
    lzo_uint i;
kusano 7d535a
    lzo_uint len = (lzo_uint) l;
kusano 7d535a
    lzo_bytep p;
kusano 7d535a
kusano 7d535a
    assert(len <= mb->len);
kusano 7d535a
kusano 7d535a
    /* bottom */
kusano 7d535a
    p = mb->ptr;
kusano 7d535a
    for (i = 0; i < 16 && p > mb->alloc_ptr; i++)
kusano 7d535a
        if (*--p != random_byte++)
kusano 7d535a
            return -1;
kusano 7d535a
    /* top */
kusano 7d535a
    p = mb->ptr + len;
kusano 7d535a
    for (i = 0; i < 16 && p < mb->alloc_ptr + mb->alloc_len; i++)
kusano 7d535a
        if (*p++ != random_byte++)
kusano 7d535a
            return -1;
kusano 7d535a
    return 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// compress a block
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
int call_compressor   ( const compress_t *c,
kusano 7d535a
                        const lzo_bytep src, lzo_uint  src_len,
kusano 7d535a
                              lzo_bytep dst, lzo_uintp dst_len )
kusano 7d535a
{
kusano 7d535a
    int r = -100;
kusano 7d535a
kusano 7d535a
    if (c && c->compress && wrkmem.len >= c->mem_compress)
kusano 7d535a
    {
kusano 7d535a
        unsigned char random_byte = (unsigned char) src_len;
kusano 7d535a
        memchecker_init(&wrkmem, c->mem_compress, random_byte);
kusano 7d535a
        if (opt_clear_wrkmem)
kusano 7d535a
            lzo_memset(wrkmem.ptr, 0, c->mem_compress);
kusano 7d535a
kusano 7d535a
        if (opt_dict && c->compress_dict)
kusano 7d535a
            r = c->compress_dict(src,src_len,dst,dst_len,wrkmem.ptr,dict.ptr,dict.len);
kusano 7d535a
        else
kusano 7d535a
            r = c->compress(src,src_len,dst,dst_len,wrkmem.ptr);
kusano 7d535a
kusano 7d535a
        if (memchecker_check(&wrkmem, c->mem_compress, random_byte) != 0)
kusano 7d535a
            printf("WARNING: wrkmem overwrite error (compress) !!!\n");
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    if (r == 0 && opt_compute_adler32)
kusano 7d535a
    {
kusano 7d535a
        lzo_uint32 adler;
kusano 7d535a
        adler = lzo_adler32(0, NULL, 0);
kusano 7d535a
        adler = lzo_adler32(adler, src, src_len);
kusano 7d535a
        adler_in = adler;
kusano 7d535a
    }
kusano 7d535a
    if (r == 0 && opt_compute_crc32)
kusano 7d535a
    {
kusano 7d535a
        lzo_uint32 crc;
kusano 7d535a
        crc = lzo_crc32(0, NULL, 0);
kusano 7d535a
        crc = lzo_crc32(crc, src, src_len);
kusano 7d535a
        crc_in = crc;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    return r;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// decompress a block
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
int call_decompressor ( const compress_t *c, lzo_decompress_t d,
kusano 7d535a
                        const lzo_bytep src, lzo_uint  src_len,
kusano 7d535a
                              lzo_bytep dst, lzo_uintp dst_len )
kusano 7d535a
{
kusano 7d535a
    int r = -100;
kusano 7d535a
kusano 7d535a
    if (c && d && wrkmem.len >= c->mem_decompress)
kusano 7d535a
    {
kusano 7d535a
        unsigned char random_byte = (unsigned char) src_len;
kusano 7d535a
        memchecker_init(&wrkmem, c->mem_decompress, random_byte);
kusano 7d535a
        if (opt_clear_wrkmem)
kusano 7d535a
            lzo_memset(wrkmem.ptr, 0, c->mem_decompress);
kusano 7d535a
kusano 7d535a
        if (opt_dict && c->decompress_dict_safe)
kusano 7d535a
            r = c->decompress_dict_safe(src,src_len,dst,dst_len,wrkmem.ptr,dict.ptr,dict.len);
kusano 7d535a
        else
kusano 7d535a
            r = d(src,src_len,dst,dst_len,wrkmem.ptr);
kusano 7d535a
kusano 7d535a
        if (memchecker_check(&wrkmem, c->mem_decompress, random_byte) != 0)
kusano 7d535a
            printf("WARNING: wrkmem overwrite error (decompress) !!!\n");
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    if (r == 0 && opt_compute_adler32)
kusano 7d535a
        adler_out = lzo_adler32(1, dst, *dst_len);
kusano 7d535a
    if (r == 0 && opt_compute_crc32)
kusano 7d535a
        crc_out = lzo_crc32(0, dst, *dst_len);
kusano 7d535a
kusano 7d535a
    return r;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// optimize a block
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
int call_optimizer   ( const compress_t *c,
kusano 7d535a
                             lzo_bytep src, lzo_uint  src_len,
kusano 7d535a
                             lzo_bytep dst, lzo_uintp dst_len )
kusano 7d535a
{
kusano 7d535a
    if (c && c->optimize && wrkmem.len >= c->mem_decompress)
kusano 7d535a
        return c->optimize(src,src_len,dst,dst_len,wrkmem.ptr);
kusano 7d535a
    return 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// read a file
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
static int load_file(const char *file_name, lzo_uint max_len)
kusano 7d535a
{
kusano 7d535a
    FILE *fp;
kusano 7d535a
    long ll = -1;
kusano 7d535a
    lzo_uint l;
kusano 7d535a
    int r;
kusano 7d535a
    mblock_t *mb = &file_data;
kusano 7d535a
kusano 7d535a
    mb_free(mb);
kusano 7d535a
kusano 7d535a
    fp = fopen(file_name,"rb");
kusano 7d535a
    if (fp == NULL)
kusano 7d535a
    {
kusano 7d535a
        fprintf(stderr,"%s: ",file_name);
kusano 7d535a
        perror("fopen");
kusano 7d535a
        fflush(stderr);
kusano 7d535a
        return EXIT_FILE;
kusano 7d535a
    }
kusano 7d535a
    r = fseek(fp,(long)max_len,SEEK_SET);
kusano 7d535a
    if (r != 0)
kusano 7d535a
        r = fseek(fp,0,SEEK_END);
kusano 7d535a
    if (r == 0)
kusano 7d535a
    {
kusano 7d535a
        ll = ftell(fp);
kusano 7d535a
        r = fseek(fp,0,SEEK_SET);
kusano 7d535a
    }
kusano 7d535a
    if (r != 0 || ll < 0)
kusano 7d535a
    {
kusano 7d535a
        fprintf(stderr,"%s: ",file_name);
kusano 7d535a
        perror("fseek");
kusano 7d535a
        fflush(stderr);
kusano 7d535a
        return EXIT_FILE;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    l = (lzo_uint) ll;
kusano 7d535a
    if (max_len > 0 && l > max_len)
kusano 7d535a
        l = max_len;
kusano 7d535a
    mb_alloc(mb, l);
kusano 7d535a
    mb->len = (lzo_uint) lzo_fread(fp, mb->ptr, mb->len);
kusano 7d535a
    if (fclose(fp) != 0)
kusano 7d535a
    {
kusano 7d535a
        mb_free(mb);
kusano 7d535a
        fprintf(stderr,"%s: ",file_name);
kusano 7d535a
        perror("fclose");
kusano 7d535a
        fflush(stderr);
kusano 7d535a
        return EXIT_FILE;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    return EXIT_OK;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/***********************************************************************
kusano 7d535a
// print some compression statistics
kusano 7d535a
************************************************************************/
kusano 7d535a
kusano 7d535a
static double t_div(double a, double b)
kusano 7d535a
{
kusano 7d535a
    return b > 0.00001 ? a / b : 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static double set_perc_d(double perc, char *s)
kusano 7d535a
{
kusano 7d535a
    if (perc <= 0) {
kusano 7d535a
        strcpy(s, "0.0");
kusano 7d535a
        return 0;
kusano 7d535a
    }
kusano 7d535a
    if (perc <= 100 - 1.0 / 16) {
kusano 7d535a
        sprintf(s, "%4.1f", perc);
kusano 7d535a
    }
kusano 7d535a
    else {
kusano 7d535a
        long p = (long) (perc + 0.5);
kusano 7d535a
        if (p < 100)
kusano 7d535a
            strcpy(s, "???");
kusano 7d535a
        else if (p >= 9999)
kusano 7d535a
            strcpy(s, "9999");
kusano 7d535a
        else
kusano 7d535a
            sprintf(s, "%ld", p);
kusano 7d535a
    }
kusano 7d535a
    return perc;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static double set_perc(unsigned long c_len, unsigned long d_len, char *s)
kusano 7d535a
{
kusano 7d535a
    double perc = 0.0;
kusano 7d535a
    if (d_len > 0)
kusano 7d535a
        perc = c_len * 100.0 / d_len;
kusano 7d535a
    return set_perc_d(perc, s);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
void print_stats ( const char *method_name, const char *file_name,
kusano 7d535a
                   long t_loops, long c_loops, long d_loops,
kusano 7d535a
                   double t_secs, double c_secs, double d_secs,
kusano 7d535a
                   unsigned long c_len, unsigned long d_len,
kusano 7d535a
                   unsigned long blocks )
kusano 7d535a
{
kusano 7d535a
    unsigned long x_len = d_len;
kusano 7d535a
    unsigned long t_bytes, c_bytes, d_bytes;
kusano 7d535a
    double c_mbs, d_mbs, t_mbs;
kusano 7d535a
    double perc;
kusano 7d535a
    char perc_str[4+1];
kusano 7d535a
kusano 7d535a
    perc = set_perc(c_len, d_len, perc_str);
kusano 7d535a
kusano 7d535a
    c_bytes = x_len * c_loops * t_loops;
kusano 7d535a
    d_bytes = x_len * d_loops * t_loops;
kusano 7d535a
    t_bytes = c_bytes + d_bytes;
kusano 7d535a
kusano 7d535a
    if (opt_uclock == 0)
kusano 7d535a
        c_secs = d_secs = t_secs = 0.0;
kusano 7d535a
kusano 7d535a
    /* speed in uncompressed megabytes per second (1 megabyte = 1.000.000 bytes) */
kusano 7d535a
    c_mbs = (c_secs > 0.001) ? (c_bytes / c_secs) / 1000000.0 : 0;
kusano 7d535a
    d_mbs = (d_secs > 0.001) ? (d_bytes / d_secs) / 1000000.0 : 0;
kusano 7d535a
    t_mbs = (t_secs > 0.001) ? (t_bytes / t_secs) / 1000000.0 : 0;
kusano 7d535a
kusano 7d535a
    total_n++;
kusano 7d535a
    total_c_len += c_len;
kusano 7d535a
    total_d_len += d_len;
kusano 7d535a
    total_blocks += blocks;
kusano 7d535a
    total_perc += perc;
kusano 7d535a
    if (c_mbs > 0) {
kusano 7d535a
        total_c_mbs_n += 1;
kusano 7d535a
        total_c_mbs_harmonic += 1.0 / c_mbs;
kusano 7d535a
        total_c_mbs_sum += c_mbs;
kusano 7d535a
    }
kusano 7d535a
    if (d_mbs > 0) {
kusano 7d535a
        total_d_mbs_n += 1;
kusano 7d535a
        total_d_mbs_harmonic += 1.0 / d_mbs;
kusano 7d535a
        total_d_mbs_sum += d_mbs;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    if (opt_verbose >= 2)
kusano 7d535a
    {
kusano 7d535a
        printf("  compressed into %lu bytes,  %s%%  (%s%.3f bits/byte)\n",
kusano 7d535a
               c_len, perc_str, "", perc * 0.08);
kusano 7d535a
kusano 7d535a
#if 0
kusano 7d535a
        printf("%-15s %5ld: ","overall", t_loops);
kusano 7d535a
        printf("%10lu bytes, %8.2f secs, %8.3f MB/sec\n",
kusano 7d535a
               t_bytes, t_secs, t_mbs);
kusano 7d535a
#else
kusano 7d535a
        LZO_UNUSED(t_mbs);
kusano 7d535a
#endif
kusano 7d535a
        printf("%-15s %5ld: ","compress", c_loops);
kusano 7d535a
        printf("%10lu bytes, %8.2f secs, %8.3f MB/sec\n",
kusano 7d535a
               c_bytes, c_secs, c_mbs);
kusano 7d535a
        printf("%-15s %5ld: ","decompress", d_loops);
kusano 7d535a
        printf("%10lu bytes, %8.2f secs, %8.3f MB/sec\n",
kusano 7d535a
               d_bytes, d_secs, d_mbs);
kusano 7d535a
        printf("\n");
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    /* create a line for util/table.pl */
kusano 7d535a
    if (opt_verbose >= 1)
kusano 7d535a
    {
kusano 7d535a
        /* get basename */
kusano 7d535a
        const char *n, *nn, *b;
kusano 7d535a
        for (nn = n = b = file_name; *nn; nn++)
kusano 7d535a
            if (*nn == '/' || *nn == '\\' || *nn == ':')
kusano 7d535a
                b = nn + 1;
kusano 7d535a
            else
kusano 7d535a
                n = b;
kusano 7d535a
kusano 7d535a
        printf("%-13s| %-14s %8lu %4lu %9lu %4s %s%8.3f %8.3f |\n",
kusano 7d535a
               method_name, n, d_len, blocks, c_len, perc_str, "", c_mbs, d_mbs);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    if (opt_verbose >= 2)
kusano 7d535a
        printf("\n");
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
void print_totals ( void )
kusano 7d535a
{
kusano 7d535a
    char perc_str[4+1];
kusano 7d535a
kusano 7d535a
    if ((opt_verbose >= 1 && total_n > 1) || (opt_totals >= 2))
kusano 7d535a
    {
kusano 7d535a
        unsigned long n = total_n > 0 ? total_n : 1;
kusano 7d535a
        const char *t1 = "-------";
kusano 7d535a
        const char *t2 = total_method_names == 1 ? total_method_name : "";
kusano 7d535a
#if 1 && defined(__ACCLIB_PCLOCK_CH_INCLUDED)
kusano 7d535a
        char uclock_mode[32+1];
kusano 7d535a
        sprintf(uclock_mode, "[clock=%d]", uch.mode);
kusano 7d535a
        t1 = uclock_mode;
kusano 7d535a
        if (opt_uclock == 0) t1 = t2;
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/print_totals.ch"
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#if 1
kusano 7d535a
        set_perc_d(total_perc / n, perc_str);
kusano 7d535a
        printf("%-13s  %-12s %10lu %4.1f %9lu %4s %8.3f %8.3f\n",
kusano 7d535a
            t1, "***AVG***",
kusano 7d535a
            total_d_len / n, total_blocks * 1.0 / n, total_c_len / n, perc_str,
kusano 7d535a
            t_div(total_c_mbs_n, total_c_mbs_harmonic),
kusano 7d535a
            t_div(total_d_mbs_n, total_d_mbs_harmonic));
kusano 7d535a
#endif
kusano 7d535a
        set_perc(total_c_len, total_d_len, perc_str);
kusano 7d535a
        printf("%-13s  %-12s %10lu %4lu %9lu %4s %s%8.3f %8.3f\n",
kusano 7d535a
            t2, "***TOTALS***",
kusano 7d535a
            total_d_len, total_blocks, total_c_len, perc_str, "",
kusano 7d535a
            t_div(total_c_mbs_n, total_c_mbs_harmonic),
kusano 7d535a
            t_div(total_d_mbs_n, total_d_mbs_harmonic));
kusano 7d535a
    }
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// compress and decompress a file
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
int process_file ( const compress_t *c, lzo_decompress_t decompress,
kusano 7d535a
                   const char *method_name,
kusano 7d535a
                   const char *file_name,
kusano 7d535a
                   long t_loops, long c_loops, long d_loops )
kusano 7d535a
{
kusano 7d535a
    long t_i;
kusano 7d535a
    unsigned long blocks = 0;
kusano 7d535a
    unsigned long compressed_len = 0;
kusano 7d535a
    double t_time = 0, c_time = 0, d_time = 0;
kusano 7d535a
    lzo_uclock_t t_start, t_stop, x_start, x_stop;
kusano 7d535a
    FILE *fp_dump = NULL;
kusano 7d535a
kusano 7d535a
    if (opt_dump_compressed_data)
kusano 7d535a
        fp_dump = fopen(opt_dump_compressed_data,"wb");
kusano 7d535a
kusano 7d535a
/* process the file */
kusano 7d535a
kusano 7d535a
    lzo_uclock_flush_cpu_cache(&uch, 0);
kusano 7d535a
    lzo_uclock_read(&uch, &t_start);
kusano 7d535a
    for (t_i = 0; t_i < t_loops; t_i++)
kusano 7d535a
    {
kusano 7d535a
        lzo_uint len, c_len, c_len_max, d_len = 0;
kusano 7d535a
        const lzo_bytep d = file_data.ptr;
kusano 7d535a
kusano 7d535a
        len = file_data.len;
kusano 7d535a
        c_len = 0;
kusano 7d535a
        blocks = 0;
kusano 7d535a
kusano 7d535a
        /* process blocks */
kusano 7d535a
        if (len > 0 || opt_try_to_compress_0_bytes) do
kusano 7d535a
        {
kusano 7d535a
            lzo_uint bl;
kusano 7d535a
            long c_i;
kusano 7d535a
            int r;
kusano 7d535a
            unsigned char random_byte = (unsigned char) file_data.len;
kusano 7d535a
#if 1 && defined(CLOCKS_PER_SEC)
kusano 7d535a
            random_byte ^= (unsigned char) clock();
kusano 7d535a
#endif
kusano 7d535a
            blocks++;
kusano 7d535a
kusano 7d535a
            bl = len > opt_block_size ? opt_block_size : len;
kusano 7d535a
            /* update lengths for memchecker_xxx() */
kusano 7d535a
            block1.len = bl + get_max_compression_expansion(c->id, bl);
kusano 7d535a
            block2.len = bl + get_max_decompression_overrun(c->id, bl);
kusano 7d535a
#if defined(__LZO_CHECKER)
kusano 7d535a
            /* malloc a block of the exact size to detect any overrun */
kusano 7d535a
            assert(block1.alloc_ptr == NULL);
kusano 7d535a
            assert(block2.alloc_ptr == NULL);
kusano 7d535a
            mb_alloc(&block1, block1.len);
kusano 7d535a
            mb_alloc(&block2, block2.len);
kusano 7d535a
#endif
kusano 7d535a
            assert(block1.len <= block1.saved_len);
kusano 7d535a
            assert(block2.len <= block2.saved_len);
kusano 7d535a
kusano 7d535a
            memchecker_init(&block1, block1.len, random_byte);
kusano 7d535a
            memchecker_init(&block2, block2.len, random_byte);
kusano 7d535a
kusano 7d535a
        /* compress the block */
kusano 7d535a
            c_len = c_len_max = 0;
kusano 7d535a
            lzo_uclock_flush_cpu_cache(&uch, 0);
kusano 7d535a
            lzo_uclock_read(&uch, &x_start);
kusano 7d535a
            for (r = 0, c_i = 0; r == 0 && c_i < c_loops; c_i++)
kusano 7d535a
            {
kusano 7d535a
                c_len = block1.len;
kusano 7d535a
                r = call_compressor(c, d, bl, block1.ptr, &c_len);
kusano 7d535a
                if (r == 0 && c_len > c_len_max)
kusano 7d535a
                    c_len_max = c_len;
kusano 7d535a
                if (r == 0 && c_len > block1.len)
kusano 7d535a
                    goto compress_overrun;
kusano 7d535a
            }
kusano 7d535a
            lzo_uclock_read(&uch, &x_stop);
kusano 7d535a
            c_time += lzo_uclock_get_elapsed(&uch, &x_start, &x_stop);
kusano 7d535a
            if (r != 0)
kusano 7d535a
            {
kusano 7d535a
                printf("  compression failed in block %ld (%d) (%lu %lu)\n",
kusano 7d535a
                    blocks, r, (long)c_len, (long)bl);
kusano 7d535a
                return EXIT_LZO_ERROR;
kusano 7d535a
            }
kusano 7d535a
            if (memchecker_check(&block1, block1.len, random_byte) != 0)
kusano 7d535a
            {
kusano 7d535a
compress_overrun:
kusano 7d535a
                printf("  compression overwrite error in block %lu "
kusano 7d535a
                    "(%lu %lu %lu %lu)\n",
kusano 7d535a
                    blocks, (long)c_len, (long)d_len, (long)bl, (long)block1.len);
kusano 7d535a
                return EXIT_LZO_ERROR;
kusano 7d535a
            }
kusano 7d535a
kusano 7d535a
        /* optimize the compressed block */
kusano 7d535a
            if (c_len < bl && opt_optimize_compressed_data)
kusano 7d535a
            {
kusano 7d535a
                d_len = bl;
kusano 7d535a
                r = call_optimizer(c, block1.ptr, c_len, block2.ptr, &d_len);
kusano 7d535a
                if (r != 0 || d_len != bl)
kusano 7d535a
                {
kusano 7d535a
                    printf("  optimization failed in block %lu (%d) "
kusano 7d535a
                        "(%lu %lu %lu)\n", blocks, r,
kusano 7d535a
                        (long)c_len, (long)d_len, (long)bl);
kusano 7d535a
                    return EXIT_LZO_ERROR;
kusano 7d535a
                }
kusano 7d535a
                if (memchecker_check(&block1, block1.len, random_byte) != 0 ||
kusano 7d535a
                    memchecker_check(&block2, block2.len, random_byte) != 0)
kusano 7d535a
                {
kusano 7d535a
                    printf("  optimize overwrite error in block %lu "
kusano 7d535a
                        "(%lu %lu %lu %lu)\n",
kusano 7d535a
                        blocks, (long)c_len, (long)d_len, (long)bl, (long)block1.len);
kusano 7d535a
                    return EXIT_LZO_ERROR;
kusano 7d535a
                }
kusano 7d535a
            }
kusano 7d535a
kusano 7d535a
            /* dump compressed data to disk */
kusano 7d535a
            if (fp_dump)
kusano 7d535a
            {
kusano 7d535a
                (void) lzo_fwrite(fp_dump, block1.ptr, c_len);
kusano 7d535a
                fflush(fp_dump);
kusano 7d535a
            }
kusano 7d535a
kusano 7d535a
        /* decompress the block and verify */
kusano 7d535a
            lzo_uclock_flush_cpu_cache(&uch, 0);
kusano 7d535a
            lzo_uclock_read(&uch, &x_start);
kusano 7d535a
            for (r = 0, c_i = 0; r == 0 && c_i < d_loops; c_i++)
kusano 7d535a
            {
kusano 7d535a
                d_len = bl;
kusano 7d535a
                r = call_decompressor(c, decompress, block1.ptr, c_len, block2.ptr, &d_len);
kusano 7d535a
                if (d_len != bl)
kusano 7d535a
                    break;
kusano 7d535a
            }
kusano 7d535a
            lzo_uclock_read(&uch, &x_stop);
kusano 7d535a
            d_time += lzo_uclock_get_elapsed(&uch, &x_start, &x_stop);
kusano 7d535a
            if (r != 0)
kusano 7d535a
            {
kusano 7d535a
                printf("  decompression failed in block %lu (%d) "
kusano 7d535a
                    "(%lu %lu %lu)\n", blocks, r,
kusano 7d535a
                    (long)c_len, (long)d_len, (long)bl);
kusano 7d535a
                return EXIT_LZO_ERROR;
kusano 7d535a
            }
kusano 7d535a
            if (d_len != bl)
kusano 7d535a
            {
kusano 7d535a
                printf("  decompression size error in block %lu (%lu %lu %lu)\n",
kusano 7d535a
                    blocks, (long)c_len, (long)d_len, (long)bl);
kusano 7d535a
                return EXIT_LZO_ERROR;
kusano 7d535a
            }
kusano 7d535a
            if (is_compressor(c))
kusano 7d535a
            {
kusano 7d535a
                if (lzo_memcmp(d, block2.ptr, bl) != 0)
kusano 7d535a
                {
kusano 7d535a
                    lzo_uint x = 0;
kusano 7d535a
                    while (x < bl && block2.ptr[x] == d[x])
kusano 7d535a
                        x++;
kusano 7d535a
                    printf("  decompression data error in block %lu at offset "
kusano 7d535a
                        "%lu (%lu %lu)\n", blocks, (long)x,
kusano 7d535a
                        (long)c_len, (long)d_len);
kusano 7d535a
                    if (opt_compute_adler32)
kusano 7d535a
                        printf("      checksum: 0x%08lx 0x%08lx\n",
kusano 7d535a
                            (long)adler_in, (long)adler_out);
kusano 7d535a
#if 0
kusano 7d535a
                    printf("Orig:  ");
kusano 7d535a
                    r = (x >= 10) ? -10 : 0 - (int) x;
kusano 7d535a
                    for (j = r; j <= 10 && x + j < bl; j++)
kusano 7d535a
                        printf(" %02x", (int)d[x+j]);
kusano 7d535a
                    printf("\nDecomp:");
kusano 7d535a
                    for (j = r; j <= 10 && x + j < bl; j++)
kusano 7d535a
                        printf(" %02x", (int)block2.ptr[x+j]);
kusano 7d535a
                    printf("\n");
kusano 7d535a
#endif
kusano 7d535a
                    return EXIT_LZO_ERROR;
kusano 7d535a
                }
kusano 7d535a
                if ((opt_compute_adler32 && adler_in != adler_out) ||
kusano 7d535a
                    (opt_compute_crc32 && crc_in != crc_out))
kusano 7d535a
                {
kusano 7d535a
                    printf("  checksum error in block %lu (%lu %lu)\n",
kusano 7d535a
                        blocks, (long)c_len, (long)d_len);
kusano 7d535a
                    printf("      adler32: 0x%08lx 0x%08lx\n",
kusano 7d535a
                        (long)adler_in, (long)adler_out);
kusano 7d535a
                    printf("      crc32: 0x%08lx 0x%08lx\n",
kusano 7d535a
                        (long)crc_in, (long)crc_out);
kusano 7d535a
                    return EXIT_LZO_ERROR;
kusano 7d535a
                }
kusano 7d535a
            }
kusano 7d535a
kusano 7d535a
            if (memchecker_check(&block2, block2.len, random_byte) != 0)
kusano 7d535a
            {
kusano 7d535a
                printf("  decompression overwrite error in block %lu "
kusano 7d535a
                    "(%lu %lu %lu %lu)\n",
kusano 7d535a
                    blocks, (long)c_len, (long)d_len, (long)bl, (long)block2.len);
kusano 7d535a
                return EXIT_LZO_ERROR;
kusano 7d535a
            }
kusano 7d535a
kusano 7d535a
#if defined(__LZO_CHECKER)
kusano 7d535a
            /* free in reverse order of allocations */
kusano 7d535a
            mb_free(&block2);
kusano 7d535a
            mb_free(&block1);
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
            d += bl;
kusano 7d535a
            len -= bl;
kusano 7d535a
            compressed_len += (unsigned long) c_len_max;
kusano 7d535a
        }
kusano 7d535a
        while (len > 0);
kusano 7d535a
    }
kusano 7d535a
    lzo_uclock_read(&uch, &t_stop);
kusano 7d535a
    t_time += lzo_uclock_get_elapsed(&uch, &t_start, &t_stop);
kusano 7d535a
kusano 7d535a
    if (fp_dump)
kusano 7d535a
        fclose(fp_dump);
kusano 7d535a
    opt_dump_compressed_data = NULL;    /* only dump the first file */
kusano 7d535a
kusano 7d535a
    print_stats(method_name, file_name,
kusano 7d535a
                t_loops, c_loops, d_loops,
kusano 7d535a
                t_time, c_time, d_time,
kusano 7d535a
                compressed_len, (unsigned long) file_data.len, blocks);
kusano 7d535a
    if (total_method_name != c->name) {
kusano 7d535a
        total_method_name = c->name;
kusano 7d535a
        total_method_names += 1;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    return EXIT_OK;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
int do_file ( int method, const char *file_name,
kusano 7d535a
              long c_loops, long d_loops,
kusano 7d535a
              lzo_uint32p p_adler, lzo_uint32p p_crc )
kusano 7d535a
{
kusano 7d535a
    int r;
kusano 7d535a
    const compress_t *c;
kusano 7d535a
    lzo_decompress_t decompress;
kusano 7d535a
    lzo_uint32 adler, crc;
kusano 7d535a
    char method_name[256+1];
kusano 7d535a
    const char *n;
kusano 7d535a
    const long t_loops = 1;
kusano 7d535a
kusano 7d535a
    adler_in = adler_out = 0;
kusano 7d535a
    crc_in = crc_out = 0;
kusano 7d535a
    if (p_adler)
kusano 7d535a
        *p_adler = 0;
kusano 7d535a
    if (p_crc)
kusano 7d535a
        *p_crc = 0;
kusano 7d535a
kusano 7d535a
    c = find_method_by_id(method);
kusano 7d535a
    if (c == NULL || c->name == NULL || c->compress == NULL)
kusano 7d535a
        return EXIT_INTERNAL;
kusano 7d535a
    decompress = get_decomp_info(c,&n);
kusano 7d535a
    if (!decompress || n == NULL || wrkmem.len < c->mem_decompress)
kusano 7d535a
        return EXIT_INTERNAL;
kusano 7d535a
    strcpy(method_name,c->name);
kusano 7d535a
    strcat(method_name,n);
kusano 7d535a
kusano 7d535a
    if (c_loops < 1)  c_loops = 1;
kusano 7d535a
    if (d_loops < 1)  d_loops = 1;
kusano 7d535a
kusano 7d535a
    fflush(stdout); fflush(stderr);
kusano 7d535a
kusano 7d535a
    /* read the whole file */
kusano 7d535a
    r = load_file(file_name, opt_max_data_len);
kusano 7d535a
    if (r != 0)
kusano 7d535a
        return r;
kusano 7d535a
kusano 7d535a
    /* compute some checksums */
kusano 7d535a
    adler = lzo_adler32(0, NULL, 0);
kusano 7d535a
    adler = lzo_adler32(adler, file_data.ptr, file_data.len);
kusano 7d535a
    if (p_adler)
kusano 7d535a
        *p_adler = adler;
kusano 7d535a
    crc = lzo_crc32(0, NULL, 0);
kusano 7d535a
    crc = lzo_crc32(crc, file_data.ptr, file_data.len);
kusano 7d535a
    if (p_crc)
kusano 7d535a
        *p_crc = crc;
kusano 7d535a
kusano 7d535a
    if (opt_verbose >= 2)
kusano 7d535a
    {
kusano 7d535a
        printf("File %s: %lu bytes   (0x%08lx, 0x%08lx)\n",
kusano 7d535a
                file_name, (long) file_data.len, (long) adler, (long) crc);
kusano 7d535a
        printf("  compressing %lu bytes (%ld/%ld/%ld loops, %lu block-size)\n",
kusano 7d535a
                (long) file_data.len, t_loops, c_loops, d_loops, (long) opt_block_size);
kusano 7d535a
        printf("  %s\n", method_name);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    r = process_file(c, decompress, method_name, file_name,
kusano 7d535a
                     t_loops, c_loops, d_loops);
kusano 7d535a
kusano 7d535a
    return r;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// Calgary Corpus and Silesia Corpus test suite driver
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
struct corpus_entry_t
kusano 7d535a
{
kusano 7d535a
    const char *name;
kusano 7d535a
    long loops;
kusano 7d535a
    lzo_uint32 adler;
kusano 7d535a
    lzo_uint32 crc;
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
static const struct corpus_entry_t calgary_corpus[] =
kusano 7d535a
{
kusano 7d535a
    { "bib",       8,  0x4bd09e98L, 0xb856ebe8L },
kusano 7d535a
    { "book1",     1,  0xd4d3613eL, 0x24e19972L },
kusano 7d535a
    { "book2",     1,  0x6fe14cc3L, 0xba0f3f26L },
kusano 7d535a
    { "geo",       6,  0xf3cc5be0L, 0x4d3a6ed0L },
kusano 7d535a
    { "news",      2,  0x2ed405b8L, 0xcafac853L },
kusano 7d535a
    { "obj1",     35,  0x3887dd2cL, 0xc7b0cd26L },
kusano 7d535a
    { "obj2",      4,  0xf89407c4L, 0x3ae33007L },
kusano 7d535a
    { "paper1",   17,  0xfe65ce62L, 0x2b6baca0L },
kusano 7d535a
    { "paper2",   11,  0x1238b7c2L, 0xf76cba72L },
kusano 7d535a
    { "pic",       4,  0xf61a5702L, 0x4b17e59cL },
kusano 7d535a
    { "progc",    25,  0x4c00ba45L, 0x6fb16094L },
kusano 7d535a
    { "progl",    20,  0x4cba738eL, 0xddbf6baaL },
kusano 7d535a
    { "progp",    28,  0x7495b92bL, 0x493a1809L },
kusano 7d535a
    { "trans",    15,  0x52a2cec8L, 0xcdec06a6L },
kusano 7d535a
    { NULL,        0,  0x00000000L, 0x00000000L }
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
static const struct corpus_entry_t silesia_corpus[] =
kusano 7d535a
{
kusano 7d535a
    { "dickens",   1,  0x170f606fL, 0xaf3a6b76L },
kusano 7d535a
    { "mozilla",   1,  0x1188dd4eL, 0x7fb0ab7dL },
kusano 7d535a
    { "mr",        1,  0xaea14b97L, 0xa341883fL },
kusano 7d535a
    { "nci",       1,  0x0af16f1fL, 0x60ff63d3L },
kusano 7d535a
    { "ooffice",   1,  0x83c8f689L, 0xa023e1faL },
kusano 7d535a
    { "osdb",      1,  0xb825b790L, 0xa0ca388cL },
kusano 7d535a
    { "reymont",   1,  0xce5c82caL, 0x50d35f03L },
kusano 7d535a
    { "samba",     1,  0x19dbb9f5L, 0x2beac5f3L },
kusano 7d535a
    { "sao",       1,  0x7edfc4a9L, 0xfda125bfL },
kusano 7d535a
    { "webster",   1,  0xf2962fc6L, 0x01f5a2e9L },
kusano 7d535a
    { "xml",       1,  0xeccd03d6L, 0xff8f3051L },
kusano 7d535a
    { "x-ray",     1,  0xc95435a0L, 0xc86a35c6L },
kusano 7d535a
    { NULL,        0,  0x00000000L, 0x00000000L }
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
int do_corpus ( const struct corpus_entry_t *corpus, int method, const char *path,
kusano 7d535a
                long c_loops, long d_loops )
kusano 7d535a
{
kusano 7d535a
    size_t i, n;
kusano 7d535a
    char name[256];
kusano 7d535a
kusano 7d535a
    if (path == NULL || strlen(path) >= sizeof(name) - 12)
kusano 7d535a
        return EXIT_USAGE;
kusano 7d535a
kusano 7d535a
    strcpy(name,path);
kusano 7d535a
    n = strlen(name);
kusano 7d535a
    if (n > 0 && name[n-1] != '/' && name[n-1] != '\\' && name[n-1] != ':')
kusano 7d535a
    {
kusano 7d535a
        strcat(name,"/");
kusano 7d535a
        n++;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    for (i = 0; corpus[i].name != NULL; i++)
kusano 7d535a
    {
kusano 7d535a
        lzo_uint32 adler, crc;
kusano 7d535a
        long c = c_loops * corpus[i].loops;
kusano 7d535a
        long d = d_loops * corpus[i].loops;
kusano 7d535a
        int r;
kusano 7d535a
kusano 7d535a
        strcpy(name+n,corpus[i].name);
kusano 7d535a
        r = do_file(method, name, c, d, &adler, &crc);
kusano 7d535a
        if (r != 0)
kusano 7d535a
            return r;
kusano 7d535a
        if (adler != corpus[i].adler)
kusano 7d535a
        {
kusano 7d535a
            printf("  invalid test suite\n");
kusano 7d535a
            return EXIT_ADLER;
kusano 7d535a
        }
kusano 7d535a
        if (corpus[i].crc && crc != corpus[i].crc)
kusano 7d535a
        {
kusano 7d535a
            printf("  internal checksum error !!  (0x%08lx 0x%08lx)\n",
kusano 7d535a
                    (long) crc, (long) corpus[i].crc);
kusano 7d535a
            return EXIT_INTERNAL;
kusano 7d535a
        }
kusano 7d535a
    }
kusano 7d535a
    return EXIT_OK;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// usage
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
void usage ( const char *name, int exit_code, lzo_bool show_methods )
kusano 7d535a
{
kusano 7d535a
    FILE *f;
kusano 7d535a
    int i;
kusano 7d535a
kusano 7d535a
    f = stdout;
kusano 7d535a
kusano 7d535a
    fflush(stdout); fflush(stderr);
kusano 7d535a
kusano 7d535a
    fprintf(f,"Usage: %s [option..] file...\n", name);
kusano 7d535a
    fprintf(f,"\n");
kusano 7d535a
    fprintf(f,"Options:\n");
kusano 7d535a
    fprintf(f,"  -m#     compression method\n");
kusano 7d535a
    fprintf(f,"  -b#     set input block size (default %ld, max %ld)\n",
kusano 7d535a
        (long) opt_block_size, (long) opt_max_data_len);
kusano 7d535a
    fprintf(f,"  -n#     number of compression/decompression runs\n");
kusano 7d535a
    fprintf(f,"  -c#     number of compression runs\n");
kusano 7d535a
    fprintf(f,"  -d#     number of decompression runs\n");
kusano 7d535a
    fprintf(f,"  -S      use safe decompressor (if available)\n");
kusano 7d535a
    fprintf(f,"  -A      use assembler decompressor (if available)\n");
kusano 7d535a
    fprintf(f,"  -F      use fast assembler decompressor (if available)\n");
kusano 7d535a
    fprintf(f,"  -O      optimize compressed data (if available)\n");
kusano 7d535a
    fprintf(f,"  -s DIR  process Calgary Corpus test suite in directory `DIR'\n");
kusano 7d535a
    fprintf(f,"  -@      read list of files to compress from stdin\n");
kusano 7d535a
    fprintf(f,"  -q      be quiet\n");
kusano 7d535a
    fprintf(f,"  -Q      be very quiet\n");
kusano 7d535a
    fprintf(f,"  -v      be verbose\n");
kusano 7d535a
    fprintf(f,"  -L      display software license\n");
kusano 7d535a
kusano 7d535a
    if (show_methods)
kusano 7d535a
    {
kusano 7d535a
#if defined(__ACCLIB_PCLOCK_CH_INCLUDED)
kusano 7d535a
        lzo_uclock_t t_dummy;
kusano 7d535a
        lzo_uclock_read(&uch, &t_dummy);
kusano 7d535a
        (void) lzo_uclock_get_elapsed(&uch, &t_dummy, &t_dummy);
kusano 7d535a
        fprintf(f,"\nAll timings are recorded using uclock mode %d %s.\n", uch.mode, uch.name);
kusano 7d535a
#endif
kusano 7d535a
        fprintf(f,"\n\n");
kusano 7d535a
        fprintf(f,"The following compression methods are available:\n");
kusano 7d535a
        fprintf(f,"\n");
kusano 7d535a
        fprintf(f,"  usage   name           memory          available extras\n");
kusano 7d535a
        fprintf(f,"  -----   ----           ------          ----------------\n");
kusano 7d535a
kusano 7d535a
        for (i = 0; i <= M_LAST_COMPRESSOR; i++)
kusano 7d535a
        {
kusano 7d535a
            const compress_t *c;
kusano 7d535a
            c = find_method_by_id(i);
kusano 7d535a
            if (c)
kusano 7d535a
            {
kusano 7d535a
                char n[16];
kusano 7d535a
                static const char * const s[3] = {"          ", ", ", ""};
kusano 7d535a
                int j = 0;
kusano 7d535a
                unsigned long m = c->mem_compress;
kusano 7d535a
kusano 7d535a
                sprintf(n,"-m%d",i);
kusano 7d535a
                fprintf(f,"  %-6s  %-13s",n,c->name);
kusano 7d535a
#if 1
kusano 7d535a
                fprintf(f,"%9ld", m);
kusano 7d535a
#else
kusano 7d535a
                m = (m + 1023) / 1024;
kusano 7d535a
                fprintf(f,"%6ld kB", m);
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
                if (c->decompress_safe)
kusano 7d535a
                    fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "safe");
kusano 7d535a
                if (c->decompress_asm)
kusano 7d535a
                    fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "asm");
kusano 7d535a
                if (c->decompress_asm_safe)
kusano 7d535a
                    fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "asm+safe");
kusano 7d535a
                if (c->decompress_asm_fast)
kusano 7d535a
                    fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "fastasm");
kusano 7d535a
                if (c->decompress_asm_fast_safe)
kusano 7d535a
                    fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "fastasm+safe");
kusano 7d535a
                if (c->optimize)
kusano 7d535a
                    fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "optimize");
kusano 7d535a
                if (j > 0)
kusano 7d535a
                    fprintf(f, s[2]);
kusano 7d535a
                fprintf(f,"\n");
kusano 7d535a
            }
kusano 7d535a
        }
kusano 7d535a
    }
kusano 7d535a
    else
kusano 7d535a
    {
kusano 7d535a
        fprintf(f,"\n");
kusano 7d535a
        fprintf(f,"Type '%s -m' to list all available methods.\n", name);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    fflush(f);
kusano 7d535a
    if (exit_code < 0)
kusano 7d535a
        exit_code = EXIT_USAGE;
kusano 7d535a
    exit(exit_code);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static
kusano 7d535a
void license(void)
kusano 7d535a
{
kusano 7d535a
    FILE *f;
kusano 7d535a
kusano 7d535a
    f = stdout;
kusano 7d535a
kusano 7d535a
    fflush(stdout); fflush(stderr);
kusano 7d535a
kusano 7d535a
#if defined(__LZO_PROFESSIONAL__)
kusano 7d535a
#  include "lzopro/license.ch"
kusano 7d535a
#else
kusano 7d535a
fprintf(f,
kusano 7d535a
"   The LZO library is free software; you can redistribute it and/or\n"
kusano 7d535a
"   modify it under the terms of the GNU General Public License as\n"
kusano 7d535a
"   published by the Free Software Foundation; either version 2 of\n"
kusano 7d535a
"   the License, or (at your option) any later version.\n"
kusano 7d535a
"\n"
kusano 7d535a
"   The LZO library is distributed in the hope that it will be useful,\n"
kusano 7d535a
"   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
kusano 7d535a
"   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
kusano 7d535a
"   GNU General Public License for more details.\n"
kusano 7d535a
    );
kusano 7d535a
fprintf(f,
kusano 7d535a
"\n"
kusano 7d535a
"   You should have received a copy of the GNU General Public License\n"
kusano 7d535a
"   along with the LZO library; see the file COPYING.\n"
kusano 7d535a
"   If not, write to the Free Software Foundation, Inc.,\n"
kusano 7d535a
"   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
kusano 7d535a
"\n"
kusano 7d535a
"   Markus F.X.J. Oberhumer\n"
kusano 7d535a
"   <markus@oberhumer.com>\n"</markus@oberhumer.com>
kusano 7d535a
"   http://www.oberhumer.com/opensource/lzo/\n"
kusano 7d535a
"\n"
kusano 7d535a
    );
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    fflush(f);
kusano 7d535a
    exit(EXIT_OK);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// parse method option '-m'
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
static int methods[256+1];
kusano 7d535a
static int methods_n = 0;
kusano 7d535a
kusano 7d535a
static void add_method(int m)
kusano 7d535a
{
kusano 7d535a
    int i;
kusano 7d535a
kusano 7d535a
    if (m > 0)
kusano 7d535a
    {
kusano 7d535a
        if (!find_method_by_id(m)) {
kusano 7d535a
            fprintf(stdout,"%s: invalid method %d\n",progname,m);
kusano 7d535a
            exit(EXIT_USAGE);
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
        for (i = 0; i < methods_n; i++)
kusano 7d535a
            if (methods[i] == m)
kusano 7d535a
                return;
kusano 7d535a
kusano 7d535a
        if (methods_n >= 256)
kusano 7d535a
        {
kusano 7d535a
            fprintf(stderr,"%s: too many methods\n",progname);
kusano 7d535a
            exit(EXIT_USAGE);
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
        methods[methods_n++] = m;
kusano 7d535a
        methods[methods_n] = 0;
kusano 7d535a
    }
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void add_methods(const int *ml)
kusano 7d535a
{
kusano 7d535a
    while (*ml != 0)
kusano 7d535a
        add_method(*ml++);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void add_all_methods(int first, int last)
kusano 7d535a
{
kusano 7d535a
    int m;
kusano 7d535a
kusano 7d535a
    for (m = first; m <= last; m++)
kusano 7d535a
        if (find_method_by_id(m) != NULL)
kusano 7d535a
            add_method(m);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static int m_strcmp(const char *a, const char *b)
kusano 7d535a
{
kusano 7d535a
    size_t n;
kusano 7d535a
kusano 7d535a
    if (a[0] == 0 || b[0] == 0)
kusano 7d535a
        return 1;
kusano 7d535a
    n = strlen(b);
kusano 7d535a
    if (strncmp(a,b,n) == 0 && (a[n] == 0 || a[n] == ','))
kusano 7d535a
        return 0;
kusano 7d535a
    return 1;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static lzo_bool m_strisdigit(const char *s)
kusano 7d535a
{
kusano 7d535a
    for (;;)
kusano 7d535a
    {
kusano 7d535a
        if (!is_digit(*s))
kusano 7d535a
            return 0;
kusano 7d535a
        s++;
kusano 7d535a
        if (*s == 0 || *s == ',')
kusano 7d535a
            return 1;
kusano 7d535a
    }
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void parse_methods(const char *p)
kusano 7d535a
{
kusano 7d535a
    const compress_t *c;
kusano 7d535a
kusano 7d535a
    for (;;)
kusano 7d535a
    {
kusano 7d535a
        if (p == NULL || p[0] == 0)
kusano 7d535a
            usage(progname,-1,1);
kusano 7d535a
        else if ((c = find_method_by_name(p)) != NULL)
kusano 7d535a
            add_method(c->id);
kusano 7d535a
        else if (m_strcmp(p,"all") == 0 || m_strcmp(p,"avail") == 0)
kusano 7d535a
            add_all_methods(1,M_LAST_COMPRESSOR);
kusano 7d535a
        else if (m_strcmp(p,"ALL") == 0)
kusano 7d535a
        {
kusano 7d535a
            add_all_methods(1,M_LAST_COMPRESSOR);
kusano 7d535a
            add_all_methods(9721,9729);
kusano 7d535a
            add_all_methods(9781,9789);
kusano 7d535a
        }
kusano 7d535a
        else if (m_strcmp(p,"lzo") == 0)
kusano 7d535a
            add_all_methods(1,M_MEMCPY);
kusano 7d535a
        else if (m_strcmp(p,"bench") == 0)
kusano 7d535a
            add_methods(benchmark_methods);
kusano 7d535a
        else if (m_strcmp(p,"m1") == 0)
kusano 7d535a
            add_methods(x1_methods);
kusano 7d535a
        else if (m_strcmp(p,"m99") == 0)
kusano 7d535a
            add_methods(x99_methods);
kusano 7d535a
        else if (m_strcmp(p,"m999") == 0)
kusano 7d535a
            add_methods(x999_methods);
kusano 7d535a
        else if (m_strcmp(p,"1x999") == 0)
kusano 7d535a
            add_all_methods(9721,9729);
kusano 7d535a
        else if (m_strcmp(p,"1y999") == 0)
kusano 7d535a
            add_all_methods(9821,9829);
kusano 7d535a
#if defined(ALG_ZLIB)
kusano 7d535a
        else if (m_strcmp(p,"zlib") == 0)
kusano 7d535a
            add_all_methods(M_ZLIB_8_1,M_ZLIB_8_9);
kusano 7d535a
#endif
kusano 7d535a
#if defined(ALG_BZIP2)
kusano 7d535a
        else if (m_strcmp(p,"bzip2") == 0)
kusano 7d535a
            add_all_methods(M_BZIP2_1,M_BZIP2_9);
kusano 7d535a
#endif
kusano 7d535a
#if defined(__LZO_PROFESSIONAL__)
kusano 7d535a
#  include "lzopro/t_opt_m.ch"
kusano 7d535a
#endif
kusano 7d535a
        else if (m_strisdigit(p))
kusano 7d535a
            add_method(atoi(p));
kusano 7d535a
        else
kusano 7d535a
        {
kusano 7d535a
            printf("%s: invalid method '%s'\n\n",progname,p);
kusano 7d535a
            exit(EXIT_USAGE);
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
        while (*p && *p != ',')
kusano 7d535a
            p++;
kusano 7d535a
        while (*p == ',')
kusano 7d535a
            p++;
kusano 7d535a
        if (*p == 0)
kusano 7d535a
            return;
kusano 7d535a
    }
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// options
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
enum {
kusano 7d535a
    OPT_LONGOPT_ONLY = 512,
kusano 7d535a
    OPT_ADLER32,
kusano 7d535a
    OPT_CALGARY_CORPUS,
kusano 7d535a
    OPT_CLEAR_WRKMEM,
kusano 7d535a
    OPT_CRC32,
kusano 7d535a
    OPT_DICT,
kusano 7d535a
    OPT_DUMP,
kusano 7d535a
    OPT_EXECUTION_TIME,
kusano 7d535a
    OPT_MAX_DATA_LEN,
kusano 7d535a
    OPT_MAX_DICT_LEN,
kusano 7d535a
    OPT_SILESIA_CORPUS,
kusano 7d535a
    OPT_UCLOCK,
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/o_enum.ch"
kusano 7d535a
#endif
kusano 7d535a
    OPT_UNUSED
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
static const struct mfx_option longopts[] =
kusano 7d535a
{
kusano 7d535a
 /* { name  has_arg  *flag  val } */
kusano 7d535a
    {"help",             0, 0, 'h'+256}, /* give help */
kusano 7d535a
    {"license",          0, 0, 'L'},     /* display software license */
kusano 7d535a
    {"quiet",            0, 0, 'q'},     /* quiet mode */
kusano 7d535a
    {"verbose",          0, 0, 'v'},     /* verbose mode */
kusano 7d535a
    {"version",          0, 0, 'V'+256}, /* display version number */
kusano 7d535a
kusano 7d535a
    {"adler32",          0, 0, OPT_ADLER32},
kusano 7d535a
    {"calgary-corpus",   1, 0, OPT_CALGARY_CORPUS},
kusano 7d535a
    {"clear-wrkmem",     0, 0, OPT_CLEAR_WRKMEM},
kusano 7d535a
    {"clock",            1, 0, OPT_UCLOCK},
kusano 7d535a
    {"corpus",           1, 0, OPT_CALGARY_CORPUS},
kusano 7d535a
    {"crc32",            0, 0, OPT_CRC32},
kusano 7d535a
    {"dict",             1, 0, OPT_DICT},
kusano 7d535a
    {"dump-compressed",  1, 0, OPT_DUMP},
kusano 7d535a
    {"execution-time",   0, 0, OPT_EXECUTION_TIME},
kusano 7d535a
    {"max-data-length",  1, 0, OPT_MAX_DATA_LEN},
kusano 7d535a
    {"max-dict-length",  1, 0, OPT_MAX_DICT_LEN},
kusano 7d535a
    {"silesia-corpus",   1, 0, OPT_SILESIA_CORPUS},
kusano 7d535a
    {"uclock",           1, 0, OPT_UCLOCK},
kusano 7d535a
    {"methods",          1, 0, 'm'},
kusano 7d535a
    {"totals",           0, 0, 'T'},
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/o_longopts.ch"
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    { 0, 0, 0, 0 }
kusano 7d535a
};
kusano 7d535a
kusano 7d535a
kusano 7d535a
static int do_option(int optc)
kusano 7d535a
{
kusano 7d535a
    switch (optc)
kusano 7d535a
    {
kusano 7d535a
    case 'A':
kusano 7d535a
        opt_use_asm_decompressor = 1;
kusano 7d535a
        break;
kusano 7d535a
    case 'b':
kusano 7d535a
        opt_block_size = 0; /* set to opt_max_data_len later */
kusano 7d535a
        if (mfx_optarg)
kusano 7d535a
        {
kusano 7d535a
            if (!mfx_optarg || !is_digit(mfx_optarg[0]))
kusano 7d535a
                return optc;
kusano 7d535a
            opt_block_size = atol(mfx_optarg);
kusano 7d535a
        }
kusano 7d535a
        break;
kusano 7d535a
    case 'c':
kusano 7d535a
    case 'C':
kusano 7d535a
        if (!mfx_optarg || !is_digit(mfx_optarg[0]))
kusano 7d535a
            return optc;
kusano 7d535a
        opt_c_loops = atol(mfx_optarg);
kusano 7d535a
        break;
kusano 7d535a
    case 'd':
kusano 7d535a
    case 'D':
kusano 7d535a
        if (!mfx_optarg || !is_digit(mfx_optarg[0]))
kusano 7d535a
            return optc;
kusano 7d535a
        opt_d_loops = atol(mfx_optarg);
kusano 7d535a
        break;
kusano 7d535a
    case 'F':
kusano 7d535a
        opt_use_asm_fast_decompressor = 1;
kusano 7d535a
        break;
kusano 7d535a
    case 'h':
kusano 7d535a
    case 'H':
kusano 7d535a
    case '?':
kusano 7d535a
    case 'h'+256:
kusano 7d535a
        usage(progname,EXIT_OK,0);
kusano 7d535a
        break;
kusano 7d535a
    case 'L':
kusano 7d535a
        license();
kusano 7d535a
        break;
kusano 7d535a
    case 'm':
kusano 7d535a
        parse_methods(mfx_optarg);
kusano 7d535a
        break;
kusano 7d535a
    case 'n':
kusano 7d535a
        if (!mfx_optarg || !is_digit(mfx_optarg[0]))
kusano 7d535a
            return optc;
kusano 7d535a
        opt_c_loops = opt_d_loops = atol(mfx_optarg);
kusano 7d535a
        break;
kusano 7d535a
    case 'O':
kusano 7d535a
        opt_optimize_compressed_data = 1;
kusano 7d535a
        break;
kusano 7d535a
    case 'q':
kusano 7d535a
        opt_verbose -= 1;
kusano 7d535a
        break;
kusano 7d535a
    case 'Q':
kusano 7d535a
        opt_verbose = 0;
kusano 7d535a
        break;
kusano 7d535a
    case 's':
kusano 7d535a
    case OPT_CALGARY_CORPUS:
kusano 7d535a
        if (!mfx_optarg || !mfx_optarg[0])
kusano 7d535a
            return optc;
kusano 7d535a
        opt_corpus_path = mfx_optarg;
kusano 7d535a
        opt_corpus = calgary_corpus;
kusano 7d535a
        break;
kusano 7d535a
    case OPT_SILESIA_CORPUS:
kusano 7d535a
        if (!mfx_optarg || !mfx_optarg[0])
kusano 7d535a
            return optc;
kusano 7d535a
        opt_corpus_path = mfx_optarg;
kusano 7d535a
        opt_corpus = silesia_corpus;
kusano 7d535a
        break;
kusano 7d535a
    case 'S':
kusano 7d535a
        opt_use_safe_decompressor = 1;
kusano 7d535a
        break;
kusano 7d535a
    case 'T':
kusano 7d535a
        opt_totals += 1;
kusano 7d535a
        break;
kusano 7d535a
    case 'v':
kusano 7d535a
        opt_verbose += 1;
kusano 7d535a
        break;
kusano 7d535a
    case 'V':
kusano 7d535a
    case 'V'+256:
kusano 7d535a
        exit(EXIT_OK);
kusano 7d535a
        break;
kusano 7d535a
    case '@':
kusano 7d535a
        opt_read_from_stdin = 1;
kusano 7d535a
        break;
kusano 7d535a
kusano 7d535a
    case '1': case '2': case '3': case '4': case '5':
kusano 7d535a
    case '6': case '7': case '8': case '9':
kusano 7d535a
        /* this is a dirty hack... */
kusano 7d535a
        parse_methods(nextchar-1);
kusano 7d535a
        if (nextchar[0])
kusano 7d535a
        {
kusano 7d535a
            nextchar = NULL;
kusano 7d535a
            mfx_optind++;
kusano 7d535a
        }
kusano 7d535a
        break;
kusano 7d535a
kusano 7d535a
    case OPT_ADLER32:
kusano 7d535a
        opt_compute_adler32 = 1;
kusano 7d535a
        break;
kusano 7d535a
    case OPT_CLEAR_WRKMEM:
kusano 7d535a
        opt_clear_wrkmem = 1;
kusano 7d535a
        break;
kusano 7d535a
    case OPT_CRC32:
kusano 7d535a
        opt_compute_crc32 = 1;
kusano 7d535a
        break;
kusano 7d535a
    case OPT_DICT:
kusano 7d535a
        opt_dict = 1;
kusano 7d535a
        opt_dictionary_file = mfx_optarg;
kusano 7d535a
        break;
kusano 7d535a
    case OPT_EXECUTION_TIME:
kusano 7d535a
        opt_execution_time = 1;
kusano 7d535a
        break;
kusano 7d535a
    case OPT_DUMP:
kusano 7d535a
        opt_dump_compressed_data = mfx_optarg;
kusano 7d535a
        break;
kusano 7d535a
    case OPT_MAX_DATA_LEN:
kusano 7d535a
        if (!mfx_optarg || !is_digit(mfx_optarg[0]))
kusano 7d535a
            return optc;
kusano 7d535a
        opt_max_data_len = atol(mfx_optarg);
kusano 7d535a
        break;
kusano 7d535a
    case OPT_MAX_DICT_LEN:
kusano 7d535a
        if (!mfx_optarg || !is_digit(mfx_optarg[0]))
kusano 7d535a
            return optc;
kusano 7d535a
        opt_max_dict_len = atol(mfx_optarg);
kusano 7d535a
        break;
kusano 7d535a
    case OPT_UCLOCK:
kusano 7d535a
        if (!mfx_optarg || !is_digit(mfx_optarg[0]))
kusano 7d535a
            return optc;
kusano 7d535a
        opt_uclock = atoi(mfx_optarg);
kusano 7d535a
#if defined(__ACCLIB_PCLOCK_CH_INCLUDED)
kusano 7d535a
        if (opt_uclock > 0)
kusano 7d535a
            uch.mode = opt_uclock;
kusano 7d535a
#endif
kusano 7d535a
        break;
kusano 7d535a
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/o_do_option.ch"
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    case '\0':
kusano 7d535a
        return -1;
kusano 7d535a
    case ':':
kusano 7d535a
        return -2;
kusano 7d535a
    default:
kusano 7d535a
        fprintf(stderr,"%s: internal error in getopt (%d)\n",progname,optc);
kusano 7d535a
        return -3;
kusano 7d535a
    }
kusano 7d535a
    return 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static int get_options(int argc, char **argv)
kusano 7d535a
{
kusano 7d535a
    int optc;
kusano 7d535a
kusano 7d535a
    mfx_optind = 0;
kusano 7d535a
    mfx_opterr = 1;
kusano 7d535a
    while ((optc = mfx_getopt_long (argc, argv,
kusano 7d535a
                      "Ab::c:C:d:D:FhHLm::n:OqQs:STvV@123456789"
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/o_shortopts.ch"
kusano 7d535a
#endif
kusano 7d535a
                      , longopts, (int *)0)) >= 0)
kusano 7d535a
    {
kusano 7d535a
        if (do_option(optc) != 0)
kusano 7d535a
            exit(EXIT_USAGE);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    return mfx_optind;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*************************************************************************
kusano 7d535a
// main
kusano 7d535a
**************************************************************************/
kusano 7d535a
kusano 7d535a
int __lzo_cdecl_main main(int argc, char *argv[])
kusano 7d535a
{
kusano 7d535a
    int r = EXIT_OK;
kusano 7d535a
    int i, ii;
kusano 7d535a
    int m;
kusano 7d535a
    time_t t_total;
kusano 7d535a
    const char *s;
kusano 7d535a
kusano 7d535a
    lzo_wildargv(&argc, &argv);
kusano 7d535a
    lzo_uclock_open(&uch);
kusano 7d535a
kusano 7d535a
    progname = argv[0];
kusano 7d535a
    for (s = progname; *s; s++)
kusano 7d535a
        if ((*s == '/' || *s == '\\') && s[1])
kusano 7d535a
            progname = s + 1;
kusano 7d535a
kusano 7d535a
#if defined(__LZO_PROFESSIONAL__)
kusano 7d535a
    printf("\nLZO Professional real-time data compression library (v%s, %s).\n",
kusano 7d535a
           lzo_version_string(), lzo_version_date());
kusano 7d535a
    printf("Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n");
kusano 7d535a
#elif defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/init.ch"
kusano 7d535a
#else
kusano 7d535a
    printf("\nLZO real-time data compression library (v%s, %s).\n",
kusano 7d535a
           lzo_version_string(), lzo_version_date());
kusano 7d535a
    printf("Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n");
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
 * Step 1: initialize the LZO library
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
    if (lzo_init() != LZO_E_OK)
kusano 7d535a
    {
kusano 7d535a
        printf("internal error - lzo_init() failed !!!\n");
kusano 7d535a
        printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable `-DLZO_DEBUG' for diagnostics)\n");
kusano 7d535a
        exit(1);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
 * Step 2: setup default options
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
    opt_max_data_len = 64 * 1024L * 1024L;
kusano 7d535a
    opt_block_size = 256 * 1024L;
kusano 7d535a
kusano 7d535a
#if defined(LZO_ARCH_I086) && defined(ACC_MM_AHSHIFT)
kusano 7d535a
#  if 1 && defined(LZO_ARCH_I086PM) && defined(BLX286)
kusano 7d535a
    opt_max_data_len = 32 * 1024L * 1024L;
kusano 7d535a
#  else
kusano 7d535a
    opt_max_data_len = 14 * 1024L * 1024L;
kusano 7d535a
#  endif
kusano 7d535a
    /* reduce memory requirements for ancient 16-bit DOS 640kB real-mode */
kusano 7d535a
    if (ACC_MM_AHSHIFT != 3) {
kusano 7d535a
        opt_max_data_len = 16 * 1024L;
kusano 7d535a
    }
kusano 7d535a
#elif defined(LZO_OS_TOS)
kusano 7d535a
    /* reduce memory requirements for 14 MB machines */
kusano 7d535a
    opt_max_data_len = 8 * 1024L * 1024L;
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
 * Step 3: parse options
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
    if (argc < 2)
kusano 7d535a
        usage(progname,-1,0);
kusano 7d535a
    i = get_options(argc,argv);
kusano 7d535a
kusano 7d535a
    if (methods_n == 0)
kusano 7d535a
        add_method(default_method);
kusano 7d535a
    if (methods_n > 1 && opt_read_from_stdin)
kusano 7d535a
    {
kusano 7d535a
        printf("%s: cannot use multiple methods and '-@'\n", progname);
kusano 7d535a
        exit(EXIT_USAGE);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    if (opt_block_size == 0)
kusano 7d535a
        opt_block_size = opt_max_data_len;
kusano 7d535a
    if (opt_block_size > opt_max_data_len)
kusano 7d535a
        opt_block_size = opt_max_data_len;
kusano 7d535a
kusano 7d535a
    if (opt_c_loops < 1)
kusano 7d535a
        opt_c_loops = 1;
kusano 7d535a
    if (opt_d_loops < 1)
kusano 7d535a
        opt_d_loops = 1;
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
 * Step 4: start work
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
    wrkmem.len = 0;
kusano 7d535a
    for (ii = 0; ii < methods_n; ii++) {
kusano 7d535a
        const compress_t *c = find_method_by_id(methods[ii]);
kusano 7d535a
        assert(c != NULL);
kusano 7d535a
        if (c->mem_compress > wrkmem.len)
kusano 7d535a
            wrkmem.len = c->mem_compress;
kusano 7d535a
        if (c->mem_decompress > wrkmem.len)
kusano 7d535a
            wrkmem.len = c->mem_decompress;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    mb_alloc(&wrkmem, wrkmem.len);
kusano 7d535a
kusano 7d535a
#if !defined(__LZO_CHECKER)
kusano 7d535a
    mb_alloc_extra(&block1, opt_block_size + get_max_compression_expansion(-1, opt_block_size), 16, 16);
kusano 7d535a
    mb_alloc_extra(&block2, opt_block_size + get_max_decompression_overrun(-1, opt_block_size), 16, 16);
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    if (opt_dict)
kusano 7d535a
    {
kusano 7d535a
        opt_optimize_compressed_data = 0;
kusano 7d535a
        dict_alloc(opt_max_dict_len);
kusano 7d535a
        if (opt_dictionary_file)
kusano 7d535a
        {
kusano 7d535a
            dict_load(opt_dictionary_file);
kusano 7d535a
            if (dict.len > 0)
kusano 7d535a
                printf("Using dictionary '%s', %ld bytes, ID 0x%08lx.\n",
kusano 7d535a
                        opt_dictionary_file,
kusano 7d535a
                        (long) dict.len, (long) dict.adler);
kusano 7d535a
        }
kusano 7d535a
        if (dict.len == 0)
kusano 7d535a
        {
kusano 7d535a
            dict_set_default();
kusano 7d535a
            printf("Using default dictionary, %ld bytes, ID 0x%08lx.\n",
kusano 7d535a
                    (long) dict.len, (long) dict.adler);
kusano 7d535a
        }
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    t_total = time(NULL);
kusano 7d535a
    ii = i;
kusano 7d535a
    for (m = 0; m < methods_n && r == EXIT_OK; m++)
kusano 7d535a
    {
kusano 7d535a
        int method = methods[m];
kusano 7d535a
kusano 7d535a
        i = ii;
kusano 7d535a
        if (i >= argc && opt_corpus_path == NULL && !opt_read_from_stdin)
kusano 7d535a
            usage(progname,-1,0);
kusano 7d535a
        if (m == 0 && opt_verbose >= 1)
kusano 7d535a
            printf("%lu block-size\n\n", (long) opt_block_size);
kusano 7d535a
kusano 7d535a
        assert(find_method_by_id(method) != NULL);
kusano 7d535a
kusano 7d535a
        if (opt_corpus_path != NULL)
kusano 7d535a
            r = do_corpus(opt_corpus, method, opt_corpus_path,
kusano 7d535a
                          opt_c_loops, opt_d_loops);
kusano 7d535a
        else
kusano 7d535a
        {
kusano 7d535a
            for ( ; i < argc && r == EXIT_OK; i++)
kusano 7d535a
            {
kusano 7d535a
                r = do_file(method,argv[i],opt_c_loops,opt_d_loops,NULL,NULL);
kusano 7d535a
                if (r == EXIT_FILE)     /* ignore file errors */
kusano 7d535a
                    r = EXIT_OK;
kusano 7d535a
            }
kusano 7d535a
            if (opt_read_from_stdin)
kusano 7d535a
            {
kusano 7d535a
                char buf[512], *p;
kusano 7d535a
kusano 7d535a
                while (r == EXIT_OK && fgets(buf,sizeof(buf)-1,stdin) != NULL)
kusano 7d535a
                {
kusano 7d535a
                    buf[sizeof(buf)-1] = 0;
kusano 7d535a
                    p = buf + strlen(buf);
kusano 7d535a
                    while (p > buf && is_space(p[-1]))
kusano 7d535a
                            *--p = 0;
kusano 7d535a
                    p = buf;
kusano 7d535a
                    while (*p && is_space(*p))
kusano 7d535a
                        p++;
kusano 7d535a
                    if (*p)
kusano 7d535a
                        r = do_file(method,p,opt_c_loops,opt_d_loops,NULL,NULL);
kusano 7d535a
                    if (r == EXIT_FILE)     /* ignore file errors */
kusano 7d535a
                        r = EXIT_OK;
kusano 7d535a
                }
kusano 7d535a
                opt_read_from_stdin = 0;
kusano 7d535a
            }
kusano 7d535a
        }
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
#if defined(LZOTEST_USE_DYNLOAD)
kusano 7d535a
#  include "dynload/exit.ch"
kusano 7d535a
#endif
kusano 7d535a
    t_total = time(NULL) - t_total;
kusano 7d535a
kusano 7d535a
    if (opt_totals)
kusano 7d535a
        print_totals();
kusano 7d535a
    if (opt_execution_time || (methods_n > 1 && opt_verbose >= 1))
kusano 7d535a
        printf("\n%s: execution time: %lu seconds\n", progname, (long) t_total);
kusano 7d535a
    if (r != EXIT_OK)
kusano 7d535a
        printf("\n%s: exit code: %d\n", progname, r);
kusano 7d535a
kusano 7d535a
    lzo_uclock_close(&uch);
kusano 7d535a
    return r;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
vi:ts=4:et
kusano 7d535a
*/
kusano 7d535a