]> git.sesse.net Git - vlc/blobdiff - src/misc/modules.c
Add facilities to report and enrich error messages.
[vlc] / src / misc / modules.c
index c89f014d0efebced58c1cc4fea2c70a82d64291d..b22a48209b977b63e291dcca234b9aff33482ff5 100644 (file)
@@ -36,8 +36,6 @@
 #include <stdio.h>                                              /* sprintf() */
 #include <string.h>                                              /* strdup() */
 
-#include <vlc/input.h>
-
 #ifdef HAVE_DIRENT_H
 #   include <dirent.h>
 #endif
 #   endif
 #endif
 
-#include "vlc_error.h"
+#include "misc/configuration.h"
 
 #include "vlc_interface.h"
-#include "vlc_interaction.h"
-#include "intf_eject.h"
-
 #include "vlc_playlist.h"
 
-#include "vlc_video.h"
-#include "video_output.h"
-#include "vout_synchro.h"
-#include "vlc_spu.h"
+#include "vlc_stream.h"
+#include "vlc_access.h"
+#include "vlc_demux.h"
 
-#include "audio_output.h"
-#include "aout_internal.h"
+#include "vlc_vout.h"
+#include "vlc_vout_synchro.h"
 
-#include "stream_output.h"
+#include "vlc_aout.h"
+
+#include "vlc_sout.h"
 #include "vlc_httpd.h"
 #include "vlc_acl.h"
 #include "vlc_tls.h"
 #include "vlc_url.h"
 
 #include "iso_lang.h"
-#include "charset.h"
+#include "vlc_charset.h"
 
 #include "vlc_block.h"
 
 #include "vlc_strings.h"
 #include "vlc_streaming.h"
 
+#include "modules.h"
+
 #if defined( _MSC_VER ) && defined( UNDER_CE )
 #    include "modules_builtin_evc.h"
 #elif defined( _MSC_VER )
 #else
 #    include "modules_builtin.h"
 #endif
-#include "network.h"
+#include "vlc_network.h"
 
 #if defined( WIN32 ) || defined( UNDER_CE )
     /* Avoid name collisions */
@@ -160,6 +158,8 @@ static char * GetWindowsError  ( void );
 #endif
 #endif
 
+static void module_LoadMain( vlc_object_t *p_this );
+
 
 /* Sub-version number
  * (only used to avoid breakage in dev version when cache structure changes) */
@@ -193,7 +193,7 @@ void __module_InitBank( vlc_object_t *p_this )
     p_bank->psz_object_name = "module bank";
     p_bank->i_usage = 1;
     p_bank->i_cache = p_bank->i_loaded_cache = 0;
-    p_bank->pp_cache = p_bank->pp_loaded_cache = 0;
+    p_bank->pp_cache = p_bank->pp_loaded_cache = NULL;
     p_bank->b_cache = p_bank->b_cache_dirty =
         p_bank->b_cache_delete = VLC_FALSE;
 
@@ -261,6 +261,7 @@ void __module_EndBank( vlc_object_t *p_this )
     if( p_bank->b_cache ) CacheSave( p_this );
     while( p_bank->i_loaded_cache-- )
     {
+        DeleteModule (p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->p_module);
         free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->psz_file );
         free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] );
     }
@@ -309,7 +310,7 @@ void __module_EndBank( vlc_object_t *p_this )
  * as another module, and for instance the configuration options of main will
  * be available in the module bank structure just as for every other module.
  *****************************************************************************/
-void __module_LoadMain( vlc_object_t *p_this )
+static void module_LoadMain( vlc_object_t *p_this )
 {
     vlc_value_t lockval;
 
@@ -698,6 +699,9 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
         {
             msg_Err( p_this, "no %s module matched \"%s\"",
                  psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
+
+            msg_StackSet( VLC_EGENERIC, "no %s module matched \"%s\"",
+                 psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
         }
     }
     else if( psz_name != NULL && *psz_name )
@@ -705,6 +709,8 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
         msg_Warn( p_this, "no %s module matching \"%s\" could be loaded",
                   psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
     }
+    else
+        msg_StackSet( VLC_EGENERIC, "no suitable %s module", psz_capability );
 
     if( psz_shortcuts )
     {
@@ -810,6 +816,12 @@ static void AllocateAllPlugins( vlc_object_t *p_this )
 static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir,
                                int i_maxdepth )
 {
+/* FIXME: Needs to be ported to wide char on ALL Windows builds */
+#ifdef WIN32
+# undef opendir
+# undef closedir
+# undef readdir
+#endif
 #if defined( UNDER_CE ) || defined( _MSC_VER )
 #ifdef UNDER_CE
     wchar_t psz_wpath[MAX_PATH + 256];
@@ -1014,7 +1026,7 @@ static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file,
         }
         else
         {
-            module_config_t *p_item;
+            module_config_t *p_item, *p_end;
 
             p_module = p_cache_entry->p_module;
             p_module->b_loaded = VLC_FALSE;
@@ -1022,8 +1034,8 @@ static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file,
             /* For now we force loading if the module's config contains
              * callbacks or actions.
              * Could be optimized by adding an API call.*/
-            for( p_item = p_module->p_config;
-                 p_item->i_type != CONFIG_HINT_END; p_item++ )
+            for( p_item = p_module->p_config, p_end = p_item + p_module->confsize;
+                 p_item < p_end; p_item++ )
             {
                 if( p_item->pf_callback || p_item->i_action )
                     p_module = AllocatePlugin( p_this, psz_file );
@@ -1702,22 +1714,28 @@ static void CacheLoad( vlc_object_t *p_this )
 #define LOAD_IMMEDIATE(a) \
     if( fread( (void *)&a, sizeof(char), sizeof(a), file ) != sizeof(a) ) goto error
 #define LOAD_STRING(a) \
-    { if( fread( &i_size, sizeof(char), sizeof(i_size), file ) \
-          != sizeof(i_size) ) goto error; \
-      if( i_size && i_size < 16384 ) { \
-          a = malloc( i_size ); \
-          if( fread( (void *)a, sizeof(char), i_size, file ) != (size_t)i_size ) \
-              goto error; \
-          if( a[i_size-1] ) { \
-              free( (void *)a ); a = 0; \
-              goto error; } \
-      } else a = 0; \
-    } while(0)
-
+{ \
+    a = NULL; \
+    if( ( fread( &i_size, sizeof(i_size), 1, file ) != 1 ) \
+     || ( i_size > 16384 ) ) \
+        goto error; \
+    if( i_size ) { \
+        char *psz = malloc( i_size ); \
+        if( fread( psz, i_size, 1, file ) != 1 ) { \
+            free( psz ); \
+            goto error; \
+        } \
+        if( psz[i_size-1] ) { \
+            free( psz ); \
+            goto error; \
+        } \
+        a = psz; \
+    } \
+}
 
     for( i = 0; i < i_cache; i++ )
     {
-        int16_t i_size;
+        uint16_t i_size;
         int i_submodules;
 
         pp_cache[i] = malloc( sizeof(module_cache_t) );
@@ -1793,10 +1811,11 @@ static void CacheLoad( vlc_object_t *p_this )
     return;
 }
 
+
 int CacheLoadConfig( module_t *p_module, FILE *file )
 {
-    int i, j, i_lines;
-    int16_t i_size;
+    uint32_t i_lines;
+    uint16_t i_size;
 
     /* Calculate the structure length */
     LOAD_IMMEDIATE( p_module->i_config_items );
@@ -1805,16 +1824,21 @@ int CacheLoadConfig( module_t *p_module, FILE *file )
     LOAD_IMMEDIATE( i_lines );
 
     /* Allocate memory */
-    p_module->p_config =
-        (module_config_t *)malloc( sizeof(module_config_t) * (i_lines + 1));
-    if( p_module->p_config == NULL )
+    if (i_lines)
     {
-        msg_Err( p_module, "config error: can't duplicate p_config" );
-        return VLC_ENOMEM;
+        p_module->p_config =
+            (module_config_t *)calloc( i_lines, sizeof(module_config_t) );
+        if( p_module->p_config == NULL )
+        {
+            p_module->confsize = 0;
+            msg_Err( p_module, "config error: can't duplicate p_config" );
+            return VLC_ENOMEM;
+        }
     }
+    p_module->confsize = i_lines;
 
     /* Do the duplication job */
-    for( i = 0; i < i_lines ; i++ )
+    for (size_t i = 0; i < i_lines; i++ )
     {
         LOAD_IMMEDIATE( p_module->p_config[i] );
 
@@ -1823,16 +1847,23 @@ int CacheLoadConfig( module_t *p_module, FILE *file )
         LOAD_STRING( p_module->p_config[i].psz_text );
         LOAD_STRING( p_module->p_config[i].psz_longtext );
         LOAD_STRING( p_module->p_config[i].psz_current );
-        LOAD_STRING( p_module->p_config[i].psz_value_orig );
-
-        p_module->p_config[i].psz_value =
-            p_module->p_config[i].psz_value_orig ?
-                strdup( p_module->p_config[i].psz_value_orig ) : 0;
-        p_module->p_config[i].i_value = p_module->p_config[i].i_value_orig;
-        p_module->p_config[i].f_value = p_module->p_config[i].f_value_orig;
-        p_module->p_config[i].i_value_saved = p_module->p_config[i].i_value;
-        p_module->p_config[i].f_value_saved = p_module->p_config[i].f_value;
-        p_module->p_config[i].psz_value_saved = 0;
+
+        if (IsConfigStringType (p_module->p_config[i].i_type))
+        {
+            LOAD_STRING (p_module->p_config[i].orig.psz);
+            p_module->p_config[i].value.psz =
+                    (p_module->p_config[i].orig.psz != NULL)
+                        ? strdup (p_module->p_config[i].orig.psz) : NULL;
+            p_module->p_config[i].saved.psz = NULL;
+        }
+        else
+        {
+            memcpy (&p_module->p_config[i].value, &p_module->p_config[i].orig,
+                    sizeof (p_module->p_config[i].value));
+            memcpy (&p_module->p_config[i].saved, &p_module->p_config[i].orig,
+                    sizeof (p_module->p_config[i].saved));
+        }
+
         p_module->p_config[i].b_dirty = VLC_FALSE;
 
         p_module->p_config[i].p_lock = &p_module->object_lock;
@@ -1841,6 +1872,7 @@ int CacheLoadConfig( module_t *p_module, FILE *file )
         {
             if( p_module->p_config[i].ppsz_list )
             {
+                int j;
                 p_module->p_config[i].ppsz_list =
                     malloc( (p_module->p_config[i].i_list+1) * sizeof(char *));
                 if( p_module->p_config[i].ppsz_list )
@@ -1852,6 +1884,7 @@ int CacheLoadConfig( module_t *p_module, FILE *file )
             }
             if( p_module->p_config[i].ppsz_list_text )
             {
+                int j;
                 p_module->p_config[i].ppsz_list_text =
                     malloc( (p_module->p_config[i].i_list+1) * sizeof(char *));
                 if( p_module->p_config[i].ppsz_list_text )
@@ -1867,7 +1900,7 @@ int CacheLoadConfig( module_t *p_module, FILE *file )
                     malloc( (p_module->p_config[i].i_list + 1) * sizeof(int) );
                 if( p_module->p_config[i].pi_list )
                 {
-                    for( j = 0; j < p_module->p_config[i].i_list; j++ )
+                    for (int j = 0; j < p_module->p_config[i].i_list; j++)
                         LOAD_IMMEDIATE( p_module->p_config[i].pi_list[j] );
                 }
             }
@@ -1880,7 +1913,7 @@ int CacheLoadConfig( module_t *p_module, FILE *file )
             p_module->p_config[i].ppsz_action_text =
                 malloc( p_module->p_config[i].i_action * sizeof(char *) );
 
-            for( j = 0; j < p_module->p_config[i].i_action; j++ )
+            for (int j = 0; j < p_module->p_config[i].i_action; j++)
             {
                 p_module->p_config[i].ppf_action[j] = 0;
                 LOAD_STRING( p_module->p_config[i].ppsz_action_text[j] );
@@ -1890,8 +1923,6 @@ int CacheLoadConfig( module_t *p_module, FILE *file )
         LOAD_IMMEDIATE( p_module->p_config[i].pf_callback );
     }
 
-    p_module->p_config[i].i_type = CONFIG_HINT_END;
-
     return VLC_SUCCESS;
 
  error:
@@ -1997,8 +2028,8 @@ static void CacheSave( vlc_object_t *p_this )
 
     for( i = 0; i < i_cache; i++ )
     {
-        int16_t i_size;
-        int32_t i_submodule;
+        uint16_t i_size;
+        uint32_t i_submodule;
 
         /* Save common info */
         SAVE_STRING( pp_cache[i]->psz_file );
@@ -2031,7 +2062,8 @@ static void CacheSave( vlc_object_t *p_this )
 
         i_submodule = pp_cache[i]->p_module->i_children;
         SAVE_IMMEDIATE( i_submodule );
-        for( i_submodule = 0; i_submodule < pp_cache[i]->p_module->i_children;
+        for( i_submodule = 0;
+             i_submodule < (unsigned)pp_cache[i]->p_module->i_children;
              i_submodule++ )
         {
             module_t *p_module =
@@ -2065,19 +2097,14 @@ static void CacheSave( vlc_object_t *p_this )
 
 void CacheSaveConfig( module_t *p_module, FILE *file )
 {
-    int i, j, i_lines = 0;
-    module_config_t *p_item;
-    int16_t i_size;
+    uint32_t i_lines = p_module->confsize;
+    uint16_t i_size;
 
     SAVE_IMMEDIATE( p_module->i_config_items );
     SAVE_IMMEDIATE( p_module->i_bool_items );
-
-    for( p_item = p_module->p_config; p_item->i_type != CONFIG_HINT_END;
-         p_item++ ) i_lines++;
-
     SAVE_IMMEDIATE( i_lines );
 
-    for( i = 0; i < i_lines ; i++ )
+    for (size_t i = 0; i < i_lines ; i++)
     {
         SAVE_IMMEDIATE( p_module->p_config[i] );
 
@@ -2086,29 +2113,30 @@ void CacheSaveConfig( module_t *p_module, FILE *file )
         SAVE_STRING( p_module->p_config[i].psz_text );
         SAVE_STRING( p_module->p_config[i].psz_longtext );
         SAVE_STRING( p_module->p_config[i].psz_current );
-        SAVE_STRING( p_module->p_config[i].psz_value_orig );
+        if (IsConfigStringType (p_module->p_config[i].i_type))
+            SAVE_STRING( p_module->p_config[i].orig.psz );
 
         if( p_module->p_config[i].i_list )
         {
             if( p_module->p_config[i].ppsz_list )
             {
-                for( j = 0; j < p_module->p_config[i].i_list; j++ )
+                for (int j = 0; j < p_module->p_config[i].i_list; j++)
                     SAVE_STRING( p_module->p_config[i].ppsz_list[j] );
             }
 
             if( p_module->p_config[i].ppsz_list_text )
             {
-                for( j = 0; j < p_module->p_config[i].i_list; j++ )
+                for (int j = 0; j < p_module->p_config[i].i_list; j++)
                     SAVE_STRING( p_module->p_config[i].ppsz_list_text[j] );
             }
             if( p_module->p_config[i].pi_list )
             {
-                for( j = 0; j < p_module->p_config[i].i_list; j++ )
+                for (int j = 0; j < p_module->p_config[i].i_list; j++)
                     SAVE_IMMEDIATE( p_module->p_config[i].pi_list[j] );
             }
         }
 
-        for( j = 0; j < p_module->p_config[i].i_action; j++ )
+        for (int j = 0; j < p_module->p_config[i].i_action; j++)
             SAVE_STRING( p_module->p_config[i].ppsz_action_text[j] );
 
         SAVE_IMMEDIATE( p_module->p_config[i].pf_callback );