kusano 7d535a
/*
kusano 7d535a
  LZ4cli - LZ4 Command Line Interface
kusano 7d535a
  Copyright (C) Yann Collet 2011-2015
kusano 7d535a
kusano 7d535a
  GPL v2 License
kusano 7d535a
kusano 7d535a
  This program is free software; you can redistribute it and/or modify
kusano 7d535a
  it under the terms of the GNU General Public License as published by
kusano 7d535a
  the Free Software Foundation; either version 2 of the License, or
kusano 7d535a
  (at your option) any later version.
kusano 7d535a
kusano 7d535a
  This program 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 along
kusano 7d535a
  with this program; 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
  You can contact the author at :
kusano 7d535a
  - LZ4 source repository : https://github.com/Cyan4973/lz4
kusano 7d535a
  - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
kusano 7d535a
*/
kusano 7d535a
/*
kusano 7d535a
  Note : this is stand-alone program.
kusano 7d535a
  It is not part of LZ4 compression library, it is a user program of the LZ4 library.
kusano 7d535a
  The license of LZ4 library is BSD.
kusano 7d535a
  The license of xxHash library is BSD.
kusano 7d535a
  The license of this compression CLI program is GPLv2.
kusano 7d535a
*/
kusano 7d535a
kusano 7d535a
/**************************************
kusano 7d535a
*  Tuning parameters
kusano 7d535a
***************************************/
kusano 7d535a
/* ENABLE_LZ4C_LEGACY_OPTIONS :
kusano 7d535a
   Control the availability of -c0, -c1 and -hc legacy arguments
kusano 7d535a
   Default : Legacy options are disabled */
kusano 7d535a
/* #define ENABLE_LZ4C_LEGACY_OPTIONS */
kusano 7d535a
kusano 7d535a
kusano 7d535a
/**************************************
kusano 7d535a
*  Compiler Options
kusano 7d535a
***************************************/
kusano 7d535a
/* Disable some Visual warning messages */
kusano 7d535a
#ifdef _MSC_VER
kusano 7d535a
#  define _CRT_SECURE_NO_WARNINGS
kusano 7d535a
#  define _CRT_SECURE_NO_DEPRECATE     /* VS2005 */
kusano 7d535a
#  pragma warning(disable : 4127)      /* disable: C4127: conditional expression is constant */
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
#define _POSIX_SOURCE 1        /* for fileno() within <stdio.h> on unix */</stdio.h>
kusano 7d535a
kusano 7d535a
kusano 7d535a
/****************************
kusano 7d535a
*  Includes
kusano 7d535a
*****************************/
kusano 7d535a
#include <stdio.h>    /* fprintf, getchar */</stdio.h>
kusano 7d535a
#include <stdlib.h>   /* exit, calloc, free */</stdlib.h>
kusano 7d535a
#include <string.h>   /* strcmp, strlen */</string.h>
kusano 7d535a
#include "bench.h"    /* BMK_benchFile, BMK_SetNbIterations, BMK_SetBlocksize, BMK_SetPause */
kusano 7d535a
#include "lz4io.h"    /* LZ4IO_compressFilename, LZ4IO_decompressFilename, LZ4IO_compressMultipleFilenames */
kusano 7d535a
kusano 7d535a
kusano 7d535a
/****************************
kusano 7d535a
*  OS-specific Includes
kusano 7d535a
*****************************/
kusano 7d535a
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32)
kusano 7d535a
#  include <io.h>       /* _isatty */</io.h>
kusano 7d535a
#  if defined(__DJGPP__)
kusano 7d535a
#    include <unistd.h></unistd.h>
kusano 7d535a
#    define _isatty isatty
kusano 7d535a
#    define _fileno fileno
kusano 7d535a
#  endif
kusano 7d535a
#  ifdef __MINGW32__
kusano 7d535a
   int _fileno(FILE *stream);   /* MINGW somehow forgets to include this prototype into <stdio.h> */</stdio.h>
kusano 7d535a
#  endif
kusano 7d535a
#  define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
kusano 7d535a
#else
kusano 7d535a
#  include <unistd.h>   /* isatty */</unistd.h>
kusano 7d535a
#  define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*****************************
kusano 7d535a
*  Constants
kusano 7d535a
******************************/
kusano 7d535a
#define COMPRESSOR_NAME "LZ4 command line interface"
kusano 7d535a
#ifndef LZ4_VERSION
kusano 7d535a
#  define LZ4_VERSION "r128"
kusano 7d535a
#endif
kusano 7d535a
#define AUTHOR "Yann Collet"
kusano 7d535a
#define WELCOME_MESSAGE "*** %s %i-bits %s, by %s (%s) ***\n", COMPRESSOR_NAME, (int)(sizeof(void*)*8), LZ4_VERSION, AUTHOR, __DATE__
kusano 7d535a
#define LZ4_EXTENSION ".lz4"
kusano 7d535a
#define LZ4CAT "lz4cat"
kusano 7d535a
#define UNLZ4 "unlz4"
kusano 7d535a
kusano 7d535a
#define KB *(1U<<10)
kusano 7d535a
#define MB *(1U<<20)
kusano 7d535a
#define GB *(1U<<30)
kusano 7d535a
kusano 7d535a
#define LZ4_BLOCKSIZEID_DEFAULT 7
kusano 7d535a
kusano 7d535a
kusano 7d535a
/**************************************
kusano 7d535a
*  Macros
kusano 7d535a
***************************************/
kusano 7d535a
#define DISPLAY(...)           fprintf(stderr, __VA_ARGS__)
kusano 7d535a
#define DISPLAYLEVEL(l, ...)   if (displayLevel>=l) { DISPLAY(__VA_ARGS__); }
kusano 7d535a
static unsigned displayLevel = 2;   /* 0 : no display ; 1: errors only ; 2 : downgradable normal ; 3 : non-downgradable normal; 4 : + information */
kusano 7d535a
kusano 7d535a
kusano 7d535a
/**************************************
kusano 7d535a
*  Local Variables
kusano 7d535a
***************************************/
kusano 7d535a
static char* programName;
kusano 7d535a
kusano 7d535a
kusano 7d535a
/**************************************
kusano 7d535a
*  Exceptions
kusano 7d535a
***************************************/
kusano 7d535a
#define DEBUG 0
kusano 7d535a
#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
kusano 7d535a
#define EXM_THROW(error, ...)                                             \
kusano 7d535a
{                                                                         \
kusano 7d535a
    DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \
kusano 7d535a
    DISPLAYLEVEL(1, "Error %i : ", error);                                \
kusano 7d535a
    DISPLAYLEVEL(1, __VA_ARGS__);                                         \
kusano 7d535a
    DISPLAYLEVEL(1, "\n");                                                \
kusano 7d535a
    exit(error);                                                          \
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
/**************************************
kusano 7d535a
*  Version modifiers
kusano 7d535a
***************************************/
kusano 7d535a
#define EXTENDED_ARGUMENTS
kusano 7d535a
#define EXTENDED_HELP
kusano 7d535a
#define EXTENDED_FORMAT
kusano 7d535a
#define DEFAULT_COMPRESSOR   LZ4IO_compressFilename
kusano 7d535a
#define DEFAULT_DECOMPRESSOR LZ4IO_decompressFilename
kusano 7d535a
int LZ4IO_compressFilename_Legacy(const char* input_filename, const char* output_filename, int compressionlevel);   /* hidden function */
kusano 7d535a
kusano 7d535a
kusano 7d535a
/*****************************
kusano 7d535a
*  Functions
kusano 7d535a
*****************************/
kusano 7d535a
static int usage(void)
kusano 7d535a
{
kusano 7d535a
    DISPLAY( "Usage :\n");
kusano 7d535a
    DISPLAY( "      %s [arg] [input] [output]\n", programName);
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "input   : a filename\n");
kusano 7d535a
    DISPLAY( "          with no FILE, or when FILE is - or %s, read standard input\n", stdinmark);
kusano 7d535a
    DISPLAY( "Arguments :\n");
kusano 7d535a
    DISPLAY( " -1     : Fast compression (default) \n");
kusano 7d535a
    DISPLAY( " -9     : High compression \n");
kusano 7d535a
    DISPLAY( " -d     : decompression (default for %s extension)\n", LZ4_EXTENSION);
kusano 7d535a
    DISPLAY( " -z     : force compression\n");
kusano 7d535a
    DISPLAY( " -f     : overwrite output without prompting \n");
kusano 7d535a
    DISPLAY( " -h/-H  : display help/long help and exit\n");
kusano 7d535a
    return 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static int usage_advanced(void)
kusano 7d535a
{
kusano 7d535a
    DISPLAY(WELCOME_MESSAGE);
kusano 7d535a
    usage();
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "Advanced arguments :\n");
kusano 7d535a
    DISPLAY( " -V     : display Version number and exit\n");
kusano 7d535a
    DISPLAY( " -v     : verbose mode\n");
kusano 7d535a
    DISPLAY( " -q     : suppress warnings; specify twice to suppress errors too\n");
kusano 7d535a
    DISPLAY( " -c     : force write to standard output, even if it is the console\n");
kusano 7d535a
    DISPLAY( " -t     : test compressed file integrity\n");
kusano 7d535a
    DISPLAY( " -m     : multiple input files (implies automatic output filenames)\n");
kusano 7d535a
    DISPLAY( " -l     : compress using Legacy format (Linux kernel compression)\n");
kusano 7d535a
    DISPLAY( " -B#    : Block size [4-7](default : 7)\n");
kusano 7d535a
    DISPLAY( " -BD    : Block dependency (improve compression ratio)\n");
kusano 7d535a
    /* DISPLAY( " -BX    : enable block checksum (default:disabled)\n");   *//* Option currently inactive */
kusano 7d535a
    DISPLAY( "--no-frame-crc : disable stream checksum (default:enabled)\n");
kusano 7d535a
    DISPLAY( "--content-size : compressed frame includes original size (default:not present)\n");
kusano 7d535a
    DISPLAY( "--[no-]sparse  : sparse mode (default:enabled on file, disabled on stdout)\n");
kusano 7d535a
    DISPLAY( "Benchmark arguments :\n");
kusano 7d535a
    DISPLAY( " -b     : benchmark file(s)\n");
kusano 7d535a
    DISPLAY( " -i#    : iteration loops [1-9](default : 3), benchmark mode only\n");
kusano 7d535a
#if defined(ENABLE_LZ4C_LEGACY_OPTIONS)
kusano 7d535a
    DISPLAY( "Legacy arguments :\n");
kusano 7d535a
    DISPLAY( " -c0    : fast compression\n");
kusano 7d535a
    DISPLAY( " -c1    : high compression\n");
kusano 7d535a
    DISPLAY( " -hc    : high compression\n");
kusano 7d535a
    DISPLAY( " -y     : overwrite output without prompting \n");
kusano 7d535a
#endif /* ENABLE_LZ4C_LEGACY_OPTIONS */
kusano 7d535a
    EXTENDED_HELP;
kusano 7d535a
    return 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static int usage_longhelp(void)
kusano 7d535a
{
kusano 7d535a
    usage_advanced();
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "Which values can get [output] ? \n");
kusano 7d535a
    DISPLAY( "[output] : a filename\n");
kusano 7d535a
    DISPLAY( "          '%s', or '-' for standard output (pipe mode)\n", stdoutmark);
kusano 7d535a
    DISPLAY( "          '%s' to discard output (test mode)\n", NULL_OUTPUT);
kusano 7d535a
    DISPLAY( "[output] can be left empty. In this case, it receives the following value : \n");
kusano 7d535a
    DISPLAY( "          - if stdout is not the console, then [output] = stdout \n");
kusano 7d535a
    DISPLAY( "          - if stdout is console : \n");
kusano 7d535a
    DISPLAY( "               + if compression selected, output to filename%s \n", LZ4_EXTENSION);
kusano 7d535a
    DISPLAY( "               + if decompression selected, output to filename without '%s'\n", LZ4_EXTENSION);
kusano 7d535a
    DISPLAY( "                    > if input filename has no '%s' extension : error\n", LZ4_EXTENSION);
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "Compression levels : \n");
kusano 7d535a
    DISPLAY( "There are technically 2 accessible compression levels.\n");
kusano 7d535a
    DISPLAY( "-0 ... -2 => Fast compression\n");
kusano 7d535a
    DISPLAY( "-3 ... -9 => High compression\n");
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "stdin, stdout and the console : \n");
kusano 7d535a
    DISPLAY( "To protect the console from binary flooding (bad argument mistake)\n");
kusano 7d535a
    DISPLAY( "%s will refuse to read from console, or write to console \n", programName);
kusano 7d535a
    DISPLAY( "except if '-c' command is specified, to force output to console \n");
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "Simple example :\n");
kusano 7d535a
    DISPLAY( "1 : compress 'filename' fast, using default output name 'filename.lz4'\n");
kusano 7d535a
    DISPLAY( "          %s filename\n", programName);
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "Arguments can be appended together, or provided independently. For example :\n");
kusano 7d535a
    DISPLAY( "2 : compress 'filename' in high compression mode, overwrite output if exists\n");
kusano 7d535a
    DISPLAY( "          %s -f9 filename \n", programName);
kusano 7d535a
    DISPLAY( "    is equivalent to :\n");
kusano 7d535a
    DISPLAY( "          %s -f -9 filename \n", programName);
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "%s can be used in 'pure pipe mode', for example :\n", programName);
kusano 7d535a
    DISPLAY( "3 : compress data stream from 'generator', send result to 'consumer'\n");
kusano 7d535a
    DISPLAY( "          generator | %s | consumer \n", programName);
kusano 7d535a
#if defined(ENABLE_LZ4C_LEGACY_OPTIONS)
kusano 7d535a
    DISPLAY( "\n");
kusano 7d535a
    DISPLAY( "Warning :\n");
kusano 7d535a
    DISPLAY( "Legacy arguments take precedence. Therefore : \n");
kusano 7d535a
    DISPLAY( "          %s -hc filename\n", programName);
kusano 7d535a
    DISPLAY( "means 'compress filename in high compression mode'\n");
kusano 7d535a
    DISPLAY( "It is not equivalent to :\n");
kusano 7d535a
    DISPLAY( "          %s -h -c filename\n", programName);
kusano 7d535a
    DISPLAY( "which would display help text and exit\n");
kusano 7d535a
#endif /* ENABLE_LZ4C_LEGACY_OPTIONS */
kusano 7d535a
    return 0;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static int badusage(void)
kusano 7d535a
{
kusano 7d535a
    DISPLAYLEVEL(1, "Incorrect parameters\n");
kusano 7d535a
    if (displayLevel >= 1) usage();
kusano 7d535a
    exit(1);
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
static void waitEnter(void)
kusano 7d535a
{
kusano 7d535a
    DISPLAY("Press enter to continue...\n");
kusano 7d535a
    (void)getchar();
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
kusano 7d535a
int main(int argc, char** argv)
kusano 7d535a
{
kusano 7d535a
    int i,
kusano 7d535a
        cLevel=0,
kusano 7d535a
        decode=0,
kusano 7d535a
        bench=0,
kusano 7d535a
        legacy_format=0,
kusano 7d535a
        forceStdout=0,
kusano 7d535a
        forceCompress=0,
kusano 7d535a
        main_pause=0,
kusano 7d535a
        multiple_inputs=0,
kusano 7d535a
        operationResult=0;
kusano 7d535a
    const char* input_filename=0;
kusano 7d535a
    const char* output_filename=0;
kusano 7d535a
    char* dynNameSpace=0;
kusano 7d535a
    const char** inFileNames = NULL;
kusano 7d535a
    unsigned ifnIdx=0;
kusano 7d535a
    char nullOutput[] = NULL_OUTPUT;
kusano 7d535a
    char extension[] = LZ4_EXTENSION;
kusano 7d535a
    int  blockSize;
kusano 7d535a
kusano 7d535a
    /* Init */
kusano 7d535a
    programName = argv[0];
kusano 7d535a
    LZ4IO_setOverwrite(0);
kusano 7d535a
    blockSize = LZ4IO_setBlockSizeID(LZ4_BLOCKSIZEID_DEFAULT);
kusano 7d535a
kusano 7d535a
    /* lz4cat predefined behavior */
kusano 7d535a
    if (!strcmp(programName, LZ4CAT)) { decode=1; forceStdout=1; output_filename=stdoutmark; displayLevel=1; }
kusano 7d535a
    if (!strcmp(programName, UNLZ4)) { decode=1; }
kusano 7d535a
kusano 7d535a
    /* command switches */
kusano 7d535a
    for(i=1; i
kusano 7d535a
    {
kusano 7d535a
        char* argument = argv[i];
kusano 7d535a
kusano 7d535a
        if(!argument) continue;   /* Protection if argument empty */
kusano 7d535a
kusano 7d535a
        /* long commands (--long-word) */
kusano 7d535a
        if (!strcmp(argument, "--compress")) { forceCompress = 1; continue; }
kusano 7d535a
        if ((!strcmp(argument, "--decompress"))
kusano 7d535a
         || (!strcmp(argument, "--uncompress"))) { decode = 1; continue; }
kusano 7d535a
        if (!strcmp(argument, "--multiple")) { multiple_inputs = 1; if (inFileNames==NULL) inFileNames = (const char**)malloc(argc * sizeof(char*)); continue; }
kusano 7d535a
        if (!strcmp(argument, "--test")) { decode = 1; LZ4IO_setOverwrite(1); output_filename=nulmark; continue; }
kusano 7d535a
        if (!strcmp(argument, "--force")) { LZ4IO_setOverwrite(1); continue; }
kusano 7d535a
        if (!strcmp(argument, "--no-force")) { LZ4IO_setOverwrite(0); continue; }
kusano 7d535a
        if ((!strcmp(argument, "--stdout"))
kusano 7d535a
         || (!strcmp(argument, "--to-stdout"))) { forceStdout=1; output_filename=stdoutmark; displayLevel=1; continue; }
kusano 7d535a
        if (!strcmp(argument, "--frame-crc")) { LZ4IO_setStreamChecksumMode(1); continue; }
kusano 7d535a
        if (!strcmp(argument, "--no-frame-crc")) { LZ4IO_setStreamChecksumMode(0); continue; }
kusano 7d535a
        if (!strcmp(argument, "--content-size")) { LZ4IO_setContentSize(1); continue; }
kusano 7d535a
        if (!strcmp(argument, "--no-content-size")) { LZ4IO_setContentSize(0); continue; }
kusano 7d535a
        if (!strcmp(argument, "--sparse")) { LZ4IO_setSparseFile(2); continue; }
kusano 7d535a
        if (!strcmp(argument, "--no-sparse")) { LZ4IO_setSparseFile(0); continue; }
kusano 7d535a
        if (!strcmp(argument, "--verbose")) { displayLevel=4; continue; }
kusano 7d535a
        if (!strcmp(argument, "--quiet")) { if (displayLevel) displayLevel--; continue; }
kusano 7d535a
        if (!strcmp(argument, "--version")) { DISPLAY(WELCOME_MESSAGE); return 0; }
kusano 7d535a
        if (!strcmp(argument, "--keep")) { continue; }   /* keep source file (default anyway; just for xz/lzma compatibility) */
kusano 7d535a
kusano 7d535a
kusano 7d535a
        /* Short commands (note : aggregated short commands are allowed) */
kusano 7d535a
        if (argument[0]=='-')
kusano 7d535a
        {
kusano 7d535a
            /* '-' means stdin/stdout */
kusano 7d535a
            if (argument[1]==0)
kusano 7d535a
            {
kusano 7d535a
                if (!input_filename) input_filename=stdinmark;
kusano 7d535a
                else output_filename=stdoutmark;
kusano 7d535a
            }
kusano 7d535a
kusano 7d535a
            while (argument[1]!=0)
kusano 7d535a
            {
kusano 7d535a
                argument ++;
kusano 7d535a
kusano 7d535a
#if defined(ENABLE_LZ4C_LEGACY_OPTIONS)
kusano 7d535a
                /* Legacy arguments (-c0, -c1, -hc, -y, -s) */
kusano 7d535a
                if ((argument[0]=='c') && (argument[1]=='0')) { cLevel=0; argument++; continue; }  /* -c0 (fast compression) */
kusano 7d535a
                if ((argument[0]=='c') && (argument[1]=='1')) { cLevel=9; argument++; continue; }  /* -c1 (high compression) */
kusano 7d535a
                if ((argument[0]=='h') && (argument[1]=='c')) { cLevel=9; argument++; continue; }  /* -hc (high compression) */
kusano 7d535a
                if (*argument=='y') { LZ4IO_setOverwrite(1); continue; }                           /* -y (answer 'yes' to overwrite permission) */
kusano 7d535a
#endif /* ENABLE_LZ4C_LEGACY_OPTIONS */
kusano 7d535a
kusano 7d535a
                if ((*argument>='0') && (*argument<='9'))
kusano 7d535a
                {
kusano 7d535a
                    cLevel = 0;
kusano 7d535a
                    while ((*argument >= '0') && (*argument <= '9'))
kusano 7d535a
                    {
kusano 7d535a
                        cLevel *= 10;
kusano 7d535a
                        cLevel += *argument - '0';
kusano 7d535a
                        argument++;
kusano 7d535a
                    }
kusano 7d535a
                    argument--;
kusano 7d535a
                    continue;
kusano 7d535a
                }
kusano 7d535a
kusano 7d535a
                switch(argument[0])
kusano 7d535a
                {
kusano 7d535a
                    /* Display help */
kusano 7d535a
                case 'V': DISPLAY(WELCOME_MESSAGE); goto _cleanup;   /* Version */
kusano 7d535a
                case 'h': usage_advanced(); goto _cleanup;
kusano 7d535a
                case 'H': usage_longhelp(); goto _cleanup;
kusano 7d535a
kusano 7d535a
                    /* Compression (default) */
kusano 7d535a
                case 'z': forceCompress = 1; break;
kusano 7d535a
kusano 7d535a
                    /* Use Legacy format (ex : Linux kernel compression) */
kusano 7d535a
                case 'l': legacy_format = 1; blockSize = 8 MB; break;
kusano 7d535a
kusano 7d535a
                    /* Decoding */
kusano 7d535a
                case 'd': decode=1; break;
kusano 7d535a
kusano 7d535a
                    /* Force stdout, even if stdout==console */
kusano 7d535a
                case 'c': forceStdout=1; output_filename=stdoutmark; displayLevel=1; break;
kusano 7d535a
kusano 7d535a
                    /* Test integrity */
kusano 7d535a
                case 't': decode=1; LZ4IO_setOverwrite(1); output_filename=nulmark; break;
kusano 7d535a
kusano 7d535a
                    /* Overwrite */
kusano 7d535a
                case 'f': LZ4IO_setOverwrite(1); break;
kusano 7d535a
kusano 7d535a
                    /* Verbose mode */
kusano 7d535a
                case 'v': displayLevel=4; break;
kusano 7d535a
kusano 7d535a
                    /* Quiet mode */
kusano 7d535a
                case 'q': if (displayLevel) displayLevel--; break;
kusano 7d535a
kusano 7d535a
                    /* keep source file (default anyway, so useless) (for xz/lzma compatibility) */
kusano 7d535a
                case 'k': break;
kusano 7d535a
kusano 7d535a
                    /* Modify Block Properties */
kusano 7d535a
                case 'B':
kusano 7d535a
                    while (argument[1]!=0)
kusano 7d535a
                    {
kusano 7d535a
                        int exitBlockProperties=0;
kusano 7d535a
                        switch(argument[1])
kusano 7d535a
                        {
kusano 7d535a
                        case '4':
kusano 7d535a
                        case '5':
kusano 7d535a
                        case '6':
kusano 7d535a
                        case '7':
kusano 7d535a
                        {
kusano 7d535a
                            int B = argument[1] - '0';
kusano 7d535a
                            blockSize = LZ4IO_setBlockSizeID(B);
kusano 7d535a
                            BMK_setBlocksize(blockSize);
kusano 7d535a
                            argument++;
kusano 7d535a
                            break;
kusano 7d535a
                        }
kusano 7d535a
                        case 'D': LZ4IO_setBlockMode(LZ4IO_blockLinked); argument++; break;
kusano 7d535a
                        case 'X': LZ4IO_setBlockChecksumMode(1); argument ++; break;   /* currently disabled */
kusano 7d535a
                        default : exitBlockProperties=1;
kusano 7d535a
                        }
kusano 7d535a
                        if (exitBlockProperties) break;
kusano 7d535a
                    }
kusano 7d535a
                    break;
kusano 7d535a
kusano 7d535a
                    /* Benchmark */
kusano 7d535a
                case 'b': bench=1; multiple_inputs=1;
kusano 7d535a
                    if (inFileNames == NULL)
kusano 7d535a
                        inFileNames = (const char**) malloc(argc * sizeof(char*));
kusano 7d535a
                    break;
kusano 7d535a
kusano 7d535a
                    /* Treat non-option args as input files.  See https://code.google.com/p/lz4/issues/detail?id=151 */
kusano 7d535a
                case 'm': multiple_inputs=1;
kusano 7d535a
                    if (inFileNames == NULL)
kusano 7d535a
                        inFileNames = (const char**) malloc(argc * sizeof(char*));
kusano 7d535a
                    break;
kusano 7d535a
kusano 7d535a
                    /* Modify Nb Iterations (benchmark only) */
kusano 7d535a
                case 'i':
kusano 7d535a
                    {
kusano 7d535a
                        unsigned iters = 0;
kusano 7d535a
                        while ((argument[1] >='0') && (argument[1] <='9'))
kusano 7d535a
                        {
kusano 7d535a
                            iters *= 10;
kusano 7d535a
                            iters += argument[1] - '0';
kusano 7d535a
                            argument++;
kusano 7d535a
                        }
kusano 7d535a
                        BMK_setNbIterations(iters);
kusano 7d535a
                    }
kusano 7d535a
                    break;
kusano 7d535a
kusano 7d535a
                    /* Pause at the end (hidden option) */
kusano 7d535a
                case 'p': main_pause=1; BMK_setPause(); break;
kusano 7d535a
kusano 7d535a
                    /* Specific commands for customized versions */
kusano 7d535a
                EXTENDED_ARGUMENTS;
kusano 7d535a
kusano 7d535a
                    /* Unrecognised command */
kusano 7d535a
                default : badusage();
kusano 7d535a
                }
kusano 7d535a
            }
kusano 7d535a
            continue;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
        /* Store in *inFileNames[] if -m is used. */
kusano 7d535a
        if (multiple_inputs) { inFileNames[ifnIdx++]=argument; continue; }
kusano 7d535a
kusano 7d535a
        /* Store first non-option arg in input_filename to preserve original cli logic. */
kusano 7d535a
        if (!input_filename) { input_filename=argument; continue; }
kusano 7d535a
kusano 7d535a
        /* Second non-option arg in output_filename to preserve original cli logic. */
kusano 7d535a
        if (!output_filename)
kusano 7d535a
        {
kusano 7d535a
            output_filename=argument;
kusano 7d535a
            if (!strcmp (output_filename, nullOutput)) output_filename = nulmark;
kusano 7d535a
            continue;
kusano 7d535a
        }
kusano 7d535a
kusano 7d535a
        /* 3rd non-option arg should not exist */
kusano 7d535a
        DISPLAYLEVEL(1, "Warning : %s won't be used ! Do you want multiple input files (-m) ? \n", argument);
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    DISPLAYLEVEL(3, WELCOME_MESSAGE);
kusano 7d535a
    if (!decode) DISPLAYLEVEL(4, "Blocks size : %i KB\n", blockSize>>10);
kusano 7d535a
kusano 7d535a
    /* No input filename ==> use stdin */
kusano 7d535a
    if (multiple_inputs) input_filename = inFileNames[0], output_filename = (const char*)(inFileNames[0]);
kusano 7d535a
    if(!input_filename) { input_filename=stdinmark; }
kusano 7d535a
kusano 7d535a
    /* Check if input is defined as console; trigger an error in this case */
kusano 7d535a
    if (!strcmp(input_filename, stdinmark) && IS_CONSOLE(stdin) ) badusage();
kusano 7d535a
kusano 7d535a
    /* Check if benchmark is selected */
kusano 7d535a
    if (bench)
kusano 7d535a
    {
kusano 7d535a
        int bmkResult = BMK_benchFiles(inFileNames, ifnIdx, cLevel);
kusano 7d535a
        free((void*)inFileNames);
kusano 7d535a
        return bmkResult;
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    /* No output filename ==> try to select one automatically (when possible) */
kusano 7d535a
    while (!output_filename)
kusano 7d535a
    {
kusano 7d535a
        if (!IS_CONSOLE(stdout)) { output_filename=stdoutmark; break; }   /* Default to stdout whenever possible (i.e. not a console) */
kusano 7d535a
        if ((!decode) && !(forceCompress))   /* auto-determine compression or decompression, based on file extension */
kusano 7d535a
        {
kusano 7d535a
            size_t l = strlen(input_filename);
kusano 7d535a
            if (!strcmp(input_filename+(l-4), LZ4_EXTENSION)) decode=1;
kusano 7d535a
        }
kusano 7d535a
        if (!decode)   /* compression to file */
kusano 7d535a
        {
kusano 7d535a
            size_t l = strlen(input_filename);
kusano 7d535a
            dynNameSpace = (char*)calloc(1,l+5);
kusano 7d535a
			if (dynNameSpace==NULL) exit(1);
kusano 7d535a
            strcpy(dynNameSpace, input_filename);
kusano 7d535a
            strcat(dynNameSpace, LZ4_EXTENSION);
kusano 7d535a
            output_filename = dynNameSpace;
kusano 7d535a
            DISPLAYLEVEL(2, "Compressed filename will be : %s \n", output_filename);
kusano 7d535a
            break;
kusano 7d535a
        }
kusano 7d535a
        /* decompression to file (automatic name will work only if input filename has correct format extension) */
kusano 7d535a
        {
kusano 7d535a
            size_t outl;
kusano 7d535a
            size_t inl = strlen(input_filename);
kusano 7d535a
            dynNameSpace = (char*)calloc(1,inl+1);
kusano 7d535a
            strcpy(dynNameSpace, input_filename);
kusano 7d535a
            outl = inl;
kusano 7d535a
            if (inl>4)
kusano 7d535a
                while ((outl >= inl-4) && (input_filename[outl] ==  extension[outl-inl+4])) dynNameSpace[outl--]=0;
kusano 7d535a
            if (outl != inl-5) { DISPLAYLEVEL(1, "Cannot determine an output filename\n"); badusage(); }
kusano 7d535a
            output_filename = dynNameSpace;
kusano 7d535a
            DISPLAYLEVEL(2, "Decoding file %s \n", output_filename);
kusano 7d535a
        }
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    /* Check if output is defined as console; trigger an error in this case */
kusano 7d535a
    if (!strcmp(output_filename,stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) badusage();
kusano 7d535a
kusano 7d535a
    /* Downgrade notification level in pure pipe mode (stdin + stdout) and multiple file mode */
kusano 7d535a
    if (!strcmp(input_filename, stdinmark) && !strcmp(output_filename,stdoutmark) && (displayLevel==2)) displayLevel=1;
kusano 7d535a
    if ((multiple_inputs) && (displayLevel==2)) displayLevel=1;
kusano 7d535a
kusano 7d535a
kusano 7d535a
    /* IO Stream/File */
kusano 7d535a
    LZ4IO_setNotificationLevel(displayLevel);
kusano 7d535a
    if (decode)
kusano 7d535a
    {
kusano 7d535a
      if (multiple_inputs)
kusano 7d535a
        operationResult = LZ4IO_decompressMultipleFilenames(inFileNames, ifnIdx, LZ4_EXTENSION);
kusano 7d535a
      else
kusano 7d535a
        DEFAULT_DECOMPRESSOR(input_filename, output_filename);
kusano 7d535a
    }
kusano 7d535a
    else
kusano 7d535a
    {
kusano 7d535a
      /* compression is default action */
kusano 7d535a
      if (legacy_format)
kusano 7d535a
      {
kusano 7d535a
        DISPLAYLEVEL(3, "! Generating compressed LZ4 using Legacy format (deprecated) ! \n");
kusano 7d535a
        LZ4IO_compressFilename_Legacy(input_filename, output_filename, cLevel);
kusano 7d535a
      }
kusano 7d535a
      else
kusano 7d535a
      {
kusano 7d535a
        if (multiple_inputs)
kusano 7d535a
          operationResult = LZ4IO_compressMultipleFilenames(inFileNames, ifnIdx, LZ4_EXTENSION, cLevel);
kusano 7d535a
        else
kusano 7d535a
          DEFAULT_COMPRESSOR(input_filename, output_filename, cLevel);
kusano 7d535a
      }
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
_cleanup:
kusano 7d535a
    if (main_pause) waitEnter();
kusano 7d535a
    free(dynNameSpace);
kusano 7d535a
    free((void*)inFileNames);
kusano 7d535a
    return operationResult;
kusano 7d535a
}