grim/gplate

merge of 'ad45b7942249101de7d7c776f41c95038f606a2e'
template_cleanup
2009-01-04, grim
809a0bef00d1
merge of 'ad45b7942249101de7d7c776f41c95038f606a2e'
and 'e8c2c372863dd1c635334abd2565520ad49222b6'
--- a/ChangeLog Thu Sep 25 02:33:39 2008 -0500
+++ b/ChangeLog Sun Jan 04 02:01:01 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
an empty string
--- a/README Thu Sep 25 02:33:39 2008 -0500
+++ b/README Sun Jan 04 02:01:01 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
+variables.
+
--- a/autogen.sh Thu Sep 25 02:33:39 2008 -0500
+++ b/autogen.sh Sun Jan 04 02:01:01 2009 -0600
@@ -1,5 +1,4 @@
#!/bin/sh
-# rapture - the final apt mirror
# Copyright (C) 2008 Gary Kramlich <grim@reaperworld.com>
#
# This program is free software; you can redistribute it and/or modify it
@@ -33,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
#
@@ -59,6 +59,9 @@
INTLTOOLIZE_CMD="intltoolize"
INTLTOOLIZE_FLAGS="-c -f --automake"
+GTKDOCIZE_CMD="gtkdocize"
+GTKDOCIZE_FLAGS="--copy"
+
ACLOCAL_CMD="aclocal"
ACLOCAL_FLAGS=""
@@ -93,7 +96,7 @@
BIN=`which ${CMD}`
if [ x"${BIN}" = x"" ] ; then
- echo "not found.\n"
+ echo "not found."
echo "${CMD} is required to build ${PACKAGE}!"
exit 1;
fi
@@ -105,7 +108,7 @@
CMD=$1
shift
- 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
@@ -160,6 +163,7 @@
###############################################################################
check "${LIBTOOLIZE_CMD}"; LIBTOOLIZE=${BIN};
check "${INTLTOOLIZE_CMD}"; INTLTOOLIZE=${BIN};
+check "${GTKDOCIZE_CMD}"; GTKDOCIZE=${BIN};
check "${ACLOCAL_CMD}"; ACLOCAL=${BIN};
check "${AUTOHEADER_CMD}"; AUTOHEADER=${BIN};
check "${AUTOMAKE_CMD}"; AUTOMAKE=${BIN};
@@ -170,6 +174,7 @@
###############################################################################
run_or_die ${LIBTOOLIZE} ${LIBTOOLIZE_FLAGS}
run_or_die ${INTLTOOLIZE} ${INTLTOOLIZE_FLAGS}
+run_or_die ${GTKDOCIZE} ${GTKDOCIZE_FLAGS}
run_or_die ${ACLOCAL} ${ACLOCAL_FLAGS}
run_or_die ${AUTOHEADER} ${AUTOHEADER_FLAGS}
run_or_die ${AUTOMAKE} ${AUTOMAKE_FLAGS}
@@ -178,6 +183,6 @@
###############################################################################
# Run configure
###############################################################################
-echo "running './configure ${CONFIGURE_FLAGS} $@'"
-./configure ${CONFIGURE_FLAGS} $@
+echo "running ./configure ${CONFIGURE_ARGS} $@"
+./configure ${CONFIGURE_ARGS} $@
--- a/configure.ac Thu Sep 25 02:33:39 2008 -0500
+++ b/configure.ac Sun Jan 04 02:01:01 2009 -0600
@@ -3,7 +3,7 @@
dnl ################################################################
dnl # Initialize autoconf
dnl ################################################################
-AC_INIT(gplate, 0.0.2, guifications-devel@lists.guifications.org)
+AC_INIT(gplate, 0.0.3mtn, guifications-devel@lists.guifications.org)
AC_PREREQ(2.50)
AC_CANONICAL_SYSTEM
AC_CONFIG_SRCDIR(config.h.in)
@@ -14,7 +14,7 @@
dnl ################################################################
GPLATE_MAJOR_VERSION=0
GPLATE_MINOR_VERSION=0
-GPLATE_MICRO_VERSION=2
+GPLATE_MICRO_VERSION=3
GPLATE_DEVEL_VERSION=0
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_MSG_RESULT(no)
CFLAGS_save="$CFLAGS"
AC_PROG_CC
CFLAGS="$CFLAGS_save"
-AC_ARG_ENABLE(debug, [ --enable-debug compile with debugging support],,enable_debug=no)
+AC_ARG_ENABLE(debug,
+ AC_HELP_STRING([--enable-debug],[compile with debugging support])
+ ,,enable_debug=no)
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_ARG_ENABLE(tests,
+ AC_HELP_STRING([--enable-tests],[build test programs])
+ ,,enable_tests=no)
CHECK_CFLAGS=
CHECK_LIBS=
--- a/gplate/functions/gplate-for-function.c Thu Sep 25 02:33:39 2008 -0500
+++ b/gplate/functions/gplate-for-function.c Sun Jan 04 02:01:01 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);
- GPlateTag *tag = NULL;
GPlateVariable *var = NULL;
+ gchar *output = NULL;
guint count = 1;
gboolean ret = FALSE;
@@ -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;
- gchar *output = NULL;
-
- contents = gplate_tag_get_contents(tag);
-
- if(contents && g_utf8_collate(contents, "endfor") == 0)
- break;
-
- output = gplate_template_render_tag(tplate, tag);
-
- g_string_append_printf(str, "%s", output);
-
- count++;
- }
+ output = gplate_template_render_until(tplate, &count,
+ GPLATE_TYPE_CODE_TAG, "endfor",
+ NULL);
+ 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 Thu Sep 25 02:33:39 2008 -0500
+++ b/gplate/gplate-template.c Sun Jan 04 02:01:01 2009 -0600
@@ -700,14 +700,28 @@
return ret;
}
+/**
+ * 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.
+ *
+ *
+ */
gchar *
-gplate_template_render_until(GPlateTemplate *tplate, ...) {
+gplate_template_render_until(GPlateTemplate *tplate, guint *ntags, ...) {
GPlateTag *tag = NULL;
GList *l = NULL;
GString *str = NULL;
GQueue *queue = NULL;
+ GType type = G_TYPE_INVALID;
gchar *ret = NULL;
- gchar *contents = NULL;
+ guint count = 0;
+ gboolean backup = FALSE;
va_list args;
g_return_val_if_fail(GPLATE_IS_TEMPLATE(tplate), NULL);
@@ -717,14 +731,17 @@
queue = g_queue_new();
/* store all of the content/tag pairs */
- va_start(args, tplate);
- while((contents = va_arg(args, gchar *)) != NULL) {
+ va_start(args, ntags);
+ while((type = va_arg(args, gsize)) != G_TYPE_INVALID) {
GPlateTemplateTagData *td = NULL;
+ gchar *contents = NULL;
td = g_new(GPlateTemplateTagData, 1);
- td->contents = contents;
- td->type = va_arg(args, GType);
+ contents = va_arg(args, gchar *);
+ td->contents = contents ? g_strdup(contents) : NULL;
+
+ td->type = type;
g_queue_push_tail(queue, td);
}
@@ -746,16 +763,21 @@
g_utf8_collate(ctd.contents, td->contents) == 0)
{
stop = TRUE;
+ backup = TRUE;
}
}
g_free(ctd.contents);
- if(stop)
+ if(stop) {
+ count++;
break;
+ }
g_string_append_printf(str, "%s",
gplate_template_render_tag(tplate, tag));
+
+ count++;
}
/* now clean everything up... */
@@ -771,6 +793,18 @@
ret = str->str;
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.
+ */
+ if(backup) {
+ gplate_template_previous_tag(tplate);
+ count--;
+ }
+
+ if(ntags)
+ *ntags = count;
+
return ret;
}
@@ -846,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.
*/
GPlateTag *
gplate_template_next_tag(GPlateTemplate *tplate) {
@@ -950,7 +984,7 @@
klass->insert_tags(tplate, tags);
}
-gchar *
+static gchar *
gplate_template_render_token(GPlateTemplate *tplate, const gchar *contents,
GType tag, GError **error)
{
--- a/gplate/gplate-template.h Thu Sep 25 02:33:39 2008 -0500
+++ b/gplate/gplate-template.h Sun Jan 04 02:01:01 2009 -0600
@@ -76,7 +76,7 @@
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, ...);
+gchar *gplate_template_render_until(GPlateTemplate *tplate, guint *ntags, ...);
GPlateTag *gplate_template_first_tag(GPlateTemplate *tplate);
GPlateTag *gplate_template_last_tag(GPlateTemplate *tplate);
--- a/gplate/variables/gplate-object-variable.c Thu Sep 25 02:33:39 2008 -0500
+++ b/gplate/variables/gplate-object-variable.c Sun Jan 04 02:01:01 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);
+
/******************************************************************************
* Enums
*****************************************************************************/
@@ -45,23 +50,219 @@
GObject *object;
} GPlateObjectVariablePrivate;
+typedef struct {
+ GObject gparent;
+
+ GPlateObjectVariable *objvar;
+
+ gboolean inited;
+
+ GParamSpec **elements;
+ guint current;
+ guint total;
+} GPlateObjectVariableIterator;
+
+typedef struct {
+ GObjectClass gparent;
+} GPlateObjectVariableIteratorClass;
+
/******************************************************************************
* Globals
*****************************************************************************/
static GObjectClass *parent_class = NULL;
+static GObjectClass *iterator_parent_class = NULL;
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static GPlateVariable *
+gplate_variable_from_paramspec(GObject *obj, GParamSpec *pspec) {
+ GPlateVariable *variable = NULL;
+ GValue value = { 0, };
+ 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)) {
+ case G_TYPE_STRING:
+ variable =
+ gplate_variable_new_from_string(name,
+ g_value_get_string(&value));
+ break;
+ case G_TYPE_INT:
+ variable =
+ gplate_variable_new_from_integer(name,
+ g_value_get_int(&value));
+ break;
+ case G_TYPE_FLOAT:
+ variable =
+ gplate_variable_new_from_float(name,
+ g_value_get_float(&value));
+ break;
+ case G_TYPE_DOUBLE:
+ variable =
+ gplate_variable_new_from_double(name,
+ g_value_get_double(&value));
+ break;
+ case G_TYPE_OBJECT:
+ variable = gplate_object_variable_new_from_object(name,
+ g_value_get_object(&value));
+ break;
+ default:
+ variable = NULL;
+ break;
+ }
+
+ return variable;
+}
/******************************************************************************
- * Interface Stuff
+ * Iterator Interface Stuff
+ *****************************************************************************/
+static gboolean
+gplate_object_variable_iterator_has_next(const GPlateIterator *iter) {
+ GPlateObjectVariableIterator *realiter =
+ GPLATE_OBJECT_VARIABLE_ITERATOR(iter);
+
+ if(realiter->inited)
+ return (realiter->current < realiter->total - 1);
+ else
+ return (realiter->elements != NULL);
+
+ return FALSE;
+}
+
+static GPlateVariable *
+gplate_object_variable_iterator_next(GPlateIterator *iter) {
+ GPlateObjectVariableIterator *realiter = NULL;
+ GObject *obj = NULL;
+ GParamSpec *pspec = NULL;
+
+ realiter = GPLATE_OBJECT_VARIABLE_ITERATOR(iter);
+
+ if(!realiter->inited) {
+ realiter->current = 0;
+ realiter->inited = TRUE;
+ } else {
+ realiter->current++;
+ }
+
+ if(realiter->current >= realiter->total)
+ return NULL;
+
+ pspec = realiter->elements[realiter->current];
+
+ obj = gplate_object_variable_get_object(realiter->objvar);
+
+ return gplate_variable_from_paramspec(obj, pspec);
+}
+
+static void
+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
+ *****************************************************************************/
+static void
+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);
+}
+
+static void
+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;
+}
+
+/******************************************************************************
+ * Iterator API
+ *****************************************************************************/
+static GType
+gplate_object_variable_iterator_get_gtype(void) {
+ static GType type = 0;
+
+ if(G_UNLIKELY(type == 0)) {
+ static const GTypeInfo info = {
+ sizeof(GPlateObjectVariableIteratorClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)gplate_object_variable_iterator_class_init,
+ NULL,
+ NULL,
+ sizeof(GPlateObjectVariableIterator),
+ 0,
+ NULL,
+ };
+
+ static const GInterfaceInfo iterator_info = {
+ (GInterfaceInitFunc)gplate_object_variable_iterator_iface_init,
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "GPlateObjectVariableIterator",
+ &info, 0);
+
+ g_type_add_interface_static(type, GPLATE_TYPE_ITERATOR,
+ &iterator_info);
+ }
+
+ return type;
+}
+
+static GPlateIterator *
+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->total);
+
+ realiter->current = 0;
+ realiter->inited = FALSE;
+
+ return iter;
+}
+
+/******************************************************************************
+ * Collection Interface Stuff
*****************************************************************************/
static GPlateVariable *
gplate_object_variable_find_variable(const GPlateCollection *collection,
const gchar *name)
{
GPlateObjectVariablePrivate *priv = NULL;
- GPlateVariable *variable = NULL;
GParamSpec *pspec = NULL;
GObjectClass *obj_class = NULL;
- GValue val = { 0, };
gchar *aname = NULL, *dot = NULL;
g_return_val_if_fail(name, NULL);
@@ -94,48 +295,24 @@
if(!G_IS_PARAM_SPEC(pspec))
return NULL;
- /* 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)) {
- case G_TYPE_STRING:
- variable =
- gplate_variable_new_from_string(g_param_spec_get_name(pspec),
- g_value_get_string(&val));
- break;
- case G_TYPE_INT:
- variable =
- gplate_variable_new_from_integer(g_param_spec_get_name(pspec),
- g_value_get_int(&val));
- break;
- case G_TYPE_FLOAT:
- variable =
- gplate_variable_new_from_float(g_param_spec_get_name(pspec),
- g_value_get_float(&val));
- break;
- case G_TYPE_DOUBLE:
- variable =
- gplate_variable_new_from_double(g_param_spec_get_name(pspec),
- g_value_get_double(&val));
- break;
- case G_TYPE_OBJECT:
- variable = gplate_object_variable_new_from_object(
- g_param_spec_get_name(pspec),
- g_value_get_object(&val));
- break;
- default:
- variable = NULL;
- break;
- }
-
- return variable;
+static GPlateIterator *
+gplate_object_variable_get_iterator(GPlateCollection *collection) {
+ GPlateObjectVariable *objvar = GPLATE_OBJECT_VARIABLE(collection);
+
+ return gplate_object_variable_iterator_new(objvar);
}
static void
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;
}
/******************************************************************************