asprintf.c 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /* Licensed under BSD-MIT - see LICENSE file for details */
  2. #include <ccan/asprintf/asprintf.h>
  3. #include <stdarg.h>
  4. #include <stdio.h>
  5. char *PRINTF_FMT(1, 2) afmt(const char *fmt, ...)
  6. {
  7. va_list ap;
  8. char *ptr;
  9. va_start(ap, fmt);
  10. /* The BSD version apparently sets ptr to NULL on fail. GNU loses. */
  11. if (vasprintf(&ptr, fmt, ap) < 0)
  12. ptr = NULL;
  13. va_end(ap);
  14. return ptr;
  15. }
  16. #if !HAVE_ASPRINTF
  17. #include <stdarg.h>
  18. #include <stdlib.h>
  19. int vasprintf(char **strp, const char *fmt, va_list ap)
  20. {
  21. int len;
  22. va_list ap_copy;
  23. /* We need to make a copy of ap, since it's a use-once. */
  24. va_copy(ap_copy, ap);
  25. len = vsnprintf(NULL, 0, fmt, ap_copy);
  26. va_end(ap_copy);
  27. /* Until version 2.0.6 glibc would return -1 on truncated output.
  28. * OTOH, they had asprintf. */
  29. if (len < 0)
  30. return -1;
  31. *strp = malloc(len+1);
  32. if (!*strp)
  33. return -1;
  34. return vsprintf(*strp, fmt, ap);
  35. }
  36. int asprintf(char **strp, const char *fmt, ...)
  37. {
  38. va_list ap;
  39. int len;
  40. va_start(ap, fmt);
  41. len = vasprintf(strp, fmt, ap);
  42. va_end(ap);
  43. return len;
  44. }
  45. #endif /* !HAVE_ASPRINTF */