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, 2010, 2011 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
));