[REACTOS]
[reactos.git] / reactos / include / reactos / debug.h
index 11626d2..c08b7df 100644 (file)
@@ -3,23 +3,22 @@
  * PROJECT:         ReactOS kernel
  * FILE:            include/internal/debug.h
  * PURPOSE:         Useful debugging macros
- * PROGRAMMER:      David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- *                28/05/98: Created
+ * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
  */
 
 /*
- * NOTE: Define NDEBUG before including this header to disable debugging
- * macros
+ * NOTE: Define NDEBUG before including this header
+ * to disable debugging macros.
  */
 
 #ifndef __INTERNAL_DEBUG
 #define __INTERNAL_DEBUG
 
-/* Define DbgPrint/DbgPrintEx/RtlAssert unless the NDK is used */
+/* Define DbgPrint/DbgPrintEx/RtlAssert/RtlRaiseStatus unless the NDK is used */
 #if !defined(_RTLFUNCS_H) && !defined(_NTDDK_)
 
-/* Make sure we have basic types (some people include us *before* SDK... */
+/* Make sure we have basic types (some people include us *before* SDK)... */
 #if !defined(_NTDEF_) && !defined(_NTDEF_H) && !defined(_WINDEF_) && !defined(_WINDEF_H)
 #error Please include SDK first.
 #endif
 ULONG
 __cdecl
 DbgPrint(
-    IN PCCH  Format,
-    IN ...
+    _In_z_ _Printf_format_string_ PCSTR Format,
+    ...
 );
 
 NTSYSAPI
 ULONG
 __cdecl
 DbgPrintEx(
-    IN ULONG ComponentId,
-    IN ULONG Level,
-    IN PCCH  Format,
-    IN ...
+    _In_ ULONG ComponentId,
+    _In_ ULONG Level,
+    _In_z_ _Printf_format_string_ PCCH Format,
+    ...
 );
 
+__analysis_noreturn
 NTSYSAPI
 VOID
 NTAPI
@@ -51,11 +51,34 @@ RtlAssert(
     PCHAR Message
 );
 
+/*
+ * This is the definition of NTSTATUS, but renamed
+ * in order not to conflict with other ones.
+ */
+typedef _Return_type_success_(return >= 0) LONG DEBUG_NTSTATUS;
+
+__analysis_noreturn
+NTSYSAPI
+VOID
+NTAPI
+RtlRaiseStatus(
+    _In_ DEBUG_NTSTATUS Status
+);
+
 #endif /* !defined(_RTLFUNCS_H) && !defined(_NTDDK_) */
 
+
+/* Fix usage of RtlRaiseStatus */
+#if !defined(_RTLFUNCS_H) && defined(_NTDDK_)
+    #define RaiseStatus ExRaiseStatus
+#else
+    #define RaiseStatus RtlRaiseStatus
+#endif /* !defined(_RTLFUNCS_H) && defined(_NTDDK_) */
+
+
 #ifndef assert
 #ifndef NASSERT
-#define assert(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
+#define assert(x) if (!(x)) { RtlAssert((PVOID)#x, (PVOID)__FILE__, __LINE__, ""); }
 #else
 #define assert(x)
 #endif
@@ -63,7 +86,7 @@ RtlAssert(
 
 #ifndef ASSERT
 #ifndef NASSERT
-#define ASSERT(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
+#define ASSERT(x) if (!(x)) { RtlAssert((PVOID)#x, (PVOID)__FILE__, __LINE__, ""); }
 #else
 #define ASSERT(x)
 #endif
@@ -71,12 +94,15 @@ RtlAssert(
 
 #ifndef ASSERTMSG
 #ifndef NASSERT
-#define ASSERTMSG(x,m) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, m); }
+#define ASSERTMSG(x,m) if (!(x)) { RtlAssert((PVOID)#x, __FILE__, __LINE__, m); }
 #else
 #define ASSERTMSG(x)
 #endif
 #endif
 
+/* For internal purposes only */
+#define __NOTICE(level, fmt, ...)   DbgPrint(#level ":  %s at %s:%d " fmt, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
+
 /* Print stuff only on Debug Builds*/
 #define DPFLTR_DEFAULT_ID -1
 #if DBG
@@ -101,17 +127,18 @@ RtlAssert(
 
     #endif
 
-    #define UNIMPLEMENTED         DbgPrint("WARNING:  %s at %s:%d is UNIMPLEMENTED!\n",__FUNCTION__,__FILE__,__LINE__);
+    #define UNIMPLEMENTED         __NOTICE(WARNING, "is UNIMPLEMENTED!\n");
 
     #define ERR_(ch, fmt, ...)    DbgPrintEx(DPFLTR_##ch##_ID, DPFLTR_ERROR_LEVEL, "(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
     #define WARN_(ch, fmt, ...)   DbgPrintEx(DPFLTR_##ch##_ID, DPFLTR_WARNING_LEVEL, "(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
     #define TRACE_(ch, fmt, ...)  DbgPrintEx(DPFLTR_##ch##_ID, DPFLTR_TRACE_LEVEL, "(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
     #define INFO_(ch, fmt, ...)   DbgPrintEx(DPFLTR_##ch##_ID, DPFLTR_INFO_LEVEL, "(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
-    
+
     #define ERR__(ch, fmt, ...)    DbgPrintEx(ch, DPFLTR_ERROR_LEVEL, "(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
     #define WARN__(ch, fmt, ...)   DbgPrintEx(ch, DPFLTR_WARNING_LEVEL, "(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
     #define TRACE__(ch, fmt, ...)  DbgPrintEx(ch, DPFLTR_TRACE_LEVEL, "(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
     #define INFO__(ch, fmt, ...)   DbgPrintEx(ch, DPFLTR_INFO_LEVEL, "(%s:%d) " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
+
 #else /* not DBG */
 
     /* On non-debug builds, we never show these */
@@ -124,13 +151,64 @@ RtlAssert(
     #define WARN_(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
     #define TRACE_(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
     #define INFO_(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
-    
+
     #define ERR__(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
     #define WARN__(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
     #define TRACE__(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
     #define INFO__(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
+
 #endif /* not DBG */
 
+/******************************************************************************/
+/* For internal purposes only */
+#define __ERROR_DBGBREAK(...)   \
+do {                            \
+    DbgPrint("" __VA_ARGS__);   \
+    DbgBreakPoint();            \
+} while (0)
+
+/* For internal purposes only */
+#define __ERROR_FATAL(Status, ...)  \
+do {                                \
+    DbgPrint("" __VA_ARGS__);       \
+    RaiseStatus((Status));          \
+} while (0)
+
+/*
+ * These macros are designed to display an optional printf-like
+ * user-defined message and to break into the debugger.
+ * After that they allow to continue the program execution.
+ */
+#define ERROR_DBGBREAK(...)         \
+do {                                \
+    __NOTICE(ERROR, "\n");          \
+    __ERROR_DBGBREAK(__VA_ARGS__);  \
+} while (0)
+
+#define UNIMPLEMENTED_DBGBREAK(...)         \
+do {                                        \
+    __NOTICE(ERROR, "is UNIMPLEMENTED!\n"); \
+    __ERROR_DBGBREAK(__VA_ARGS__);          \
+} while (0)
+
+/*
+ * These macros are designed to display an optional printf-like
+ * user-defined message and to break into the debugger.
+ * After that they halt the execution of the current thread.
+ */
+#define ERROR_FATAL(...)                                    \
+do {                                                        \
+    __NOTICE(UNRECOVERABLE ERROR, "\n");                    \
+    __ERROR_FATAL(STATUS_ASSERTION_FAILURE, __VA_ARGS__);   \
+} while (0)
+
+#define UNIMPLEMENTED_FATAL(...)                            \
+do {                                                        \
+    __NOTICE(UNRECOVERABLE ERROR, "is UNIMPLEMENTED!\n");   \
+    __ERROR_FATAL(STATUS_NOT_IMPLEMENTED, __VA_ARGS__);     \
+} while (0)
+/******************************************************************************/
+
 #define ASSERT_IRQL_LESS_OR_EQUAL(x) ASSERT(KeGetCurrentIrql()<=(x))
 #define ASSERT_IRQL_EQUAL(x) ASSERT(KeGetCurrentIrql()==(x))
 #define ASSERT_IRQL_LESS(x) ASSERT(KeGetCurrentIrql()<(x))