From 44843c753301db0e8f8343745777479465f34ccc Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 22 Jul 2009 15:06:49 -0700 Subject: [PATCH] parser: Clean up generation of error strings during assembly --- src/mesa/shader/program_parse.tab.c | 61 +++++++++++++++++++++++++++-- src/mesa/shader/program_parse.y | 61 +++++++++++++++++++++++++++-- src/mesa/shader/program_parser.h | 11 +++--- 3 files changed, 120 insertions(+), 13 deletions(-) diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c index cb5fa7cd71c..8f8dae92238 100644 --- a/src/mesa/shader/program_parse.tab.c +++ b/src/mesa/shader/program_parse.tab.c @@ -4801,15 +4801,57 @@ initialize_symbol_from_const(struct gl_program *prog, } +char * +make_error_string(const char *fmt, ...) +{ + int length; + char *str; + va_list args; + + va_start(args, fmt); + + /* Call vsnprintf once to determine how large the final string is. Call it + * again to do the actual formatting. from the vsnprintf manual page: + * + * Upon successful return, these functions return the number of + * characters printed (not including the trailing '\0' used to end + * output to strings). + */ + length = 1 + vsnprintf(NULL, 0, fmt, args); + + str = _mesa_malloc(length); + if (str) { + vsnprintf(str, length, fmt, args); + } + + va_end(args); + + return str; +} + + void yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) { - (void) state; + char *err_str; + - fprintf(stderr, "line %u, char %u: error: %s\n", locp->first_line, - locp->first_column, s); + err_str = make_error_string("glProgramStringARB(%s)\n", s); + if (err_str) { + _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str); + _mesa_free(err_str); + } + + err_str = make_error_string("line %u, char %u: error: %s\n", + locp->first_line, locp->first_column, s); + _mesa_set_program_error(state->ctx, locp->position, err_str); + + if (err_str) { + _mesa_free(err_str); + } } + GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, GLsizei len, struct asm_parser_state *state) @@ -4819,6 +4861,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, unsigned i; GLubyte *strz; + state->ctx = ctx; state->prog->Target = target; state->prog->Parameters = _mesa_new_parameter_list(); @@ -4877,8 +4920,18 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, _mesa_program_lexer_dtor(state->scanner); + if (ctx->Program.ErrorPos != -1) { + return GL_FALSE; + } + if (! _mesa_layout_parameters(state)) { - fprintf(stderr, "error: layout\n"); + struct YYLTYPE loc; + + loc.first_line = 0; + loc.first_column = 0; + loc.position = len; + + yyerror(& loc, state, "invalid PARAM usage"); return GL_FALSE; } diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y index fe9022b1218..6881562902e 100644 --- a/src/mesa/shader/program_parse.y +++ b/src/mesa/shader/program_parse.y @@ -2017,15 +2017,57 @@ initialize_symbol_from_const(struct gl_program *prog, } +char * +make_error_string(const char *fmt, ...) +{ + int length; + char *str; + va_list args; + + va_start(args, fmt); + + /* Call vsnprintf once to determine how large the final string is. Call it + * again to do the actual formatting. from the vsnprintf manual page: + * + * Upon successful return, these functions return the number of + * characters printed (not including the trailing '\0' used to end + * output to strings). + */ + length = 1 + vsnprintf(NULL, 0, fmt, args); + + str = _mesa_malloc(length); + if (str) { + vsnprintf(str, length, fmt, args); + } + + va_end(args); + + return str; +} + + void yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) { - (void) state; + char *err_str; + - fprintf(stderr, "line %u, char %u: error: %s\n", locp->first_line, - locp->first_column, s); + err_str = make_error_string("glProgramStringARB(%s)\n", s); + if (err_str) { + _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str); + _mesa_free(err_str); + } + + err_str = make_error_string("line %u, char %u: error: %s\n", + locp->first_line, locp->first_column, s); + _mesa_set_program_error(state->ctx, locp->position, err_str); + + if (err_str) { + _mesa_free(err_str); + } } + GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, GLsizei len, struct asm_parser_state *state) @@ -2035,6 +2077,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, unsigned i; GLubyte *strz; + state->ctx = ctx; state->prog->Target = target; state->prog->Parameters = _mesa_new_parameter_list(); @@ -2093,8 +2136,18 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, _mesa_program_lexer_dtor(state->scanner); + if (ctx->Program.ErrorPos != -1) { + return GL_FALSE; + } + if (! _mesa_layout_parameters(state)) { - fprintf(stderr, "error: layout\n"); + struct YYLTYPE loc; + + loc.first_line = 0; + loc.first_column = 0; + loc.position = len; + + yyerror(& loc, state, "invalid PARAM usage"); return GL_FALSE; } diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h index 20190470ea9..aeb2efd7ab6 100644 --- a/src/mesa/shader/program_parser.h +++ b/src/mesa/shader/program_parser.h @@ -24,6 +24,11 @@ #include "main/config.h" +#ifndef MTYPES_H +struct __GLcontextRec; +typedef struct __GLcontextRec GLcontext; +#endif + enum asm_type { at_none, at_address, @@ -119,6 +124,7 @@ struct asm_instruction { struct asm_parser_state { + GLcontext *ctx; struct gl_program *prog; /** @@ -213,11 +219,6 @@ typedef struct YYLTYPE { #define YYLTYPE_IS_TRIVIAL 1 -#ifndef MTYPES_H -struct __GLcontextRec; -typedef struct __GLcontextRec GLcontext; -#endif - extern GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, GLsizei len, struct asm_parser_state *state); -- 2.30.2