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