diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2012-08-13 14:24:36 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2012-08-21 07:54:07 +1000 |
commit | 7f8c39c8b5ef89153ecd84d16331e96d8feb18ef (patch) | |
tree | 9be2f3af42f5d7dc074c10e4978ee34af358cf9f | |
parent | 36c1d92ec0ef0f3927034a12d4cb79dcc22bd185 (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.h | 1 | ||||
-rw-r--r-- | os/utils.c | 14 | ||||
-rw-r--r-- | test/signal-logging.c | 80 |
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) |