]> Creatis software - bbtk.git/blob - kernel/src/bbtkMessageManager.h
51d7da68c13c1fc0ae5198bcd2c6407b1e136586
[bbtk.git] / kernel / src / bbtkMessageManager.h
1 /*
2  # ---------------------------------------------------------------------
3  #
4  # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5  #                        pour la SantÈ)
6  # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7  # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8  # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9  #
10  #  This software is governed by the CeCILL-B license under French law and
11  #  abiding by the rules of distribution of free software. You can  use,
12  #  modify and/ or redistribute the software under the terms of the CeCILL-B
13  #  license as circulated by CEA, CNRS and INRIA at the following URL
14  #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15  #  or in the file LICENSE.txt.
16  #
17  #  As a counterpart to the access to the source code and  rights to copy,
18  #  modify and redistribute granted by the license, users are provided only
19  #  with a limited warranty  and the software's author,  the holder of the
20  #  economic rights,  and the successive licensors  have only  limited
21  #  liability.
22  #
23  #  The fact that you are presently reading this means that you have had
24  #  knowledge of the CeCILL-B license and that you accept its terms.
25  # ------------------------------------------------------------------------ */
26
27
28 /*=========================================================================
29   Program:   bbtk
30   Module:    $RCSfile: bbtkMessageManager.h,v $
31   Language:  C++
32   Date:      $Date: 2012/11/16 08:49:01 $
33   Version:   $Revision: 1.10 $
34 =========================================================================*/
35
36
37
38
39
40 /*! \file
41  
42   \brief Class bbtkMessageManager and Macros for outputing messages in bbtk
43
44   There are 4 kinds of messages :
45   - Messages (normal messages)
46   - Debug messages (not compiled in release)
47   - Warnings 
48   - Errors
49   There are also "types" of messages which are strings which identify the nature of the message 
50   (for example : "Kernel" messages are generated by the core classes of the library, there can be a type of 
51   message for each type of Node, and so on...)
52   A type of message must be declared by registering it into the MessageManager. This is done by a line like :
53   bbtk::MessageManager::RegisterMessageType("Kernel","Messages generated by the core classes of the library",5);
54   where : 
55   -The first string is the type of the message (the category which will be used to generate a message of this type)
56   -The second string is help string
57   -The integer is the initial level for the messages of this type (see below).
58   
59   To generate a message of a known type then use one of the macros :
60   bbtkMessage, bbtkDebugMessage, bbtkWarning, bbtkError or their variants.
61
62   example :
63
64   bbtkMessage("Kernel",4,"problem with "<<GetName()<<bbtkendl);
65
66   will push the 3rd argument in std::cout if the message level of "Kernel" messages is greater or equal to 4.
67   which means that it generates a message of level 4 (0 : very important/always displayed ... 9 : deep debug message).
68
69   At run time, one is able to change the level of the messages displayed by using a command like :
70   
71   bbtk::MessageManager::SetMessageLevel("Kernel",5); 
72   
73   which tells the manager to display all Kernel messages of level up to 5.
74
75   Variants :
76
77   bbtk*Cont : continues a previous bbtkMessage on the same line (without rewriting the type and level)
78   bbtk*Inc / Dec : displays the message and then increments/decrement the messages tabulation 
79
80 */
81   //===========================================================
82   /**
83      \class bbtk::MessageManager
84      \brief Manages the messages displayed by bbtk
85   */
86
87
88 #ifndef __bbtkMessageManager_h__
89 #define __bbtkMessageManager_h__
90
91 // The do { } while(0) statement in macros is made to "swallow the semicolon" 
92 // see http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon
93
94 #include "bbtkSystem.h"
95 #include "bbtkRTTI.h"
96
97 #include <string>
98 #include <map>
99 #include <iostream>
100 #include <sstream>
101
102 // Comment out these symbols to prevent compilation 
103 //#define BBTK_COMPILE_MESSAGES
104 //#define BBTK_COMPILE_DEBUG_MESSAGES
105 //#define BBTK_COMPILE_WARNING_MESSAGES
106 //#define BBTK_COMPILE_ERROR_MESSAGES
107
108
109 #define bbtkOnMessageLevel(key,value)                   \
110   int __bbtkOnMessageLevelVariable =                    \
111     bbtk::MessageManager::GetMessageLevel(key);         \
112   if ( __bbtkOnMessageLevelVariable<0)                  \
113     {                                                   \
114       bbtkWarning("message type '"<<key<<"' unknown");  \
115     }                                                   \
116   else if (value<= __bbtkOnMessageLevelVariable) 
117
118 #define BBTK_PREPEND_MESSAGE_WITH_CODE
119 #ifdef BBTK_PREPEND_MESSAGE_WITH_CODE
120 #define bbtkMessageCode(key,value)                      \
121   bbtk::MessageManager::FormatKey(key,value) 
122 #else 
123 #define bbtkMessageCode(key,value) ""
124 #endif 
125
126 #ifdef BBTK_PREPEND_MESSAGE_WITH_TAB
127 #define bbtkMessageTab                          \
128   bbtk::MessageManager::GetTab()
129 #else 
130 #define bbtkMessageTab ""
131 #endif
132
133 //#define BBTK_PREPEND_MESSAGE_WITH_SPACE
134 #ifdef BBTK_PREPEND_MESSAGE_WITH_SPACE
135 #define bbtkMessageSpace(value)                 \
136   bbtk::MessageManager::GetSpace(value)
137 #else 
138 #define bbtkMessageSpace(value) ""
139 #endif
140  
141
142 //===========================================================
143 #ifdef BBTK_COMPILE_MESSAGES
144
145 // Macro for messages
146 #define bbtkMessage(key,value,MESSAGE)                  \
147   do {                                                  \
148     bbtkOnMessageLevel(key,value)                       \
149       {                                                 \
150         std::cout << bbtkMessageCode(key,value)         \
151                   << bbtkMessageTab                     \
152                   << bbtkMessageSpace(value)            \
153                   << MESSAGE;                           \
154       }                                                 \
155   }                                                     \
156   while (0)
157
158 // Macro for continuing a message (when one wants to split the macro
159 // call into multiple lines)
160 #define bbtkMessageCont(key,value,MESSAGE)      \
161   do                                            \
162     {                                           \
163       bbtkOnMessageLevel(key,value)             \
164         {                                       \
165           std::cout << MESSAGE;                 \
166         }                                       \
167     }                                           \
168   while (0)
169
170 #define bbtkMessageInc(key,value,MESSAGE)               \
171   do                                                    \
172     {                                                   \
173       bbtkOnMessageLevel(key,value)                     \
174         {                                               \
175           std::cout << bbtkMessageCode(key,value)               \
176                     << bbtkMessageTab                   \
177                     << bbtkMessageSpace(value)          \
178                     << MESSAGE;                         \
179           bbtk::MessageManager::IncTab();               \
180         }                                               \
181     }                                                   \
182   while (0)
183
184 #define bbtkMessageDec(key,value,MESSAGE)               \
185   do                                                    \
186     {                                                   \
187       bbtkOnMessageLevel(key,value)                     \
188         {                                               \
189           bbtk::MessageManager::DecTab();               \
190           std::cout << bbtkMessageCode(key,value)               \
191                     << bbtkMessageTab                   \
192                     << bbtkMessageSpace(value)          \
193                     << MESSAGE;                         \
194         }                                               \
195     }                                                   \
196   while (0)
197
198 #define bbtkDecTab(key,value)                   \
199   do                                            \
200     {                                           \
201       bbtkOnMessageLevel(key,value)             \
202         {                                       \
203           bbtk::MessageManager::DecTab();       \
204         }                                       \
205     }                                           \
206   while (0)
207
208 #define bbtkIncTab(key,value)                   \
209   do                                            \
210     {                                           \
211       bbtkOnMessageLevel(key,value)             \
212         {                                       \
213           bbtk::MessageManager::IncTab();       \
214         }                                       \
215     }                                           \
216   while (0)
217
218 #define bbtkResetTab()                          \
219   do                                            \
220     {                                           \
221       bbtk::MessageManager::ResetTab();         \
222     }                                           \
223   while (0)
224
225 #else
226 #define bbtkMessage(key,value,MESSAGE)
227 #define bbtkMessageInc(key,value,MESSAGE)
228 #define bbtkMessageDec(key,value,MESSAGE)
229 #define bbtkMessageCont(key,value,MESSAGE)
230 #define bbtkDecTab(key,value)
231 #define bbtkIncTab(key,value)
232 #define bbtkResetTab()
233 #endif
234 //===========================================================
235
236
237
238 //===========================================================
239 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
240
241 // Macro for debug messages
242 #define bbtkDebugMessage(key,value,MESSAGE)             \
243   do                                                    \
244     {                                                   \
245       bbtkOnMessageLevel(key,value)                     \
246         {                                               \
247           std::cout << bbtkMessageCode(key,value)               \
248                     << bbtkMessageTab                   \
249                     << bbtkMessageSpace(value)          \
250                     << MESSAGE;                         \
251         }                                               \
252     }                                                   \
253   while (0)
254
255 // Macro for continuing a debug message (when one wants to split the
256 // macro call into multiple lines)
257 #define bbtkDebugMessageCont(key,value,MESSAGE) \
258   do                                            \
259     {                                           \
260       bbtkOnMessageLevel(key,value)             \
261         {                                       \
262           std::cout << MESSAGE;                 \
263         }                                       \
264     }                                           \
265   while (0)
266
267 #define bbtkDebugMessageInc(key,value,MESSAGE)          \
268   do                                                    \
269     {                                                   \
270       bbtkOnMessageLevel(key,value)                     \
271         {                                               \
272           std::cout << bbtkMessageCode(key,value)               \
273                     << bbtkMessageTab                   \
274                     << bbtkMessageSpace(value)          \
275                     << MESSAGE;                         \
276           bbtk::MessageManager::IncTab();               \
277         }                                               \
278     }                                                   \
279   while (0)
280
281 #define bbtkDebugMessageDec(key,value,MESSAGE)          \
282   do                                                    \
283     {                                                   \
284       bbtkOnMessageLevel(key,value)                     \
285         {                                               \
286           bbtk::MessageManager::DecTab();               \
287           std::cout << bbtkMessageCode(key,value)       \
288                     << bbtkMessageTab                   \
289                     << bbtkMessageSpace(value)          \
290                     << MESSAGE;                         \
291         }                                               \
292     }                                                   \
293   while (0)
294
295 #define bbtkDebugDecTab(key,value)              \
296   do                                            \
297     {                                           \
298       bbtkOnMessageLevel(key,value)             \
299         {                                       \
300           bbtk::MessageManager::DecTab();       \
301         }                                       \
302     }                                           \
303   while (0)
304
305 #define bbtkDebugIncTab(key,value)              \
306     do                                          \
307       {                                         \
308         bbtkOnMessageLevel(key,value)           \
309           {                                     \
310             bbtk::MessageManager::IncTab();     \
311           }                                     \
312       }                                         \
313     while (0)
314     
315 #define bbtkDebugResetTab()                     \
316     do                                          \
317       {                                         \
318         bbtk::MessageManager::ResetTab();       \
319       }                                         \
320     while (0)
321
322 #else
323 #define bbtkDebugMessage(key,value,MESSAGE) 
324 #define bbtkDebugMessageCont(key,value,MESSAGE) 
325 #define bbtkDebugMessageInc(key,value,MESSAGE)
326 #define bbtkDebugMessageDec(key,value,MESSAGE) 
327 #define bbtkDebugDecTab(key,value)
328 #define bbtkDebugIncTab(key,value)
329 #endif
330 //===========================================================
331
332 //===========================================================
333 #ifdef BBTK_COMPILE_WARNING_MESSAGES
334 #define bbtkWarning(MESSAGE)                                            \
335   do                                                                    \
336     {                                                                   \
337       int lev = bbtk::MessageManager::GetMessageLevel("Warning");       \
338       if (lev >0)                                                       \
339         {                                                               \
340           std::cerr << "!! WARNING !! " << MESSAGE << std::endl;        \
341           if (lev >1)                                                   \
342             {                                                           \
343               std::cerr << "!! WARNING !! In file '"<<__FILE__          \
344                         <<"' ; Line "<<__LINE__<<std::endl;             \
345             }                                                           \
346         }                                                               \
347     }                                                                   \
348   while (0) 
349
350 #else
351 #define bbtkWarning(MESSAGE) 
352 #endif
353 //===========================================================
354
355
356 //===========================================================
357 #ifdef BBTK_COMPILE_ERROR_MESSAGES
358 //#include "bbtkWx.h"
359 #define bbtkError(MESSAGE)                              \
360   do                                                    \
361     {                                                   \
362       std::ostringstream s;                             \
363       s << MESSAGE;                                     \
364       std::ostringstream f;                             \
365       f << __FILE__ << " (l."<<__LINE__<<")";           \
366       bbtk::Exception e( BBTK_GET_CURRENT_OBJECT_NAME,  \
367                         f.str(),                        \
368                         s.str());                       \
369       throw e;                                          \
370     }                                                   \
371   while (0) 
372
373 #define bbtkGlobalError(MESSAGE)                                \
374   do                                                    \
375     {                                                   \
376       std::ostringstream s;                             \
377       s << MESSAGE;                                     \
378       std::ostringstream f;                             \
379       f << __FILE__ << " (l."<<__LINE__<<")";           \
380       bbtk::Exception e( "global scope",                \
381                         f.str(),                        \
382                         s.str());                       \
383       throw e;                                          \
384     }                                                   \
385   while (0) 
386
387 #define BBTK_INTERNAL_ERROR_MESSAGE \
388   "\n\n***********************************************\n**** THIS IS AN INTERNAL ERROR TO BBTK     ****\n**** Please send a full bug report to :    ****\n****  bbtk-developers@creatis.insa-lyon.fr ****\n***********************************************\n\n"
389
390 #define bbtkInternalError(MESSAGE)                      \
391   do                                                    \
392     {                                                   \
393       std::ostringstream s;                             \
394       s << MESSAGE << BBTK_INTERNAL_ERROR_MESSAGE;      \
395       std::ostringstream f;                             \
396       f << __FILE__ << " (l."<<__LINE__<<")";           \
397       bbtk::Exception e( BBTK_GET_CURRENT_OBJECT_NAME,  \
398                          f.str(),                       \
399                          s.str());                      \
400       throw e;                                          \
401     }                                                   \
402   while (0) 
403
404 #else
405 #define bbtkError(MESSAGE)
406 #define bbtkGlobalError(MESSAGE)
407 #define bbtkInternalError(MESSAGE)
408 #endif
409 //===========================================================
410
411 //===========================================================
412 #define bbtkendl std::endl
413 //===========================================================
414
415
416 namespace bbtk 
417 {
418
419   class BBTK_EXPORT MessageManager
420   {
421   public:
422     ///
423     MessageManager();
424     ///
425     ~MessageManager();
426     ///
427     static MessageManager* GetInstance();
428     ///
429     static bool RegisterMessageType(std::string key, 
430                                     std::string help,
431                                     unsigned char default_level = 9);
432     ///
433     static void SetMessageLevel(std::string key, unsigned char level);
434     ///
435     static int GetMessageLevel(std::string key);
436     ///  
437     static std::string& GetTab() { static std::string s; return s; }
438     ///
439     static std::string GetSpace(int n) { 
440       std::string s; s.insert(0,"                ",n); return s; }
441     ///
442     static void IncTab() { GetTab() += std::string(" "); }
443     ///
444     static void DecTab() { GetTab() = GetTab().substr(0,GetTab().length()-1); }
445     ///
446     static void ResetTab() { GetTab() = std::string(""); }
447     ///
448     static void PrintInfo();
449
450     static std::string FormatKey(const std::string& key, int value);
451
452   private:
453     std::map<std::string,int> mMessageLevel;
454     std::map<std::string,std::string> mMessageHelp;  
455     unsigned int mMaxMessageLength;
456   };
457   //===========================================================
458   
459 }
460
461 #include "bbtkException.h"
462
463 #endif