eon is a tru64 regression, not a linux one
[gem5.git] / src / base / misc.hh
index 87faf20e6b05b9abe6dc0198b82201cd6290b5c4..1509ea2d2738a775b8080dfe31b23f9055fd4b71 100644 (file)
 #ifndef __MISC_HH__
 #define __MISC_HH__
 
-#include <assert.h>
+#include <cassert>
+
+#include "base/compiler.hh"
 #include "base/cprintf.hh"
+#include "base/varargs.hh"
+
+#if defined(__SUNPRO_CC)
+#define __FUNCTION__ "how to fix me?"
+#endif
 
 //
 // This implements a cprintf based panic() function.  panic() should
 // calls abort which can dump core or enter the debugger.
 //
 //
-void __panic(const std::string&, cp::ArgList &, const char*, const char*, int)
-    __attribute__((noreturn));
-#define __panic__(format, args...) \
-    __panic(format, (*(new cp::ArgList), args), \
-        __FUNCTION__, __FILE__, __LINE__)
-#define panic(args...) \
-    __panic__(args, cp::ArgListNull())
+void __panic(const char *func, const char *file, int line, const char *format,
+             CPRINTF_DECLARATION) M5_ATTR_NORETURN;
+void __panic(const char *func, const char *file, int line,
+             const std::string &format, CPRINTF_DECLARATION)
+M5_ATTR_NORETURN;
+
+inline void
+__panic(const char *func, const char *file, int line,
+        const std::string &format, CPRINTF_DEFINITION)
+{
+    __panic(func, file, line, format.c_str(), VARARGS_ALLARGS);
+}
+M5_PRAGMA_NORETURN(__panic)
+#define panic(...) __panic(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
 
 //
 // This implements a cprintf based fatal() function.  fatal() should
@@ -58,31 +72,54 @@ void __panic(const std::string&, cp::ArgList &, const char*, const char*, int)
 // "normal" exit with an error code, as opposed to abort() like
 // panic() does.
 //
-void __fatal(const std::string&, cp::ArgList &, const char*, const char*, int)
-    __attribute__((noreturn));
-#define __fatal__(format, args...) \
-    __fatal(format, (*(new cp::ArgList), args), \
-        __FUNCTION__, __FILE__, __LINE__)
-#define fatal(args...) \
-    __fatal__(args, cp::ArgListNull())
+void __fatal(const char *func, const char *file, int line, const char *format,
+             CPRINTF_DECLARATION) M5_ATTR_NORETURN;
+void __fatal(const char *func, const char *file, int line,
+             const std::string &format, CPRINTF_DECLARATION)
+    M5_ATTR_NORETURN;
+
+inline void
+__fatal(const char *func, const char *file, int line,
+        const std::string &format, CPRINTF_DEFINITION)
+{
+    __fatal(func, file, line, format.c_str(), VARARGS_ALLARGS);
+}
+M5_PRAGMA_NORETURN(__fatal)
+#define fatal(...) __fatal(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
 
 //
 // This implements a cprintf based warn
 //
-void __warn(const std::string&, cp::ArgList &, const char*, const char*, int);
-#define __warn__(format, args...) \
-    __warn(format, (*(new cp::ArgList), args), \
-           __FUNCTION__, __FILE__, __LINE__)
-#define warn(args...) \
-    __warn__(args, cp::ArgListNull())
+void __warn(const char *func, const char *file, int line, const char *format,
+            CPRINTF_DECLARATION);
+inline void
+__warn(const char *func, const char *file, int line, const std::string &format,
+       CPRINTF_DECLARATION)
+{
+    __warn(func, file, line, format, VARARGS_ALLARGS);
+}
+#define warn(...) __warn(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
+
+// Only print the warning message the first time it is seen.  This
+// doesn't check the warning string itself, it just only lets one
+// warning come from the statement. So, even if the arguments change
+// and that would have resulted in a different warning message,
+// subsequent messages would still be supressed.
+#define warn_once(...) do {                         \
+        static bool once = false;                   \
+        if (!once) {                                \
+            warn(__VA_ARGS__);                       \
+            once = true;                            \
+        }                                           \
+    } while (0)
 
 //
 // assert() that prints out the current cycle
 //
-#define m5_assert(TEST) \
-   if (!(TEST)) { \
-     std::cerr << "Assertion failure, curTick = " << curTick << std::endl; \
-   } \
-   assert(TEST);
+#define m5_assert(TEST) do {                                            \
+    if (!(TEST))                                                        \
+        ccprintf(std::cerr, "Assertion failure, curTick = %d\n", curTick); \
+    assert(TEST);                                                       \
+} while (0)
 
 #endif // __MISC_HH__