| #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; |
| } |
| |