📄 messages.c
字号:
/***************************************************************************** * messages.c: messages interface * This library provides an interface to the message queue to be used by other * modules, especially intf modules. See vlc_config.h for output configuration. ***************************************************************************** * Copyright (C) 1998-2005 the VideoLAN team * $Id: be832c65c87fba5ec3ea54be0cd2c8e3768f2059 $ * * Authors: Vincent Seguin <seguin@via.ecp.fr> * Samuel Hocevar <sam@zoy.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <stdarg.h> /* va_list for BSD */#ifdef HAVE_FCNTL_H# include <fcntl.h> /* O_CREAT, O_TRUNC, O_WRONLY, O_SYNC */#endif#include <errno.h> /* errno */#ifdef WIN32# include <vlc_network.h> /* 'net_strerror' and 'WSAGetLastError' */#endif#ifdef HAVE_UNISTD_H# include <unistd.h> /* close(), write() */#endif#include <assert.h>#include <vlc_charset.h>#include "../libvlc.h"/***************************************************************************** * Local macros *****************************************************************************/#if defined(HAVE_VA_COPY)# define vlc_va_copy(dest,src) va_copy(dest,src)#elif defined(HAVE___VA_COPY)# define vlc_va_copy(dest,src) __va_copy(dest,src)#else# define vlc_va_copy(dest,src) (dest)=(src)#endif#define QUEUE priv->msg_bank.queue#define LOCK_BANK vlc_mutex_lock( &priv->msg_bank.lock );#define UNLOCK_BANK vlc_mutex_unlock( &priv->msg_bank.lock );/***************************************************************************** * Local prototypes *****************************************************************************/static void QueueMsg ( vlc_object_t *, int, const char *, const char *, va_list );static void FlushMsg ( msg_queue_t * );static void PrintMsg ( vlc_object_t *, msg_item_t * );/** * Initialize messages queues * This function initializes all message queues */void msg_Create (libvlc_int_t *p_libvlc){ libvlc_priv_t *priv = libvlc_priv (p_libvlc); vlc_mutex_init( &priv->msg_bank.lock ); vlc_mutex_init( &QUEUE.lock ); QUEUE.b_overflow = false; QUEUE.i_start = 0; QUEUE.i_stop = 0; QUEUE.i_sub = 0; QUEUE.pp_sub = 0;#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}/** * Flush all message queues */void msg_Flush (libvlc_int_t *p_libvlc){ libvlc_priv_t *priv = libvlc_priv (p_libvlc); vlc_mutex_lock( &QUEUE.lock ); FlushMsg( &QUEUE ); vlc_mutex_unlock( &QUEUE.lock );}/** * Destroy the message queues * * This functions prints all messages remaining in the queues, * then frees all the allocated ressources * No other messages interface functions should be called after this one. */void msg_Destroy (libvlc_int_t *p_libvlc){ libvlc_priv_t *priv = libvlc_priv (p_libvlc); if( QUEUE.i_sub ) msg_Err( p_libvlc, "stale interface subscribers" ); FlushMsg( &QUEUE );#ifdef UNDER_CE CloseHandle( QUEUE.logfile );#endif /* Destroy lock */ vlc_mutex_destroy( &QUEUE.lock ); vlc_mutex_destroy( &priv->msg_bank.lock);}/** * Subscribe to a message queue. */msg_subscription_t *__msg_Subscribe( vlc_object_t *p_this ){ libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); msg_subscription_t *p_sub = malloc( sizeof( msg_subscription_t ) ); if (p_sub == NULL) return NULL; LOCK_BANK; vlc_mutex_lock( &QUEUE.lock ); TAB_APPEND( QUEUE.i_sub, QUEUE.pp_sub, p_sub ); p_sub->i_start = QUEUE.i_start; p_sub->pi_stop = &QUEUE.i_stop; p_sub->p_msg = QUEUE.msg; p_sub->p_lock = &QUEUE.lock; vlc_mutex_unlock( &QUEUE.lock ); UNLOCK_BANK; return p_sub;}/** * Unsubscribe from a message queue. */void __msg_Unsubscribe( vlc_object_t *p_this, msg_subscription_t *p_sub ){ libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); LOCK_BANK; vlc_mutex_lock( &QUEUE.lock ); for( int j = 0 ; j< QUEUE.i_sub ; j++ ) { if( QUEUE.pp_sub[j] == p_sub ) { REMOVE_ELEM( QUEUE.pp_sub, QUEUE.i_sub, j ); free( p_sub ); } } vlc_mutex_unlock( &QUEUE.lock ); UNLOCK_BANK;}/***************************************************************************** * __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, const char *psz_format, ... ){ va_list args; va_start( args, psz_format ); QueueMsg( 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 );}/* Generic functions used when variadic macros are not available. */#define DECLARE_MSG_FN( FN_NAME, FN_TYPE ) \ void FN_NAME( vlc_object_t *p_this, const char *psz_format, ... ) \ { \ va_list args; \ va_start( args, psz_format ); \ QueueMsg( p_this, FN_TYPE, "unknown", psz_format, args ); \ va_end( args ); \ } \ struct _/** * Output an informational message. * \note Do not use this for debug messages * \see input_AddInfo */DECLARE_MSG_FN( __msg_Info, VLC_MSG_INFO );/** * Output an error message. */DECLARE_MSG_FN( __msg_Err, VLC_MSG_ERR );/** * Output a waring message */DECLARE_MSG_FN( __msg_Warn, VLC_MSG_WARN );/** * Output a debug message */DECLARE_MSG_FN( __msg_Dbg, VLC_MSG_DBG );/** * Add a message to a queue * * This function provides basic functionnalities to other msg_* functions. * It adds a message to a queue (after having printed all stored messages if it * 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 ){ assert (p_this); libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); int 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; msg_item_t * p_item = NULL; /* pointer to message */ msg_item_t item; /* message in case of a full queue */ msg_queue_t *p_queue;#if !defined(HAVE_VASPRINTF) || defined(__APPLE__) || defined(SYS_BEOS) int i_size = strlen(psz_format) + INTF_MAX_MSG_SIZE;#endif if( p_this->i_flags & OBJECT_FLAGS_QUIET || (p_this->i_flags & OBJECT_FLAGS_NODBG && i_type == VLC_MSG_DBG) ) return;#ifndef __GLIBC__ /* Expand %m to strerror(errno) - only once */ char buf[strlen( psz_format ) + 2001], *ptr; strcpy( buf, psz_format ); ptr = (char*)buf; psz_format = (const char*) buf; for( ;; ) { ptr = strchr( ptr, '%' ); if( ptr == NULL ) break; if( ptr[1] == 'm' ) { char errbuf[2001]; size_t errlen;#ifndef WIN32 strerror_r( errno, errbuf, 1001 );#else int sockerr = WSAGetLastError( ); if( sockerr ) { strncpy( errbuf, net_strerror( sockerr ), 1001 ); WSASetLastError( sockerr ); } if ((sockerr == 0) || (strcmp ("Unknown network stack error", errbuf) == 0)) strncpy( errbuf, strerror( errno ), 1001 );#endif errbuf[1000] = 0; /* Escape '%' from the error string */ for( char *percent = strchr( errbuf, '%' ); percent != NULL; percent = strchr( percent + 2, '%' ) ) { memmove( percent + 1, percent, strlen( percent ) + 1 ); } errlen = strlen( errbuf ); memmove( ptr + errlen, ptr + 2, strlen( ptr + 2 ) + 1 ); memcpy( ptr, errbuf, errlen ); break; /* Only once, so we don't overflow */ } /* Looks for conversion specifier... */ do ptr++; while( *ptr && ( strchr( "diouxXeEfFgGaAcspn%", *ptr ) == NULL ) ); if( *ptr ) ptr++; /* ...and skip it */ }#endif /* Convert message to string */#if defined(HAVE_VASPRINTF) && !defined(__APPLE__) && !defined( SYS_BEOS ) vlc_va_copy( args, _args ); if( vasprintf( &psz_str, psz_format, args ) == -1 ) psz_str = NULL; va_end( args );#else psz_str = (char*) malloc( i_size );#endif if( psz_str == NULL ) {#ifdef __GLIBC__ fprintf( stderr, "main warning: can't store message (%m): " );#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -