Merge branch 'matthiasc/for-main' into 'main'

css: Avoid some allocations

See merge request GNOME/gtk!5413
This commit is contained in:
Matthias Clasen 2023-01-12 15:20:49 +00:00
commit b92e52bf0e
12 changed files with 146 additions and 184 deletions

View File

@ -586,7 +586,7 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
{
const char *s = token->string.string;
const char *s = gtk_css_token_get_string (token);
switch (strlen (s))
{
@ -637,13 +637,13 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
{
*rgba = (GdkRGBA) { 0, 0, 0, 0 };
}
else if (gdk_rgba_parse (rgba, token->string.string))
else if (gdk_rgba_parse (rgba, gtk_css_token_get_string (token)))
{
/* everything's fine */
}
else
{
gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", token->string.string);
gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", gtk_css_token_get_string (token));
return FALSE;
}

View File

@ -418,7 +418,7 @@ parse_string (GtkCssParser *parser,
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_STRING))
return FALSE;
s = g_strdup (token->string.string);
s = g_strdup (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (parser);
g_free (*(char **) out_string);
@ -931,7 +931,7 @@ parse_declarations (GtkCssParser *parser,
{
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
gtk_css_parser_error_syntax (parser, "No variable named \"%s\"",
gtk_css_parser_get_token (parser)->string.string);
gtk_css_token_get_string (gtk_css_parser_get_token (parser)));
else
gtk_css_parser_error_syntax (parser, "Expected a variable name");
}
@ -1894,7 +1894,7 @@ parse_node (GtkCssParser *parser,
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
gtk_css_parser_error_value (parser, "\"%s\" is not a valid node name",
gtk_css_parser_get_token (parser)->string.string);
gtk_css_token_get_string (gtk_css_parser_get_token (parser)));
else
gtk_css_parser_error_syntax (parser, "Expected a node name");

View File

@ -1,72 +0,0 @@
/* GSK - The GIMP Toolkit
* Copyright (C) 2019 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkcsslocationprivate.h"
/**
* GtkCssLocation:
* @bytes: number of bytes parsed since the beginning
* @chars: number of characters parsed since the beginning
* @lines: number of full lines that have been parsed. If you want to
* display this as a line number, you need to add 1 to this.
* @line_bytes: Number of bytes parsed since the last line break
* @line_chars: Number of characters parsed since the last line break
*
* Represents a location in a file or other source of data parsed
* by the CSS engine.
*
* The @bytes and @line_bytes offsets are meant to be used to
* programmatically match data. The @lines and @line_chars offsets
* can be used for printing the location in a file.
*
* Note that the @lines parameter starts from 0 and is increased
* whenever a CSS line break is encountered. (CSS defines the C character
* sequences "\r\n", "\r", "\n" and "\f" as newlines.)
* If your document uses different rules for line breaking, you might want
* run into problems here.
*/
void
gtk_css_location_init (GtkCssLocation *location)
{
memset (location, 0, sizeof (GtkCssLocation));
}
void
gtk_css_location_advance (GtkCssLocation *location,
gsize bytes,
gsize chars)
{
location->bytes += bytes;
location->chars += chars;
location->line_bytes += bytes;
location->line_chars += chars;
}
void
gtk_css_location_advance_newline (GtkCssLocation *location,
gboolean is_windows)
{
gtk_css_location_advance (location, is_windows ? 2 : 1, is_windows ? 2 : 1);
location->lines++;
location->line_bytes = 0;
location->line_chars = 0;
}

View File

@ -25,13 +25,33 @@
G_BEGIN_DECLS
void gtk_css_location_init (GtkCssLocation *location);
static inline void
gtk_css_location_init (GtkCssLocation *location)
{
memset (location, 0, sizeof (GtkCssLocation));
}
void gtk_css_location_advance (GtkCssLocation *location,
gsize bytes,
gsize chars);
void gtk_css_location_advance_newline (GtkCssLocation *location,
gboolean is_windows);
static inline void
gtk_css_location_advance (GtkCssLocation *location,
gsize bytes,
gsize chars)
{
location->bytes += bytes;
location->chars += chars;
location->line_bytes += bytes;
location->line_chars += chars;
}
static inline void
gtk_css_location_advance_newline (GtkCssLocation *location,
gboolean is_windows)
{
location->bytes += is_windows ? 2 : 1;
location->chars += is_windows ? 2 : 1;
location->line_bytes = 0;
location->line_chars = 0;
location->lines++;
}
G_END_DECLS

View File

@ -642,13 +642,13 @@ gtk_css_parser_consume_function (GtkCssParser *self,
{
const GtkCssToken *token;
gboolean result = FALSE;
char *function_name;
char function_name[64];
guint arg;
token = gtk_css_parser_get_token (self);
g_return_val_if_fail (gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION), FALSE);
function_name = g_strdup (token->string.string);
g_strlcpy (function_name, gtk_css_token_get_string (token), 64);
gtk_css_parser_start_block (self);
arg = 0;
@ -691,7 +691,6 @@ gtk_css_parser_consume_function (GtkCssParser *self,
}
gtk_css_parser_end_block (self);
g_free (function_name);
return result;
}
@ -734,7 +733,7 @@ gtk_css_parser_has_ident (GtkCssParser *self,
token = gtk_css_parser_get_token (self);
return gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
g_ascii_strcasecmp (token->string.string, ident) == 0;
g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0;
}
gboolean
@ -756,7 +755,7 @@ gtk_css_parser_has_integer (GtkCssParser *self)
* Checks if the next token is a function with the given @name.
*
* Returns: %TRUE if the next token is a function with the given @name
**/
*/
gboolean
gtk_css_parser_has_function (GtkCssParser *self,
const char *name)
@ -766,7 +765,7 @@ gtk_css_parser_has_function (GtkCssParser *self,
token = gtk_css_parser_get_token (self);
return gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION) &&
g_ascii_strcasecmp (token->string.string, name) == 0;
g_ascii_strcasecmp (gtk_css_token_get_string (token), name) == 0;
}
/**
@ -819,7 +818,7 @@ gtk_css_parser_try_ident (GtkCssParser *self,
token = gtk_css_parser_get_token (self);
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) ||
g_ascii_strcasecmp (token->string.string, ident) != 0)
g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) != 0)
return FALSE;
gtk_css_parser_consume_token (self);
@ -846,7 +845,7 @@ gtk_css_parser_try_at_keyword (GtkCssParser *self,
token = gtk_css_parser_get_token (self);
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_AT_KEYWORD) ||
g_ascii_strcasecmp (token->string.string, keyword) != 0)
g_ascii_strcasecmp (gtk_css_token_get_string (token), keyword) != 0)
return FALSE;
gtk_css_parser_consume_token (self);
@ -908,7 +907,7 @@ gtk_css_parser_consume_ident (GtkCssParser *self)
return NULL;
}
ident = g_strdup (token->string.string);
ident = g_strdup (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (self);
return ident;
@ -939,7 +938,7 @@ gtk_css_parser_consume_string (GtkCssParser *self)
return NULL;
}
ident = g_strdup (token->string.string);
ident = g_strdup (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (self);
return ident;
@ -980,7 +979,7 @@ gtk_css_parser_consume_url (GtkCssParser *self)
if (gtk_css_token_is (token, GTK_CSS_TOKEN_URL))
{
url = g_strdup (token->string.string);
url = g_strdup (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (self);
}
else if (gtk_css_token_is_function (token, "url"))

View File

@ -50,18 +50,14 @@ gtk_css_token_clear (GtkCssToken *token)
case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
case GTK_CSS_TOKEN_HASH_ID:
case GTK_CSS_TOKEN_URL:
g_free (token->string.string);
if (token->string.len >= 16)
g_free (token->string.u.string);
break;
case GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION:
case GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION:
case GTK_CSS_TOKEN_SIGNED_DIMENSION:
case GTK_CSS_TOKEN_SIGNLESS_DIMENSION:
g_free (token->dimension.dimension);
break;
default:
g_assert_not_reached ();
case GTK_CSS_TOKEN_EOF:
case GTK_CSS_TOKEN_WHITESPACE:
case GTK_CSS_TOKEN_OPEN_PARENS:
@ -91,6 +87,9 @@ gtk_css_token_clear (GtkCssToken *token)
case GTK_CSS_TOKEN_BAD_URL:
case GTK_CSS_TOKEN_COMMENT:
break;
default:
g_assert_not_reached ();
}
token->type = GTK_CSS_TOKEN_EOF;
@ -296,7 +295,7 @@ gtk_css_token_is_ident (const GtkCssToken *token,
const char *ident)
{
return gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)
&& (g_ascii_strcasecmp (token->string.string, ident) == 0);
&& (g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0);
}
gboolean
@ -304,7 +303,7 @@ gtk_css_token_is_function (const GtkCssToken *token,
const char *ident)
{
return gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION)
&& (g_ascii_strcasecmp (token->string.string, ident) == 0);
&& (g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0);
}
gboolean
@ -324,33 +323,33 @@ gtk_css_token_print (const GtkCssToken *token,
switch (token->type)
{
case GTK_CSS_TOKEN_STRING:
append_string (string, token->string.string);
append_string (string, gtk_css_token_get_string (token));
break;
case GTK_CSS_TOKEN_IDENT:
append_ident (string, token->string.string);
append_ident (string, gtk_css_token_get_string (token));
break;
case GTK_CSS_TOKEN_URL:
g_string_append (string, "url(");
append_ident (string, token->string.string);
append_ident (string, gtk_css_token_get_string (token));
g_string_append (string, ")");
break;
case GTK_CSS_TOKEN_FUNCTION:
append_ident (string, token->string.string);
append_ident (string, gtk_css_token_get_string (token));
g_string_append_c (string, '(');
break;
case GTK_CSS_TOKEN_AT_KEYWORD:
g_string_append_c (string, '@');
append_ident (string, token->string.string);
append_ident (string, gtk_css_token_get_string (token));
break;
case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
case GTK_CSS_TOKEN_HASH_ID:
g_string_append_c (string, '#');
append_ident (string, token->string.string);
append_ident (string, gtk_css_token_get_string (token));
break;
case GTK_CSS_TOKEN_DELIM:
@ -492,7 +491,7 @@ gtk_css_token_to_string (const GtkCssToken *token)
static void
gtk_css_token_init_string (GtkCssToken *token,
GtkCssTokenType type,
char *string)
GString *string)
{
token->type = type;
@ -505,7 +504,11 @@ gtk_css_token_init_string (GtkCssToken *token,
case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
case GTK_CSS_TOKEN_HASH_ID:
case GTK_CSS_TOKEN_URL:
token->string.string = string;
token->string.len = string->len;
if (string->len < 16)
g_strlcpy (token->string.u.buf, string->str, 16);
else
token->string.u.string = g_strdup (string->str);
break;
default:
g_assert_not_reached ();
@ -545,7 +548,7 @@ static void
gtk_css_token_init_dimension (GtkCssToken *token,
GtkCssTokenType type,
double value,
char *dimension)
GString *string)
{
token->type = type;
@ -556,7 +559,7 @@ gtk_css_token_init_dimension (GtkCssToken *token,
case GTK_CSS_TOKEN_SIGNED_DIMENSION:
case GTK_CSS_TOKEN_SIGNLESS_DIMENSION:
token->dimension.value = value;
token->dimension.dimension = dimension;
g_strlcpy (token->dimension.dimension, string->str, 8);
break;
default:
g_assert_not_reached ();
@ -630,7 +633,7 @@ gtk_css_tokenizer_parse_error (GError **error,
va_end (args);
}
static gboolean
static inline gboolean
is_newline (char c)
{
return c == '\n'
@ -638,7 +641,7 @@ is_newline (char c)
|| c == '\f';
}
static gboolean
static inline gboolean
is_whitespace (char c)
{
return is_newline (c)
@ -646,13 +649,13 @@ is_whitespace (char c)
|| c == ' ';
}
static gboolean
static inline gboolean
is_multibyte (char c)
{
return c & 0x80;
}
static gboolean
static inline gboolean
is_name_start (char c)
{
return is_multibyte (c)
@ -660,7 +663,7 @@ is_name_start (char c)
|| c == '_';
}
static gboolean
static inline gboolean
is_name (char c)
{
return is_name_start (c)
@ -668,7 +671,7 @@ is_name (char c)
|| c == '-';
}
static gboolean
static inline gboolean
is_non_printable (char c)
{
return (c >= 0 && c <= 0x08)
@ -678,7 +681,7 @@ is_non_printable (char c)
|| c == 0x7F;
}
static gboolean
static inline gboolean
is_valid_escape (const char *data,
const char *end)
{
@ -703,7 +706,7 @@ gtk_css_tokenizer_remaining (GtkCssTokenizer *tokenizer)
return tokenizer->end - tokenizer->data;
}
static gboolean
static inline gboolean
gtk_css_tokenizer_has_valid_escape (GtkCssTokenizer *tokenizer)
{
return is_valid_escape (tokenizer->data, tokenizer->end);
@ -875,7 +878,7 @@ gtk_css_tokenizer_read_escape (GtkCssTokenizer *tokenizer)
return value;
}
static char *
static void
gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
{
g_string_set_size (tokenizer->name_buffer, 0);
@ -911,8 +914,6 @@ gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
}
}
while (tokenizer->data != tokenizer->end);
return g_strndup (tokenizer->name_buffer->str, tokenizer->name_buffer->len);
}
static void
@ -1005,7 +1006,8 @@ gtk_css_tokenizer_read_url (GtkCssTokenizer *tokenizer,
}
}
gtk_css_token_init_string (token, GTK_CSS_TOKEN_URL, g_string_free (url, FALSE));
gtk_css_token_init_string (token, GTK_CSS_TOKEN_URL, url);
g_string_free (url, TRUE);
return TRUE;
}
@ -1015,12 +1017,12 @@ gtk_css_tokenizer_read_ident_like (GtkCssTokenizer *tokenizer,
GtkCssToken *token,
GError **error)
{
char *name = gtk_css_tokenizer_read_name (tokenizer);
gtk_css_tokenizer_read_name (tokenizer);
if (*tokenizer->data == '(')
{
gtk_css_tokenizer_consume_ascii (tokenizer);
if (g_ascii_strcasecmp (name, "url") == 0)
if (g_ascii_strcasecmp (tokenizer->name_buffer->str, "url") == 0)
{
const char *data = tokenizer->data;
@ -1028,18 +1030,15 @@ gtk_css_tokenizer_read_ident_like (GtkCssTokenizer *tokenizer,
data++;
if (*data != '"' && *data != '\'')
{
g_free (name);
return gtk_css_tokenizer_read_url (tokenizer, token, error);
}
return gtk_css_tokenizer_read_url (tokenizer, token, error);
}
gtk_css_token_init_string (token, GTK_CSS_TOKEN_FUNCTION, name);
gtk_css_token_init_string (token, GTK_CSS_TOKEN_FUNCTION, tokenizer->name_buffer);
return TRUE;
}
else
{
gtk_css_token_init_string (token, GTK_CSS_TOKEN_IDENT, name);
gtk_css_token_init_string (token, GTK_CSS_TOKEN_IDENT, tokenizer->name_buffer);
return TRUE;
}
}
@ -1129,7 +1128,8 @@ gtk_css_tokenizer_read_numeric (GtkCssTokenizer *tokenizer,
else
type = has_sign ? GTK_CSS_TOKEN_SIGNED_DIMENSION : GTK_CSS_TOKEN_SIGNLESS_DIMENSION;
gtk_css_token_init_dimension (token, type, value, gtk_css_tokenizer_read_name (tokenizer));
gtk_css_tokenizer_read_name (tokenizer);
gtk_css_token_init_dimension (token, type, value, tokenizer->name_buffer);
}
else if (gtk_css_tokenizer_remaining (tokenizer) > 0 && *tokenizer->data == '%')
{
@ -1145,7 +1145,7 @@ gtk_css_tokenizer_read_numeric (GtkCssTokenizer *tokenizer,
else
type = has_sign ? GTK_CSS_TOKEN_SIGNED_NUMBER : GTK_CSS_TOKEN_SIGNLESS_NUMBER;
gtk_css_token_init_number (token, type,value);
gtk_css_token_init_number (token, type, value);
}
}
@ -1196,7 +1196,8 @@ gtk_css_tokenizer_read_string (GtkCssTokenizer *tokenizer,
GtkCssToken *token,
GError **error)
{
GString *string = g_string_new (NULL);
g_string_set_size (tokenizer->name_buffer, 0);
char end = *tokenizer->data;
gtk_css_tokenizer_consume_ascii (tokenizer);
@ -1222,23 +1223,22 @@ gtk_css_tokenizer_read_string (GtkCssTokenizer *tokenizer,
}
else
{
g_string_append_unichar (string, gtk_css_tokenizer_read_escape (tokenizer));
g_string_append_unichar (tokenizer->name_buffer, gtk_css_tokenizer_read_escape (tokenizer));
}
}
else if (is_newline (*tokenizer->data))
{
g_string_free (string, TRUE);
gtk_css_token_init (token, GTK_CSS_TOKEN_BAD_STRING);
gtk_css_tokenizer_parse_error (error, "Newlines inside strings must be escaped");
return FALSE;
}
else
{
gtk_css_tokenizer_consume_char (tokenizer, string);
gtk_css_tokenizer_consume_char (tokenizer, tokenizer->name_buffer);
}
}
gtk_css_token_init_string (token, GTK_CSS_TOKEN_STRING, g_string_free (string, FALSE));
gtk_css_token_init_string (token, GTK_CSS_TOKEN_STRING, tokenizer->name_buffer);
return TRUE;
}
@ -1322,9 +1322,8 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
else
type = GTK_CSS_TOKEN_HASH_UNRESTRICTED;
gtk_css_token_init_string (token,
type,
gtk_css_tokenizer_read_name (tokenizer));
gtk_css_tokenizer_read_name (tokenizer);
gtk_css_token_init_string (token, type, tokenizer->name_buffer);
}
else
{
@ -1404,9 +1403,8 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
gtk_css_tokenizer_consume_ascii (tokenizer);
if (gtk_css_tokenizer_has_identifier (tokenizer))
{
gtk_css_token_init_string (token,
GTK_CSS_TOKEN_AT_KEYWORD,
gtk_css_tokenizer_read_name (tokenizer));
gtk_css_tokenizer_read_name (tokenizer);
gtk_css_token_init_string (token, GTK_CSS_TOKEN_AT_KEYWORD, tokenizer->name_buffer);
}
else
{

View File

@ -81,7 +81,11 @@ typedef struct _GtkCssDimensionToken GtkCssDimensionToken;
struct _GtkCssStringToken {
GtkCssTokenType type;
char *string;
int len;
union {
char buf[16];
char *string;
} u;
};
struct _GtkCssDelimToken {
@ -97,7 +101,7 @@ struct _GtkCssNumberToken {
struct _GtkCssDimensionToken {
GtkCssTokenType type;
double value;
char *dimension;
char dimension[8];
};
union _GtkCssToken {
@ -108,6 +112,15 @@ union _GtkCssToken {
GtkCssDimensionToken dimension;
};
static inline const char *
gtk_css_token_get_string (const GtkCssToken *token)
{
if (token->string.len < 16)
return token->string.u.buf;
else
return token->string.u.string;
}
void gtk_css_token_clear (GtkCssToken *token);
gboolean gtk_css_token_is_finite (const GtkCssToken *token) G_GNUC_PURE;

View File

@ -1,5 +1,4 @@
gtk_css_public_sources = files([
'gtkcsslocation.c',
'gtkcsserror.c',
'gtkcsssection.c',
])

View File

@ -722,7 +722,7 @@ _gtk_css_color_value_parse (GtkCssParser *parser)
{
const GtkCssToken *token = gtk_css_parser_get_token (parser);
value = _gtk_css_color_value_new_name (token->string.string);
value = _gtk_css_color_value_new_name (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (parser);
return value;

View File

@ -947,7 +947,7 @@ gtk_css_selector_parse_selector_class (GtkCssParser *parser,
selector = gtk_css_selector_new (negate ? &GTK_CSS_SELECTOR_NOT_CLASS
: &GTK_CSS_SELECTOR_CLASS,
selector);
selector->style_class.style_class = g_quark_from_string (token->string.string);
selector->style_class.style_class = g_quark_from_string (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (parser);
return selector;
}
@ -1060,7 +1060,7 @@ parse_n_plus_b (GtkCssParser *parser,
return parse_plus_b (parser, TRUE, b);
}
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
string_has_number (token->string.string, "n-", b))
string_has_number (gtk_css_token_get_string (token), "n-", b))
{
*a = before;
*b = -*b;
@ -1156,7 +1156,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
}
else if (!seen_sign &&
gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
string_has_number (token->string.string, "-n-", b))
string_has_number (gtk_css_token_get_string (token), "-n-", b))
{
*a = -1;
*b = -*b;
@ -1169,7 +1169,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
return parse_n_plus_b (parser, seen_sign ? seen_sign : 1, a, b);
}
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
string_has_number (token->string.string, "n-", b))
string_has_number (gtk_css_token_get_string (token), "n-", b))
{
*a = seen_sign ? seen_sign : 1;
*b = -*b;
@ -1177,7 +1177,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
return TRUE;
}
else if (!seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
string_has_number (token->string.string, "-n-", b))
string_has_number (gtk_css_token_get_string (token), "-n-", b))
{
*a = -1;
*b = -*b;
@ -1288,7 +1288,7 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser *parser,
for (i = 0; i < G_N_ELEMENTS (pseudo_classes); i++)
{
if (g_ascii_strcasecmp (pseudo_classes[i].name, token->string.string) == 0)
if (g_ascii_strcasecmp (pseudo_classes[i].name, gtk_css_token_get_string (token)) == 0)
{
if (pseudo_classes[i].state_flag)
{
@ -1380,13 +1380,13 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser *parser,
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
{
selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_NOT_NAME, selector);
selector->name.name = g_quark_from_string (token->string.string);
selector->name.name = g_quark_from_string (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (parser);
}
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
{
selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_NOT_ID, selector);
selector->id.name = g_quark_from_string (token->string.string);
selector->id.name = g_quark_from_string (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (parser);
}
else if (gtk_css_token_is_delim (token, '.'))
@ -1499,13 +1499,13 @@ gtk_css_selector_parse_simple_selector (GtkCssParser *parser,
else if (!parsed_something && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
{
selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_NAME, selector);
selector->name.name = g_quark_from_string (token->string.string);
selector->name.name = g_quark_from_string (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (parser);
}
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
{
selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_ID, selector);
selector->id.name = g_quark_from_string (token->string.string);
selector->id.name = g_quark_from_string (gtk_css_token_get_string (token));
gtk_css_parser_consume_token (parser);
}
else if (gtk_css_token_is_delim (token, '.'))

View File

@ -188,6 +188,7 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
guint32 image_list_offset, n_images;
int i, j;
GHashTable *icons = NULL;
GString *string;
directory_index = get_directory_index (cache, directory);
@ -197,6 +198,8 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
hash_offset = GET_UINT32 (cache->buffer, 4);
n_buckets = GET_UINT32 (cache->buffer, hash_offset);
string = g_string_new ("");
for (i = 0; i < n_buckets; i++)
{
chain_offset = GET_UINT32 (cache->buffer, hash_offset + 4 + 4 * i);
@ -223,15 +226,18 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
const char *name = cache->buffer + name_offset;
const char *interned_name;
guint32 hash_flags = 0;
int len;
/* Icons named foo.symbolic.png are stored in the cache as "foo.symbolic" with ICON_CACHE_FLAG_PNG,
* but we convert it internally to ICON_CACHE_FLAG_SYMBOLIC_PNG.
* Otherwise we use the same enum values and names as on disk. */
if (g_str_has_suffix (name, ".symbolic") && (flags & ICON_CACHE_FLAG_PNG_SUFFIX) != 0)
len = strlen (name);
if (g_str_equal (name + len - strlen (".symbolic"), ".symbolic") && (flags & ICON_CACHE_FLAG_PNG_SUFFIX) != 0)
{
char *converted_name = g_strndup (name, strlen (name) - 9);
interned_name = gtk_string_set_add (set, converted_name);
g_free (converted_name);
g_string_set_size (string, 0);
g_string_append_len (string, name, len - strlen (".symbolic"));
interned_name = gtk_string_set_add (set, string->str);
flags |= ICON_CACHE_FLAG_SYMBOLIC_PNG_SUFFIX;
flags &= ~ICON_CACHE_FLAG_PNG_SUFFIX;
}
@ -249,5 +255,7 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
}
}
g_string_free (string, TRUE);
return icons;
}

View File

@ -1715,7 +1715,6 @@ insert_theme (GtkIconTheme *self,
IconTheme *theme = NULL;
char *path;
GKeyFile *theme_file;
GError *error = NULL;
GStatBuf stat_buf;
for (l = self->themes; l != NULL; l = l->next)
@ -1725,6 +1724,7 @@ insert_theme (GtkIconTheme *self,
return;
}
theme_file = NULL;
for (i = 0; self->search_path[i]; i++)
{
IconThemeDirMtime dir_mtime;
@ -1736,6 +1736,22 @@ insert_theme (GtkIconTheme *self,
{
dir_mtime.mtime = stat_buf.st_mtime;
dir_mtime.exists = TRUE;
if (!theme_file)
{
char *file = g_build_filename (path, "index.theme", NULL);
if (g_file_test (file, G_FILE_TEST_IS_REGULAR))
{
theme_file = g_key_file_new ();
g_key_file_set_list_separator (theme_file, ',');
if (!g_key_file_load_from_file (theme_file, file, 0, NULL))
{
g_key_file_free (theme_file);
theme_file = NULL;
}
}
g_free (file);
}
}
else
{
@ -1746,25 +1762,6 @@ insert_theme (GtkIconTheme *self,
g_array_insert_val (self->dir_mtimes, 0, dir_mtime);
}
theme_file = NULL;
for (i = 0; self->search_path[i] && !theme_file; i++)
{
path = g_build_filename (self->search_path[i], theme_name, "index.theme", NULL);
if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
{
theme_file = g_key_file_new ();
g_key_file_set_list_separator (theme_file, ',');
if (!g_key_file_load_from_file (theme_file, path, 0, &error))
{
g_key_file_free (theme_file);
theme_file = NULL;
g_error_free (error);
error = NULL;
}
}
g_free (path);
}
if (theme_file == NULL)
{
if (strcmp (theme_name, FALLBACK_ICON_THEME) == 0)