changeset 2004:161e731eb152

Improve dmGetIntVal() to accept an optional negative value boolean flag pointer. Also improve error handling in it.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 07 Jul 2018 01:11:22 +0300
parents 2ae47dcaaf10
children 2ff214f811b4
files src/dmlib.c src/dmlib.h tests/dzlibtest.c tools/gfxconv.c tools/objlink.c tools/packed.c
diffstat 6 files changed, 83 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/dmlib.c	Tue Jul 03 09:54:14 2018 +0300
+++ b/src/dmlib.c	Sat Jul 07 01:11:22 2018 +0300
@@ -136,22 +136,76 @@
 #endif
 
 
-BOOL dmGetIntVal(const char *s, unsigned int *i)
+BOOL dmGetIntVal(const char *str, unsigned int *value, BOOL *neg)
 {
-    if (s[0] == '$')
+    int ch;
+    BOOL hex = FALSE;
+
+    // Is the value negative?
+    if (*str == '-')
     {
-        if (sscanf(&s[1], "%x", i) < 1)
+        if (neg == NULL)
             return FALSE;
+
+        *neg = TRUE;
+        str++;
     }
-    else if (s[0] == '0' && s[1] == 'x')
+    else
+    if (neg != NULL)
+        *neg = FALSE;
+
+    // Is it hexadecimal?
+    if (*str == '$')
+    {
+        hex = TRUE;
+        str++;
+    }
+    else
+    if (str[0] == '0' && str[1] == 'x')
     {
-        if (sscanf(&s[2], "%x", i) < 1)
-            return FALSE;
+        hex = TRUE;
+        str += 2;
+    }
+
+    // Parse the value
+    *value = 0;
+    if (hex)
+    {
+        while ((ch = *str++))
+        {
+            if (ch >= '0' && ch <= '9')
+            {
+                *value <<= 4;
+                *value |= ch - '0';
+            }
+            else
+            if (ch >= 'A' && ch <= 'F')
+            {
+                *value <<= 4;
+                *value |= ch - 'A';
+            }
+            else
+            if (ch >= 'a' && ch <= 'f')
+            {
+                *value <<= 4;
+                *value |= ch - 'a';
+            }
+            else
+                return FALSE;
+        }
     }
     else
     {
-        if (sscanf(s, "%u", i) < 1)
-            return FALSE;
+        while ((ch = *str++))
+        {
+            if (ch >= '0' && ch <= '9')
+            {
+                *value *= 10;
+                *value += ch - '0';
+            }
+            else
+                return FALSE;
+        }
     }
     return TRUE;
 }
--- a/src/dmlib.h	Tue Jul 03 09:54:14 2018 +0300
+++ b/src/dmlib.h	Sat Jul 07 01:11:22 2018 +0300
@@ -418,7 +418,7 @@
 char *     dm_strdup_fext(const char *filename, const char *fmt);
 char *     dm_strrcasecmp(char *str, const char *needle);
 
-BOOL       dmGetIntVal(const char *s, unsigned int *i);
+BOOL       dmGetIntVal(const char *str, unsigned int *value, BOOL *neg);
 
 
 /* Mutexes
--- a/tests/dzlibtest.c	Tue Jul 03 09:54:14 2018 +0300
+++ b/tests/dzlibtest.c	Sat Jul 07 01:11:22 2018 +0300
@@ -61,7 +61,7 @@
             break;
 
         case 4:
-            if (!dmGetIntVal(optArg, &optCompressLevel) ||
+            if (!dmGetIntVal(optArg, &optCompressLevel, NULL) ||
                 optCompressLevel < 1 || optCompressLevel > 9)
             {
                 dmErrorMsg("Invalid compression level argument '%s', must be 1 .. 9.\n", optArg);
@@ -70,9 +70,9 @@
             break;
 
         case 5:
-            if (!dmGetIntVal(optArg, &optSkip))
+            if (!dmGetIntVal(optArg, &optSkip, NULL))
             {
-                dmErrorMsg("Invalid skip value.\n", optArg);
+                dmErrorMsg("Invalid skip value '%s'.\n", optArg);
                 return FALSE;
             }
             break;
--- a/tools/gfxconv.c	Tue Jul 03 09:54:14 2018 +0300
+++ b/tools/gfxconv.c	Sat Jul 07 01:11:22 2018 +0300
@@ -381,7 +381,7 @@
     }
     else
     {
-        if (!dmGetIntVal(opt, &value->from))
+        if (!dmGetIntVal(opt, &value->from, NULL))
         {
             dmErrorMsg("Invalid %s value '%s', could not parse source value '%s'.\n", msg, popt, opt);
             goto error;
@@ -394,7 +394,7 @@
     while (*split && isspace(*split)) split++;
 
     // Parse destination value
-    if (!dmGetIntVal(split, &value->to))
+    if (!dmGetIntVal(split, &value->to, NULL))
     {
         dmErrorMsg("Invalid %s value '%s', could not parse destination value '%s'.\n", msg, popt, split);
         goto error;
@@ -449,7 +449,7 @@
             return FALSE;
         }
 
-        if (!dmGetIntVal(opt, &value[index]))
+        if (!dmGetIntVal(opt, &value[index], NULL))
         {
             dmErrorMsg("Invalid %s value '%s', could not parse.\n", msg, opt);
             return FALSE;
@@ -606,7 +606,7 @@
 
     *arg = ptr;
 
-    return dmGetIntVal(start, value);
+    return dmGetIntVal(start, value, NULL);
 }
 
 
@@ -653,7 +653,7 @@
             break;
 
         case 4:
-            if (!dmGetIntVal(optArg, &optInSkip))
+            if (!dmGetIntVal(optArg, &optInSkip, NULL))
             {
                 dmErrorMsg("Invalid skip value argument '%s'.\n", optArg);
                 return FALSE;
@@ -696,7 +696,7 @@
             break;
 
         case 7:
-            if (!dmGetIntVal(optArg, &tmpUInt) ||
+            if (!dmGetIntVal(optArg, &tmpUInt, NULL) ||
                 tmpUInt < 1)
             {
                 dmErrorMsg("Invalid count value argument '%s' [1 .. MAXINT]\n",
@@ -768,7 +768,7 @@
             break;
 
         case 11:
-            if (!dmGetIntVal(optArg, &tmpUInt) ||
+            if (!dmGetIntVal(optArg, &tmpUInt, NULL) ||
                 tmpUInt < 1 || tmpUInt > 512)
             {
                 dmErrorMsg("Invalid planed width value '%s' [1 .. 512]\n",
@@ -783,7 +783,7 @@
             break;
 
         case 13:
-            if (!dmGetIntVal(optArg, &tmpUInt) ||
+            if (!dmGetIntVal(optArg, &tmpUInt, NULL) ||
                 tmpUInt < 1 || tmpUInt > 8)
             {
                 dmErrorMsg("Invalid number of bitplanes value '%s' [1 .. 8]\n",
@@ -794,7 +794,7 @@
             break;
 
         case 18:
-            if (!dmGetIntVal(optArg, &tmpUInt) ||
+            if (!dmGetIntVal(optArg, &tmpUInt, NULL) ||
                 tmpUInt < 1 || tmpUInt > 32)
             {
                 dmErrorMsg("Invalid number of bits per pixel value '%s' [1 .. 32]\n",
--- a/tools/objlink.c	Tue Jul 03 09:54:14 2018 +0300
+++ b/tools/objlink.c	Sat Jul 07 01:11:22 2018 +0300
@@ -259,7 +259,7 @@
     *sep = 0;
 
     // Get value
-    if (!dmGetIntVal(str, sectStart))
+    if (!dmGetIntVal(str, sectStart, NULL))
     {
         dmErrorMsg("Section start address '%s' in '%s' invalid.\n", str, arg);
         goto out;
@@ -288,7 +288,7 @@
     }
 
     // Get end address or length
-    if (!dmGetIntVal(sep + 1, &tmpi))
+    if (!dmGetIntVal(sep + 1, &tmpi, NULL))
     {
         dmErrorMsg("Section %s '%s' in '%s' invalid.\n",
             sectMode == '-' ? "end address" : "length",
@@ -328,7 +328,7 @@
     if ((sep = strrchr(arg, ':')) != NULL)
     {
         *sep = 0;
-        if (!dmGetIntVal(sep + 1, &tmpi))
+        if (!dmGetIntVal(sep + 1, &tmpi, NULL))
         {
             dmErrorMsg("Invalid %s address '%s' specified for '%s'.\n",
                 desc, sep + 1, arg);
@@ -438,7 +438,7 @@
                     return FALSE;
             }
         }
-        if (!dmGetIntVal(optArg, &tmpi))
+        if (!dmGetIntVal(optArg, &tmpi, NULL))
         {
             dmErrorMsg("Invalid initvalue '%s'.\n", optArg);
             return FALSE;
@@ -488,7 +488,7 @@
             optLoadAddress = LA_NONE;
         else
         {
-            if (!dmGetIntVal(optArg, &tmpi))
+            if (!dmGetIntVal(optArg, &tmpi, NULL))
             {
                 dmErrorMsg("Invalid loading address '%s'.\n", optArg);
                 return FALSE;
--- a/tools/packed.c	Tue Jul 03 09:54:14 2018 +0300
+++ b/tools/packed.c	Sat Jul 07 01:11:22 2018 +0300
@@ -121,13 +121,13 @@
 
         case 4:
             {
-                unsigned int i;
-                if (!dmGetIntVal(optArg, &i))
+                unsigned int tmpUI;
+                if (!dmGetIntVal(optArg, &tmpUI, NULL))
                 {
                     dmErrorMsg("Invalid flags value '%s'.\n", optArg);
                     return FALSE;
                 }
-                optDefResFlags = i;
+                optDefResFlags = tmpUI;
             }
             break;