1 // Hxt - Copyright (C)
2 // 2016 - 2020 UCLouvain
3 //
4 // See the LICENSE.txt file for license information.
5 //
6 // Contributor(s):
7 //   Célestin Marot
8 
9 #ifndef HXT_MESSAGE_H
10 #define HXT_MESSAGE_H
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #include <stdlib.h>
17 #include <stdarg.h>
18 
19 
20 /* HEXTREME FUNCTIONS ONLY RETURN A STATUS (except hxtGetMessageString)*/
21 typedef enum
22 {
23   // positive values mean a success         => HXT_CHECK does nothing for positive values
24   HXT_STATUS_OK                    = 0,
25   HXT_STATUS_TRUE                  = 0,
26   HXT_STATUS_FALSE                 = 1,
27 
28 
29   // ====== ERRORS
30   // negatives values means errors
31 
32   // Fatal Errors                            => HXT_CHECK give trace message and return
33   HXT_STATUS_ERROR                 = -1,
34   HXT_STATUS_FAILED                = -2,
35   HXT_STATUS_ASSERTION_FAILED      = -3,
36   HXT_STATUS_OUT_OF_MEMORY         = -4,
37   HXT_STATUS_FILE_CANNOT_BE_OPENED = -5,
38   HXT_STATUS_POINTER_ERROR         = -6,
39   HXT_STATUS_READ_ERROR            = -7,
40   HXT_STATUS_WRITE_ERROR           = -8,
41   HXT_STATUS_RANGE_ERROR           = -9,
42   HXT_STATUS_FORMAT_ERROR          = -10,
43 
44 
45   // INTERNAL Errors (<= HXT_STATUS_INTERNAL) => HXT_CHECK does not give trace message but returns... should be catched internally !
46   HXT_STATUS_INTERNAL              = -1024,
47   HXT_STATUS_SKIP                  = -1025,
48   HXT_STATUS_TRYAGAIN              = -1026,
49   // a smoothing or topological operation can silently fail because of these
50   HXT_STATUS_CONFLICT              = -1027,
51   HXT_STATUS_CONSTRAINT            = -1028,
52   HXT_STATUS_NOTBETTER             = -1029,
53   HXT_STATUS_DOUBLE_PT             = -1030
54 
55 
56 }HXTStatus;
57 
58 
59 #define STR(x) #x
60 #define STRINGIFY(x) STR(x)
61 
62 #define HXT_INFO(...)                 hxtMessageInfo(__func__, __FILE__, STRINGIFY(__LINE__), ## __VA_ARGS__ )
63 #define HXT_INFO_COND(cond, ...)      ((cond)?HXT_INFO(__VA_ARGS__):HXT_STATUS_OK)
64 #define HXT_WARNING(...)              hxtMessageWarning(__func__, __FILE__, STRINGIFY(__LINE__), ## __VA_ARGS__ )
65 
66 /* print an error message corresponding to a status */
67 #define HXT_ERROR_MSG(status, ...)    hxtMessageError(status, __func__, __FILE__, STRINGIFY(__LINE__), ## __VA_ARGS__ )
68 #define HXT_ERROR(status)             HXT_ERROR_MSG(status,NULL)
69 
70 /* give trace message if status is not OK, but does not return */
71 #ifdef NDEBUG
72 #define HXT_TRACE_MSG(status, ...)    (void)0 // do nothing
73 #else
74 #define HXT_TRACE_MSG(status, ...)    hxtMessageTraceError(status, __func__, __FILE__, STRINGIFY(__LINE__), ## __VA_ARGS__ )
75 #endif
76 #define HXT_TRACE(status)             HXT_TRACE_MSG(status, NULL)
77 
78 /* give trace message and return the error status if not ok */
79 #define HXT_CHECK_MSG(status, ...)              \
80   do {                                          \
81     HXTStatus _tmp_ = status;                   \
82     if(_tmp_<0) {                               \
83       if (_tmp_>HXT_STATUS_INTERNAL) {          \
84         HXT_TRACE_MSG(_tmp_, ## __VA_ARGS__);   \
85       }                                         \
86       return _tmp_;                             \
87     }                                           \
88   } while(0)
89 
90 
91 #define HXT_CHECK(status)             HXT_CHECK_MSG(status,NULL)
92 
93 /* use to check some expression inside of function, throw error if exp is not true */
94 #ifndef NDEBUG
95   #define HXT_ASSERT_MSG(exp, ...)                                          \
96     do {                                                                    \
97       if (!(exp)) {                                                         \
98         HXT_ERROR_MSG(HXT_STATUS_ASSERTION_FAILED, ## __VA_ARGS__ );        \
99         abort();                                                            \
100     }                                                                       \
101   } while(0)
102   #define HXT_ASSERT(exp)             HXT_ASSERT_MSG(exp, "assertion (" #exp ") Failed")
103 #else
104   #define HXT_ASSERT_MSG(exp, ...)
105   #define HXT_ASSERT(exp)
106 #endif
107 
108 
109 const char*  hxtGetStatusString(HXTStatus status);
110 
111 
112 /* MESSAGE */
113 typedef struct {
114   /* the message content */
115   const char* string; // lifetime = time of callback function
116 
117   /* information about the location of the code which sent the message */
118   const char* func;   // lifetime = forever
119   const char* file;   // lifetime = forever
120   const char* line;   // lifetime = forever
121   int threadId;      // the thread which sent the message
122   int numThreads;    // the number of threads
123 
124   enum{
125     HXT_MSGLEVEL_INFO     = 0,
126     HXT_MSGLEVEL_DEBUG    = 1,
127     HXT_MSGLEVEL_WARNING  = 2,
128     HXT_MSGLEVEL_ERROR    = 3,
129     HXT_MSGLEVEL_TRACE    = 4
130   } level;
131 } HXTMessage;
132 
133 
134 /* MESSAGE AND ERROR HANDLING */
135 HXTStatus  hxtSetMessageCallback (HXTStatus (*hxtMsgCallback)(HXTMessage* msg));
136 
137 HXTStatus  hxtMessageInfo       ( const char* func, const char* file, const char* line, const char *fmt, ...);
138 HXTStatus  hxtMessageWarning    ( const char* func, const char* file, const char* line, const char *fmt, ...);
139 HXTStatus  hxtMessageError      ( HXTStatus status, const char* func, const char* file, const char* line, const char *fmt, ...);
140 
141 #ifndef NDEBUG
142 HXTStatus  hxtMessageTraceError ( HXTStatus status, const char* func, const char* file, const char* line, const char *fmt, ...);
143 #endif
144 
145 #ifdef __cplusplus
146 }
147 #endif
148 
149 #endif
150