1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21843b4e0SJosh Poimboeuf #ifndef __SUBCMD_UTIL_H 31843b4e0SJosh Poimboeuf #define __SUBCMD_UTIL_H 44b6ab94eSJosh Poimboeuf 54b6ab94eSJosh Poimboeuf #include <stdarg.h> 64b6ab94eSJosh Poimboeuf #include <stdlib.h> 74b6ab94eSJosh Poimboeuf #include <stdio.h> 84b6ab94eSJosh Poimboeuf 94b6ab94eSJosh Poimboeuf #define NORETURN __attribute__((__noreturn__)) 104b6ab94eSJosh Poimboeuf 114b6ab94eSJosh Poimboeuf static inline void report(const char *prefix, const char *err, va_list params) 124b6ab94eSJosh Poimboeuf { 134b6ab94eSJosh Poimboeuf char msg[1024]; 144b6ab94eSJosh Poimboeuf vsnprintf(msg, sizeof(msg), err, params); 154b6ab94eSJosh Poimboeuf fprintf(stderr, " %s%s\n", prefix, msg); 164b6ab94eSJosh Poimboeuf } 174b6ab94eSJosh Poimboeuf 184b6ab94eSJosh Poimboeuf static NORETURN inline void die(const char *err, ...) 194b6ab94eSJosh Poimboeuf { 204b6ab94eSJosh Poimboeuf va_list params; 214b6ab94eSJosh Poimboeuf 224b6ab94eSJosh Poimboeuf va_start(params, err); 234b6ab94eSJosh Poimboeuf report(" Fatal: ", err, params); 244b6ab94eSJosh Poimboeuf exit(128); 254b6ab94eSJosh Poimboeuf va_end(params); 264b6ab94eSJosh Poimboeuf } 274b6ab94eSJosh Poimboeuf 284b6ab94eSJosh Poimboeuf #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) 294b6ab94eSJosh Poimboeuf 304b6ab94eSJosh Poimboeuf #define alloc_nr(x) (((x)+16)*3/2) 314b6ab94eSJosh Poimboeuf 324b6ab94eSJosh Poimboeuf /* 334b6ab94eSJosh Poimboeuf * Realloc the buffer pointed at by variable 'x' so that it can hold 344b6ab94eSJosh Poimboeuf * at least 'nr' entries; the number of entries currently allocated 354b6ab94eSJosh Poimboeuf * is 'alloc', using the standard growing factor alloc_nr() macro. 364b6ab94eSJosh Poimboeuf * 374b6ab94eSJosh Poimboeuf * DO NOT USE any expression with side-effect for 'x' or 'alloc'. 384b6ab94eSJosh Poimboeuf */ 394b6ab94eSJosh Poimboeuf #define ALLOC_GROW(x, nr, alloc) \ 404b6ab94eSJosh Poimboeuf do { \ 414b6ab94eSJosh Poimboeuf if ((nr) > alloc) { \ 424b6ab94eSJosh Poimboeuf if (alloc_nr(alloc) < (nr)) \ 434b6ab94eSJosh Poimboeuf alloc = (nr); \ 444b6ab94eSJosh Poimboeuf else \ 454b6ab94eSJosh Poimboeuf alloc = alloc_nr(alloc); \ 464b6ab94eSJosh Poimboeuf x = xrealloc((x), alloc * sizeof(*(x))); \ 474b6ab94eSJosh Poimboeuf } \ 484b6ab94eSJosh Poimboeuf } while(0) 494b6ab94eSJosh Poimboeuf 504b6ab94eSJosh Poimboeuf static inline void *xrealloc(void *ptr, size_t size) 514b6ab94eSJosh Poimboeuf { 524b6ab94eSJosh Poimboeuf void *ret = realloc(ptr, size); 534b6ab94eSJosh Poimboeuf if (!ret && !size) 544b6ab94eSJosh Poimboeuf ret = realloc(ptr, 1); 554b6ab94eSJosh Poimboeuf if (!ret) { 564b6ab94eSJosh Poimboeuf ret = realloc(ptr, size); 574b6ab94eSJosh Poimboeuf if (!ret && !size) 584b6ab94eSJosh Poimboeuf ret = realloc(ptr, 1); 594b6ab94eSJosh Poimboeuf if (!ret) 604b6ab94eSJosh Poimboeuf die("Out of memory, realloc failed"); 614b6ab94eSJosh Poimboeuf } 624b6ab94eSJosh Poimboeuf return ret; 634b6ab94eSJosh Poimboeuf } 644b6ab94eSJosh Poimboeuf 654b6ab94eSJosh Poimboeuf #define astrcatf(out, fmt, ...) \ 664b6ab94eSJosh Poimboeuf ({ \ 674b6ab94eSJosh Poimboeuf char *tmp = *(out); \ 684b6ab94eSJosh Poimboeuf if (asprintf((out), "%s" fmt, tmp ?: "", ## __VA_ARGS__) == -1) \ 694b6ab94eSJosh Poimboeuf die("asprintf failed"); \ 704b6ab94eSJosh Poimboeuf free(tmp); \ 714b6ab94eSJosh Poimboeuf }) 724b6ab94eSJosh Poimboeuf 734b6ab94eSJosh Poimboeuf static inline void astrcat(char **out, const char *add) 744b6ab94eSJosh Poimboeuf { 754b6ab94eSJosh Poimboeuf char *tmp = *out; 764b6ab94eSJosh Poimboeuf 774b6ab94eSJosh Poimboeuf if (asprintf(out, "%s%s", tmp ?: "", add) == -1) 784b6ab94eSJosh Poimboeuf die("asprintf failed"); 794b6ab94eSJosh Poimboeuf 804b6ab94eSJosh Poimboeuf free(tmp); 814b6ab94eSJosh Poimboeuf } 824b6ab94eSJosh Poimboeuf 831843b4e0SJosh Poimboeuf #endif /* __SUBCMD_UTIL_H */ 84