X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fmessages.c;h=906b489cb6e66eeea7022ad140fd049dd4799b1c;hb=6bff1cc92a66ab1a73ba1fbf22523671bf5c8ce3;hp=eaafc8862bca05df0c68d077511c68ab83b96c26;hpb=53afb986b8d77e7151fe1375afae0b5a1b2ae7b9;p=vlc diff --git a/src/misc/messages.c b/src/misc/messages.c index eaafc8862b..906b489cb6 100644 --- a/src/misc/messages.c +++ b/src/misc/messages.c @@ -35,11 +35,11 @@ #include #include /* va_list for BSD */ - -#ifdef HAVE_FCNTL_H -# include /* O_CREAT, O_TRUNC, O_WRONLY, O_SYNC */ +#ifdef __APPLE__ +# include +#elif defined(HAVE_LOCALE_H) +# include #endif - #include /* errno */ #ifdef WIN32 @@ -82,49 +82,58 @@ static uintptr_t banks = 0; # define vlc_va_copy(dest,src) (dest)=(src) #endif -#define QUEUE priv->msg_bank static inline msg_bank_t *libvlc_bank (libvlc_int_t *inst) { - return &(libvlc_priv (inst))->msg_bank; + return (libvlc_priv (inst))->msg_bank; } /***************************************************************************** * Local prototypes *****************************************************************************/ -static void QueueMsg ( vlc_object_t *, int, const char *, - const char *, va_list ); static void PrintMsg ( vlc_object_t *, msg_item_t * ); static vlc_mutex_t msg_stack_lock = VLC_STATIC_MUTEX; +/** + * Store all data required by messages interfaces. + */ +struct msg_bank_t +{ + /** Message queue lock */ + vlc_rwlock_t lock; + + /* Subscribers */ + int i_sub; + msg_subscription_t **pp_sub; + + locale_t locale; /**< C locale for error messages */ + vlc_dictionary_t enabled_objects; ///< Enabled objects + bool all_objects_enabled; ///< Should we print all objects? +}; + /** * Initialize messages queues * This function initializes all message queues */ -void msg_Create (libvlc_int_t *p_libvlc) +msg_bank_t *msg_Create (void) { - libvlc_priv_t *priv = libvlc_priv (p_libvlc); - msg_bank_t *bank = libvlc_bank (p_libvlc); + msg_bank_t *bank = malloc (sizeof (*bank)); vlc_rwlock_init (&bank->lock); - vlc_dictionary_init( &priv->msg_enabled_objects, 0 ); - priv->msg_all_objects_enabled = true; - - QUEUE.i_sub = 0; - QUEUE.pp_sub = NULL; - -#ifdef UNDER_CE - QUEUE.logfile = - CreateFile( L"vlc-log.txt", GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, - CREATE_ALWAYS, 0, NULL ); - SetFilePointer( QUEUE.logfile, 0, NULL, FILE_END ); -#endif + vlc_dictionary_init (&bank->enabled_objects, 0); + bank->all_objects_enabled = true; + + bank->i_sub = 0; + bank->pp_sub = NULL; + + /* C locale to get error messages in English in the logs */ + bank->locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0); vlc_mutex_lock( &msg_stack_lock ); if( banks++ == 0 ) vlc_threadvar_create( &msg_context, cleanup_msg_context ); vlc_mutex_unlock( &msg_stack_lock ); + return bank; } /** @@ -133,26 +142,32 @@ void msg_Create (libvlc_int_t *p_libvlc) static void const * kObjectPrintingEnabled = &kObjectPrintingEnabled; static void const * kObjectPrintingDisabled = &kObjectPrintingDisabled; -void __msg_EnableObjectPrinting (vlc_object_t *p_this, char * psz_object) +#undef msg_EnableObjectPrinting +void msg_EnableObjectPrinting (vlc_object_t *obj, const char * psz_object) { - libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); - vlc_rwlock_wrlock( &QUEUE.lock ); + msg_bank_t *bank = libvlc_bank (obj->p_libvlc); + + vlc_rwlock_wrlock (&bank->lock); if( !strcmp(psz_object, "all") ) - priv->msg_all_objects_enabled = true; + bank->all_objects_enabled = true; else - vlc_dictionary_insert( &priv->msg_enabled_objects, psz_object, (void *)kObjectPrintingEnabled ); - vlc_rwlock_unlock( &QUEUE.lock ); + vlc_dictionary_insert (&bank->enabled_objects, psz_object, + (void *)kObjectPrintingEnabled); + vlc_rwlock_unlock (&bank->lock); } -void __msg_DisableObjectPrinting (vlc_object_t *p_this, char * psz_object) +#undef msg_DisableObjectPrinting +void msg_DisableObjectPrinting (vlc_object_t *obj, const char * psz_object) { - libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); - vlc_rwlock_wrlock( &QUEUE.lock ); + msg_bank_t *bank = libvlc_bank (obj->p_libvlc); + + vlc_rwlock_wrlock (&bank->lock); if( !strcmp(psz_object, "all") ) - priv->msg_all_objects_enabled = false; + bank->all_objects_enabled = false; else - vlc_dictionary_insert( &priv->msg_enabled_objects, psz_object, (void *)kObjectPrintingDisabled ); - vlc_rwlock_unlock( &QUEUE.lock ); + vlc_dictionary_insert (&bank->enabled_objects, psz_object, + (void *)kObjectPrintingDisabled); + vlc_rwlock_unlock (&bank->lock); } /** @@ -162,13 +177,10 @@ void __msg_DisableObjectPrinting (vlc_object_t *p_this, char * psz_object) * then frees all the allocated resources * No other messages interface functions should be called after this one. */ -void msg_Destroy (libvlc_int_t *p_libvlc) +void msg_Destroy (msg_bank_t *bank) { - libvlc_priv_t *priv = libvlc_priv (p_libvlc); - msg_bank_t *bank = libvlc_bank (p_libvlc); - - if( QUEUE.i_sub ) - msg_Err( p_libvlc, "stale interface subscribers (VLC might crash)" ); + if (unlikely(bank->i_sub != 0)) + fputs ("stale interface subscribers (LibVLC might crash)\n", stderr); vlc_mutex_lock( &msg_stack_lock ); assert(banks > 0); @@ -176,13 +188,13 @@ void msg_Destroy (libvlc_int_t *p_libvlc) vlc_threadvar_delete( &msg_context ); vlc_mutex_unlock( &msg_stack_lock ); -#ifdef UNDER_CE - CloseHandle( QUEUE.logfile ); -#endif + if (bank->locale != (locale_t)0) + freelocale (bank->locale); - vlc_dictionary_clear( &priv->msg_enabled_objects, NULL, NULL ); + vlc_dictionary_clear (&bank->enabled_objects, NULL, NULL); vlc_rwlock_destroy (&bank->lock); + free (bank); } struct msg_subscription_t @@ -236,26 +248,20 @@ void msg_Unsubscribe (msg_subscription_t *sub) } /***************************************************************************** - * __msg_*: print a message + * msg_*: print a message ***************************************************************************** * These functions queue a message for later printing. *****************************************************************************/ -void __msg_Generic( vlc_object_t *p_this, int i_type, const char *psz_module, +void msg_Generic( vlc_object_t *p_this, int i_type, const char *psz_module, const char *psz_format, ... ) { va_list args; va_start( args, psz_format ); - QueueMsg( p_this, i_type, psz_module, psz_format, args ); + msg_GenericVa (p_this, i_type, psz_module, psz_format, args); va_end( args ); } -void __msg_GenericVa( vlc_object_t *p_this, int i_type, const char *psz_module, - const char *psz_format, va_list args ) -{ - QueueMsg( p_this, i_type, psz_module, psz_format, args ); -} - /** * Destroys a message. */ @@ -269,6 +275,7 @@ static void msg_Free (gc_object_t *gc) free (msg); } +#undef msg_GenericVa /** * Add a message to a queue * @@ -277,21 +284,25 @@ static void msg_Free (gc_object_t *gc) * is full). If the message can't be converted to string in memory, it issues * a warning. */ -static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, - const char *psz_format, va_list _args ) +void msg_GenericVa (vlc_object_t *p_this, int i_type, + const char *psz_module, + const char *psz_format, va_list _args) { - assert (p_this); - libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); - int i_header_size; /* Size of the additionnal header */ + size_t i_header_size; /* Size of the additionnal header */ vlc_object_t *p_obj; char * psz_str = NULL; /* formatted message string */ char * psz_header = NULL; va_list args; + assert (p_this); + if( p_this->i_flags & OBJECT_FLAGS_QUIET || (p_this->i_flags & OBJECT_FLAGS_NODBG && i_type == VLC_MSG_DBG) ) return; + msg_bank_t *bank = libvlc_bank (p_this->p_libvlc); + locale_t locale = uselocale (bank->locale); + #ifndef __GLIBC__ /* Expand %m to strerror(errno) - only once */ char buf[strlen( psz_format ) + 2001], *ptr; @@ -377,11 +388,12 @@ static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, va_end( args ); fputs( "\n", stderr ); vlc_restorecancel (canc); + uselocale (locale); return; } + uselocale (locale); msg_item_t * p_item = malloc (sizeof (*p_item)); - if (p_item == NULL) return; /* Uho! */ @@ -401,13 +413,13 @@ static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, if( psz_header ) { psz_old = strdup( psz_header ); - psz_header = (char*)realloc( psz_header, i_header_size ); + psz_header = xrealloc( psz_header, i_header_size ); snprintf( psz_header, i_header_size , "[%s] %s", p_obj->psz_header, psz_old ); } else { - psz_header = (char *)malloc( i_header_size ); + psz_header = xmalloc( i_header_size ); snprintf( psz_header, i_header_size, "[%s]", p_obj->psz_header ); } @@ -426,7 +438,6 @@ static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, PrintMsg( p_this, p_item ); - msg_bank_t *bank = &QUEUE; vlc_rwlock_rdlock (&bank->lock); for (int i = 0; i < bank->i_sub; i++) { @@ -451,13 +462,11 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item ) # define WHITE COL(0) # define GRAY "\033[0m" -#ifdef UNDER_CE - int i_dummy; -#endif static const char ppsz_type[4][9] = { "", " error", " warning", " debug" }; static const char ppsz_color[4][8] = { WHITE, RED, YELLOW, GRAY }; const char *psz_object; libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); + msg_bank_t *bank = priv->msg_bank; int i_type = p_item->i_type; switch( i_type ) @@ -477,37 +486,24 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item ) } psz_object = p_item->psz_object_type; - void * val = vlc_dictionary_value_for_key( &priv->msg_enabled_objects, - p_item->psz_module ); + void * val = vlc_dictionary_value_for_key (&bank->enabled_objects, + p_item->psz_module); if( val == kObjectPrintingDisabled ) return; if( val == kObjectPrintingEnabled ) /* Allowed */; else { - val = vlc_dictionary_value_for_key( &priv->msg_enabled_objects, - psz_object ); + val = vlc_dictionary_value_for_key (&bank->enabled_objects, + psz_object); if( val == kObjectPrintingDisabled ) return; if( val == kObjectPrintingEnabled ) /* Allowed */; - else if( !priv->msg_all_objects_enabled ) + else if( !bank->all_objects_enabled ) return; } -#ifdef UNDER_CE -# define CE_WRITE(str) WriteFile( QUEUE.logfile, \ - str, strlen(str), &i_dummy, NULL ); - CE_WRITE( p_item->psz_module ); - CE_WRITE( " " ); - CE_WRITE( psz_object ); - CE_WRITE( ppsz_type[i_type] ); - CE_WRITE( ": " ); - CE_WRITE( p_item->psz_msg ); - CE_WRITE( "\r\n" ); - FlushFileBuffers( QUEUE.logfile ); - -#else int canc = vlc_savecancel (); /* Send the message to stderr */ utf8_fprintf( stderr, "[%s%p%s] %s%s%s %s%s: %s%s%s\n", @@ -522,11 +518,10 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item ) p_item->psz_msg, priv->b_color ? GRAY : "" ); -# if defined(WIN32) +#ifdef WIN32 fflush( stderr ); -# endif - vlc_restorecancel (canc); #endif + vlc_restorecancel (canc); } static msg_context_t* GetContext(void) @@ -543,14 +538,6 @@ static msg_context_t* GetContext(void) return p_ctx; } -void msg_StackDestroy (void *data) -{ - msg_context_t *p_ctx = data; - - free (p_ctx->psz_message); - free (p_ctx); -} - void msg_StackSet( int i_code, const char *psz_message, ... ) { va_list ap;