--- a/ChangeLog Fri Oct 10 23:17:45 2008 -0500
+++ b/ChangeLog Sun Jan 04 02:02:57 2009 -0600
@@ -1,3 +1,6 @@
+Version 0.0.3 ??/??/????: + * Added an iterator to GPlateObjectVariable Version 0.0.2 09/20/2008:
* Fixed the bug where a default tag that didn't start with a word rendered
--- a/README Fri Oct 10 23:17:45 2008 -0500
+++ b/README Sun Jan 04 02:02:57 2009 -0600
@@ -6,4 +6,7 @@
that are already using glib.
The idea behind gplate is to be extendable by the applications using it so that
-it can fit whatever you needs may arise.
+it can fit whatever you needs may arise. You can customize the tags and the +functions bound to them. You can also create easily your own functions and --- a/autogen.sh Fri Oct 10 23:17:45 2008 -0500
+++ b/autogen.sh Sun Jan 04 02:02:57 2009 -0600
@@ -1,5 +1,5 @@
-# Copyright (C) 2007-2008 Gary Kramlich <grim@reaperworld.com>
+# Copyright (C) 2008 Gary Kramlich <grim@reaperworld.com> # This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
@@ -32,6 +32,7 @@
# AUTOHEADER_FLAGS - command line arguments to pass to autoheader
# AUTOMAKE_FLAGS - command line arguments to pass to automake flags
# CONFIGURE_FLAGS - command line arguments to pass to configure
+# GTKDOCIZE_FLAGS - command line arguments to pass to gtkdocize # INTLTOOLIZE_FLAGS - command line arguments to pass to intltoolize
# LIBTOOLIZE_FLAGS - command line arguments to pass to libtoolize
@@ -95,7 +96,7 @@
if [ x"${BIN}" = x"" ] ; then
echo "${CMD} is required to build ${PACKAGE}!"
@@ -107,7 +108,7 @@
- OUTPUT=`mktemp .autogen-XXXXXX`
+ OUTPUT=`mktemp autogen-XXXXXX` # we have to stash ${@} into a variable, otherwise printf has "issues" if
# ${@} was expanded from a variable. Fortunately, this let's us clean up
@@ -182,6 +183,6 @@
###############################################################################
###############################################################################
-echo "running './configure ${CONFIGURE_FLAGS} $@'"
+echo "running ./configure ${CONFIGURE_FLAGS} $@" ./configure ${CONFIGURE_FLAGS} $@
--- a/configure.ac Fri Oct 10 23:17:45 2008 -0500
+++ b/configure.ac Sun Jan 04 02:02:57 2009 -0600
@@ -14,7 +14,7 @@
dnl ################################################################
GPLATE_VERSION=$GPLATE_MAJOR_VERSION.$GPLATE_MINOR_VERSION.$GPLATE_MICRO_VERSION
@@ -108,13 +108,15 @@
dnl #######################################################################
dnl # Look for the C compiler
dnl #######################################################################
-AC_MSG_CHECKING([useful C based html templating library so I don't have to write one])
+AC_MSG_CHECKING([useful C based templating library so I don't have to write one]) -AC_ARG_ENABLE(debug, [ --enable-debug compile with debugging support],,enable_debug=no)
+ AC_HELP_STRING([--enable-debug],[compile with debugging support]) if test x"$enable_debug" = x"yes" ; then
AC_DEFINE(DEBUG, 1, [Define if debugging is enabled.])
@@ -128,7 +130,9 @@
dnl #######################################################################
dnl # do we want to build the tests?
dnl #######################################################################
-AC_ARG_ENABLE(tests, [ --enable-tests build test programs],,enable_tests=no)
+ AC_HELP_STRING([--enable-tests],[build test programs]) --- a/gplate/functions/gplate-for-function.c Fri Oct 10 23:17:45 2008 -0500
+++ b/gplate/functions/gplate-for-function.c Sun Jan 04 02:02:57 2009 -0600
@@ -26,6 +26,7 @@
#include <gplate/gplate-iterator.h>
#include <gplate/gplate-tag.h>
#include <gplate/gplate-variable.h>
+#include <gplate/tags/gplate-code-tag.h> #define SYNTAX_REGEX "^(.+)\\s+in\\s+(.+)$"
@@ -116,8 +117,8 @@
iter = gplate_collection_get_iterator(collection);
while(gplate_iterator_has_next(iter)) {
GPlateCollection *tc = GPLATE_COLLECTION(tplate);
GPlateVariable *var = NULL;
@@ -130,21 +131,10 @@
ret = gplate_collection_add_variable_with_name(tc, iter_name, var);
/* iterate through the tokens */
- while((tag = gplate_template_next_tag(tplate))) {
- const gchar *contents = NULL;
- contents = gplate_tag_get_contents(tag);
- if(contents && g_utf8_collate(contents, "endfor") == 0)
- output = gplate_template_render_tag(tplate, tag);
- g_string_append_printf(str, "%s", output);
+ output = gplate_template_render_until(tplate, &count, + GPLATE_TYPE_CODE_TAG, "endfor", + g_string_append_printf(str, "%s", output); if(gplate_iterator_has_next(iter))
gplate_template_nth_previous_tag(tplate, count);
--- a/gplate/gplate-template.c Fri Oct 10 23:17:45 2008 -0500
+++ b/gplate/gplate-template.c Sun Jan 04 02:02:57 2009 -0600
@@ -56,6 +56,11 @@
+} GPlateTemplateTagData; /******************************************************************************
*****************************************************************************/
@@ -140,16 +145,11 @@
-} GPlateTemplateFindTagData;
gplate_template_find_tag_helper(GType tag, const gchar *prefix,
const gchar *suffix, gpointer d)
- GPlateTemplateFindTagData *data = (GPlateTemplateFindTagData *)d;
+ GPlateTemplateTagData *data = (GPlateTemplateTagData *)d; /* if our tag info doesn't have a prefix or a suffix, we drop out. */
@@ -173,8 +173,8 @@
-gplate_template_find_tag(GPlateTemplate *tplate, const gchar *contents) {
- GPlateTemplateFindTagData d;
+gplate_template_find_tag(GPlateTemplate *tplate, gchar *contents) { + GPlateTemplateTagData d; @@ -701,6 +701,114 @@
+ * gplate_template_render_until: + * @tplate: The #GPlateTemplate + * @ntags: A return address for the number of tags that were rendered + * @Varargs: A NULL terminated list of #GType, content pairs. + * Renders the tags in a template from the current point until it a tag is + * found that is the correct type and has the same contents as one of the + * #GType, content pairs. +gplate_template_render_until(GPlateTemplate *tplate, guint *ntags, ...) { + GType type = G_TYPE_INVALID; + gboolean backup = FALSE; + g_return_val_if_fail(GPLATE_IS_TEMPLATE(tplate), NULL); + str = g_string_new(""); + /* store all of the content/tag pairs */ + while((type = va_arg(args, gsize)) != G_TYPE_INVALID) { + GPlateTemplateTagData *td = NULL; + gchar *contents = NULL; + td = g_new(GPlateTemplateTagData, 1); + contents = va_arg(args, gchar *); + td->contents = contents ? g_strdup(contents) : NULL; + g_queue_push_tail(queue, td); + /* now iterate the tags */ + while((tag = gplate_template_next_tag(tplate))) { + GPlateTemplateTagData ctd; + ctd.contents = gplate_tag_get_contents(tag); + ctd.type = G_OBJECT_TYPE(tag); + /* run through our list of TagData's to stop on */ + for(l = queue->head; l; l = l->next) { + GPlateTemplateTagData *td = (GPlateTemplateTagData *)l->data; + if(ctd.type == td->type && + g_utf8_collate(ctd.contents, td->contents) == 0) + g_string_append_printf(str, "%s", + gplate_template_render_tag(tplate, tag)); + /* now clean everything up... */ + for(l = queue->head; l; l = l->next) { + GPlateTemplateTagData *td = (GPlateTemplateTagData *)l->data; + g_string_free(str, FALSE); + /* if backup is set, we back up to the tag which caused us to stop. In + * other words, the tag stack will currently be at the tag after the one + * we stopped at, but we want to be on the one that we stopped on. + gplate_template_previous_tag(tplate); * gplate_template_first_tag:
* @tplate: The #GPlateTemplate.
@@ -772,7 +880,7 @@
* Moves the tag stack forward one tag and returns it.
- * Return Value: The previous tag or NULL.
+ * Return Value: The next tag or NULL. gplate_template_next_tag(GPlateTemplate *tplate) {
@@ -876,7 +984,7 @@
klass->insert_tags(tplate, tags);
gplate_template_render_token(GPlateTemplate *tplate, const gchar *contents,
GType tag, GError **error)
--- a/gplate/gplate-template.h Fri Oct 10 23:17:45 2008 -0500
+++ b/gplate/gplate-template.h Sun Jan 04 02:02:57 2009 -0600
@@ -76,6 +76,8 @@
gchar *gplate_template_render(GPlateTemplate *tplate, const gchar *tplate_string, GError **error);
gchar *gplate_template_render_file(GPlateTemplate *tplate, const gchar *filename, GError **error);
+gchar *gplate_template_render_until(GPlateTemplate *tplate, guint *ntags, ...); GPlateTag *gplate_template_first_tag(GPlateTemplate *tplate);
GPlateTag *gplate_template_last_tag(GPlateTemplate *tplate);
GPlateTag *gplate_template_current_tag(GPlateTemplate *tplate);
--- a/gplate/variables/gplate-object-variable.c Fri Oct 10 23:17:45 2008 -0500
+++ b/gplate/variables/gplate-object-variable.c Sun Jan 04 02:02:57 2009 -0600
@@ -29,6 +29,11 @@
#define GPLATE_OBJECT_VARIABLE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLATE_TYPE_OBJECT_VARIABLE, GPlateObjectVariablePrivate))
+#define GPLATE_TYPE_OBJECT_VARIABLE_ITERATOR (gplate_object_variable_iterator_get_gtype()) +#define GPLATE_OBJECT_VARIABLE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLATE_TYPE_OBJECT_VARIABLE_ITERATOR, GPlateObjectVariableIterator)) +static GType gplate_object_variable_iterator_get_gtype(void); /******************************************************************************
*****************************************************************************/
@@ -45,23 +50,219 @@
} GPlateObjectVariablePrivate;
+ GPlateObjectVariable *objvar; +} GPlateObjectVariableIterator; +} GPlateObjectVariableIteratorClass; /******************************************************************************
*****************************************************************************/
static GObjectClass *parent_class = NULL;
+static GObjectClass *iterator_parent_class = NULL; +/****************************************************************************** + *****************************************************************************/ +gplate_variable_from_paramspec(GObject *obj, GParamSpec *pspec) { + GPlateVariable *variable = NULL; + const gchar *name = NULL; + /* initialize our value to the type of the pspec */ + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + name = g_param_spec_get_name(pspec); + g_object_get_property(obj, name, &value); + switch(G_PARAM_SPEC_VALUE_TYPE(pspec)) { + gplate_variable_new_from_string(name, + g_value_get_string(&value)); + gplate_variable_new_from_integer(name, + g_value_get_int(&value)); + gplate_variable_new_from_float(name, + g_value_get_float(&value)); + gplate_variable_new_from_double(name, + g_value_get_double(&value)); + variable = gplate_object_variable_new_from_object(name, + g_value_get_object(&value)); /******************************************************************************
+ * Iterator Interface Stuff + *****************************************************************************/ +gplate_object_variable_iterator_has_next(const GPlateIterator *iter) { + GPlateObjectVariableIterator *realiter = + GPLATE_OBJECT_VARIABLE_ITERATOR(iter); + return (realiter->current < realiter->total - 1); + return (realiter->elements != NULL); +gplate_object_variable_iterator_next(GPlateIterator *iter) { + GPlateObjectVariableIterator *realiter = NULL; + GParamSpec *pspec = NULL; + realiter = GPLATE_OBJECT_VARIABLE_ITERATOR(iter); + if(!realiter->inited) { + realiter->inited = TRUE; + if(realiter->current >= realiter->total) + pspec = realiter->elements[realiter->current]; + obj = gplate_object_variable_get_object(realiter->objvar); + return gplate_variable_from_paramspec(obj, pspec); +gplate_object_variable_iterator_iface_init(GPlateIteratorIface *iface) { + iface->has_next = gplate_object_variable_iterator_has_next; + iface->next = gplate_object_variable_iterator_next; +/****************************************************************************** + * Iterator Object Stuff + *****************************************************************************/ +gplate_object_variable_iterator_finalize(GObject *obj) { + GPlateObjectVariableIterator *iter = GPLATE_OBJECT_VARIABLE_ITERATOR(obj); + g_object_unref(iter->objvar); + g_free(iter->elements); + G_OBJECT_CLASS(iterator_parent_class)->finalize(obj); +gplate_object_variable_iterator_class_init( + GPlateObjectVariableIteratorClass *klass) + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + iterator_parent_class = g_type_class_peek_parent(klass); + obj_class->finalize = gplate_object_variable_iterator_finalize; +/****************************************************************************** + *****************************************************************************/ +gplate_object_variable_iterator_get_gtype(void) { + if(G_UNLIKELY(type == 0)) { + static const GTypeInfo info = { + sizeof(GPlateObjectVariableIteratorClass), + (GClassInitFunc)gplate_object_variable_iterator_class_init, + sizeof(GPlateObjectVariableIterator), + static const GInterfaceInfo iterator_info = { + (GInterfaceInitFunc)gplate_object_variable_iterator_iface_init, + type = g_type_register_static(G_TYPE_OBJECT, + "GPlateObjectVariableIterator", + g_type_add_interface_static(type, GPLATE_TYPE_ITERATOR, +gplate_object_variable_iterator_new(GPlateObjectVariable *objvar) { + GPlateIterator *iter = NULL; + GPlateObjectVariableIterator *realiter = NULL; + GPlateObjectVariablePrivate *priv = NULL; + GObjectClass *klass = NULL; + iter = g_object_new(GPLATE_TYPE_OBJECT_VARIABLE_ITERATOR, NULL); + realiter = GPLATE_OBJECT_VARIABLE_ITERATOR(iter); + realiter->objvar = g_object_ref(objvar); + priv = GPLATE_OBJECT_VARIABLE_GET_PRIVATE(objvar); + klass = G_OBJECT_GET_CLASS(priv->object); + realiter->elements = g_object_class_list_properties(klass, + realiter->inited = FALSE; +/****************************************************************************** + * Collection Interface Stuff *****************************************************************************/
gplate_object_variable_find_variable(const GPlateCollection *collection,
GPlateObjectVariablePrivate *priv = NULL;
- GPlateVariable *variable = NULL;
GParamSpec *pspec = NULL;
GObjectClass *obj_class = NULL;
gchar *aname = NULL, *dot = NULL;
g_return_val_if_fail(name, NULL);
@@ -94,48 +295,24 @@
if(!G_IS_PARAM_SPEC(pspec))
- /* We know the type early, so we'll initialize our value to that type */
- g_value_init(&val, G_PARAM_SPEC_VALUE_TYPE(pspec));
+ /* now we have the value, so let's create our variable */ + return gplate_variable_from_paramspec(priv->object, pspec); - /* now we have the value, so let's create our variable */
- switch(G_PARAM_SPEC_VALUE_TYPE(pspec)) {
- gplate_variable_new_from_string(g_param_spec_get_name(pspec),
- g_value_get_string(&val));
- gplate_variable_new_from_integer(g_param_spec_get_name(pspec),
- g_value_get_int(&val));
- gplate_variable_new_from_float(g_param_spec_get_name(pspec),
- g_value_get_float(&val));
- gplate_variable_new_from_double(g_param_spec_get_name(pspec),
- g_value_get_double(&val));
- variable = gplate_object_variable_new_from_object(
- g_param_spec_get_name(pspec),
- g_value_get_object(&val));
+gplate_object_variable_get_iterator(GPlateCollection *collection) { + GPlateObjectVariable *objvar = GPLATE_OBJECT_VARIABLE(collection); + return gplate_object_variable_iterator_new(objvar); gplate_object_variable_collection_init(GPlateCollectionIface *iface) {
iface->find_variable = gplate_object_variable_find_variable;
iface->add_variable_with_name = NULL;
+ iface->remove_variable = NULL; + iface->remove_all = NULL; + iface->get_iterator = gplate_object_variable_get_iterator; /******************************************************************************
--- a/tests/test-dictionary-variable.c Fri Oct 10 23:17:45 2008 -0500
+++ b/tests/test-dictionary-variable.c Sun Jan 04 02:02:57 2009 -0600
@@ -193,6 +193,7 @@