/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Dave Greene
 */

#ifndef __BASE_MISC_HH__
#define __BASE_MISC_HH__

#include "base/compiler.hh"
#include "base/cprintf.hh"
#include "base/varargs.hh"

#if defined(__SUNPRO_CC)
#define __FUNCTION__ "how to fix me?"
#endif

// General exit message, these functions will never return and will
// either abort() if code is < 0 or exit with the code if >= 0
void __exit_message(const char *prefix, int code,
    const char *func, const char *file, int line,
    const char *format, CPRINTF_DECLARATION) M5_ATTR_NORETURN;

void __exit_message(const char *prefix, int code,
    const char *func, const char *file, int line,
    const std::string &format, CPRINTF_DECLARATION) M5_ATTR_NORETURN;

inline void
__exit_message(const char *prefix, int code,
    const char *func, const char *file, int line,
    const std::string& format, CPRINTF_DEFINITION)
{
    __exit_message(prefix, code, func, file, line, format.c_str(),
                   VARARGS_ALLARGS);
}

M5_PRAGMA_NORETURN(__exit_message)
#define exit_message(prefix, code, ...)                            \
    __exit_message(prefix, code, __FUNCTION__, __FILE__, __LINE__, \
                   __VA_ARGS__)

//
// This implements a cprintf based panic() function.  panic() should
// be called when something happens that should never ever happen
// regardless of what the user does (i.e., an acutal m5 bug).  panic()
// calls abort which can dump core or enter the debugger.
//
//
#define panic(...) exit_message("panic", -1, __VA_ARGS__)

//
// This implements a cprintf based fatal() function.  fatal() should
// be called when the simulation cannot continue due to some condition
// that is the user's fault (bad configuration, invalid arguments,
// etc.) and not a simulator bug.  fatal() calls exit(1), i.e., a
// "normal" exit with an error code, as opposed to abort() like
// panic() does.
//
#define fatal(...) exit_message("fatal", 1, __VA_ARGS__)

void
__base_message(std::ostream &stream, const char *prefix, bool verbose,
          const char *func, const char *file, int line,
          const char *format, CPRINTF_DECLARATION);

inline void
__base_message(std::ostream &stream, const char *prefix, bool verbose,
          const char *func, const char *file, int line,
          const std::string &format, CPRINTF_DECLARATION)
{
    __base_message(stream, prefix, verbose, func, file, line, format.c_str(),
              VARARGS_ALLARGS);
}

#define base_message(stream, prefix, verbose, ...)                      \
    __base_message(stream, prefix, verbose, __FUNCTION__, __FILE__, __LINE__, \
                   __VA_ARGS__)

// Only print the message the first time this expression is
// encountered.  i.e.  This doesn't check the string itself and
// prevent duplicate strings, this prevents the statement from
// happening more than once. So, even if the arguments change and that
// would have resulted in a different message thoes messages would be
// supressed.
#define base_message_once(...) do {                     \
        static bool once = false;                       \
        if (!once) {                                    \
            base_message(__VA_ARGS__);                  \
            once = true;                                \
        }                                               \
    } while (0)

#define cond_message(cond, ...) do {            \
        if (cond)                               \
            base_message(__VA_ARGS__);          \
    } while (0)

#define cond_message_once(cond, ...) do {               \
        static bool once = false;                       \
        if (!once && cond) {                            \
            base_message(__VA_ARGS__);                  \
            once = true;                                \
        }                                               \
    } while (0)


extern bool want_warn, warn_verbose;
extern bool want_info, info_verbose;
extern bool want_hack, hack_verbose;

#define warn(...) \
    cond_message(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__)
#define inform(...) \
    cond_message(want_info, std::cout, "info", info_verbose, __VA_ARGS__)
#define hack(...) \
    cond_message(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__)

#define warn_once(...) \
    cond_message_once(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__)
#define inform_once(...) \
    cond_message_once(want_info, std::cout, "info", info_verbose, __VA_ARGS__)
#define hack_once(...) \
    cond_message_once(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__)

#endif // __BASE_MISC_HH__
