Home
util.c - ics2txt - convert icalendar .ics file to plain text HTML 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 }