Blame lib/driver/logging.c

Packit dd8086
/*
Packit dd8086
  Copyright (C) 2003, 2004, 2008, 2011, 2012, 2015
Packit dd8086
  Rocky Bernstein <rocky@gnu.org>
Packit dd8086
  Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Packit dd8086
Packit dd8086
  This program is free software: you can redistribute it and/or modify
Packit dd8086
  it under the terms of the GNU General Public License as published by
Packit dd8086
  the Free Software Foundation, either version 3 of the License, or
Packit dd8086
  (at your option) any later version.
Packit dd8086
Packit dd8086
  This program is distributed in the hope that it will be useful,
Packit dd8086
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit dd8086
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit dd8086
  GNU General Public License for more details.
Packit dd8086
Packit dd8086
  You should have received a copy of the GNU General Public License
Packit dd8086
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit dd8086
*/
Packit dd8086

Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
# define __CDIO_CONFIG_H__ 1
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#ifdef HAVE_STDLIB_H
Packit dd8086
#include <stdlib.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_STDARG_H
Packit dd8086
#include <stdarg.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_STDIO_H
Packit dd8086
#include <stdio.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <cdio/logging.h>
Packit dd8086
#include "cdio_assert.h"
Packit dd8086
#include "portable.h"
Packit dd8086
#include <assert.h>
Packit dd8086
Packit dd8086
cdio_log_level_t cdio_loglevel_default = CDIO_LOG_WARN;
Packit dd8086
Packit dd8086
extern void
Packit dd8086
cdio_default_log_handler(cdio_log_level_t level, const char message[])
Packit dd8086
{
Packit dd8086
  switch (level)
Packit dd8086
    {
Packit dd8086
    case CDIO_LOG_ERROR:
Packit dd8086
      if (level >= cdio_loglevel_default) {
Packit dd8086
        fprintf (stderr, "**ERROR: %s\n", message);
Packit dd8086
        fflush (stderr);
Packit dd8086
      }
Packit dd8086
      exit (EXIT_FAILURE);
Packit dd8086
      break;
Packit dd8086
    case CDIO_LOG_DEBUG:
Packit dd8086
      if (level >= cdio_loglevel_default) {
Packit dd8086
        fprintf (stdout, "--DEBUG: %s\n", message);
Packit dd8086
      }
Packit dd8086
      break;
Packit dd8086
    case CDIO_LOG_WARN:
Packit dd8086
      if (level >= cdio_loglevel_default) {
Packit dd8086
        fprintf (stdout, "++ WARN: %s\n", message);
Packit dd8086
      }
Packit dd8086
      break;
Packit dd8086
    case CDIO_LOG_INFO:
Packit dd8086
      if (level >= cdio_loglevel_default) {
Packit dd8086
        fprintf (stdout, "   INFO: %s\n", message);
Packit dd8086
      }
Packit dd8086
      break;
Packit dd8086
    case CDIO_LOG_ASSERT:
Packit dd8086
      if (level >= cdio_loglevel_default) {
Packit dd8086
        fprintf (stderr, "!ASSERT: %s\n", message);
Packit dd8086
        fflush (stderr);
Packit dd8086
      }
Packit dd8086
      abort ();
Packit dd8086
      break;
Packit dd8086
    default:
Packit dd8086
      cdio_assert_not_reached ();
Packit dd8086
      break;
Packit dd8086
    }
Packit dd8086
Packit dd8086
  fflush (stdout);
Packit dd8086
}
Packit dd8086
Packit dd8086
cdio_log_handler_t _handler = cdio_default_log_handler;
Packit dd8086
Packit dd8086
cdio_log_handler_t
Packit dd8086
cdio_log_set_handler(cdio_log_handler_t new_handler)
Packit dd8086
{
Packit dd8086
  cdio_log_handler_t old_handler = _handler;
Packit dd8086
Packit dd8086
  _handler = new_handler;
Packit dd8086
Packit dd8086
  return old_handler;
Packit dd8086
}
Packit dd8086
Packit dd8086
static void
Packit dd8086
cdio_logv(cdio_log_level_t level, const char format[], va_list args)
Packit dd8086
{
Packit dd8086
  char buf[1024] = { 0, };
Packit dd8086
Packit dd8086
  /* _handler() is user defined and we want to make sure _handler()
Packit dd8086
  doesn't call us, cdio_logv. in_recursion is used for that, however
Packit dd8086
  it has a problem in multi-threaded programs. I'm not sure how to
Packit dd8086
  handle multi-threading and recursion checking both. For now, we'll
Packit dd8086
  leave in the recursion checking, at the expense of handling
Packit dd8086
  multi-threaded log calls. To ameliorate this, we'll check the log
Packit dd8086
  level and handle calls where there is no output, before the
Packit dd8086
  recursion check.
Packit dd8086
  */
Packit dd8086
 static int in_recursion = 0;
Packit dd8086
Packit dd8086
  if (level < cdio_loglevel_default) return;
Packit dd8086
Packit dd8086
  if (in_recursion) {
Packit dd8086
    /* Can't use cdio_assert_not_reached() as that may call cdio_logv */
Packit dd8086
    assert(0);
Packit dd8086
  }
Packit dd8086
Packit dd8086
  in_recursion = 1;
Packit dd8086
Packit dd8086
  vsnprintf(buf, sizeof(buf)-1, format, args);
Packit dd8086
Packit dd8086
  _handler(level, buf);
Packit dd8086
Packit dd8086
  in_recursion = 0;
Packit dd8086
}
Packit dd8086
Packit dd8086
void
Packit dd8086
cdio_log(cdio_log_level_t level, const char format[], ...)
Packit dd8086
{
Packit dd8086
  va_list args;
Packit dd8086
  va_start (args, format);
Packit dd8086
  cdio_logv (level, format, args);
Packit dd8086
  va_end (args);
Packit dd8086
}
Packit dd8086
Packit dd8086
#define CDIO_LOG_TEMPLATE(level, LEVEL) \
Packit dd8086
void \
Packit dd8086
cdio_ ## level (const char format[], ...) \
Packit dd8086
{ \
Packit dd8086
  va_list args; \
Packit dd8086
  va_start (args, format); \
Packit dd8086
  cdio_logv (CDIO_LOG_ ## LEVEL, format, args); \
Packit dd8086
  va_end (args); \
Packit dd8086
}
Packit dd8086
Packit dd8086
CDIO_LOG_TEMPLATE(debug, DEBUG)
Packit dd8086
CDIO_LOG_TEMPLATE(info, INFO)
Packit dd8086
CDIO_LOG_TEMPLATE(warn, WARN)
Packit dd8086
CDIO_LOG_TEMPLATE(error, ERROR)
Packit dd8086
Packit dd8086
#undef CDIO_LOG_TEMPLATE
Packit dd8086
Packit dd8086

Packit dd8086
/*
Packit dd8086
 * Local variables:
Packit dd8086
 *  c-file-style: "gnu"
Packit dd8086
 *  tab-width: 8
Packit dd8086
 *  indent-tabs-mode: nil
Packit dd8086
 * End:
Packit dd8086
 */