at v4.8 91 lines 2.0 kB view raw
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 10static 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 17static 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 49static 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 72static 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 82static inline int prefixcmp(const char *str, const char *prefix) 83{ 84 for (; ; str++, prefix++) 85 if (!*prefix) 86 return 0; 87 else if (*str != *prefix) 88 return (unsigned char)*prefix - (unsigned char)*str; 89} 90 91#endif /* __SUBCMD_UTIL_H */