Skip to content

Commit 9eb1fd0

Browse files
author
Binh Vo
committed
Add support for --long-param flag
1 parent d2f31b6 commit 9eb1fd0

File tree

2 files changed

+62
-17
lines changed

2 files changed

+62
-17
lines changed

programs/zstdcli.c

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ static void usage_advanced(const char* programName)
206206
DISPLAYOUT( "--ultra : enable levels beyond %i, up to %i (requires more memory) \n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel());
207207
DISPLAYOUT( "--long[=#]: enable long distance matching with given window log (default: %u) \n", g_defaultMaxWindowLog);
208208
DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1);
209+
DISPLAYOUT( "--long-param=#: specify compression level, accepts negative values as fast compression levels \n");
209210
DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n");
210211
DISPLAYOUT( "--[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n");
211212
DISPLAYOUT( "--patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n");
@@ -354,6 +355,25 @@ static unsigned readU32FromChar(const char** stringPtr) {
354355
return result;
355356
}
356357

358+
#ifndef ZSTD_NOCOMPRESS
359+
/*! readIntFromChar() :
360+
* @return : signed integer value read from input in `char` format.
361+
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
362+
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
363+
* Note : function will exit() program if digit sequence overflows */
364+
static int readIntFromChar(const char** stringPtr) {
365+
static const char errorMsg[] = "error: numeric value overflows 32-bit int";
366+
int sign = 1;
367+
unsigned result;
368+
if (**stringPtr=='-') {
369+
(*stringPtr)++;
370+
sign = -1;
371+
}
372+
if (readU32FromCharChecked(stringPtr, &result)) { errorOut(errorMsg); }
373+
return (int) result * sign;
374+
}
375+
#endif
376+
357377
/*! readSizeTFromCharChecked() :
358378
* @return 0 if success, and store the result in *value.
359379
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
@@ -940,23 +960,6 @@ int main(int const argCount, const char* argv[])
940960
if (longCommandWArg(&argument, "--trace")) { char const* traceFile; NEXT_FIELD(traceFile); TRACE_enable(traceFile); continue; }
941961
#endif
942962
if (longCommandWArg(&argument, "--patch-from")) { NEXT_FIELD(patchFromDictFileName); continue; }
943-
if (longCommandWArg(&argument, "--long")) {
944-
unsigned ldmWindowLog = 0;
945-
ldmFlag = 1;
946-
/* Parse optional window log */
947-
if (*argument == '=') {
948-
++argument;
949-
ldmWindowLog = readU32FromChar(&argument);
950-
} else if (*argument != 0) {
951-
/* Invalid character following --long */
952-
badusage(programName);
953-
CLEAN_RETURN(1);
954-
}
955-
/* Only set windowLog if not already set by --zstd */
956-
if (compressionParams.windowLog == 0)
957-
compressionParams.windowLog = ldmWindowLog;
958-
continue;
959-
}
960963
#ifndef ZSTD_NOCOMPRESS /* linking ZSTD_minCLevel() requires compression support */
961964
if (longCommandWArg(&argument, "--fast")) {
962965
/* Parse optional acceleration factor */
@@ -981,8 +984,43 @@ int main(int const argCount, const char* argv[])
981984
}
982985
continue;
983986
}
987+
988+
if (longCommandWArg(&argument, "--long-param")) {
989+
if (*argument == '=') {
990+
int maxLevel = ZSTD_maxCLevel();
991+
int minLevel = ZSTD_minCLevel();
992+
++argument;
993+
int readLevel = readIntFromChar(&argument);
994+
if (readLevel > maxLevel) readLevel = maxLevel;
995+
if (readLevel < minLevel) readLevel = minLevel;
996+
cLevel = readLevel;
997+
} else {
998+
/* --long-param requires an argument */
999+
badusage(programName);
1000+
CLEAN_RETURN(1);
1001+
}
1002+
continue;
1003+
}
9841004
#endif
9851005

1006+
if (longCommandWArg(&argument, "--long")) {
1007+
unsigned ldmWindowLog = 0;
1008+
ldmFlag = 1;
1009+
/* Parse optional window log */
1010+
if (*argument == '=') {
1011+
++argument;
1012+
ldmWindowLog = readU32FromChar(&argument);
1013+
} else if (*argument != 0) {
1014+
/* Invalid character following --long */
1015+
badusage(programName);
1016+
CLEAN_RETURN(1);
1017+
}
1018+
/* Only set windowLog if not already set by --zstd */
1019+
if (compressionParams.windowLog == 0)
1020+
compressionParams.windowLog = ldmWindowLog;
1021+
continue;
1022+
}
1023+
9861024
if (longCommandWArg(&argument, "--filelist")) {
9871025
const char* listName;
9881026
NEXT_FIELD(listName);

tests/playTests.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,13 @@ zstd --fast=3 -f tmp # == -3
191191
zstd --fast=200000 -f tmp # too low compression level, automatic fixed
192192
zstd --fast=5000000000 -f tmp && die "too large numeric value : must fail"
193193
zstd -c --fast=0 tmp > $INTOVOID && die "--fast must not accept value 0"
194+
println "test : --long-param compression levels"
195+
zstd --long-param=1 -f tmp
196+
zstd --long-param=0 -f tmp
197+
zstd --long-param=-1 -f tmp
198+
zstd --long-param=-10000 -f tmp # too low, automatic fixed
199+
zstd --long-param=10000 -f tmp # too high, automatic fixed
200+
zstd --long-param -f tmp > $INTOVOID && die "--long-param must be given a value"
194201
println "test : too large numeric argument"
195202
zstd --fast=9999999999 -f tmp && die "should have refused numeric value"
196203
println "test : set compression level with environment variable ZSTD_CLEVEL"

0 commit comments

Comments
 (0)