Merge lp:~smspillaz/compiz-libcompizconfig/ccs-object into lp:~compiz-team/compiz-libcompizconfig/0.9.8
- ccs-object
- Merge into 0.9.8
Status: | Superseded |
---|---|
Proposed branch: | lp:~smspillaz/compiz-libcompizconfig/ccs-object |
Merge into: | lp:~compiz-team/compiz-libcompizconfig/0.9.8 |
Diff against target: |
690 lines (+613/-1) 6 files modified
CMakeLists.txt (+1/-0) include/ccs.h (+101/-1) src/CMakeLists.txt (+3/-0) src/main.c (+179/-0) tests/CMakeLists.txt (+56/-0) tests/test-ccs-object.cpp (+273/-0) |
To merge this branch: | bzr merge lp:~smspillaz/compiz-libcompizconfig/ccs-object |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sam Spilsbury | Needs Fixing | ||
Alan Griffiths | Pending | ||
Review via email: mp+104864@code.launchpad.net |
This proposal supersedes a proposal from 2012-05-04.
Commit message
Description of the change
This is all about bug 990690.
!! - It probably isn't a good idea to test this branch in isolation, as it is part of a pipeline to get compiz-
lp:~smspillaz/compiz-libcompizconfig/setting-mock
lp:~smspillaz/compiz-compizconfig-python/compiz-compizconfig-python.setting-api
lp:~smspillaz/compiz-compizconfig-gconf/compiz-compizconfig-gconf.adapt-to-new-interfaces
.. that's all !!
This branch introduces some preliminary work in a series of branches to get libcompizconfig under test. In order to test the objects properly, we need to abstract away their interfaces into replacable structs so you can test the interaction between the various classes.
This would be awkward to do correctly if we didn't have a suitable object system to handle interface implementation, referencing, private storage etc.
As such, a new struct CCSObject is introduced. It is similar in design to GObject, but with a much smaller feature set centered mostly around the handling of interfaces and composition / indirection. A type registrar is also included (also very simple).
Tests are included.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
> I know it is common (and may be a project style) but there is no advantage to
> having different names to refer to the same thing in different namespaces.
> That is not:
>
> typedef struct _CCSObject CCSObject;
>
> struct _CCSObject
> {
> ...
> };
>
> but:
>
> typedef struct CCSObject
> {
> ...
> } CCSObject;
Actually, it doesn't seem that client code should be interested in the members of [_]CCSObject, so why not a completely opaque type? Vis:
typedef struct CCSObject CCSObject;
in the header. And move the definition to the .c file.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
I don't like the style of coding in ccsObjectAddInt
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
> I don't like the style of coding in ccsObjectAddInt
> realloc fails then the object is hosed. Admittedly FALSE is returned to
> inform the caller, but I'd prefer the object to remain viable and just the
> call to fail. Anything else can cause nasty surprises in client code.
> (Admittedly, if realloc fails there are probably worse problems to deal with.)
Forgot to mention: the cost of calling realloc in ccsObjectRemove
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
> > I know it is common (and may be a project style) but there is no advantage
> to
> > having different names to refer to the same thing in different namespaces.
> > That is not:
> >
> > typedef struct _CCSObject CCSObject;
> >
> > struct _CCSObject
> > {
> > ...
> > };
> >
> > but:
> >
> > typedef struct CCSObject
> > {
> > ...
> > } CCSObject;
>
> Actually, it doesn't seem that client code should be interested in the members
> of [_]CCSObject, so why not a completely opaque type? Vis:
>
> typedef struct CCSObject CCSObject;
>
> in the header. And move the definition to the .c file.
I think the struct can't be opaque because of the way that we actually access the object data (eg, casting it to a CCSObject * and accessing the data in the CCSObject in the first part of the struct).
As for realloc - I agree and had similar concerns, and will change that.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
ccsObjectInit is only used by the test harness which ignores the return code, so the intended use is unclear. Surely a better return value would be a pointer to the initialised object?
ccsObjectRemove
ccsObjectAddInt
struct _CCSObjectAlloc
Actually, talking of reserved names: names that begin with an underscore and a capital are reserved, which is another reason for not using these names in the struct namespace. (I still see no point in having different names (e.g. _CCSObject) in the struct namespace.)
The tests imply that the intended usage is to cast a pointer to some other structure (represented by "TestingObjectW
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
Let me suggest a way that the client code could be eg "ccsObjectRef(
...
Bool ccsObjectRef_
#define ccsObjectRef(obj) ccsObjectRef_
...
No nasty casts, and type safe. At the cost of requiring a member named "object" of CCSObject type.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
> ccsObjectInit is only used by the test harness which ignores the return code,
> so the intended use is unclear. Surely a better return value would be a
> pointer to the initialised object?
Indeed, future merges will introduce proper constructors (but this is not trivial right now).
>
> ccsObjectRemove
> to NULL without first freeing the memory referenced.
>
> ccsObjectAddInt
> without first freeing the memory referenced.
They use realloc, so I don't see why this is a problem ?
>
> struct _CCSObjectAlloc
> realloc, malloc, calloc - these are reserved names.
ack.
>
> Actually, talking of reserved names: names that begin with an underscore and a
> capital are reserved, which is another reason for not using these names in the
> struct namespace. (I still see no point in having different names (e.g.
> _CCSObject) in the struct namespace.)
Right, we should evaluate this elsewhere
>
> The tests imply that the intended usage is to cast a pointer to some other
> structure (represented by "TestingObjectW
> that to ccsObjectXXX. If this is not the intended usage the tests are
> inappropriate. If it is intended there's negative value in these taking a
> pointer to the CCSObject as a parameter, they may as well take void* in the
> same way as ccsObjectInit does. It's a waste of the type-safety features of
> C.
Right, this sucks, but we're introspecting the state of the object. Mabye we can get rid of the casts and just do to->object.foo
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
> > ccsObjectRemove
> > to NULL without first freeing the memory referenced.
> >
> > ccsObjectAddInt
> > without first freeing the memory referenced.
>
> They use realloc, so I don't see why this is a problem ?
Ah, I wrongly assumed you were using a function with different semantics to avoid the problems discussed earlier (i.e. invalidating the object on failed realloc).
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
ccsObjectRemove
ccsObjectAddInt
Is there really value in CCSObjectAlloca
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
These macros can lead to surprising results in user code:
86 +#define ccsObjectRef(o) \
87 + ((o)->object)
88 +
89 +#define ccsObjectUnref(o, freeFunc) \
90 + ((o)->object)
91 + if (!((o)-
92 + freeFunc (o)
Example of problem:
if (false) ccsObjectUnref(o, f);
will call f(o).
Rewrite as:
86 +#define ccsObjectRef(o) \
87 + do { ((o)->object)
88 +
89 +#define ccsObjectUnref(o, freeFunc) \
90 + do { ((o)->object)
91 + if (!((o)-
92 + freeFunc (o) } while(false)
PS It feels awkward to require freeFunc as a parameter, but I don't have a cleaner alternative suggestion just now.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
Bad example.
if (false) ccsObjectUnref(o, f);
is OK.
But...
if (true) ccsObjectUnref(o, f);
else printf("surprise");
is a good example (i.e. broken).
- 437. By Sam Spilsbury
-
Free interfaces once objects are removed
- 438. By Sam Spilsbury
-
Fix potential macro problems
Sam Spilsbury (smspillaz) wrote : | # |
Keeping old status
Sam Spilsbury (smspillaz) wrote : | # |
>ccsObjectRemov
Fixed as discussed
> ccsObjectAddInt
Not an issue as discussed on irc. (realloc (foo, sizeof (whatever)); doesn't invalidate foo if realloc fails)
> Is there really value in CCSObjectAlloca
Yes, for mocking allocation failures. Feel crap having to inject it, but there isn't much of an alternative
> Bad example.
> if (false) ccsObjectUnref(o, f);
> is OK.
> But...
> if (true) ccsObjectUnref(o, f);
> else printf("surprise");
> is a good example (i.e. broken).
Fixed as discussed
> PS It feels awkward to require freeFunc as a parameter, but I don't have a cleaner alternative suggestion just now.
If / when we add proper constructor / destructor semantics this will go away :) (That's a larger change though that should be done later)
- 439. By Sam Spilsbury
-
Lose the ;
- 440. By Sam Spilsbury
-
Added a free thread
- 441. By Sam Spilsbury
-
Also test for free
Unmerged revisions
- 441. By Sam Spilsbury
-
Also test for free
- 440. By Sam Spilsbury
-
Added a free thread
- 439. By Sam Spilsbury
-
Lose the ;
- 438. By Sam Spilsbury
-
Fix potential macro problems
- 437. By Sam Spilsbury
-
Free interfaces once objects are removed
- 436. By Sam Spilsbury
-
Don't use reserved name
- 435. By Sam Spilsbury
-
Make the CCSObject API a bit more typesafe
- 434. By Sam Spilsbury
-
Don't reallocate all the time. Also handle realloc failures better
- 433. By Sam Spilsbury
-
Added a simple type registrar
- 432. By Sam Spilsbury
-
Added a ccsObjectFinalize function which frees everything in CCSObject storage
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2011-07-07 12:23:21 +0000 | |||
3 | +++ CMakeLists.txt 2012-05-07 10:49:18 +0000 | |||
4 | @@ -141,6 +141,7 @@ | |||
5 | 141 | add_subdirectory (src) | 141 | add_subdirectory (src) |
6 | 142 | add_subdirectory (include) | 142 | add_subdirectory (include) |
7 | 143 | add_subdirectory (cmake) | 143 | add_subdirectory (cmake) |
8 | 144 | add_subdirectory (tests) | ||
9 | 144 | 145 | ||
10 | 145 | compiz_print_configure_header ("CompizConfig Library") | 146 | compiz_print_configure_header ("CompizConfig Library") |
11 | 146 | compiz_color_message ("\n${_escape}[4mOptional features:${_escape}[0m\n") | 147 | compiz_color_message ("\n${_escape}[4mOptional features:${_escape}[0m\n") |
12 | 147 | 148 | ||
13 | === modified file 'include/ccs.h' | |||
14 | --- include/ccs.h 2011-08-20 19:03:37 +0000 | |||
15 | +++ include/ccs.h 2012-05-07 10:49:18 +0000 | |||
16 | @@ -19,10 +19,14 @@ | |||
17 | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
18 | 20 | */ | 20 | */ |
19 | 21 | 21 | ||
20 | 22 | |||
21 | 23 | #ifndef _CSS_H | 22 | #ifndef _CSS_H |
22 | 24 | #define _CSS_H | 23 | #define _CSS_H |
23 | 25 | 24 | ||
24 | 25 | #ifdef __cplusplus | ||
25 | 26 | extern "C" | ||
26 | 27 | { | ||
27 | 28 | #endif | ||
28 | 29 | |||
29 | 26 | #define D_NONE 0 | 30 | #define D_NONE 0 |
30 | 27 | #define D_NORMAL 1 | 31 | #define D_NORMAL 1 |
31 | 28 | #define D_FULL 2 | 32 | #define D_FULL 2 |
32 | @@ -124,6 +128,98 @@ | |||
33 | 124 | CCSLIST_HDR (StrRestriction, CCSStrRestriction) | 128 | CCSLIST_HDR (StrRestriction, CCSStrRestriction) |
34 | 125 | CCSLIST_HDR (StrExtension, CCSStrExtension) | 129 | CCSLIST_HDR (StrExtension, CCSStrExtension) |
35 | 126 | 130 | ||
36 | 131 | typedef struct _CCSInterface CCSInterface; /* Dummy typedef */ | ||
37 | 132 | typedef struct _CCSPrivate CCSPrivate; /* Dummy typedef */ | ||
38 | 133 | typedef struct _CCSObject CCSObject; | ||
39 | 134 | |||
40 | 135 | typedef void * (*reallocProc) (void *, size_t); | ||
41 | 136 | typedef void * (*mallocProc) (size_t); | ||
42 | 137 | typedef void * (*callocProc) (size_t, size_t); | ||
43 | 138 | |||
44 | 139 | typedef struct _CCSObjectAllocationInterface | ||
45 | 140 | { | ||
46 | 141 | reallocProc realloc_; | ||
47 | 142 | mallocProc malloc_; | ||
48 | 143 | callocProc calloc_; | ||
49 | 144 | } CCSObjectAllocationInterface; | ||
50 | 145 | |||
51 | 146 | extern CCSObjectAllocationInterface ccsDefaultObjectAllocator; | ||
52 | 147 | |||
53 | 148 | struct _CCSObject | ||
54 | 149 | { | ||
55 | 150 | CCSPrivate *priv; /* Private pointer for object storage */ | ||
56 | 151 | |||
57 | 152 | const CCSInterface **interfaces; /* An array of interfaces that this object implements */ | ||
58 | 153 | int *interface_types; /* An array of interface types */ | ||
59 | 154 | unsigned int n_interfaces; | ||
60 | 155 | unsigned int n_allocated_interfaces; | ||
61 | 156 | |||
62 | 157 | CCSObjectAllocationInterface *object_allocation; | ||
63 | 158 | |||
64 | 159 | unsigned int refcnt; /* Reference count of this object */ | ||
65 | 160 | }; | ||
66 | 161 | |||
67 | 162 | Bool | ||
68 | 163 | ccsObjectInit_ (CCSObject *object, CCSObjectAllocationInterface *interface); | ||
69 | 164 | |||
70 | 165 | #define ccsObjectInit(o, interface) (ccsObjectInit_) (&(o)->object, interface) | ||
71 | 166 | |||
72 | 167 | Bool | ||
73 | 168 | ccsObjectAddInterface_ (CCSObject *object, const CCSInterface *interface, int interface_type); | ||
74 | 169 | |||
75 | 170 | #define ccsObjectAddInterface(o, interface, type) (ccsObjectAddInterface_) (&(o)->object, interface, type); | ||
76 | 171 | |||
77 | 172 | Bool | ||
78 | 173 | ccsObjectRemoveInterface_ (CCSObject *object, int interface_type); | ||
79 | 174 | |||
80 | 175 | #define ccsObjectRemoveInterface(o, interface_type) (ccsObjectRemoveInterface_) (&(o)->object, interface_type); | ||
81 | 176 | |||
82 | 177 | const CCSInterface * ccsObjectGetInterface_ (CCSObject *object, int interface_type); | ||
83 | 178 | |||
84 | 179 | #define ccsObjectGetInterface(o, interface_type) (ccsObjectGetInterface_) (&(o)->object, interface_type) | ||
85 | 180 | |||
86 | 181 | #define ccsObjectRef(o) \ | ||
87 | 182 | do { ((o)->object).refcnt++; } while (FALSE) | ||
88 | 183 | |||
89 | 184 | #define ccsObjectUnref(o, freeFunc) \ | ||
90 | 185 | do \ | ||
91 | 186 | { \ | ||
92 | 187 | ((o)->object).refcnt--; \ | ||
93 | 188 | if (!((o)->object).refcnt) \ | ||
94 | 189 | freeFunc (o); \ | ||
95 | 190 | } while (FALSE) | ||
96 | 191 | |||
97 | 192 | CCSPrivate * | ||
98 | 193 | ccsObjectGetPrivate_ (CCSObject *object); | ||
99 | 194 | |||
100 | 195 | #define ccsObjectGetPrivate(o) (ccsObjectGetPrivate_) (&(o)->object) | ||
101 | 196 | |||
102 | 197 | void | ||
103 | 198 | ccsObjectSetPrivate_ (CCSObject *object, CCSPrivate *priv); | ||
104 | 199 | |||
105 | 200 | #define ccsObjectSetPrivate(o, priv) (ccsObjectSetPrivate_) (&(o)->object, priv) | ||
106 | 201 | |||
107 | 202 | void | ||
108 | 203 | ccsObjectFinalize_ (CCSObject *object); | ||
109 | 204 | |||
110 | 205 | #define ccsObjectFinalize(o) (ccsObjectFinalize_) (&(o)->object) | ||
111 | 206 | |||
112 | 207 | unsigned int | ||
113 | 208 | ccsAllocateType (); | ||
114 | 209 | |||
115 | 210 | #define GET_INTERFACE_TYPE(Interface) \ | ||
116 | 211 | ccs##Interface##GetType (); | ||
117 | 212 | |||
118 | 213 | #define INTERFACE_TYPE(Interface) \ | ||
119 | 214 | inline unsigned int ccs##Interface##GetType () \ | ||
120 | 215 | { \ | ||
121 | 216 | static unsigned int type_id = 0; \ | ||
122 | 217 | if (!type_id) \ | ||
123 | 218 | type_id = ccsAllocateType (); \ | ||
124 | 219 | \ | ||
125 | 220 | return type_id; \ | ||
126 | 221 | } | ||
127 | 222 | |||
128 | 127 | /** | 223 | /** |
129 | 128 | * reference counting | 224 | * reference counting |
130 | 129 | * | 225 | * |
131 | @@ -913,4 +1009,8 @@ | |||
132 | 913 | /* Checks if settings need to be constrained */ | 1009 | /* Checks if settings need to be constrained */ |
133 | 914 | Bool ccsContextNeedsConstraining (CCSContext *context); | 1010 | Bool ccsContextNeedsConstraining (CCSContext *context); |
134 | 915 | 1011 | ||
135 | 1012 | #ifdef __cplusplus | ||
136 | 1013 | } | ||
137 | 1014 | #endif | ||
138 | 1015 | |||
139 | 916 | #endif | 1016 | #endif |
140 | 917 | 1017 | ||
141 | === modified file 'src/CMakeLists.txt' | |||
142 | --- src/CMakeLists.txt 2011-10-15 07:28:45 +0000 | |||
143 | +++ src/CMakeLists.txt 2012-05-07 10:49:18 +0000 | |||
144 | @@ -35,6 +35,9 @@ | |||
145 | 35 | ${LIBCOMPIZCONFIG_FILES} | 35 | ${LIBCOMPIZCONFIG_FILES} |
146 | 36 | compizconfig.pb.cc | 36 | compizconfig.pb.cc |
147 | 37 | ) | 37 | ) |
148 | 38 | set (LIBCOMPIZCONFIG_LIBRARIES | ||
149 | 39 | ${LIBCOMPIZCONFIG_LIBRARIES} | ||
150 | 40 | protobuf) | ||
151 | 38 | add_definitions ( | 41 | add_definitions ( |
152 | 39 | -DUSE_PROTOBUF | 42 | -DUSE_PROTOBUF |
153 | 40 | ) | 43 | ) |
154 | 41 | 44 | ||
155 | === modified file 'src/main.c' | |||
156 | --- src/main.c 2011-11-10 00:58:18 +0000 | |||
157 | +++ src/main.c 2012-05-07 10:49:18 +0000 | |||
158 | @@ -39,6 +39,173 @@ | |||
159 | 39 | #include "ccs-private.h" | 39 | #include "ccs-private.h" |
160 | 40 | #include "iniparser.h" | 40 | #include "iniparser.h" |
161 | 41 | 41 | ||
162 | 42 | CCSObjectAllocationInterface ccsDefaultObjectAllocator = | ||
163 | 43 | { | ||
164 | 44 | realloc, | ||
165 | 45 | malloc, | ||
166 | 46 | calloc | ||
167 | 47 | }; | ||
168 | 48 | |||
169 | 49 | /* CCSObject stuff */ | ||
170 | 50 | Bool | ||
171 | 51 | ccsObjectInit_(CCSObject *object, CCSObjectAllocationInterface *object_allocation) | ||
172 | 52 | { | ||
173 | 53 | object->priv = NULL; | ||
174 | 54 | object->n_interfaces = 0; | ||
175 | 55 | object->n_allocated_interfaces = 0; | ||
176 | 56 | object->interfaces = NULL; | ||
177 | 57 | object->interface_types = NULL; | ||
178 | 58 | object->object_allocation = object_allocation; | ||
179 | 59 | object->refcnt = 0; | ||
180 | 60 | |||
181 | 61 | return TRUE; | ||
182 | 62 | } | ||
183 | 63 | |||
184 | 64 | Bool | ||
185 | 65 | ccsObjectAddInterface_(CCSObject *object, const CCSInterface *interface, int interface_type) | ||
186 | 66 | { | ||
187 | 67 | object->n_interfaces++; | ||
188 | 68 | |||
189 | 69 | if (object->n_allocated_interfaces < object->n_interfaces) | ||
190 | 70 | { | ||
191 | 71 | unsigned int old_allocated_interfaces = object->n_allocated_interfaces; | ||
192 | 72 | object->n_allocated_interfaces = object->n_interfaces; | ||
193 | 73 | CCSInterface **ifaces = (*object->object_allocation->realloc_) (object->interfaces, object->n_allocated_interfaces * sizeof (CCSInterface *)); | ||
194 | 74 | int *iface_types = (*object->object_allocation->realloc_) (object->interface_types, object->n_allocated_interfaces * sizeof (int)); | ||
195 | 75 | |||
196 | 76 | if (!ifaces || !iface_types) | ||
197 | 77 | { | ||
198 | 78 | if (ifaces) | ||
199 | 79 | free (ifaces); | ||
200 | 80 | |||
201 | 81 | if (iface_types) | ||
202 | 82 | free (iface_types); | ||
203 | 83 | |||
204 | 84 | object->n_interfaces--; | ||
205 | 85 | object->n_allocated_interfaces = old_allocated_interfaces; | ||
206 | 86 | return FALSE; | ||
207 | 87 | } | ||
208 | 88 | else | ||
209 | 89 | { | ||
210 | 90 | object->interfaces = (const CCSInterface **) ifaces; | ||
211 | 91 | object->interface_types = iface_types; | ||
212 | 92 | } | ||
213 | 93 | } | ||
214 | 94 | |||
215 | 95 | object->interfaces[object->n_interfaces - 1] = interface; | ||
216 | 96 | object->interface_types[object->n_interfaces - 1] = interface_type; | ||
217 | 97 | |||
218 | 98 | return TRUE; | ||
219 | 99 | } | ||
220 | 100 | |||
221 | 101 | Bool | ||
222 | 102 | ccsObjectRemoveInterface_(CCSObject *object, int interface_type) | ||
223 | 103 | { | ||
224 | 104 | unsigned int i = 0; | ||
225 | 105 | |||
226 | 106 | if (!object->n_interfaces) | ||
227 | 107 | return FALSE; | ||
228 | 108 | |||
229 | 109 | const CCSInterface **o = object->interfaces; | ||
230 | 110 | int *type = object->interface_types; | ||
231 | 111 | |||
232 | 112 | for (; i < object->n_interfaces; i++, o++, type++) | ||
233 | 113 | { | ||
234 | 114 | if (object->interface_types[i] == interface_type) | ||
235 | 115 | break; | ||
236 | 116 | } | ||
237 | 117 | |||
238 | 118 | if (i >= object->n_interfaces) | ||
239 | 119 | return FALSE; | ||
240 | 120 | |||
241 | 121 | /* Now clear this section and move everything back */ | ||
242 | 122 | object->interfaces[i] = NULL; | ||
243 | 123 | |||
244 | 124 | i++; | ||
245 | 125 | |||
246 | 126 | const CCSInterface **oLast = o; | ||
247 | 127 | int *typeLast = type; | ||
248 | 128 | |||
249 | 129 | o++; | ||
250 | 130 | type++; | ||
251 | 131 | |||
252 | 132 | memmove ((void *) oLast, (void *)o, (object->n_interfaces - i) * sizeof (CCSInterface *)); | ||
253 | 133 | memmove ((void *) typeLast, (void *) type, (object->n_interfaces - i) * sizeof (int)); | ||
254 | 134 | |||
255 | 135 | object->n_interfaces--; | ||
256 | 136 | |||
257 | 137 | if (!object->n_interfaces) | ||
258 | 138 | { | ||
259 | 139 | free (object->interfaces); | ||
260 | 140 | free (object->interface_types); | ||
261 | 141 | object->interfaces = NULL; | ||
262 | 142 | object->interface_types = NULL; | ||
263 | 143 | object->n_allocated_interfaces = 0; | ||
264 | 144 | } | ||
265 | 145 | |||
266 | 146 | return TRUE; | ||
267 | 147 | } | ||
268 | 148 | |||
269 | 149 | const CCSInterface * | ||
270 | 150 | ccsObjectGetInterface_(CCSObject *object, int interface_type) | ||
271 | 151 | { | ||
272 | 152 | unsigned int i = 0; | ||
273 | 153 | |||
274 | 154 | for (; i < object->n_interfaces; i++) | ||
275 | 155 | { | ||
276 | 156 | if (object->interface_types[i] == interface_type) | ||
277 | 157 | return object->interfaces[i]; | ||
278 | 158 | } | ||
279 | 159 | |||
280 | 160 | return NULL; | ||
281 | 161 | } | ||
282 | 162 | |||
283 | 163 | CCSPrivate * | ||
284 | 164 | ccsObjectGetPrivate_(CCSObject *object) | ||
285 | 165 | { | ||
286 | 166 | return object->priv; | ||
287 | 167 | } | ||
288 | 168 | |||
289 | 169 | void | ||
290 | 170 | ccsObjectSetPrivate_(CCSObject *object, CCSPrivate *priv) | ||
291 | 171 | { | ||
292 | 172 | object->priv = priv; | ||
293 | 173 | } | ||
294 | 174 | |||
295 | 175 | void | ||
296 | 176 | ccsObjectFinalize_(CCSObject *object) | ||
297 | 177 | { | ||
298 | 178 | if (object->priv) | ||
299 | 179 | { | ||
300 | 180 | free (object->priv); | ||
301 | 181 | object->priv = NULL; | ||
302 | 182 | } | ||
303 | 183 | |||
304 | 184 | if (object->interfaces) | ||
305 | 185 | { | ||
306 | 186 | free (object->interfaces); | ||
307 | 187 | object->interfaces = NULL; | ||
308 | 188 | } | ||
309 | 189 | |||
310 | 190 | if (object->interface_types) | ||
311 | 191 | { | ||
312 | 192 | free (object->interface_types); | ||
313 | 193 | object->interface_types = NULL; | ||
314 | 194 | } | ||
315 | 195 | |||
316 | 196 | object->n_interfaces = 0; | ||
317 | 197 | } | ||
318 | 198 | |||
319 | 199 | unsigned int | ||
320 | 200 | ccsAllocateType () | ||
321 | 201 | { | ||
322 | 202 | static unsigned int start = 0; | ||
323 | 203 | |||
324 | 204 | start++; | ||
325 | 205 | |||
326 | 206 | return start; | ||
327 | 207 | } | ||
328 | 208 | |||
329 | 42 | Bool basicMetadata = FALSE; | 209 | Bool basicMetadata = FALSE; |
330 | 43 | 210 | ||
331 | 44 | void | 211 | void |
332 | @@ -592,6 +759,18 @@ | |||
333 | 592 | CCSREF (StrRestriction, CCSStrRestriction) | 759 | CCSREF (StrRestriction, CCSStrRestriction) |
334 | 593 | CCSREF (StrExtension, CCSStrExtension) | 760 | CCSREF (StrExtension, CCSStrExtension) |
335 | 594 | 761 | ||
336 | 762 | #define CCSREF_OBJ(type,dtype) \ | ||
337 | 763 | void ccs##type##Ref (dtype *d) \ | ||
338 | 764 | { \ | ||
339 | 765 | ((CCSObject *) d)->refcnt++; \ | ||
340 | 766 | } \ | ||
341 | 767 | void ccs##type##Unref (dtype *d) \ | ||
342 | 768 | { \ | ||
343 | 769 | ((CCSObject *) d)->refcnt--; \ | ||
344 | 770 | if (((CCSObject *) d)->refcnt == 0) \ | ||
345 | 771 | ccsFree##type (d); \ | ||
346 | 772 | } \ | ||
347 | 773 | |||
348 | 595 | static void * | 774 | static void * |
349 | 596 | openBackend (char *backend) | 775 | openBackend (char *backend) |
350 | 597 | { | 776 | { |
351 | 598 | 777 | ||
352 | === added directory 'tests' | |||
353 | === added file 'tests/CMakeLists.txt' | |||
354 | --- tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
355 | +++ tests/CMakeLists.txt 2012-05-07 10:49:18 +0000 | |||
356 | @@ -0,0 +1,56 @@ | |||
357 | 1 | # Build Google Test and make its headers known | ||
358 | 2 | find_package (GTest) | ||
359 | 3 | |||
360 | 4 | if (NOT GTEST_FOUND) | ||
361 | 5 | |||
362 | 6 | # Check for google test and build it locally | ||
363 | 7 | set (GTEST_ROOT_DIR | ||
364 | 8 | "/usr/src/gtest" # Default value, adjustable by user with e.g., ccmake | ||
365 | 9 | CACHE | ||
366 | 10 | PATH | ||
367 | 11 | "Path to Google test srcs" | ||
368 | 12 | ) | ||
369 | 13 | |||
370 | 14 | find_path (GTEST_INCLUDE_DIR gtest/gtest.h) | ||
371 | 15 | |||
372 | 16 | if (GTEST_INCLUDE_DIR) | ||
373 | 17 | #FIXME - hardcoded is bad! | ||
374 | 18 | add_subdirectory (${GTEST_ROOT_DIR} | ||
375 | 19 | gtest) | ||
376 | 20 | endif(GTEST_INCLUDE_DIR) | ||
377 | 21 | |||
378 | 22 | set (GTEST_BOTH_LIBRARIES gtest gtest_main) | ||
379 | 23 | set (GTEST_FOUND TRUE) | ||
380 | 24 | |||
381 | 25 | endif (NOT GTEST_FOUND) | ||
382 | 26 | |||
383 | 27 | find_library (GMOCK_LIBRARY gmock) | ||
384 | 28 | find_library (GMOCK_MAIN_LIBRARY gmock_main) | ||
385 | 29 | |||
386 | 30 | if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND) | ||
387 | 31 | message ("Google Mock and Google Test not found - cannot build tests!") | ||
388 | 32 | set (COMPIZ_BUILD_TESTING OFF) | ||
389 | 33 | endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND) | ||
390 | 34 | |||
391 | 35 | include_directories (${GTEST_INCLUDE_DIRS}) | ||
392 | 36 | include_directories (${CMAKE_SOURCE_DIR}/include) | ||
393 | 37 | link_directories (${CMAKE_INSTALL_PREFIX}/lib) | ||
394 | 38 | |||
395 | 39 | add_executable (test-ccs-object | ||
396 | 40 | ${CMAKE_CURRENT_SOURCE_DIR}/test-ccs-object.cpp) | ||
397 | 41 | |||
398 | 42 | if (HAVE_PROTOBUF) | ||
399 | 43 | set (LIBCOMPIZCONFIG_LIBRARIES | ||
400 | 44 | ${LIBCOMPIZCONFIG_LIBRARIES} | ||
401 | 45 | protobuf) | ||
402 | 46 | endif (HAVE_PROTOBUF) | ||
403 | 47 | |||
404 | 48 | target_link_libraries (test-ccs-object | ||
405 | 49 | ${GTEST_BOTH_LIBRARIES} | ||
406 | 50 | ${GMOCK_LIBRARY} | ||
407 | 51 | ${GMOCK_MAIN_LIBRARY} | ||
408 | 52 | ${CMAKE_THREAD_LIBS_INIT} | ||
409 | 53 | ${LIBCOMPIZCONFIG_LIBRARIES} | ||
410 | 54 | compizconfig) | ||
411 | 55 | |||
412 | 56 | gtest_add_tests (test-ccs-object "" ${CMAKE_CURRENT_SOURCE_DIR}/test-ccs-object.cpp) | ||
413 | 0 | 57 | ||
414 | === added file 'tests/test-ccs-object.cpp' | |||
415 | --- tests/test-ccs-object.cpp 1970-01-01 00:00:00 +0000 | |||
416 | +++ tests/test-ccs-object.cpp 2012-05-07 10:49:18 +0000 | |||
417 | @@ -0,0 +1,273 @@ | |||
418 | 1 | #include <gtest/gtest.h> | ||
419 | 2 | #include <gmock/gmock.h> | ||
420 | 3 | #include <ccs.h> | ||
421 | 4 | #include <cstdio> | ||
422 | 5 | |||
423 | 6 | using ::testing::_; | ||
424 | 7 | using ::testing::Return; | ||
425 | 8 | |||
426 | 9 | class CCSObjectTest : | ||
427 | 10 | public ::testing::Test | ||
428 | 11 | { | ||
429 | 12 | }; | ||
430 | 13 | |||
431 | 14 | struct TestingObjectWrapper | ||
432 | 15 | { | ||
433 | 16 | CCSObject object; | ||
434 | 17 | }; | ||
435 | 18 | |||
436 | 19 | typedef void (*dummyFunc) (void); | ||
437 | 20 | |||
438 | 21 | struct DummyInterface | ||
439 | 22 | { | ||
440 | 23 | dummyFunc dummy; | ||
441 | 24 | }; | ||
442 | 25 | |||
443 | 26 | struct Dummy2Interface | ||
444 | 27 | { | ||
445 | 28 | dummyFunc dummy; | ||
446 | 29 | }; | ||
447 | 30 | |||
448 | 31 | class GoogleMockDummyInterface | ||
449 | 32 | { | ||
450 | 33 | public: | ||
451 | 34 | |||
452 | 35 | virtual ~GoogleMockDummyInterface () {}; | ||
453 | 36 | |||
454 | 37 | virtual void dummyFunc () = 0; | ||
455 | 38 | virtual void freeTestingObjectWrapper (TestingObjectWrapper *) = 0; | ||
456 | 39 | }; | ||
457 | 40 | |||
458 | 41 | class GoogleMockDummy : | ||
459 | 42 | public GoogleMockDummyInterface | ||
460 | 43 | { | ||
461 | 44 | public: | ||
462 | 45 | |||
463 | 46 | MOCK_METHOD0 (dummyFunc, void ()); | ||
464 | 47 | MOCK_METHOD1 (freeTestingObjectWrapper, void (TestingObjectWrapper *)); | ||
465 | 48 | public: | ||
466 | 49 | |||
467 | 50 | static void thunkDummyFunc () { return _mockDummy.dummyFunc (); } | ||
468 | 51 | static GoogleMockDummy _mockDummy; | ||
469 | 52 | }; | ||
470 | 53 | |||
471 | 54 | GoogleMockDummy GoogleMockDummy::_mockDummy; | ||
472 | 55 | |||
473 | 56 | const struct DummyInterface SomeDummyInterface = | ||
474 | 57 | { | ||
475 | 58 | GoogleMockDummy::thunkDummyFunc | ||
476 | 59 | }; | ||
477 | 60 | |||
478 | 61 | #define CCS_INTERFACE_TYPE_DUMMY GET_INTERFACE_TYPE (DummyInterface) | ||
479 | 62 | #define CCS_INTERFACE_TYPE_DUMMY2 GET_INTERFACE_TYPE (Dummy2Interface) | ||
480 | 63 | |||
481 | 64 | INTERFACE_TYPE (DummyInterface) | ||
482 | 65 | INTERFACE_TYPE (Dummy2Interface) | ||
483 | 66 | |||
484 | 67 | TEST(CCSObjectTest, TestTypeAllocation) | ||
485 | 68 | { | ||
486 | 69 | unsigned int i = CCS_INTERFACE_TYPE_DUMMY; | ||
487 | 70 | unsigned int j = CCS_INTERFACE_TYPE_DUMMY; | ||
488 | 71 | unsigned int k = CCS_INTERFACE_TYPE_DUMMY2; | ||
489 | 72 | |||
490 | 73 | EXPECT_EQ (i, 1); | ||
491 | 74 | EXPECT_EQ (j ,1); | ||
492 | 75 | EXPECT_EQ (k, 2); | ||
493 | 76 | } | ||
494 | 77 | |||
495 | 78 | TEST(CCSObjectTest, InterfaceAdd) | ||
496 | 79 | { | ||
497 | 80 | TestingObjectWrapper *to = (TestingObjectWrapper *) calloc (1, sizeof (TestingObjectWrapper)); | ||
498 | 81 | |||
499 | 82 | ccsObjectInit (to, &ccsDefaultObjectAllocator); | ||
500 | 83 | ccsObjectAddInterface (to, (const CCSInterface *) &SomeDummyInterface, 1); | ||
501 | 84 | |||
502 | 85 | EXPECT_EQ (*((CCSObject *) to)->interfaces, (const CCSInterface *) (&SomeDummyInterface)); | ||
503 | 86 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 1); | ||
504 | 87 | EXPECT_EQ (*((CCSObject *) to)->interface_types, 1); | ||
505 | 88 | |||
506 | 89 | free (to); | ||
507 | 90 | } | ||
508 | 91 | |||
509 | 92 | TEST(CCSObjectTest, InterfaceRemove) | ||
510 | 93 | { | ||
511 | 94 | TestingObjectWrapper *to = (TestingObjectWrapper *) calloc (1, sizeof (TestingObjectWrapper)); | ||
512 | 95 | |||
513 | 96 | ccsObjectInit (to, &ccsDefaultObjectAllocator); | ||
514 | 97 | ccsObjectAddInterface (to, (const CCSInterface *) &SomeDummyInterface, 1); | ||
515 | 98 | |||
516 | 99 | EXPECT_EQ (*((CCSObject *) to)->interfaces, (const CCSInterface *) (&SomeDummyInterface)); | ||
517 | 100 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 1); | ||
518 | 101 | EXPECT_EQ (*((CCSObject *) to)->interface_types, 1); | ||
519 | 102 | |||
520 | 103 | ccsObjectRemoveInterface (to, 1); | ||
521 | 104 | |||
522 | 105 | EXPECT_EQ (NULL, ((CCSObject *) to)->interfaces); | ||
523 | 106 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 0); | ||
524 | 107 | EXPECT_EQ (NULL, ((CCSObject *) to)->interface_types); | ||
525 | 108 | |||
526 | 109 | free (to); | ||
527 | 110 | } | ||
528 | 111 | |||
529 | 112 | TEST(CCSObjectTest, InterfaceFetchCall) | ||
530 | 113 | { | ||
531 | 114 | TestingObjectWrapper *to = (TestingObjectWrapper *) calloc (1, sizeof (TestingObjectWrapper)); | ||
532 | 115 | |||
533 | 116 | ccsObjectInit (to, &ccsDefaultObjectAllocator); | ||
534 | 117 | ccsObjectAddInterface (to, (const CCSInterface *) &SomeDummyInterface, 1); | ||
535 | 118 | |||
536 | 119 | EXPECT_EQ (*((CCSObject *) to)->interfaces, (const CCSInterface *) (&SomeDummyInterface)); | ||
537 | 120 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 1); | ||
538 | 121 | EXPECT_EQ (*((CCSObject *) to)->interface_types, 1); | ||
539 | 122 | |||
540 | 123 | const DummyInterface *myDummyInterface = (const DummyInterface *) ccsObjectGetInterface (to, 1); | ||
541 | 124 | |||
542 | 125 | EXPECT_CALL (GoogleMockDummy::_mockDummy, dummyFunc ()); | ||
543 | 126 | |||
544 | 127 | (*myDummyInterface->dummy) (); | ||
545 | 128 | |||
546 | 129 | ccsObjectRemoveInterface (to, 1); | ||
547 | 130 | |||
548 | 131 | EXPECT_EQ (NULL, ((CCSObject *) to)->interfaces); | ||
549 | 132 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 0); | ||
550 | 133 | EXPECT_EQ (NULL, ((CCSObject *) to)->interface_types); | ||
551 | 134 | |||
552 | 135 | free (to); | ||
553 | 136 | } | ||
554 | 137 | |||
555 | 138 | TEST(CCSObjectTest, SetPrivateGetPrivate) | ||
556 | 139 | { | ||
557 | 140 | TestingObjectWrapper *to = (TestingObjectWrapper *) calloc (1, sizeof (TestingObjectWrapper)); | ||
558 | 141 | |||
559 | 142 | int i = 1; | ||
560 | 143 | |||
561 | 144 | ccsObjectInit (to, &ccsDefaultObjectAllocator); | ||
562 | 145 | ccsObjectSetPrivate (to, (CCSPrivate *) &i); | ||
563 | 146 | |||
564 | 147 | CCSPrivate *p = ccsObjectGetPrivate (to); | ||
565 | 148 | |||
566 | 149 | EXPECT_EQ (&i, (int *) p); | ||
567 | 150 | EXPECT_EQ (i, (*((int *) p))); | ||
568 | 151 | } | ||
569 | 152 | |||
570 | 153 | void ccsFreeTestingObjectWrapper (TestingObjectWrapper *wrapper) | ||
571 | 154 | { | ||
572 | 155 | GoogleMockDummy::_mockDummy.freeTestingObjectWrapper (wrapper); | ||
573 | 156 | } | ||
574 | 157 | |||
575 | 158 | #define CCSREF_OBJ(type,dtype) \ | ||
576 | 159 | void ccs##type##Ref (dtype *d) \ | ||
577 | 160 | { \ | ||
578 | 161 | ccsObjectRef (d); \ | ||
579 | 162 | } \ | ||
580 | 163 | \ | ||
581 | 164 | void ccs##type##Unref (dtype *d) \ | ||
582 | 165 | { \ | ||
583 | 166 | ccsObjectUnref (d, ccsFree##type); \ | ||
584 | 167 | } \ | ||
585 | 168 | |||
586 | 169 | CCSREF_HDR(TestingObjectWrapper, TestingObjectWrapper); | ||
587 | 170 | CCSREF_OBJ(TestingObjectWrapper, TestingObjectWrapper); | ||
588 | 171 | |||
589 | 172 | TEST(CCSObjectTest, TestRefUnrefFreesObject) | ||
590 | 173 | { | ||
591 | 174 | TestingObjectWrapper *to = (TestingObjectWrapper *) calloc (1, sizeof (TestingObjectWrapper)); | ||
592 | 175 | |||
593 | 176 | ccsObjectInit (to, &ccsDefaultObjectAllocator); | ||
594 | 177 | ccsTestingObjectWrapperRef (to); | ||
595 | 178 | |||
596 | 179 | EXPECT_CALL (GoogleMockDummy::_mockDummy, freeTestingObjectWrapper (to)); | ||
597 | 180 | |||
598 | 181 | ccsTestingObjectWrapperUnref (to); | ||
599 | 182 | } | ||
600 | 183 | |||
601 | 184 | TEST(CCSObjectTest, TestFinalizeFreesEverything) | ||
602 | 185 | { | ||
603 | 186 | TestingObjectWrapper *to = (TestingObjectWrapper *) calloc (1, sizeof (TestingObjectWrapper)); | ||
604 | 187 | |||
605 | 188 | ccsObjectInit (to, &ccsDefaultObjectAllocator); | ||
606 | 189 | ccsObjectAddInterface (to, (const CCSInterface *) &SomeDummyInterface, 1); | ||
607 | 190 | |||
608 | 191 | EXPECT_EQ (*((CCSObject *) to)->interfaces, (const CCSInterface *) (&SomeDummyInterface)); | ||
609 | 192 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 1); | ||
610 | 193 | EXPECT_EQ (*((CCSObject *) to)->interface_types, 1); | ||
611 | 194 | |||
612 | 195 | int *i = (int *) malloc (sizeof (int)); | ||
613 | 196 | |||
614 | 197 | *i = 1; | ||
615 | 198 | |||
616 | 199 | ccsObjectSetPrivate (to, (CCSPrivate *) i); | ||
617 | 200 | |||
618 | 201 | CCSPrivate *p = ccsObjectGetPrivate (to); | ||
619 | 202 | |||
620 | 203 | EXPECT_EQ (i, (int *) p); | ||
621 | 204 | EXPECT_EQ (*i, (*((int *) p))); | ||
622 | 205 | |||
623 | 206 | ccsObjectFinalize (to); | ||
624 | 207 | |||
625 | 208 | EXPECT_EQ (NULL, ((CCSObject *) to)->priv); | ||
626 | 209 | EXPECT_EQ (NULL, ((CCSObject *) to)->interfaces); | ||
627 | 210 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 0); | ||
628 | 211 | EXPECT_EQ (NULL, ((CCSObject *) to)->interface_types); | ||
629 | 212 | } | ||
630 | 213 | |||
631 | 214 | void * | ||
632 | 215 | failingRealloc (void *p, size_t n) | ||
633 | 216 | { | ||
634 | 217 | return NULL; | ||
635 | 218 | } | ||
636 | 219 | |||
637 | 220 | CCSObjectAllocationInterface failingAllocator = | ||
638 | 221 | { | ||
639 | 222 | failingRealloc, | ||
640 | 223 | malloc, | ||
641 | 224 | calloc | ||
642 | 225 | }; | ||
643 | 226 | |||
644 | 227 | TEST(CCSObjectTest, TestReallocFailures) | ||
645 | 228 | { | ||
646 | 229 | TestingObjectWrapper *to = (TestingObjectWrapper *) calloc (1, sizeof (TestingObjectWrapper)); | ||
647 | 230 | |||
648 | 231 | ccsObjectInit (to, &failingAllocator); | ||
649 | 232 | ccsObjectAddInterface (to, (const CCSInterface *) &SomeDummyInterface, 1); | ||
650 | 233 | |||
651 | 234 | EXPECT_EQ (NULL, ((CCSObject *) to)->interfaces); | ||
652 | 235 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 0); | ||
653 | 236 | EXPECT_EQ (NULL, ((CCSObject *) to)->interface_types); | ||
654 | 237 | |||
655 | 238 | free (to); | ||
656 | 239 | } | ||
657 | 240 | |||
658 | 241 | TEST(CCSObjectTest, TestAllocatedMemoryOnRemove) | ||
659 | 242 | { | ||
660 | 243 | TestingObjectWrapper *to = (TestingObjectWrapper *) calloc (1, sizeof (TestingObjectWrapper)); | ||
661 | 244 | |||
662 | 245 | ccsObjectInit (to, &ccsDefaultObjectAllocator); | ||
663 | 246 | ccsObjectAddInterface (to, (const CCSInterface *) &SomeDummyInterface, 1); | ||
664 | 247 | |||
665 | 248 | EXPECT_EQ (*((CCSObject *) to)->interfaces, (const CCSInterface *) (&SomeDummyInterface)); | ||
666 | 249 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 1); | ||
667 | 250 | EXPECT_EQ (*((CCSObject *) to)->interface_types, 1); | ||
668 | 251 | |||
669 | 252 | ccsObjectAddInterface (to, (const CCSInterface *) &SomeDummyInterface, 2); | ||
670 | 253 | |||
671 | 254 | EXPECT_EQ (*((CCSObject *) to)->interfaces, (const CCSInterface *) (&SomeDummyInterface)); | ||
672 | 255 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 2); | ||
673 | 256 | EXPECT_EQ (*((CCSObject *) to)->interface_types, 1); | ||
674 | 257 | |||
675 | 258 | ccsObjectRemoveInterface (to, 1); | ||
676 | 259 | |||
677 | 260 | EXPECT_EQ (*((CCSObject *) to)->interfaces, (const CCSInterface *) (&SomeDummyInterface)); | ||
678 | 261 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 1); | ||
679 | 262 | EXPECT_EQ (((CCSObject *) to)->n_allocated_interfaces, 2); | ||
680 | 263 | EXPECT_EQ (*((CCSObject *) to)->interface_types, 2); | ||
681 | 264 | |||
682 | 265 | ccsObjectRemoveInterface (to, 2); | ||
683 | 266 | |||
684 | 267 | EXPECT_EQ (NULL, ((CCSObject *) to)->interfaces); | ||
685 | 268 | EXPECT_EQ (((CCSObject *) to)->n_interfaces, 0); | ||
686 | 269 | EXPECT_EQ (((CCSObject *) to)->n_allocated_interfaces, 0); | ||
687 | 270 | EXPECT_EQ (NULL, ((CCSObject *) to)->interface_types); | ||
688 | 271 | |||
689 | 272 | free (to); | ||
690 | 273 | } |
I know it is common (and may be a project style) but there is no advantage to having different names to refer to the same thing in different namespaces. That is not:
typedef struct _CCSObject CCSObject;
struct _CCSObject
{
...
};
but:
typedef struct CCSObject
{
...
} CCSObject;