]> Pileus Git - ~andy/gtk/blob - gtk/gtkargcollector.c
reverted bogus and undocumented!!! changes from Jay Cox (98/11/23
[~andy/gtk] / gtk / gtkargcollector.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /* collect a single argument value from a va_list.
21  * this is implemented as a huge macro <shrug>, because we can't
22  * pass va_list variables by reference on some systems.
23  * the corresponding prototype would be:
24  * static inline gchar*
25  * gtk_arg_collect_value (GtkArg  *arg,
26  *                        va_list  var_args);
27  */
28 #define GTK_ARG_COLLECT_VALUE(arg, var_args, _error)    \
29 G_STMT_START { \
30   gchar *error_msg; \
31   GtkType fundamental_type; \
32   \
33   fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type); \
34   if (fundamental_type > GTK_TYPE_FUNDAMENTAL_LAST) \
35     { \
36       fundamental_type = gtk_type_get_varargs_type (fundamental_type); \
37       if (!fundamental_type) \
38         fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type); \
39     } \
40  \
41   error_msg = NULL; \
42   switch (fundamental_type) \
43     { \
44     case GTK_TYPE_INVALID: \
45       error_msg = g_strdup ("invalid untyped argument"); \
46       break; \
47  \
48     case GTK_TYPE_NONE: \
49       /* we just ignore this type, since it arithmetically just requires \
50        * us to not move the var_args pointer any further. callers need to \
51        * check for the validity of GTK_TYPE_NONE themselves. \
52        * \
53        * error_msg = g_strdup ("invalid argument type `void'"); \
54        */ \
55       break; \
56  \
57       /* everything smaller than an int is guarranteed to be \
58        * passed as an int \
59        */ \
60     case GTK_TYPE_CHAR: \
61       GTK_VALUE_CHAR (*arg) = va_arg (var_args, gint); \
62       break; \
63     case GTK_TYPE_UCHAR: \
64       GTK_VALUE_UCHAR (*arg) = va_arg (var_args, guint); \
65       break; \
66     case GTK_TYPE_BOOL: \
67       GTK_VALUE_BOOL (*arg) = va_arg (var_args, gint); \
68       break; \
69     case GTK_TYPE_INT: \
70       GTK_VALUE_INT (*arg) = va_arg (var_args, gint); \
71       break; \
72     case GTK_TYPE_UINT: \
73       GTK_VALUE_UINT (*arg) = va_arg (var_args, guint); \
74       break; \
75     case GTK_TYPE_ENUM: \
76       GTK_VALUE_ENUM (*arg) = va_arg (var_args, gint); \
77       break; \
78     case GTK_TYPE_FLAGS: \
79       GTK_VALUE_FLAGS (*arg) = va_arg (var_args, guint); \
80       break; \
81  \
82       /* we collect longs as glongs since they differ in size with \
83        * integers on some platforms \
84        */ \
85     case GTK_TYPE_LONG: \
86       GTK_VALUE_LONG (*arg) = va_arg (var_args, glong); \
87       break; \
88     case GTK_TYPE_ULONG: \
89       GTK_VALUE_ULONG (*arg) = va_arg (var_args, gulong); \
90       break; \
91  \
92       /* floats are always passed as doubles \
93        */ \
94     case GTK_TYPE_FLOAT: \
95       /* GTK_VALUE_FLOAT (*arg) = va_arg (var_args, gfloat); */ \
96       GTK_VALUE_FLOAT (*arg) = va_arg (var_args, gdouble); \
97       break; \
98     case GTK_TYPE_DOUBLE: \
99       GTK_VALUE_DOUBLE (*arg) = va_arg (var_args, gdouble); \
100       break; \
101  \
102       /* collect pointer values \
103        */ \
104     case GTK_TYPE_STRING: \
105       GTK_VALUE_STRING (*arg) = va_arg (var_args, gchar*); \
106       break; \
107     case GTK_TYPE_POINTER: \
108       GTK_VALUE_POINTER (*arg) = va_arg (var_args, gpointer); \
109       break; \
110     case GTK_TYPE_BOXED: \
111       GTK_VALUE_BOXED (*arg) = va_arg (var_args, gpointer); \
112       break; \
113  \
114       /* structured types \
115        */ \
116     case GTK_TYPE_SIGNAL: \
117       GTK_VALUE_SIGNAL (*arg).f = va_arg (var_args, GtkSignalFunc); \
118       GTK_VALUE_SIGNAL (*arg).d = va_arg (var_args, gpointer); \
119       break; \
120     case GTK_TYPE_ARGS: \
121       GTK_VALUE_ARGS (*arg).n_args = va_arg (var_args, gint); \
122       GTK_VALUE_ARGS (*arg).args = va_arg (var_args, GtkArg*); \
123       break; \
124     case GTK_TYPE_FOREIGN: \
125       GTK_VALUE_FOREIGN (*arg).data = va_arg (var_args, gpointer); \
126       GTK_VALUE_FOREIGN (*arg).notify = va_arg (var_args, GtkDestroyNotify); \
127       break; \
128     case GTK_TYPE_CALLBACK: \
129       GTK_VALUE_CALLBACK (*arg).marshal = va_arg (var_args, GtkCallbackMarshal); \
130       GTK_VALUE_CALLBACK (*arg).data = va_arg (var_args, gpointer); \
131       GTK_VALUE_CALLBACK (*arg).notify = va_arg (var_args, GtkDestroyNotify); \
132       break; \
133     case GTK_TYPE_C_CALLBACK: \
134       GTK_VALUE_C_CALLBACK (*arg).func = va_arg (var_args, GtkFunction); \
135       GTK_VALUE_C_CALLBACK (*arg).func_data = va_arg (var_args, gpointer); \
136       break; \
137  \
138       /* we do some extra sanity checking when collecting objects, \
139        * i.e. if the object pointer is not NULL, we check whether we \
140        * actually got an object pointer within the desired class branch. \
141        */ \
142     case GTK_TYPE_OBJECT: \
143       GTK_VALUE_OBJECT (*arg) = va_arg (var_args, GtkObject*); \
144       if (GTK_VALUE_OBJECT (*arg) != NULL) \
145         { \
146           register GtkObject *object = GTK_VALUE_OBJECT (*arg); \
147            \
148           if (object->klass == NULL) \
149             error_msg = g_strconcat ("invalid unclassed object pointer for argument type `", \
150                                      gtk_type_name (arg->type), \
151                                      "'", \
152                                      NULL); \
153           else if (!gtk_type_is_a (GTK_OBJECT_TYPE (object), arg->type)) \
154             error_msg = g_strconcat ("invalid object `", \
155                                      gtk_type_name (GTK_OBJECT_TYPE (object)), \
156                                      "' for argument type `", \
157                                      gtk_type_name (arg->type), \
158                                      "'", \
159                                      NULL); \
160         } \
161       break; \
162  \
163     default: \
164       error_msg = g_strconcat ("unsupported argument type `", \
165                                gtk_type_name (arg->type), \
166                                "'", \
167                                NULL); \
168       break; \
169     } \
170    \
171   _error = error_msg; /* return error_msg; */ \
172 } G_STMT_END