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