summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-04-19 14:58:49 -0400
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-04-19 14:58:49 -0400
commit59289ffaf96f5db926755f97dc83e17b63836013 (patch)
treed89820e3c71beaca7ef2d6c7d7d810758acea987
parent7b2ba6dfce48c9aa7df7c5e096bc74bd023b2efc (diff)
Typesafe arrays
-rw-r--r--array.c10
-rw-r--r--configure.ac2
-rw-r--r--dbus.c16
-rw-r--r--libnul.h76
-rw-r--r--prefix-test.c23
-rw-r--r--signal-handler.c4
6 files changed, 97 insertions, 34 deletions
diff --git a/array.c b/array.c
index f8e9b82..f8341c0 100644
--- a/array.c
+++ b/array.c
@@ -212,31 +212,31 @@ array_len (const void *data, const int *magic)
static const int arr_t_magic;
nul_ptr_t
-nul_array_new (int element_size)
+nul_garray_new (int element_size)
{
return array_new (element_size, &arr_t_magic, 0);
}
nul_ptr_t
-nul_array_new_prefix (int element_size, int prefix_size)
+nul_garray_new_prefix (int element_size, int prefix_size)
{
return array_new (element_size, &arr_t_magic, prefix_size);
}
nul_ptr_t
-nul_array_append (nul_ptr_t arr, nul_ptr_t element)
+nul_garray_append (nul_ptr_t arr, nul_ptr_t element)
{
return array_append (arr, &arr_t_magic, element);
}
void
-nul_array_free (nul_ptr_t array)
+nul_garray_free (nul_ptr_t array)
{
array_free (array, &arr_t_magic);
}
gsize
-nul_array_len (const nul_ptr_t array)
+nul_garray_len (const nul_ptr_t array)
{
return array_len (array, &arr_t_magic);
}
diff --git a/configure.ac b/configure.ac
index 04d4993..69c997f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,6 +39,8 @@ if test "x$GCC" = "xyes"; then
fi
AC_C_CHAR_UNSIGNED
+AC_C_TYPEOF
+
AC_CONFIG_SUBDIRS(libffi)
diff --git a/dbus.c b/dbus.c
index d4a4fdc..7c69d9d 100644
--- a/dbus.c
+++ b/dbus.c
@@ -443,7 +443,7 @@ decode_arg (nul_arg_t **args,
break;
}
- *args = nul_array_append (*args, &arg);
+ *args = nul_array_append (*args, arg);
return TRUE;
}
@@ -495,7 +495,7 @@ fail:
memset (&arg, 0, sizeof (arg));
- *args = nul_array_append (*args, &arg);
+ *args = nul_array_append (*args, arg);
i++;
}
@@ -553,7 +553,7 @@ invoke (DBusConnection *connection,
nul_dbus_member_t *member,
DBusMessage *message)
{
- nul_arg_t *args = nul_array_new (sizeof (nul_arg_t));
+ nul_arg_t *args = nul_array_new (nul_arg_t);
DBusMessage *error_reply;
nul_dbus_parameter_t **inputs;
DBusHandlerResult result;
@@ -569,7 +569,7 @@ invoke (DBusConnection *connection,
arg.v_pointer = object->data;
- args = nul_array_append (args, &arg);
+ args = nul_array_append (args, arg);
inputs = (nul_dbus_parameter_t **)member->parameters;
@@ -591,7 +591,7 @@ invoke (DBusConnection *connection,
g_assert (parameter->out);
- args = nul_array_append (args, &arg);
+ args = nul_array_append (args, arg);
pa = &(args[nul_array_len (args) - 1].v_pointer);
@@ -1199,16 +1199,16 @@ on_reply (DBusPendingCall *pending,
outputs = (nul_dbus_parameter_t **)&(info->method->parameters[info->method->n_inputs]);
- args = nul_array_new (sizeof (nul_arg_t));
+ args = nul_array_new (nul_arg_t);
if (!decode_message (&args, reply, n_outputs, outputs, &err))
arg.v_pointer = err;
else
arg.v_pointer = NULL;
- args = nul_array_append (args, &arg); /* error */
+ args = nul_array_append (args, arg); /* error */
arg.v_pointer = info->data;
- args = nul_array_append (args, &arg);
+ args = nul_array_append (args, arg);
nul_fun_def_invoke (info->method->reply_fun, (nul_function_t)info->callback, args);
diff --git a/libnul.h b/libnul.h
index 3bf4106..766ea95 100644
--- a/libnul.h
+++ b/libnul.h
@@ -44,19 +44,36 @@
#define G_GNUC_WARN_UNUSED_RESULT
#endif /* __GNUC__ */
+#define NUL_COMPILE_TIME_ASSERT(condition,text) \
+ typedef char nul_error_##text[(condition)? 1 : -1]
+
#define NUL_UR G_GNUC_WARN_UNUSED_RESULT
typedef void * nul_ptr_t;
typedef void * const nul_const_ptr_t;
/*
- * Generic arrays
+ * Generic array implementation
*/
-nul_ptr_t nul_array_new (int element_size) NUL_UR;
-nul_ptr_t nul_array_new_prefix (int element_size, int prefix_size); NUL_UR;
-nul_ptr_t nul_array_append (nul_ptr_t array, nul_ptr_t element) NUL_UR;
-gsize nul_array_len (nul_ptr_t array);
-void nul_array_free (nul_ptr_t array);
+nul_ptr_t nul_garray_new (int element_size) NUL_UR;
+nul_ptr_t nul_garray_new_prefix (int element_size, int prefix_size) NUL_UR;
+nul_ptr_t nul_garray_append (nul_ptr_t array, nul_ptr_t element) NUL_UR;
+gsize nul_garray_len (nul_ptr_t array);
+void nul_garray_free (nul_ptr_t array);
+
+#define nul_array_new(type) _nul_array_new_impl(type)
+#define nul_array_append(array,value) _nul_array_append_impl(array,value)
+#define nul_array_len(array) nul_garray_len(array)
+#define nul_array_free(array) nul_garray_free(array)
+
+#define nul_prefix_array_new(type,member) \
+ _nul_prefix_array_new_impl(type,member)
+#define nul_prefix_array_append(array,member,value) \
+ _nul_prefix_array_append_impl(array,member,value)
+#define nul_prefix_array_len(array,member) \
+ _nul_prefix_array_len_impl(array,member)
+#define nul_prefix_array_free(array,member) \
+ _nul_prefix_array_free_impl(array,member)
/*
* Pointer arrays
@@ -320,4 +337,51 @@ void nul_dbus_invoke (nul_dbus_service_t *service,
gpointer data,
...);
+
+
+/* Implementation of the array macros */
+
+#define _NUL_TYPE_CHECK_ARRAY(array,value) \
+ NUL_COMPILE_TIME_ASSERT( \
+ __builtin_types_compatible_p(typeof (*array),typeof(value)), \
+ incompatible_types \
+ )
+
+#define _nul_array_new_impl(type) \
+ ((type *)nul_garray_new(sizeof(type)))
+
+#define _nul_array_append_impl(array,value) \
+ ((typeof (array)) \
+ nul_garray_append(array, ({ \
+ typeof (value) __nul_temp = value; \
+ _NUL_TYPE_CHECK_ARRAY(array,value); \
+ &__nul_temp; \
+ })))
+
+#define _nul_prefix_array_new_impl(type,member) \
+ ((type *)nul_garray_new_prefix( \
+ sizeof(((type *)NULL)->member[0]), \
+ NUL_STRUCT_OFFSET(type,member)))
+
+#define _nul_prefix_array_append_impl(array,member,value) \
+ ((typeof (array)) \
+ nul_garray_append(array, ({ \
+ typeof (value) __nul_temp = (value); \
+ _NUL_TYPE_CHECK_ARRAY(&((array)->member)[0], (value)); \
+ &__nul_temp; \
+ })))
+
+#define _nul_prefix_array_len_impl(array,member) \
+ ({ (void)((array)->member); \
+ nul_garray_len(array); \
+ })
+
+#define _nul_prefix_array_free_impl(array,member) \
+ ({ (void)((array)->member); \
+ nul_garray_free(array); \
+ })
+
+
+
+
#endif
diff --git a/prefix-test.c b/prefix-test.c
index 5c44562..ca1659d 100644
--- a/prefix-test.c
+++ b/prefix-test.c
@@ -16,25 +16,22 @@ int
main (void)
{
int i;
- prefixed_t *prefixed = nul_array_new_prefix (
- sizeof (int), NUL_STRUCT_OFFSET (prefixed_t, data));
-
+ prefixed_t *prefixed = nul_prefix_array_new (prefixed_t, data);
+ int *is = nul_array_new (int);
+
prefixed->a = 0xaaaaaaaa;
prefixed->b = 0xbbbbbbbb;
prefixed->x = "HI!";
- i = 0;
- prefixed = nul_array_append (prefixed, &i); i++;
- prefixed = nul_array_append (prefixed, &i); i++;
- prefixed = nul_array_append (prefixed, &i); i++;
- prefixed = nul_array_append (prefixed, &i); i++;
- prefixed = nul_array_append (prefixed, &i); i++;
- prefixed = nul_array_append (prefixed, &i); i++;
+ is = nul_array_append (is, i);
+
+ for (i = 0; i < 128; ++i)
+ prefixed = nul_prefix_array_append (prefixed, data, i);
- for (i = 0; i < nul_array_len (prefixed); ++i)
- {
+ for (i = 0; i < nul_garray_len (prefixed); ++i)
printf ("%d\n", prefixed->data[i]);
- }
+
+ printf ("a: %x b: %x, c: %s\n", prefixed->a, prefixed->b, prefixed->x);
return 0;
}
diff --git a/signal-handler.c b/signal-handler.c
index 01cf8c8..fb35c24 100644
--- a/signal-handler.c
+++ b/signal-handler.c
@@ -183,9 +183,9 @@ nul_signal_set_handler (int signo,
sigaction (signo, &watch->old_action, NULL);
signal_watch_free (watch);
-
- return TRUE;
}
+
+ return TRUE;
}
else
{