1 #ifndef __SUBCMD_UTIL_H 2 #define __SUBCMD_UTIL_H 3 4 #include <stdarg.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 8 #define NORETURN __attribute__((__noreturn__)) 9 10 static inline void report(const char *prefix, const char *err, va_list params) 11 { 12 char msg[1024]; 13 vsnprintf(msg, sizeof(msg), err, params); 14 fprintf(stderr, " %s%s\n", prefix, msg); 15 } 16 17 static NORETURN inline void die(const char *err, ...) 18 { 19 va_list params; 20 21 va_start(params, err); 22 report(" Fatal: ", err, params); 23 exit(128); 24 va_end(params); 25 } 26 27 #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) 28 29 #define alloc_nr(x) (((x)+16)*3/2) 30 31 /* 32 * Realloc the buffer pointed at by variable 'x' so that it can hold 33 * at least 'nr' entries; the number of entries currently allocated 34 * is 'alloc', using the standard growing factor alloc_nr() macro. 35 * 36 * DO NOT USE any expression with side-effect for 'x' or 'alloc'. 37 */ 38 #define ALLOC_GROW(x, nr, alloc) \ 39 do { \ 40 if ((nr) > alloc) { \ 41 if (alloc_nr(alloc) < (nr)) \ 42 alloc = (nr); \ 43 else \ 44 alloc = alloc_nr(alloc); \ 45 x = xrealloc((x), alloc * sizeof(*(x))); \ 46 } \ 47 } while(0) 48 49 static inline void *xrealloc(void *ptr, size_t size) 50 { 51 void *ret = realloc(ptr, size); 52 if (!ret && !size) 53 ret = realloc(ptr, 1); 54 if (!ret) { 55 ret = realloc(ptr, size); 56 if (!ret && !size) 57 ret = realloc(ptr, 1); 58 if (!ret) 59 die("Out of memory, realloc failed"); 60 } 61 return ret; 62 } 63 64 #define astrcatf(out, fmt, ...) \ 65 ({ \ 66 char *tmp = *(out); \ 67 if (asprintf((out), "%s" fmt, tmp ?: "", ## __VA_ARGS__) == -1) \ 68 die("asprintf failed"); \ 69 free(tmp); \ 70 }) 71 72 static inline void astrcat(char **out, const char *add) 73 { 74 char *tmp = *out; 75 76 if (asprintf(out, "%s%s", tmp ?: "", add) == -1) 77 die("asprintf failed"); 78 79 free(tmp); 80 } 81 82 #endif /* __SUBCMD_UTIL_H */ 83