File: fmt.c

package info (click to toggle)
xwayland 2%3A24.1.6-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 11,656 kB
  • sloc: ansic: 202,932; xml: 6,578; sh: 208; makefile: 21
file content (101 lines) | stat: -rw-r--r-- 2,438 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* 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';
}