changeset 1888:b97f273a9d54

Improve some gfxconv commanline option parsing.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 25 Jun 2018 15:54:23 +0300
parents 297aa8f0ca7f
children ac9784afae27
files tools/gfxconv.c
diffstat 1 files changed, 112 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/tools/gfxconv.c	Mon Jun 25 14:04:06 2018 +0300
+++ b/tools/gfxconv.c	Mon Jun 25 15:54:23 2018 +0300
@@ -488,6 +488,8 @@
     while (fgets(line, sizeof(line), fp))
     {
         char *start = line;
+        line[sizeof(line) - 1] = 0;
+
         while (*start && isspace(*start)) start++;
 
         if (*start != 0 && *start != ';')
@@ -557,8 +559,43 @@
 }
 
 
+BOOL dmParseIntValWithSep(char **arg, int *value, char *end, const char sep)
+{
+    unsigned int val;
+    char *ptr = *arg, *ptr2;
+    BOOL ret;
+
+    // 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)
+        ptr++;
+
+    ptr2 = ptr;
+
+    // Skip whitespace again
+    while (*ptr != 0 && isspace(*ptr))
+        ptr++;
+
+    *end = *ptr;
+    *ptr2 = 0;
+    if (*end != 0)
+        ptr++;
+
+    ret = dmGetIntVal(*arg, &val);
+    *arg = ptr;
+    *value = val;
+    return ret;
+}
+
+
 BOOL argHandleOpt(const int optN, char *optArg, char *currArg)
 {
+    int tmpInt;
+    char *tmpStr;
+
     switch (optN)
     {
         case 0:
@@ -652,37 +689,66 @@
             break;
 
         case 9:
-            if (sscanf(optArg, "%d:%d", &optSpec.scaleX, &optSpec.scaleY) != 2)
             {
-                if (sscanf(optArg, "%d", &optSpec.scaleX) == 1)
-                    optSpec.scaleY = optSpec.scaleX;
+                BOOL error = FALSE;
+                char *tmpStr = dm_strdup(optArg),
+                    *tmpOpt = tmpStr, sep;
+
+                if (dmParseIntValWithSep(&tmpOpt, &tmpInt, &sep, ':'))
+                {
+                    if (sep == ':' &&
+                        dmParseIntValWithSep(&tmpOpt, &optSpec.scaleY, &sep, '*'))
+                    {
+                        optSpec.scaleX = tmpInt;
+                        if (sep == '*' &&
+                            dmParseIntValWithSep(&tmpOpt, &tmpInt, &sep, 0))
+                        {
+                            optSpec.scaleX *= tmpInt;
+                            optSpec.scaleY *= tmpInt;
+                        }
+
+                        error = (sep != 0);
+                    }
+                    else
+                        error = TRUE;
+                }
                 else
+                    error = TRUE;
+
+                dmFree(tmpStr);
+
+                if (error)
                 {
-                    dmErrorMsg("Invalid scale option value '%s', should be <n> or <w>:<h>.\n", optArg);
+                    dmErrorMsg(
+                        "Invalid scale option value '%s', should be <n>, <w>:<h> or <w>:<h>*<n>.\n",
+                        optArg);
                     return FALSE;
                 }
-            }
-            if (optSpec.scaleX < 1 || optSpec.scaleX > 50)
-            {
-                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);
-                return FALSE;
+
+                if (optSpec.scaleX < 1 || optSpec.scaleX > 50)
+                {
+                    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);
+                    return FALSE;
+                }
             }
             break;
 
         case 11:
             if (sscanf(optArg, "%d", &optPlanedWidth) != 1)
             {
-                dmErrorMsg("Invalid planed width value argument '%s'.\n", optArg);
+                dmErrorMsg("Invalid planed width value argument '%s'.\n",
+                    optArg);
                 return FALSE;
             }
             if (optPlanedWidth < 1 || optPlanedWidth > 512)
             {
-                dmErrorMsg("Invalid planed width value '%d' [1..512].\n", optPlanedWidth);
+                dmErrorMsg("Invalid planed width value '%d' [1..512].\n",
+                    optPlanedWidth);
                 return FALSE;
             }
             break;
@@ -692,27 +758,25 @@
             break;
 
         case 13:
+            if (sscanf(optArg, "%d", &tmpInt) != 1 ||
+                tmpInt < 1 || tmpInt > 8)
             {
-                int tmp = atoi(optArg);
-                if (tmp < 1 || tmp > 8)
-                {
-                    dmErrorMsg("Invalid number of bitplanes value '%s'.\n", optArg);
-                    return FALSE;
-                }
-                optSpec.nplanes = tmp;
+                dmErrorMsg("Invalid number of bitplanes value '%s' [1..8].\n",
+                    optArg);
+                return FALSE;
             }
+            optSpec.nplanes = tmpInt;
             break;
 
         case 18:
+            if (sscanf(optArg, "%d", &tmpInt) != 1 ||
+                tmpInt < 1 || tmpInt > 32)
             {
-                int tmp = atoi(optArg);
-                if (tmp < 1 || tmp > 32)
-                {
-                    dmErrorMsg("Invalid number of bits per pixel value '%s'.\n", optArg);
-                    return FALSE;
-                }
-                optSpec.nplanes = tmp;
+                dmErrorMsg("Invalid number of bits per pixel value '%s' [1..32].\n",
+                    optArg);
+                return FALSE;
             }
+            optSpec.nplanes = tmpInt;
             break;
 
         case 14:
@@ -720,36 +784,33 @@
             break;
 
         case 16:
+            if ((tmpStr = dm_strrcasecmp(optArg, "+remove")) != NULL)
             {
-                char *tmp;
-                if ((tmp = dm_strrcasecmp(optArg, "+remove")) != NULL)
-                {
-                    optRemapRemove = TRUE;
-                    *tmp = 0;
-                }
+                optRemapRemove = TRUE;
+                *tmpStr = 0;
+            }
 
-                if (optArg[0] == '@')
+            if (optArg[0] == '@')
+            {
+                if (optArg[1] != 0)
                 {
-                    if (optArg[1] != 0)
-                    {
-                        int res;
-                        if ((res = dmParseColorRemapFile(optArg + 1,
-                            optRemapTable, &optNRemapTable, DM_MAX_COLORS)) != DMERR_OK)
-                            return FALSE;
-                    }
-                    else
-                    {
-                        dmErrorMsg("No remap filename given.\n");
+                    int res;
+                    if ((res = dmParseColorRemapFile(optArg + 1,
+                        optRemapTable, &optNRemapTable, DM_MAX_COLORS)) != DMERR_OK)
                         return FALSE;
-                    }
                 }
                 else
                 {
-                    if (!dmParseMapOptionString(optArg, optRemapTable,
-                        &optNRemapTable, DM_MAX_COLORS, TRUE, "color remap option"))
-                        return FALSE;
+                    dmErrorMsg("No remap filename given.\n");
+                    return FALSE;
                 }
             }
+            else
+            {
+                if (!dmParseMapOptionString(optArg, optRemapTable,
+                    &optNRemapTable, DM_MAX_COLORS, TRUE, "color remap option"))
+                    return FALSE;
+            }
 
             optRemapColors = TRUE;
             break;