[PATCH vkd3d v3 4/5] vkd3d-shader: Handle preprocessor parsing errors.
Zebediah Figura
zfigura at codeweavers.com
Mon Dec 7 12:56:33 CST 2020
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
libs/vkd3d-shader/preproc.h | 11 +++++++
libs/vkd3d-shader/preproc.l | 39 +++++++++++++++++++++++-
libs/vkd3d-shader/preproc.y | 39 +++++++++++++++++++++++-
libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++
4 files changed, 89 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/preproc.h b/libs/vkd3d-shader/preproc.h
index cbd93229..769b8c23 100644
--- a/libs/vkd3d-shader/preproc.h
+++ b/libs/vkd3d-shader/preproc.h
@@ -23,11 +23,22 @@
#include "vkd3d_shader_private.h"
+struct preproc_location
+{
+ const char *filename;
+ unsigned int first_line, first_column;
+};
+
struct preproc_ctx
{
void *scanner;
+ struct vkd3d_shader_message_context *message_context;
struct vkd3d_string_buffer buffer;
+ unsigned int line, column;
+ const char *source_name;
+
+ bool error;
};
#endif
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l
index 4d809b8f..116a7ed5 100644
--- a/libs/vkd3d-shader/preproc.l
+++ b/libs/vkd3d-shader/preproc.l
@@ -27,6 +27,10 @@
#define YY_DECL static int preproc_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner)
+static void update_location(struct preproc_ctx *ctx);
+
+#define YY_USER_ACTION update_location(yyget_extra(yyscanner));
+
%}
%option 8bit
@@ -88,6 +92,28 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
%%
+static void update_location(struct preproc_ctx *ctx)
+{
+ unsigned int i, leng = yyget_leng(ctx->scanner);
+ const char *text = yyget_text(ctx->scanner);
+
+ /* We want to do this here, rather than before calling yylex(), because
+ * some tokens are skipped by the lexer. */
+
+ yyget_lloc(ctx->scanner)->first_line = ctx->line;
+ yyget_lloc(ctx->scanner)->first_column = ctx->column;
+
+ for (i = 0; i < leng; ++i)
+ {
+ ++ctx->column;
+ if (text[i] == '\n')
+ {
+ ctx->column = 1;
+ ++ctx->line;
+ }
+ }
+}
+
int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
{
struct preproc_ctx *ctx = yyget_extra(scanner);
@@ -101,7 +127,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
return 0;
text = yyget_text(scanner);
- TRACE("Parsing token %d, string %s.\n", token, debugstr_a(text));
+ TRACE("Parsing token %d, line %d, string %s.\n", token, lloc->first_line, debugstr_a(text));
vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text);
}
@@ -115,6 +141,10 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
void *output_code;
vkd3d_string_buffer_init(&ctx.buffer);
+ ctx.message_context = message_context;
+ ctx.source_name = compile_info->source_name ? compile_info->source_name : "<anonymous>";
+ ctx.line = 1;
+ ctx.column = 1;
yylex_init_extra(&ctx, &ctx.scanner);
top_buffer = yy_scan_bytes(compile_info->source.code, compile_info->source.size, ctx.scanner);
@@ -124,6 +154,13 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
yy_delete_buffer(top_buffer, ctx.scanner);
yylex_destroy(ctx.scanner);
+ if (ctx.error)
+ {
+ WARN("Failed to preprocess.\n");
+ vkd3d_string_buffer_cleanup(&ctx.buffer);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
if (!(output_code = vkd3d_malloc(ctx.buffer.content_size)))
{
vkd3d_string_buffer_cleanup(&ctx.buffer);
diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y
index 92448f24..88b855c6 100644
--- a/libs/vkd3d-shader/preproc.y
+++ b/libs/vkd3d-shader/preproc.y
@@ -36,13 +36,50 @@ int preproc_yylex(PREPROC_YYSTYPE *yylval_param, PREPROC_YYLTYPE *yylloc_param,
%code
{
+#define YYLLOC_DEFAULT(cur, rhs, n) \
+ do \
+ { \
+ if (n) \
+ { \
+ (cur).filename = YYRHSLOC(rhs, 1).filename; \
+ (cur).first_line = YYRHSLOC(rhs, 1).first_line; \
+ (cur).first_column = YYRHSLOC(rhs, 1).first_column; \
+ } \
+ else \
+ { \
+ (cur).filename = YYRHSLOC(rhs, 0).filename; \
+ (cur).first_line = YYRHSLOC(rhs, 0).first_line; \
+ (cur).first_column = YYRHSLOC(rhs, 0).first_column; \
+ } \
+ } while (0)
+
+static void set_location(struct preproc_ctx *ctx, const struct preproc_location *loc)
+{
+ ctx->message_context->source_name = loc->filename;
+ ctx->message_context->line = loc->first_line;
+ ctx->message_context->column = loc->first_column;
+}
+
+static void preproc_error(struct preproc_ctx *ctx, const struct preproc_location *loc,
+ enum vkd3d_shader_error error, const char *format, ...)
+{
+ va_list args;
+
+ set_location(ctx, loc);
+ va_start(args, format);
+ vkd3d_shader_verror(ctx->message_context, error, format, args);
+ va_end(args);
+ ctx->error = true;
+}
+
static void yyerror(const YYLTYPE *loc, void *scanner, struct preproc_ctx *ctx, const char *string)
{
- FIXME("Error reporting is not implemented.\n");
+ preproc_error(ctx, loc, VKD3D_SHADER_ERROR_PP_INVALID_SYNTAX, "%s", string);
}
}
+%define api.location.type {struct preproc_location}
%define api.prefix {preproc_yy}
%define api.pure full
%define parse.error verbose
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 83038384..5a022708 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -79,6 +79,8 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_RS_INVALID_ROOT_PARAMETER_TYPE = 3002,
VKD3D_SHADER_ERROR_RS_INVALID_DESCRIPTOR_RANGE_TYPE = 3003,
VKD3D_SHADER_ERROR_RS_MIXED_DESCRIPTOR_RANGE_TYPES = 3004,
+
+ VKD3D_SHADER_ERROR_PP_INVALID_SYNTAX = 4000,
};
enum VKD3D_SHADER_INSTRUCTION_HANDLER
--
2.29.2
More information about the wine-devel
mailing list