]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Add support for --long-param flag 2703/head
authorBinh Vo <binhvo@fb.com>
Wed, 9 Jun 2021 18:00:29 +0000 (14:00 -0400)
committerBinh Vo <binhvo@fb.com>
Wed, 9 Jun 2021 18:07:52 +0000 (14:07 -0400)
programs/zstdcli.c
tests/playTests.sh

index 9e2133c4f867f74c6f4eacf7b608ba6c257d5515..28fc980a2bf14f8a06dd9f7553c87526114721df 100644 (file)
@@ -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");
@@ -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.
@@ -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 */
@@ -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);
index 25293900656d813db706ef799eea46b5bba6380b..09dae1a297f2243be1e3b60dc1e2f8db802ad064 100755 (executable)
@@ -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"