Xinqi Bao's Git

Revert aac29e2 as it is nonsense
[slstatus.git] / util.c
1 /* See LICENSE file for copyright and license details. */
2 #include <errno.h>
3 #include <stdarg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "util.h"
9
10 char *argv0;
11
12 static void
13 verr(const char *fmt, va_list ap)
14 {
15 if (argv0 && strncmp(fmt, "usage", sizeof("usage") - 1)) {
16 fprintf(stderr, "%s: ", argv0);
17 }
18
19 vfprintf(stderr, fmt, ap);
20
21 if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
22 fputc(' ', stderr);
23 perror(NULL);
24 } else {
25 fputc('\n', stderr);
26 }
27 }
28
29 void
30 warn(const char *fmt, ...)
31 {
32 va_list ap;
33
34 va_start(ap, fmt);
35 verr(fmt, ap);
36 va_end(ap);
37 }
38
39 void
40 die(const char *fmt, ...)
41 {
42 va_list ap;
43
44 va_start(ap, fmt);
45 verr(fmt, ap);
46 va_end(ap);
47
48 exit(1);
49 }
50
51 const char *
52 bprintf(const char *fmt, ...)
53 {
54 va_list ap;
55 int ret;
56
57 va_start(ap, fmt);
58 if ((ret = vsnprintf(buf, sizeof(buf), fmt, ap)) < 0) {
59 warn("vsnprintf:");
60 } else if ((size_t)ret >= sizeof(buf)) {
61 warn("vsnprintf: Output truncated");
62 }
63 va_end(ap);
64
65 return buf;
66 }
67
68 const char *
69 fmt_scaled(size_t bytes)
70 {
71 unsigned int i;
72 float scaled;
73 const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB",
74 "ZiB", "YiB" };
75
76 scaled = bytes;
77 for (i = 0; i < LEN(units) && scaled >= 1024; i++) {
78 scaled /= 1024.0;
79 }
80
81 return bprintf("%.1f%s", scaled, units[i]);
82 }
83
84 int
85 pscanf(const char *path, const char *fmt, ...)
86 {
87 FILE *fp;
88 va_list ap;
89 int n;
90
91 if (!(fp = fopen(path, "r"))) {
92 warn("fopen '%s':", path);
93 return -1;
94 }
95 va_start(ap, fmt);
96 n = vfscanf(fp, fmt, ap);
97 va_end(ap);
98 fclose(fp);
99
100 return (n == EOF) ? -1 : n;
101 }