Predator  [unstable] git snapshot
cl_msg.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Kamil Dudka <kdudka@redhat.com>
3  *
4  * This file is part of predator.
5  *
6  * predator is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * any later version.
10  *
11  * predator is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with predator. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef H_GUARD_CL_MSG_H
21 #define H_GUARD_CL_MSG_H
22 
23 /**
24  * @file cl_msg.hh
25  * Macros for emitting @b error, @b warning, @b info and @b debug messages
26  * through the code listener interface
27  */
28 
29 #include "code_listener.h"
30 
31 #include <cstdlib> // needed for abort()
32 #include <sstream> // needed for std::ostringstream
33 #include <string> // needed for operator<<(std::ostream, std::string)
34 
35 /**
36  * emit a fatal error message and ask the code listener peer to shoot down the
37  * process
38  * @param msg a message to emit before the process dies, it must be a string
39  * literal
40  */
41 #define CL_DIE(msg) do { \
42  cl_die("fatal error: " msg "\n"); \
43  abort(); \
44 } while (0)
45 
46 /**
47  * standard output stream wrapper on top of the code listener interface
48  * @param fnc a function used to emit the message - cl_debug(), cl_warn(),
49  * cl_error() or cl_note()
50  * @param to_stream whatever you need to stream out. Stuff with defined
51  * operator<<(std::ostream, ...) is a viable start.
52  */
53 #define CL_MSG_STREAM(fnc, to_stream) do { \
54  if ((cl_debug == (fnc)) && !cl_debug_level()) \
55  break; \
56  \
57  std::ostringstream str; \
58  str << to_stream; \
59  fnc(str.str().c_str()); \
60 } while (0)
61 
62 /**
63  * wrapper around CL_MSG_STREAM decorating the message by @b internal location
64  * info
65  *
66  * see cl_msg.hh::CL_MSG_STREAM for details
67  */
68 #define CL_MSG_STREAM_INTERNAL(fnc, to_stream) \
69  CL_MSG_STREAM(fnc, __FILE__ << ":" << __LINE__ \
70  << ": " << to_stream << " [internal location]")
71 
72 /**
73  * emit a @b debug message with @b internal location info
74  */
75 #define CL_DEBUG(to_stream) \
76  CL_MSG_STREAM_INTERNAL(cl_debug, "debug: " << to_stream)
77 
78 /**
79  * emit a @b warning message with @b internal location info
80  */
81 #define CL_WARN(to_stream) \
82  CL_MSG_STREAM_INTERNAL(cl_warn, "warning: " << to_stream)
83 
84 /**
85  * emit an @b error message with @b internal location info
86  */
87 #define CL_ERROR(to_stream) \
88  CL_MSG_STREAM_INTERNAL(cl_error, "error: " << to_stream)
89 
90 /**
91  * emit a @b note message with @b internal location info
92  */
93 #define CL_NOTE(to_stream) \
94  CL_MSG_STREAM_INTERNAL(cl_note, "note: " << to_stream)
95 
96 /**
97  * emit a @b debug message using the given location info
98  * @param loc location info to use
99  * @param what whatever you need to stream out
100  */
101 #define CL_DEBUG_MSG(loc, what) \
102  CL_MSG_STREAM(cl_debug, *(loc) << "debug: " << what)
103 
104 /**
105  * emit a @b warning message using the given location info
106  * @param loc location info to use
107  * @param what whatever you need to stream out
108  */
109 #define CL_WARN_MSG(loc, what) \
110  CL_MSG_STREAM(cl_warn, *(loc) << "warning: " << what)
111 
112 /**
113  * emit an @b error message using the given location info
114  * @param loc location info to use
115  * @param what whatever you need to stream out
116  */
117 #define CL_ERROR_MSG(loc, what) \
118  CL_MSG_STREAM(cl_error, *(loc) << "error: " << what)
119 
120 /**
121  * emit a @b note message using the given location info
122  * @param loc location info to use
123  * @param what whatever you need to stream out
124  */
125 #define CL_NOTE_MSG(loc, what) \
126  CL_MSG_STREAM(cl_note, *(loc) << "note: " << what)
127 
128 /// same as CL_DEBUG, but compares the current debug level with the given one
129 #define CL_DEBUG_AT(level, what) do { \
130  if (cl_debug_level() < (level)) \
131  break; \
132  \
133  CL_DEBUG(what); \
134 } while (0)
135 
136 /// same as CL_DEBUG_MSG, but compares current debug level with the given one
137 #define CL_DEBUG_MSG_AT(level, loc, what) do { \
138  if (cl_debug_level() < (level)) \
139  break; \
140  \
141  CL_DEBUG_MSG(loc, what); \
142 } while (0)
143 
144 inline std::ostream& operator<<(std::ostream &str, const struct cl_loc &loc)
145 {
146  if (!&loc || !loc.file) {
147  str << "<unknown location>: ";
148  return str;
149  }
150 
151  // print file
152  str << loc.file << ":";
153 
154  if (0 < loc.line) {
155  // print lineno
156  str << loc.line << ":";
157 
158  if (0 < loc.column)
159  // print column
160  str << loc.column << ":";
161  }
162 
163  str << " ";
164  return str;
165 }
166 
167 /**
168  * emit raw debug message
169  *
170  * @param[in] msg The message to be emitted
171  */
172 void cl_debug(const char *msg);
173 
174 /**
175  * emit raw warning message
176  *
177  * @param[in] msg The message to be emitted
178  */
179 void cl_warn(const char *msg);
180 
181 /**
182  * emit raw error message
183  *
184  * @param[in] msg The message to be emitted
185  */
186 void cl_error(const char *msg);
187 
188 /**
189  * emit raw note message
190  *
191  * @param[in] msg The message to be emitted
192  */
193 void cl_note(const char *msg);
194 
195 /**
196  * emit raw fatal error and ask cl peer to shoot down the process
197  *
198  * @param[in] msg The message to be emitted
199  */
200 void cl_die(const char *msg);
201 
202 /**
203  * current debugging level
204  *
205  * @returns Current debugging level
206  */
207 int cl_debug_level(void);
208 
209 #endif /* H_GUARD_CL_MSG_H */