* interface, such as message output. See config.h for output configuration.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
+ * $Id: intf_msg.c,v 1.36 2001/06/02 01:09:03 sam Exp $
*
- * Authors:
+ * Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* 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
#include <stdarg.h> /* va_list for BSD */
#include <stdlib.h> /* malloc() */
#include <string.h> /* strerror() */
+
+#ifdef HAVE_UNISTD_H
#include <unistd.h> /* close(), write() */
+#endif
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
-#include "plugins.h"
+
#include "intf_msg.h"
#include "interface.h"
-#include "intf_console.h"
#include "main.h"
+#ifdef WIN32
+#ifndef snprintf
+#define snprintf _snprintf /* snprintf not defined in mingw32 (bug?) */
+#endif
+#endif
+
/*****************************************************************************
* intf_msg_item_t
*****************************************************************************
* Store a single message. Messages have a maximal size of INTF_MSG_MSGSIZE.
- * If DEBUG is defined, messages have a date field and debug messages are
+ * If TRACE is defined, messages have a date field and debug messages are
* printed with a date to allow more precise profiling.
*****************************************************************************/
typedef struct
int i_type; /* message type, see below */
char * psz_msg; /* the message itself */
-#ifdef DEBUG
- /* Debugging informations - in DEBUG mode, debug messages have calling
+#ifdef TRACE
+ /* Debugging informations - in TRACE mode, debug messages have calling
* location informations printed */
mtime_t date; /* date of the message */
char * psz_file; /* file in which the function was called */
/* Message types */
#define INTF_MSG_STD 0 /* standard message */
#define INTF_MSG_ERR 1 /* error message */
-#define INTF_MSG_INTF 2 /* interface message */
#define INTF_MSG_DBG 3 /* debug message */
#define INTF_MSG_WARN 4 /* warning message*/
intf_msg_item_t msg[INTF_MSG_QSIZE]; /* message queue */
#endif
-#ifdef DEBUG_LOG
+#ifdef TRACE_LOG
/* Log file */
FILE * p_log_file; /* log file */
#endif
-#if !defined(INTF_MSG_QUEUE) && !defined(DEBUG_LOG)
+#if !defined(INTF_MSG_QUEUE) && !defined(TRACE_LOG)
/* If neither messages queue, neither log file is used, then the structure
* is empty. However, empty structures are not allowed in C. Therefore, a
* dummy integer is used to fill it. */
static void QueueMsg ( intf_msg_t *p_msg, int i_type,
char *psz_format, va_list ap );
static void PrintMsg ( intf_msg_item_t *p_msg );
-#ifdef DEBUG
+#ifdef TRACE
static void QueueDbgMsg ( intf_msg_t *p_msg, char *psz_file,
char *psz_function, int i_line,
char *psz_format, va_list ap );
#endif
-#ifdef DEBUG_LOG
+#ifdef TRACE_LOG
/* Log file initialization - on failure, file pointer will be null,
* and no log will be issued, but this is not considered as an
* error */
- p_msg->p_log_file = fopen( DEBUG_LOG, "w" );
+ p_msg->p_log_file = fopen( TRACE_LOG, "w" );
#endif
}
return( p_msg );
{
intf_FlushMsg(); /* print all remaining messages */
-#ifdef DEBUG_LOG
+#ifdef TRACE_LOG
/* Close log file if any */
if( p_main->p_msg->p_log_file != NULL )
{
}
#endif
+#ifdef INTF_MSG_QUEUE
+ /* destroy lock */
+ vlc_mutex_destroy( &p_main->p_msg->lock );
+#endif
+
/* Free structure */
free( p_main->p_msg );
}
{
va_list ap;
- if( i_level >= p_main->p_intf->i_warning_level )
+ if( i_level <= p_main->i_warning_level )
{
va_start( ap, psz_format );
QueueMsg( p_main->p_msg, INTF_MSG_WARN, psz_format, ap );
}
-/*****************************************************************************
- * intf_IntfMsg : print an interface message (ok ?)
- *****************************************************************************
- * In opposition to all other intf_*Msg function, this function does not print
- * it's message on default terminal (stdout or stderr), but send it to
- * interface (in fact to the X11 console). This means that the interface MUST
- * be initialized and a X11 console openned before this function is used, and
- * that once the console is closed, this call is vorbidden.
- * Practically, only the interface thread itself should call this function, and
- * flush all messages before intf_CloseX11Console() is called.
- *****************************************************************************/
-void intf_IntfMsg(char *psz_format, ...)
-{
- va_list ap;
-
- va_start( ap, psz_format );
- QueueMsg( p_main->p_msg, INTF_MSG_INTF, psz_format, ap );
- va_end( ap );
-}
-
/*****************************************************************************
* _intf_DbgMsg: print a debugging message (ok ?)
*****************************************************************************
* This function prints a debugging message. Compared to other intf_*Msg
- * functions, it is only defined if DEBUG is defined and require a file name,
+ * functions, it is only defined if TRACE is defined and require a file name,
* a function name and a line number as additionnal debugging informations. It
* also prints a debugging header for each received line.
*****************************************************************************/
-#ifdef DEBUG
+#ifdef TRACE
void _intf_DbgMsg( char *psz_file, char *psz_function, int i_line,
char *psz_format, ...)
{
{
va_list ap;
- if( i_level >= p_main->p_intf->i_warning_level )
+ if( i_level <= p_main->i_warning_level )
{
va_start( ap, psz_format );
QueueMsg( p_main->p_msg, INTF_MSG_WARN, psz_format, ap );
* message immediately. It should only be called through the macro
* intf_DbgMsgImm().
*****************************************************************************/
-#ifdef DEBUG
+#ifdef TRACE
void _intf_DbgMsgImm( char *psz_file, char *psz_function, int i_line,
char *psz_format, ...)
{
}
#endif
+/*****************************************************************************
+ * intf_WarnHexDump : print a hexadecimal dump of a memory area
+ *****************************************************************************
+ * This is convenient for debugging purposes.
+ *****************************************************************************/
+void intf_WarnHexDump( int i_level, void *p_data, int i_size )
+{
+ int i_index = 0;
+ int i_subindex;
+ char p_string[75];
+ u8 *p_area = (u8 *)p_data;
+
+ intf_WarnMsg( i_level, "hexdump: dumping %i bytes at address %p",
+ i_size, p_data );
+
+ while( i_index < i_size )
+ {
+ i_subindex = 0;
+
+ while( ( i_subindex < 24 ) && ( i_index + i_subindex < i_size ) )
+ {
+ sprintf( p_string + 3 * i_subindex, "%.2x ",
+ p_area[ i_index + i_subindex ] );
+
+ i_subindex++;
+ }
+
+ /* -1 here is safe because we know we printed at least one */
+ p_string[ 3 * i_subindex - 1 ] = '\0';
+ intf_WarnMsg( i_level, "0x%.4x: %s", i_index, p_string );
+
+ i_index += 24;
+ }
+
+ intf_WarnMsg( i_level, "hexdump: %i bytes dumped", i_size );
+}
+
/*****************************************************************************
* intf_FlushMsg (ok ?)
*****************************************************************************
vasprintf( &psz_str, psz_format, ap );
#else
psz_str = (char*) malloc( strlen(psz_format) + INTF_MAX_MSG_SIZE );
- vsprintf( psz_str, psz_format, ap );
#endif
if( psz_str == NULL )
{
fprintf(stderr, "\n" );
exit( errno );
}
+#ifdef HAVE_VASPRINTF
+#else
+ vsprintf( psz_str, psz_format, ap );
+#endif
#ifdef INTF_MSG_QUEUE /*...................................... queue mode ...*/
vlc_mutex_lock( &p_msg->lock ); /* get lock */
*/
p_msg_item->i_type = i_type;
p_msg_item->psz_msg = psz_str;
-#ifdef DEBUG
- p_msg_item->date = mdate();
+#ifdef TRACE
+ p_msg_item->date = mdate();
#endif
#ifdef INTF_MSG_QUEUE /*......................................... queue mode */
* QueueDbgMsg: add a message to a queue with debugging informations
*****************************************************************************
* This function is the same as QueueMsg, except that it is only defined when
- * DEBUG is define, and require additionnal debugging informations.
+ * TRACE is define, and require additionnal debugging informations.
*****************************************************************************/
-#ifdef DEBUG
+#ifdef TRACE
static void QueueDbgMsg(intf_msg_t *p_msg, char *psz_file, char *psz_function,
int i_line, char *psz_format, va_list ap)
{
* PrintMsg: print a message (ok ?)
*****************************************************************************
* Print a single message. The message data is not freed. This function exists
- * in two version. The DEBUG version prints a date with each message, and is
- * able to log messages (if DEBUG_LOG is defined).
+ * in two version. The TRACE version prints a date with each message, and is
+ * able to log messages (if TRACE_LOG is defined).
* The normal one just prints messages to the screen.
*****************************************************************************/
-#ifdef DEBUG
+#ifdef TRACE
static void PrintMsg( intf_msg_item_t *p_msg )
{
char psz_date[MSTRTIME_MAX_SIZE]; /* formatted time buffer */
- char * psz_msg; /* message buffer */
+ int i_msg_len = MSTRTIME_MAX_SIZE + strlen(p_msg->psz_msg) + 200;
+ char *psz_msg; /* message buffer */
+
+ psz_msg = malloc( sizeof( char ) * i_msg_len );
+
+ /* Check if allocation succeeded */
+ if( psz_msg == NULL )
+ {
+ fprintf( stderr, "error: not enough memory for message %s\n",
+ p_msg->psz_msg );
+ return;
+ }
/* Format message - the message is formatted here because in case the log
* file is used, it avoids another format string parsing */
{
case INTF_MSG_STD: /* regular messages */
case INTF_MSG_ERR:
- asprintf( &psz_msg, "%s", p_msg->psz_msg );
+ snprintf( psz_msg, i_msg_len, "%s", p_msg->psz_msg );
break;
case INTF_MSG_WARN: /* Warning message */
mstrtime( psz_date, p_msg->date );
- asprintf( &psz_msg, "(%s) %s",
+ snprintf( psz_msg, i_msg_len, "(%s) %s",
psz_date, p_msg->psz_msg );
break;
- case INTF_MSG_INTF: /* interface messages */
- asprintf( &psz_msg, "%s", p_msg->psz_msg );
- break;
-
case INTF_MSG_DBG: /* debug messages */
mstrtime( psz_date, p_msg->date );
- asprintf( &psz_msg, "(%s) " INTF_MSG_DBG_FORMAT "%s",
+ snprintf( psz_msg, i_msg_len, "(%s) " INTF_MSG_DBG_FORMAT "%s",
psz_date, p_msg->psz_file, p_msg->psz_function, p_msg->i_line,
p_msg->psz_msg );
break;
}
- /* Check if formatting function succeeded */
- if( psz_msg == NULL )
- {
- fprintf( stderr, "error: can not format message (%s): %s\n",
- strerror( errno ), p_msg->psz_msg );
- return;
- }
-
/*
* Print messages
*/
break;
case INTF_MSG_ERR: /* error messages */
case INTF_MSG_WARN:
-#ifndef DEBUG_LOG_ONLY
+#ifndef TRACE_LOG_ONLY
case INTF_MSG_DBG: /* debugging messages */
#endif
fprintf( stderr, "%s\n", psz_msg );
break;
- case INTF_MSG_INTF: /* interface messages */
- intf_ConsolePrint( p_main->p_intf->p_console, psz_msg );
- break;
}
-#ifdef DEBUG_LOG
+#ifdef TRACE_LOG
/* Append all messages to log file */
if( p_main->p_msg->p_log_file != NULL )
{
}
#endif
- /* Free formatted message */
+ /* Free the message */
free( psz_msg );
}
case INTF_MSG_WARN:
fprintf( stderr, "%s\n", p_msg->psz_msg ); /* warning message */
break;
- case INTF_MSG_INTF: /* interface messages */
- intf_ConsolePrint( p_main->p_intf->p_console, p_msg->psz_msg );
- break;
}
}