diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 4fbce393..607b0674 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -281,6 +281,15 @@ static void set_status(struct fx_write_context *fx, int status) fx->status = status; } +static void fx_print_string(struct vkd3d_string_buffer *buffer, const char *prefix, + const char *s, size_t len) +{ + if (len) + --len; /* Trim terminating null. */ + vkd3d_string_buffer_printf(buffer, "%s", prefix); + vkd3d_string_buffer_print_string_escaped(buffer, s, len); +} + static uint32_t write_string(const char *string, struct fx_write_context *fx) { return fx->ops->write_string(string, fx); @@ -3452,13 +3461,12 @@ static void parse_fx_print_indent(struct fx_parser *parser) vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); } -static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset) +static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset, uint32_t *size) { const char *ptr; - uint32_t size; - fx_parser_read_unstructured(parser, &size, offset, sizeof(size)); - ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, size); + fx_parser_read_unstructured(parser, size, offset, sizeof(*size)); + ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size); if (!ptr) { @@ -3624,13 +3632,14 @@ static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset) uint32_t element_count; } var; const char *name; + uint32_t size; fx_parser_read_unstructured(parser, &var, offset, sizeof(var)); fx_parse_fx_2_type(parser, offset); - name = fx_2_get_string(parser, var.name); - vkd3d_string_buffer_printf(&parser->buffer, " %s", name); + name = fx_2_get_string(parser, var.name, &size); + fx_print_string(&parser->buffer, " ", name, size); if (var.element_count) vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count); } @@ -3787,16 +3796,17 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) uint32_t assignment_count; } pass; const char *name; + uint32_t size; if (parser->failed) return; fx_parser_read_u32s(parser, &technique, sizeof(technique)); - name = fx_2_get_string(parser, technique.name); + name = fx_2_get_string(parser, technique.name, &size); parse_fx_print_indent(parser); - vkd3d_string_buffer_printf(&parser->buffer, "technique %s", name); + fx_print_string(&parser->buffer, "technique ", name, size); fx_parse_fx_2_annotations(parser, technique.annotation_count); vkd3d_string_buffer_printf(&parser->buffer, "\n"); @@ -3807,10 +3817,10 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) for (uint32_t i = 0; i < technique.pass_count; ++i) { fx_parser_read_u32s(parser, &pass, sizeof(pass)); - name = fx_2_get_string(parser, pass.name); + name = fx_2_get_string(parser, pass.name, &size); parse_fx_print_indent(parser); - vkd3d_string_buffer_printf(&parser->buffer, "pass %s", name); + fx_print_string(&parser->buffer, "pass ", name, size); fx_parse_fx_2_annotations(parser, pass.annotation_count); vkd3d_string_buffer_printf(&parser->buffer, "\n"); @@ -3887,7 +3897,8 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) parse_fx_start_indent(parser); parse_fx_print_indent(parser); str = fx_parser_get_ptr(parser, size); - vkd3d_string_buffer_printf(&parser->buffer, "\"%.*s\"\n", size, str); + fx_print_string(&parser->buffer, "\"", str, size); + vkd3d_string_buffer_printf(&parser->buffer, "\"\n"); parse_fx_end_indent(parser); } break; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 455d00ed..6493a6e1 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -348,49 +348,12 @@ static void spirv_parser_print_instruction_offset(struct spirv_parser *parser, parser->colours.comment, offset * sizeof(uint32_t), parser->colours.reset, suffix); } -static char get_escape_char(char c) -{ - switch (c) - { - case '"': - case '\\': - return c; - case '\t': - return 't'; - case '\n': - return 'n'; - case '\v': - return 'v'; - case '\f': - return 'f'; - case '\r': - return 'r'; - default: - return 0; - } -} - static void spirv_parser_print_string_literal(struct spirv_parser *parser, struct vkd3d_string_buffer *buffer, const char *prefix, const char *s, size_t len, const char *suffix) { - size_t start, i; - char c; - vkd3d_string_buffer_printf(buffer, "%s\"%s", prefix, parser->colours.literal); - for (i = 0, start = 0; i < len; ++i) - { - if ((c = get_escape_char(s[i]))) - { - vkd3d_string_buffer_printf(buffer, "%.*s\\%c", (int)(i - start), &s[start], c); - start = i + 1; - } - else if (!isprint(s[i])) - { - vkd3d_string_buffer_printf(buffer, "%.*s\\%03o", (int)(i - start), &s[start], (uint8_t)s[i]); - start = i + 1; - } - } - vkd3d_string_buffer_printf(buffer, "%.*s%s\"%s", (int)(len - start), &s[start], parser->colours.reset, suffix); + vkd3d_string_buffer_print_string_escaped(buffer, s, len); + vkd3d_string_buffer_printf(buffer, "%s\"%s", parser->colours.reset, suffix); } static const struct spirv_parser_enumerant *spirv_parser_get_enumerant( diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index a2c5d9fb..fdc60291 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -163,6 +163,60 @@ int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d) return ret; } +static char get_escape_char(char c) +{ + switch (c) + { + case '"': + case '\\': + return c; + case '\t': + return 't'; + case '\n': + return 'n'; + case '\v': + return 'v'; + case '\f': + return 'f'; + case '\r': + return 'r'; + default: + return 0; + } +} + +int vkd3d_string_buffer_print_string_escaped(struct vkd3d_string_buffer *buffer, const char *s, size_t len) +{ + size_t content_size, start, i; + int ret; + char c; + + content_size = buffer->content_size; + for (i = 0, start = 0; i < len; ++i) + { + if ((c = get_escape_char(s[i]))) + { + if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s\\%c", (int)(i - start), &s[start], c)) < 0) + goto fail; + start = i + 1; + } + else if (!isprint(s[i])) + { + if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s\\%03o", + (int)(i - start), &s[start], (uint8_t)s[i])) < 0) + goto fail; + start = i + 1; + } + } + if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s", (int)(len - start), &s[start])) < 0) + goto fail; + return ret; + +fail: + buffer->content_size = content_size; + return ret; +} + void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function) { vkd3d_shader_trace_text_(buffer->buffer, buffer->content_size, function); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 53a9f844..b766b0e7 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1565,6 +1565,7 @@ void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer); void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t size); int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f); int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d); +int vkd3d_string_buffer_print_string_escaped(struct vkd3d_string_buffer *buffer, const char *s, size_t len); int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format, ...) VKD3D_PRINTF_FUNC(2, 3); void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *list, struct vkd3d_string_buffer *buffer); #define vkd3d_string_buffer_trace(buffer) \