changeset 1889:ac9784afae27

Improve option argument parsing.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 25 Jun 2018 17:10:24 +0300
parents b97f273a9d54
children ee95059b4c18
files tools/gfxconv.c
diffstat 1 files changed, 52 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/tools/gfxconv.c	Mon Jun 25 15:54:23 2018 +0300
+++ b/tools/gfxconv.c	Mon Jun 25 17:10:24 2018 +0300
@@ -128,8 +128,9 @@
     {  6, 'c', "colormap",      "Color mappings (see below for information)", OPT_ARGREQ },
     {  7, 'n', "numitems",      "How many 'items' to output (default: all)", OPT_ARGREQ },
     { 11, 'w', "width",         "Item width (number of items per row, min 1)", OPT_ARGREQ },
-    {  9, 'S', "scale",         "Scale output image by <n> or <x>:<y> integer factor(s). "
-                                "-S <n> scales both height and width by <n>.", OPT_ARGREQ },
+    {  9, 'S', "scale",         "Scale output image by <n>, <x>:<y>, <x>:<y>*<n> integer factor(s). "
+                                "-S <n> scales both height and width by <n>. -S <x>:<y>*<n> scales "
+                                "width by X*n and height Y*n.", OPT_ARGREQ },
     { 12, 'P', "paletted",      "Use indexed/paletted output IF possible.", OPT_NONE },
     { 13, 'N', "nplanes",       "# of bitplanes (some output formats)", OPT_ARGREQ },
     { 18, 'B', "bpp",           "Bits per pixel (some output formats)", OPT_ARGREQ },
@@ -559,41 +560,47 @@
 }
 
 
-BOOL dmParseIntValWithSep(char **arg, int *value, char *end, const char sep)
+BOOL dmParseIntValWithSep(char **arg, unsigned int *value, char *last, const char sep)
 {
-    unsigned int val;
-    char *ptr = *arg, *ptr2;
-    BOOL ret;
+    char *ptr = *arg, *end, *start;
 
     // Skip any whitespace at start
     while (*ptr != 0 && isspace(*ptr))
         ptr++;
 
-    // Find end of non-whitespace
-    while (*ptr != 0 && (isxdigit(*ptr) || *ptr == 'x' || *ptr == '$') && *ptr != sep)
+    start = ptr;
+
+    // Find next not-xdigit/separator
+    while (*ptr != 0 &&
+        (isxdigit(*ptr) || *ptr == 'x' || *ptr == '$') &&
+        *ptr != sep)
         ptr++;
 
-    ptr2 = ptr;
+    end = ptr;
 
     // Skip whitespace again
     while (*ptr != 0 && isspace(*ptr))
         ptr++;
 
-    *end = *ptr;
-    *ptr2 = 0;
-    if (*end != 0)
+    // Return last character in "last"
+    *last = *ptr;
+
+    // Set end to NUL
+    *end = 0;
+
+    // And if last character is not NUL, move ptr
+    if (*last != 0)
         ptr++;
 
-    ret = dmGetIntVal(*arg, &val);
     *arg = ptr;
-    *value = val;
-    return ret;
+
+    return dmGetIntVal(start, value);
 }
 
 
 BOOL argHandleOpt(const int optN, char *optArg, char *currArg)
 {
-    int tmpInt;
+    unsigned int tmpUInt;
     char *tmpStr;
 
     switch (optN)
@@ -677,11 +684,14 @@
             break;
 
         case 7:
-            if (sscanf(optArg, "%d", &optItemCount) != 1)
+            if (!dmGetIntVal(optArg, &tmpUInt) ||
+                tmpUInt < 1)
             {
-                dmErrorMsg("Invalid count value argument '%s'.\n", optArg);
+                dmErrorMsg("Invalid count value argument '%s' [1 .. MAXINT]\n",
+                    optArg);
                 return FALSE;
             }
+            optItemCount = tmpUInt;
             break;
 
         case 8:
@@ -691,22 +701,24 @@
         case 9:
             {
                 BOOL error = FALSE;
+                unsigned int tmpUInt2;
                 char *tmpStr = dm_strdup(optArg),
-                    *tmpOpt = tmpStr, sep;
+                     *tmpOpt = tmpStr, sep;
 
-                if (dmParseIntValWithSep(&tmpOpt, &tmpInt, &sep, ':'))
+                if (dmParseIntValWithSep(&tmpOpt, &tmpUInt, &sep, ':'))
                 {
                     if (sep == ':' &&
-                        dmParseIntValWithSep(&tmpOpt, &optSpec.scaleY, &sep, '*'))
+                        dmParseIntValWithSep(&tmpOpt, &tmpUInt2, &sep, '*'))
                     {
-                        optSpec.scaleX = tmpInt;
+                        optSpec.scaleX = tmpUInt;
+                        optSpec.scaleY = tmpUInt2;
+
                         if (sep == '*' &&
-                            dmParseIntValWithSep(&tmpOpt, &tmpInt, &sep, 0))
+                            dmParseIntValWithSep(&tmpOpt, &tmpUInt, &sep, 0))
                         {
-                            optSpec.scaleX *= tmpInt;
-                            optSpec.scaleY *= tmpInt;
+                            optSpec.scaleX *= tmpUInt;
+                            optSpec.scaleY *= tmpUInt;
                         }
-
                         error = (sep != 0);
                     }
                     else
@@ -727,30 +739,26 @@
 
                 if (optSpec.scaleX < 1 || optSpec.scaleX > 50)
                 {
-                    dmErrorMsg("Invalid X scale value '%d'.\n", optSpec.scaleX);
+                    dmErrorMsg("Invalid X scale value %d.\n", optSpec.scaleX);
                     return FALSE;
                 }
                 if (optSpec.scaleY < 1 || optSpec.scaleY > 50)
                 {
-                    dmErrorMsg("Invalid Y scale value '%d'.\n", optSpec.scaleY);
+                    dmErrorMsg("Invalid Y scale value %d.\n", optSpec.scaleY);
                     return FALSE;
                 }
             }
             break;
 
         case 11:
-            if (sscanf(optArg, "%d", &optPlanedWidth) != 1)
+            if (!dmGetIntVal(optArg, &tmpUInt) ||
+                tmpUInt < 1 || tmpUInt > 512)
             {
-                dmErrorMsg("Invalid planed width value argument '%s'.\n",
+                dmErrorMsg("Invalid planed width value '%s' [1 .. 512]\n",
                     optArg);
                 return FALSE;
             }
-            if (optPlanedWidth < 1 || optPlanedWidth > 512)
-            {
-                dmErrorMsg("Invalid planed width value '%d' [1..512].\n",
-                    optPlanedWidth);
-                return FALSE;
-            }
+            optPlanedWidth = tmpUInt;
             break;
 
         case 12:
@@ -758,25 +766,25 @@
             break;
 
         case 13:
-            if (sscanf(optArg, "%d", &tmpInt) != 1 ||
-                tmpInt < 1 || tmpInt > 8)
+            if (!dmGetIntVal(optArg, &tmpUInt) ||
+                tmpUInt < 1 || tmpUInt > 8)
             {
-                dmErrorMsg("Invalid number of bitplanes value '%s' [1..8].\n",
+                dmErrorMsg("Invalid number of bitplanes value '%s' [1 .. 8]\n",
                     optArg);
                 return FALSE;
             }
-            optSpec.nplanes = tmpInt;
+            optSpec.nplanes = tmpUInt;
             break;
 
         case 18:
-            if (sscanf(optArg, "%d", &tmpInt) != 1 ||
-                tmpInt < 1 || tmpInt > 32)
+            if (!dmGetIntVal(optArg, &tmpUInt) ||
+                tmpUInt < 1 || tmpUInt > 32)
             {
-                dmErrorMsg("Invalid number of bits per pixel value '%s' [1..32].\n",
+                dmErrorMsg("Invalid number of bits per pixel value '%s' [1 .. 32]\n",
                     optArg);
                 return FALSE;
             }
-            optSpec.nplanes = tmpInt;
+            optSpec.nplanes = tmpUInt;
             break;
 
         case 14: