From 02ba47f09d04538a9fd8119161c6ff0697e2e8ee Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Sun, 18 Feb 2024 12:40:42 +0100 Subject: [PATCH] os: move out Format*() functions Move out the Format*() functions to separate source and header. These aren't exported, thus no module API change. Signed-off-by: Enrico Weigelt, metux IT consult Part-of: --- include/misc.h | 4 -- os/fmt.c | 101 ++++++++++++++++++++++++++++++++++++++++++ os/fmt.h | 15 +++++++ os/log.c | 2 + os/meson.build | 1 + os/utils.c | 90 ------------------------------------- test/signal-logging.c | 3 ++ 7 files changed, 122 insertions(+), 94 deletions(-) create mode 100644 os/fmt.c create mode 100644 os/fmt.h diff --git a/include/misc.h b/include/misc.h index 3e1834f54..795cf1890 100644 --- a/include/misc.h +++ b/include/misc.h @@ -236,10 +236,6 @@ padding_for_int32(const int bytes) extern _X_EXPORT 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); -extern void FormatDouble(double dbl, char *string); /** * Compare the two version numbers comprising of major.minor. diff --git a/os/fmt.c b/os/fmt.c new file mode 100644 index 000000000..c5c61bdba --- /dev/null +++ b/os/fmt.c @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: MIT OR X11 + * + * Copyright © 2024 Enrico Weigelt, metux IT consult + * Copyright © 1987, 1998 The Open Group + * Copyright © 1987 by Digital Equipment Corporation, Maynard, Massachusetts, + * Copyright © 1994 Quarterdeck Office Systems. + */ + +#include + +#include "os/fmt.h" + +/* 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 +FormatUInt64(uint64_t num, char *string) +{ + uint64_t divisor; + int len; + int i; + + for (len = 1, divisor = 10; + len < 20 && num / divisor; + len++, divisor *= 10); + + for (i = len, divisor = 1; i > 0; i--, divisor *= 10) + string[i - 1] = '0' + ((num / divisor) % 10); + + string[len] = '\0'; +} + +/** + * Format a double number as %.2f. + */ +void +FormatDouble(double dbl, char *string) +{ + int slen = 0; + uint64_t frac; + + frac = (dbl > 0 ? dbl : -dbl) * 100.0 + 0.5; + frac %= 100; + + /* write decimal part to string */ + if (dbl < 0 && dbl > -1) + string[slen++] = '-'; + FormatInt64((int64_t)dbl, &string[slen]); + + while(string[slen] != '\0') + slen++; + + /* append fractional part, but only if we have enough characters. We + * expect string to be 21 chars (incl trailing \0) */ + if (slen <= 17) { + string[slen++] = '.'; + if (frac < 10) + string[slen++] = '0'; + + FormatUInt64(frac, &string[slen]); + } +} + + +/* Format a number into a hexadecimal string in a signal safe manner. The string + * should be at least 17 characters in order to handle all uint64_t values. */ +void +FormatUInt64Hex(uint64_t num, char *string) +{ + uint64_t divisor; + int len; + int i; + + for (len = 1, divisor = 0x10; + len < 16 && num / divisor; + len++, divisor *= 0x10); + + for (i = len, divisor = 1; i > 0; i--, divisor *= 0x10) { + int val = (num / divisor) % 0x10; + + if (val < 10) + string[i - 1] = '0' + val; + else + string[i - 1] = 'a' + val - 10; + } + + string[len] = '\0'; +} diff --git a/os/fmt.h b/os/fmt.h new file mode 100644 index 000000000..63cdfe99f --- /dev/null +++ b/os/fmt.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT OR X11 + * + * Copyright © 2024 Enrico Weigelt, metux IT consult + */ +#ifndef _XSERVER_OS_FMT_H +#define _XSERVER_OS_FMT_H + +#include + +void FormatInt64(int64_t num, char *string); +void FormatUInt64(uint64_t num, char *string); +void FormatUInt64Hex(uint64_t num, char *string); +void FormatDouble(double dbl, char *string); + +#endif /* _XSERVER_OS_FMT_H */ diff --git a/os/log.c b/os/log.c index 189ab355b..ae02dc746 100644 --- a/os/log.c +++ b/os/log.c @@ -87,6 +87,8 @@ OR PERFORMANCE OF THIS SOFTWARE. #include /* for malloc() */ #include +#include "os/fmt.h" + #include "input.h" #include "opaque.h" #include "osdep.h" diff --git a/os/meson.build b/os/meson.build index 67c7140ed..2f40a7525 100644 --- a/os/meson.build +++ b/os/meson.build @@ -6,6 +6,7 @@ srcs_os = [ 'backtrace.c', 'client.c', 'connection.c', + 'fmt.c', 'inputthread.c', 'io.c', 'mitauth.c', diff --git a/os/utils.c b/os/utils.c index 739c01c3f..9173fcbf2 100644 --- a/os/utils.c +++ b/os/utils.c @@ -1850,96 +1850,6 @@ CheckUserAuthorization(void) #endif } -/* 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 -FormatUInt64(uint64_t num, char *string) -{ - uint64_t divisor; - int len; - int i; - - for (len = 1, divisor = 10; - len < 20 && num / divisor; - len++, divisor *= 10); - - for (i = len, divisor = 1; i > 0; i--, divisor *= 10) - string[i - 1] = '0' + ((num / divisor) % 10); - - string[len] = '\0'; -} - -/** - * Format a double number as %.2f. - */ -void -FormatDouble(double dbl, char *string) -{ - int slen = 0; - uint64_t frac; - - frac = (dbl > 0 ? dbl : -dbl) * 100.0 + 0.5; - frac %= 100; - - /* write decimal part to string */ - if (dbl < 0 && dbl > -1) - string[slen++] = '-'; - FormatInt64((int64_t)dbl, &string[slen]); - - while(string[slen] != '\0') - slen++; - - /* append fractional part, but only if we have enough characters. We - * expect string to be 21 chars (incl trailing \0) */ - if (slen <= 17) { - string[slen++] = '.'; - if (frac < 10) - string[slen++] = '0'; - - FormatUInt64(frac, &string[slen]); - } -} - - -/* Format a number into a hexadecimal string in a signal safe manner. The string - * should be at least 17 characters in order to handle all uint64_t values. */ -void -FormatUInt64Hex(uint64_t num, char *string) -{ - uint64_t divisor; - int len; - int i; - - for (len = 1, divisor = 0x10; - len < 16 && num / divisor; - len++, divisor *= 0x10); - - for (i = len, divisor = 1; i > 0; i--, divisor *= 0x10) { - int val = (num / divisor) % 0x10; - - if (val < 10) - string[i - 1] = '0' + val; - else - string[i - 1] = 'a' + val - 10; - } - - string[len] = '\0'; -} - #if !defined(WIN32) || defined(__CYGWIN__) /* Move a file descriptor out of the way of our select mask; this * is useful for file descriptors which will never appear in the diff --git a/test/signal-logging.c b/test/signal-logging.c index 80d7c6f60..22966ed4c 100644 --- a/test/signal-logging.c +++ b/test/signal-logging.c @@ -30,6 +30,9 @@ #include #include + +#include "os/fmt.h" + #include "assert.h" #include "misc.h"