log.c 5.01 KB
Newer Older
1 2 3
/*****************************************************************************
 * log.c: libvlc new API log functions
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2005 VLC authors and VideoLAN
5
 *
6
 * $Id$
7 8 9
 *
 * Authors: Damien Fouilleul <damienf@videolan.org>
 *
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
10 11 12
 * 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
13 14 15 16
 * (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
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
17 18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
19
 *
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
20 21 22
 * 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.
23 24
 *****************************************************************************/

25 26 27 28
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
29
#include <assert.h>
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
#include <vlc/libvlc.h>
#include "libvlc_internal.h"
#include <vlc_common.h>
#include <vlc_interface.h>

/*** Logging core dispatcher ***/

static vlc_rwlock_t log_lock = VLC_STATIC_RWLOCK;
static libvlc_log_subscriber_t *log_first = NULL;
static msg_subscription_t sub;

VLC_FORMAT(2,3)
static void libvlc_log (int level, const char *fmt, ...)
{
    libvlc_log_subscriber_t *sub;
    va_list ap;

    switch (level)
    {
        case VLC_MSG_INFO: level = LIBVLC_NOTICE;  break;
        case VLC_MSG_ERR:  level = LIBVLC_ERROR;   break;
        case VLC_MSG_WARN: level = LIBVLC_WARNING; break;
        case VLC_MSG_DBG:  level = LIBVLC_DEBUG;   break;
    }

    va_start (ap, fmt);
    vlc_rwlock_rdlock (&log_lock);
    for (sub = log_first; sub != NULL; sub = sub->next)
        sub->func (sub->opaque, level, fmt, ap);
    vlc_rwlock_unlock (&log_lock);
    va_end (ap);
}

static void libvlc_logf (void *dummy, int level, const msg_item_t *item,
                         const char *fmt, va_list ap)
{
    char *msg;

    if (unlikely(vasprintf (&msg, fmt, ap) == -1))
        msg = NULL;
    if (item->psz_header != NULL)
        libvlc_log (level, "[%p] [%s]: %s %s %s", (void *)item->i_object_id,
                    item->psz_header, item->psz_module, item->psz_object_type,
                    msg ? msg : "Not enough memory");
    else
        libvlc_log (level, "[%p]: %s %s %s", (void *)item->i_object_id,
                    item->psz_module, item->psz_object_type,
                    msg ? msg : "Not enough memory");
    free (msg);
    (void) dummy;
}

void libvlc_log_init (void)
{
    vlc_Subscribe (&sub, libvlc_logf, NULL);
}

void libvlc_log_deinit (void)
{
    vlc_Unsubscribe (&sub);
}

void libvlc_log_subscribe (libvlc_log_subscriber_t *sub,
                           libvlc_log_cb cb, void *data)
{
    sub->prev = NULL;
    sub->func = cb;
    sub->opaque = data;
    vlc_rwlock_wrlock (&log_lock);
    sub->next = log_first;
    log_first = sub;
    vlc_rwlock_unlock (&log_lock);
}

void libvlc_log_unsubscribe( libvlc_log_subscriber_t *sub )
{
    vlc_rwlock_wrlock (&log_lock);
    if (sub->next != NULL)
        sub->next->prev = sub->prev;
    if (sub->prev != NULL)
        sub->prev->next = sub->next;
    else
        log_first = sub->next;
    vlc_rwlock_unlock (&log_lock);
}
115

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
/*** Helpers for logging to files ***/
static void libvlc_log_file (void *data, int level, const char *fmt,
                             va_list ap)
{
    FILE *stream = data;

    flockfile (stream);
    vfprintf (stream, fmt, ap);
    fputc ('\n', stream);
    funlockfile (stream);
    (void) level;
}

void libvlc_log_subscribe_file (libvlc_log_subscriber_t *sub, FILE *stream)
{
    libvlc_log_subscribe (sub, libvlc_log_file, stream);
}

/*** Stubs for the old interface ***/
135
unsigned libvlc_get_log_verbosity( const libvlc_instance_t *p_instance )
136
{
137 138
    (void) p_instance;
    return -1;
139 140
}

141
void libvlc_set_log_verbosity( libvlc_instance_t *p_instance, unsigned level )
142
{
143 144
    (void) p_instance;
    (void) level;
145 146
}

147
libvlc_log_t *libvlc_log_open( libvlc_instance_t *p_instance )
148
{
149 150
    (void) p_instance;
    return malloc(1);
151 152
}

153
void libvlc_log_close( libvlc_log_t *p_log )
154
{
155
    free(p_log);
156 157
}

158
unsigned libvlc_log_count( const libvlc_log_t *p_log )
159
{
160 161
    (void) p_log;
    return 0;
162 163
}

164
void libvlc_log_clear( libvlc_log_t *p_log )
165
{
166
    (void) p_log;
167 168
}

169
libvlc_log_iterator_t *libvlc_log_get_iterator( const libvlc_log_t *p_log )
170
{
171
    return (p_log != NULL) ? malloc(1) : NULL;
172 173
}

174
void libvlc_log_iterator_free( libvlc_log_iterator_t *p_iter )
175
{
176
    free( p_iter );
177 178
}

179
int libvlc_log_iterator_has_next( const libvlc_log_iterator_t *p_iter )
180
{
181 182
    (void) p_iter;
    return 0;
183 184 185
}

libvlc_log_message_t *libvlc_log_iterator_next( libvlc_log_iterator_t *p_iter,
186
                                                libvlc_log_message_t *buffer )
187
{
188
    (void) p_iter; (void) buffer;
189
    return NULL;
190
}