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