From f9badfd50240e419a84ac15fb84b1affa71557a6 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 7 Jul 2019 11:37:48 +0000 Subject: [PATCH 1/5] Fix: Corrected double referencing of (x) in type checking macros that resulted in memory leaks --- include/igloo/ro.h | 11 +++++++---- src/ro.c | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/igloo/ro.h b/include/igloo/ro.h index ae5f5e8..4498990 100644 --- a/include/igloo/ro.h +++ b/include/igloo/ro.h @@ -89,22 +89,25 @@ struct igloo_ro_base_tag { int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap); /* ---[ END PRIVATE ]--- */ +igloo_ro_t igloo_RO_TO_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type); #ifdef IGLOO_CTC_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION #define igloo_RO__GETBASE(x) (((igloo_ro_t)(x)).subtype__igloo_ro_base_t) #define igloo_RO_NULL ((igloo_ro_t)(igloo_ro_base_t*)NULL) #define igloo_RO_IS_NULL(x) (igloo_RO__GETBASE((x)) == NULL) -#define igloo_RO_TO_TYPE(x,type) (igloo_RO_IS_VALID((x),type) ? ((igloo_ro_t)(x)).subtype__ ## type : NULL) +#define igloo_RO_TO_TYPE(x,type) (((igloo_ro_t)igloo_RO_TO_TYPE_raw((x), (igloo_ro__type__ ## type))).subtype__ ## type) #else #define igloo_RO__GETBASE(x) ((igloo_ro_base_t*)(x)) #define igloo_RO_NULL NULL #define igloo_RO_IS_NULL(x) ((x) == NULL) -#define igloo_RO_TO_TYPE(x,type) (igloo_RO_IS_VALID((x),type) ? (type*)(x) : (type*)NULL) +#define igloo_RO_TO_TYPE(x,type) ((type*)igloo_RO_TO_TYPE_raw((x), (igloo_ro__type__ ## type))) #endif #define igloo_RO_GET_TYPE(x) (igloo_RO__GETBASE((x)) == NULL ? NULL : igloo_RO__GETBASE((x))->type) #define igloo_RO_GET_TYPENAME(x) (igloo_RO_GET_TYPE((x)) == NULL ? NULL : igloo_RO_GET_TYPE((x))->type_name) -#define igloo_RO_IS_VALID(x,type) (!igloo_RO_IS_NULL((x)) && igloo_RO_GET_TYPE((x)) == (igloo_ro__type__ ## type) && igloo_RO__GETBASE((x))->refc) -#define igloo_RO_HAS_TYPE(x,type) (!igloo_RO_IS_NULL((x)) && igloo_RO_GET_TYPE((x)) == (type)) +int igloo_RO_IS_VALID_raw(igloo_ro_t object, const igloo_ro_type_t *type); +#define igloo_RO_IS_VALID(x,type) igloo_RO_IS_VALID_raw((x), (igloo_ro__type__ ## type)) +int igloo_RO_HAS_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type); +#define igloo_RO_HAS_TYPE(x,type) igloo_RO_HAS_TYPE_raw((x), (type)) /* Create a new refobject * The type argument gives the type for the new object, diff --git a/src/ro.c b/src/ro.c index 1e985d0..7f3c0a4 100644 --- a/src/ro.c +++ b/src/ro.c @@ -43,6 +43,29 @@ static inline int check_type(const igloo_ro_type_t *type) type->type_length >= sizeof(igloo_ro_base_t); } + +static inline int igloo_RO_HAS_TYPE_raw_il(igloo_ro_t object, const igloo_ro_type_t *type) +{ + return !igloo_RO_IS_NULL(object) && igloo_RO_GET_TYPE(object) == type; +} +int igloo_RO_HAS_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type) +{ + return igloo_RO_HAS_TYPE_raw_il(object, type); +} +static inline int igloo_RO_IS_VALID_raw_li(igloo_ro_t object, const igloo_ro_type_t *type) +{ + return igloo_RO_HAS_TYPE_raw_il(object, type) && igloo_RO__GETBASE(object)->refc; +} +int igloo_RO_IS_VALID_raw(igloo_ro_t object, const igloo_ro_type_t *type) +{ + return igloo_RO_IS_VALID_raw_li(object, type); +} +igloo_ro_t igloo_RO_TO_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type) +{ + return igloo_RO_IS_VALID_raw_li(object, type) ? object : igloo_RO_NULL; +} + + igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated) { igloo_ro_base_t *base; From d1e2abbddde9b61d8bb5293578f467bfe9d85a66 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 7 Jul 2019 16:01:06 +0000 Subject: [PATCH 2/5] Feature: Added additional functions to work with pure refobjects --- include/igloo/ro.h | 192 ++++++++++++++++++++++++++++++++++++++-- include/igloo/typedef.h | 4 + src/ro.c | 163 ++++++++++++++++++++++++++++++++++ 3 files changed, 352 insertions(+), 7 deletions(-) diff --git a/include/igloo/ro.h b/include/igloo/ro.h index 4498990..914acb2 100644 --- a/include/igloo/ro.h +++ b/include/igloo/ro.h @@ -24,6 +24,11 @@ extern "C" { #endif +#include + +#ifdef IGLOO_CTC_HAVE_STDINT_H +#include +#endif #include #include @@ -49,6 +54,106 @@ typedef void (*igloo_ro_free_t)(igloo_ro_t self); */ typedef int (*igloo_ro_new_t)(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap); +/* Type used to store flags for clone operations. + */ +#ifdef IGLOO_CTC_HAVE_STDINT_H +typedef uint_least32_t igloo_ro_cf_t; +#else +typedef unsigned long int igloo_ro_cf_t; +#endif + +/* No clone flags set. Usefull for variable initialization. */ +#define igloo_RO_CF_NONE ((igloo_ro_cf_t)0x0000) +/* Make a shallow copy of the object */ +#define igloo_RO_CF_SHALLOW ((igloo_ro_cf_t)0x0001) +/* Make a deep copy of the object */ +#define igloo_RO_CF_DEEP ((igloo_ro_cf_t)0x0002) +/* Make a copy of the object that shares part of it's state with the original. + * This is similar to using dup() on a POSIX filehandle. + * This is useful when interacting with IO. + */ +#define igloo_RO_CF_DUP ((igloo_ro_cf_t)0x0004) +/* Defaults to use if required and allowed is igloo_RO_CF_NONE */ +#define igloo_RO_CF_DEFAULT (igloo_RO_CF_SHALLOW|igloo_RO_CF_DEEP) + +/* Type uses for callback called when the object should be cloned. + * + * A clone of the object must never have the same address of the object that was cloned. + * + * Parameters: + * self + * The object to clone. + * required, allowed + * See igloo_ro_clone(). + * name, associated + * See igloo_ro_new(). + */ +typedef igloo_ro_t (*igloo_ro_clone_t)(igloo_ro_t self, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated); + +/* Type used for callback called when the object needs to be converted to another type. + * + * This callback is not used when a object of the same type is requested. + * On that case clone is requested. + * + * There are two cases that must be handled by the callback: + * 0) The object self is of the same type as this callback is set for and type is pointing to different type. + * 1) The object self is of any type and type is pointing to the type this callback was set to. + * + * If the callback can not convert it must return igloo_RO_NULL. + * + * Parameters: + * self + * The object to convert. + * type + * The type to convert to. + * required, allowed + * See igloo_ro_clone(). + * name, associated + * See igloo_ro_new(). + */ +typedef igloo_ro_t (*igloo_ro_convert_t)(igloo_ro_t self, const igloo_ro_type_t *type, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated); + +/* Type used for callback called when the object needs to be converted to a string. + * + * This is used mostly for debugging or preseting the object to the user. + * The callback is not expected to return a string that can be used to reconstruct the object. + */ +typedef char * (*igloo_ro_stringify_t)(igloo_ro_t self); + +/* Type used as a result of a compare between objects. + */ +typedef enum { + /* The objects could not be compared. + * Common cases may be that when one is NULL and the other is not NULL + * or when both are of difference types that can not be compared to each other + * (e.g. a IO handle and a buffer.) + */ + igloo_RO_CR__ERROR = -1, + /* Both objects represent the same thing but are not the same object. + * See also igloo_RO_CR_SAME. + */ + igloo_RO_CR_EQUAL = 0, + /* Both objects are distinct and no other relation can be applied. */ + igloo_RO_CR_NOTEQUAL, + /* Object A is less than object B. */ + igloo_RO_CR_ALESSTHANB, + /* Object A is greather than object B. */ + igloo_RO_CR_AGREATERTHANB, + /* Both objects are the same. + * That is then they share the same address in memory. + */ + igloo_RO_CR_SAME +} igloo_ro_cr_t; + +/* Type used for callback called then two objects must be compared. + * + * Object a is always a object that belongs to the type this callback was set for. + * Objects a, and b are not igloo_RO_NULL. + * Objects a, and b may be of diffrent type. + * Objects a, and b are not the same (See igloo_RO_CR_SAME). + */ +typedef igloo_ro_cr_t (*igloo_ro_compare_t)(igloo_ro_t a, igloo_ro_t b); + /* Meta type used to defined types. * DO NOT use any of the members in here directly! */ @@ -60,18 +165,27 @@ typedef int (*igloo_ro_new_t)(igloo_ro_t self, const igloo_ro_type_t *type, va_l */ struct igloo_ro_type_tag { /* Size of this control structure */ - size_t control_length; + size_t control_length; /* ABI version of this structure */ - int control_version; + int control_version; /* Total length of the objects to be created */ - size_t type_length; + size_t type_length; /* Name of type */ - const char * type_name; + const char * type_name; /* Callback to be called on final free() */ - igloo_ro_free_t type_freecb; - /* Callback to be callback by igloo_ro_new() */ - igloo_ro_new_t type_newcb; + igloo_ro_free_t type_freecb; + /* Callback to be called by igloo_ro_new() */ + igloo_ro_new_t type_newcb; + + /* Callback to be called by igloo_ro_clone() */ + igloo_ro_clone_t type_clonecb; + /* Callback to be called by igloo_ro_convert() */ + igloo_ro_convert_t type_convertcb; + /* Callback to be called by igloo_ro_stringify() */ + igloo_ro_stringify_t type_stringifycb; + /* Callback to be called by igloo_ro_compare() */ + igloo_ro_compare_t type_comparecb; }; struct igloo_ro_base_tag { /* Type of the object */ @@ -140,6 +254,70 @@ const char * igloo_ro_get_name(igloo_ro_t self); igloo_ro_t igloo_ro_get_associated(igloo_ro_t self); int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated); +/* Clone the given object returning a copy of it. + * + * This creates a copy of the passed object if possible. + * The mode of copy is selected by the parameters required and allowed. + * Both list flags of modes. Modes listed as required are adhered to. + * However the application may select any additional mode from the allowed + * flags. + * + * If both required and allowed are zero a set of default flags is applied + * as allowed flags. + * + * Parameters: + * self + * The object to copy. + * required + * Flags that must be adhered to when coping. + * allowed + * Flags that are allowed to be used. + * Flags that are listed as required are automatically added the list of allowed flags. + * name, associated + * See igloo_ro_new(). + */ +igloo_ro_t igloo_ro_clone(igloo_ro_t self, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated); + +/* Make a copy of a object but converts it to another type as well. + * + * This makes makes a copy of the object that is also of a diffrent type. + * If the type is the same as the type of self igloo_ro_clone() is called. + * + * Parameters: + * self + * The object to copy and convert. + * type + * The type to convert to. + * required, allowed + * See igloo_ro_clone(). + * name, associated + * See igloo_ro_new(). + */ +igloo_ro_t igloo_ro_convert(igloo_ro_t self, const igloo_ro_type_t *type, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated); + +/* Convert a object to a string. + * This is used for debugging and presenting to the user. + * + * The resulting string can not be used to recreate the object. + * + * Parameters: + * self + * The object to convert to a string. + * Returns: + * A string as allocated using malloc(3). The caller must call free(3). + */ +char * igloo_ro_stringify(igloo_ro_t self); + +/* Compare two objects. + * + * Parameters: + * a, b + * The objects to compare. + * Returns: + * Thre result of the compare. See igloo_ro_cr_t. + */ +igloo_ro_cr_t igloo_ro_compare(igloo_ro_t a, igloo_ro_t b); + #ifdef __cplusplus } #endif diff --git a/include/igloo/typedef.h b/include/igloo/typedef.h index e6d34f9..af5a108 100644 --- a/include/igloo/typedef.h +++ b/include/igloo/typedef.h @@ -49,6 +49,10 @@ static const igloo_ro_type_t igloo_ro__typedef__ ## type = \ #define igloo_RO_TYPEDECL_FREE(cb) .type_freecb = (cb) #define igloo_RO_TYPEDECL_NEW(cb) .type_newcb = (cb) #define igloo_RO_TYPEDECL_NEW_NOOP() .type_newcb = igloo_ro_new__return_zero +#define igloo_RO_TYPEDECL_CLONE(cb) .type_clonecb = (cb) +#define igloo_RO_TYPEDECL_CONVERT(cb) .type_convertcb = (cb) +#define igloo_RO_TYPEDECL_STRINGIFY(cb) .type_stringifycb = (cb) +#define igloo_RO_TYPEDECL_COMPARE(cb) .type_comparecb = (cb) #ifdef __cplusplus } diff --git a/src/ro.c b/src/ro.c index 7f3c0a4..5398458 100644 --- a/src/ro.c +++ b/src/ro.c @@ -21,6 +21,7 @@ #include #endif +#include #include #include @@ -309,3 +310,165 @@ int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated) return 0; } + +igloo_ro_t igloo_ro_clone(igloo_ro_t self, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated) +{ + igloo_ro_base_t *base = igloo_RO__GETBASE(self); + igloo_ro_t ret = igloo_RO_NULL; + + if (!base) + return igloo_RO_NULL; + + allowed |= required; + + if (!allowed) + allowed = igloo_RO_CF_DEFAULT; + + igloo_thread_mutex_lock(&(base->lock)); + if (!base->refc) { + igloo_thread_mutex_unlock(&(base->lock)); + return igloo_RO_NULL; + } + + if (base->type->type_clonecb) + ret = base->type->type_clonecb(self, required, allowed, name, associated); + igloo_thread_mutex_unlock(&(base->lock)); + + return ret; +} + +igloo_ro_t igloo_ro_convert(igloo_ro_t self, const igloo_ro_type_t *type, igloo_ro_cf_t required, igloo_ro_cf_t allowed, const char *name, igloo_ro_t associated) +{ + igloo_ro_base_t *base = igloo_RO__GETBASE(self); + igloo_ro_t ret = igloo_RO_NULL; + + if (!base || !type) + return igloo_RO_NULL; + + igloo_thread_mutex_lock(&(base->lock)); + if (!base->refc) { + igloo_thread_mutex_unlock(&(base->lock)); + return igloo_RO_NULL; + } + + if (base->type == type) { + igloo_thread_mutex_unlock(&(base->lock)); + return igloo_ro_clone(self, required, allowed, name, associated); + } + + allowed |= required; + + if (!allowed) + allowed = igloo_RO_CF_DEFAULT; + + if (base->type->type_convertcb) + ret = base->type->type_convertcb(self, type, required, allowed, name, associated); + + if (igloo_RO_IS_NULL(ret)) + if (type->type_convertcb) + ret = type->type_convertcb(self, type, required, allowed, name, associated); + igloo_thread_mutex_unlock(&(base->lock)); + + return ret; +} + +char * igloo_ro_stringify(igloo_ro_t self) +{ + igloo_ro_base_t *base = igloo_RO__GETBASE(self); + char *ret = NULL; + + if (!base) + return strdup("{igloo_RO_NULL}"); + + igloo_thread_mutex_lock(&(base->lock)); + if (!base->refc) { + int len; + char buf; + +#define STRINGIFY_FORMAT_WEAK "{%s@%p, weak}", base->type->type_name, base + len = snprintf(&buf, 1, STRINGIFY_FORMAT_WEAK); + if (len > 2) { + /* We add 2 bytes just to make sure no buggy interpretation of \0 inclusion could bite us. */ + ret = calloc(1, len + 2); + if (ret) { + snprintf(ret, len + 1, STRINGIFY_FORMAT_WEAK); + } + } + + igloo_thread_mutex_unlock(&(base->lock)); + return ret; + } + + if (base->type->type_stringifycb) { + ret = base->type->type_stringifycb(self); + } else { + int len; + char buf; + +#define STRINGIFY_FORMAT_FULL "{%s@%p, strong, name=\"%s\", associated=%p}", base->type->type_name, base, base->name, igloo_RO__GETBASE(base->associated) + len = snprintf(&buf, 1, STRINGIFY_FORMAT_FULL); + if (len > 2) { + /* We add 2 bytes just to make sure no buggy interpretation of \0 inclusion could bite us. */ + ret = calloc(1, len + 2); + if (ret) { + snprintf(ret, len + 1, STRINGIFY_FORMAT_FULL); + } + } + } + igloo_thread_mutex_unlock(&(base->lock)); + + return ret; +} + +igloo_ro_cr_t igloo_ro_compare(igloo_ro_t a, igloo_ro_t b) +{ + igloo_ro_base_t *base_a = igloo_RO__GETBASE(a); + igloo_ro_base_t *base_b = igloo_RO__GETBASE(b); + igloo_ro_cr_t ret = igloo_RO_CR__ERROR; + + if (base_a == base_b) + return igloo_RO_CR_SAME; + + if (!base_a || !base_b) + return igloo_RO_CR__ERROR; + + igloo_thread_mutex_lock(&(base_a->lock)); + igloo_thread_mutex_lock(&(base_b->lock)); + + if (!base_a->refc || !base_b->refc) { + igloo_thread_mutex_unlock(&(base_b->lock)); + igloo_thread_mutex_unlock(&(base_a->lock)); + return igloo_RO_CR__ERROR; + } + + if (base_a->type->type_comparecb) + ret = base_a->type->type_comparecb(a, b); + + if (ret == igloo_RO_CR__ERROR) { + ret = base_b->type->type_comparecb(b, a); + + /* we switched arguments here, so we need to reverse the result */ + switch (ret) { + case igloo_RO_CR__ERROR: + case igloo_RO_CR_EQUAL: + case igloo_RO_CR_NOTEQUAL: + /* those are the same in both directions */ + break; + case igloo_RO_CR_ALESSTHANB: + ret = igloo_RO_CR_AGREATERTHANB; + break; + case igloo_RO_CR_AGREATERTHANB: + ret = igloo_RO_CR_ALESSTHANB; + break; + default: + /* Cases we do not yet handle or that are not a valid result. */ + ret = igloo_RO_CR__ERROR; + break; + } + } + + igloo_thread_mutex_unlock(&(base_b->lock)); + igloo_thread_mutex_unlock(&(base_a->lock)); + + return ret; +} From b92d680fccfbdd11fbfe186dd0ef8dfb45cbe9f2 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 7 Jul 2019 16:02:54 +0000 Subject: [PATCH 3/5] Feature: Added igloo_ro_stringify() support to buffers --- include/igloo/buffer.h | 2 ++ src/buffer.c | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/igloo/buffer.h b/include/igloo/buffer.h index 107b7a4..f9749e2 100644 --- a/include/igloo/buffer.h +++ b/include/igloo/buffer.h @@ -81,6 +81,8 @@ void igloo_buffer_preallocate(igloo_buffer_t *buffer, size_t request); int igloo_buffer_get_data(igloo_buffer_t *buffer, const void **data, size_t *length); /* Gets data as a string. The string is '\0'-terminated. + * igloo_ro_stringify(buffer) will also return this buffer. + * * Parameters: * buffery * The buffer to operate on. diff --git a/src/buffer.c b/src/buffer.c index 49e21c2..55679b4 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -31,10 +31,12 @@ struct igloo_buffer_tag { }; static void __free(igloo_ro_t self); +static char * __stringify(igloo_ro_t self); igloo_RO_PUBLIC_TYPE(igloo_buffer_t, igloo_RO_TYPEDECL_FREE(__free), - igloo_RO_TYPEDECL_NEW_NOOP() + igloo_RO_TYPEDECL_NEW_NOOP(), + igloo_RO_TYPEDECL_STRINGIFY(__stringify) ); static void __free(igloo_ro_t self) @@ -139,6 +141,20 @@ int igloo_buffer_get_string(igloo_buffer_t *buffer, const char **string) return 0; } +static char * __stringify(igloo_ro_t self) +{ + igloo_buffer_t *buffer = igloo_RO_TO_TYPE(self, igloo_buffer_t); + const char *ret; + + if (!buffer) + return NULL; + + if (igloo_buffer_get_string(buffer, &ret) != 0) + return NULL; + + return strdup(ret); +} + int igloo_buffer_set_length(igloo_buffer_t *buffer, size_t length) { if (!buffer) From 732baaa895981286d379c25aa1511582593b335c Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Mon, 8 Jul 2019 07:39:36 +0000 Subject: [PATCH 4/5] Feature: Corrected tabs to spaces --- include/igloo/interface.h | 2 +- include/igloo/ro.h | 52 +++++++++++++++++++-------------------- include/igloo/typedef.h | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/include/igloo/interface.h b/include/igloo/interface.h index 45febc3..cfc5c9e 100644 --- a/include/igloo/interface.h +++ b/include/igloo/interface.h @@ -42,7 +42,7 @@ extern "C" { */ typedef int (*igloo_interface_free_t)(igloo_INTERFACE_BASIC_ARGS); -#define igloo_INTERFACE_DESCRIPTION_BASE__VERSION 1 +#define igloo_INTERFACE_DESCRIPTION_BASE__VERSION 1 typedef struct { size_t base_length; diff --git a/include/igloo/ro.h b/include/igloo/ro.h index 914acb2..66bbab7 100644 --- a/include/igloo/ro.h +++ b/include/igloo/ro.h @@ -174,9 +174,9 @@ struct igloo_ro_type_tag { /* Name of type */ const char * type_name; /* Callback to be called on final free() */ - igloo_ro_free_t type_freecb; + igloo_ro_free_t type_freecb; /* Callback to be called by igloo_ro_new() */ - igloo_ro_new_t type_newcb; + igloo_ro_new_t type_newcb; /* Callback to be called by igloo_ro_clone() */ igloo_ro_clone_t type_clonecb; @@ -188,16 +188,16 @@ struct igloo_ro_type_tag { igloo_ro_compare_t type_comparecb; }; struct igloo_ro_base_tag { - /* Type of the object */ + /* Type of the object */ const igloo_ro_type_t * type; - /* Reference counters */ + /* Reference counters */ size_t refc; size_t wrefc; - /* Mutex for igloo_ro_*(). */ + /* Mutex for igloo_ro_*(). */ igloo_mutex_t lock; - /* Name of the object. */ + /* Name of the object. */ char * name; - /* Associated objects */ + /* Associated objects */ igloo_ro_t associated; }; int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap); @@ -205,23 +205,23 @@ int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_l igloo_ro_t igloo_RO_TO_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type); #ifdef IGLOO_CTC_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION -#define igloo_RO__GETBASE(x) (((igloo_ro_t)(x)).subtype__igloo_ro_base_t) -#define igloo_RO_NULL ((igloo_ro_t)(igloo_ro_base_t*)NULL) -#define igloo_RO_IS_NULL(x) (igloo_RO__GETBASE((x)) == NULL) -#define igloo_RO_TO_TYPE(x,type) (((igloo_ro_t)igloo_RO_TO_TYPE_raw((x), (igloo_ro__type__ ## type))).subtype__ ## type) +#define igloo_RO__GETBASE(x) (((igloo_ro_t)(x)).subtype__igloo_ro_base_t) +#define igloo_RO_NULL ((igloo_ro_t)(igloo_ro_base_t*)NULL) +#define igloo_RO_IS_NULL(x) (igloo_RO__GETBASE((x)) == NULL) +#define igloo_RO_TO_TYPE(x,type) (((igloo_ro_t)igloo_RO_TO_TYPE_raw((x), (igloo_ro__type__ ## type))).subtype__ ## type) #else -#define igloo_RO__GETBASE(x) ((igloo_ro_base_t*)(x)) -#define igloo_RO_NULL NULL -#define igloo_RO_IS_NULL(x) ((x) == NULL) -#define igloo_RO_TO_TYPE(x,type) ((type*)igloo_RO_TO_TYPE_raw((x), (igloo_ro__type__ ## type))) +#define igloo_RO__GETBASE(x) ((igloo_ro_base_t*)(x)) +#define igloo_RO_NULL NULL +#define igloo_RO_IS_NULL(x) ((x) == NULL) +#define igloo_RO_TO_TYPE(x,type) ((type*)igloo_RO_TO_TYPE_raw((x), (igloo_ro__type__ ## type))) #endif -#define igloo_RO_GET_TYPE(x) (igloo_RO__GETBASE((x)) == NULL ? NULL : igloo_RO__GETBASE((x))->type) -#define igloo_RO_GET_TYPENAME(x) (igloo_RO_GET_TYPE((x)) == NULL ? NULL : igloo_RO_GET_TYPE((x))->type_name) +#define igloo_RO_GET_TYPE(x) (igloo_RO__GETBASE((x)) == NULL ? NULL : igloo_RO__GETBASE((x))->type) +#define igloo_RO_GET_TYPENAME(x) (igloo_RO_GET_TYPE((x)) == NULL ? NULL : igloo_RO_GET_TYPE((x))->type_name) int igloo_RO_IS_VALID_raw(igloo_ro_t object, const igloo_ro_type_t *type); -#define igloo_RO_IS_VALID(x,type) igloo_RO_IS_VALID_raw((x), (igloo_ro__type__ ## type)) +#define igloo_RO_IS_VALID(x,type) igloo_RO_IS_VALID_raw((x), (igloo_ro__type__ ## type)) int igloo_RO_HAS_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t *type); -#define igloo_RO_HAS_TYPE(x,type) igloo_RO_HAS_TYPE_raw((x), (type)) +#define igloo_RO_HAS_TYPE(x,type) igloo_RO_HAS_TYPE_raw((x), (type)) /* Create a new refobject * The type argument gives the type for the new object, @@ -229,12 +229,12 @@ int igloo_RO_HAS_TYPE_raw(igloo_ro_t object, const igloo_ro_type_t * * the associated refobject is given by associated. */ -igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated); -#define igloo_ro_new_raw(type, name, associated) igloo_RO_TO_TYPE(igloo_ro_new__raw((igloo_ro__type__ ## type), (name), (associated)), type) +igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated); +#define igloo_ro_new_raw(type, name, associated) igloo_RO_TO_TYPE(igloo_ro_new__raw((igloo_ro__type__ ## type), (name), (associated)), type) -igloo_ro_t igloo_ro_new__simple(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated, ...); -#define igloo_ro_new(type, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), NULL, igloo_RO_NULL, ## __VA_ARGS__), type) -#define igloo_ro_new_ext(type, name, associated, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), (name), (associated), ## __VA_ARGS__), type) +igloo_ro_t igloo_ro_new__simple(const igloo_ro_type_t *type, const char *name, igloo_ro_t associated, ...); +#define igloo_ro_new(type, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), NULL, igloo_RO_NULL, ## __VA_ARGS__), type) +#define igloo_ro_new_ext(type, name, associated, ...) igloo_RO_TO_TYPE(igloo_ro_new__simple((igloo_ro__type__ ## type), (name), (associated), ## __VA_ARGS__), type) /* This increases the reference counter of the object */ int igloo_ro_ref(igloo_ro_t self); @@ -251,8 +251,8 @@ int igloo_ro_weak_unref(igloo_ro_t self); const char * igloo_ro_get_name(igloo_ro_t self); /* This gets the object's associated object. */ -igloo_ro_t igloo_ro_get_associated(igloo_ro_t self); -int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated); +igloo_ro_t igloo_ro_get_associated(igloo_ro_t self); +int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated); /* Clone the given object returning a copy of it. * diff --git a/include/igloo/typedef.h b/include/igloo/typedef.h index af5a108..21f4f90 100644 --- a/include/igloo/typedef.h +++ b/include/igloo/typedef.h @@ -32,7 +32,7 @@ typedef struct igloo_ro_type_tag igloo_ro_type_t; #define igloo_RO_TYPE(type) type * subtype__ ## type; -#define igloo_RO__CONTROL_VERSION 1 +#define igloo_RO__CONTROL_VERSION 1 #define igloo_RO__DEFINE_TYPE(type, suffix, ...) \ static const igloo_ro_type_t igloo_ro__typedef__ ## type = \ { \ From a9e1d240e3d5d0c07b8c2590efdf7b8d1e304efe Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Mon, 8 Jul 2019 07:44:16 +0000 Subject: [PATCH 5/5] Update: Added fields for future use. --- include/igloo/ro.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/igloo/ro.h b/include/igloo/ro.h index 66bbab7..60d3ac4 100644 --- a/include/igloo/ro.h +++ b/include/igloo/ro.h @@ -173,6 +173,10 @@ struct igloo_ro_type_tag { size_t type_length; /* Name of type */ const char * type_name; + + /* STILL UNUSED: Parent type */ + const igloo_ro_type_t * type_parent; + /* Callback to be called on final free() */ igloo_ro_free_t type_freecb; /* Callback to be called by igloo_ro_new() */ @@ -199,6 +203,8 @@ struct igloo_ro_base_tag { char * name; /* Associated objects */ igloo_ro_t associated; + /* STILL UNUSED: Instance objects */ + igloo_ro_t instance; }; int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap); /* ---[ END PRIVATE ]--- */