we assumed GType fitted in an int

which isn't true on freebsd, and perhaps others
This commit is contained in:
John Cupitt 2014-06-29 11:17:23 +01:00
parent 362b2db9ab
commit c2a8c542b6
3 changed files with 33 additions and 19 deletions

View File

@ -3,6 +3,7 @@
- improve short option name handling, thanks bgilbert - improve short option name handling, thanks bgilbert
- added --enable-docs configure option to help freebsd - added --enable-docs configure option to help freebsd
- removed a bash-ism from configure to help freebsd - removed a bash-ism from configure to help freebsd
- don't assume GType fits in an int to help freebsd
24/6/14 started 7.40.1 24/6/14 started 7.40.1
- revise man.1 pages - revise man.1 pages

3
TODO
View File

@ -1,6 +1,3 @@
- need a --nodoc flag for freebsd
stops anything in doc/ running
- threadpool recyling might be useful for dzsave? - threadpool recyling might be useful for dzsave?

View File

@ -2541,25 +2541,36 @@ vips_class_find( const char *basename, const char *nickname )
return( class ); return( class );
} }
/* What we store for each nickname. We can't just store the type with
* GINT_TO_POINTER() since GType is 64 bits on some platforms.
*/
typedef struct _NicknameGType {
const char *nickname;
GType type;
gboolean duplicate;
} NicknameGType;
static void * static void *
vips_class_add_hash( VipsObjectClass *class, GHashTable *table ) vips_class_add_hash( VipsObjectClass *class, GHashTable *table )
{ {
GType type = G_OBJECT_CLASS_TYPE( class ); GType type = G_OBJECT_CLASS_TYPE( class );
NicknameGType *hit;
/* If this is not a unique name, store -1 for the GType. In this case hit = (NicknameGType *)
g_hash_table_lookup( table, (void *) class->nickname );
/* If this is not a unique name, mark as a duplicate. In this case
* we'll need to fall back to a search. * we'll need to fall back to a search.
*/ */
if( g_hash_table_lookup( table, (void *) class->nickname ) ) { if( hit )
g_hash_table_insert( table, hit->duplicate = TRUE;
(void *) class->nickname, GINT_TO_POINTER( -1 ) ); else {
#ifdef DEBUG hit = g_new( NicknameGType, 1 );
printf( "vips_class_add_hash: duplicate nickname %s\n", hit->nickname = class->nickname;
class->nickname ); hit->type = type;
#endif /*DEBUG*/ hit->duplicate = FALSE;
g_hash_table_insert( table, (void *) hit->nickname, hit );
} }
else
g_hash_table_insert( table,
(void *) class->nickname, GINT_TO_POINTER( type ) );
return( NULL ); return( NULL );
} }
@ -2587,27 +2598,32 @@ vips_type_find( const char *basename, const char *nickname )
const char *classname = basename ? basename : "VipsObject"; const char *classname = basename ? basename : "VipsObject";
NicknameGType *hit;
GType base; GType base;
GType type; GType type;
vips__object_nickname_table = (GHashTable *) g_once( &once, vips__object_nickname_table = (GHashTable *) g_once( &once,
(GThreadFunc) vips_class_build_hash, NULL ); (GThreadFunc) vips_class_build_hash, NULL );
type = GPOINTER_TO_INT( g_hash_table_lookup( hit = (NicknameGType *)
vips__object_nickname_table, (void *) nickname ) ); g_hash_table_lookup( vips__object_nickname_table,
(void *) nickname );
/* We must only search below basename ... check that the cache hit is /* We must only search below basename ... check that the cache hit is
* in the right part of the tree. * in the right part of the tree.
*/ */
if( !(base = g_type_from_name( classname )) ) if( !(base = g_type_from_name( classname )) )
return( 0 ); return( 0 );
if( !type || if( hit &&
type == -1 || !hit->duplicate &&
!g_type_is_a( type, base ) ) { g_type_is_a( hit->type, base ) )
type = hit->type;
else {
VipsObjectClass *class; VipsObjectClass *class;
if( !(class = vips_class_find( basename, nickname )) ) if( !(class = vips_class_find( basename, nickname )) )
return( 0 ); return( 0 );
type = G_OBJECT_CLASS_TYPE( class ); type = G_OBJECT_CLASS_TYPE( class );
} }