summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2012-08-13 14:24:36 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2012-08-21 07:54:07 +1000
commit7f8c39c8b5ef89153ecd84d16331e96d8feb18ef (patch)
tree9be2f3af42f5d7dc074c10e4978ee34af358cf9f
parent36c1d92ec0ef0f3927034a12d4cb79dcc22bd185 (diff)
Add FormatInt64 to convert signed integers in signal-safe manner
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
-rw-r--r--include/misc.h1
-rw-r--r--os/utils.c14
-rw-r--r--test/signal-logging.c80
3 files changed, 92 insertions, 3 deletions
diff --git a/include/misc.h b/include/misc.h
index 7f7f221a8..348717676 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 947f8673a..04bcbc61f 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 f66f773c4..0e352aa0b 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)