1*27162e4eSAndroid Build Coastguard Worker /*
2*27162e4eSAndroid Build Coastguard Worker LZ4cli - LZ4 Command Line Interface
3*27162e4eSAndroid Build Coastguard Worker Copyright (C) Yann Collet 2011-2023
4*27162e4eSAndroid Build Coastguard Worker
5*27162e4eSAndroid Build Coastguard Worker GPL v2 License
6*27162e4eSAndroid Build Coastguard Worker
7*27162e4eSAndroid Build Coastguard Worker This program is free software; you can redistribute it and/or modify
8*27162e4eSAndroid Build Coastguard Worker it under the terms of the GNU General Public License as published by
9*27162e4eSAndroid Build Coastguard Worker the Free Software Foundation; either version 2 of the License, or
10*27162e4eSAndroid Build Coastguard Worker (at your option) any later version.
11*27162e4eSAndroid Build Coastguard Worker
12*27162e4eSAndroid Build Coastguard Worker This program is distributed in the hope that it will be useful,
13*27162e4eSAndroid Build Coastguard Worker but WITHOUT ANY WARRANTY; without even the implied warranty of
14*27162e4eSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*27162e4eSAndroid Build Coastguard Worker GNU General Public License for more details.
16*27162e4eSAndroid Build Coastguard Worker
17*27162e4eSAndroid Build Coastguard Worker You should have received a copy of the GNU General Public License along
18*27162e4eSAndroid Build Coastguard Worker with this program; if not, write to the Free Software Foundation, Inc.,
19*27162e4eSAndroid Build Coastguard Worker 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20*27162e4eSAndroid Build Coastguard Worker
21*27162e4eSAndroid Build Coastguard Worker You can contact the author at :
22*27162e4eSAndroid Build Coastguard Worker - LZ4 source repository : https://github.com/lz4/lz4
23*27162e4eSAndroid Build Coastguard Worker - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
24*27162e4eSAndroid Build Coastguard Worker */
25*27162e4eSAndroid Build Coastguard Worker /*
26*27162e4eSAndroid Build Coastguard Worker Note : this is stand-alone program.
27*27162e4eSAndroid Build Coastguard Worker It is not part of LZ4 compression library, it is a user program of the LZ4 library.
28*27162e4eSAndroid Build Coastguard Worker The license of LZ4 library is BSD.
29*27162e4eSAndroid Build Coastguard Worker The license of xxHash library is BSD.
30*27162e4eSAndroid Build Coastguard Worker The license of this compression CLI program is GPLv2.
31*27162e4eSAndroid Build Coastguard Worker */
32*27162e4eSAndroid Build Coastguard Worker
33*27162e4eSAndroid Build Coastguard Worker
34*27162e4eSAndroid Build Coastguard Worker /*-************************************
35*27162e4eSAndroid Build Coastguard Worker * Compiler options
36*27162e4eSAndroid Build Coastguard Worker **************************************/
37*27162e4eSAndroid Build Coastguard Worker #ifdef _MSC_VER /* Visual Studio */
38*27162e4eSAndroid Build Coastguard Worker # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
39*27162e4eSAndroid Build Coastguard Worker #endif
40*27162e4eSAndroid Build Coastguard Worker
41*27162e4eSAndroid Build Coastguard Worker
42*27162e4eSAndroid Build Coastguard Worker /****************************
43*27162e4eSAndroid Build Coastguard Worker * Includes
44*27162e4eSAndroid Build Coastguard Worker *****************************/
45*27162e4eSAndroid Build Coastguard Worker #include "platform.h" /* Compiler options, IS_CONSOLE */
46*27162e4eSAndroid Build Coastguard Worker #include "util.h" /* UTIL_HAS_CREATEFILELIST, UTIL_createFileList */
47*27162e4eSAndroid Build Coastguard Worker #include <stdio.h> /* fprintf, getchar */
48*27162e4eSAndroid Build Coastguard Worker #include <stdlib.h> /* exit, calloc, free */
49*27162e4eSAndroid Build Coastguard Worker #include <string.h> /* strcmp, strlen */
50*27162e4eSAndroid Build Coastguard Worker #include "lz4conf.h" /* compile-time constants */
51*27162e4eSAndroid Build Coastguard Worker #include "bench.h" /* BMK_benchFile, BMK_SetNbIterations, BMK_SetBlocksize, BMK_SetPause */
52*27162e4eSAndroid Build Coastguard Worker #include "lz4io.h" /* LZ4IO_compressFilename, LZ4IO_decompressFilename, LZ4IO_compressMultipleFilenames */
53*27162e4eSAndroid Build Coastguard Worker #include "lz4hc.h" /* LZ4HC_CLEVEL_MAX */
54*27162e4eSAndroid Build Coastguard Worker #include "lz4.h" /* LZ4_VERSION_STRING */
55*27162e4eSAndroid Build Coastguard Worker
56*27162e4eSAndroid Build Coastguard Worker
57*27162e4eSAndroid Build Coastguard Worker /*****************************
58*27162e4eSAndroid Build Coastguard Worker * Constants
59*27162e4eSAndroid Build Coastguard Worker ******************************/
60*27162e4eSAndroid Build Coastguard Worker #if LZ4IO_MULTITHREAD
61*27162e4eSAndroid Build Coastguard Worker # define IO_MT "multithread"
62*27162e4eSAndroid Build Coastguard Worker #else
63*27162e4eSAndroid Build Coastguard Worker # define IO_MT "single-thread"
64*27162e4eSAndroid Build Coastguard Worker #endif
65*27162e4eSAndroid Build Coastguard Worker #define COMPRESSOR_NAME "lz4"
66*27162e4eSAndroid Build Coastguard Worker #define AUTHOR "Yann Collet"
67*27162e4eSAndroid Build Coastguard Worker #define WELCOME_MESSAGE "*** %s v%s %i-bit %s, by %s ***\n", COMPRESSOR_NAME, LZ4_versionString(), (int)(sizeof(void*)*8), IO_MT, AUTHOR
68*27162e4eSAndroid Build Coastguard Worker #define LZ4_EXTENSION ".lz4"
69*27162e4eSAndroid Build Coastguard Worker #define LZ4CAT "lz4cat"
70*27162e4eSAndroid Build Coastguard Worker #define UNLZ4 "unlz4"
71*27162e4eSAndroid Build Coastguard Worker #define LZ4_LEGACY "lz4c"
72*27162e4eSAndroid Build Coastguard Worker static int g_lz4c_legacy_commands = 0;
73*27162e4eSAndroid Build Coastguard Worker
74*27162e4eSAndroid Build Coastguard Worker #define KB *(1U<<10)
75*27162e4eSAndroid Build Coastguard Worker #define MB *(1U<<20)
76*27162e4eSAndroid Build Coastguard Worker #define GB *(1U<<30)
77*27162e4eSAndroid Build Coastguard Worker
78*27162e4eSAndroid Build Coastguard Worker
79*27162e4eSAndroid Build Coastguard Worker /*-************************************
80*27162e4eSAndroid Build Coastguard Worker * Macros
81*27162e4eSAndroid Build Coastguard Worker ***************************************/
82*27162e4eSAndroid Build Coastguard Worker #define DISPLAYOUT(...) fprintf(stdout, __VA_ARGS__)
83*27162e4eSAndroid Build Coastguard Worker #define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
84*27162e4eSAndroid Build Coastguard Worker #define DISPLAYLEVEL(l, ...) do { if (displayLevel>=l) DISPLAY(__VA_ARGS__); } while (0)
85*27162e4eSAndroid Build Coastguard Worker static unsigned displayLevel = 2; /* 0 : no display ; 1: errors only ; 2 : downgradable normal ; 3 : non-downgradable normal; 4 : + information */
86*27162e4eSAndroid Build Coastguard Worker
87*27162e4eSAndroid Build Coastguard Worker
88*27162e4eSAndroid Build Coastguard Worker /*-************************************
89*27162e4eSAndroid Build Coastguard Worker * Errors and Messages
90*27162e4eSAndroid Build Coastguard Worker ***************************************/
91*27162e4eSAndroid Build Coastguard Worker #ifndef DEBUG
92*27162e4eSAndroid Build Coastguard Worker # define DEBUG 0
93*27162e4eSAndroid Build Coastguard Worker #endif
94*27162e4eSAndroid Build Coastguard Worker #define DEBUGOUTPUT(...) do { if (DEBUG) DISPLAY(__VA_ARGS__); } while (0)
95*27162e4eSAndroid Build Coastguard Worker #define END_PROCESS(error, ...) \
96*27162e4eSAndroid Build Coastguard Worker do { \
97*27162e4eSAndroid Build Coastguard Worker DEBUGOUTPUT("Error in %s, line %i : \n", __FILE__, __LINE__); \
98*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "Error %i : ", error); \
99*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, __VA_ARGS__); \
100*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "\n"); \
101*27162e4eSAndroid Build Coastguard Worker exit(error); \
102*27162e4eSAndroid Build Coastguard Worker } while (0)
103*27162e4eSAndroid Build Coastguard Worker
errorOut(const char * msg)104*27162e4eSAndroid Build Coastguard Worker static void errorOut(const char* msg)
105*27162e4eSAndroid Build Coastguard Worker {
106*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "%s \n", msg); exit(1);
107*27162e4eSAndroid Build Coastguard Worker }
108*27162e4eSAndroid Build Coastguard Worker
109*27162e4eSAndroid Build Coastguard Worker
110*27162e4eSAndroid Build Coastguard Worker /*-************************************
111*27162e4eSAndroid Build Coastguard Worker * Version modifiers
112*27162e4eSAndroid Build Coastguard Worker ***************************************/
113*27162e4eSAndroid Build Coastguard Worker #define DEFAULT_COMPRESSOR LZ4IO_compressFilename
114*27162e4eSAndroid Build Coastguard Worker #define DEFAULT_DECOMPRESSOR LZ4IO_decompressFilename
115*27162e4eSAndroid Build Coastguard Worker int LZ4IO_compressFilename_Legacy(const char* input_filename, const char* output_filename, int compressionlevel, const LZ4IO_prefs_t* prefs); /* hidden function */
116*27162e4eSAndroid Build Coastguard Worker int LZ4IO_compressMultipleFilenames_Legacy(
117*27162e4eSAndroid Build Coastguard Worker const char** inFileNamesTable, int ifntSize,
118*27162e4eSAndroid Build Coastguard Worker const char* suffix,
119*27162e4eSAndroid Build Coastguard Worker int compressionLevel, const LZ4IO_prefs_t* prefs);
120*27162e4eSAndroid Build Coastguard Worker
121*27162e4eSAndroid Build Coastguard Worker /*-***************************
122*27162e4eSAndroid Build Coastguard Worker * Functions
123*27162e4eSAndroid Build Coastguard Worker *****************************/
usage(const char * exeName)124*27162e4eSAndroid Build Coastguard Worker static int usage(const char* exeName)
125*27162e4eSAndroid Build Coastguard Worker {
126*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Usage : \n");
127*27162e4eSAndroid Build Coastguard Worker DISPLAY( " %s [arg] [input] [output] \n", exeName);
128*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
129*27162e4eSAndroid Build Coastguard Worker DISPLAY( "input : a filename \n");
130*27162e4eSAndroid Build Coastguard Worker DISPLAY( " with no FILE, or when FILE is - or %s, read standard input\n", stdinmark);
131*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Arguments : \n");
132*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -1 : fast compression (default) \n");
133*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -%2d : slowest compression level \n", LZ4HC_CLEVEL_MAX);
134*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -T# : use # threads for compression (default:%i==auto) \n", LZ4_NBWORKERS_DEFAULT);
135*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -d : decompression (default for %s extension)\n", LZ4_EXTENSION);
136*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -f : overwrite output without prompting \n");
137*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -k : preserve source files(s) (default) \n");
138*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--rm : remove source file(s) after successful de/compression \n");
139*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -h/-H : display help/long help and exit \n");
140*27162e4eSAndroid Build Coastguard Worker return 0;
141*27162e4eSAndroid Build Coastguard Worker }
142*27162e4eSAndroid Build Coastguard Worker
usage_advanced(const char * exeName)143*27162e4eSAndroid Build Coastguard Worker static int usage_advanced(const char* exeName)
144*27162e4eSAndroid Build Coastguard Worker {
145*27162e4eSAndroid Build Coastguard Worker DISPLAY(WELCOME_MESSAGE);
146*27162e4eSAndroid Build Coastguard Worker usage(exeName);
147*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
148*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Advanced arguments :\n");
149*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -V : display Version number and exit \n");
150*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -v : verbose mode \n");
151*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n");
152*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -c : force write to standard output, even if it is the console\n");
153*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -t : test compressed file integrity\n");
154*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -m : multiple input files (implies automatic output filenames)\n");
155*27162e4eSAndroid Build Coastguard Worker #ifdef UTIL_HAS_CREATEFILELIST
156*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -r : operate recursively on directories (sets also -m) \n");
157*27162e4eSAndroid Build Coastguard Worker #endif
158*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -l : compress using Legacy format (Linux kernel compression)\n");
159*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -z : force compression \n");
160*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -D FILE: use FILE as dictionary (compression & decompression)\n");
161*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -B# : cut file into blocks of size # bytes [32+] \n");
162*27162e4eSAndroid Build Coastguard Worker DISPLAY( " or predefined block size [4-7] (default: %i) \n", LZ4_BLOCKSIZEID_DEFAULT);
163*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -BI : Block Independence (default) \n");
164*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -BD : Block dependency (improves compression ratio) \n");
165*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -BX : enable block checksum (default:disabled) \n");
166*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--no-frame-crc : disable stream checksum (default:enabled) \n");
167*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--content-size : compressed frame includes original size (default:not present)\n");
168*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--list FILE : lists information about .lz4 files (useful for files compressed with --content-size flag)\n");
169*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)\n");
170*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--favor-decSpeed: compressed files decompress faster, but are less compressed \n");
171*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--fast[=#]: switch to ultra fast compression level (default: %i)\n", 1);
172*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--best : same as -%d\n", LZ4HC_CLEVEL_MAX);
173*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Benchmark arguments : \n");
174*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -b# : benchmark file(s), using # compression level (default : 1) \n");
175*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -e# : test all compression levels from -bX to # (default : 1)\n");
176*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -i# : minimum evaluation time in seconds (default : 3s) \n");
177*27162e4eSAndroid Build Coastguard Worker if (g_lz4c_legacy_commands) {
178*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Legacy arguments : \n");
179*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -c0 : fast compression \n");
180*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -c1 : high compression \n");
181*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -c2,-hc: very high compression \n");
182*27162e4eSAndroid Build Coastguard Worker DISPLAY( " -y : overwrite output without prompting \n");
183*27162e4eSAndroid Build Coastguard Worker }
184*27162e4eSAndroid Build Coastguard Worker return 0;
185*27162e4eSAndroid Build Coastguard Worker }
186*27162e4eSAndroid Build Coastguard Worker
usage_longhelp(const char * exeName)187*27162e4eSAndroid Build Coastguard Worker static int usage_longhelp(const char* exeName)
188*27162e4eSAndroid Build Coastguard Worker {
189*27162e4eSAndroid Build Coastguard Worker usage_advanced(exeName);
190*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
191*27162e4eSAndroid Build Coastguard Worker DISPLAY( "****************************\n");
192*27162e4eSAndroid Build Coastguard Worker DISPLAY( "***** Advanced comment *****\n");
193*27162e4eSAndroid Build Coastguard Worker DISPLAY( "****************************\n");
194*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
195*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Which values can [output] have ? \n");
196*27162e4eSAndroid Build Coastguard Worker DISPLAY( "---------------------------------\n");
197*27162e4eSAndroid Build Coastguard Worker DISPLAY( "[output] : a filename \n");
198*27162e4eSAndroid Build Coastguard Worker DISPLAY( " '%s', or '-' for standard output (pipe mode)\n", stdoutmark);
199*27162e4eSAndroid Build Coastguard Worker DISPLAY( " '%s' to discard output (test mode) \n", NULL_OUTPUT);
200*27162e4eSAndroid Build Coastguard Worker DISPLAY( "[output] can be left empty. In this case, it receives the following value :\n");
201*27162e4eSAndroid Build Coastguard Worker DISPLAY( " - if stdout is not the console, then [output] = stdout \n");
202*27162e4eSAndroid Build Coastguard Worker DISPLAY( " - if stdout is console : \n");
203*27162e4eSAndroid Build Coastguard Worker DISPLAY( " + for compression, output to filename%s \n", LZ4_EXTENSION);
204*27162e4eSAndroid Build Coastguard Worker DISPLAY( " + for decompression, output to filename without '%s'\n", LZ4_EXTENSION);
205*27162e4eSAndroid Build Coastguard Worker DISPLAY( " > if input filename has no '%s' extension : error \n", LZ4_EXTENSION);
206*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
207*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Compression levels : \n");
208*27162e4eSAndroid Build Coastguard Worker DISPLAY( "---------------------\n");
209*27162e4eSAndroid Build Coastguard Worker DISPLAY( "-0 ... -2 => Fast compression, all identical\n");
210*27162e4eSAndroid Build Coastguard Worker DISPLAY( "-3 ... -%d => High compression; higher number == more compression but slower\n", LZ4HC_CLEVEL_MAX);
211*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
212*27162e4eSAndroid Build Coastguard Worker DISPLAY( "stdin, stdout and the console : \n");
213*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--------------------------------\n");
214*27162e4eSAndroid Build Coastguard Worker DISPLAY( "To protect the console from binary flooding (bad argument mistake)\n");
215*27162e4eSAndroid Build Coastguard Worker DISPLAY( "%s will refuse to read from console, or write to console \n", exeName);
216*27162e4eSAndroid Build Coastguard Worker DISPLAY( "except if '-c' command is specified, to force output to console \n");
217*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
218*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Simple example :\n");
219*27162e4eSAndroid Build Coastguard Worker DISPLAY( "----------------\n");
220*27162e4eSAndroid Build Coastguard Worker DISPLAY( "1 : compress 'filename' fast, using default output name 'filename.lz4'\n");
221*27162e4eSAndroid Build Coastguard Worker DISPLAY( " %s filename\n", exeName);
222*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
223*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Short arguments can be aggregated. For example :\n");
224*27162e4eSAndroid Build Coastguard Worker DISPLAY( "----------------------------------\n");
225*27162e4eSAndroid Build Coastguard Worker DISPLAY( "2 : compress 'filename' in high compression mode, overwrite output if exists\n");
226*27162e4eSAndroid Build Coastguard Worker DISPLAY( " %s -9 -f filename \n", exeName);
227*27162e4eSAndroid Build Coastguard Worker DISPLAY( " is equivalent to :\n");
228*27162e4eSAndroid Build Coastguard Worker DISPLAY( " %s -9f filename \n", exeName);
229*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
230*27162e4eSAndroid Build Coastguard Worker DISPLAY( "%s can be used in 'pure pipe mode'. For example :\n", exeName);
231*27162e4eSAndroid Build Coastguard Worker DISPLAY( "-------------------------------------\n");
232*27162e4eSAndroid Build Coastguard Worker DISPLAY( "3 : compress data stream from 'generator', send result to 'consumer'\n");
233*27162e4eSAndroid Build Coastguard Worker DISPLAY( " generator | %s | consumer \n", exeName);
234*27162e4eSAndroid Build Coastguard Worker if (g_lz4c_legacy_commands) {
235*27162e4eSAndroid Build Coastguard Worker DISPLAY( "\n");
236*27162e4eSAndroid Build Coastguard Worker DISPLAY( "***** Warning ***** \n");
237*27162e4eSAndroid Build Coastguard Worker DISPLAY( "Legacy arguments take precedence. Therefore : \n");
238*27162e4eSAndroid Build Coastguard Worker DISPLAY( "--------------------------------- \n");
239*27162e4eSAndroid Build Coastguard Worker DISPLAY( " %s -hc filename \n", exeName);
240*27162e4eSAndroid Build Coastguard Worker DISPLAY( "means 'compress filename in high compression mode' \n");
241*27162e4eSAndroid Build Coastguard Worker DISPLAY( "It is not equivalent to : \n");
242*27162e4eSAndroid Build Coastguard Worker DISPLAY( " %s -h -c filename \n", exeName);
243*27162e4eSAndroid Build Coastguard Worker DISPLAY( "which displays help text and exits \n");
244*27162e4eSAndroid Build Coastguard Worker }
245*27162e4eSAndroid Build Coastguard Worker return 0;
246*27162e4eSAndroid Build Coastguard Worker }
247*27162e4eSAndroid Build Coastguard Worker
badusage(const char * exeName)248*27162e4eSAndroid Build Coastguard Worker static int badusage(const char* exeName)
249*27162e4eSAndroid Build Coastguard Worker {
250*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "Incorrect parameters\n");
251*27162e4eSAndroid Build Coastguard Worker if (displayLevel >= 1) usage(exeName);
252*27162e4eSAndroid Build Coastguard Worker exit(1);
253*27162e4eSAndroid Build Coastguard Worker }
254*27162e4eSAndroid Build Coastguard Worker
255*27162e4eSAndroid Build Coastguard Worker
waitEnter(void)256*27162e4eSAndroid Build Coastguard Worker static void waitEnter(void)
257*27162e4eSAndroid Build Coastguard Worker {
258*27162e4eSAndroid Build Coastguard Worker DISPLAY("Press enter to continue...\n");
259*27162e4eSAndroid Build Coastguard Worker (void)getchar();
260*27162e4eSAndroid Build Coastguard Worker }
261*27162e4eSAndroid Build Coastguard Worker
lastNameFromPath(const char * path)262*27162e4eSAndroid Build Coastguard Worker static const char* lastNameFromPath(const char* path)
263*27162e4eSAndroid Build Coastguard Worker {
264*27162e4eSAndroid Build Coastguard Worker const char* name = path;
265*27162e4eSAndroid Build Coastguard Worker if (strrchr(name, '/')) name = strrchr(name, '/') + 1;
266*27162e4eSAndroid Build Coastguard Worker if (strrchr(name, '\\')) name = strrchr(name, '\\') + 1; /* windows */
267*27162e4eSAndroid Build Coastguard Worker return name;
268*27162e4eSAndroid Build Coastguard Worker }
269*27162e4eSAndroid Build Coastguard Worker
270*27162e4eSAndroid Build Coastguard Worker /*! exeNameMatch() :
271*27162e4eSAndroid Build Coastguard Worker @return : a non-zero value if exeName matches test, excluding the extension
272*27162e4eSAndroid Build Coastguard Worker */
exeNameMatch(const char * exeName,const char * test)273*27162e4eSAndroid Build Coastguard Worker static int exeNameMatch(const char* exeName, const char* test)
274*27162e4eSAndroid Build Coastguard Worker {
275*27162e4eSAndroid Build Coastguard Worker return !strncmp(exeName, test, strlen(test)) &&
276*27162e4eSAndroid Build Coastguard Worker (exeName[strlen(test)] == '\0' || exeName[strlen(test)] == '.');
277*27162e4eSAndroid Build Coastguard Worker }
278*27162e4eSAndroid Build Coastguard Worker
279*27162e4eSAndroid Build Coastguard Worker /*! readU32FromChar() :
280*27162e4eSAndroid Build Coastguard Worker * @return : unsigned integer value read from input in `char` format
281*27162e4eSAndroid Build Coastguard Worker * allows and interprets K, KB, KiB, M, MB and MiB suffix.
282*27162e4eSAndroid Build Coastguard Worker * Will also modify `*stringPtr`, advancing it to position where it stopped reading.
283*27162e4eSAndroid Build Coastguard Worker * Note : function result can overflow if digit string > MAX_UINT */
readU32FromChar(const char ** stringPtr)284*27162e4eSAndroid Build Coastguard Worker static unsigned readU32FromChar(const char** stringPtr)
285*27162e4eSAndroid Build Coastguard Worker {
286*27162e4eSAndroid Build Coastguard Worker unsigned result = 0;
287*27162e4eSAndroid Build Coastguard Worker while ((**stringPtr >='0') && (**stringPtr <='9')) {
288*27162e4eSAndroid Build Coastguard Worker result *= 10;
289*27162e4eSAndroid Build Coastguard Worker result += (unsigned)(**stringPtr - '0');
290*27162e4eSAndroid Build Coastguard Worker (*stringPtr)++ ;
291*27162e4eSAndroid Build Coastguard Worker }
292*27162e4eSAndroid Build Coastguard Worker if ((**stringPtr=='K') || (**stringPtr=='M')) {
293*27162e4eSAndroid Build Coastguard Worker result <<= 10;
294*27162e4eSAndroid Build Coastguard Worker if (**stringPtr=='M') result <<= 10;
295*27162e4eSAndroid Build Coastguard Worker (*stringPtr)++ ;
296*27162e4eSAndroid Build Coastguard Worker if (**stringPtr=='i') (*stringPtr)++;
297*27162e4eSAndroid Build Coastguard Worker if (**stringPtr=='B') (*stringPtr)++;
298*27162e4eSAndroid Build Coastguard Worker }
299*27162e4eSAndroid Build Coastguard Worker return result;
300*27162e4eSAndroid Build Coastguard Worker }
301*27162e4eSAndroid Build Coastguard Worker
302*27162e4eSAndroid Build Coastguard Worker #define CLEAN_RETURN(i) { operationResult = (i); goto _cleanup; }
303*27162e4eSAndroid Build Coastguard Worker
304*27162e4eSAndroid Build Coastguard Worker #define NEXT_FIELD(ptr) { \
305*27162e4eSAndroid Build Coastguard Worker if (*argument == '=') { \
306*27162e4eSAndroid Build Coastguard Worker ptr = ++argument; \
307*27162e4eSAndroid Build Coastguard Worker argument += strlen(ptr); \
308*27162e4eSAndroid Build Coastguard Worker } else { \
309*27162e4eSAndroid Build Coastguard Worker argNb++; \
310*27162e4eSAndroid Build Coastguard Worker if (argNb >= argCount) { \
311*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "error: missing command argument \n"); \
312*27162e4eSAndroid Build Coastguard Worker CLEAN_RETURN(1); \
313*27162e4eSAndroid Build Coastguard Worker } \
314*27162e4eSAndroid Build Coastguard Worker ptr = argv[argNb]; \
315*27162e4eSAndroid Build Coastguard Worker assert(ptr != NULL); \
316*27162e4eSAndroid Build Coastguard Worker if (ptr[0]=='-') { \
317*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "error: command cannot be separated from its argument by another command \n"); \
318*27162e4eSAndroid Build Coastguard Worker CLEAN_RETURN(1); \
319*27162e4eSAndroid Build Coastguard Worker } } }
320*27162e4eSAndroid Build Coastguard Worker
321*27162e4eSAndroid Build Coastguard Worker #define NEXT_UINT32(val32) { \
322*27162e4eSAndroid Build Coastguard Worker const char* __nb; \
323*27162e4eSAndroid Build Coastguard Worker NEXT_FIELD(__nb); \
324*27162e4eSAndroid Build Coastguard Worker val32 = readU32FromChar(&__nb); \
325*27162e4eSAndroid Build Coastguard Worker if(*__nb != 0) { \
326*27162e4eSAndroid Build Coastguard Worker errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed"); \
327*27162e4eSAndroid Build Coastguard Worker } \
328*27162e4eSAndroid Build Coastguard Worker }
329*27162e4eSAndroid Build Coastguard Worker
330*27162e4eSAndroid Build Coastguard Worker /** longCommandWArg() :
331*27162e4eSAndroid Build Coastguard Worker * check if *stringPtr is the same as longCommand.
332*27162e4eSAndroid Build Coastguard Worker * If yes, @return 1 and advances *stringPtr to the position which immediately follows longCommand.
333*27162e4eSAndroid Build Coastguard Worker * @return 0 and doesn't modify *stringPtr otherwise.
334*27162e4eSAndroid Build Coastguard Worker */
longCommandWArg(const char ** stringPtr,const char * longCommand)335*27162e4eSAndroid Build Coastguard Worker static int longCommandWArg(const char** stringPtr, const char* longCommand)
336*27162e4eSAndroid Build Coastguard Worker {
337*27162e4eSAndroid Build Coastguard Worker size_t const comSize = strlen(longCommand);
338*27162e4eSAndroid Build Coastguard Worker int const result = !strncmp(*stringPtr, longCommand, comSize);
339*27162e4eSAndroid Build Coastguard Worker if (result) *stringPtr += comSize;
340*27162e4eSAndroid Build Coastguard Worker return result;
341*27162e4eSAndroid Build Coastguard Worker }
342*27162e4eSAndroid Build Coastguard Worker
343*27162e4eSAndroid Build Coastguard Worker typedef enum { om_auto, om_compress, om_decompress, om_test, om_bench, om_list } operationMode_e;
344*27162e4eSAndroid Build Coastguard Worker
345*27162e4eSAndroid Build Coastguard Worker /** determineOpMode() :
346*27162e4eSAndroid Build Coastguard Worker * auto-determine operation mode, based on input filename extension
347*27162e4eSAndroid Build Coastguard Worker * @return `om_decompress` if input filename has .lz4 extension and `om_compress` otherwise.
348*27162e4eSAndroid Build Coastguard Worker */
determineOpMode(const char * inputFilename)349*27162e4eSAndroid Build Coastguard Worker static operationMode_e determineOpMode(const char* inputFilename)
350*27162e4eSAndroid Build Coastguard Worker {
351*27162e4eSAndroid Build Coastguard Worker size_t const inSize = strlen(inputFilename);
352*27162e4eSAndroid Build Coastguard Worker size_t const extSize = strlen(LZ4_EXTENSION);
353*27162e4eSAndroid Build Coastguard Worker size_t const extStart= (inSize > extSize) ? inSize-extSize : 0;
354*27162e4eSAndroid Build Coastguard Worker if (!strcmp(inputFilename+extStart, LZ4_EXTENSION)) return om_decompress;
355*27162e4eSAndroid Build Coastguard Worker else return om_compress;
356*27162e4eSAndroid Build Coastguard Worker }
357*27162e4eSAndroid Build Coastguard Worker
358*27162e4eSAndroid Build Coastguard Worker #define ENV_NBTHREADS "LZ4_NBWORKERS"
359*27162e4eSAndroid Build Coastguard Worker
init_nbWorkers(void)360*27162e4eSAndroid Build Coastguard Worker static unsigned init_nbWorkers(void)
361*27162e4eSAndroid Build Coastguard Worker {
362*27162e4eSAndroid Build Coastguard Worker const char* const env = getenv(ENV_NBTHREADS);
363*27162e4eSAndroid Build Coastguard Worker if (env != NULL) {
364*27162e4eSAndroid Build Coastguard Worker const char* ptr = env;
365*27162e4eSAndroid Build Coastguard Worker if ((*ptr>='0') && (*ptr<='9')) {
366*27162e4eSAndroid Build Coastguard Worker return readU32FromChar(&ptr);
367*27162e4eSAndroid Build Coastguard Worker }
368*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: not a valid unsigned value \n", ENV_NBTHREADS, env);
369*27162e4eSAndroid Build Coastguard Worker }
370*27162e4eSAndroid Build Coastguard Worker return LZ4_NBWORKERS_DEFAULT;
371*27162e4eSAndroid Build Coastguard Worker }
372*27162e4eSAndroid Build Coastguard Worker
373*27162e4eSAndroid Build Coastguard Worker #define ENV_CLEVEL "LZ4_CLEVEL"
374*27162e4eSAndroid Build Coastguard Worker
init_cLevel(void)375*27162e4eSAndroid Build Coastguard Worker static int init_cLevel(void)
376*27162e4eSAndroid Build Coastguard Worker {
377*27162e4eSAndroid Build Coastguard Worker const char* const env = getenv(ENV_CLEVEL);
378*27162e4eSAndroid Build Coastguard Worker if (env != NULL) {
379*27162e4eSAndroid Build Coastguard Worker const char* ptr = env;
380*27162e4eSAndroid Build Coastguard Worker if ((*ptr>='0') && (*ptr<='9')) {
381*27162e4eSAndroid Build Coastguard Worker return (int)readU32FromChar(&ptr);
382*27162e4eSAndroid Build Coastguard Worker }
383*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: not a valid unsigned value \n", ENV_CLEVEL, env);
384*27162e4eSAndroid Build Coastguard Worker }
385*27162e4eSAndroid Build Coastguard Worker return LZ4_CLEVEL_DEFAULT;
386*27162e4eSAndroid Build Coastguard Worker }
387*27162e4eSAndroid Build Coastguard Worker
main(int argCount,const char ** argv)388*27162e4eSAndroid Build Coastguard Worker int main(int argCount, const char** argv)
389*27162e4eSAndroid Build Coastguard Worker {
390*27162e4eSAndroid Build Coastguard Worker int argNb,
391*27162e4eSAndroid Build Coastguard Worker cLevel=init_cLevel(),
392*27162e4eSAndroid Build Coastguard Worker cLevelLast=-10000,
393*27162e4eSAndroid Build Coastguard Worker legacy_format=0,
394*27162e4eSAndroid Build Coastguard Worker forceStdout=0,
395*27162e4eSAndroid Build Coastguard Worker forceOverwrite=0,
396*27162e4eSAndroid Build Coastguard Worker main_pause=0,
397*27162e4eSAndroid Build Coastguard Worker multiple_inputs=0,
398*27162e4eSAndroid Build Coastguard Worker all_arguments_are_files=0,
399*27162e4eSAndroid Build Coastguard Worker operationResult=0;
400*27162e4eSAndroid Build Coastguard Worker unsigned nbWorkers = init_nbWorkers();
401*27162e4eSAndroid Build Coastguard Worker operationMode_e mode = om_auto;
402*27162e4eSAndroid Build Coastguard Worker const char* input_filename = NULL;
403*27162e4eSAndroid Build Coastguard Worker const char* output_filename= NULL;
404*27162e4eSAndroid Build Coastguard Worker const char* dictionary_filename = NULL;
405*27162e4eSAndroid Build Coastguard Worker char* dynNameSpace = NULL;
406*27162e4eSAndroid Build Coastguard Worker const char** inFileNames = (const char**)calloc((size_t)argCount, sizeof(char*));
407*27162e4eSAndroid Build Coastguard Worker unsigned ifnIdx=0;
408*27162e4eSAndroid Build Coastguard Worker LZ4IO_prefs_t* const prefs = LZ4IO_defaultPreferences();
409*27162e4eSAndroid Build Coastguard Worker const char nullOutput[] = NULL_OUTPUT;
410*27162e4eSAndroid Build Coastguard Worker const char extension[] = LZ4_EXTENSION;
411*27162e4eSAndroid Build Coastguard Worker size_t blockSize = LZ4IO_setBlockSizeID(prefs, LZ4_BLOCKSIZEID_DEFAULT);
412*27162e4eSAndroid Build Coastguard Worker const char* const exeName = lastNameFromPath(argv[0]);
413*27162e4eSAndroid Build Coastguard Worker char* fileNamesBuf = NULL;
414*27162e4eSAndroid Build Coastguard Worker #ifdef UTIL_HAS_CREATEFILELIST
415*27162e4eSAndroid Build Coastguard Worker unsigned fileNamesNb, recursive=0;
416*27162e4eSAndroid Build Coastguard Worker #endif
417*27162e4eSAndroid Build Coastguard Worker
418*27162e4eSAndroid Build Coastguard Worker /* Init */
419*27162e4eSAndroid Build Coastguard Worker if (inFileNames==NULL) {
420*27162e4eSAndroid Build Coastguard Worker DISPLAY("Allocation error : not enough memory \n");
421*27162e4eSAndroid Build Coastguard Worker operationResult = 1;
422*27162e4eSAndroid Build Coastguard Worker goto _cleanup;
423*27162e4eSAndroid Build Coastguard Worker }
424*27162e4eSAndroid Build Coastguard Worker inFileNames[0] = stdinmark;
425*27162e4eSAndroid Build Coastguard Worker LZ4IO_setOverwrite(prefs, 0);
426*27162e4eSAndroid Build Coastguard Worker
427*27162e4eSAndroid Build Coastguard Worker /* predefined behaviors, based on binary/link name */
428*27162e4eSAndroid Build Coastguard Worker if (exeNameMatch(exeName, LZ4CAT)) {
429*27162e4eSAndroid Build Coastguard Worker mode = om_decompress;
430*27162e4eSAndroid Build Coastguard Worker LZ4IO_setOverwrite(prefs, 1);
431*27162e4eSAndroid Build Coastguard Worker LZ4IO_setPassThrough(prefs, 1);
432*27162e4eSAndroid Build Coastguard Worker LZ4IO_setRemoveSrcFile(prefs, 0);
433*27162e4eSAndroid Build Coastguard Worker forceStdout=1;
434*27162e4eSAndroid Build Coastguard Worker output_filename=stdoutmark;
435*27162e4eSAndroid Build Coastguard Worker displayLevel=1;
436*27162e4eSAndroid Build Coastguard Worker multiple_inputs=1;
437*27162e4eSAndroid Build Coastguard Worker }
438*27162e4eSAndroid Build Coastguard Worker if (exeNameMatch(exeName, UNLZ4)) { mode = om_decompress; }
439*27162e4eSAndroid Build Coastguard Worker if (exeNameMatch(exeName, LZ4_LEGACY)) { g_lz4c_legacy_commands=1; }
440*27162e4eSAndroid Build Coastguard Worker
441*27162e4eSAndroid Build Coastguard Worker /* command switches */
442*27162e4eSAndroid Build Coastguard Worker for(argNb=1; argNb<argCount; argNb++) {
443*27162e4eSAndroid Build Coastguard Worker const char* argument = argv[argNb];
444*27162e4eSAndroid Build Coastguard Worker
445*27162e4eSAndroid Build Coastguard Worker if(!argument) continue; /* Protection if argument empty */
446*27162e4eSAndroid Build Coastguard Worker
447*27162e4eSAndroid Build Coastguard Worker /* Short commands (note : aggregated short commands are allowed) */
448*27162e4eSAndroid Build Coastguard Worker if (!all_arguments_are_files && argument[0]=='-') {
449*27162e4eSAndroid Build Coastguard Worker /* '-' means stdin/stdout */
450*27162e4eSAndroid Build Coastguard Worker if (argument[1]==0) {
451*27162e4eSAndroid Build Coastguard Worker if (!input_filename) input_filename=stdinmark;
452*27162e4eSAndroid Build Coastguard Worker else output_filename=stdoutmark;
453*27162e4eSAndroid Build Coastguard Worker continue;
454*27162e4eSAndroid Build Coastguard Worker }
455*27162e4eSAndroid Build Coastguard Worker
456*27162e4eSAndroid Build Coastguard Worker /* long commands (--long-word) */
457*27162e4eSAndroid Build Coastguard Worker if (argument[1]=='-') {
458*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--")) { all_arguments_are_files = 1; continue; }
459*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--compress")) { mode = om_compress; continue; }
460*27162e4eSAndroid Build Coastguard Worker if ( (!strcmp(argument, "--decompress"))
461*27162e4eSAndroid Build Coastguard Worker || (!strcmp(argument, "--uncompress"))) {
462*27162e4eSAndroid Build Coastguard Worker if (mode != om_bench) mode = om_decompress;
463*27162e4eSAndroid Build Coastguard Worker BMK_setDecodeOnlyMode(1);
464*27162e4eSAndroid Build Coastguard Worker continue;
465*27162e4eSAndroid Build Coastguard Worker }
466*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--multiple")) { multiple_inputs = 1; continue; }
467*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--test")) { mode = om_test; continue; }
468*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--force")) { LZ4IO_setOverwrite(prefs, 1); continue; }
469*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--no-force")) { LZ4IO_setOverwrite(prefs, 0); continue; }
470*27162e4eSAndroid Build Coastguard Worker if ((!strcmp(argument, "--stdout"))
471*27162e4eSAndroid Build Coastguard Worker || (!strcmp(argument, "--to-stdout"))) { forceStdout=1; output_filename=stdoutmark; continue; }
472*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--frame-crc")) { LZ4IO_setStreamChecksumMode(prefs, 1); BMK_skipChecksums(0); continue; }
473*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--no-frame-crc")) { LZ4IO_setStreamChecksumMode(prefs, 0); BMK_skipChecksums(1); continue; }
474*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--no-crc")) { LZ4IO_setStreamChecksumMode(prefs, 0); LZ4IO_setBlockChecksumMode(prefs, 0); BMK_skipChecksums(1); continue; }
475*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--content-size")) { LZ4IO_setContentSize(prefs, 1); continue; }
476*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--no-content-size")) { LZ4IO_setContentSize(prefs, 0); continue; }
477*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--list")) { mode = om_list; multiple_inputs = 1; continue; }
478*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--sparse")) { LZ4IO_setSparseFile(prefs, 2); continue; }
479*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--no-sparse")) { LZ4IO_setSparseFile(prefs, 0); continue; }
480*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--favor-decSpeed")) { LZ4IO_favorDecSpeed(prefs, 1); continue; }
481*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--verbose")) { displayLevel++; continue; }
482*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--quiet")) { if (displayLevel) displayLevel--; continue; }
483*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--version")) { DISPLAYOUT(WELCOME_MESSAGE); goto _cleanup; }
484*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--help")) { usage_advanced(exeName); goto _cleanup; }
485*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--keep")) { LZ4IO_setRemoveSrcFile(prefs, 0); continue; } /* keep source file (default) */
486*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--rm")) { LZ4IO_setRemoveSrcFile(prefs, 1); continue; }
487*27162e4eSAndroid Build Coastguard Worker
488*27162e4eSAndroid Build Coastguard Worker if (longCommandWArg(&argument, "--threads")) {
489*27162e4eSAndroid Build Coastguard Worker NEXT_UINT32(nbWorkers);
490*27162e4eSAndroid Build Coastguard Worker continue;
491*27162e4eSAndroid Build Coastguard Worker }
492*27162e4eSAndroid Build Coastguard Worker if (longCommandWArg(&argument, "--fast")) {
493*27162e4eSAndroid Build Coastguard Worker /* Parse optional acceleration factor */
494*27162e4eSAndroid Build Coastguard Worker if (*argument == '=') {
495*27162e4eSAndroid Build Coastguard Worker U32 fastLevel;
496*27162e4eSAndroid Build Coastguard Worker ++argument;
497*27162e4eSAndroid Build Coastguard Worker fastLevel = readU32FromChar(&argument);
498*27162e4eSAndroid Build Coastguard Worker if (fastLevel) {
499*27162e4eSAndroid Build Coastguard Worker cLevel = -(int)fastLevel;
500*27162e4eSAndroid Build Coastguard Worker } else {
501*27162e4eSAndroid Build Coastguard Worker badusage(exeName);
502*27162e4eSAndroid Build Coastguard Worker }
503*27162e4eSAndroid Build Coastguard Worker } else if (*argument != 0) {
504*27162e4eSAndroid Build Coastguard Worker /* Invalid character following --fast */
505*27162e4eSAndroid Build Coastguard Worker badusage(exeName);
506*27162e4eSAndroid Build Coastguard Worker } else {
507*27162e4eSAndroid Build Coastguard Worker cLevel = -1; /* default for --fast */
508*27162e4eSAndroid Build Coastguard Worker }
509*27162e4eSAndroid Build Coastguard Worker continue;
510*27162e4eSAndroid Build Coastguard Worker }
511*27162e4eSAndroid Build Coastguard Worker
512*27162e4eSAndroid Build Coastguard Worker /* For gzip(1) compatibility */
513*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "--best")) { cLevel=LZ4HC_CLEVEL_MAX; continue; }
514*27162e4eSAndroid Build Coastguard Worker }
515*27162e4eSAndroid Build Coastguard Worker
516*27162e4eSAndroid Build Coastguard Worker while (argument[1]!=0) {
517*27162e4eSAndroid Build Coastguard Worker argument ++;
518*27162e4eSAndroid Build Coastguard Worker
519*27162e4eSAndroid Build Coastguard Worker if (g_lz4c_legacy_commands) {
520*27162e4eSAndroid Build Coastguard Worker /* Legacy commands (-c0, -c1, -hc, -y) */
521*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "c0")) { cLevel=0; argument++; continue; } /* -c0 (fast compression) */
522*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "c1")) { cLevel=9; argument++; continue; } /* -c1 (high compression) */
523*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "c2")) { cLevel=12; argument++; continue; } /* -c2 (very high compression) */
524*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "hc")) { cLevel=12; argument++; continue; } /* -hc (very high compression) */
525*27162e4eSAndroid Build Coastguard Worker if (!strcmp(argument, "y")) { LZ4IO_setOverwrite(prefs, 1); continue; } /* -y (answer 'yes' to overwrite permission) */
526*27162e4eSAndroid Build Coastguard Worker }
527*27162e4eSAndroid Build Coastguard Worker
528*27162e4eSAndroid Build Coastguard Worker if ((*argument>='0') && (*argument<='9')) {
529*27162e4eSAndroid Build Coastguard Worker cLevel = (int)readU32FromChar(&argument);
530*27162e4eSAndroid Build Coastguard Worker argument--;
531*27162e4eSAndroid Build Coastguard Worker continue;
532*27162e4eSAndroid Build Coastguard Worker }
533*27162e4eSAndroid Build Coastguard Worker
534*27162e4eSAndroid Build Coastguard Worker
535*27162e4eSAndroid Build Coastguard Worker switch(argument[0])
536*27162e4eSAndroid Build Coastguard Worker {
537*27162e4eSAndroid Build Coastguard Worker /* Display help */
538*27162e4eSAndroid Build Coastguard Worker case 'V': DISPLAYOUT(WELCOME_MESSAGE); goto _cleanup; /* Version */
539*27162e4eSAndroid Build Coastguard Worker case 'h': usage_advanced(exeName); goto _cleanup;
540*27162e4eSAndroid Build Coastguard Worker case 'H': usage_longhelp(exeName); goto _cleanup;
541*27162e4eSAndroid Build Coastguard Worker
542*27162e4eSAndroid Build Coastguard Worker case 'e':
543*27162e4eSAndroid Build Coastguard Worker argument++;
544*27162e4eSAndroid Build Coastguard Worker cLevelLast = (int)readU32FromChar(&argument);
545*27162e4eSAndroid Build Coastguard Worker argument--;
546*27162e4eSAndroid Build Coastguard Worker break;
547*27162e4eSAndroid Build Coastguard Worker
548*27162e4eSAndroid Build Coastguard Worker /* Compression (default) */
549*27162e4eSAndroid Build Coastguard Worker case 'z': mode = om_compress; break;
550*27162e4eSAndroid Build Coastguard Worker
551*27162e4eSAndroid Build Coastguard Worker /* Modify Nb Worker threads (compression only) */
552*27162e4eSAndroid Build Coastguard Worker case 'T':
553*27162e4eSAndroid Build Coastguard Worker { argument++;
554*27162e4eSAndroid Build Coastguard Worker nbWorkers = readU32FromChar(&argument);
555*27162e4eSAndroid Build Coastguard Worker argument--;
556*27162e4eSAndroid Build Coastguard Worker }
557*27162e4eSAndroid Build Coastguard Worker break;
558*27162e4eSAndroid Build Coastguard Worker
559*27162e4eSAndroid Build Coastguard Worker case 'D':
560*27162e4eSAndroid Build Coastguard Worker if (argument[1] == '\0') {
561*27162e4eSAndroid Build Coastguard Worker /* path is next arg */
562*27162e4eSAndroid Build Coastguard Worker if (argNb + 1 == argCount) {
563*27162e4eSAndroid Build Coastguard Worker /* there is no next arg */
564*27162e4eSAndroid Build Coastguard Worker badusage(exeName);
565*27162e4eSAndroid Build Coastguard Worker }
566*27162e4eSAndroid Build Coastguard Worker dictionary_filename = argv[++argNb];
567*27162e4eSAndroid Build Coastguard Worker } else {
568*27162e4eSAndroid Build Coastguard Worker /* path follows immediately */
569*27162e4eSAndroid Build Coastguard Worker dictionary_filename = argument + 1;
570*27162e4eSAndroid Build Coastguard Worker }
571*27162e4eSAndroid Build Coastguard Worker /* skip to end of argument so that we jump to parsing next argument */
572*27162e4eSAndroid Build Coastguard Worker argument += strlen(argument) - 1;
573*27162e4eSAndroid Build Coastguard Worker break;
574*27162e4eSAndroid Build Coastguard Worker
575*27162e4eSAndroid Build Coastguard Worker /* Use Legacy format (ex : Linux kernel compression) */
576*27162e4eSAndroid Build Coastguard Worker case 'l': legacy_format = 1; blockSize = 8 MB; break;
577*27162e4eSAndroid Build Coastguard Worker
578*27162e4eSAndroid Build Coastguard Worker /* Decoding */
579*27162e4eSAndroid Build Coastguard Worker case 'd':
580*27162e4eSAndroid Build Coastguard Worker if (mode != om_bench) mode = om_decompress;
581*27162e4eSAndroid Build Coastguard Worker BMK_setDecodeOnlyMode(1);
582*27162e4eSAndroid Build Coastguard Worker break;
583*27162e4eSAndroid Build Coastguard Worker
584*27162e4eSAndroid Build Coastguard Worker /* Force stdout, even if stdout==console */
585*27162e4eSAndroid Build Coastguard Worker case 'c':
586*27162e4eSAndroid Build Coastguard Worker forceStdout=1;
587*27162e4eSAndroid Build Coastguard Worker output_filename=stdoutmark;
588*27162e4eSAndroid Build Coastguard Worker LZ4IO_setPassThrough(prefs, 1);
589*27162e4eSAndroid Build Coastguard Worker break;
590*27162e4eSAndroid Build Coastguard Worker
591*27162e4eSAndroid Build Coastguard Worker /* Test integrity */
592*27162e4eSAndroid Build Coastguard Worker case 't': mode = om_test; break;
593*27162e4eSAndroid Build Coastguard Worker
594*27162e4eSAndroid Build Coastguard Worker /* Overwrite */
595*27162e4eSAndroid Build Coastguard Worker case 'f': forceOverwrite=1; LZ4IO_setOverwrite(prefs, 1); break;
596*27162e4eSAndroid Build Coastguard Worker
597*27162e4eSAndroid Build Coastguard Worker /* Verbose mode */
598*27162e4eSAndroid Build Coastguard Worker case 'v': displayLevel++; break;
599*27162e4eSAndroid Build Coastguard Worker
600*27162e4eSAndroid Build Coastguard Worker /* Quiet mode */
601*27162e4eSAndroid Build Coastguard Worker case 'q': if (displayLevel) displayLevel--; break;
602*27162e4eSAndroid Build Coastguard Worker
603*27162e4eSAndroid Build Coastguard Worker /* keep source file (default anyway, so useless) (for xz/lzma compatibility) */
604*27162e4eSAndroid Build Coastguard Worker case 'k': LZ4IO_setRemoveSrcFile(prefs, 0); break;
605*27162e4eSAndroid Build Coastguard Worker
606*27162e4eSAndroid Build Coastguard Worker /* Modify Block Properties */
607*27162e4eSAndroid Build Coastguard Worker case 'B':
608*27162e4eSAndroid Build Coastguard Worker while (argument[1]!=0) {
609*27162e4eSAndroid Build Coastguard Worker int exitBlockProperties=0;
610*27162e4eSAndroid Build Coastguard Worker switch(argument[1])
611*27162e4eSAndroid Build Coastguard Worker {
612*27162e4eSAndroid Build Coastguard Worker case 'D': LZ4IO_setBlockMode(prefs, LZ4IO_blockLinked); argument++; break;
613*27162e4eSAndroid Build Coastguard Worker case 'I': LZ4IO_setBlockMode(prefs, LZ4IO_blockIndependent); argument++; break;
614*27162e4eSAndroid Build Coastguard Worker case 'X': LZ4IO_setBlockChecksumMode(prefs, 1); argument ++; break; /* disabled by default */
615*27162e4eSAndroid Build Coastguard Worker default :
616*27162e4eSAndroid Build Coastguard Worker if (argument[1] < '0' || argument[1] > '9') {
617*27162e4eSAndroid Build Coastguard Worker exitBlockProperties=1;
618*27162e4eSAndroid Build Coastguard Worker break;
619*27162e4eSAndroid Build Coastguard Worker } else {
620*27162e4eSAndroid Build Coastguard Worker unsigned B;
621*27162e4eSAndroid Build Coastguard Worker argument++;
622*27162e4eSAndroid Build Coastguard Worker B = readU32FromChar(&argument);
623*27162e4eSAndroid Build Coastguard Worker argument--;
624*27162e4eSAndroid Build Coastguard Worker if (B < 4) badusage(exeName);
625*27162e4eSAndroid Build Coastguard Worker if (B <= 7) {
626*27162e4eSAndroid Build Coastguard Worker blockSize = LZ4IO_setBlockSizeID(prefs, B);
627*27162e4eSAndroid Build Coastguard Worker BMK_setBlockSize(blockSize);
628*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(2, "using blocks of size %u KB \n", (U32)(blockSize>>10));
629*27162e4eSAndroid Build Coastguard Worker } else {
630*27162e4eSAndroid Build Coastguard Worker if (B < 32) badusage(exeName);
631*27162e4eSAndroid Build Coastguard Worker blockSize = LZ4IO_setBlockSize(prefs, B);
632*27162e4eSAndroid Build Coastguard Worker BMK_setBlockSize(blockSize);
633*27162e4eSAndroid Build Coastguard Worker if (blockSize >= 1024) {
634*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(2, "using blocks of size %u KB \n", (U32)(blockSize>>10));
635*27162e4eSAndroid Build Coastguard Worker } else {
636*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(2, "using blocks of size %u bytes \n", (U32)(blockSize));
637*27162e4eSAndroid Build Coastguard Worker }
638*27162e4eSAndroid Build Coastguard Worker }
639*27162e4eSAndroid Build Coastguard Worker break;
640*27162e4eSAndroid Build Coastguard Worker }
641*27162e4eSAndroid Build Coastguard Worker }
642*27162e4eSAndroid Build Coastguard Worker if (exitBlockProperties) break;
643*27162e4eSAndroid Build Coastguard Worker }
644*27162e4eSAndroid Build Coastguard Worker break;
645*27162e4eSAndroid Build Coastguard Worker
646*27162e4eSAndroid Build Coastguard Worker /* Benchmark */
647*27162e4eSAndroid Build Coastguard Worker case 'b': mode = om_bench; multiple_inputs=1;
648*27162e4eSAndroid Build Coastguard Worker break;
649*27162e4eSAndroid Build Coastguard Worker
650*27162e4eSAndroid Build Coastguard Worker /* hidden command : benchmark files, but do not fuse result */
651*27162e4eSAndroid Build Coastguard Worker case 'S': BMK_setBenchSeparately(1);
652*27162e4eSAndroid Build Coastguard Worker break;
653*27162e4eSAndroid Build Coastguard Worker
654*27162e4eSAndroid Build Coastguard Worker #ifdef UTIL_HAS_CREATEFILELIST
655*27162e4eSAndroid Build Coastguard Worker /* recursive */
656*27162e4eSAndroid Build Coastguard Worker case 'r': recursive=1;
657*27162e4eSAndroid Build Coastguard Worker #endif
658*27162e4eSAndroid Build Coastguard Worker /* fall-through */
659*27162e4eSAndroid Build Coastguard Worker /* Treat non-option args as input files. See https://code.google.com/p/lz4/issues/detail?id=151 */
660*27162e4eSAndroid Build Coastguard Worker case 'm': multiple_inputs=1;
661*27162e4eSAndroid Build Coastguard Worker break;
662*27162e4eSAndroid Build Coastguard Worker
663*27162e4eSAndroid Build Coastguard Worker /* Modify Nb Seconds (benchmark only) */
664*27162e4eSAndroid Build Coastguard Worker case 'i':
665*27162e4eSAndroid Build Coastguard Worker { unsigned iters;
666*27162e4eSAndroid Build Coastguard Worker argument++;
667*27162e4eSAndroid Build Coastguard Worker iters = readU32FromChar(&argument);
668*27162e4eSAndroid Build Coastguard Worker argument--;
669*27162e4eSAndroid Build Coastguard Worker BMK_setNotificationLevel(displayLevel);
670*27162e4eSAndroid Build Coastguard Worker BMK_setNbSeconds(iters); /* notification if displayLevel >= 3 */
671*27162e4eSAndroid Build Coastguard Worker }
672*27162e4eSAndroid Build Coastguard Worker break;
673*27162e4eSAndroid Build Coastguard Worker
674*27162e4eSAndroid Build Coastguard Worker /* Pause at the end (hidden option) */
675*27162e4eSAndroid Build Coastguard Worker case 'p': main_pause=1; break;
676*27162e4eSAndroid Build Coastguard Worker
677*27162e4eSAndroid Build Coastguard Worker /* Unrecognised command */
678*27162e4eSAndroid Build Coastguard Worker default : badusage(exeName);
679*27162e4eSAndroid Build Coastguard Worker }
680*27162e4eSAndroid Build Coastguard Worker }
681*27162e4eSAndroid Build Coastguard Worker continue;
682*27162e4eSAndroid Build Coastguard Worker }
683*27162e4eSAndroid Build Coastguard Worker
684*27162e4eSAndroid Build Coastguard Worker /* Store in *inFileNames[] if -m is used. */
685*27162e4eSAndroid Build Coastguard Worker if (multiple_inputs) { inFileNames[ifnIdx++] = argument; continue; }
686*27162e4eSAndroid Build Coastguard Worker
687*27162e4eSAndroid Build Coastguard Worker /* original cli logic : lz4 input output */
688*27162e4eSAndroid Build Coastguard Worker /* First non-option arg is input_filename. */
689*27162e4eSAndroid Build Coastguard Worker if (!input_filename) { input_filename = argument; continue; }
690*27162e4eSAndroid Build Coastguard Worker
691*27162e4eSAndroid Build Coastguard Worker /* Second non-option arg is output_filename */
692*27162e4eSAndroid Build Coastguard Worker if (!output_filename) {
693*27162e4eSAndroid Build Coastguard Worker output_filename = argument;
694*27162e4eSAndroid Build Coastguard Worker if (!strcmp (output_filename, nullOutput)) output_filename = nulmark;
695*27162e4eSAndroid Build Coastguard Worker continue;
696*27162e4eSAndroid Build Coastguard Worker }
697*27162e4eSAndroid Build Coastguard Worker
698*27162e4eSAndroid Build Coastguard Worker /* 3rd+ non-option arg should not exist */
699*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "%s : %s won't be used ! Do you want multiple input files (-m) ? \n",
700*27162e4eSAndroid Build Coastguard Worker forceOverwrite ? "Warning" : "Error",
701*27162e4eSAndroid Build Coastguard Worker argument);
702*27162e4eSAndroid Build Coastguard Worker if (!forceOverwrite) exit(1);
703*27162e4eSAndroid Build Coastguard Worker }
704*27162e4eSAndroid Build Coastguard Worker
705*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(3, WELCOME_MESSAGE);
706*27162e4eSAndroid Build Coastguard Worker #ifdef _POSIX_C_SOURCE
707*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(4, "_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
708*27162e4eSAndroid Build Coastguard Worker #endif
709*27162e4eSAndroid Build Coastguard Worker #ifdef _POSIX_VERSION
710*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(4, "_POSIX_VERSION defined: %ldL\n", (long) _POSIX_VERSION);
711*27162e4eSAndroid Build Coastguard Worker #endif
712*27162e4eSAndroid Build Coastguard Worker #ifdef PLATFORM_POSIX_VERSION
713*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(4, "PLATFORM_POSIX_VERSION defined: %ldL\n", (long) PLATFORM_POSIX_VERSION);
714*27162e4eSAndroid Build Coastguard Worker #endif
715*27162e4eSAndroid Build Coastguard Worker #ifdef _FILE_OFFSET_BITS
716*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(5, "_FILE_OFFSET_BITS defined: %ldL\n", (long) _FILE_OFFSET_BITS);
717*27162e4eSAndroid Build Coastguard Worker #endif
718*27162e4eSAndroid Build Coastguard Worker #if !LZ4IO_MULTITHREAD
719*27162e4eSAndroid Build Coastguard Worker if (nbWorkers > 1) {
720*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(2, "warning: this executable doesn't support multithreading \n");
721*27162e4eSAndroid Build Coastguard Worker }
722*27162e4eSAndroid Build Coastguard Worker #endif
723*27162e4eSAndroid Build Coastguard Worker if ((mode == om_compress) || (mode == om_bench)) {
724*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(4, "Blocks size : %u KB\n", (U32)(blockSize>>10));
725*27162e4eSAndroid Build Coastguard Worker }
726*27162e4eSAndroid Build Coastguard Worker
727*27162e4eSAndroid Build Coastguard Worker if (multiple_inputs) {
728*27162e4eSAndroid Build Coastguard Worker input_filename = inFileNames[0];
729*27162e4eSAndroid Build Coastguard Worker #ifdef UTIL_HAS_CREATEFILELIST
730*27162e4eSAndroid Build Coastguard Worker if (recursive) { /* at this stage, filenameTable is a list of paths, which can contain both files and directories */
731*27162e4eSAndroid Build Coastguard Worker const char** extendedFileList = UTIL_createFileList(inFileNames, ifnIdx, &fileNamesBuf, &fileNamesNb);
732*27162e4eSAndroid Build Coastguard Worker if (extendedFileList) {
733*27162e4eSAndroid Build Coastguard Worker unsigned u;
734*27162e4eSAndroid Build Coastguard Worker for (u=0; u<fileNamesNb; u++) DISPLAYLEVEL(4, "%u %s\n", u, extendedFileList[u]);
735*27162e4eSAndroid Build Coastguard Worker free((void*)inFileNames);
736*27162e4eSAndroid Build Coastguard Worker inFileNames = extendedFileList;
737*27162e4eSAndroid Build Coastguard Worker ifnIdx = fileNamesNb;
738*27162e4eSAndroid Build Coastguard Worker } }
739*27162e4eSAndroid Build Coastguard Worker #endif
740*27162e4eSAndroid Build Coastguard Worker }
741*27162e4eSAndroid Build Coastguard Worker
742*27162e4eSAndroid Build Coastguard Worker if (dictionary_filename) {
743*27162e4eSAndroid Build Coastguard Worker if (!strcmp(dictionary_filename, stdinmark) && IS_CONSOLE(stdin)) {
744*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "refusing to read from a console\n");
745*27162e4eSAndroid Build Coastguard Worker exit(1);
746*27162e4eSAndroid Build Coastguard Worker }
747*27162e4eSAndroid Build Coastguard Worker LZ4IO_setDictionaryFilename(prefs, dictionary_filename);
748*27162e4eSAndroid Build Coastguard Worker }
749*27162e4eSAndroid Build Coastguard Worker
750*27162e4eSAndroid Build Coastguard Worker /* benchmark and test modes */
751*27162e4eSAndroid Build Coastguard Worker if (mode == om_bench) {
752*27162e4eSAndroid Build Coastguard Worker BMK_setNotificationLevel(displayLevel);
753*27162e4eSAndroid Build Coastguard Worker operationResult = BMK_benchFiles(inFileNames, ifnIdx, cLevel, cLevelLast, dictionary_filename);
754*27162e4eSAndroid Build Coastguard Worker goto _cleanup;
755*27162e4eSAndroid Build Coastguard Worker }
756*27162e4eSAndroid Build Coastguard Worker
757*27162e4eSAndroid Build Coastguard Worker if (mode == om_test) {
758*27162e4eSAndroid Build Coastguard Worker LZ4IO_setTestMode(prefs, 1);
759*27162e4eSAndroid Build Coastguard Worker output_filename = nulmark;
760*27162e4eSAndroid Build Coastguard Worker mode = om_decompress; /* defer to decompress */
761*27162e4eSAndroid Build Coastguard Worker }
762*27162e4eSAndroid Build Coastguard Worker
763*27162e4eSAndroid Build Coastguard Worker /* No input provided => use stdin */
764*27162e4eSAndroid Build Coastguard Worker if (!input_filename) input_filename = stdinmark;
765*27162e4eSAndroid Build Coastguard Worker
766*27162e4eSAndroid Build Coastguard Worker /* Refuse to use the console as input */
767*27162e4eSAndroid Build Coastguard Worker if (!strcmp(input_filename, stdinmark) && IS_CONSOLE(stdin) ) {
768*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "refusing to read from a console\n");
769*27162e4eSAndroid Build Coastguard Worker exit(1);
770*27162e4eSAndroid Build Coastguard Worker }
771*27162e4eSAndroid Build Coastguard Worker
772*27162e4eSAndroid Build Coastguard Worker if (!strcmp(input_filename, stdinmark)) {
773*27162e4eSAndroid Build Coastguard Worker /* if input==stdin and no output defined, stdout becomes default output */
774*27162e4eSAndroid Build Coastguard Worker if (!output_filename) output_filename = stdoutmark;
775*27162e4eSAndroid Build Coastguard Worker }
776*27162e4eSAndroid Build Coastguard Worker
777*27162e4eSAndroid Build Coastguard Worker /* No output filename ==> try to select one automatically (when possible) */
778*27162e4eSAndroid Build Coastguard Worker if ((!output_filename) && (multiple_inputs==0)) {
779*27162e4eSAndroid Build Coastguard Worker if (mode == om_auto) { /* auto-determine compression or decompression, based on file extension */
780*27162e4eSAndroid Build Coastguard Worker mode = determineOpMode(input_filename);
781*27162e4eSAndroid Build Coastguard Worker }
782*27162e4eSAndroid Build Coastguard Worker if (mode == om_compress) { /* compression to file */
783*27162e4eSAndroid Build Coastguard Worker size_t const l = strlen(input_filename);
784*27162e4eSAndroid Build Coastguard Worker dynNameSpace = (char*)calloc(1,l+5);
785*27162e4eSAndroid Build Coastguard Worker if (dynNameSpace==NULL) { perror(exeName); exit(1); }
786*27162e4eSAndroid Build Coastguard Worker strcpy(dynNameSpace, input_filename);
787*27162e4eSAndroid Build Coastguard Worker strcat(dynNameSpace, LZ4_EXTENSION);
788*27162e4eSAndroid Build Coastguard Worker output_filename = dynNameSpace;
789*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(2, "Compressed filename will be : %s \n", output_filename);
790*27162e4eSAndroid Build Coastguard Worker }
791*27162e4eSAndroid Build Coastguard Worker if (mode == om_decompress) {
792*27162e4eSAndroid Build Coastguard Worker /* decompress to file (automatic output name only works if input filename has correct format extension) */
793*27162e4eSAndroid Build Coastguard Worker size_t outl;
794*27162e4eSAndroid Build Coastguard Worker size_t const inl = strlen(input_filename);
795*27162e4eSAndroid Build Coastguard Worker dynNameSpace = (char*)calloc(1,inl+1);
796*27162e4eSAndroid Build Coastguard Worker if (dynNameSpace==NULL) { perror(exeName); exit(1); }
797*27162e4eSAndroid Build Coastguard Worker strcpy(dynNameSpace, input_filename);
798*27162e4eSAndroid Build Coastguard Worker outl = inl;
799*27162e4eSAndroid Build Coastguard Worker if (inl>4)
800*27162e4eSAndroid Build Coastguard Worker while ((outl >= inl-4) && (input_filename[outl] == extension[outl-inl+4])) dynNameSpace[outl--]=0;
801*27162e4eSAndroid Build Coastguard Worker if (outl != inl-5) { DISPLAYLEVEL(1, "Cannot determine an output filename \n"); badusage(exeName); }
802*27162e4eSAndroid Build Coastguard Worker output_filename = dynNameSpace;
803*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(2, "Decoding file %s \n", output_filename);
804*27162e4eSAndroid Build Coastguard Worker }
805*27162e4eSAndroid Build Coastguard Worker }
806*27162e4eSAndroid Build Coastguard Worker
807*27162e4eSAndroid Build Coastguard Worker if (mode == om_list) {
808*27162e4eSAndroid Build Coastguard Worker if (!multiple_inputs) inFileNames[ifnIdx++] = input_filename;
809*27162e4eSAndroid Build Coastguard Worker } else {
810*27162e4eSAndroid Build Coastguard Worker if (!multiple_inputs) assert(output_filename != NULL);
811*27162e4eSAndroid Build Coastguard Worker }
812*27162e4eSAndroid Build Coastguard Worker /* when multiple_inputs==1, output_filename may simply be useless,
813*27162e4eSAndroid Build Coastguard Worker * however, output_filename must be !NULL for next strcmp() tests */
814*27162e4eSAndroid Build Coastguard Worker if (!output_filename) output_filename = "*\\dummy^!//";
815*27162e4eSAndroid Build Coastguard Worker
816*27162e4eSAndroid Build Coastguard Worker /* Check if output is defined as console; trigger an error in this case */
817*27162e4eSAndroid Build Coastguard Worker if ( !strcmp(output_filename,stdoutmark)
818*27162e4eSAndroid Build Coastguard Worker && mode != om_list
819*27162e4eSAndroid Build Coastguard Worker && IS_CONSOLE(stdout)
820*27162e4eSAndroid Build Coastguard Worker && !forceStdout) {
821*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(1, "refusing to write to console without -c \n");
822*27162e4eSAndroid Build Coastguard Worker exit(1);
823*27162e4eSAndroid Build Coastguard Worker }
824*27162e4eSAndroid Build Coastguard Worker /* Downgrade notification level in stdout and multiple file mode */
825*27162e4eSAndroid Build Coastguard Worker if (!strcmp(output_filename,stdoutmark) && (displayLevel==2)) displayLevel=1;
826*27162e4eSAndroid Build Coastguard Worker if ((multiple_inputs) && (displayLevel==2)) displayLevel=1;
827*27162e4eSAndroid Build Coastguard Worker
828*27162e4eSAndroid Build Coastguard Worker /* Auto-determine compression or decompression, based on file extension */
829*27162e4eSAndroid Build Coastguard Worker if (mode == om_auto) {
830*27162e4eSAndroid Build Coastguard Worker mode = determineOpMode(input_filename);
831*27162e4eSAndroid Build Coastguard Worker }
832*27162e4eSAndroid Build Coastguard Worker
833*27162e4eSAndroid Build Coastguard Worker /* IO Stream/File */
834*27162e4eSAndroid Build Coastguard Worker LZ4IO_setNotificationLevel((int)displayLevel);
835*27162e4eSAndroid Build Coastguard Worker if (ifnIdx == 0) multiple_inputs = 0;
836*27162e4eSAndroid Build Coastguard Worker if (mode == om_decompress) {
837*27162e4eSAndroid Build Coastguard Worker if (multiple_inputs) {
838*27162e4eSAndroid Build Coastguard Worker const char* dec_extension = LZ4_EXTENSION;
839*27162e4eSAndroid Build Coastguard Worker if (!strcmp(output_filename, stdoutmark)) dec_extension = stdoutmark;
840*27162e4eSAndroid Build Coastguard Worker if (!strcmp(output_filename, nulmark)) dec_extension = nulmark;
841*27162e4eSAndroid Build Coastguard Worker assert(ifnIdx < INT_MAX);
842*27162e4eSAndroid Build Coastguard Worker operationResult = LZ4IO_decompressMultipleFilenames(inFileNames, (int)ifnIdx, dec_extension, prefs);
843*27162e4eSAndroid Build Coastguard Worker } else {
844*27162e4eSAndroid Build Coastguard Worker operationResult = DEFAULT_DECOMPRESSOR(input_filename, output_filename, prefs);
845*27162e4eSAndroid Build Coastguard Worker }
846*27162e4eSAndroid Build Coastguard Worker } else if (mode == om_list){
847*27162e4eSAndroid Build Coastguard Worker operationResult = LZ4IO_displayCompressedFilesInfo(inFileNames, ifnIdx);
848*27162e4eSAndroid Build Coastguard Worker } else { /* compression is default action */
849*27162e4eSAndroid Build Coastguard Worker #if LZ4IO_MULTITHREAD
850*27162e4eSAndroid Build Coastguard Worker if (nbWorkers != 1) {
851*27162e4eSAndroid Build Coastguard Worker if (nbWorkers==0)
852*27162e4eSAndroid Build Coastguard Worker nbWorkers = (unsigned)LZ4IO_defaultNbWorkers();
853*27162e4eSAndroid Build Coastguard Worker if (nbWorkers > LZ4_NBWORKERS_MAX) {
854*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(3, "Requested %u threads too large => automatically reduced to %u \n",
855*27162e4eSAndroid Build Coastguard Worker nbWorkers, LZ4_NBWORKERS_MAX);
856*27162e4eSAndroid Build Coastguard Worker nbWorkers = LZ4_NBWORKERS_MAX;
857*27162e4eSAndroid Build Coastguard Worker } else {
858*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(3, "Using %u threads for compression \n", nbWorkers);
859*27162e4eSAndroid Build Coastguard Worker }
860*27162e4eSAndroid Build Coastguard Worker }
861*27162e4eSAndroid Build Coastguard Worker LZ4IO_setNbWorkers(prefs, (int)nbWorkers);
862*27162e4eSAndroid Build Coastguard Worker #endif
863*27162e4eSAndroid Build Coastguard Worker if (legacy_format) {
864*27162e4eSAndroid Build Coastguard Worker DISPLAYLEVEL(3, "! Generating LZ4 Legacy format (deprecated) ! \n");
865*27162e4eSAndroid Build Coastguard Worker if(multiple_inputs){
866*27162e4eSAndroid Build Coastguard Worker const char* const leg_extension = !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION;
867*27162e4eSAndroid Build Coastguard Worker operationResult = LZ4IO_compressMultipleFilenames_Legacy(inFileNames, (int)ifnIdx, leg_extension, cLevel, prefs);
868*27162e4eSAndroid Build Coastguard Worker } else {
869*27162e4eSAndroid Build Coastguard Worker operationResult = LZ4IO_compressFilename_Legacy(input_filename, output_filename, cLevel, prefs);
870*27162e4eSAndroid Build Coastguard Worker }
871*27162e4eSAndroid Build Coastguard Worker } else {
872*27162e4eSAndroid Build Coastguard Worker if (multiple_inputs) {
873*27162e4eSAndroid Build Coastguard Worker const char* const comp_extension = !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION;
874*27162e4eSAndroid Build Coastguard Worker assert(ifnIdx <= INT_MAX);
875*27162e4eSAndroid Build Coastguard Worker operationResult = LZ4IO_compressMultipleFilenames(inFileNames, (int)ifnIdx, comp_extension, cLevel, prefs);
876*27162e4eSAndroid Build Coastguard Worker } else {
877*27162e4eSAndroid Build Coastguard Worker operationResult = DEFAULT_COMPRESSOR(input_filename, output_filename, cLevel, prefs);
878*27162e4eSAndroid Build Coastguard Worker } } }
879*27162e4eSAndroid Build Coastguard Worker
880*27162e4eSAndroid Build Coastguard Worker _cleanup:
881*27162e4eSAndroid Build Coastguard Worker if (main_pause) waitEnter();
882*27162e4eSAndroid Build Coastguard Worker free(dynNameSpace);
883*27162e4eSAndroid Build Coastguard Worker free(fileNamesBuf);
884*27162e4eSAndroid Build Coastguard Worker LZ4IO_freePreferences(prefs);
885*27162e4eSAndroid Build Coastguard Worker free((void*)inFileNames);
886*27162e4eSAndroid Build Coastguard Worker return operationResult;
887*27162e4eSAndroid Build Coastguard Worker }
888