util.c - ics2txt - convert icalendar .ics file to plain text
(HTM) git clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
---
util.c (3112B)
---
1 #include "util.h"
2 #include <assert.h>
3 #include <errno.h>
4 #include <stdint.h>
5 #include <limits.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <time.h>
10
11 char *arg0;
12
13 static void
14 _log(char const *fmt, va_list va)
15 {
16 if (arg0 != NULL)
17 fprintf(stderr, "%s: ", arg0);
18 vfprintf(stderr, fmt, va);
19 fprintf(stderr, "\n");
20 fflush(stderr);
21 }
22
23 void
24 err(int e, char const *fmt, ...)
25 {
26 va_list va;
27
28 va_start(va, fmt);
29 _log( fmt, va);
30 exit(e);
31 }
32
33 void
34 warn(char const *fmt, ...)
35 {
36 va_list va;
37
38 va_start(va, fmt);
39 _log(fmt, va);
40 }
41
42 void
43 debug(char const *fmt, ...)
44 {
45 static int verbose = -1;
46 va_list va;
47
48 if (verbose < 0)
49 verbose = (getenv("DEBUG") != NULL);
50 if (!verbose)
51 return;
52 va_start(va, fmt);
53 _log(fmt, va);
54 }
55
56 size_t
57 strlcpy(char *d, char const *s, size_t sz)
58 {
59 size_t len, cpy;
60
61 len = strlen(s);
62 cpy = (len > sz) ? (sz) : (len);
63 memcpy(d, s, cpy + 1);
64 d[sz - 1] = '\0';
65 return len;
66 }
67
68 size_t
69 strlcat(char *d, char const *s, size_t dsz)
70 {
71 size_t dlen;
72
73 dlen = strlen(d);
74 if (dlen >= dsz)
75 return dlen + strlen(s);
76 return dlen + strlcpy(d + dlen, s, dsz - dlen);
77 }
78
79 char *
80 strsep(char **sp, char const *sep)
81 {
82 char *s, *prev;
83
84 if (*sp == NULL)
85 return NULL;
86 prev = *sp;
87 for (s = *sp; strchr(sep, *s) == NULL; s++);
88 if (*s == '\0') {
89 *sp = NULL;
90 } else {
91 *sp = s + 1;
92 *s = '\0';
93 }
94 return prev;
95 }
96
97 void
98 strchomp(char *line)
99 {
100 size_t len;
101
102 len = strlen(line);
103 if (len > 0 && line[len - 1] == '\n')
104 line[--len] = '\0';
105 if (len > 0 && line[len - 1] == '\r')
106 line[--len] = '\0';
107 }
108
109 char *
110 strappend(char **dp, char const *s)
111 {
112 size_t dlen, slen;
113 void *mem;
114
115 dlen = (*dp == NULL) ? 0 : strlen(*dp);
116 slen = strlen(s);
117 if ((mem = realloc(*dp, dlen + slen + 1)) == NULL)
118 return NULL;
119 *dp = mem;
120 memcpy(*dp + dlen, s, slen + 1);
121 return *dp;
122 }
123
124 size_t
125 strsplit(char *s, char **array, size_t len, char const *sep)
126 {
127 size_t i;
128
129 assert(len > 0);
130 for (i = 0; i < len; i++)
131 if ((array[i] = strsep(&s, sep)) == NULL)
132 break;
133 array[len - 1] = NULL;
134 return i;
135 }
136
137 long long
138 strtonum(char const *s, long long min, long long max, char const **errstr)
139 {
140 long long ll = 0;
141 char *end;
142
143 assert(min < max);
144 errno = 0;
145 ll = strtoll(s, &end, 10);
146 if ((errno == ERANGE && ll == LLONG_MIN) || ll < min) {
147 if (errstr != NULL)
148 *errstr = "too small";
149 return 0;
150 }
151 if ((errno == ERANGE && ll == LLONG_MAX) || ll > max) {
152 if (errstr != NULL)
153 *errstr = "too large";
154 return 0;
155 }
156 if (errno == EINVAL || *end != '\0') {
157 if (errstr != NULL)
158 *errstr = "invalid";
159 return 0;
160 }
161 assert(errno == 0);
162 if (errstr != NULL)
163 *errstr = NULL;
164 return ll;
165 }
166
167 void *
168 reallocarray(void *mem, size_t n, size_t sz)
169 {
170 if (SIZE_MAX / n < sz)
171 return errno=ERANGE, NULL;
172 return realloc(mem, n * sz);
173 }
174
175 time_t
176 tztime(struct tm *tm, char const *tz)
177 {
178 char *env, old[32];
179 time_t t;
180
181 env = getenv("TZ");
182 if (strlcpy(old, env ? env : "", sizeof old) >= sizeof old)
183 return -1;
184 if (setenv("TZ", tz, 1) < 0)
185 return -1;
186
187 tzset();
188 t = mktime(tm);
189
190 if (env == NULL)
191 unsetenv("TZ");
192 else if (setenv("TZ", old, 1) < 0)
193 return -1;
194 return t;
195 }