X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fmessages.c;h=3679ade29531680ddcc7b1fb2879a1968057307b;hb=c8d5ba620ec54ffb35792777dbdaf5cdb8493281;hp=5a9be21338073eb388f8bd5192b7701c67aa688f;hpb=166da1cec3c63eabd727429125689eb4d4be9b87;p=vlc diff --git a/src/misc/messages.c b/src/misc/messages.c index 5a9be21338..3679ade295 100644 --- a/src/misc/messages.c +++ b/src/misc/messages.c @@ -3,25 +3,25 @@ * 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 + * Copyright (C) 1998-2005 VLC authors and VideoLAN * $Id$ * * Authors: Vincent Seguin * Samuel Hocevar * - * 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 + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser 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. + * You should have received a copy of the GNU Lesser 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. *****************************************************************************/ /***************************************************************************** @@ -32,455 +32,454 @@ # include "config.h" #endif -#include - +#include #include /* va_list for BSD */ -#ifdef __APPLE__ -# include -#elif defined(HAVE_LOCALE_H) -# include -#endif -#include /* errno */ - -#ifdef WIN32 -# include /* 'net_strerror' and 'WSAGetLastError' */ -#endif - -#ifdef HAVE_UNISTD_H -# include /* close(), write() */ -#endif - +#include #include +#include +#include #include +#include #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) +#ifdef __ANDROID__ +#include #endif -static inline msg_bank_t *libvlc_bank (libvlc_int_t *inst) +struct vlc_logger_t { - return (libvlc_priv (inst))->msg_bank; -} + VLC_COMMON_MEMBERS + vlc_rwlock_t lock; + vlc_log_cb log; + void *sys; + module_t *module; +}; -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static void PrintMsg ( vlc_object_t *, const msg_item_t * ); +static void vlc_vaLogCallback(libvlc_int_t *vlc, int type, + const vlc_log_t *item, const char *format, + va_list ap) +{ + vlc_logger_t *logger = libvlc_priv(vlc)->logger; -/** - * Store all data required by messages interfaces. - */ -struct msg_bank_t + assert(logger != NULL); + vlc_rwlock_rdlock(&logger->lock); + logger->log(logger->sys, type, item, format, ap); + vlc_rwlock_unlock(&logger->lock); +} + +static void vlc_LogCallback(libvlc_int_t *vlc, int type, const vlc_log_t *item, + const char *format, ...) { - /** Message queue lock */ - vlc_rwlock_t lock; + va_list ap; - /* Subscribers */ - int i_sub; - msg_subscription_t **pp_sub; + va_start(ap, format); + vlc_vaLogCallback(vlc, type, item, format, ap); + va_end(ap); +} - locale_t locale; /**< C locale for error messages */ - vlc_dictionary_t enabled_objects; ///< Enabled objects - bool all_objects_enabled; ///< Should we print all objects? -}; +#ifdef _WIN32 +static void Win32DebugOutputMsg (void *, int , const vlc_log_t *, + const char *, va_list); +#endif /** - * Initialize messages queues - * This function initializes all message queues + * Emit a log message. This function is the variable argument list equivalent + * to vlc_Log(). */ -msg_bank_t *msg_Create (void) +void vlc_vaLog (vlc_object_t *obj, int type, const char *module, + const char *file, unsigned line, const char *func, + const char *format, va_list args) { - msg_bank_t *bank = malloc (sizeof (*bank)); + if (obj != NULL && obj->i_flags & OBJECT_FLAGS_QUIET) + return; + + /* Get basename from the module filename */ + char *p = strrchr(module, '/'); + if (p != NULL) + module = p; + p = strchr(module, '.'); + + size_t modlen = (p != NULL) ? (p - module) : 0; + char modulebuf[modlen + 1]; + if (p != NULL) + { + memcpy(modulebuf, module, modlen); + modulebuf[modlen] = '\0'; + module = modulebuf; + } + + /* Fill message information fields */ + vlc_log_t msg; + + msg.i_object_id = (uintptr_t)obj; + msg.psz_object_type = (obj != NULL) ? obj->psz_object_type : "generic"; + msg.psz_module = module; + msg.psz_header = NULL; + msg.file = file; + msg.line = line; + msg.func = func; - vlc_rwlock_init (&bank->lock); - vlc_dictionary_init (&bank->enabled_objects, 0); - bank->all_objects_enabled = true; + for (vlc_object_t *o = obj; o != NULL; o = o->p_parent) + if (o->psz_header != NULL) + { + msg.psz_header = o->psz_header; + break; + } - bank->i_sub = 0; - bank->pp_sub = NULL; +#ifdef _WIN32 + va_list ap; - /* C locale to get error messages in English in the logs */ - bank->locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0); - return bank; + va_copy (ap, args); + Win32DebugOutputMsg (NULL, type, &msg, format, ap); + va_end (ap); +#endif + + /* Pass message to the callback */ + if (obj != NULL) + vlc_vaLogCallback(obj->p_libvlc, type, &msg, format, args); } /** - * Object Printing selection + * Emit a log message. + * \param obj VLC object emitting the message or NULL + * \param type VLC_MSG_* message type (info, error, warning or debug) + * \param module name of module from which the message come + * (normally MODULE_STRING) + * \param file source module file name (normally __FILE__) or NULL + * \param line function call source line number (normally __LINE__) or 0 + * \param func calling function name (normally __func__) or NULL + * \param format printf-like message format */ -static void const * kObjectPrintingEnabled = &kObjectPrintingEnabled; -static void const * kObjectPrintingDisabled = &kObjectPrintingDisabled; - - -#undef msg_EnableObjectPrinting -void msg_EnableObjectPrinting (vlc_object_t *obj, const char * psz_object) +void vlc_Log(vlc_object_t *obj, int type, const char *module, + const char *file, unsigned line, const char *func, + const char *format, ... ) { - msg_bank_t *bank = libvlc_bank (obj->p_libvlc); + va_list ap; - vlc_rwlock_wrlock (&bank->lock); - if( !strcmp(psz_object, "all") ) - bank->all_objects_enabled = true; - else - vlc_dictionary_insert (&bank->enabled_objects, psz_object, - (void *)kObjectPrintingEnabled); - vlc_rwlock_unlock (&bank->lock); + va_start(ap, format); + vlc_vaLog(obj, type, module, file, line, func, format, ap); + va_end(ap); } -#undef msg_DisableObjectPrinting -void msg_DisableObjectPrinting (vlc_object_t *obj, const char * psz_object) +#ifdef _WIN32 +static const char msg_type[4][9] = { "", " error", " warning", " debug" }; + +static void Win32DebugOutputMsg (void* d, int type, const vlc_log_t *p_item, + const char *format, va_list dol) { - msg_bank_t *bank = libvlc_bank (obj->p_libvlc); + VLC_UNUSED(p_item); - vlc_rwlock_wrlock (&bank->lock); - if( !strcmp(psz_object, "all") ) - bank->all_objects_enabled = false; - else - vlc_dictionary_insert (&bank->enabled_objects, psz_object, - (void *)kObjectPrintingDisabled); - vlc_rwlock_unlock (&bank->lock); + const signed char *pverbose = d; + if (pverbose && (*pverbose < 0 || *pverbose < (type - VLC_MSG_ERR))) + return; + + va_list dol2; + va_copy (dol2, dol); + int msg_len = vsnprintf(NULL, 0, format, dol2); + va_end (dol2); + + if(msg_len <= 0) + return; + + char *msg = malloc(msg_len + 1 + 1); + if (!msg) + return; + + msg_len = vsnprintf(msg, msg_len+1, format, dol); + if (msg_len > 0){ + if(msg[msg_len-1] != '\n'){ + msg[msg_len] = '\n'; + msg[msg_len + 1] = '\0'; + } + char* psz_msg = NULL; + if(asprintf(&psz_msg, "%s %s%s: %s", p_item->psz_module, + p_item->psz_object_type, msg_type[type], msg) > 0) { + wchar_t* wmsg = ToWide(psz_msg); + OutputDebugStringW(wmsg); + free(wmsg); + free(psz_msg); + } + } + free(msg); } +#endif -/** - * Destroy the message queues - * - * This functions prints all messages remaining in the queues, - * then frees all the allocated resources - * No other messages interface functions should be called after this one. - */ -void msg_Destroy (msg_bank_t *bank) +#ifdef __ANDROID__ +static void AndroidPrintMsg (void *d, int type, const vlc_log_t *p_item, + const char *format, va_list ap) { - if (unlikely(bank->i_sub != 0)) - fputs ("stale interface subscribers (LibVLC might crash)\n", stderr); + int verbose = (intptr_t)d; + int prio; - if (bank->locale != (locale_t)0) - freelocale (bank->locale); + if (verbose < 0 || verbose < (type - VLC_MSG_ERR)) + return; - vlc_dictionary_clear (&bank->enabled_objects, NULL, NULL); + int canc = vlc_savecancel (); - vlc_rwlock_destroy (&bank->lock); - free (bank); + char *format2; + if (asprintf (&format2, "[%0*"PRIxPTR"] %s %s: %s", + ptr_width, p_item->i_object_id, p_item->psz_module, + p_item->psz_object_type, format) < 0) + return; + switch (type) { + case VLC_MSG_INFO: + prio = ANDROID_LOG_INFO; + break; + case VLC_MSG_ERR: + prio = ANDROID_LOG_ERROR; + break; + case VLC_MSG_WARN: + prio = ANDROID_LOG_WARN; + break; + default: + case VLC_MSG_DBG: + prio = ANDROID_LOG_DEBUG; + } + __android_log_vprint (prio, "VLC", format2, ap); + free (format2); + vlc_restorecancel (canc); } +#endif -struct msg_subscription_t +typedef struct vlc_log_early_t { - libvlc_int_t *instance; - msg_callback_t func; - msg_cb_data_t *opaque; - int verbosity; -}; + struct vlc_log_early_t *next; + int type; + vlc_log_t meta; + char *msg; +} vlc_log_early_t; -/** - * Subscribe to the message queue. - * Whenever a message is emitted, a callback will be called. - * Callback invocation are serialized within a subscription. - * - * @param instance LibVLC instance to get messages from - * @param cb callback function - * @param opaque data for the callback function - * @return a subscription pointer, or NULL in case of failure - */ -msg_subscription_t *msg_Subscribe (libvlc_int_t *instance, msg_callback_t cb, - msg_cb_data_t *opaque) +typedef struct { - msg_subscription_t *sub = malloc (sizeof (*sub)); - if (sub == NULL) - return NULL; + vlc_mutex_t lock; + vlc_log_early_t *head; + vlc_log_early_t **tailp; +} vlc_logger_early_t; - sub->instance = instance; - sub->func = cb; - sub->opaque = opaque; - sub->verbosity = 2; /* by default, give all the messages */ +static void vlc_vaLogEarly(void *d, int type, const vlc_log_t *item, + const char *format, va_list ap) +{ + vlc_logger_early_t *sys = d; - msg_bank_t *bank = libvlc_bank (instance); - vlc_rwlock_wrlock (&bank->lock); - TAB_APPEND (bank->i_sub, bank->pp_sub, sub); - vlc_rwlock_unlock (&bank->lock); + vlc_log_early_t *log = malloc(sizeof (*log)); + if (unlikely(log == NULL)) + return; - return sub; + log->next = NULL; + log->type = type; + log->meta.i_object_id = item->i_object_id; + /* NOTE: Object types MUST be static constant - no need to copy them. */ + log->meta.psz_object_type = item->psz_object_type; + log->meta.psz_module = item->psz_module; /* Ditto. */ + log->meta.psz_header = item->psz_header ? strdup(item->psz_header) : NULL; + log->meta.file = item->file; + log->meta.line = item->line; + log->meta.func = item->func; + + int canc = vlc_savecancel(); /* XXX: needed for vasprintf() ? */ + if (vasprintf(&log->msg, format, ap) == -1) + log->msg = NULL; + vlc_restorecancel(canc); + + vlc_mutex_lock(&sys->lock); + assert(sys->tailp != NULL); + assert(*(sys->tailp) == NULL); + *(sys->tailp) = log; + sys->tailp = &log->next; + vlc_mutex_unlock(&sys->lock); } -/** - * Unsubscribe from the message queue. - * This function waits for the message callback to return if needed. - */ -void msg_Unsubscribe (msg_subscription_t *sub) +static int vlc_LogEarlyOpen(vlc_logger_t *logger) { - msg_bank_t *bank = libvlc_bank (sub->instance); + vlc_logger_early_t *sys = malloc(sizeof (*sys)); + + if (unlikely(sys == NULL)) + return -1; - vlc_rwlock_wrlock (&bank->lock); - TAB_REMOVE (bank->i_sub, bank->pp_sub, sub); - vlc_rwlock_unlock (&bank->lock); - free (sub); + vlc_mutex_init(&sys->lock); + sys->head = NULL; + sys->tailp = &sys->head; + + logger->log = vlc_vaLogEarly; + logger->sys = sys; + return 0; } -void msg_SubscriptionSetVerbosity( msg_subscription_t *sub, const int i_verbosity ) +static void vlc_LogEarlyClose(vlc_logger_t *logger, void *d) { - if( i_verbosity < 0 || i_verbosity > 2 ) return; + libvlc_int_t *vlc = logger->p_libvlc; + vlc_logger_early_t *sys = d; - msg_bank_t *bank = libvlc_bank ( sub->instance ); + /* Drain early log messages */ + for (vlc_log_early_t *log = sys->head, *next; log != NULL; log = next) + { + vlc_LogCallback(vlc, log->type, &log->meta, "%s", + (log->msg != NULL) ? log->msg : "message lost"); + free(log->msg); + next = log->next; + free(log); + } - vlc_rwlock_wrlock (&bank->lock); + vlc_mutex_destroy(&sys->lock); + free(sys); +} - sub->verbosity = i_verbosity; +static void vlc_vaLogDiscard(void *d, int type, const vlc_log_t *item, + const char *format, va_list ap) +{ + (void) d; (void) type; (void) item; (void) format; (void) ap; +} + +static int vlc_logger_load(void *func, va_list ap) +{ + vlc_log_cb (*activate)(vlc_object_t *, void **) = func; + vlc_logger_t *logger = va_arg(ap, vlc_logger_t *); + vlc_log_cb *cb = va_arg(ap, vlc_log_cb *); + void **sys = va_arg(ap, void **); - vlc_rwlock_unlock (&bank->lock); + *cb = activate(VLC_OBJECT(logger), sys); + return (*cb != NULL) ? VLC_SUCCESS : VLC_EGENERIC; } -/***************************************************************************** - * 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, ... ) + +static void vlc_logger_unload(void *func, va_list ap) { - va_list args; + void (*deactivate)(vlc_logger_t *) = func; + void *sys = va_arg(ap, void *); - va_start( args, psz_format ); - msg_GenericVa (p_this, i_type, psz_module, psz_format, args); - va_end( args ); + deactivate(sys); } -#undef msg_GenericVa /** - * Add a message to a queue + * Performs preinitialization of the messages logging subsystem. * - * 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. + * Early log messages will be stored in memory until the subsystem is fully + * initialized with vlc_LogInit(). This enables logging before the + * configuration and modules bank are ready. + * + * \return 0 on success, -1 on error. */ -void msg_GenericVa (vlc_object_t *p_this, int i_type, - const char *psz_module, - const char *psz_format, va_list _args) +int vlc_LogPreinit(libvlc_int_t *vlc) { - char * psz_str = NULL; /* formatted message string */ - va_list args; + vlc_logger_t *logger = vlc_custom_create(vlc, sizeof (*logger), "logger"); - assert (p_this); + libvlc_priv(vlc)->logger = logger; - if( p_this->i_flags & OBJECT_FLAGS_QUIET || - (p_this->i_flags & OBJECT_FLAGS_NODBG && i_type == VLC_MSG_DBG) ) - return; + if (unlikely(logger == NULL)) + return -1; - msg_bank_t *bank = libvlc_bank (p_this->p_libvlc); - locale_t locale = uselocale (bank->locale); + vlc_rwlock_init(&logger->lock); -#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( ;; ) + if (vlc_LogEarlyOpen(logger)) { - ptr = strchr( ptr, '%' ); - if( ptr == NULL ) - break; + logger->log = vlc_vaLogDiscard; + return -1; + } - if( ptr[1] == 'm' ) - { - char errbuf[2001]; - size_t errlen; + /* Announce who we are */ + msg_Dbg(vlc, "VLC media player - %s", VERSION_MESSAGE); + msg_Dbg(vlc, "%s", COPYRIGHT_MESSAGE); + msg_Dbg(vlc, "revision %s", psz_vlc_changeset); + msg_Dbg(vlc, "configured with %s", CONFIGURE_LINE); + return 0; +} -#ifndef WIN32 - strerror_r( errno, errbuf, 1001 ); +/** + * Initializes the messages logging subsystem and drain the early messages to + * the configured log. + * + * \return 0 on success, -1 on error. + */ +int vlc_LogInit(libvlc_int_t *vlc) +{ + vlc_logger_t *logger = libvlc_priv(vlc)->logger; + if (unlikely(logger == NULL)) + return -1; + + vlc_log_cb cb; + void *sys, *early_sys = NULL; + + /* TODO: module configuration item */ + module_t *module = vlc_module_load(logger, "logger", NULL, false, + vlc_logger_load, logger, &cb, &sys); + if (module == NULL) +#ifdef __ANDROID__ + cb = AndroidPrintMsg, sys = NULL; #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 ); + cb = vlc_vaLogDiscard; #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 + vlc_rwlock_wrlock(&logger->lock); + if (logger->log == vlc_vaLogEarly) + early_sys = logger->sys; - /* Convert message to string */ - vlc_va_copy( args, _args ); - if( vasprintf( &psz_str, psz_format, args ) == -1 ) - psz_str = NULL; - va_end( args ); + logger->log = cb; + logger->sys = sys; + assert(logger->module == NULL); /* Only one call to vlc_LogInit()! */ + logger->module = module; + vlc_rwlock_unlock(&logger->lock); - if( psz_str == NULL ) - { - int canc = vlc_savecancel (); /* Do not print half of a message... */ -#ifdef __GLIBC__ - fprintf( stderr, "main warning: can't store message (%m): " ); -#else - char psz_err[1001]; -#ifndef WIN32 - /* we're not using GLIBC, so we are sure that the error description - * will be stored in the buffer we provide to strerror_r() */ - strerror_r( errno, psz_err, 1001 ); -#else - strncpy( psz_err, strerror( errno ), 1001 ); -#endif - psz_err[1000] = '\0'; - fprintf( stderr, "main warning: can't store message (%s): ", psz_err ); -#endif - vlc_va_copy( args, _args ); - /* We should use utf8_vfprintf - but it calls malloc()... */ - vfprintf( stderr, psz_format, args ); - va_end( args ); - fputs( "\n", stderr ); - vlc_restorecancel (canc); - uselocale (locale); + if (early_sys != NULL) + vlc_LogEarlyClose(logger, early_sys); + + return 0; +} + +/** + * Sets the message logging callback. + * \param cb message callback, or NULL to clear + * \param data data pointer for the message callback + */ +void vlc_LogSet(libvlc_int_t *vlc, vlc_log_cb cb, void *opaque) +{ + vlc_logger_t *logger = libvlc_priv(vlc)->logger; + + if (unlikely(logger == NULL)) return; - } - uselocale (locale); - /* Fill message information fields */ - msg_item_t msg; + module_t *module; + void *sys; - msg.i_type = i_type; - msg.i_object_id = (uintptr_t)p_this; - msg.psz_object_type = p_this->psz_object_type; - msg.psz_module = psz_module; - msg.psz_msg = psz_str; - msg.psz_header = NULL; + if (cb == NULL) + cb = vlc_vaLogDiscard; - for (vlc_object_t *o = p_this; o != NULL; o = o->p_parent) - if (o->psz_header != NULL) - { - msg.psz_header = o->psz_header; - break; - } + vlc_rwlock_wrlock(&logger->lock); + sys = logger->sys; + module = logger->module; - PrintMsg( p_this, &msg ); + logger->log = cb; + logger->sys = opaque; + logger->module = NULL; + vlc_rwlock_unlock(&logger->lock); - vlc_rwlock_rdlock (&bank->lock); - for (int i = 0; i < bank->i_sub; i++) - { - msg_subscription_t *sub = bank->pp_sub[i]; - libvlc_priv_t *priv = libvlc_priv( sub->instance ); - msg_bank_t *bank = priv->msg_bank; - void *val = vlc_dictionary_value_for_key( &bank->enabled_objects, - msg.psz_module ); - if( val == kObjectPrintingDisabled ) continue; - if( val != kObjectPrintingEnabled ) /*if not allowed */ - { - val = vlc_dictionary_value_for_key( &bank->enabled_objects, - msg.psz_object_type ); - if( val == kObjectPrintingDisabled ) continue; - if( val == kObjectPrintingEnabled ); /* Allowed */ - else if( !bank->all_objects_enabled ) continue; - } - switch( msg.i_type ) - { - case VLC_MSG_INFO: - case VLC_MSG_ERR: - if( sub->verbosity < 0 ) continue; - break; - case VLC_MSG_WARN: - if( sub->verbosity < 1 ) continue; - break; - case VLC_MSG_DBG: - if( sub->verbosity < 2 ) continue; - break; - } + if (module != NULL) + vlc_module_unload(module, vlc_logger_unload, sys); - sub->func (sub->opaque, &msg, 0); - } - vlc_rwlock_unlock (&bank->lock); - free (msg.psz_msg); + /* Announce who we are */ + msg_Dbg (vlc, "VLC media player - %s", VERSION_MESSAGE); + msg_Dbg (vlc, "%s", COPYRIGHT_MESSAGE); + msg_Dbg (vlc, "revision %s", psz_vlc_changeset); + msg_Dbg (vlc, "configured with %s", CONFIGURE_LINE); } -/***************************************************************************** - * PrintMsg: output a standard message item to stderr - ***************************************************************************** - * Print a message to stderr, with colour formatting if needed. - *****************************************************************************/ -static void PrintMsg ( vlc_object_t *p_this, const msg_item_t *p_item ) +void vlc_LogDeinit(libvlc_int_t *vlc) { -# define COL(x,y) "\033[" #x ";" #y "m" -# define RED COL(31,1) -# define GREEN COL(32,1) -# define YELLOW COL(0,33) -# define WHITE COL(0,1) -# define GRAY "\033[0m" - static const char msgtype[4][9] = { "", " error", " warning", " debug" }; - static const char msgcolor[4][8] = { WHITE, RED, YELLOW, GRAY }; - - libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); - int type = p_item->i_type; - - if (priv->i_verbose < 0 || priv->i_verbose < (type - VLC_MSG_ERR)) - return; + vlc_logger_t *logger = libvlc_priv(vlc)->logger; - const char *objtype = p_item->psz_object_type; - msg_bank_t *bank = priv->msg_bank; - void * val = vlc_dictionary_value_for_key (&bank->enabled_objects, - p_item->psz_module); - if( val == kObjectPrintingDisabled ) + if (unlikely(logger == NULL)) return; - if( val == kObjectPrintingEnabled ) - /* Allowed */; + + if (logger->module != NULL) + vlc_module_unload(logger->module, vlc_logger_unload, logger->sys); else + /* Flush early log messages (corner case: no call to vlc_LogInit()) */ + if (logger->log == vlc_vaLogEarly) { - val = vlc_dictionary_value_for_key (&bank->enabled_objects, - objtype); - if( val == kObjectPrintingDisabled ) - return; - if( val == kObjectPrintingEnabled ) - /* Allowed */; - else if( !bank->all_objects_enabled ) - return; + logger->log = vlc_vaLogDiscard; + vlc_LogEarlyClose(logger, logger->sys); } - /* Send the message to stderr */ - FILE *stream = stderr; - int canc = vlc_savecancel (); - - flockfile (stream); - fprintf (stream, priv->b_color ? "["GREEN"%p"GRAY"] " : "[%p] ", - (void *)p_item->i_object_id); - if (p_item->psz_header != NULL) - utf8_fprintf (stream, "[%s] ", p_item->psz_header); - utf8_fprintf (stream, "%s %s%s: ", p_item->psz_module, objtype, - msgtype[type]); - if (priv->b_color) - fputs (msgcolor[type], stream); - fputs (p_item->psz_msg, stream); - if (priv->b_color) - fputs (GRAY, stream); - putc_unlocked ('\n', stream); -#if defined (WIN32) || defined (__OS2__) - fflush (stream); -#endif - funlockfile (stream); - vlc_restorecancel (canc); + vlc_rwlock_destroy(&logger->lock); + vlc_object_release(logger); + libvlc_priv(vlc)->logger = NULL; }