From a2aaf2b90ed8740391c4e0002a8a97ebe0cb6d54 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 27 Sep 2017 17:18:53 +0200 Subject: [PATCH] gskslpreprocessor: Return fatalness of parsing Instead of relying on parsing functions to return FALSE on error, we record that parsing failed inside the preprocessor object and continue parsing (potentially using dummy objects as the result). That way, we keep parsing and can emit potentially useful error messages for the rest of the document. Now we just need to implement that mentality. --- gsk/gskslcompiler.c | 4 +++- gsk/gskslpreprocessor.c | 9 +++++++++ gsk/gskslpreprocessorprivate.h | 1 + gsk/gskslprogram.c | 17 +++++++---------- gsk/gskslprogramprivate.h | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/gsk/gskslcompiler.c b/gsk/gskslcompiler.c index 1e9cfead17..b473cecf1d 100644 --- a/gsk/gskslcompiler.c +++ b/gsk/gskslcompiler.c @@ -196,7 +196,9 @@ gsk_sl_compiler_compile (GskSlCompiler *compiler, preproc = gsk_sl_preprocessor_new (compiler, source); - if (!gsk_sl_program_parse (program, preproc)) + gsk_sl_program_parse (program, preproc); + + if (gsk_sl_preprocessor_has_fatal_error (preproc)) { g_object_unref (program); program = NULL; diff --git a/gsk/gskslpreprocessor.c b/gsk/gskslpreprocessor.c index 98c2fd5fce..ca39e79d43 100644 --- a/gsk/gskslpreprocessor.c +++ b/gsk/gskslpreprocessor.c @@ -39,6 +39,7 @@ struct _GskSlPreprocessor GskSlTokenizer *tokenizer; GArray *tokens; GHashTable *defines; + gboolean fatal_error; }; /* API */ @@ -111,6 +112,12 @@ gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc) g_slice_free (GskSlPreprocessor, preproc); } +gboolean +gsk_sl_preprocessor_has_fatal_error (GskSlPreprocessor *preproc) +{ + return preproc->fatal_error; +} + static gboolean gsk_sl_preprocessor_next_token (GskSlPreprocessor *preproc, GskSlPpToken *pp, @@ -375,6 +382,8 @@ gsk_sl_preprocessor_emit_error (GskSlPreprocessor *preproc, const GskCodeLocation *location, const GError *error) { + preproc->fatal_error |= fatal; + g_printerr ("%3zu:%2zu: %s: %s\n", location->lines + 1, location->line_bytes, fatal ? "error" : "warn", diff --git a/gsk/gskslpreprocessorprivate.h b/gsk/gskslpreprocessorprivate.h index 8fcb429c3d..b6544cca73 100644 --- a/gsk/gskslpreprocessorprivate.h +++ b/gsk/gskslpreprocessorprivate.h @@ -31,6 +31,7 @@ GskSlPreprocessor * gsk_sl_preprocessor_new (GskSlCompiler GskSlPreprocessor * gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc); void gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc); +gboolean gsk_sl_preprocessor_has_fatal_error (GskSlPreprocessor *preproc); const GskSlToken * gsk_sl_preprocessor_get (GskSlPreprocessor *preproc); const GskCodeLocation * gsk_sl_preprocessor_get_location (GskSlPreprocessor *preproc); void gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc, diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c index 8f9c3edb60..d1dea506cb 100644 --- a/gsk/gskslprogram.c +++ b/gsk/gskslprogram.c @@ -136,7 +136,7 @@ gsk_sl_program_parse_variable (GskSlProgram *program, return TRUE; } -static gboolean +static void gsk_sl_program_parse_declaration (GskSlProgram *program, GskSlScope *scope, GskSlPreprocessor *preproc) @@ -155,7 +155,7 @@ gsk_sl_program_parse_declaration (GskSlProgram *program, if (type == NULL) { gsk_sl_preprocessor_consume (preproc, program); - return FALSE; + return; } token = gsk_sl_preprocessor_get (preproc); @@ -170,13 +170,13 @@ gsk_sl_program_parse_declaration (GskSlProgram *program, gsk_sl_preprocessor_consume (preproc, program); } gsk_sl_type_unref (type); - return success; + return; } else if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER)) { gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected a variable name"); gsk_sl_type_unref (type); - return FALSE; + return; } name = g_strdup (token->str); @@ -204,24 +204,21 @@ gsk_sl_program_parse_declaration (GskSlProgram *program, g_free (name); - return success; + return; } -gboolean +void gsk_sl_program_parse (GskSlProgram *program, GskSlPreprocessor *preproc) { const GskSlToken *token; - gboolean success = TRUE; for (token = gsk_sl_preprocessor_get (preproc); !gsk_sl_token_is (token, GSK_SL_TOKEN_EOF); token = gsk_sl_preprocessor_get (preproc)) { - success &= gsk_sl_program_parse_declaration (program, program->scope, preproc); + gsk_sl_program_parse_declaration (program, program->scope, preproc); } - - return success; } void diff --git a/gsk/gskslprogramprivate.h b/gsk/gskslprogramprivate.h index 9b24b8eda5..4d9ec97c7b 100644 --- a/gsk/gskslprogramprivate.h +++ b/gsk/gskslprogramprivate.h @@ -24,7 +24,7 @@ G_BEGIN_DECLS -gboolean gsk_sl_program_parse (GskSlProgram *program, +void gsk_sl_program_parse (GskSlProgram *program, GskSlPreprocessor *preproc); G_END_DECLS