aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/camel-arg-collector.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/camel/camel-arg-collector.c b/camel/camel-arg-collector.c
new file mode 100644
index 0000000000..091cc82251
--- /dev/null
+++ b/camel/camel-arg-collector.c
@@ -0,0 +1,186 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * included in camel because it is not exported
+ * by gtk
+ *
+ * Bertrand Guiheneuf <Bertrand.Guiheneuf@aful.org>
+ */
+
+/* collect a single argument value from a va_list.
+ * this is implemented as a huge macro <shrug>, because we can't
+ * pass va_list variables by reference on some systems.
+ * the corresponding prototype would be:
+ * static inline gchar*
+ * gtk_arg_collect_value (GtkArg *arg,
+ * va_list var_args);
+ */
+#define CAMEL_ARG_COLLECT_VALUE(arg, var_args, _error) \
+G_STMT_START { \
+ gchar *error_msg; \
+ GtkType fundamental_type; \
+ \
+ fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type); \
+ if (fundamental_type > GTK_TYPE_FUNDAMENTAL_LAST) \
+ { \
+ fundamental_type = gtk_type_get_varargs_type (fundamental_type); \
+ if (!fundamental_type) \
+ fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type); \
+ } \
+ \
+ error_msg = NULL; \
+ switch (fundamental_type) \
+ { \
+ case GTK_TYPE_INVALID: \
+ error_msg = g_strdup ("invalid untyped argument"); \
+ break; \
+ \
+ case GTK_TYPE_NONE: \
+ /* we just ignore this type, since it arithmetically just requires \
+ * us to not move the var_args pointer any further. callers need to \
+ * check for the validity of GTK_TYPE_NONE themselves. \
+ * \
+ * error_msg = g_strdup ("invalid argument type `void'"); \
+ */ \
+ break; \
+ \
+ /* everything smaller than an int is guarranteed to be \
+ * passed as an int \
+ */ \
+ case GTK_TYPE_CHAR: \
+ GTK_VALUE_CHAR (*arg) = va_arg (var_args, gint); \
+ break; \
+ case GTK_TYPE_UCHAR: \
+ GTK_VALUE_UCHAR (*arg) = va_arg (var_args, guint); \
+ break; \
+ case GTK_TYPE_BOOL: \
+ GTK_VALUE_BOOL (*arg) = va_arg (var_args, gint); \
+ break; \
+ case GTK_TYPE_INT: \
+ GTK_VALUE_INT (*arg) = va_arg (var_args, gint); \
+ break; \
+ case GTK_TYPE_UINT: \
+ GTK_VALUE_UINT (*arg) = va_arg (var_args, guint); \
+ break; \
+ case GTK_TYPE_ENUM: \
+ GTK_VALUE_ENUM (*arg) = va_arg (var_args, gint); \
+ break; \
+ case GTK_TYPE_FLAGS: \
+ GTK_VALUE_FLAGS (*arg) = va_arg (var_args, guint); \
+ break; \
+ \
+ /* we collect longs as glongs since they differ in size with \
+ * integers on some platforms \
+ */ \
+ case GTK_TYPE_LONG: \
+ GTK_VALUE_LONG (*arg) = va_arg (var_args, glong); \
+ break; \
+ case GTK_TYPE_ULONG: \
+ GTK_VALUE_ULONG (*arg) = va_arg (var_args, gulong); \
+ break; \
+ \
+ /* floats are always passed as doubles \
+ */ \
+ case GTK_TYPE_FLOAT: \
+ /* GTK_VALUE_FLOAT (*arg) = va_arg (var_args, gfloat); */ \
+ GTK_VALUE_FLOAT (*arg) = va_arg (var_args, gdouble); \
+ break; \
+ case GTK_TYPE_DOUBLE: \
+ GTK_VALUE_DOUBLE (*arg) = va_arg (var_args, gdouble); \
+ break; \
+ \
+ /* collect pointer values \
+ */ \
+ case GTK_TYPE_STRING: \
+ GTK_VALUE_STRING (*arg) = va_arg (var_args, gchar*); \
+ break; \
+ case GTK_TYPE_POINTER: \
+ GTK_VALUE_POINTER (*arg) = va_arg (var_args, gpointer); \
+ break; \
+ case GTK_TYPE_BOXED: \
+ GTK_VALUE_BOXED (*arg) = va_arg (var_args, gpointer); \
+ break; \
+ \
+ /* structured types \
+ */ \
+ case GTK_TYPE_SIGNAL: \
+ GTK_VALUE_SIGNAL (*arg).f = va_arg (var_args, GtkSignalFunc); \
+ GTK_VALUE_SIGNAL (*arg).d = va_arg (var_args, gpointer); \
+ break; \
+ case GTK_TYPE_ARGS: \
+ GTK_VALUE_ARGS (*arg).n_args = va_arg (var_args, gint); \
+ GTK_VALUE_ARGS (*arg).args = va_arg (var_args, GtkArg*); \
+ break; \
+ case GTK_TYPE_FOREIGN: \
+ GTK_VALUE_FOREIGN (*arg).data = va_arg (var_args, gpointer); \
+ GTK_VALUE_FOREIGN (*arg).notify = va_arg (var_args, GtkDestroyNotify); \
+ break; \
+ case GTK_TYPE_CALLBACK: \
+ GTK_VALUE_CALLBACK (*arg).marshal = va_arg (var_args, GtkCallbackMarshal); \
+ GTK_VALUE_CALLBACK (*arg).data = va_arg (var_args, gpointer); \
+ GTK_VALUE_CALLBACK (*arg).notify = va_arg (var_args, GtkDestroyNotify); \
+ break; \
+ case GTK_TYPE_C_CALLBACK: \
+ GTK_VALUE_C_CALLBACK (*arg).func = va_arg (var_args, GtkFunction); \
+ GTK_VALUE_C_CALLBACK (*arg).func_data = va_arg (var_args, gpointer); \
+ break; \
+ \
+ /* we do some extra sanity checking when collecting objects, \
+ * i.e. if the object pointer is not NULL, we check whether we \
+ * actually got an object pointer within the desired class branch. \
+ */ \
+ case GTK_TYPE_OBJECT: \
+ GTK_VALUE_OBJECT (*arg) = va_arg (var_args, GtkObject*); \
+ if (GTK_VALUE_OBJECT (*arg) != NULL) \
+ { \
+ register GtkObject *object = GTK_VALUE_OBJECT (*arg); \
+ \
+ if (object->klass == NULL) \
+ error_msg = g_strconcat ("invalid unclassed object pointer for argument type `", \
+ gtk_type_name (arg->type), \
+ "'", \
+ NULL); \
+ else if (!gtk_type_is_a (GTK_OBJECT_TYPE (object), arg->type)) \
+ error_msg = g_strconcat ("invalid object `", \
+ gtk_type_name (GTK_OBJECT_TYPE (object)), \
+ "' for argument type `", \
+ gtk_type_name (arg->type), \
+ "'", \
+ NULL); \
+ } \
+ break; \
+ \
+ default: \
+ error_msg = g_strconcat ("unsupported argument type `", \
+ gtk_type_name (arg->type), \
+ "'", \
+ NULL); \
+ break; \
+ } \
+ \
+ _error = error_msg; /* return error_msg; */ \
+} G_STMT_END