Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for --long-param flag, fix #2104 #2703

Merged
merged 1 commit into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 56 additions & 17 deletions programs/zstdcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ static void usage_advanced(const char* programName)
DISPLAYOUT( "--ultra : enable levels beyond %i, up to %i (requires more memory) \n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel());
DISPLAYOUT( "--long[=#]: enable long distance matching with given window log (default: %u) \n", g_defaultMaxWindowLog);
DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1);
DISPLAYOUT( "--long-param=#: specify compression level, accepts negative values as fast compression levels \n");
DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n");
DISPLAYOUT( "--[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n");
DISPLAYOUT( "--patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n");
Expand Down Expand Up @@ -354,6 +355,25 @@ static unsigned readU32FromChar(const char** stringPtr) {
return result;
}

#ifndef ZSTD_NOCOMPRESS
/*! readIntFromChar() :
* @return : signed integer value read from input in `char` format.
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
* Note : function will exit() program if digit sequence overflows */
static int readIntFromChar(const char** stringPtr) {
static const char errorMsg[] = "error: numeric value overflows 32-bit int";
int sign = 1;
unsigned result;
if (**stringPtr=='-') {
(*stringPtr)++;
sign = -1;
}
if (readU32FromCharChecked(stringPtr, &result)) { errorOut(errorMsg); }
return (int) result * sign;
}
#endif

/*! readSizeTFromCharChecked() :
* @return 0 if success, and store the result in *value.
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
Expand Down Expand Up @@ -940,23 +960,6 @@ int main(int const argCount, const char* argv[])
if (longCommandWArg(&argument, "--trace")) { char const* traceFile; NEXT_FIELD(traceFile); TRACE_enable(traceFile); continue; }
#endif
if (longCommandWArg(&argument, "--patch-from")) { NEXT_FIELD(patchFromDictFileName); continue; }
if (longCommandWArg(&argument, "--long")) {
unsigned ldmWindowLog = 0;
ldmFlag = 1;
/* Parse optional window log */
if (*argument == '=') {
++argument;
ldmWindowLog = readU32FromChar(&argument);
} else if (*argument != 0) {
/* Invalid character following --long */
badusage(programName);
CLEAN_RETURN(1);
}
/* Only set windowLog if not already set by --zstd */
if (compressionParams.windowLog == 0)
compressionParams.windowLog = ldmWindowLog;
continue;
}
#ifndef ZSTD_NOCOMPRESS /* linking ZSTD_minCLevel() requires compression support */
if (longCommandWArg(&argument, "--fast")) {
/* Parse optional acceleration factor */
Expand All @@ -981,8 +984,44 @@ int main(int const argCount, const char* argv[])
}
continue;
}

if (longCommandWArg(&argument, "--long-param")) {
if (*argument == '=') {
int maxLevel = ZSTD_maxCLevel();
int minLevel = ZSTD_minCLevel();
int readLevel;
++argument;
readLevel = readIntFromChar(&argument);
if (readLevel > maxLevel) readLevel = maxLevel;
if (readLevel < minLevel) readLevel = minLevel;
cLevel = readLevel;
} else {
/* --long-param requires an argument */
badusage(programName);
CLEAN_RETURN(1);
}
continue;
}
#endif

if (longCommandWArg(&argument, "--long")) {
unsigned ldmWindowLog = 0;
ldmFlag = 1;
/* Parse optional window log */
if (*argument == '=') {
++argument;
ldmWindowLog = readU32FromChar(&argument);
} else if (*argument != 0) {
/* Invalid character following --long */
badusage(programName);
CLEAN_RETURN(1);
}
/* Only set windowLog if not already set by --zstd */
if (compressionParams.windowLog == 0)
compressionParams.windowLog = ldmWindowLog;
continue;
}

if (longCommandWArg(&argument, "--filelist")) {
const char* listName;
NEXT_FIELD(listName);
Expand Down
7 changes: 7 additions & 0 deletions tests/playTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ zstd --fast=3 -f tmp # == -3
zstd --fast=200000 -f tmp # too low compression level, automatic fixed
zstd --fast=5000000000 -f tmp && die "too large numeric value : must fail"
zstd -c --fast=0 tmp > $INTOVOID && die "--fast must not accept value 0"
println "test : --long-param compression levels"
zstd --long-param=1 -f tmp
zstd --long-param=0 -f tmp
zstd --long-param=-1 -f tmp
zstd --long-param=-10000 -f tmp # too low, automatic fixed
zstd --long-param=10000 -f tmp # too high, automatic fixed
zstd --long-param -f tmp > $INTOVOID && die "--long-param must be given a value"
println "test : too large numeric argument"
zstd --fast=9999999999 -f tmp && die "should have refused numeric value"
println "test : set compression level with environment variable ZSTD_CLEVEL"
Expand Down