FIXME: Should rework API toward allowing multiple in-flight temp buffers (easier and safer for caller) by making the caller acquire a temp buffer token, with either explicit or destructor release, e.g. ImGuiTempBufferToken token; ImFormatStringToTempBuffer(token, ...);
| 2353 | // ImGuiTempBufferToken token; |
| 2354 | // ImFormatStringToTempBuffer(token, ...); |
| 2355 | void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args) |
| 2356 | { |
| 2357 | ImGuiContext& g = *GImGui; |
| 2358 | if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) |
| 2359 | { |
| 2360 | const char* buf = va_arg(args, const char*); // Skip formatting when using "%s" |
| 2361 | if (buf == NULL) |
| 2362 | buf = "(null)"; |
| 2363 | *out_buf = buf; |
| 2364 | if (out_buf_end) { *out_buf_end = buf + ImStrlen(buf); } |
| 2365 | } |
| 2366 | else if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 's' && fmt[4] == 0) |
| 2367 | { |
| 2368 | int buf_len = va_arg(args, int); // Skip formatting when using "%.*s" |
| 2369 | const char* buf = va_arg(args, const char*); |
| 2370 | if (buf == NULL) |
| 2371 | { |
| 2372 | buf = "(null)"; |
| 2373 | buf_len = ImMin(buf_len, 6); |
| 2374 | } |
| 2375 | *out_buf = buf; |
| 2376 | *out_buf_end = buf + buf_len; // Disallow not passing 'out_buf_end' here. User is expected to use it. |
| 2377 | } |
| 2378 | else |
| 2379 | { |
| 2380 | int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args); |
| 2381 | *out_buf = g.TempBuffer.Data; |
| 2382 | if (out_buf_end) { *out_buf_end = g.TempBuffer.Data + buf_len; } |
| 2383 | } |
| 2384 | } |
| 2385 | |
| 2386 | #ifndef IMGUI_ENABLE_SSE4_2_CRC |
| 2387 | // CRC32 needs a 1KB lookup table (not cache friendly) |
no test coverage detected