[PATCH 3/5] Add FormatInt64 to convert signed integers in signal-safe manner

Peter Hutterer peter.hutterer at who-t.net
Wed Aug 15 21:52:47 PDT 2012


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 include/misc.h        |  1 +
 os/utils.c            | 14 +++++++++
 test/signal-logging.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 92 insertions(+), 3 deletions(-)

diff --git a/include/misc.h b/include/misc.h
index 7f7f221..3487176 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -247,6 +247,7 @@ padding_for_int32(const int bytes)
 
 
 extern char **xstrtokenize(const char *str, const char *separators);
+extern void FormatInt64(int64_t num, char *string);
 extern void FormatUInt64(uint64_t num, char *string);
 extern void FormatUInt64Hex(uint64_t num, char *string);
 
diff --git a/os/utils.c b/os/utils.c
index 947f867..04bcbc6 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1924,6 +1924,20 @@ xstrtokenize(const char *str, const char *separators)
     return NULL;
 }
 
+/* Format a signed number into a string in a signal safe manner. The string
+ * should be at least 21 characters in order to handle all int64_t values.
+ */
+void
+FormatInt64(int64_t num, char *string)
+{
+    if (num < 0) {
+        string[0] = '-';
+        num *= -1;
+        string++;
+    }
+    FormatUInt64(num, string);
+}
+
 /* Format a number into a string in a signal safe manner. The string should be
  * at least 21 characters in order to handle all uint64_t values. */
 void
diff --git a/test/signal-logging.c b/test/signal-logging.c
index f66f773..0e352aa 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -36,6 +36,26 @@ struct number_format_test {
     char hex_string[17];
 };
 
+struct signed_number_format_test {
+    int64_t number;
+    char string[21];
+};
+
+static Bool
+check_signed_number_format_test(const struct signed_number_format_test *test)
+{
+    char string[21];
+
+    FormatInt64(test->number, string);
+    if(strncmp(string, test->string, 21) != 0) {
+        fprintf(stderr, "Failed to convert %jd to decimal string (%s vs %s)\n",
+                test->number, test->string, string);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 static Bool
 check_number_format_test(const struct number_format_test *test)
 {
@@ -62,7 +82,7 @@ static void
 number_formatting(void)
 {
     int i;
-    struct number_format_test tests[] = {
+    struct number_format_test unsigned_tests[] = {
         { /* Zero */
             0,
             "0",
@@ -100,8 +120,62 @@ number_formatting(void)
         },
     };
 
-    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
-        assert(check_number_format_test(tests + i));
+    struct signed_number_format_test signed_tests[] = {
+        { /* Zero */
+            0,
+            "0",
+        },
+        { /* Single digit number */
+            5,
+            "5",
+        },
+        { /* Two digit decimal number */
+            12,
+            "12",
+        },
+        { /* Two digit hex number */
+            37,
+            "37",
+        },
+        { /* Large < 32 bit number */
+            0xC90B2,
+            "823474",
+        },
+        { /* Large > 32 bit number */
+            0x15D027BF211B37A,
+            "98237498237498234",
+        },
+        { /* Maximum 64-bit signed number */
+            0x7FFFFFFFFFFFFFFF,
+            "9223372036854775807",
+        },
+        { /* Single digit number */
+            -1,
+            "-1",
+        },
+        { /* Two digit decimal number */
+            -12,
+            "-12",
+        },
+        { /* Large < 32 bit number */
+            -0xC90B2,
+            "-823474",
+        },
+        { /* Large > 32 bit number */
+            -0x15D027BF211B37A,
+            "-98237498237498234",
+        },
+        { /* Maximum 64-bit number */
+            -0x7FFFFFFFFFFFFFFF,
+            "-9223372036854775807",
+        },
+    };
+
+    for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++)
+        assert(check_number_format_test(unsigned_tests + i));
+
+    for (i = 0; i < sizeof(unsigned_tests) / sizeof(signed_tests[0]); i++)
+        assert(check_signed_number_format_test(signed_tests + i));
 }
 
 static void logging_format(void)
-- 
1.7.11.2



More information about the xorg-devel mailing list