3
* A Nautilus extension which offers configurable context menu actions.
5
* Copyright (C) 2005 The GNOME Foundation
6
* Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
7
* Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
9
* This Program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License as
11
* published by the Free Software Foundation; either version 2 of
12
* the License, or (at your option) any later version.
14
* This Program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public
20
* License along with this Library; see the file COPYING. If not,
21
* write to the Free Software Foundation, Inc., 59 Temple Place,
22
* Suite 330, Boston, MA 02111-1307, USA.
25
* Frederic Ruaudel <grumz@grumz.net>
26
* Rodrigo Moya <rodrigo@gnome-db.org>
27
* Pierre Wieser <pwieser@trychlos.org>
28
* ... and many others (see AUTHORS)
31
/* We want test here what is the exact behavior of virtual functions in
32
* derived classes, whether or not base class has implemented them or
35
* We define three classes, and some virtual functions :
36
* class A: fn1, fn2, fn3
37
* class AB: implements fn1, fn2
38
* class ABC: implements fn1, fn3
40
* Public entry points are defined in class A: we check that calling
41
* public entry points with an object of each class actually calls the
42
* relevant virtual function.
44
* Also we check that calling the parent class is possible even if the
45
* parent class has not explicitely defined the virtual function.
47
* Same as test-virtuals.c, without the test for existance of function.
50
#include <glib-object.h>
53
#define PWI_FIRST_TYPE ( pwi_first_get_type())
54
#define PWI_FIRST( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, PWI_FIRST_TYPE, PwiFirst ))
55
#define PWI_FIRST_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, PWI_FIRST_TYPE, PwiFirstClass ))
56
#define PWI_IS_FIRST( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, PWI_FIRST_TYPE ))
57
#define PWI_IS_FIRST_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), PWI_FIRST_TYPE ))
58
#define PWI_FIRST_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), PWI_FIRST_TYPE, PwiFirstClass ))
60
typedef struct PwiFirstPrivate PwiFirstPrivate;
64
PwiFirstPrivate *private;
68
typedef struct PwiFirstClassPrivate PwiFirstClassPrivate;
72
PwiFirstClassPrivate *private;
74
/* virtual functions */
75
void ( *fn_a )( PwiFirst *instance );
76
void ( *fn_b )( PwiFirst *instance );
77
void ( *fn_c )( PwiFirst *instance );
81
GType pwi_first_get_type( void );
83
void pwi_first_fn_a( PwiFirst *instance );
84
void pwi_first_fn_b( PwiFirst *instance );
85
void pwi_first_fn_c( PwiFirst *instance );
87
#define PWI_FIRST_SECOND_TYPE ( pwi_first_second_get_type())
88
#define PWI_FIRST_SECOND( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, PWI_FIRST_SECOND_TYPE, PwiFirstSecond ))
89
#define PWI_FIRST_SECOND_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, PWI_FIRST_SECOND_TYPE, PwiFirstSecondClass ))
90
#define PWI_IS_FIRST_SECOND( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, PWI_FIRST_SECOND_TYPE ))
91
#define PWI_IS_FIRST_SECOND_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), PWI_FIRST_SECOND_TYPE ))
92
#define PWI_FIRST_SECOND_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), PWI_FIRST_SECOND_TYPE, PwiFirstSecondClass ))
94
typedef struct PwiFirstSecondPrivate PwiFirstSecondPrivate;
98
PwiFirstSecondPrivate *private;
102
typedef struct PwiFirstSecondClassPrivate PwiFirstSecondClassPrivate;
105
PwiFirstClass parent;
106
PwiFirstSecondClassPrivate *private;
110
GType pwi_first_second_get_type( void );
112
#define PWI_FIRST_SECOND_THREE_TYPE ( pwi_first_second_three_get_type())
113
#define PWI_FIRST_SECOND_THREE( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, PWI_FIRST_SECOND_THREE_TYPE, PwiFirstSecondThree ))
114
#define PWI_FIRST_SECOND_THREE_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, PWI_FIRST_SECOND_THREE_TYPE, PwiFirstSecondThreeClass ))
115
#define PWI_IS_FIRST_SECOND_THREE( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, PWI_FIRST_SECOND_THREE_TYPE ))
116
#define PWI_IS_FIRST_SECOND_THREE_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), PWI_FIRST_SECOND_THREE_TYPE ))
117
#define PWI_FIRST_SECOND_THREE_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), PWI_FIRST_SECOND_THREE_TYPE, PwiFirstSecondThreeClass ))
119
typedef struct PwiFirstSecondThreePrivate PwiFirstSecondThreePrivate;
122
PwiFirstSecond parent;
123
PwiFirstSecondThreePrivate *private;
127
typedef struct PwiFirstSecondThreeClassPrivate PwiFirstSecondThreeClassPrivate;
130
PwiFirstSecondClass parent;
131
PwiFirstSecondThreeClassPrivate *private;
133
PwiFirstSecondThreeClass;
135
GType pwi_first_second_three_get_type( void );
137
struct PwiFirstClassPrivate {
138
void *empty; /* so that gcc -pedantic is happy */
141
struct PwiFirstPrivate {
142
void *empty; /* so that gcc -pedantic is happy */
145
static GObjectClass *st_first_parent_class = NULL;
147
static GType first_register_type( void );
148
static void first_class_init( PwiFirstClass *klass );
149
static void first_instance_init( GTypeInstance *instance, gpointer klass );
150
static void first_instance_dispose( GObject *application );
151
static void first_instance_finalize( GObject *application );
153
static void do_first_fn_a( PwiFirst *instance );
154
static void do_first_fn_b( PwiFirst *instance );
155
static void do_first_fn_c( PwiFirst *instance );
158
pwi_first_get_type( void )
160
static GType type = 0;
163
type = first_register_type();
170
first_register_type( void )
172
static const gchar *thisfn = "first_register_type";
174
static GTypeInfo info = {
175
sizeof( PwiFirstClass ),
176
( GBaseInitFunc ) NULL,
177
( GBaseFinalizeFunc ) NULL,
178
( GClassInitFunc ) first_class_init,
183
( GInstanceInitFunc ) first_instance_init
186
g_debug( "%s", thisfn );
187
return( g_type_register_static( G_TYPE_OBJECT, "PwiFirst", &info, 0 ));
191
first_class_init( PwiFirstClass *klass )
193
static const gchar *thisfn = "first_class_init";
194
GObjectClass *object_class;
196
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
198
st_first_parent_class = g_type_class_peek_parent( klass );
200
object_class = G_OBJECT_CLASS( klass );
201
object_class->dispose = first_instance_dispose;
202
object_class->finalize = first_instance_finalize;
204
klass->private = g_new0( PwiFirstClassPrivate, 1 );
206
klass->fn_a = do_first_fn_a;
207
klass->fn_b = do_first_fn_b;
208
klass->fn_c = do_first_fn_c;
212
first_instance_init( GTypeInstance *instance, gpointer klass )
214
static const gchar *thisfn = "first_instance_init";
217
g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) instance, ( void * ) klass );
218
g_assert( PWI_IS_FIRST( instance ));
219
self = PWI_FIRST( instance );
221
self->private = g_new0( PwiFirstPrivate, 1 );
225
first_instance_dispose( GObject *instance )
227
static const gchar *thisfn = "first_instance_dispose";
230
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
231
g_assert( PWI_IS_FIRST( instance ));
232
self = PWI_FIRST( instance );
234
/* chain up to the parent class */
235
G_OBJECT_CLASS( st_first_parent_class )->dispose( instance );
239
first_instance_finalize( GObject *instance )
241
static const gchar *thisfn = "first_instance_finalize";
244
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
245
g_assert( PWI_IS_FIRST( instance ));
246
self = PWI_FIRST( instance );
248
g_free( self->private );
250
/* chain call to parent class */
251
G_OBJECT_CLASS( st_first_parent_class )->finalize( instance );
255
pwi_first_fn_a( PwiFirst *instance )
257
g_debug( "pwi_first_fn_a: instance=%p", ( void * ) instance );
258
g_assert( PWI_IS_FIRST( instance ));
260
PWI_FIRST_GET_CLASS( instance )->fn_a( instance );
264
do_first_fn_a( PwiFirst *instance )
266
g_debug( "do_first_fn_a: instance=%p", ( void * ) instance );
270
pwi_first_fn_b( PwiFirst *instance )
272
g_debug( "pwi_first_fn_b: instance=%p", ( void * ) instance );
273
g_assert( PWI_IS_FIRST( instance ));
275
PWI_FIRST_GET_CLASS( instance )->fn_b( instance );
279
do_first_fn_b( PwiFirst *instance )
281
g_debug( "do_first_fn_b: instance=%p", ( void * ) instance );
285
pwi_first_fn_c( PwiFirst *instance )
287
g_debug( "pwi_first_fn_c: instance=%p", ( void * ) instance );
288
g_assert( PWI_IS_FIRST( instance ));
290
PWI_FIRST_GET_CLASS( instance )->fn_c( instance );
294
do_first_fn_c( PwiFirst *instance )
296
g_debug( "do_first_fn_c: instance=%p", ( void * ) instance );
299
struct PwiFirstSecondClassPrivate {
300
void *empty; /* so that gcc -pedantic is happy */
303
struct PwiFirstSecondPrivate {
304
void *empty; /* so that gcc -pedantic is happy */
307
static PwiFirstClass *st_first_second_parent_class = NULL;
309
static GType first_second_register_type( void );
310
static void first_second_class_init( PwiFirstSecondClass *klass );
311
static void first_second_instance_init( GTypeInstance *instance, gpointer klass );
312
static void first_second_instance_dispose( GObject *application );
313
static void first_second_instance_finalize( GObject *application );
315
static void do_first_second_fn_a( PwiFirst *instance );
316
static void do_first_second_fn_b( PwiFirst *instance );
319
pwi_first_second_get_type( void )
321
static GType type = 0;
324
type = first_second_register_type();
331
first_second_register_type( void )
333
static const gchar *thisfn = "first_second_register_type";
335
static GTypeInfo info = {
336
sizeof( PwiFirstSecondClass ),
337
( GBaseInitFunc ) NULL,
338
( GBaseFinalizeFunc ) NULL,
339
( GClassInitFunc ) first_second_class_init,
342
sizeof( PwiFirstSecond ),
344
( GInstanceInitFunc ) first_second_instance_init
347
g_debug( "%s", thisfn );
348
return( g_type_register_static( PWI_FIRST_TYPE, "PwiFirstSecond", &info, 0 ));
352
first_second_class_init( PwiFirstSecondClass *klass )
354
static const gchar *thisfn = "first_second_class_init";
355
GObjectClass *object_class;
356
PwiFirstClass *first_class;
358
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
360
st_first_second_parent_class = g_type_class_peek_parent( klass );
362
object_class = G_OBJECT_CLASS( klass );
363
object_class->dispose = first_second_instance_dispose;
364
object_class->finalize = first_second_instance_finalize;
366
klass->private = g_new0( PwiFirstSecondClassPrivate, 1 );
368
first_class = PWI_FIRST_CLASS( klass );
369
first_class->fn_a = do_first_second_fn_a;
370
first_class->fn_b = do_first_second_fn_b;
371
first_class->fn_c = NULL;
375
first_second_instance_init( GTypeInstance *instance, gpointer klass )
377
static const gchar *thisfn = "first_second_instance_init";
378
PwiFirstSecond *self;
380
g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) instance, ( void * ) klass );
381
g_assert( PWI_IS_FIRST_SECOND( instance ));
382
self = PWI_FIRST_SECOND( instance );
384
self->private = g_new0( PwiFirstSecondPrivate, 1 );
388
first_second_instance_dispose( GObject *instance )
390
static const gchar *thisfn = "first_second_instance_dispose";
391
PwiFirstSecond *self;
393
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
394
g_assert( PWI_IS_FIRST_SECOND( instance ));
395
self = PWI_FIRST_SECOND( instance );
397
/* chain up to the parent class */
398
G_OBJECT_CLASS( st_first_second_parent_class )->dispose( instance );
402
first_second_instance_finalize( GObject *instance )
404
static const gchar *thisfn = "first_second_instance_finalize";
405
PwiFirstSecond *self;
407
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
408
g_assert( PWI_IS_FIRST_SECOND( instance ));
409
self = PWI_FIRST_SECOND( instance );
411
g_free( self->private );
413
/* chain call to parent class */
414
G_OBJECT_CLASS( st_first_second_parent_class )->finalize( instance );
418
do_first_second_fn_a( PwiFirst *instance )
420
g_debug( "do_first_second_fn_a: instance=%p", ( void * ) instance );
421
PWI_FIRST_CLASS( st_first_second_parent_class )->fn_a( instance );
425
do_first_second_fn_b( PwiFirst *instance )
427
g_debug( "do_first_second_fn_b: instance=%p", ( void * ) instance );
428
PWI_FIRST_CLASS( st_first_second_parent_class )->fn_b( instance );
431
struct PwiFirstSecondThreeClassPrivate {
432
void *empty; /* so that gcc -pedantic is happy */
435
struct PwiFirstSecondThreePrivate {
436
void *empty; /* so that gcc -pedantic is happy */
439
static PwiFirstSecondClass *st_first_second_three_parent_class = NULL;
441
static GType first_second_three_register_type( void );
442
static void first_second_three_class_init( PwiFirstSecondThreeClass *klass );
443
static void first_second_three_instance_init( GTypeInstance *instance, gpointer klass );
444
static void first_second_three_instance_dispose( GObject *application );
445
static void first_second_three_instance_finalize( GObject *application );
447
static void do_first_second_three_fn_a( PwiFirst *instance );
448
static void do_first_second_three_fn_c( PwiFirst *instance );
451
pwi_first_second_three_get_type( void )
453
static GType type = 0;
456
type = first_second_three_register_type();
463
first_second_three_register_type( void )
465
static const gchar *thisfn = "first_second_three_register_type";
467
static GTypeInfo info = {
468
sizeof( PwiFirstSecondThreeClass ),
469
( GBaseInitFunc ) NULL,
470
( GBaseFinalizeFunc ) NULL,
471
( GClassInitFunc ) first_second_three_class_init,
474
sizeof( PwiFirstSecondThree ),
476
( GInstanceInitFunc ) first_second_three_instance_init
479
g_debug( "%s", thisfn );
480
return( g_type_register_static( PWI_FIRST_SECOND_TYPE, "PwiFirstSecondThree", &info, 0 ));
484
first_second_three_class_init( PwiFirstSecondThreeClass *klass )
486
static const gchar *thisfn = "first_second_three_class_init";
487
GObjectClass *object_class;
488
PwiFirstClass *first_class;
490
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
492
st_first_second_three_parent_class = g_type_class_peek_parent( klass );
494
object_class = G_OBJECT_CLASS( klass );
495
object_class->dispose = first_second_three_instance_dispose;
496
object_class->finalize = first_second_three_instance_finalize;
498
klass->private = g_new0( PwiFirstSecondThreeClassPrivate, 1 );
500
first_class = PWI_FIRST_CLASS( klass );
501
first_class->fn_a = do_first_second_three_fn_a;
502
first_class->fn_b = NULL;
503
first_class->fn_c = do_first_second_three_fn_c;
507
first_second_three_instance_init( GTypeInstance *instance, gpointer klass )
509
static const gchar *thisfn = "first_second_three_instance_init";
510
PwiFirstSecondThree *self;
512
g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) instance, ( void * ) klass );
513
g_assert( PWI_IS_FIRST_SECOND_THREE( instance ));
514
self = PWI_FIRST_SECOND_THREE( instance );
516
self->private = g_new0( PwiFirstSecondThreePrivate, 1 );
520
first_second_three_instance_dispose( GObject *instance )
522
static const gchar *thisfn = "first_second_three_instance_dispose";
523
PwiFirstSecondThree *self;
525
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
526
g_assert( PWI_IS_FIRST_SECOND_THREE( instance ));
527
self = PWI_FIRST_SECOND_THREE( instance );
529
/* chain up to the parent class */
530
G_OBJECT_CLASS( st_first_second_three_parent_class )->dispose( instance );
534
first_second_three_instance_finalize( GObject *instance )
536
static const gchar *thisfn = "first_second_three_instance_finalize";
537
PwiFirstSecondThree *self;
539
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
540
g_assert( PWI_IS_FIRST_SECOND_THREE( instance ));
541
self = PWI_FIRST_SECOND_THREE( instance );
543
g_free( self->private );
545
/* chain call to parent class */
546
G_OBJECT_CLASS( st_first_second_three_parent_class )->finalize( instance );
550
do_first_second_three_fn_a( PwiFirst *instance )
552
g_debug( "do_first_second_three_fn_a: instance=%p", ( void * ) instance );
553
PWI_FIRST_CLASS( st_first_second_three_parent_class )->fn_a( instance );
557
do_first_second_three_fn_c( PwiFirst *instance )
559
g_debug( "do_first_second_three_fn_c: instance=%p", ( void * ) instance );
560
PWI_FIRST_CLASS( st_first_second_three_parent_class )->fn_c( instance );
564
main( int argc, char **argv )
568
PwiFirstSecondThree *c;
572
a = g_object_new( PWI_FIRST_TYPE, NULL );
573
b = g_object_new( PWI_FIRST_SECOND_TYPE, NULL );
574
c = g_object_new( PWI_FIRST_SECOND_THREE_TYPE, NULL );
576
g_debug( "expected pwi_first_fn_a, do_first_fn_a" );
577
pwi_first_fn_a( PWI_FIRST( a ));
578
g_debug( "expected pwi_first_fn_a, do_first_second_fn_a, do_first_fn_a" );
579
pwi_first_fn_a( PWI_FIRST( b ));
580
g_debug( "expected pwi_first_fn_a, do_first_second_three_fn_a, do_first_second_fn_a, do_first_fn_a" );
581
pwi_first_fn_a( PWI_FIRST( c ));
585
g_debug( "expected pwi_first_fn_b, do_first_fn_b" );
586
pwi_first_fn_b( PWI_FIRST( a ));
587
g_debug( "expected pwi_first_fn_b, do_first_second_fn_b, do_first_fn_b" );
588
pwi_first_fn_b( PWI_FIRST( b ));
589
g_debug( "expected pwi_first_fn_b, do_first_second_fn_b, do_first_fn_b" );
591
* segmentation fault after pwi_first_fn_b */
592
pwi_first_fn_b( PWI_FIRST( c ));
596
g_debug( "expected pwi_first_fn_c, do_first_fn_c" );
597
pwi_first_fn_c( PWI_FIRST( a ));
598
g_debug( "expected pwi_first_fn_c, do_first_fn_c" );
599
pwi_first_fn_c( PWI_FIRST( b ));
600
g_debug( "expected pwi_first_fn_c, do_first_second_three_fn_c, do_first_fn_c" );
601
pwi_first_fn_c( PWI_FIRST( c ));