xserver/os/fmt.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';
}