102 lines
2.4 KiB
C
102 lines
2.4 KiB
C
/* SPDX-License-Identifier: MIT OR X11
|
|
*
|
|
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
|
|
* Copyright © 1987, 1998 The Open Group
|
|
* Copyright © 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
|
|
* Copyright © 1994 Quarterdeck Office Systems.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
|
|
#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';
|
|
}
|