1 /*****************************************************************************
2  * Author:   Valient Gough <vgough@pobox.com>
3  *
4  *****************************************************************************
5  * Copyright (c) 2002-2004, Valient Gough
6  *
7  * This library is free software; you can distribute it and/or modify it under
8  * the terms of the GNU Lesser General Public License (LGPL), as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at your
10  * option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the LGPL in the file COPYING for more
15  * details.
16  *
17  */
18 
19 /*! @def _rMessageDef
20   Defines a static RLogPublisher and points it to the registration function for
21   the first call.
22   @internal
23 */
24 #define _rMessageDef(ID, COMPONENT) \
25   static rlog::PublishLoc ID RLOG_SECTION = {& ID ## _enabled, \
26       &rlog::RLog_Register, 0, STR(COMPONENT), __FILE__, \
27       __FUNCTION__, __LINE__, 0};
28 
29 /*! @def _rMessageCall
30   Checks if the RLogPublisher is enabled and publishes the message if so.
31   @internal
32 */
33 #if HAVE_PRINTF_FP || !HAVE_PRINTF_ATTR
34 #  define _rMessageCall(ID, COMPONENT, CHANNEL, ...) \
35   static bool ID ## _enabled = true; \
36   if(unlikely(ID ## _enabled)) \
37   { \
38     _rMessageDef(ID, COMPONENT) \
39     (*ID.publish)( &ID, CHANNEL, ##__VA_ARGS__ ); \
40   }
41 #else // no PRINTF attributes..
42 # define _rMessageCall(ID, COMPONENT, CHANNEL, ...) \
43   static bool ID ## _enabled = true; \
44   if(unlikely(ID ## _enabled))  \
45   { \
46     _rMessageDef(ID, COMPONENT) \
47     (*ID.publish)( &ID, CHANNEL, ##__VA_ARGS__ ); \
48     rlog::__checkArgs( 0, ##__VA_ARGS__ ); \
49   }
50 #endif
51 
52 /*! @def _rMessage(ID, CHANNEL, ... )
53 
54   Combines the publisher definition (_rMessageDef) and invokation
55   (_rMessageCall)
56 
57   enclose in do{}while(0) to insure that it acts as a single statement even if
58   placed in various if/else constructs..
59   @internal
60 */
61 #define _rMessage(ID, CHANNEL, ... ) \
62   do { _rMessageCall(ID, RLOG_COMPONENT, CHANNEL, ##__VA_ARGS__ ) } while(0)
63 
64 /*! @addtogroup RLogMacros
65   These macros are the primary interface for logging messages:
66   - rDebug(format, ...)
67   - rInfo(format, ...)
68   - rWarning(format, ...)
69   - rError(format, ...)
70   - rLog(channel, format, ...)
71   - rAssert( condition )
72   @{
73 */
74 
75 /*! @def rDebug(format, ...)
76     @brief Log a message to the "debug" channel.  Takes printf style arguments.
77 
78     Format is ala printf, eg:
79     @code
80     rDebug("I'm sorry %s, I can't do %s", name, request);
81     @endcode
82 
83     When using a recent GNU compiler, it should automatically detect format
84     string / argument mismatch just like it would with printf.
85 
86     Note that unless there are subscribers to this message, it will do nothing.
87 */
88 #define rDebug(...) \
89   _rMessage( LOGID, rlog::_RLDebugChannel, ##__VA_ARGS__ )
90 
91 /*! @def rInfo(format, ...)
92     @brief Log a message to the "debug" channel.  Takes printf style arguments.
93 
94     Format is ala printf, eg:
95     @code
96     rInfo("I'm sorry %s, I can't do %s", name, request);
97     @endcode
98 
99     When using a recent GNU compiler, it should automatically detect format
100     string / argument mismatch just like it would with printf.
101 
102     Note that unless there are subscribers to this message, it will do nothing.
103 */
104 #define rInfo(...) \
105   _rMessage( LOGID, rlog::_RLInfoChannel, ##__VA_ARGS__ )
106 
107 /*! @def rWarning(format, ...)
108     @brief Log a message to the "warning" channel.  Takes printf style
109     arguments.
110 
111     Output a warning message - meant to indicate that something doesn't seem
112     right.
113 
114     Format is ala printf, eg:
115     @code
116     rWarning("passed %i, expected %i, continuing", foo, bar);
117     @endcode
118 
119     When using a recent GNU compiler, it should automatically detect format
120     string / argument mismatch just like it would with printf.
121 
122     Note that unless there are subscribers to this message, it will do nothing.
123 */
124 #define rWarning(...) \
125   _rMessage( LOGID, rlog::_RLWarningChannel, ##__VA_ARGS__ )
126 
127 /*! @def rError(...)
128     @brief Log a message to the "error" channel. Takes printf style arguments.
129 
130     An error indicates that something has definately gone wrong.
131 
132     Format is ala printf, eg:
133     @code
134     rError("bad input %s, aborting request", input);
135     @endcode
136 
137     When using a recent GNU compiler, it should automatically detect format
138     string / argument mismatch just like it would with printf.
139 
140     Note that unless there are subscribers to this message, it will do nothing.
141 */
142 #define rError(...) \
143   _rMessage( LOGID, rlog::_RLErrorChannel, ##__VA_ARGS__ )
144 
145 /*! @def rLog(channel,format,...)
146     @brief Log a message to a user defined channel. Takes a channel and printf
147     style arguments.
148 
149     An error indicates that something has definately gone wrong.
150 
151     Format is ala printf, eg:
152     @code
153     static RLogChannel * MyChannel = RLOG_CHANNEL( "debug/mine" );
154     rLog(MyChannel, "happy happy, joy joy");
155     @endcode
156 
157     When using a recent GNU compiler, it should automatically detect format
158     string / argument mismatch just like it would with printf.
159 
160     Note that unless there are subscribers to this message, it will do nothing.
161 */
162 #define rLog(channel, ...) \
163   _rMessage( LOGID, channel, ##__VA_ARGS__ )
164 
165 
166