1#include <errno.h>
2#include <stdarg.h>
3#include <stdbool.h>
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8
9#include "util.h"
10
11extern const char *argv0;
12
13static void
14vwarn(const char *fmt, va_list ap)
15{
16 fprintf(stderr, "%s: ", argv0);
17 vfprintf(stderr, fmt, ap);
18 if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
19 putc(' ', stderr);
20 perror(NULL);
21 } else {
22 putc('\n', stderr);
23 }
24}
25
26void
27warn(const char *fmt, ...)
28{
29 va_list ap;
30
31 va_start(ap, fmt);
32 vwarn(fmt, ap);
33 va_end(ap);
34}
35
36void
37die(const char *fmt, ...)
38{
39 va_list ap;
40
41 va_start(ap, fmt);
42 vwarn(fmt, ap);
43 va_end(ap);
44 exit(1);
45}
46
47void *
48xmalloc(size_t n)
49{
50 void *p;
51
52 p = malloc(n ? n : 1);
53 if (!p)
54 die("malloc:");
55 return p;
56}
57
58void *
59xcalloc(size_t n, size_t m)
60{
61 void *p;
62
63 p = calloc(n, m);
64 if (!p)
65 die("calloc:");
66 return p;
67}
68
69static void *
70reallocarray_(void *p, size_t n, size_t m)
71{
72 if (m && n > SIZE_MAX / m) {
73 errno = ENOMEM;
74 return NULL;
75 }
76 return realloc(p, n * m);
77}
78
79void *
80xreallocarray(void *p, size_t n, size_t m)
81{
82 p = reallocarray_(p, n, m);
83 if (!p)
84 die("reallocarray:");
85 return p;
86}
87
88char *
89xstrdup(const char *s)
90{
91 size_t n;
92 char *p;
93
94 n = strlen(s) + 1;
95 p = xmalloc(n);
96 memcpy(p, s, n);
97 return p;
98}
99
100char *
101xmemdup0(const char *s, size_t n)
102{
103 char *p;
104
105 p = xmalloc(n + 1);
106 memcpy(p, s, n);
107 p[n] = '\0';
108 return p;
109}
110
111int
112xasprintf(char **s, const char *fmt, ...)
113{
114 va_list ap;
115 int ret;
116 size_t n;
117
118 va_start(ap, fmt);
119 ret = vsnprintf(NULL, 0, fmt, ap);
120 va_end(ap);
121 if (ret < 0)
122 die("vsnprintf:");
123 n = (size_t)ret + 1;
124 *s = xmalloc(n);
125 va_start(ap, fmt);
126 ret = vsnprintf(*s, n, fmt, ap);
127 va_end(ap);
128 if (ret < 0 || (size_t)ret >= n)
129 die("vsnprintf:");
130 return ret;
131}