Skip to content

Commit 78e16b1

Browse files
authored
Merge pull request #2703 from binhdvo/bootcamp
Add support for --long-param flag, fix #2104
2 parents 05d7090 + 6583fa3 commit 78e16b1

File tree

2 files changed

+63
-17
lines changed

2 files changed

+63
-17
lines changed

programs/zstdcli.c

Lines changed: 56 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,44 @@ 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+
int readLevel;
993+
++argument;
994+
readLevel = readIntFromChar(&argument);
995+
if (readLevel > maxLevel) readLevel = maxLevel;
996+
if (readLevel < minLevel) readLevel = minLevel;
997+
cLevel = readLevel;
998+
} else {
999+
/* --long-param requires an argument */
1000+
badusage(programName);
1001+
CLEAN_RETURN(1);
1002+
}
1003+
continue;
1004+
}
9841005
#endif
9851006

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