Like sdscatprintf() but gets va_list instead of being variadic. */
| 555 | |
| 556 | /* Like sdscatprintf() but gets va_list instead of being variadic. */ |
| 557 | sds sdscatvprintf(sds s, const char *fmt, va_list ap) { |
| 558 | va_list cpy; |
| 559 | char staticbuf[1024], *buf = staticbuf, *t; |
| 560 | size_t buflen = strlen(fmt)*2; |
| 561 | int bufstrlen; |
| 562 | |
| 563 | /* We try to start using a static buffer for speed. |
| 564 | * If not possible we revert to heap allocation. */ |
| 565 | if (buflen > sizeof(staticbuf)) { |
| 566 | buf = s_malloc(buflen); |
| 567 | if (buf == NULL) return NULL; |
| 568 | } else { |
| 569 | buflen = sizeof(staticbuf); |
| 570 | } |
| 571 | |
| 572 | /* Alloc enough space for buffer and \0 after failing to |
| 573 | * fit the string in the current buffer size. */ |
| 574 | while(1) { |
| 575 | va_copy(cpy,ap); |
| 576 | bufstrlen = vsnprintf(buf, buflen, fmt, cpy); |
| 577 | va_end(cpy); |
| 578 | if (bufstrlen < 0) { |
| 579 | if (buf != staticbuf) s_free(buf); |
| 580 | return NULL; |
| 581 | } |
| 582 | if (((size_t)bufstrlen) >= buflen) { |
| 583 | if (buf != staticbuf) s_free(buf); |
| 584 | buflen = ((size_t)bufstrlen) + 1; |
| 585 | buf = s_malloc(buflen); |
| 586 | if (buf == NULL) return NULL; |
| 587 | continue; |
| 588 | } |
| 589 | break; |
| 590 | } |
| 591 | |
| 592 | /* Finally concat the obtained string to the SDS string and return it. */ |
| 593 | t = sdscatlen(s, buf, bufstrlen); |
| 594 | if (buf != staticbuf) s_free(buf); |
| 595 | return t; |
| 596 | } |
| 597 | |
| 598 | /* Append to the sds string 's' a string obtained using printf-alike format |
| 599 | * specifier. |
no test coverage detected