// vi:set ft=cpp: -*- Mode: C++ -*-
/**
 * \internal
 * \file
 * \brief Debug interface
 */
/*
 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
 *               Alexander Warg <warg@os.inf.tu-dresden.de>
 *     economic rights: Technische Universität Dresden (Germany)
 *
 * This file is part of TUD:OS and distributed under the terms of the
 * GNU General Public License 2.
 * Please see the COPYING-GPL-2 file for details.
 *
 * As a special exception, you may use this file as part of a free software
 * library without restriction.  Specifically, if other files instantiate
 * templates or use macros or inline functions from this file, or you compile
 * this file and link it with other files to produce an executable, this
 * file does not by itself cause the resulting executable to be covered by
 * the GNU General Public License.  This exception does not however
 * invalidate any other reasons why the executable file might be covered by
 * the GNU General Public License.
 */
#pragma once

#include <l4/sys/types.h>

namespace L4Re { namespace Util {
class Err
{
public:
  enum Level
  {
    Normal = 0,
    Fatal,
  };

  static char const *const levels[];

  void tag() const
  { cprintf("%s: %s", _component, levels[_l]); }

  int printf(char const *fmt, ...) const
    __attribute__((format(printf,2,3)));

  int cprintf(char const *fmt, ...) const
    __attribute__((format(printf,2,3)));

  Err(Level l, char const *component) : _l(l), _component(component)
  {}

private:
  Level _l;
  char const *_component;
};


class Dbg
{
private:
  void tag() const;

#ifndef NDEBUG

  unsigned long _m;
  char const *const _component;
  char const *const _subsys;

public:
  static unsigned long level;

  static void set_level(unsigned long l) { level = l; }

  bool is_active() const { return _m & level; }

  int printf(char const *fmt, ...) const
    __attribute__((format(printf, 2, 3)));

  int cprintf(char const *fmt, ...) const
    __attribute__((format(printf, 2, 3)));

  explicit
  Dbg() : _m(1), _component(0), _subsys(0) { };

  explicit
  Dbg(unsigned long mask, char const *comp, char const *subs)
  : _m(mask), _component(comp), _subsys(subs)
  {}

#else

public:
  static void set_level(unsigned long) {}
  bool is_active() const { return false; }

  int printf(char const * /*fmt*/, ...) const
    __attribute__((format(printf, 2, 3)))
  { return 0; }

  int cprintf(char const * /*fmt*/, ...) const
    __attribute__((format(printf, 2, 3)))
  { return 0; }

  explicit
  Dbg() {}

  explicit
  Dbg(unsigned long, char const *, char const *) {}

#endif

};

}}

