i3 - improved tiling WM


disk: Distinguish between metric and binary prefixes

Patch status: rejected

Patch by Mats

To apply this patch, use:
curl http://cr.i3wm.org/patch/321/raw.patch | git am

b/i3status.c

16
@@ -281,6 +281,7 @@ int main(int argc, char *argv[]) {
17
 
18
         cfg_opt_t disk_opts[] = {
19
                 CFG_STR("format", "%free", CFGF_NONE),
20
+                CFG_BOOL("si_units", false, CFGF_NONE),
21
                 CFG_END()
22
         };
23
 
24
@@ -483,7 +484,7 @@ int main(int argc, char *argv[]) {
25
 
26
                         CASE_SEC_TITLE("disk") {
27
                                 SEC_OPEN_MAP("disk_info");
28
-                                print_disk_info(json_gen, buffer, title, cfg_getstr(sec, "format"));
29
+                                print_disk_info(json_gen, buffer, title, cfg_getstr(sec, "format"), cfg_getbool(sec, "si_units"));
30
                                 SEC_CLOSE_MAP;
31
                         }
32
 

b/include/i3status.h

37
@@ -145,7 +145,7 @@ char *auto_detect_format();
38
 void set_timezone(const char *tz);
39
 
40
 void print_ipv6_info(yajl_gen json_gen, char *buffer, const char *format_up, const char *format_down);
41
-void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format);
42
+void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const bool si_units);
43
 void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity);
44
 void print_time(yajl_gen json_gen, char *buffer, const char *format, const char *tz, time_t t);
45
 void print_ddate(yajl_gen json_gen, char *buffer, const char *format, time_t t);

b/man/i3status.man

50
@@ -177,6 +177,9 @@ Gets used, free, available and total amount of bytes on the given mounted filesy
51
 These values can also be expressed in percentages with the percentage_used,
52
 percentage_free, percentage_avail and percentage_used_of_avail formats.
53
 
54
+By default, byte sizes are displayed using binary prefixes, e.g. 8.8 GiB. To
55
+use SI prefixes (e.g., 9.5 GB) set +si_units = true+.
56
+
57
 *Example order*: +disk /mnt/usbstick+
58
 
59
 *Example format*: +%free (%avail)/ %total+

b/src/print_disk_info.c

64
@@ -15,35 +15,70 @@
65
 
66
 #include "i3status.h"
67
 
68
-#define TERABYTE (1024ULL * 1024 * 1024 * 1024)
69
-#define GIGABYTE (1024ULL * 1024 * 1024)
70
-#define MEGABYTE (1024ULL * 1024)
71
-#define KILOBYTE (1024ULL)
72
+#define TERABYTE (1000ULL * 1000 * 1000 * 1000)
73
+#define GIGABYTE (1000ULL * 1000 * 1000)
74
+#define MEGABYTE (1000ULL * 1000)
75
+#define KILOBYTE (1000ULL)
76
+
77
+#define TEBIBYTE (1024ULL * 1024 * 1024 * 1024)
78
+#define GIBIBYTE (1024ULL * 1024 * 1024)
79
+#define MEBIBYTE (1024ULL * 1024)
80
+#define KIBIBYTE (1024ULL)
81
 
82
 /*
83
- * Prints the given amount of bytes in a human readable manner.
84
+ * Prints bytes in a human readable format using metric (SI) prefixes.
85
  *
86
  */
87
-static int print_bytes_human(char *outwalk, uint64_t bytes) {
88
-        if (bytes > TERABYTE)
89
+static int print_bytes_human_metric(char *outwalk, uint64_t bytes) {
90
+        if (bytes >= TERABYTE)
91
                 return sprintf(outwalk, "%.02f TB", (double)bytes / TERABYTE);
92
-        else if (bytes > GIGABYTE)
93
+        else if (bytes >= GIGABYTE)
94
                 return sprintf(outwalk, "%.01f GB", (double)bytes / GIGABYTE);
95
-        else if (bytes > MEGABYTE)
96
+        else if (bytes >= MEGABYTE)
97
                 return sprintf(outwalk, "%.01f MB", (double)bytes / MEGABYTE);
98
-        else if (bytes > KILOBYTE)
99
-                return sprintf(outwalk, "%.01f KB", (double)bytes / KILOBYTE);
100
+        else if (bytes >= KILOBYTE)
101
+                return sprintf(outwalk, "%.01f kB", (double)bytes / KILOBYTE);
102
         else {
103
                 return sprintf(outwalk, "%.01f B", (double)bytes);
104
         }
105
 }
106
 
107
 /*
108
+ * Prints bytes in a human readable format using binary prefixes.
109
+ *
110
+ */
111
+static int print_bytes_human_binary(char *outwalk, uint64_t bytes) {
112
+        if (bytes >= TEBIBYTE)
113
+                return sprintf(outwalk, "%.02f TiB", (double)bytes / TEBIBYTE);
114
+        else if (bytes >= GIGABYTE)
115
+                return sprintf(outwalk, "%.01f GiB", (double)bytes / GIBIBYTE);
116
+        else if (bytes >= MEGABYTE)
117
+                return sprintf(outwalk, "%.01f MiB", (double)bytes / MEBIBYTE);
118
+        else if (bytes >= KILOBYTE)
119
+                return sprintf(outwalk, "%.01f KiB", (double)bytes / KIBIBYTE);
120
+        else {
121
+                return sprintf(outwalk, "%.01f B", (double)bytes);
122
+        }
123
+}
124
+
125
+/*
126
+ * Prints the given amount of bytes in a human readable manner.
127
+ *
128
+ */
129
+static int print_bytes_human(char *outwalk, uint64_t bytes, bool si_units) {
130
+        if (si_units) {
131
+                return print_bytes_human_metric(outwalk, bytes);
132
+        } else {
133
+                return print_bytes_human_binary(outwalk, bytes);
134
+        }
135
+}
136
+
137
+/*
138
  * Does a statvfs and prints either free, used or total amounts of bytes in a
139
  * human readable manner.
140
  *
141
  */
142
-void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format) {
143
+void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const bool si_units) {
144
         const char *walk;
145
         char *outwalk = buffer;
146
 
147
@@ -68,22 +103,22 @@ void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const ch
148
                 }
149
 
150
                 if (BEGINS_WITH(walk+1, "free")) {
151
-                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree);
152
+                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree, si_units);
153
                         walk += strlen("free");
154
                 }
155
 
156
                 if (BEGINS_WITH(walk+1, "used")) {
157
-                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree));
158
+                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree), si_units);
159
                         walk += strlen("used");
160
                 }
161
 
162
                 if (BEGINS_WITH(walk+1, "total")) {
163
-                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks);
164
+                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks, si_units);
165
                         walk += strlen("total");
166
                 }
167
 
168
                 if (BEGINS_WITH(walk+1, "avail")) {
169
-                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail);
170
+                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail, si_units);
171
                         walk += strlen("avail");
172
                 }
173