css: Make property parsing functions take a css parser

Instead of reading a string and then passing that in, let the parse
functions use the full power of the parser.
This commit is contained in:
Benjamin Otte 2011-05-18 18:32:22 +02:00
parent 03e84b7ee3
commit d2ef71627b
5 changed files with 419 additions and 655 deletions

View File

@ -107,6 +107,15 @@ _gtk_css_parser_get_position (GtkCssParser *parser)
return parser->data - parser->line_start;
}
void
_gtk_css_parser_take_error (GtkCssParser *parser,
GError *error)
{
parser->error_func (parser, error, parser->user_data);
g_error_free (error);
}
void
_gtk_css_parser_error (GtkCssParser *parser,
const char *format,
@ -122,9 +131,7 @@ _gtk_css_parser_error (GtkCssParser *parser,
format, args);
va_end (args);
parser->error_func (parser, error, parser->user_data);
g_error_free (error);
_gtk_css_parser_take_error (parser, error);
}
static gboolean

View File

@ -35,6 +35,8 @@ GtkCssParser * _gtk_css_parser_new (const char *data,
gpointer user_data);
void _gtk_css_parser_free (GtkCssParser *parser);
void _gtk_css_parser_take_error (GtkCssParser *parser,
GError *error);
void _gtk_css_parser_error (GtkCssParser *parser,
const char *format,
...) G_GNUC_PRINTF (2, 3);

View File

@ -1187,6 +1187,20 @@ gtk_css_provider_get_style (GtkStyleProvider *provider,
return props;
}
static void
gtk_css_provider_parser_error (GtkCssParser *parser,
const GError *error,
gpointer user_data)
{
GtkCssProvider *provider = user_data;
gtk_css_provider_take_error_full (provider,
NULL,
_gtk_css_parser_get_line (parser),
_gtk_css_parser_get_position (parser),
g_error_copy (error));
}
static gboolean
gtk_css_provider_get_style_property (GtkStyleProvider *provider,
GtkWidgetPath *path,
@ -1227,21 +1241,20 @@ gtk_css_provider_get_style_property (GtkStyleProvider *provider,
((selector_state & state) != 0 &&
(selector_state & ~(state)) == 0)))
{
GError *error = NULL;
GtkCssParser *parser;
found = _gtk_css_value_from_string (value,
NULL,
g_value_get_string (val),
&error);
parser = _gtk_css_parser_new (g_value_get_string (val),
gtk_css_provider_parser_error,
provider);
found = _gtk_css_value_parse (value,
parser,
NULL);
_gtk_css_parser_free (parser);
if (found)
break;
/* error location should be _way_ better */
gtk_css_provider_take_error_full (GTK_CSS_PROVIDER (provider),
NULL,
0, 0,
error);
}
}
@ -1902,7 +1915,7 @@ parse_declaration (GtkCssScanner *scanner,
{
GtkStylePropertyParser parse_func = NULL;
GParamSpec *pspec = NULL;
char *name, *value_str;
char *name;
name = _gtk_css_parser_try_ident (scanner->parser, TRUE);
if (name == NULL)
@ -1930,14 +1943,6 @@ parse_declaration (GtkCssScanner *scanner,
return;
}
value_str = _gtk_css_parser_read_value (scanner->parser);
if (value_str == NULL)
{
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
g_free (name);
return;
}
if (pspec)
{
GValue *val;
@ -1947,7 +1952,7 @@ parse_declaration (GtkCssScanner *scanner,
val = g_slice_new0 (GValue);
g_value_init (val, pspec->value_type);
if (strcmp (value_str, "none") == 0)
if (_gtk_css_parser_try (scanner->parser, "none", TRUE))
{
/* Insert the default value, so it has an opportunity
* to override other style providers when merged
@ -1958,47 +1963,80 @@ parse_declaration (GtkCssScanner *scanner,
else if (parse_func)
{
GError *error = NULL;
char *value_str;
value_str = _gtk_css_parser_read_value (scanner->parser);
if (value_str == NULL)
{
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
return;
}
if ((*parse_func) (value_str, val, &error))
gtk_css_ruleset_add (ruleset, pspec, val);
else
gtk_css_provider_take_error (scanner->provider, scanner, error);
g_free (value_str);
}
else
{
GError *error = NULL;
if (_gtk_css_value_from_string (val,
gtk_css_scanner_get_base_url (scanner),
value_str,
&error))
if (_gtk_css_value_parse (val,
scanner->parser,
gtk_css_scanner_get_base_url (scanner)))
{
gtk_css_ruleset_add (ruleset, pspec, val);
if (_gtk_css_parser_begins_with (scanner->parser, ';') ||
_gtk_css_parser_begins_with (scanner->parser, '}') ||
_gtk_css_parser_is_eof (scanner->parser))
{
gtk_css_ruleset_add (ruleset, pspec, val);
}
else
{
gtk_css_provider_error_literal (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
"Junk at end of value");
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
g_value_unset (val);
g_slice_free (GValue, val);
return;
}
}
else
{
g_value_unset (val);
g_slice_free (GValue, val);
gtk_css_provider_take_error (scanner->provider, scanner, error);
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
return;
}
}
}
else if (name[0] == '-')
{
GValue *val;
char *value_str;
val = g_slice_new0 (GValue);
g_value_init (val, G_TYPE_STRING);
g_value_set_string (val, value_str);
value_str = _gtk_css_parser_read_value (scanner->parser);
if (value_str)
{
GValue *val;
gtk_css_ruleset_add_style (ruleset, name, val);
val = g_slice_new0 (GValue);
g_value_init (val, G_TYPE_STRING);
g_value_take_string (val, value_str);
gtk_css_ruleset_add_style (ruleset, name, val);
}
else
{
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
return;
}
}
else
g_free (name);
g_free (value_str);
check_for_semicolon:
if (!_gtk_css_parser_try (scanner->parser, ";", TRUE))
{

File diff suppressed because it is too large Load Diff

View File

@ -20,20 +20,17 @@
#ifndef __GTK_CSS_STRINGFUNCS_PRIVATE_H__
#define __GTK_CSS_STRINGFUNCS_PRIVATE_H__
#include <gtk/gtksymboliccolor.h>
#include "gtkcssparserprivate.h"
G_BEGIN_DECLS
gboolean _gtk_css_value_from_string (GValue *value,
GFile *base,
const char *string,
GError **error);
gboolean _gtk_css_value_parse (GValue *value,
GtkCssParser *parser,
GFile *base);
char * _gtk_css_value_to_string (const GValue *value);
GFile * _gtk_css_parse_url (GFile *base,
const char *str,
char **end,
GError **error);
GFile * _gtk_css_parse_url (GtkCssParser *parser,
GFile *base);
G_END_DECLS