ohmu
·
2026-10-15
1#include "common/size.h"
2#include "common/textModifier.h"
3#include "fastfetch.h"
4
5#include <stdint.h>
6#include <stdio.h>
7#include <stdlib.h>
8
9static void verify(uint64_t bytes, const char* expected, int lineNo) {
10 FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate();
11 ffSizeAppendNum(bytes, &result);
12
13 if (!ffStrbufEqualS(&result, expected)) {
14 fprintf(stderr, FASTFETCH_TEXT_MODIFIER_ERROR "[%d] ffSizeAppendNum(%llu): expected \"%s\", got \"%s\"\n" FASTFETCH_TEXT_MODIFIER_RESET,
15 lineNo, (unsigned long long) bytes, expected, result.chars);
16 exit(1);
17 }
18}
19
20#define VERIFY_SIZE(bytes, expected) verify((bytes), (expected), __LINE__)
21
22int main(void) {
23 // Use the real defaults rather than a hand built config, so a changed default is caught here too
24 ffOptionsInitDisplay(&instance.config.display);
25 FFOptionsDisplay* options = &instance.config.display;
26
27 // IEC (the default): 1024 based, with the `KiB` style suffixes
28 {
29 VERIFY_SIZE(0, "0 B");
30 VERIFY_SIZE(1, "1 B");
31 VERIFY_SIZE(999, "999 B");
32 VERIFY_SIZE(1023, "1023 B"); // one byte short of the first prefix
33 VERIFY_SIZE(1024, "1.00 KiB");
34 VERIFY_SIZE(1025, "1.00 KiB"); // below the rounding precision
35 VERIFY_SIZE(1536, "1.50 KiB");
36 VERIFY_SIZE(1024ULL * 1024, "1.00 MiB");
37 VERIFY_SIZE(1024ULL * 1024 * 1024, "1.00 GiB");
38 VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024, "1.00 TiB");
39 VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024 * 1024, "1.00 PiB");
40 VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024 * 1024 * 1024, "1.00 EiB");
41
42 // The largest 64 bit value is 16 EiB; `ZiB` and `YiB` are listed but can never be reached
43 // through an IEC conversion of a `uint64_t`.
44 VERIFY_SIZE(UINT64_MAX, "16.00 EiB");
45 }
46
47 // SI: 1000 based, with the `kB` style suffixes
48 {
49 options->sizeBinaryPrefix = FF_SIZE_BINARY_PREFIX_TYPE_SI;
50
51 VERIFY_SIZE(0, "0 B");
52 VERIFY_SIZE(999, "999 B");
53 VERIFY_SIZE(1000, "1.00 kB");
54 VERIFY_SIZE(1500, "1.50 kB");
55 VERIFY_SIZE(1000000, "1.00 MB");
56 VERIFY_SIZE(1000000000ULL, "1.00 GB");
57 VERIFY_SIZE(1000000000000ULL, "1.00 TB");
58 VERIFY_SIZE(1000000000000000ULL, "1.00 PB");
59 VERIFY_SIZE(1000000000000000000ULL, "1.00 EB");
60 VERIFY_SIZE(UINT64_MAX, "18.45 EB");
61 }
62
63 // JEDEC: 1024 based, but with the `KB` style suffixes. The suffix list stops at `TB`, so the
64 // loop has to stop there as well instead of reading past the end.
65 {
66 options->sizeBinaryPrefix = FF_SIZE_BINARY_PREFIX_TYPE_JEDEC;
67
68 VERIFY_SIZE(1023, "1023 B");
69 VERIFY_SIZE(1024, "1.00 KB");
70 VERIFY_SIZE(1024ULL * 1024, "1.00 MB");
71 VERIFY_SIZE(1024ULL * 1024 * 1024, "1.00 GB");
72 VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024, "1.00 TB");
73 VERIFY_SIZE(1024ULL * 1024 * 1024 * 1024 * 1024, "1024.00 TB"); // no `PB` in JEDEC
74 VERIFY_SIZE(UINT64_MAX, "16777216.00 TB");
75 }
76
77 options->sizeBinaryPrefix = FF_SIZE_BINARY_PREFIX_TYPE_IEC;
78
79 // sizeNdigits: the number of digits after the decimal point. It applies only once a prefix is
80 // used -- a plain byte count is always printed as an integer.
81 {
82 options->sizeNdigits = 0;
83 VERIFY_SIZE(1024, "1 KiB");
84 VERIFY_SIZE(1536, "2 KiB"); // rounded, not truncated
85 VERIFY_SIZE(512, "512 B");
86 VERIFY_SIZE(1023, "1023 B");
87
88 options->sizeNdigits = 4;
89 VERIFY_SIZE(1024, "1.0000 KiB");
90 VERIFY_SIZE(1536, "1.5000 KiB");
91 VERIFY_SIZE(512, "512 B"); // still an integer
92 VERIFY_SIZE(0, "0 B");
93
94 options->sizeNdigits = 2;
95 }
96
97 // sizeMaxPrefix: the index of the largest suffix that may be used. `0` disables the conversion
98 // entirely.
99 {
100 options->sizeMaxPrefix = 0;
101 VERIFY_SIZE(0, "0 B");
102 VERIFY_SIZE(1024, "1024 B");
103 VERIFY_SIZE(UINT64_MAX, "18446744073709551615 B");
104
105 options->sizeMaxPrefix = 1;
106 VERIFY_SIZE(1024, "1.00 KiB");
107 VERIFY_SIZE(1024ULL * 1024, "1024.00 KiB");
108 VERIFY_SIZE(1024ULL * 1024 * 1024, "1048576.00 KiB");
109
110 options->sizeMaxPrefix = 8;
111 }
112
113 // sizeSpaceBeforeUnit: only `never` removes the space, `default` and `always` both keep it
114 {
115 options->sizeSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_NEVER;
116 VERIFY_SIZE(0, "0B");
117 VERIFY_SIZE(1024, "1.00KiB");
118 VERIFY_SIZE(1536, "1.50KiB");
119
120 options->sizeSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_ALWAYS;
121 VERIFY_SIZE(0, "0 B");
122 VERIFY_SIZE(1024, "1.00 KiB");
123
124 options->sizeSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
125 VERIFY_SIZE(1024, "1.00 KiB");
126 }
127
128 // The result is appended to the buffer instead of replacing it
129 {
130 FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateS("Size: ");
131 ffSizeAppendNum(1024, &result);
132 if (!ffStrbufEqualS(&result, "Size: 1.00 KiB")) {
133 fprintf(stderr, FASTFETCH_TEXT_MODIFIER_ERROR "[%d] ffSizeAppendNum did not append: got \"%s\"\n" FASTFETCH_TEXT_MODIFIER_RESET, __LINE__, result.chars);
134 exit(1);
135 }
136 }
137
138 ffOptionsDestroyDisplay(options);
139
140 puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
141 return 0;
142}