Use vsnprintf() instead of vasprintf()
Windows doesn't reliably offer *asprintf() (sprintf functions that automatically malloc as much memory as they need) so hand-roll the equivalent on all platforms.
This commit is contained in:
parent
c76379e6f5
commit
439eeb2b06
39
c/ios.c
39
c/ios.c
|
@ -992,43 +992,46 @@ char *ios_readline(struct ios *s)
|
||||||
return ios_takebuf(&dest, &n);
|
return ios_takebuf(&dest, &n);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vasprintf(char **strp, const char *fmt, va_list ap);
|
|
||||||
|
|
||||||
int ios_vprintf(struct ios *s, const char *format, va_list args)
|
int ios_vprintf(struct ios *s, const char *format, va_list args)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
int c;
|
|
||||||
va_list al;
|
va_list al;
|
||||||
size_t avail;
|
size_t avail;
|
||||||
|
int len;
|
||||||
char *start;
|
char *start;
|
||||||
|
|
||||||
str = NULL;
|
|
||||||
va_copy(al, args);
|
va_copy(al, args);
|
||||||
if (s->state == bst_wr && s->bpos < s->maxsize && s->bm != bm_none) {
|
if (s->state == bst_wr && s->bpos < s->maxsize && s->bm != bm_none) {
|
||||||
avail = s->maxsize - s->bpos;
|
avail = s->maxsize - s->bpos;
|
||||||
start = s->buf + s->bpos;
|
start = s->buf + s->bpos;
|
||||||
c = vsnprintf(start, avail, format, args);
|
len = vsnprintf(start, avail, format, args);
|
||||||
if (c < 0) {
|
if (len < 0) {
|
||||||
va_end(al);
|
goto done;
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
if (avail > (size_t)c) {
|
if (avail > (size_t)len) {
|
||||||
s->bpos += (size_t)c;
|
s->bpos += (size_t)len;
|
||||||
_write_update_pos(s);
|
_write_update_pos(s);
|
||||||
// TODO: only works right if newline is at end
|
// TODO: only works right if newline is at end
|
||||||
if (s->bm == bm_line && our_memrchr(start, '\n', (size_t)c))
|
if (s->bm == bm_line && our_memrchr(start, '\n', (size_t)len)) {
|
||||||
ios_flush(s);
|
ios_flush(s);
|
||||||
va_end(al);
|
}
|
||||||
return c;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = vasprintf(&str, format, al);
|
len = vsnprintf(NULL, 0, format, al);
|
||||||
if (c >= 0) {
|
if (len <= 0) {
|
||||||
ios_write(s, str, c);
|
len = 0;
|
||||||
LLT_FREE(str);
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (!(str = calloc(1, len + 1))) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
len = vsnprintf(str, len, format, al);
|
||||||
|
ios_write(s, str, len);
|
||||||
|
LLT_FREE(str);
|
||||||
|
done:
|
||||||
va_end(al);
|
va_end(al);
|
||||||
return c;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ios_printf(struct ios *s, const char *format, ...)
|
int ios_printf(struct ios *s, const char *format, ...)
|
||||||
|
|
Loading…
Reference in New Issue