tokenizer: Emit token in error vfunc

This commit is contained in:
Benjamin Otte
2016-03-14 19:03:05 +01:00
parent 840d347d59
commit e64a143ff7
3 changed files with 68 additions and 16 deletions

View File

@@ -20,6 +20,7 @@
#include "gtkcssparserprivate.h"
#include "gtkcssdimensionvalueprivate.h"
#include "gtkcsstokenizerprivate.h"
#include <errno.h>
#include <string.h>
@@ -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;

View File

@@ -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;

View File

@@ -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;