diff options
author | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-04-19 14:58:49 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-04-19 14:58:49 -0400 |
commit | 59289ffaf96f5db926755f97dc83e17b63836013 (patch) | |
tree | d89820e3c71beaca7ef2d6c7d7d810758acea987 | |
parent | 7b2ba6dfce48c9aa7df7c5e096bc74bd023b2efc (diff) |
Typesafe arrays
-rw-r--r-- | array.c | 10 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | dbus.c | 16 | ||||
-rw-r--r-- | libnul.h | 76 | ||||
-rw-r--r-- | prefix-test.c | 23 | ||||
-rw-r--r-- | signal-handler.c | 4 |
6 files changed, 97 insertions, 34 deletions
@@ -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) @@ -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); @@ -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 { |