#include <stdlib.h>
#include <stdarg.h> /* va_list for BSD */
-#ifdef __APPLE__
-# include <xlocale.h>
-#elif defined(HAVE_LOCALE_H)
-# include <locale.h>
-#endif
-#include <errno.h> /* errno */
-#include <assert.h>
#include <unistd.h>
#include <vlc_common.h>
#include <vlc_interface.h>
-#ifdef WIN32
-# include <vlc_network.h> /* 'net_strerror' and 'WSAGetLastError' */
-#endif
#include <vlc_charset.h>
#include "../libvlc.h"
+#ifdef __ANDROID__
+#include <android/log.h>
+#endif
+
/**
* Emit a log message.
* \param obj VLC object emitting the message or NULL
va_end (args);
}
-#ifdef WIN32
+#ifdef _WIN32
static void Win32DebugOutputMsg (void *, int , const vlc_log_t *,
const char *, va_list);
#endif
if (obj != NULL && obj->i_flags & OBJECT_FLAGS_QUIET)
return;
- /* C locale to get error messages in English in the logs */
- locale_t c = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0);
- locale_t locale = uselocale (c);
-
-#ifndef __GLIBC__
- /* Expand %m to strerror(errno) - only once */
- char buf[strlen(format) + 2001], *ptr;
- strcpy (buf, format);
- ptr = (char*)buf;
- format = (const char*) buf;
+ /* Get basename from the module filename */
+ char *p = strrchr(module, '/');
+ if (p != NULL)
+ module = p;
+ p = strchr(module, '.');
- for( ;; )
+ size_t modlen = (p != NULL) ? (p - module) : 0;
+ char modulebuf[modlen + 1];
+ if (p != NULL)
{
- 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 */
+ memcpy(modulebuf, module, modlen);
+ modulebuf[modlen] = '\0';
+ module = modulebuf;
}
-#endif
/* Fill message information fields */
vlc_log_t msg;
}
/* Pass message to the callback */
- libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc);
+ libvlc_priv_t *priv = obj ? libvlc_priv (obj->p_libvlc) : NULL;
-#ifdef WIN32
+#ifdef _WIN32
va_list ap;
va_copy (ap, args);
- Win32DebugOutputMsg (&priv->log.verbose, type, &msg, format, ap);
+ Win32DebugOutputMsg (priv ? &priv->log.verbose : NULL, type, &msg, format, ap);
va_end (ap);
#endif
- vlc_rwlock_rdlock (&priv->log.lock);
- priv->log.cb (priv->log.opaque, type, &msg, format, args);
- vlc_rwlock_unlock (&priv->log.lock);
-
- uselocale (locale);
- freelocale (c);
+ if (priv) {
+ vlc_rwlock_rdlock (&priv->log.lock);
+ priv->log.cb (priv->log.opaque, type, &msg, format, args);
+ vlc_rwlock_unlock (&priv->log.lock);
+ }
}
static const char msg_type[4][9] = { "", " error", " warning", " debug" };
#define GRAY "\033[0m"
static const char msg_color[4][8] = { WHITE, RED, YELLOW, GRAY };
+/* Display size of a pointer */
+static const int ptr_width = 2 * /* hex digits */ sizeof(uintptr_t);
+
static void PrintColorMsg (void *d, int type, const vlc_log_t *p_item,
const char *format, va_list ap)
{
int canc = vlc_savecancel ();
flockfile (stream);
- fprintf (stream, "["GREEN"%p"GRAY"] ", (void *)p_item->i_object_id);
+ utf8_fprintf (stream, "["GREEN"%0*"PRIxPTR""GRAY"] ", ptr_width, 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: %s", p_item->psz_module,
p_item->psz_object_type, msg_type[type], msg_color[type]);
utf8_vfprintf (stream, format, ap);
fputs (GRAY"\n", stream);
-#if defined (WIN32) || defined (__OS2__)
+#if defined (_WIN32) || defined (__OS2__)
fflush (stream);
#endif
funlockfile (stream);
int canc = vlc_savecancel ();
flockfile (stream);
- fprintf (stream, "[%p] ", (void *)p_item->i_object_id);
+ utf8_fprintf (stream, "[%0*"PRIxPTR"] ", ptr_width, 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,
p_item->psz_object_type, msg_type[type]);
utf8_vfprintf (stream, format, ap);
putc_unlocked ('\n', stream);
-#if defined (WIN32) || defined (__OS2__)
+#if defined (_WIN32) || defined (__OS2__)
fflush (stream);
#endif
funlockfile (stream);
vlc_restorecancel (canc);
}
-#ifdef WIN32
+#ifdef _WIN32
static void Win32DebugOutputMsg (void* d, int type, const vlc_log_t *p_item,
const char *format, va_list dol)
{
}
#endif
+#ifdef __ANDROID__
+static void AndroidPrintMsg (void *d, int type, const vlc_log_t *p_item,
+ const char *format, va_list ap)
+{
+ int verbose = (intptr_t)d;
+ int prio;
+
+ if (verbose < 0 || verbose < (type - VLC_MSG_ERR))
+ return;
+
+ int canc = vlc_savecancel ();
+
+ 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
+
/**
* Sets the message logging callback.
* \param cb message callback, or NULL to reset
if (cb == NULL)
{
-#if defined (HAVE_ISATTY) && !defined (WIN32)
+#ifdef __ANDROID__
+ cb = AndroidPrintMsg;
+#else
+#if defined (HAVE_ISATTY) && !defined (_WIN32)
if (isatty (STDERR_FILENO) && var_InheritBool (vlc, "color"))
cb = PrintColorMsg;
else
#endif
cb = PrintMsg;
+#endif // __ANDROID__
opaque = (void *)(intptr_t)priv->log.verbose;
}