From e570eb4f867982e43731caea5cac71126fc5a16c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 3 May 2024 12:00:13 -0400 Subject: [PATCH] css parser: Use a GdkArray for blocks This avoids some allocations, and is typesafe. --- gtk/css/gtkcssparser.c | 75 ++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/gtk/css/gtkcssparser.c b/gtk/css/gtkcssparser.c index 418368369a..ac8c75209f 100644 --- a/gtk/css/gtkcssparser.c +++ b/gtk/css/gtkcssparser.c @@ -28,6 +28,33 @@ typedef struct _GtkCssParserBlock GtkCssParserBlock; +struct _GtkCssParserBlock +{ + GtkCssLocation start_location; + GtkCssTokenType end_token; + GtkCssTokenType inherited_end_token; + GtkCssTokenType alternative_token; +}; + +#define GDK_ARRAY_NAME gtk_css_parser_blocks +#define GDK_ARRAY_TYPE_NAME GtkCssParserBlocks +#define GDK_ARRAY_ELEMENT_TYPE GtkCssParserBlock +#define GDK_ARAY_PREALLOC 32 +#define GDK_ARRAY_NO_MEMSET 1 +#include "gdk/gdkarrayimpl.c" + +static inline GtkCssParserBlock * +gtk_css_parser_blocks_get_last (GtkCssParserBlocks *blocks) +{ + return gtk_css_parser_blocks_index (blocks, gtk_css_parser_blocks_get_size (blocks) - 1); +} + +static inline void +gtk_css_parser_blocks_drop_last (GtkCssParserBlocks *blocks) +{ + gtk_css_parser_blocks_set_size (blocks, gtk_css_parser_blocks_get_size (blocks) - 1); +} + struct _GtkCssParser { volatile int ref_count; @@ -39,19 +66,11 @@ struct _GtkCssParser gpointer user_data; GDestroyNotify user_destroy; - GArray *blocks; + GtkCssParserBlocks blocks; GtkCssLocation location; GtkCssToken token; }; -struct _GtkCssParserBlock -{ - GtkCssLocation start_location; - GtkCssTokenType end_token; - GtkCssTokenType inherited_end_token; - GtkCssTokenType alternative_token; -}; - static GtkCssParser * gtk_css_parser_new (GtkCssTokenizer *tokenizer, GFile *file, @@ -74,7 +93,7 @@ gtk_css_parser_new (GtkCssTokenizer *tokenizer, self->error_func = error_func; self->user_data = user_data; self->user_destroy = user_destroy; - self->blocks = g_array_new (FALSE, FALSE, sizeof (GtkCssParserBlock)); + gtk_css_parser_blocks_init (&self->blocks); return self; } @@ -126,9 +145,9 @@ gtk_css_parser_finalize (GtkCssParser *self) g_clear_pointer (&self->tokenizer, gtk_css_tokenizer_unref); g_clear_object (&self->file); g_clear_object (&self->directory); - if (self->blocks->len) - g_critical ("Finalizing CSS parser with %u remaining blocks", self->blocks->len); - g_array_free (self->blocks, TRUE); + if (gtk_css_parser_blocks_get_size (&self->blocks) > 0) + g_critical ("Finalizing CSS parser with %lu remaining blocks", gtk_css_parser_blocks_get_size (&self->blocks)); + gtk_css_parser_blocks_clear (&self->blocks); g_free (self); } @@ -259,13 +278,13 @@ gtk_css_parser_get_block_location (GtkCssParser *self) { const GtkCssParserBlock *block; - if (self->blocks->len == 0) + if (gtk_css_parser_blocks_get_size (&self->blocks) == 0) { static const GtkCssLocation start_of_document = { 0, }; return &start_of_document; } - block = &g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1); + block = gtk_css_parser_blocks_get_last (&self->blocks); return &block->start_location; } @@ -295,9 +314,9 @@ gtk_css_parser_peek_token (GtkCssParser *self) gtk_css_parser_ensure_token (self); - if (self->blocks->len) + if (gtk_css_parser_blocks_get_size (&self->blocks) > 0) { - const GtkCssParserBlock *block = &g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1); + const GtkCssParserBlock *block = gtk_css_parser_blocks_get_last (&self->blocks); if (gtk_css_token_is (&self->token, block->end_token) || gtk_css_token_is (&self->token, block->inherited_end_token) || gtk_css_token_is (&self->token, block->alternative_token)) @@ -352,7 +371,7 @@ gtk_css_parser_start_block (GtkCssParser *self) block.inherited_end_token = GTK_CSS_TOKEN_EOF; block.alternative_token = GTK_CSS_TOKEN_EOF; block.start_location = self->location; - g_array_append_val (self->blocks, block); + gtk_css_parser_blocks_append (&self->blocks, block); gtk_css_token_clear (&self->token); } @@ -364,13 +383,13 @@ gtk_css_parser_start_semicolon_block (GtkCssParser *self, GtkCssParserBlock block; block.end_token = GTK_CSS_TOKEN_SEMICOLON; - if (self->blocks->len) - block.inherited_end_token = g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1).end_token; + if (gtk_css_parser_blocks_get_size (&self->blocks) > 0) + block.inherited_end_token = gtk_css_parser_blocks_get_last (&self->blocks)->end_token; else block.inherited_end_token = GTK_CSS_TOKEN_EOF; block.alternative_token = alternative_token; block.start_location = self->location; - g_array_append_val (self->blocks, block); + gtk_css_parser_blocks_append (&self->blocks, block); } void @@ -378,9 +397,9 @@ gtk_css_parser_end_block_prelude (GtkCssParser *self) { GtkCssParserBlock *block; - g_return_if_fail (self->blocks->len > 0); + g_return_if_fail (gtk_css_parser_blocks_get_size (&self->blocks) > 0); - block = &g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1); + block = gtk_css_parser_blocks_get_last (&self->blocks); if (block->alternative_token == GTK_CSS_TOKEN_EOF) return; @@ -405,11 +424,11 @@ gtk_css_parser_end_block (GtkCssParser *self) { GtkCssParserBlock *block; - g_return_if_fail (self->blocks->len > 0); + g_return_if_fail (gtk_css_parser_blocks_get_size (&self->blocks) > 0); gtk_css_parser_skip_until (self, GTK_CSS_TOKEN_EOF); - block = &g_array_index (self->blocks, GtkCssParserBlock, self->blocks->len - 1); + block = gtk_css_parser_blocks_get_last (&self->blocks); if (gtk_css_token_is (&self->token, GTK_CSS_TOKEN_EOF)) { @@ -418,7 +437,7 @@ gtk_css_parser_end_block (GtkCssParser *self) gtk_css_parser_get_block_location (self), gtk_css_parser_get_start_location (self), "Unterminated block at end of document"); - g_array_set_size (self->blocks, self->blocks->len - 1); + gtk_css_parser_blocks_drop_last (&self->blocks); } else if (gtk_css_token_is (&self->token, block->inherited_end_token)) { @@ -428,11 +447,11 @@ gtk_css_parser_end_block (GtkCssParser *self) gtk_css_parser_get_block_location (self), gtk_css_parser_get_start_location (self), "Expected ';' at end of block"); - g_array_set_size (self->blocks, self->blocks->len - 1); + gtk_css_parser_blocks_drop_last (&self->blocks); } else { - g_array_set_size (self->blocks, self->blocks->len - 1); + gtk_css_parser_blocks_drop_last (&self->blocks); if (gtk_css_token_is_preserved (&self->token, NULL)) { gtk_css_token_clear (&self->token);