diff --git a/src/ucs/type/class.c b/src/ucs/type/class.c index ce00bb832df..949acb5dfba 100644 --- a/src/ucs/type/class.c +++ b/src/ucs/type/class.c @@ -32,6 +32,8 @@ void _ucs_class_call_cleanup_chain(ucs_class_t *cls, void *obj, int limit) ucs_class_t *c; int depth, skip; + ucs_assert((limit == -1) || (limit >= 1)); + /* Count how many classes are there */ for (depth = 0, c = cls; c != NULL; ++depth, c = c->superclass); diff --git a/src/ucs/type/class.h b/src/ucs/type/class.h index 991c51edc0a..073823d5083 100644 --- a/src/ucs/type/class.h +++ b/src/ucs/type/class.h @@ -53,8 +53,8 @@ struct ucs_class { * Class initialization/cleanup function prototypes. */ #define UCS_CLASS_INIT_FUNC(_type, ...) \ - ucs_status_t _UCS_CLASS_INIT_NAME(_type)(_type *self, ## __VA_ARGS__, \ - ucs_class_t *_myclass, int *_init_count) + ucs_status_t _UCS_CLASS_INIT_NAME(_type)(_type *self, ucs_class_t *_myclass, \ + int *_init_count, ## __VA_ARGS__) #define UCS_CLASS_CLEANUP_FUNC(_type) \ void _UCS_CLASS_CLEANUP_NAME(_type)(_type *self) @@ -89,10 +89,11 @@ struct ucs_class { ({ \ UCS_CLASS_DECLARE(_type) \ ucs_class_t *cls = &_UCS_CLASS_DECL_NAME(_type); \ - int init_count = 0; \ + int init_count = 1; \ ucs_status_t status; \ \ - status = _UCS_CLASS_INIT_NAME(_type)((_type*)(_obj), ## __VA_ARGS__, cls, &init_count); \ + status = _UCS_CLASS_INIT_NAME(_type)((_type*)(_obj), cls, &init_count, \ + ## __VA_ARGS__); \ if (status != UCS_OK) { \ _ucs_class_call_cleanup_chain(&_UCS_CLASS_DECL_NAME(_type), \ (_obj), init_count); \ @@ -170,13 +171,16 @@ struct ucs_class { */ #define UCS_CLASS_CALL_SUPER_INIT(...) \ { \ + ucs_assert(*_init_count >= 1); \ ucs_status_t status = \ - _myclass->superclass->init(self, ## __VA_ARGS__, \ - _myclass->superclass, _init_count); \ + _myclass->superclass->init(self, _myclass->superclass, _init_count, \ + ## __VA_ARGS__); \ if (status != UCS_OK) { \ return status; \ } \ - ++(*_init_count); \ + if (_myclass->superclass != &_UCS_CLASS_DECL_NAME(void)) { \ + ++(*_init_count); \ + } \ } @@ -194,12 +198,13 @@ struct ucs_class { * status = _type##_new(arg1, arg2, arg3, &obj); * } */ -#define UCS_CLASS_DEFINE_NEW_FUNC(_type, _argtype, ...) \ +#define UCS_CLASS_DECLARE_NEW_FUNC(_type, _argtype, ...) \ ucs_status_t UCS_CLASS_NEW_FUNC_NAME(_type)( \ UCS_PP_FOREACH(_UCS_CLASS_INIT_ARG_DEFINE, _, \ UCS_PP_ZIP((UCS_PP_SEQ(UCS_PP_NUM_ARGS(__VA_ARGS__))), (__VA_ARGS__))) \ - _argtype **obj_p) \ - { \ + _argtype **obj_p) +#define UCS_CLASS_DEFINE_NEW_FUNC(_type, _argtype, ...) \ + UCS_CLASS_DECLARE_NEW_FUNC(_type, _argtype, ## __VA_ARGS__) { \ return UCS_CLASS_NEW(_type, obj_p \ UCS_PP_FOREACH(_UCS_CLASS_INIT_ARG_PASS, _, \ UCS_PP_SEQ(UCS_PP_NUM_ARGS(__VA_ARGS__)))); \ @@ -233,8 +238,10 @@ struct ucs_class { * _type *obj = ...; * _type##_delete(obj); */ +#define UCS_CLASS_DECLARE_DELETE_FUNC(_type, _argtype) \ + void UCS_CLASS_DELETE_FUNC_NAME(_type)(_argtype *self) #define UCS_CLASS_DEFINE_DELETE_FUNC(_type, _argtype) \ - void UCS_CLASS_DELETE_FUNC_NAME(_type)(_argtype *self) \ + UCS_CLASS_DECLARE_DELETE_FUNC(_type, _argtype) \ { \ UCS_CLASS_DELETE(_type, self); \ } @@ -257,4 +264,9 @@ struct ucs_class { void _ucs_class_call_cleanup_chain(ucs_class_t *cls, void *obj, int limit); +/** + * The empty class. + */ +UCS_CLASS_DECLARE(void); + #endif