util/u_printf: properly handle %%
Cc: mesa-stable Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29776>
This commit is contained in:
@@ -217,5 +217,5 @@ TEST_F(u_printf_test, util_printf_mixed_multiple)
|
||||
add_arg<float>(3.0);
|
||||
add_arg<float, 4>(floats);
|
||||
|
||||
EXPECT_EQ(parse(), "ABCED\n-5 6\n%%%%mesa 10 3.000000 1.0,2.0,3.0,4.0 ");
|
||||
EXPECT_EQ(parse(), "ABCED\n-5 6\n%%mesa 10 3.000000 1.0,2.0,3.0,4.0 ");
|
||||
}
|
||||
|
||||
+41
-5
@@ -99,6 +99,42 @@ size_t u_printf_length(const char *fmt, va_list untouched_args)
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to print plain format strings without arguments as some post-processing
|
||||
* will be required:
|
||||
* - %% needs to be printed as %
|
||||
*/
|
||||
static void
|
||||
u_printf_plain_sized(FILE *out, const char* format, size_t len)
|
||||
{
|
||||
bool found = false;
|
||||
size_t last = 0;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (!found && format[i] == '%') {
|
||||
found = true;
|
||||
} else if (found && format[i] == '%') {
|
||||
/* print one character less so we only print a single % */
|
||||
fwrite(format + last, i - last - 1, 1, out);
|
||||
|
||||
last = i;
|
||||
found = false;
|
||||
} else {
|
||||
/* We should never end up here with an actual format token */
|
||||
assert(!found);
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(format + last, len - last, 1, out);
|
||||
}
|
||||
|
||||
static void
|
||||
u_printf_plain(FILE *out, const char* format)
|
||||
{
|
||||
u_printf_plain_sized(out, format, strlen(format));
|
||||
}
|
||||
|
||||
static void
|
||||
u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
||||
const u_printf_info *info,
|
||||
@@ -122,7 +158,7 @@ u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
||||
buf_pos += sizeof(fmt_idx);
|
||||
|
||||
if (!fmt->num_args) {
|
||||
fprintf(out, "%s", format);
|
||||
u_printf_plain(out, format);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -131,7 +167,7 @@ u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
||||
size_t spec_pos = util_printf_next_spec_pos(format, 0);
|
||||
|
||||
if (spec_pos == -1) {
|
||||
fprintf(out, "%s", format);
|
||||
u_printf_plain(out, format);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -140,13 +176,13 @@ u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
||||
|
||||
/* print the part before the format token */
|
||||
if (token != format)
|
||||
fwrite(format, token - format, 1, out);
|
||||
u_printf_plain_sized(out, format, token - format);
|
||||
|
||||
char *print_str = strndup(token, next_format - token);
|
||||
/* rebase spec_pos so we can use it with print_str */
|
||||
spec_pos += format - token;
|
||||
|
||||
/* print the formated part */
|
||||
/* print the formatted part */
|
||||
if (print_str[spec_pos] == 's') {
|
||||
uint64_t idx;
|
||||
memcpy(&idx, &buffer[buf_pos], 8);
|
||||
@@ -233,7 +269,7 @@ u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
||||
}
|
||||
|
||||
/* print remaining */
|
||||
fprintf(out, "%s", format);
|
||||
u_printf_plain(out, format);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user