Commit 6aeeca6d authored by Sam Hocevar's avatar Sam Hocevar

  * ./src/misc/modules.c: changed module_Need to make it possible to
    have several modules with the same shortcut name.
parent 11a8a96f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* modules.c : Built-in and plugin modules management functions * modules.c : Built-in and plugin modules management functions
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: modules.c,v 1.50 2002/01/24 13:32:53 sam Exp $ * $Id: modules.c,v 1.51 2002/02/04 09:58:59 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Ethan C. Baldridge <BaldridgeE@cadmus.com> * Ethan C. Baldridge <BaldridgeE@cadmus.com>
...@@ -268,18 +268,25 @@ int module_NeedIntf( intf_module_t *p_intf ) ...@@ -268,18 +268,25 @@ int module_NeedIntf( intf_module_t *p_intf )
*****************************************************************************/ *****************************************************************************/
module_t * module_Need( int i_capability, char *psz_name, probedata_t *p_data ) module_t * module_Need( int i_capability, char *psz_name, probedata_t *p_data )
{ {
module_t * p_module; typedef struct module_list_s
{
struct module_s *p_module;
struct module_list_s* p_next;
} module_list_t;
struct module_list_s *p_list, *p_first;
int i_score = 0;
int i_index = 0;
module_t *p_module;
char *psz_realname = NULL;
/* We take the global lock */ /* We take the global lock */
vlc_mutex_lock( &p_module_bank->lock ); vlc_mutex_lock( &p_module_bank->lock );
if( psz_name != NULL && *psz_name ) if( psz_name != NULL && *psz_name )
{ {
/* A module name was requested. Use the first matching one. */ /* A module name was requested. */
char *psz_realname = NULL;
int i_index;
boolean_t b_ok = 0;
psz_realname = strdup( psz_name ); psz_realname = strdup( psz_name );
if( psz_realname ) if( psz_realname )
{ {
...@@ -291,160 +298,121 @@ module_t * module_Need( int i_capability, char *psz_name, probedata_t *p_data ) ...@@ -291,160 +298,121 @@ module_t * module_Need( int i_capability, char *psz_name, probedata_t *p_data )
} }
psz_name = psz_realname; psz_name = psz_realname;
} }
}
for( p_module = p_module_bank->first;
p_module != NULL;
p_module = p_module->next )
{
/* Test that this module can do everything we need */
if( !(p_module->i_capabilities & ( 1 << i_capability )) )
{
continue;
}
/* Test if we have the required CPU */
if( (p_module->i_cpu_capabilities & p_main->i_cpu_capabilities)
!= p_module->i_cpu_capabilities )
{
continue;
}
/* Test if this plugin exports the required shortcut */
for( i_index = 0;
!b_ok && p_module->pp_shortcuts[i_index];
i_index++ )
{
b_ok = !strcmp( psz_name, p_module->pp_shortcuts[i_index] );
}
if( b_ok ) /* Sort the modules and test them */
{ p_list = malloc( p_module_bank->i_count * sizeof( module_list_t ) );
break; p_first = NULL;
}
}
if( b_ok ) /* Parse the module list for capabilities and probe each of them */
{ for( p_module = p_module_bank->first ;
/* Open it ! */ p_module != NULL ;
LockModule( p_module ); p_module = p_module->next )
} {
else /* Test that this module can do everything we need */
if( !(p_module->i_capabilities & ( 1 << i_capability )) )
{ {
intf_ErrMsg( "module error: requested %s module `%s' not found", continue;
GetCapabilityName( i_capability ), psz_name );
} }
if( psz_realname ) /* Test if we have the required CPU */
if( (p_module->i_cpu_capabilities & p_main->i_cpu_capabilities)
!= p_module->i_cpu_capabilities )
{ {
free( psz_realname ); continue;
} }
}
else /* Test if this plugin exports the required shortcut */
{ if( psz_name != NULL && *psz_name )
/* No module name was requested. Sort the modules and test them */
typedef struct module_list_s
{
struct module_s *p_module;
struct module_list_s* p_next;
} module_list_t;
int i_score = 0;
int i_index = 0;
struct module_list_s *p_list = malloc( p_module_bank->i_count
* sizeof( module_list_t ) );
struct module_list_s *p_first = NULL;
/* Parse the module list for capabilities and probe each of them */
for( p_module = p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
{ {
/* Test that this module can do everything we need */ boolean_t b_ok = 0;
if( !(p_module->i_capabilities & ( 1 << i_capability )) ) int i_dummy;
for( i_dummy = 0;
!b_ok && p_module->pp_shortcuts[i_dummy];
i_dummy++ )
{ {
continue; b_ok = !strcmp( psz_name, p_module->pp_shortcuts[i_dummy] );
} }
/* Test if we have the required CPU */ if( !b_ok )
if( (p_module->i_cpu_capabilities & p_main->i_cpu_capabilities)
!= p_module->i_cpu_capabilities )
{ {
continue; continue;
} }
}
/* Test if we requested a particular intf plugin */ /* Test if we requested a particular intf plugin */
#if 0 #if 0
if( i_capability == MODULE_CAPABILITY_INTF if( i_capability == MODULE_CAPABILITY_INTF
&& p_module->psz_program != NULL && p_module->psz_program != NULL
&& strcmp( p_module->psz_program, p_main->psz_arg0 ) ) && strcmp( p_module->psz_program, p_main->psz_arg0 ) )
{ {
continue; continue;
} }
#endif #endif
/* Store this new module */ /* Store this new module */
p_list[ i_index ].p_module = p_module; p_list[ i_index ].p_module = p_module;
if( i_index == 0 ) if( i_index == 0 )
{
p_list[ i_index ].p_next = NULL;
p_first = p_list;
}
else
{
/* Ok, so at school you learned that quicksort is quick, and
* bubble sort sucks raw eggs. But that's when dealing with
* thousands of items. Here we have barely 50. */
struct module_list_s *p_newlist = p_first;
if( p_first->p_module->pi_score[i_capability]
< p_module->pi_score[i_capability] )
{ {
p_list[ i_index ].p_next = NULL; p_list[ i_index ].p_next = p_first;
p_first = p_list; p_first = &p_list[ i_index ];
} }
else else
{ {
/* Ok, so at school you learned that quicksort is quick, and while( p_newlist->p_next != NULL
* bubble sort sucks raw eggs. But that's when dealing with && p_newlist->p_next
* thousands of items. Here we have barely 50. */ ->p_module->pi_score[i_capability]
struct module_list_s *p_newlist = p_first; >= p_module->pi_score[i_capability] )
if( p_first->p_module->pi_score[i_capability]
< p_module->pi_score[i_capability] )
{ {
p_list[ i_index ].p_next = p_first; p_newlist = p_newlist->p_next;
p_first = &p_list[ i_index ];
} }
else
{
while( p_newlist->p_next != NULL
&& p_newlist->p_next
->p_module->pi_score[i_capability]
>= p_module->pi_score[i_capability] )
{
p_newlist = p_newlist->p_next;
}
p_list[ i_index ].p_next = p_newlist->p_next; p_list[ i_index ].p_next = p_newlist->p_next;
p_newlist->p_next = &p_list[ i_index ]; p_newlist->p_next = &p_list[ i_index ];
}
} }
i_index++;
} }
/* Parse the linked list and use the first successful module */ i_index++;
while( p_first != NULL ) }
{
LockModule( p_first->p_module );
/* Test the requested capability */
i_score += ((function_list_t *)p_first->p_module->p_functions)
[i_capability].pf_probe( p_data );
/* If the high score was broken, we have a new champion */ /* Parse the linked list and use the first successful module */
if( i_score ) while( p_first != NULL )
{ {
break; LockModule( p_first->p_module );
}
UnlockModule( p_first->p_module ); /* Test the requested capability */
i_score += ((function_list_t *)p_first->p_module->p_functions)
[i_capability].pf_probe( p_data );
p_first = p_first->p_next; /* If the high score was broken, we have a new champion */
if( i_score )
{
break;
} }
p_module = (p_first == NULL) ? NULL : p_first->p_module; UnlockModule( p_first->p_module );
free( p_list );
p_first = p_first->p_next;
} }
p_module = (p_first == NULL) ? NULL : p_first->p_module;
free( p_list );
/* We can release the global lock, module refcount was incremented */ /* We can release the global lock, module refcount was incremented */
vlc_mutex_unlock( &p_module_bank->lock ); vlc_mutex_unlock( &p_module_bank->lock );
...@@ -454,6 +422,16 @@ module_t * module_Need( int i_capability, char *psz_name, probedata_t *p_data ) ...@@ -454,6 +422,16 @@ module_t * module_Need( int i_capability, char *psz_name, probedata_t *p_data )
GetCapabilityName( i_capability ), GetCapabilityName( i_capability ),
p_module->psz_name ); p_module->psz_name );
} }
else if( psz_name != NULL && *psz_name )
{
intf_ErrMsg( "module error: requested %s module `%s' not found",
GetCapabilityName( i_capability ), psz_name );
}
if( psz_realname )
{
free( psz_realname );
}
/* Don't forget that the module is still locked if bestmodule != NULL */ /* Don't forget that the module is still locked if bestmodule != NULL */
return( p_module ); return( p_module );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment