[gnome-builder/gnome-builder-3-20] tmpl: import recent template-glib
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/gnome-builder-3-20] tmpl: import recent template-glib
- Date: Sat, 14 May 2016 12:48:28 +0000 (UTC)
commit c20d762c53d6827fe30430d0235110ec094311ff
Author: Christian Hergert <chergert redhat com>
Date: Sat May 14 13:10:56 2016 +0300
tmpl: import recent template-glib
This adds hooks for missing symbol lookups.
contrib/tmpl/tmpl-scope.c | 77 +++++++++++++++++++++++++++++++++++----------
contrib/tmpl/tmpl-scope.h | 29 +++++++++++------
2 files changed, 79 insertions(+), 27 deletions(-)
---
diff --git a/contrib/tmpl/tmpl-scope.c b/contrib/tmpl/tmpl-scope.c
index f1c892a..a4a0792 100644
--- a/contrib/tmpl/tmpl-scope.c
+++ b/contrib/tmpl/tmpl-scope.c
@@ -21,9 +21,12 @@
struct _TmplScope
{
- volatile gint ref_count;
- TmplScope *parent;
- GHashTable *symbols;
+ volatile gint ref_count;
+ TmplScope *parent;
+ GHashTable *symbols;
+ TmplScopeResolver resolver;
+ gpointer resolver_data;
+ GDestroyNotify resolver_destroy;
};
G_DEFINE_BOXED_TYPE (TmplScope, tmpl_scope, tmpl_scope_ref, tmpl_scope_unref)
@@ -47,6 +50,10 @@ tmpl_scope_unref (TmplScope *self)
if (g_atomic_int_dec_and_test (&self->ref_count))
{
+ if (self->resolver_destroy)
+ g_clear_pointer (&self->resolver_data, self->resolver_destroy);
+ self->resolver = NULL;
+ self->resolver_destroy = NULL;
g_clear_pointer (&self->symbols, g_hash_table_unref);
g_clear_pointer (&self->parent, tmpl_scope_unref);
g_slice_free (TmplScope, self);
@@ -99,6 +106,7 @@ tmpl_scope_get_full (TmplScope *self,
gboolean create)
{
TmplSymbol *symbol = NULL;
+ TmplScope *parent;
g_return_val_if_fail (self != NULL, NULL);
@@ -110,17 +118,22 @@ tmpl_scope_get_full (TmplScope *self,
}
/* Try to locate the symbol in a parent scope */
- if (symbol == NULL)
+ for (parent = self->parent; parent != NULL; parent = parent->parent)
{
- TmplScope *parent;
+ if (parent->symbols != NULL)
+ {
+ if ((symbol = g_hash_table_lookup (parent->symbols, name)))
+ return symbol;
+ }
+ }
- for (parent = self->parent; parent != NULL; parent = parent->parent)
+ /* Call our resolver helper to locate the symbol */
+ for (parent = self; parent != NULL; parent = parent->parent)
+ {
+ if (parent->resolver)
{
- if (parent->symbols != NULL)
- {
- if ((symbol = g_hash_table_lookup (parent->symbols, name)))
- return symbol;
- }
+ if (parent->resolver (parent, name, &symbol, parent->resolver_data) && symbol)
+ goto save_symbol;
}
}
@@ -128,15 +141,20 @@ tmpl_scope_get_full (TmplScope *self,
{
/* Define the symbol in this scope */
symbol = tmpl_symbol_new ();
- if (self->symbols == NULL)
- self->symbols = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify)tmpl_symbol_unref);
- g_hash_table_insert (self->symbols, g_strdup (name), symbol);
+ goto save_symbol;
}
return symbol;
+
+save_symbol:
+ if (self->symbols == NULL)
+ self->symbols = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ (GDestroyNotify)tmpl_symbol_unref);
+ g_hash_table_insert (self->symbols, g_strdup (name), symbol);
+
+ return symbol;
}
/**
@@ -166,3 +184,28 @@ tmpl_scope_peek (TmplScope *self,
{
return tmpl_scope_get_full (self, name, FALSE);
}
+
+void
+tmpl_scope_set_resolver (TmplScope *self,
+ TmplScopeResolver resolver,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ g_return_if_fail (self != NULL);
+
+ if (resolver != self->resolver ||
+ user_data != self->resolver_data ||
+ destroy != self->resolver_destroy)
+ {
+ if (self->resolver && self->resolver_destroy && self->resolver_data)
+ {
+ g_clear_pointer (&self->resolver_data, self->resolver_destroy);
+ self->resolver_destroy = NULL;
+ self->resolver = NULL;
+ }
+
+ self->resolver = resolver;
+ self->resolver_data = user_data;
+ self->resolver_destroy = destroy;
+ }
+}
diff --git a/contrib/tmpl/tmpl-scope.h b/contrib/tmpl/tmpl-scope.h
index 60efd9a..12e1871 100644
--- a/contrib/tmpl/tmpl-scope.h
+++ b/contrib/tmpl/tmpl-scope.h
@@ -27,17 +27,26 @@
G_BEGIN_DECLS
+typedef gboolean (*TmplScopeResolver) (TmplScope *scope,
+ const gchar *name,
+ TmplSymbol **symbol,
+ gpointer user_data);
+
TmplScope *tmpl_scope_new (void);
-TmplScope *tmpl_scope_new_with_parent (TmplScope *parent);
-TmplScope *tmpl_scope_ref (TmplScope *self);
-void tmpl_scope_unref (TmplScope *self);
-TmplSymbol *tmpl_scope_peek (TmplScope *self,
- const gchar *name);
-TmplSymbol *tmpl_scope_get (TmplScope *self,
- const gchar *name);
-void tmpl_scope_set (TmplScope *self,
- const gchar *name,
- TmplSymbol *symbol);
+TmplScope *tmpl_scope_new_with_parent (TmplScope *parent);
+TmplScope *tmpl_scope_ref (TmplScope *self);
+void tmpl_scope_unref (TmplScope *self);
+TmplSymbol *tmpl_scope_peek (TmplScope *self,
+ const gchar *name);
+TmplSymbol *tmpl_scope_get (TmplScope *self,
+ const gchar *name);
+void tmpl_scope_set (TmplScope *self,
+ const gchar *name,
+ TmplSymbol *symbol);
+void tmpl_scope_set_resolver (TmplScope *self,
+ TmplScopeResolver resolver,
+ gpointer user_data,
+ GDestroyNotify destroy);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (TmplScope, tmpl_scope_unref)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]