From e64a143ff7cdded85bf13d8c856a09d30efed0f0 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 14 Mar 2016 19:03:05 +0100 Subject: [PATCH] tokenizer: Emit token in error vfunc --- gtk/gtkcssparser.c | 49 ++++++++++++++++++++++++++++++++++++ gtk/gtkcsstokenizer.c | 28 +++++++++++---------- gtk/gtkcsstokenizerprivate.h | 7 +++--- 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/gtk/gtkcssparser.c b/gtk/gtkcssparser.c index 44ff7bcfca..2a732e6b0f 100644 --- a/gtk/gtkcssparser.c +++ b/gtk/gtkcssparser.c @@ -20,6 +20,7 @@ #include "gtkcssparserprivate.h" #include "gtkcssdimensionvalueprivate.h" +#include "gtkcsstokenizerprivate.h" #include #include @@ -46,6 +47,52 @@ struct _GtkCssParser guint line; }; +#include "gtkcssstylesheetprivate.h" + +static void +do_the_tokenizer (const char *data) +{ +#if 0 + GtkCssTokenizer *tokenizer; + GtkCssToken token; + GBytes *bytes; + + bytes = g_bytes_new_static (data, strlen (data)); + tokenizer = gtk_css_tokenizer_new (bytes, NULL, NULL, NULL); + g_bytes_unref (bytes); + + for (gtk_css_tokenizer_read_token (tokenizer, &token); + token.type != GTK_CSS_TOKEN_EOF; + gtk_css_tokenizer_read_token (tokenizer, &token)) + { + char *s = gtk_css_token_to_string (&token); + g_print ("%3zu:%02zu %2d %s\n", + gtk_css_tokenizer_get_line (tokenizer), gtk_css_tokenizer_get_line_char (tokenizer), + token.type, s); + g_free (s); + gtk_css_token_clear (&token); + } + + gtk_css_tokenizer_unref (tokenizer); +#else + GtkCssStyleSheet *sheet; + GtkCssTokenSource *source; + GtkCssTokenizer *tokenizer; + GBytes *bytes; + + bytes = g_bytes_new_static (data, strlen (data)); + tokenizer = gtk_css_tokenizer_new (bytes, NULL, NULL, NULL); + source = gtk_css_token_source_new_for_tokenizer (tokenizer); + sheet = gtk_css_style_sheet_new (); + gtk_css_style_sheet_parse (sheet, source); + + g_object_unref (sheet); + gtk_css_token_source_unref (source); + gtk_css_tokenizer_unref (tokenizer); + g_bytes_unref (bytes); +#endif +} + GtkCssParser * _gtk_css_parser_new (const char *data, GFile *file, @@ -57,6 +104,8 @@ _gtk_css_parser_new (const char *data, g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL); + do_the_tokenizer (data); + parser = g_slice_new0 (GtkCssParser); parser->data = data; diff --git a/gtk/gtkcsstokenizer.c b/gtk/gtkcsstokenizer.c index 74cad73485..e26e70d5eb 100644 --- a/gtk/gtkcsstokenizer.c +++ b/gtk/gtkcsstokenizer.c @@ -504,12 +504,14 @@ gtk_css_tokenizer_get_line_char (GtkCssTokenizer *tokenizer) } static void -gtk_css_tokenizer_parse_error (GtkCssTokenizer *tokenizer, - const char *format, - ...) G_GNUC_PRINTF(2, 3); +gtk_css_tokenizer_parse_error (GtkCssTokenizer *tokenizer, + const GtkCssToken *token, + const char *format, + ...) G_GNUC_PRINTF(3, 4); static void -gtk_css_tokenizer_parse_error (GtkCssTokenizer *tokenizer, - const char *format, +gtk_css_tokenizer_parse_error (GtkCssTokenizer *tokenizer, + const GtkCssToken *token, + const char *format, ...) { GError *error; @@ -522,7 +524,7 @@ gtk_css_tokenizer_parse_error (GtkCssTokenizer *tokenizer, va_end (args); if (tokenizer->error_func) - tokenizer->error_func (tokenizer, error, tokenizer->user_data); + tokenizer->error_func (tokenizer, token, error, tokenizer->user_data); else g_print ("error: %s\n", error->message); @@ -854,24 +856,24 @@ gtk_css_tokenizer_read_url (GtkCssTokenizer *tokenizer, } else { - gtk_css_tokenizer_parse_error (tokenizer, "Whitespace only allowed at start and end of url"); gtk_css_tokenizer_read_bad_url (tokenizer, token); + gtk_css_tokenizer_parse_error (tokenizer, token, "Whitespace only allowed at start and end of url"); return; } } else if (is_non_printable (*tokenizer->data)) { - gtk_css_tokenizer_parse_error (tokenizer, "Nonprintable character 0x%02X in url", *tokenizer->data); gtk_css_tokenizer_read_bad_url (tokenizer, token); g_string_free (url, TRUE); + gtk_css_tokenizer_parse_error (tokenizer, token, "Nonprintable character 0x%02X in url", *tokenizer->data); return; } else if (*tokenizer->data == '"' || *tokenizer->data == '\'' || *tokenizer->data == '(') { - gtk_css_tokenizer_parse_error (tokenizer, "Invalid character %c in url", *tokenizer->data); gtk_css_tokenizer_read_bad_url (tokenizer, token); + gtk_css_tokenizer_parse_error (tokenizer, token, "Invalid character %c in url", *tokenizer->data); g_string_free (url, TRUE); return; } @@ -881,8 +883,8 @@ gtk_css_tokenizer_read_url (GtkCssTokenizer *tokenizer, } else if (*tokenizer->data == '\\') { - gtk_css_tokenizer_parse_error (tokenizer, "Newline may not follow '\' escape character"); gtk_css_tokenizer_read_bad_url (tokenizer, token); + gtk_css_tokenizer_parse_error (tokenizer, token, "Newline may not follow '\' escape character"); g_string_free (url, TRUE); return; } @@ -1092,9 +1094,9 @@ gtk_css_tokenizer_read_string (GtkCssTokenizer *tokenizer, } else if (is_newline (*tokenizer->data)) { - gtk_css_tokenizer_parse_error (tokenizer, "Newlines inside strings must be escaped"); g_string_free (string, TRUE); gtk_css_token_init (token, GTK_CSS_TOKEN_BAD_STRING); + gtk_css_tokenizer_parse_error (tokenizer, token, "Newlines inside strings must be escaped"); return; } else @@ -1125,7 +1127,7 @@ gtk_css_tokenizer_read_comment (GtkCssTokenizer *tokenizer, } gtk_css_token_init (token, GTK_CSS_TOKEN_COMMENT); - gtk_css_tokenizer_parse_error (tokenizer, "Comment not terminated at end of document."); + gtk_css_tokenizer_parse_error (tokenizer, token, "Comment not terminated at end of document."); } static void @@ -1292,8 +1294,8 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer, } else { - gtk_css_tokenizer_parse_error (tokenizer, "Newline may not follow '\' escape character"); gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, '\\'); + gtk_css_tokenizer_parse_error (tokenizer, token, "Newline may not follow '\' escape character"); } break; diff --git a/gtk/gtkcsstokenizerprivate.h b/gtk/gtkcsstokenizerprivate.h index e9dab165b8..4dba797b4f 100644 --- a/gtk/gtkcsstokenizerprivate.h +++ b/gtk/gtkcsstokenizerprivate.h @@ -73,9 +73,10 @@ typedef struct _GtkCssDelimToken GtkCssDelimToken; typedef struct _GtkCssNumberToken GtkCssNumberToken; typedef struct _GtkCssDimensionToken GtkCssDimensionToken; -typedef void (* GtkCssTokenizerErrorFunc) (GtkCssTokenizer *parser, - const GError *error, - gpointer user_data); +typedef void (* GtkCssTokenizerErrorFunc) (GtkCssTokenizer *parser, + const GtkCssToken *token, + const GError *error, + gpointer user_data); struct _GtkCssStringToken { GtkCssTokenType type;