mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-14 14:03:58 +00:00
Rewrite vformat_string to not use string_buffer
This commit is contained in:
parent
00764406d7
commit
0a5680c3e8
1 changed files with 50 additions and 6 deletions
56
common.cpp
56
common.cpp
|
@ -449,12 +449,56 @@ wcstring format_string(const wchar_t *format, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wcstring vformat_string(const wchar_t *format, va_list va_orig)
|
wcstring vformat_string(const wchar_t *format, va_list va_orig)
|
||||||
{
|
{
|
||||||
string_buffer_t buffer;
|
const int saved_err = errno;
|
||||||
sb_init(&buffer);
|
/*
|
||||||
sb_vprintf(&buffer, format, va_orig);
|
As far as I know, there is no way to check if a
|
||||||
wcstring result = (wchar_t *)buffer.buff;
|
vswprintf-call failed because of a badly formated string
|
||||||
sb_destroy(&buffer);
|
option or because the supplied destination string was to
|
||||||
|
small. In GLIBC, errno seems to be set to EINVAL either way.
|
||||||
|
|
||||||
|
Because of this, on failiure we try to
|
||||||
|
increase the buffer size until the free space is
|
||||||
|
larger than max_size, at which point it will
|
||||||
|
conclude that the error was probably due to a badly
|
||||||
|
formated string option, and return an error. Make
|
||||||
|
sure to null terminate string before that, though.
|
||||||
|
*/
|
||||||
|
const size_t max_size = (128*1024*1024);
|
||||||
|
wchar_t static_buff[256];
|
||||||
|
size_t size = 0;
|
||||||
|
wchar_t *buff = NULL;
|
||||||
|
int status = -1;
|
||||||
|
while (status < 0) {
|
||||||
|
/* Reallocate if necessary */
|
||||||
|
if (size == 0) {
|
||||||
|
buff = static_buff;
|
||||||
|
size = sizeof static_buff;
|
||||||
|
} else {
|
||||||
|
size *= 2;
|
||||||
|
if (size >= max_size) {
|
||||||
|
buff[0] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buff = (wchar_t *)realloc( (buff == static_buff ? NULL : buff), size);
|
||||||
|
if (buff == NULL) {
|
||||||
|
DIE_MEM();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try printing */
|
||||||
|
va_list va;
|
||||||
|
va_copy( va, va_orig );
|
||||||
|
status = vswprintf(buff, size / sizeof(wchar_t), format, va);
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
wcstring result = wcstring(buff);
|
||||||
|
|
||||||
|
if (buff != static_buff)
|
||||||
|
free(buff);
|
||||||
|
|
||||||
|
errno = saved_err;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue