Commit e569955ca6136f5efc90ebab526de409ec7a5e30

Authored by Georg Hopp
1 parent 2132f4fd

added a polymorphic clear method, give messages if an assertion in an test fails

... ... @@ -32,33 +32,33 @@
32 32 extern const _CCLASS const __##_class; \
33 33 struct _##_class
34 34
35   -#define ENDC(_class) } * _class; \
36   - extern const _CCLASS const __##_class;
37   -
38 35 typedef void (* ctor)(void *, va_list *);
  36 +typedef void (* clr)(void *);
39 37 typedef void (* dtor)(void *);
40 38 typedef void (* jCtor)(void *, struct json_object *);
41 39 typedef void (* jTo)(void *, struct json_object **);
42 40
43   -
44 41 typedef struct CCLASS {
45 42 const int magic;
46 43 size_t size;
47 44 void (* __construct)(void * _this, va_list * params);
  45 + void (* __clear)(void * _this);
48 46 void (* __destruct)(void * _this);
49 47 void (* __jsonConst)(void * _this, struct json_object * json);
50 48 void (* __toJson)(void * _this, struct json_object ** json);
51 49 } * _CCLASS;
52   -#define CCLASS_PTR_SIZE sizeof(struct CCLASS *)
53   -#define CCLASS_SIZE sizeof(struct CCLASS)
  50 +#define _CCLASS_SIZE sizeof(_CCLASS)
  51 +#define CCLASS_SIZE sizeof(struct CCLASS)
54 52
55 53 #define __construct(class) static void __construct(class _this, va_list * params)
  54 +#define __clear(class) static void __clear(class _this)
56 55 #define __destruct(class) static void __destruct(class _this)
57 56 #define __jsonConst(class) static void __jsonConst(class _this, struct json_object * json)
58 57 #define __toJson(class) static void __toJson(class _this, struct json_object ** json)
59 58
60 59 #define INIT_CCLASS(class) \
61 60 __construct(class); \
  61 + __clear(class); \
62 62 __destruct(class); \
63 63 __jsonConst(class); \
64 64 __toJson(class); \
... ... @@ -66,6 +66,7 @@ typedef struct CCLASS {
66 66 CCLASS_MAGIC, \
67 67 sizeof(struct _##class), \
68 68 (ctor)__construct, \
  69 + (clr)__clear, \
69 70 (dtor)__destruct, \
70 71 (jCtor)__jsonConst, \
71 72 (jTo)__toJson \
... ... @@ -73,6 +74,7 @@ typedef struct CCLASS {
73 74
74 75 void * _new(const _CCLASS _class, ...);
75 76 void * _newFromJson(const _CCLASS _class, struct json_object * json);
  77 +void clear(void * _object);
76 78 void delete(void * _object);
77 79 void toJson(void * _object, struct json_object ** json);
78 80 int isObject(void * _object);
... ...
... ... @@ -40,11 +40,10 @@ enum DYNTYPE_TYPES {
40 40 CLASS(DYNTYPE) {
41 41 const _CCLASS const class;
42 42 enum DYNTYPE_TYPES type;
43   - size_t size;
44 43 union _data {
45 44 unsigned char _boolean;
46 45 int _int;
47   - double _float;
  46 + double _double;
48 47 char * _string;
49 48 struct _DYNTYPE ** _array;
50 49 DYNTYPE_HASH _hash;
... ... @@ -53,6 +52,22 @@ CLASS(DYNTYPE) {
53 52
54 53 #include "token/dyntype/hash.h"
55 54
  55 +#define dyntype_newBoolean(value) new(DYNTYPE, DYNTYPE_TYPE_BOOLEAN, value)
  56 +#define dyntype_newInt(value) new(DYNTYPE, DYNTYPE_TYPE_INT, value)
  57 +#define dyntype_newDouble(value) new(DYNTYPE, DYNTYPE_TYPE_DOUBLE, value)
  58 +#define dyntype_newString(value) new(DYNTYPE, DYNTYPE_TYPE_STRING, value)
  59 +#define dyntype_newArray(value) new(DYNTYPE, DYNTYPE_TYPE_ARRAY, value)
  60 +#define dyntype_newHash(value) new(DYNTYPE, DYNTYPE_TYPE_HASH, value)
  61 +
  62 +enum DYNTYPE_TYPES dyntype_getType(DYNTYPE _this);
  63 +size_t dyntype_getSize(DYNTYPE _this);
  64 +unsigned char dyntype_getBoolean(DYNTYPE _this);
  65 +int dyntype_getInt(DYNTYPE _this);
  66 +double dyntype_getDouble(DYNTYPE _this);
  67 +char * dyntype_getString(DYNTYPE _this);
  68 +DYNTYPE * dyntype_getArray(DYNTYPE _this);
  69 +DYNTYPE_HASH dyntype_getHash(DYNTYPE _this);
  70 +
56 71 #endif//__DYNTYPE_H__
57 72
58 73 // vim: set et ts=4 sw=4:
... ...
... ... @@ -23,6 +23,7 @@
23 23 #include "token/cclass.h"
24 24
25 25 #undef __construct
  26 +#undef __clear
26 27 #undef __destruct
27 28 #undef __jsonConst
28 29 #undef __toJson
... ... @@ -62,6 +63,16 @@ _newFromJson(const _CCLASS _class, struct json_object * json)
62 63 }
63 64
64 65 void
  66 +clear(void * _object)
  67 +{
  68 + const struct CCLASS ** class = _object;
  69 +
  70 + if (_object && *class && (*class)->__clear) {
  71 + (*class)->__clear(_object);
  72 + }
  73 +}
  74 +
  75 +void
65 76 delete(void * _object)
66 77 {
67 78 const struct CCLASS ** class = *(void**)_object;
... ... @@ -97,7 +108,7 @@ _instanceOf(const _CCLASS _class, void * _object)
97 108 {
98 109 const struct CCLASS ** class = _object;
99 110
100   - return (_class == *class);
  111 + return (class && _class == *class);
101 112 }
102 113
103 114 // vim: set et ts=4 sw=4:
... ...
... ... @@ -56,6 +56,7 @@ __destruct(CRYPT)
56 56
57 57 __jsonConst(CRYPT) {}
58 58 __toJson(CRYPT) {}
  59 +__clear(CRYPT) {}
59 60
60 61 void *
61 62 crypt_createIv(CRYPT _this)
... ...
... ... @@ -23,13 +23,22 @@
23 23 #include "token/dyntype.h"
24 24 #include "token/dyntype/hash.h"
25 25
  26 +static
  27 +size_t _dyntype_sizes[] = {
  28 + 0,
  29 + sizeof(unsigned char),
  30 + sizeof(int),
  31 + sizeof(double),
  32 + sizeof(char *),
  33 + sizeof(DYNTYPE *),
  34 + sizeof(DYNTYPE_HASH)
  35 +};
26 36
27 37 INIT_CCLASS(DYNTYPE);
28 38
29 39 __construct(DYNTYPE)
30 40 {
31 41 _this->type = va_arg(* params, enum DYNTYPE_TYPES);
32   - _this->size = va_arg(* params, size_t);
33 42
34 43 switch(_this->type) {
35 44 case DYNTYPE_TYPE_INT:
... ... @@ -37,8 +46,13 @@ __construct(DYNTYPE)
37 46 break;
38 47
39 48 case DYNTYPE_TYPE_STRING:
40   - (_this->data)._string = calloc(_this->size + 1, sizeof(char));
41   - memcpy((_this->data)._string, va_arg(* params, const char *), _this->size);
  49 + {
  50 + const char * string = va_arg(* params, const char *);
  51 + const size_t length = strlen(string);
  52 +
  53 + (_this->data)._string = calloc(length + 1, sizeof(char));
  54 + memcpy((_this->data)._string, string, length);
  55 + }
42 56 break;
43 57
44 58 case DYNTYPE_TYPE_HASH:
... ... @@ -55,35 +69,34 @@ __jsonConst(DYNTYPE)
55 69 switch (json_object_get_type(json)) {
56 70 case json_type_int:
57 71 _this->type = DYNTYPE_TYPE_INT;
58   - _this->size = sizeof(int);
59 72 (_this->data)._int = (int)json_object_get_int(json);
60 73 break;
61 74
62 75 case json_type_string:
63 76 {
64 77 const char * string = json_object_get_string(json);
  78 + const size_t length = strlen(string);
65 79
66 80 _this->type = DYNTYPE_TYPE_STRING;
67   - _this->size = strlen(string);
68   - (_this->data)._string = calloc(_this->size + 1, sizeof(char));
69   - memcpy((_this->data)._string, string, _this->size);
  81 + (_this->data)._string = calloc(length + 1, sizeof(char));
  82 + memcpy((_this->data)._string, string, length);
70 83 // the json object handles the memory for string....
71 84 }
72 85 break;
73 86
74 87 case json_type_object:
75 88 _this->type = DYNTYPE_TYPE_HASH;
76   - _this->size = sizeof(DYNTYPE_HASH);
77 89 (_this->data)._hash = newFromJson(DYNTYPE_HASH, json);
78 90 break;
79 91
80 92 default:
81 93 _this->type = DYNTYPE_TYPE_NULL;
82   - _this->size = 0;
83 94 (_this->data)._hash = NULL;
84 95 }
85 96 }
86 97
  98 +__clear(DYNTYPE) {}
  99 +
87 100 __destruct(DYNTYPE)
88 101 {
89 102 if (_this) {
... ... @@ -122,4 +135,53 @@ __toJson(DYNTYPE)
122 135 }
123 136 }
124 137
  138 +enum DYNTYPE_TYPES
  139 +dyntype_getType(DYNTYPE _this)
  140 +{
  141 + return _this->type;
  142 +}
  143 +
  144 +size_t
  145 +dyntype_getSize(DYNTYPE _this)
  146 +{
  147 + return _dyntype_sizes[_this->type];
  148 +}
  149 +
  150 +unsigned char
  151 +dyntype_getBoolean(DYNTYPE _this)
  152 +{
  153 + return (_this->data)._boolean;
  154 +}
  155 +
  156 +int
  157 +dyntype_getInt(DYNTYPE _this)
  158 +{
  159 + return (_this->data)._int;
  160 +}
  161 +
  162 +double
  163 +dyntype_getDouble(DYNTYPE _this)
  164 +{
  165 + return (_this->data)._double;
  166 +}
  167 +
  168 +char *
  169 +dyntype_getString(DYNTYPE _this)
  170 +{
  171 + return (_this->data)._string;
  172 +}
  173 +
  174 +DYNTYPE *
  175 +dyntype_getArray(DYNTYPE _this)
  176 +{
  177 + return (_this->data)._array;
  178 +}
  179 +
  180 +DYNTYPE_HASH
  181 +dyntype_getHash(DYNTYPE _this)
  182 +{
  183 + return (_this->data)._hash;
  184 +}
  185 +
  186 +
125 187 // vim: set et ts=4 sw=4:
... ...
... ... @@ -37,6 +37,7 @@ __construct(DYNTYPE_HASH)
37 37 _this->used = 0;
38 38 _updateHashSize(_this);
39 39 }
  40 +
40 41 #undef __construct
41 42
42 43 __jsonConst(DYNTYPE_HASH)
... ... @@ -52,16 +53,22 @@ __jsonConst(DYNTYPE_HASH)
52 53 }
53 54 }
54 55
  56 +__clear(DYNTYPE_HASH) {}
  57 +
55 58 __destruct(DYNTYPE_HASH)
56 59 {
57 60 size_t index;
58 61
59 62 for (index = 0; index < _this->used; index ++) {
60 63 free(_this->keys[index]);
  64 + delete(_this->values[index]);
61 65 }
62 66
63 67 free(_this->keys);
64 68 free(_this->values);
  69 +
  70 + _this->size = _this->used = 0;
  71 + _updateHashSize(_this);
65 72 }
66 73
67 74 __toJson(DYNTYPE_HASH)
... ...
... ... @@ -24,7 +24,23 @@ INIT_CCLASS(PACKET);
24 24
25 25 __construct(PACKET)
26 26 {
27   - packet_set_default_content(_this);
  27 + DYNTYPE header = va_arg(* params, DYNTYPE);
  28 + DYNTYPE data = NULL;
  29 +
  30 + if (instanceOf(DYNTYPE, header)) {
  31 + data = va_arg(* params, DYNTYPE);
  32 + }
  33 +
  34 + if (instanceOf(DYNTYPE, data)) {
  35 +
  36 + packet_setHeader(_this, header);
  37 + packet_setData(_this, data);
  38 +
  39 + } else {
  40 +
  41 + packet_set_default_content(_this);
  42 +
  43 + }
28 44 }
29 45
30 46 __jsonConst(PACKET)
... ... @@ -49,7 +65,21 @@ __jsonConst(PACKET)
49 65 packet_setData(_this, newFromJson(DYNTYPE, data));
50 66 }
51 67
52   -__destruct(PACKET) {}
  68 +__clear(PACKET) {}
  69 +
  70 +__destruct(PACKET)
  71 +{
  72 + DYNTYPE header = packet_getHeader(_this);
  73 + DYNTYPE data = packet_getData(_this);
  74 +
  75 + if (NULL != header) {
  76 + delete(&header);
  77 + }
  78 +
  79 + if (NULL != data) {
  80 + delete(&data);
  81 + }
  82 +}
53 83
54 84 __toJson(PACKET)
55 85 {
... ...
  1 +#include <stdio.h>
1 2 #include <sys/types.h>
2 3 #include <json/json.h>
3 4
... ...
  1 +#include <stdio.h>
1 2 #include <mcrypt.h>
2 3 #include <stdlib.h>
3 4 #include <sys/types.h>
... ...
... ... @@ -22,6 +22,8 @@ __jsonConst(MOCK_CLASS)
22 22 _this->value = json_object_get_int(json);
23 23 }
24 24
  25 +__clear(MOCK_CLASS) {}
  26 +
25 27 __destruct(MOCK_CLASS)
26 28 {
27 29 _called = 1;
... ...
  1 +#include <stdio.h>
  2 +
1 3 #include "runtest.h"
2 4 #include "token/cclass.h"
3 5 #include "token/packet.h"
... ... @@ -36,14 +38,59 @@ static
36 38 int
37 39 testDefaultInit()
38 40 {
  41 + ASSERT_INSTANCE_OF(PACKET, packet);
39 42 ASSERT_NULL(packet_getHeader(packet));
40 43 ASSERT_NULL(packet_getData(packet));
41 44
42 45 return TEST_OK;
43 46 }
44 47
  48 +static
  49 +int
  50 +testParamInit1()
  51 +{
  52 + __tearDown();
  53 +
  54 + DYNTYPE header = dyntype_newInt(123);
  55 + packet = new(PACKET, header, NULL);
  56 +
  57 + ASSERT_INSTANCE_OF(PACKET, packet);
  58 + ASSERT_NULL(packet_getHeader(packet));
  59 + ASSERT_NULL(packet_getData(packet));
  60 +
  61 + delete(&header);
  62 +
  63 + return TEST_OK;
  64 +}
  65 +
  66 +static
  67 +int
  68 +testParamInit2()
  69 +{
  70 + DYNTYPE header, data;
  71 +
  72 + __tearDown();
  73 +
  74 + packet = new(PACKET, dyntype_newInt(123), dyntype_newInt(321));
  75 +
  76 + ASSERT_INSTANCE_OF(PACKET, packet);
  77 +
  78 + header = packet_getHeader(packet);
  79 + data = packet_getData(packet);
  80 +
  81 + ASSERT_INSTANCE_OF(DYNTYPE, header);
  82 + ASSERT_INSTANCE_OF(DYNTYPE, data);
  83 +
  84 + ASSERT_EQUAL(123, dyntype_getInt(header));
  85 + ASSERT_EQUAL(321, dyntype_getInt(data));
  86 +
  87 + return TEST_OK;
  88 +}
  89 +
45 90 const testfunc tests[] = {
46   - testDefaultInit
  91 + testDefaultInit,
  92 + testParamInit1,
  93 + testParamInit2
47 94 };
48 95 const size_t count = FUNCS_COUNT(tests);
49 96
... ...
... ... @@ -24,7 +24,7 @@ isObjectNull(void * _object)
24 24 const struct CCLASS ** class = _object;
25 25
26 26 ASSERT_OBJECT(_object);
27   - ASSERT_MEM_NULL(_object + CCLASS_PTR_SIZE, (*class)->size - CCLASS_PTR_SIZE);
  27 + ASSERT_MEM_NULL(_object + _CCLASS_SIZE, (*class)->size - _CCLASS_SIZE);
28 28
29 29 return TEST_OK;
30 30 }
... ...
... ... @@ -11,26 +11,68 @@ enum RESULT_TYPES {
11 11 TEST_ERROR
12 12 };
13 13
14   -#define ASSERT_NULL(value) if (NULL != (value)) return TEST_FAILED
15   -#define ASSERT_NOT_NULL(value) if (NULL == (value)) return TEST_FAILED
16   -#define ASSERT_EQUAL(val1,val2) if ((val1) != (val2)) return TEST_FAILED
17   -#define ASSERT_NOT_EQUAL(val1,val2) if ((val1) == (val2)) return TEST_FAILED
  14 +#define ASSERT_NULL(value) \
  15 + if (NULL != (value)) { \
  16 + printf("%s[%d]: Assertion failed that %s is NULL\n", \
  17 + __FILE__, __LINE__, #value); \
  18 + return TEST_FAILED; }
  19 +
  20 +#define ASSERT_NOT_NULL(value) \
  21 + if (NULL == (value)) { \
  22 + printf("%s[%d]: Assertion failed that %s is NOT NULL\n", \
  23 + __FILE__, __LINE__, #value); \
  24 + return TEST_FAILED; }
  25 +
  26 +#define ASSERT_EQUAL(val1,val2) \
  27 + if ((val1) != (val2)) { \
  28 + printf("%s[%d]: Assertion failed that %s equals %s\n", \
  29 + __FILE__, __LINE__, #val1, #val2); \
  30 + return TEST_FAILED; }
  31 +
  32 +#define ASSERT_NOT_EQUAL(val1,val2) \
  33 + if ((val1) == (val2)) { \
  34 + printf("%s[%d]: Assertion failed that %s not equals %2\n", \
  35 + __FILE__, __LINE__, #val1, #val2); \
  36 + return TEST_FAILED; }
  37 +
18 38 #define ASSERT_MEM_EQUAL(val1,val2,size) \
19   - if(0 != memcmp((val1), (val2), (size))) return TEST_FAILED
  39 + if(0 != memcmp((val1), (val2), (size))) { \
  40 + printf("%s[%d]: Assertion failed that memory at %s equals %s for %lu bytes\n", \
  41 + __FILE__, __LINE__, #val1, #val2, size); \
  42 + return TEST_FAILED; }
  43 +
20 44 #define ASSERT_MEM_NOT_EQUAL(val1,val2,size) \
21   - if(0 == memcmp((val1), (val2), (size))) return TEST_FAILED
22   -#define ASSERT_MEM_NULL(val, size) if (! isMemNull((val), (size))) return TEST_FAILED
  45 + if(0 == memcmp((val1), (val2), (size))) { \
  46 + printf("%s[%d]: Assertion failed that memory at %s not equals %s for %lu bytes\n", \
  47 + __FILE__, __LINE__, #val1, #val2, size); \
  48 + return TEST_FAILED; }
  49 +
  50 +#define ASSERT_MEM_NULL(val, size) \
  51 + if (! isMemNull((val), (size))) { \
  52 + printf("%s[%d]: Assertion failed that memory at %s is NULL for %lu bytes\n", \
  53 + __FILE__, __LINE__, #val, size); \
  54 + return TEST_FAILED; }
  55 +
23 56 #define ASSERT_MEM_NOT_NULL(val, size) \
24   - if (isMemNull((val), (size))) return TEST_FAILED
  57 + if (isMemNull((val), (size))) { \
  58 + printf("%s[%d]: Assertion failed that memory at %s is NOT NULL for %lu bytes\n", \
  59 + __FILE__, __LINE__, #val, size); \
  60 + return TEST_FAILED; }
  61 +
25 62 #define ASSERT_STRING_EQUAL(val1,val2) \
26 63 if(0 != strcmp((val1), (val2))) return TEST_FAILED
27 64 #define ASSERT_STRING_NOT_EQUAL(val1,val2) \
28 65 if(0 == strcmp((val1), (val2))) return TEST_FAILED
  66 +
29 67 #define ASSERT_OBJECT(val) if (! isObject((val))) return TEST_FAILED
30 68 #define ASSERT_OBJECT_NULL(val) if (! isObjectNull((val))) return TEST_FAILED
31 69 #define ASSERT_OBJECT_NOT_NULL(val) if (isObjectNull((val))) return TEST_FAILED
  70 +
32 71 #define ASSERT_INSTANCE_OF(class, val) \
33   - if (! instanceOf(class, val)) return TEST_FAILED
  72 + if (! instanceOf(class, val)) { \
  73 + printf("%s[%d]: Assertion failed that %s is instance of %s\n", \
  74 + __FILE__, __LINE__, #val, #class); \
  75 + return TEST_FAILED; }
34 76
35 77
36 78 typedef int (* const testfunc)(void);
... ...
Please register or login to post a comment