css parser: Use a GdkArray for blocks

This avoids some allocations, and is typesafe.
This commit is contained in:
Matthias Clasen 2024-05-03 12:00:13 -04:00
parent de5b6764bc
commit e570eb4f86

View File

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