subcmd-util.h 1.8 KB

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