From 99f3bc51dfef8d4fb16c3d0540c669c79a02563b Mon Sep 17 00:00:00 2001
From: Iztok Jeras <iztok.jeras@redpitaya.com>
Date: 摹曛, 08 10月 2015 03:00:34 +0800
Subject: [PATCH] integer parser: removing some signed/unsigned function duplication

---
 libscpi/src/parser.c           |   78 +++------------
 libscpi/test/test_scpi_utils.c |   44 ++++----
 libscpi/inc/scpi/parser.h      |    8 -
 libscpi/inc/scpi/utils.h       |    8 -
 libscpi/src/utils.c            |  142 +++-------------------------
 5 files changed, 59 insertions(+), 221 deletions(-)

diff --git a/libscpi/inc/scpi/parser.h b/libscpi/inc/scpi/parser.h
index 35e3123..f7f2716 100644
--- a/libscpi/inc/scpi/parser.h
+++ b/libscpi/inc/scpi/parser.h
@@ -51,16 +51,14 @@
 
     size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len);
 #define SCPI_ResultMnemonic(context, data) SCPI_ResultCharacters((context), (data), strlen(data))
+    size_t SCPI_ResultInt32Base(scpi_t * context, int32_t val, int8_t base, scpi_bool_t sign);
+#define SCPI_ResultIntBase(context, val, base) SCPI_ResultInt32Base ((context), (val), (base), TRUE)
     size_t SCPI_ResultInt32(scpi_t * context, int32_t val);
 #define SCPI_ResultInt(context, val) SCPI_ResultInt32 ((context), (val))
-    size_t SCPI_ResultInt32Base(scpi_t * context, int32_t val, int8_t base);
-#define SCPI_ResultIntBase(context, val, base) SCPI_ResultInt32Base ((context), (val), (base))
     size_t SCPI_ResultUInt32(scpi_t * context, uint32_t val);
-    size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base);
+    size_t SCPI_ResultInt64Base(scpi_t * context, int64_t val, int8_t base, scpi_bool_t sign);
     size_t SCPI_ResultInt64(scpi_t * context, int64_t val);
-    size_t SCPI_ResultInt64Base(scpi_t * context, int64_t val, int8_t base);
     size_t SCPI_ResultUInt64(scpi_t * context, uint64_t val);
-    size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base);
     size_t SCPI_ResultDouble(scpi_t * context, double val);
     size_t SCPI_ResultText(scpi_t * context, const char * data);
     size_t SCPI_ResultArbitraryBlock(scpi_t * context, const char * data, size_t len);
diff --git a/libscpi/inc/scpi/utils.h b/libscpi/inc/scpi/utils.h
index ba80b8e..6822650 100644
--- a/libscpi/inc/scpi/utils.h
+++ b/libscpi/inc/scpi/utils.h
@@ -43,11 +43,9 @@
 extern "C" {
 #endif
 
-    size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len, int8_t base);
-#define SCPI_LongToStr(val, str, len, base) SCPI_Int32ToStr((val), (str), (len), (base))
-    size_t SCPI_UInt32ToStr(uint32_t val, char * str, size_t len, int8_t base);
-    size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len, int8_t base);
-    size_t SCPI_UInt64ToStr(uint64_t val, char * str, size_t len, int8_t base);
+    size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign);
+#define SCPI_LongToStr(val, str, len, base) SCPI_Int32ToStr((val), (str), (len), (base), TRUE)
+    size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign);
     size_t SCPI_DoubleToStr(double val, char * str, size_t len);
 
 #ifdef	__cplusplus
diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c
index 494ff70..5e475a9 100644
--- a/libscpi/src/parser.c
+++ b/libscpi/src/parser.c
@@ -323,7 +323,7 @@
  * @return
  */
 size_t SCPI_ResultInt32(scpi_t * context, int32_t val) {
-    return SCPI_ResultInt32Base(context, val, 10);
+    return SCPI_ResultInt32Base(context, val, 10, TRUE);
 }
 
 /**
@@ -333,7 +333,7 @@
  * @return
  */
 size_t SCPI_ResultUInt32(scpi_t * context, uint32_t val) {
-    return SCPI_ResultUInt32Base(context, val, 10);
+    return SCPI_ResultInt32Base(context, val, 10, FALSE);
 }
 
 /**
@@ -343,7 +343,7 @@
  * @return
  */
 size_t SCPI_ResultInt64(scpi_t * context, int64_t val) {
-    return SCPI_ResultInt64Base(context, val, 10);
+    return SCPI_ResultInt64Base(context, val, 10, TRUE);
 }
 
 /**
@@ -353,7 +353,7 @@
  * @return
  */
 size_t SCPI_ResultUInt64(scpi_t * context, uint64_t val) {
-    return SCPI_ResultUInt64Base(context, val, 10);
+    return SCPI_ResultInt64Base(context, val, 10, FALSE);
 }
 
 /**
@@ -371,19 +371,20 @@
 }
 
 /**
- * Write signed 32 bit integer value in specific base to the result
+ * Write signed/unsigned 32 bit integer value in specific base to the result
  * @param context
  * @param val
  * @param base
+ * @param sign
  * @return
  */
-size_t SCPI_ResultInt32Base(scpi_t * context, int32_t val, int8_t base) {
+size_t SCPI_ResultInt32Base(scpi_t * context, int32_t val, int8_t base, scpi_bool_t sign) {
     char buffer[32+1];
     const char * basePrefix;
     size_t result = 0;
     size_t len;
 
-    len = SCPI_Int32ToStr(val, buffer, sizeof (buffer), base);
+    len = SCPI_Int32ToStr(val, buffer, sizeof (buffer), base, sign);
     basePrefix = getBasePrefix(base);
 
     result += writeDelimiter(context);
@@ -396,69 +397,20 @@
 }
 
 /**
- * Write unsigned 32 bit integer value in specific base to the result
+ * Write signed/unsigned 64 bit integer value in specific base to the result
  * @param context
  * @param val
  * @param base
+ * @param sign
  * @return
  */
-size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base) {
-    char buffer[32+1];
-    const char * basePrefix;
-    size_t result = 0;
-    size_t len;
-
-    len = SCPI_UInt32ToStr(val, buffer, sizeof (buffer), base);
-    basePrefix = getBasePrefix(base);
-
-    result += writeDelimiter(context);
-    if (basePrefix != NULL) {
-        result += writeData(context, basePrefix, 2);
-    }
-    result += writeData(context, buffer, len);
-    context->output_count++;
-    return result;
-}
-
-/**
- * Write signed 64 bit integer value in specific base to the result
- * @param context
- * @param val
- * @param base
- * @return
- */
-size_t SCPI_ResultInt64Base(scpi_t * context, int64_t val, int8_t base) {
+size_t SCPI_ResultInt64Base(scpi_t * context, int64_t val, int8_t base, scpi_bool_t sign) {
     char buffer[64+1];
     const char * basePrefix;
     size_t result = 0;
     size_t len;
 
-    len = SCPI_Int64ToStr(val, buffer, sizeof (buffer), base);
-    basePrefix = getBasePrefix(base);
-
-    result += writeDelimiter(context);
-    if (basePrefix != NULL) {
-        result += writeData(context, basePrefix, 2);
-    }
-    result += writeData(context, buffer, len);
-    context->output_count++;
-    return result;
-}
-
-/**
- * Write unsigned 64 bit integer value in specific base to the result
- * @param context
- * @param val
- * @param base
- * @return
- */
-size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base) {
-    char buffer[64+1];
-    const char * basePrefix;
-    size_t result = 0;
-    size_t len;
-
-    len = SCPI_UInt64ToStr(val, buffer, sizeof (buffer), base);
+    len = SCPI_Int64ToStr(val, buffer, sizeof (buffer), base, sign);
     basePrefix = getBasePrefix(base);
 
     result += writeDelimiter(context);
@@ -516,7 +468,7 @@
     char block_header[12];
     size_t header_len;
     block_header[0] = '#';
-    SCPI_Int32ToStr(len, block_header + 2, 10, 10);
+    SCPI_Int32ToStr(len, block_header + 2, 10, 10, FALSE);
 
     header_len = strlen(block_header + 2);
     block_header[1] = (char)(header_len + '0');
@@ -535,7 +487,7 @@
  * @return
  */
 size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val) {
-    return SCPI_ResultInt32Base(context, val ? 1 : 0, 10);
+    return SCPI_ResultInt32Base(context, val ? 1 : 0, 10, FALSE);
 }
 
 /* parsing parameters */
@@ -635,6 +587,7 @@
  * @param context
  * @param parameter
  * @param value result
+ * @param sign
  * @return TRUE if succesful
  */
 static scpi_bool_t ParamToInt32(scpi_t * context, scpi_parameter_t * parameter, int32_t * value, scpi_bool_t sign) {
@@ -755,6 +708,7 @@
  * @param context
  * @param value
  * @param mandatory
+ * @param sign
  * @return
  */
 static scpi_bool_t ParamInt32(scpi_t * context, int32_t * value, scpi_bool_t mandatory, scpi_bool_t sign) {
diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c
index 72c13e9..711782d 100644
--- a/libscpi/src/utils.c
+++ b/libscpi/src/utils.c
@@ -69,14 +69,15 @@
 }
 
 /**
- * Converts signed 32b integer value to string
+ * Converts signed/unsigned 32 bit integer value to string
  * @param val   integer value
  * @param str   converted textual representation
  * @param len   string buffer length
  * @param base  output base
+ * @param sign  
  * @return number of bytes written to str (without '\0')
  */
-size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len, int8_t base) {
+size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) {
     const char digits[] = "0123456789ABCDEF";
 
 #define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
@@ -99,7 +100,7 @@
             case 10:
                 x = 1000000000L;
                 break;
-            case 0x10:
+            case 16:
                 x = 0x10000000L;
                 break;
             default:
@@ -109,7 +110,7 @@
         }
 
         // add sign for numbers in base 10
-        if ((val < 0) && (base == 10)) {
+        if (sign && (val < 0) && (base == 10)) {
             uval = -val;
             ADD_CHAR('-');
         }
@@ -133,71 +134,15 @@
 }
 
 /**
- * Converts unsigned 32b integer value to string
+ * Converts signed/unsigned 64 bit integer value to string
  * @param val   integer value
  * @param str   converted textual representation
  * @param len   string buffer length
  * @param base  output base
+ * @param sign  
  * @return number of bytes written to str (without '\0')
  */
-size_t SCPI_UInt32ToStr(uint32_t val, char * str, size_t len, int8_t base) {
-    const char digits[] = "0123456789ABCDEF";
-
-#define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
-    uint32_t x = 0;
-    int_fast8_t digit;
-    size_t pos = 0;
-
-    if (val == 0) {
-        ADD_CHAR('0');
-    } else {
-
-        switch (base) {
-            case 2: 
-                x = 0x80000000L;
-                break;
-            case 8:
-                x = 0x40000000L;
-                break;
-            case 10:
-                x = 1000000000L;
-                break;
-            case 0x10:
-                x = 0x10000000L;
-                break;
-            default:
-                x = 1000000000L;
-                base = 10;
-                break;
-        }
-
-        // remove leading zeros
-        while ((val / x) == 0) {
-            x /= base;
-        }
-
-        do {
-            digit = (uint8_t) (val / x);
-            ADD_CHAR(digits[digit]);
-            val -= digit * x;
-            x /= base;
-        } while (x && (pos < len));
-    }
-
-    if (pos < len) str[pos] = 0;
-    return pos;
-#undef ADD_CHAR
-}
-
-/**
- * Converts signed 64b integer value to string
- * @param val   integer value
- * @param str   converted textual representation
- * @param len   string buffer length
- * @param base  output base
- * @return number of bytes written to str (without '\0')
- */
-size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len, int8_t base) {
+size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) {
     const char digits[] = "0123456789ABCDEF";
 
 #define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
@@ -212,25 +157,25 @@
 
         switch (base) {
             case 2: 
-                x = 0x8000000000000000LL;
+                x = 0x8000000000000000ULL;
                 break;
             case 8:
-                x = 0x8000000000000000LL;
+                x = 0x8000000000000000ULL;
                 break;
             case 10:
-                x = 1000000000000000000LL;
+                x = 10000000000000000000ULL;
                 break;
-            case 0x10:
-                x = 0x1000000000000000LL;
+            case 16:
+                x = 0x1000000000000000ULL;
                 break;
             default:
-                x = 1000000000000000000LL;
+                x = 10000000000000000000ULL;
                 base = 10;
                 break;
         }
 
         // add sign for numbers in base 10
-        if ((val < 0) && (base == 10)) {
+        if (sign && (val < 0) && (base == 10)) {
             uval = -val;
             ADD_CHAR('-');
         }
@@ -244,63 +189,6 @@
             digit = (uint8_t) (uval / x);
             ADD_CHAR(digits[digit]);
             uval -= digit * x;
-            x /= base;
-        } while (x && (pos < len));
-    }
-
-    if (pos < len) str[pos] = 0;
-    return pos;
-#undef ADD_CHAR
-}
-
-/**
- * Converts unsigned 64b integer value to string
- * @param val   integer value
- * @param str   converted textual representation
- * @param len   string buffer length
- * @param base  output base
- * @return number of bytes written to str (without '\0')
- */
-size_t SCPI_UInt64ToStr(uint64_t val, char * str, size_t len, int8_t base) {
-    const char digits[] = "0123456789ABCDEF";
-
-#define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
-    uint64_t x = 0;
-    int_fast8_t digit;
-    size_t pos = 0;
-
-    if (val == 0) {
-        ADD_CHAR('0');
-    } else {
-
-        switch (base) {
-            case 2: 
-                x = 0x8000000000000000ULL;
-                break;
-            case 8:
-                x = 0x8000000000000000ULL;
-                break;
-            case 10:
-                x = 10000000000000000000ULL;
-                break;
-            case 0x10:
-                x = 0x1000000000000000ULL;
-                break;
-            default:
-                x = 10000000000000000000ULL;
-                base = 10;
-                break;
-        }
-
-        // remove leading zeros
-        while ((val / x) == 0) {
-            x /= base;
-        }
-
-        do {
-            digit = (uint8_t) (val / x);
-            ADD_CHAR(digits[digit]);
-            val -= digit * x;
             x /= base;
         } while (x && (pos < len));
     }
diff --git a/libscpi/test/test_scpi_utils.c b/libscpi/test/test_scpi_utils.c
index 43f5515..5951520 100644
--- a/libscpi/test/test_scpi_utils.c
+++ b/libscpi/test/test_scpi_utils.c
@@ -78,7 +78,7 @@
 
     // test conversion to decimal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_Int32ToStr(val[i], str, max, 10);
+        len = SCPI_Int32ToStr(val[i], str, max, 10, TRUE);
         snprintf(ref, max, "%"PRIi32, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -86,7 +86,7 @@
 
     // test conversion to hexadecimal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_Int32ToStr(val[i], str, max, 16);
+        len = SCPI_Int32ToStr(val[i], str, max, 16, TRUE);
         snprintf(ref, max, "%"PRIX32, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -94,30 +94,30 @@
 
     // test conversion to octal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_Int32ToStr(val[i], str, max, 8);
+        len = SCPI_Int32ToStr(val[i], str, max, 8, TRUE);
         snprintf(ref, max, "%"PRIo32, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
     }
 
     // test conversion to binary numbers
-    len = SCPI_Int32ToStr(0, str, max, 2);
+    len = SCPI_Int32ToStr(0, str, max, 2, TRUE);
     CU_ASSERT(len == 1);
     CU_ASSERT_STRING_EQUAL(str, "0");
 
-    len = SCPI_Int32ToStr(1, str, max, 2);
+    len = SCPI_Int32ToStr(1, str, max, 2, TRUE);
     CU_ASSERT(len == 1);
     CU_ASSERT_STRING_EQUAL(str, "1");
 
-    len = SCPI_Int32ToStr(-1, str, max, 2);
+    len = SCPI_Int32ToStr(-1, str, max, 2, TRUE);
     CU_ASSERT(len == 32);
     CU_ASSERT_STRING_EQUAL(str, "11111111111111111111111111111111");
 
-    len = SCPI_Int32ToStr(0x01234567, str, max, 2);
+    len = SCPI_Int32ToStr(0x01234567, str, max, 2, TRUE);
     CU_ASSERT(len == 25);
     CU_ASSERT_STRING_EQUAL(str, "1001000110100010101100111");
 
-    len = SCPI_Int32ToStr(0x89abcdef, str, max, 2);
+    len = SCPI_Int32ToStr(0x89abcdef, str, max, 2, TRUE);
     CU_ASSERT(len == 32);
     CU_ASSERT_STRING_EQUAL(str, "10001001101010111100110111101111");
 }
@@ -131,7 +131,7 @@
 
     // test conversion to decimal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_UInt32ToStr(val[i], str, max, 10);
+        len = SCPI_Int32ToStr(val[i], str, max, 10, FALSE);
         snprintf(ref, max, "%"PRIu32, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -139,7 +139,7 @@
 
     // test conversion to hexadecimal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_UInt32ToStr(val[i], str, max, 16);
+        len = SCPI_Int32ToStr(val[i], str, max, 16, FALSE);
         snprintf(ref, max, "%"PRIX32, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -147,7 +147,7 @@
 
     // test conversion to octal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_UInt32ToStr(val[i], str, max, 8);
+        len = SCPI_Int32ToStr(val[i], str, max, 8, FALSE);
         snprintf(ref, max, "%"PRIo32, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -163,7 +163,7 @@
 
     // test conversion to decimal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_Int64ToStr(val[i], str, max, 10);
+        len = SCPI_Int64ToStr(val[i], str, max, 10, TRUE);
         snprintf(ref, max, "%"PRIi64, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -171,7 +171,7 @@
 
     // test conversion to hexadecimal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_Int64ToStr(val[i], str, max, 16);
+        len = SCPI_Int64ToStr(val[i], str, max, 16, TRUE);
         snprintf(ref, max, "%"PRIX64, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -179,30 +179,30 @@
 
     // test conversion to octal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_Int64ToStr(val[i], str, max, 8);
+        len = SCPI_Int64ToStr(val[i], str, max, 8, TRUE);
         snprintf(ref, max, "%"PRIo64, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
     }
 
     // test conversion to binary numbers
-    len = SCPI_Int64ToStr(0, str, max, 2);
+    len = SCPI_Int64ToStr(0, str, max, 2, TRUE);
     CU_ASSERT(len == 1);
     CU_ASSERT_STRING_EQUAL(str, "0");
 
-    len = SCPI_Int64ToStr(1, str, max, 2);
+    len = SCPI_Int64ToStr(1, str, max, 2, TRUE);
     CU_ASSERT(len == 1);
     CU_ASSERT_STRING_EQUAL(str, "1");
 
-    len = SCPI_Int64ToStr(-1, str, max, 2);
+    len = SCPI_Int64ToStr(-1, str, max, 2, TRUE);
     CU_ASSERT(len == 64);
     CU_ASSERT_STRING_EQUAL(str, "1111111111111111111111111111111111111111111111111111111111111111");
 
-    len = SCPI_Int64ToStr(0x0123456789abcdef, str, max, 2);
+    len = SCPI_Int64ToStr(0x0123456789abcdef, str, max, 2, TRUE);
     CU_ASSERT(len == 57);
     CU_ASSERT_STRING_EQUAL(str, "100100011010001010110011110001001101010111100110111101111");
 
-    len = SCPI_Int64ToStr(0xfedcba9876543210, str, max, 2);
+    len = SCPI_Int64ToStr(0xfedcba9876543210, str, max, 2, TRUE);
     CU_ASSERT(len == 64);
     CU_ASSERT_STRING_EQUAL(str, "1111111011011100101110101001100001110110010101000011001000010000");
 }
@@ -216,7 +216,7 @@
 
     // test conversion to decimal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_UInt64ToStr(val[i], str, max, 10);
+        len = SCPI_Int64ToStr(val[i], str, max, 10, FALSE);
         snprintf(ref, max, "%"PRIu64, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -224,7 +224,7 @@
 
     // test conversion to hexadecimal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_UInt64ToStr(val[i], str, max, 16);
+        len = SCPI_Int64ToStr(val[i], str, max, 16, FALSE);
         snprintf(ref, max, "%"PRIX64, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);
@@ -232,7 +232,7 @@
 
     // test conversion to octal numbers
     for (uintptr_t i=0; i<7; i++) {
-        len = SCPI_UInt64ToStr(val[i], str, max, 8);
+        len = SCPI_Int64ToStr(val[i], str, max, 8, FALSE);
         snprintf(ref, max, "%"PRIo64, val[i]);
         CU_ASSERT(len == strlen(ref));
         CU_ASSERT_STRING_EQUAL(str, ref);

--
Gitblit v1.9.1