--- /dev/null
+#include <asn_internal.h>
+
+ssize_t
+asn__format_to_callback(int (*cb)(const void *, size_t, void *key), void *key,
+ const char *fmt, ...) {
+ char scratch[64];
+ char *buf = scratch;
+ size_t buf_size = sizeof(scratch);
+ int wrote;
+ int cb_ret;
+
+ do {
+ va_list args;
+ va_start(args, fmt);
+
+ wrote = vsnprintf(buf, buf_size, fmt, args);
+ if(wrote < (ssize_t)buf_size) {
+ if(wrote < 0) {
+ if(buf != scratch) FREEMEM(buf);
+ va_end(args);
+ return -1;
+ }
+ break;
+ }
+
+ buf_size <<= 1;
+ if(buf == scratch) {
+ buf = MALLOC(buf_size);
+ if(!buf) return -1;
+ } else {
+ void *p = REALLOC(buf, buf_size);
+ if(!p) {
+ FREEMEM(buf);
+ return -1;
+ }
+ buf = p;
+ }
+ } while(1);
+
+ cb_ret = cb(buf, wrote, key);
+ if(buf != scratch) FREEMEM(buf);
+ if(cb_ret < 0) {
+ return -1;
+ }
+
+ return wrote;
+}
+