1notcurses_metric(3) notcurses_metric(3)
2
3
4
6 notcurses_metric - fixed-width numeric output with metric suffixes
7
9 #include <notcurses/notcurses.h>
10
11 #define NCPREFIXCOLUMNS 7
12 #define NCIPREFIXCOLUMNS 8
13 #define NCBPREFIXCOLUMNS 9
14 #define NCPREFIXSTRLEN (NCPREFIXCOLUMNS + 1)
15 #define NCIPREFIXSTRLEN (NCIPREFIXCOLUMNS + 1)
16 #define NCBPREFIXSTRLEN (NCBPREFIXCOLUMNS + 1)
17 #define NCMETRICFWIDTH(x, cols) ((int)(strlen(x) - ncstrwidth(x) + (cols)))
18 #define NCPREFIXFMT(x) NCMETRICFWIDTH((x), NCPREFIXCOLUMNS), (x)
19 #define NCIPREFIXFMT(x) NCMETRIXFWIDTH((x), NCIPREFIXCOLUMNS), (x)
20 #define NCBPREFIXFMT(x) NCMETRICFWIDTH((x), NCBPREFIXCOLUMNS), (x)
21
22 const char* ncnmetric(uintmax_t val, size_t s, uintmax_t decimal, char*
23 buf, int omitdec, unsigned mult, int uprefix);
24
25 static inline const char* ncqprefix(uintmax_t val, uintmax_t decimal,
26 char* buf, int omitdec);
27
28 static inline const char* nciprefix(uintmax_t val, uintmax_t decimal,
29 char* buf, int omitdec);
30
31 static inline const char* ncbprefix(uintmax_t val, uintmax_t decimal,
32 char* buf, int omitdec);
33
35 ncmetric (and the helper wrappers qprefix and bprefix) accept very
36 large (or very small) non-negative numbers, and prepare formatted out‐
37 put of a maximum width using metric suffixes. The suffix can represent
38 arbitrary amounts of growth, but is designed for 1000 (NCPREFIX) or
39 1024 (NCIPREFIX). 1024 is used for "digital units of information",
40 i.e. kibibytes and gibibits. ncmetric supports the large suffixes
41 KMGTPEZY (Kilo, Mega, Giga, Tera, Peta, Exa, Zetta, and Yotta) and the
42 small suffixes mµnpfazy (Milli, Micro, Nano, Pico, Femto, Atto, Zepto,
43 and Yocto). This covers the range 1e24 (one septillion) through 1e-24,
44 sufficing for all possible values of a 64-bit uintmax_t.
45
46 val is the value being output, having been scaled by decimal. decimal
47 will typically be 1; to represent values less than 1, decimal should be
48 larger than val. The output will be written to buf, which must be at
49 least:
50
51 • NCPREFIXSTRLEN + 1 bytes for a 1000-based value
52
53 • NCIPREFIXSTRLEN + 1 bytes for a 1024-based value
54
55 • NCBPREFIXSTRLEN + 1 bytes for a 1024-based value with an 'i' suffix
56
57 s is the maximum output size, including '\0', used in the same fashion
58 as snprintf(3) (which ncnmetric calls).
59
60 Three helper functions are provided to simplify these common cases:
61
62 // Mega, kilo, gigafoo. Use NCPREFIXSTRLEN + 1 and NCPREFIXCOLUMNS.
63 static inline const char*
64 ncqprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){
65 return ncmetric(val, decimal, buf, omitdec, 1000, '\0');
66 }
67
68 // Mibi, kebi, gibibytes sans 'i' suffix. Use NCIPREFIXSTRLEN + 1.
69 static inline const char*
70 nciprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){
71 return ncmetric(val, decimal, buf, omitdec, 1024, '\0');
72 }
73
74 // Mibi, kebi, gibibytes. Use NCBPREFIXSTRLEN + 1 and NCBPREFIXCOLUMNS.
75 static inline const char*
76 ncbprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){
77 return ncmetric(val, decimal, buf, omitdec, 1024, 'i');
78 }
79
80 If omitdec is not zero, the decimal point and mantissa will be omitted
81 if all digits to be displayed would be zero. The decimal point takes
82 the current locale into account (see setlocale(3) and localeconv(3)).
83 mult is the relative multiple for each suffix. uprefix, if not zero,
84 will be used as a suffix following any metric suffix.
85
86 The maximum number of columns is not directly related to the maximum
87 number of bytes, since Unicode doesn't necessarily map to single-byte
88 characters (including the 'µ' micro suffix). The corresponding defines
89 for maximum column length are:
90
91 • NCPREFIXCOLUMNS (7)
92
93 • NCIPREFIXCOLUMNS (8)
94
95 • NCBPREFIXCOLUMNS (9)
96
97 In general, the maximum-width output will take the form CCC.mmMu, where
98 C are digits of the characteristic (up to ceil(log10(mult)) digits),
99 the decimal point follows, m are digits of the mantissa (up to 2), M is
100 the metric suffix, and u is the uprefix. The minimum-width output will
101 take the form C. This minimal form can occur if omitdec is non-zero
102 and a single-column value such as 5 is passed for val.
103
104 Three more defines are provided to simplify formatted fixed-width out‐
105 put using the results of ncmetric. Each of these macros accepts a
106 character buffer holding the result of the call, and expand to two ar‐
107 guments:
108
109 • NCPREFIXFMT(x)
110
111 • NCIPREFIXFMT(x)
112
113 • NCBPREFIXFMT(x)
114
115 These can be used in e.g. the following ungainly fashion:
116
117 **ncplane_printf(n, "%*s", NCPREFIXFMT(buf));**
118
119 to ensure that the output is always NCPREFIXCOLUMNS wide.
120
122 NULL if input parameters were invalid. Otherwise, a pointer to buf,
123 filled in with the formatted output.
124
126 ncnmetric(0, INT_MAX, buf, 0, 1000, '\0'): "0.00".
127
128 ncnmetric(0, INT_MAX, buf, 1, 1000, '\0'): "0".
129
130 ncnmetric(1023, INT_MAX, buf, 1, 1000, '\0'): "1.02K".
131
132 ncnmetric(1023, INT_MAX, buf, 1, 1024, 'i'): "1023".
133
134 ncnmetric(1024, INT_MAX, buf, 1, 1024, 'i'): "1Ki".
135
136 ncnmetric(4096, INT_MAX, buf, 0, 1024, 'i'): "4.00Ki".
137
138 ncnmetric(0x7fffffffffffffff, INT_MAX, buf, 0, 1000, '\0'): "9.22E".
139
140 ncnmetric(0xffffffffffffffff, INT_MAX, buf, 0, 1000, '\0'): "18.45E".
141
143 This function is difficult to understand.
144
146 localeconv(3), notcurses(3), notcurses_output(3), setlocale(3),
147 snprintf(3)
148
150 nick black <nickblack@linux.com>.
151
152
153
154 v3.0.8 notcurses_metric(3)