vasprintf.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
  2. *
  3. * GNU Library General Public License (LGPL) version 2 or later.
  4. *
  5. * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
  6. */
  7. #include <features.h>
  8. #ifdef __USE_GNU
  9. #include "_stdio.h"
  10. #include <stdarg.h>
  11. #include <bits/uClibc_va_copy.h>
  12. #ifdef __UCLIBC_MJN3_ONLY__
  13. /* Do the memstream stuff inline to avoid fclose and the openlist? */
  14. #warning CONSIDER: avoid open_memstream call?
  15. #endif
  16. #ifndef __STDIO_HAS_VSNPRINTF
  17. #warning Skipping vasprintf since no vsnprintf!
  18. #else
  19. #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
  20. #else
  21. #endif
  22. int vasprintf(char **__restrict buf, const char * __restrict format,
  23. va_list arg)
  24. {
  25. #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
  26. FILE *f;
  27. size_t size;
  28. int rv = -1;
  29. *buf = NULL;
  30. if ((f = open_memstream(buf, &size)) != NULL) {
  31. rv = vfprintf(f, format, arg);
  32. fclose(f);
  33. if (rv < 0) {
  34. free(*buf);
  35. *buf = NULL;
  36. }
  37. }
  38. assert(rv >= -1);
  39. return rv;
  40. #else /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
  41. /* This implementation actually calls the printf machinery twice, but
  42. * only does one malloc. This can be a problem though when custom printf
  43. * specs or the %m specifier are involved because the results of the
  44. * second call might be different from the first. */
  45. va_list arg2;
  46. int rv;
  47. va_copy(arg2, arg);
  48. rv = vsnprintf(NULL, 0, format, arg2);
  49. va_end(arg2);
  50. *buf = NULL;
  51. if (rv >= 0) {
  52. if ((*buf = malloc(++rv)) != NULL) {
  53. if ((rv = vsnprintf(*buf, rv, format, arg)) < 0) {
  54. free(*buf);
  55. *buf = NULL;
  56. }
  57. }
  58. }
  59. assert(rv >= -1);
  60. return rv;
  61. #endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
  62. }
  63. libc_hidden_def(vasprintf)
  64. #endif
  65. #endif