Xinqi Bao's Git

Add warn() and die()
[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 int
69 pscanf(const char *path, const char *fmt, ...)
70 {
71 FILE *fp;
72 va_list ap;
73 int n;
74
75 if (!(fp = fopen(path, "r"))) {
76 warn("fopen '%s':", path);
77 return -1;
78 }
79 va_start(ap, fmt);
80 n = vfscanf(fp, fmt, ap);
81 va_end(ap);
82 fclose(fp);
83
84 return (n == EOF) ? -1 : n;
85 }