asn_internal.c 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #include <asn_internal.h>
  2. ssize_t
  3. asn__format_to_callback(int (*cb)(const void *, size_t, void *key), void *key,
  4. const char *fmt, ...) {
  5. char scratch[64];
  6. char *buf = scratch;
  7. size_t buf_size = sizeof(scratch);
  8. int wrote;
  9. int cb_ret;
  10. do {
  11. va_list args;
  12. va_start(args, fmt);
  13. wrote = vsnprintf(buf, buf_size, fmt, args);
  14. if(wrote < (ssize_t)buf_size) {
  15. if(wrote < 0) {
  16. if(buf != scratch) FREEMEM(buf);
  17. return -1;
  18. }
  19. break;
  20. }
  21. buf_size <<= 1;
  22. if(buf == scratch) {
  23. buf = MALLOC(buf_size);
  24. if(!buf) return -1;
  25. } else {
  26. void *p = REALLOC(buf, buf_size);
  27. if(!p) {
  28. FREEMEM(buf);
  29. return -1;
  30. }
  31. buf = p;
  32. }
  33. } while(1);
  34. cb_ret = cb(buf, wrote, key);
  35. if(buf != scratch) FREEMEM(buf);
  36. if(cb_ret < 0) {
  37. return -1;
  38. }
  39. return wrote;
  40. }