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';
 | 
						|
}
 |