diff options
-rw-r--r-- | lib/curl_printf.h | 2 | ||||
-rw-r--r-- | lib/dynbuf.c | 14 | ||||
-rw-r--r-- | lib/dynbuf.h | 4 | ||||
-rw-r--r-- | lib/mprintf.c | 43 |
4 files changed, 45 insertions, 18 deletions
diff --git a/lib/curl_printf.h b/lib/curl_printf.h index 0d37b8e57..9d2de7ba8 100644 --- a/lib/curl_printf.h +++ b/lib/curl_printf.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/lib/dynbuf.c b/lib/dynbuf.c index 5e15040bb..2dace3428 100644 --- a/lib/dynbuf.c +++ b/lib/dynbuf.c @@ -181,8 +181,17 @@ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str) */ CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...) { - char *str; va_list ap; +#ifdef BUILDING_LIBCURL + int rc; + va_start(ap, fmt); + rc = Curl_dyn_vprintf(s, fmt, ap); + va_end(ap); + + if(!rc) + return CURLE_OK; +#else + char *str; va_start(ap, fmt); str = vaprintf(fmt, ap); /* this allocs a new string to append */ va_end(ap); @@ -194,9 +203,12 @@ CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...) } /* If we failed, we cleanup the whole buffer and return error */ Curl_dyn_free(s); +#endif return CURLE_OUT_OF_MEMORY; } + + /* * Returns a pointer to the buffer. */ diff --git a/lib/dynbuf.h b/lib/dynbuf.h index 1360dd432..94b5dbf68 100644 --- a/lib/dynbuf.h +++ b/lib/dynbuf.h @@ -62,6 +62,10 @@ char *Curl_dyn_ptr(const struct dynbuf *s); unsigned char *Curl_dyn_uptr(const struct dynbuf *s); size_t Curl_dyn_len(const struct dynbuf *s); +/* returns 0 on success, -1 on error */ +/* The implementation of this function exists in mprintf.c */ +int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save); + /* Dynamic buffer max sizes */ #define DYN_DOH_RESPONSE 3000 #define DYN_DOH_CNAME 256 diff --git a/lib/mprintf.c b/lib/mprintf.c index 6b62fdfbc..8f0011e91 100644 --- a/lib/mprintf.c +++ b/lib/mprintf.c @@ -169,7 +169,7 @@ struct nsprintf { }; struct asprintf { - struct dynbuf b; + struct dynbuf *b; bool fail; /* if an alloc has failed and thus the output is not the complete data */ }; @@ -1042,50 +1042,61 @@ static int alloc_addbyter(int output, FILE *data) struct asprintf *infop = (struct asprintf *)data; unsigned char outc = (unsigned char)output; - if(Curl_dyn_addn(&infop->b, &outc, 1)) { + if(Curl_dyn_addn(infop->b, &outc, 1)) { infop->fail = 1; return -1; /* fail */ } return outc; /* fputc() returns like this on success */ } -char *curl_maprintf(const char *format, ...) +extern int Curl_dyn_vprintf(struct dynbuf *dyn, + const char *format, va_list ap_save); + +/* appends the formatted string, returns 0 on success, 1 on error */ +int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save) { - va_list ap_save; /* argument pointer */ int retcode; struct asprintf info; - Curl_dyn_init(&info.b, DYN_APRINTF); + info.b = dyn; info.fail = 0; - va_start(ap_save, format); retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - va_end(ap_save); if((-1 == retcode) || info.fail) { - Curl_dyn_free(&info.b); - return NULL; + Curl_dyn_free(info.b); + return 1; } - if(Curl_dyn_len(&info.b)) - return Curl_dyn_ptr(&info.b); - return strdup(""); + return 0; } char *curl_mvaprintf(const char *format, va_list ap_save) { int retcode; struct asprintf info; - Curl_dyn_init(&info.b, DYN_APRINTF); + struct dynbuf dyn; + info.b = &dyn; + Curl_dyn_init(info.b, DYN_APRINTF); info.fail = 0; retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); if((-1 == retcode) || info.fail) { - Curl_dyn_free(&info.b); + Curl_dyn_free(info.b); return NULL; } - if(Curl_dyn_len(&info.b)) - return Curl_dyn_ptr(&info.b); + if(Curl_dyn_len(info.b)) + return Curl_dyn_ptr(info.b); return strdup(""); } +char *curl_maprintf(const char *format, ...) +{ + va_list ap_save; + char *s; + va_start(ap_save, format); + s = curl_mvaprintf(format, ap_save); + va_end(ap_save); + return s; +} + static int storebuffer(int output, FILE *data) { char **buffer = (char **)data; |