summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Staudinger <robsta@gnome.org>2009-09-01 14:53:59 +0200
committerRobert Staudinger <robsta@gnome.org>2009-09-01 14:53:59 +0200
commit4e7867badc228edbed1aedb69b7690e2771c3e9b (patch)
tree757524cad3940c786dafb6817439c71a34dac8a3
parent22a09db8093b039b435322d756b7bbc4c6eca90f (diff)
[function] Make function objects dynamically creatable and ref-counted.
-rw-r--r--ccss-doc/ccss-sections.txt18
-rw-r--r--ccss-gtk/ccss-gtk-functions.c26
-rw-r--r--ccss-gtk/ccss-gtk-functions.h3
-rw-r--r--ccss-gtk/ccss-gtk-grammar.c3
-rw-r--r--ccss/Makefile.am1
-rw-r--r--ccss/ccss-function-impl.h28
-rw-r--r--ccss/ccss-function.c110
-rw-r--r--ccss/ccss-function.h28
-rw-r--r--ccss/ccss-grammar-function.c8
-rw-r--r--ccss/ccss-grammar.c33
-rw-r--r--ccss/ccss-grammar.h4
-rw-r--r--ccss/ccss.sym5
-rw-r--r--examples/example-3.c4
-rw-r--r--examples/example-5.c4
14 files changed, 218 insertions, 57 deletions
diff --git a/ccss-doc/ccss-sections.txt b/ccss-doc/ccss-sections.txt
index 57a9ec0..b3bd7e9 100644
--- a/ccss-doc/ccss-sections.txt
+++ b/ccss-doc/ccss-sections.txt
@@ -72,6 +72,17 @@ ccss_color_parse
</SECTION>
<SECTION>
+<TITLE>ccss_function_t</TITLE>
+<FILE>function</FILE>
+ccss_function_f
+ccss_function_t
+ccss_function_create
+ccss_function_destroy
+ccss_function_get_reference_count
+ccss_function_reference
+</SECTION>
+
+<SECTION>
<TITLE>ccss_grammar_t</TITLE>
<FILE>grammar</FILE>
ccss_grammar_t
@@ -181,10 +192,3 @@ ccss_property_get_state
ccss_property_state_serialize
</SECTION>
-<SECTION>
-<TITLE>ccss_function_t</TITLE>
-<FILE>function</FILE>
-ccss_function_f
-ccss_function_t
-</SECTION>
-
diff --git a/ccss-gtk/ccss-gtk-functions.c b/ccss-gtk/ccss-gtk-functions.c
index c2c5106..aabd24d 100644
--- a/ccss-gtk/ccss-gtk-functions.c
+++ b/ccss-gtk/ccss-gtk-functions.c
@@ -367,20 +367,20 @@ darker (GSList const *args,
result.blue / 65535.0);
}
-static ccss_function_t const _functions[] =
-{
- { "url", url, NULL },
- { "gtk-color", color, NULL },
- { "gtk-mix", mix, NULL },
- { "gtk-shade", shade, NULL },
- { "gtk-lighter", lighter, NULL },
- { "gtk-darker", darker, NULL },
- { NULL }
-};
-
-ccss_function_t const *
-ccss_gtk_functions_get_vtable (void)
+ccss_function_t *
+ccss_gtk_functions_peek_vtable (void)
{
+ static ccss_function_t _functions[] =
+ {
+ { "url", url, 1 },
+ { "gtk-color", color, 1 },
+ { "gtk-mix", mix, 1 },
+ { "gtk-shade", shade, 1 },
+ { "gtk-lighter", lighter, 1 },
+ { "gtk-darker", darker, 1 },
+ { NULL }
+ };
+
return _functions;
}
diff --git a/ccss-gtk/ccss-gtk-functions.h b/ccss-gtk/ccss-gtk-functions.h
index b79de14..f6a8fed 100644
--- a/ccss-gtk/ccss-gtk-functions.h
+++ b/ccss-gtk/ccss-gtk-functions.h
@@ -32,7 +32,8 @@
CCSS_BEGIN_DECLS
-ccss_function_t const * ccss_gtk_functions_get_vtable (void);
+ccss_function_t *
+ccss_gtk_functions_peek_vtable (void);
CCSS_END_DECLS
diff --git a/ccss-gtk/ccss-gtk-grammar.c b/ccss-gtk/ccss-gtk-grammar.c
index e1fe3c0..8cc8b7c 100644
--- a/ccss-gtk/ccss-gtk-grammar.c
+++ b/ccss-gtk/ccss-gtk-grammar.c
@@ -22,6 +22,7 @@
#include <string.h>
#include <gtk/gtk.h>
#include <ccss-cairo/ccss-cairo.h>
+#include <ccss/ccss-function-impl.h>
#include "ccss-gtk-grammar.h"
#include "ccss-gtk-functions.h"
#include "ccss-gtk-property.h"
@@ -50,7 +51,7 @@ ccss_gtk_grammar_create (void)
ccss_gtk_property_set_fallback_class (fallback_property_class);
ccss_grammar_add_properties (self, ccss_gtk_property_get_property_classes ());
- ccss_grammar_add_functions (self, ccss_gtk_functions_get_vtable ());
+ ccss_grammar_add_functions (self, ccss_gtk_functions_peek_vtable ());
return self;
}
diff --git a/ccss/Makefile.am b/ccss/Makefile.am
index 106e976..513fd2e 100644
--- a/ccss/Makefile.am
+++ b/ccss/Makefile.am
@@ -39,6 +39,7 @@ libccss_1_la_SOURCES = \
ccss-border-image-parser.h \
ccss-color.c \
ccss-color-parser.c \
+ ccss-function.c \
ccss-grammar.c \
ccss-grammar-function.c \
ccss-grammar-parse.c \
diff --git a/ccss/ccss-function-impl.h b/ccss/ccss-function-impl.h
index b6d19c2..fc08864 100644
--- a/ccss/ccss-function-impl.h
+++ b/ccss/ccss-function-impl.h
@@ -35,26 +35,14 @@
CCSS_BEGIN_DECLS
-/* Let's just forward declare this, so we don't have to pull in <glib.h>. */
-struct _GSList;
-
-/**
- * ccss_function_f:
- * @args: argument-list passed to the function.
- * @user_data: user data associated to the function handler.
- *
- * Prototype for a custom `CSS function' handler.
- *
- * Returns: the function's result as a string.
- **/
-typedef char * (*ccss_function_f) (struct _GSList const *args,
- void *user_data);
+/* Avoid circular dependencies. */
+struct ccss_grammar_;
/**
* ccss_function_t:
- * @name: identifier of the function, as used in CSS.
- * @function: handler, see #ccss_function_f.
- * @user_data: data to pass to the function handler.
+ * @name: identifier of the function, as used in CSS.
+ * @function: handler, see #ccss_function_f.
+ * @reference_count: the reference count.
*
* This datastructure represents one line in the libccss' consumers vtable.
**/
@@ -62,9 +50,13 @@ struct ccss_function_ {
/*< private >*/
CCSS_DEPRECATED (char const *name);
CCSS_DEPRECATED (ccss_function_f function);
- CCSS_DEPRECATED (void *user_data);
+ CCSS_DEPRECATED (unsigned int reference_count);
};
+void
+ccss_grammar_add_functions (struct ccss_grammar_ *self,
+ ccss_function_t *functions);
+
CCSS_END_DECLS
#endif /* CCSS_FUNCTION_IMPL_H */
diff --git a/ccss/ccss-function.c b/ccss/ccss-function.c
new file mode 100644
index 0000000..a4b9a2c
--- /dev/null
+++ b/ccss/ccss-function.c
@@ -0,0 +1,110 @@
+/* vim: set ts=8 sw=8 noexpandtab: */
+
+/* The `C' CSS Library.
+ * Copyright (C) 2008 Robert Staudinger
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include "ccss-function-impl.h"
+
+/*
+ * FIXME: move to reference counting.
+ * So statically allocated function structs will never actually be destroyed.
+ */
+
+/**
+ * ccss_function_create:
+ * @name: function identifier as used in CSS.
+ * @function: function pointer.
+ *
+ * Create a new function instance.
+ *
+ * Returns: a #ccss_function_t.
+ **/
+ccss_function_t *
+ccss_function_create (char const *name,
+ ccss_function_f function)
+{
+ ccss_function_t *self;
+
+ g_return_val_if_fail (name, NULL);
+ g_return_val_if_fail (function, NULL);
+
+ self = g_new0 (ccss_function_t, 1);
+ self->name = g_strdup (name);
+ self->function = function;
+
+ return self;
+}
+
+/**
+ * ccss_function_destroy:
+ *
+ * Destroy a function instance.
+ **/
+void
+ccss_function_destroy (ccss_function_t *self)
+{
+ g_return_if_fail (self);
+
+ self->reference_count--;
+
+ if (0 == self->reference_count) {
+ /* This string is owned for dynamically created functions. */
+ g_free ((char *) self->name);
+ g_free (self);
+ }
+}
+
+/**
+ * ccss_function_reference:
+ * @self: a #ccss_function_t.
+ *
+ * Increases the reference count on @self by one. This prevents @self from being
+ * destroyed until a matching call to ccss_function_destroy() is made.
+ *
+ * The number of references to a #ccss_function_t can be acquired using
+ * ccss_function_get_reference_count().
+ *
+ * Returns: the referenced #ccss_function_t.
+ **/
+ccss_function_t *
+ccss_function_reference (ccss_function_t *self)
+{
+ g_return_val_if_fail (self, NULL);
+
+ self->reference_count++;
+
+ return self;
+}
+
+/**
+ * ccss_function_get_reference_count:
+ * @self: a #ccss_function_t.
+ *
+ * Returns: the current reference count of @self.
+ * If @self is a nil object, 0 will be returned.
+ **/
+unsigned int
+ccss_function_get_reference_count (ccss_function_t const *self)
+{
+ g_return_val_if_fail (self, 0);
+
+ return self->reference_count;
+}
+
diff --git a/ccss/ccss-function.h b/ccss/ccss-function.h
index 4945756..0b444ce 100644
--- a/ccss/ccss-function.h
+++ b/ccss/ccss-function.h
@@ -26,8 +26,36 @@
CCSS_BEGIN_DECLS
+/* Let's just forward declare this, so we don't have to pull in <glib.h>. */
+struct _GSList;
+
+/**
+ * ccss_function_f:
+ * @args: argument-list passed to the function.
+ * @user_data: user data associated to the function handler.
+ *
+ * Prototype for a custom `CSS function' handler.
+ *
+ * Returns: the function's result as a string.
+ **/
+typedef char * (*ccss_function_f) (struct _GSList const *args,
+ void *user_data);
+
typedef struct ccss_function_ ccss_function_t;
+ccss_function_t *
+ccss_function_create (char const *name,
+ ccss_function_f function);
+
+void
+ccss_function_destroy (ccss_function_t *self);
+
+ccss_function_t *
+ccss_function_reference (ccss_function_t *self);
+
+unsigned int
+ccss_function_get_reference_count (ccss_function_t const *self);
+
CCSS_END_DECLS
#endif /* CCSS_FUNCTION_H */
diff --git a/ccss/ccss-grammar-function.c b/ccss/ccss-grammar-function.c
index f095dab..1649707 100644
--- a/ccss/ccss-grammar-function.c
+++ b/ccss/ccss-grammar-function.c
@@ -140,7 +140,6 @@ ccss_grammar_invoke_function (ccss_grammar_t const *self,
{
ccss_function_t const *handler;
GSList *args;
- void *actual_user_data;
char *ret;
g_return_val_if_fail (self && function_name, NULL);
@@ -158,12 +157,7 @@ ccss_grammar_invoke_function (ccss_grammar_t const *self,
args = g_slist_reverse (args);
/* dispatch */
- if (user_data) {
- actual_user_data = user_data;
- } else {
- actual_user_data = handler->user_data;
- }
- ret = handler->function (args, actual_user_data);
+ ret = handler->function (args, user_data);
/* free args */
while (args) {
diff --git a/ccss/ccss-grammar.c b/ccss/ccss-grammar.c
index 6f18498..1e2591c 100644
--- a/ccss/ccss-grammar.c
+++ b/ccss/ccss-grammar.c
@@ -51,7 +51,10 @@ ccss_grammar_create_generic (void)
self = g_new0 (ccss_grammar_t, 1);
self->reference_count = 1;
self->properties = g_hash_table_new (g_str_hash, g_str_equal);
- self->functions = g_hash_table_new (g_str_hash, g_str_equal);
+ self->functions = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ (GDestroyNotify) ccss_function_destroy);
ccss_grammar_add_properties (self, ccss_property_parser_get_property_classes ());
@@ -187,6 +190,28 @@ ccss_grammar_lookup_property (ccss_grammar_t const *self,
}
/**
+ * ccss_grammar_add_function:
+ * @self: a #ccss_grammar_t.
+ * @function: a #ccss_function_t to register.
+ *
+ * Register a single custom css function handler with the grammar.
+ **/
+void
+ccss_grammar_add_function (ccss_grammar_t *self,
+ ccss_function_t *function)
+{
+ g_return_if_fail (self);
+ g_return_if_fail (function);
+
+ /* Handler already exists? */
+ g_warn_if_fail (NULL == g_hash_table_lookup (self->functions, function->name));
+
+ g_hash_table_insert (self->functions,
+ (gpointer) function->name,
+ ccss_function_reference (function));
+}
+
+/**
* ccss_grammar_add_functions:
* @self: a #ccss_grammar_t.
* @functions: Null-terminated array of #ccss_function_t to register.
@@ -194,8 +219,8 @@ ccss_grammar_lookup_property (ccss_grammar_t const *self,
* Register a set of custom css function handlers with the grammar.
**/
void
-ccss_grammar_add_functions (ccss_grammar_t *self,
- ccss_function_t const *functions)
+ccss_grammar_add_functions (ccss_grammar_t *self,
+ ccss_function_t *functions)
{
g_return_if_fail (self && functions);
@@ -206,7 +231,7 @@ ccss_grammar_add_functions (ccss_grammar_t *self,
g_hash_table_insert (self->functions,
(gpointer) functions[i].name,
- (gpointer) &functions[i]);
+ ccss_function_reference (&functions[i]));
}
}
diff --git a/ccss/ccss-grammar.h b/ccss/ccss-grammar.h
index 71d5512..9dd49bb 100644
--- a/ccss/ccss-grammar.h
+++ b/ccss/ccss-grammar.h
@@ -55,8 +55,8 @@ ccss_grammar_lookup_property (ccss_grammar_t const *self,
char const *name);
void
-ccss_grammar_add_functions (ccss_grammar_t *self,
- ccss_function_t const *functions);
+ccss_grammar_add_function (ccss_grammar_t *self,
+ ccss_function_t *function);
ccss_function_t const *
ccss_grammar_lookup_function (ccss_grammar_t const *self,
diff --git a/ccss/ccss.sym b/ccss/ccss.sym
index a124d57..578ceea 100644
--- a/ccss/ccss.sym
+++ b/ccss/ccss.sym
@@ -28,6 +28,11 @@ ccss_color_get_blue
ccss_color_get_green
ccss_color_get_red
ccss_color_parse
+ccss_function_create
+ccss_function_destroy
+ccss_function_get_reference_count
+ccss_function_reference
+ccss_grammar_add_function
ccss_grammar_add_functions
ccss_grammar_add_properties
ccss_grammar_create_css
diff --git a/examples/example-3.c b/examples/example-3.c
index 1b6367e..1a76996 100644
--- a/examples/example-3.c
+++ b/examples/example-3.c
@@ -52,9 +52,9 @@ url (GSList const *args,
return uri;
}
-static ccss_function_t const _functions[] =
+static ccss_function_t _functions[] =
{
- { "url", url, NULL },
+ { "url", url, 1 },
{ NULL }
};
diff --git a/examples/example-5.c b/examples/example-5.c
index 3c50155..6fc3a5f 100644
--- a/examples/example-5.c
+++ b/examples/example-5.c
@@ -52,9 +52,9 @@ url (GSList const *args,
return uri;
}
-static ccss_function_t const _functions[] =
+static ccss_function_t _functions[] =
{
- { "url", url, NULL },
+ { "url", url, 1 },
{ NULL }
};