]> git.saurik.com Git - apt.git/blame - apt-pkg/contrib/error.h
fix resource leak (thanks coverity)
[apt.git] / apt-pkg / contrib / error.h
CommitLineData
578bfd0a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
233b185f 3// $Id: error.h,v 1.8 2001/05/07 05:06:52 jgg Exp $
578bfd0a
AL
4/* ######################################################################
5
6 Global Erorr Class - Global error mechanism
7
8 This class has a single global instance. When a function needs to
9 generate an error condition, such as a read error, it calls a member
10 in this class to add the error to a stack of errors.
11
12 By using a stack the problem with a scheme like errno is removed and
13 it allows a very detailed account of what went wrong to be transmitted
14 to the UI for display. (Errno has problems because each function sets
15 errno to 0 if it didn't have an error thus eraseing erno in the process
16 of cleanup)
17
18 Several predefined error generators are provided to handle common
19 things like errno. The general idea is that all methods return a bool.
20 If the bool is true then things are OK, if it is false then things
21 should start being undone and the stack should unwind under program
22 control.
23
24 A Warning should not force the return of false. Things did not fail, but
25 they might have had unexpected problems. Errors are stored in a FIFO
26 so Pop will return the first item..
27
28 I have some thoughts about extending this into a more general UI<->
29 Engine interface, ie allowing the Engine to say 'The disk is full' in
30 a dialog that says 'Panic' and 'Retry'.. The error generator functions
31 like errno, Warning and Error return false always so this is normal:
32 if (open(..))
33 return _error->Errno(..);
34
35 This source is placed in the Public Domain, do with it what you will
36 It was originally written by Jason Gunthorpe.
37
38 ##################################################################### */
39 /*}}}*/
578bfd0a
AL
40#ifndef PKGLIB_ERROR_H
41#define PKGLIB_ERROR_H
42
2893f7b5 43#include <apt-pkg/macros.h>
13500573 44
98ee7cd3
DK
45#include <iostream>
46#include <list>
578bfd0a 47#include <string>
578bfd0a 48
98ee7cd3
DK
49#include <stdarg.h>
50
51class GlobalError /*{{{*/
578bfd0a 52{
98ee7cd3
DK
53public: /*{{{*/
54 /** \brief a message can have one of following severity */
55 enum MsgType {
56 /** \brief Message will be printed instantly as it is likely that
57 this error will lead to a complete crash */
58 FATAL = 40,
59 /** \brief An error does hinder the correct execution and should be corrected */
60 ERROR = 30,
61 /** \brief indicates problem that can lead to errors later on */
62 WARNING = 20,
63 /** \brief deprecation warnings, old fallback behavior, … */
64 NOTICE = 10,
65 /** \brief for developers only in areas it is hard to print something directly */
66 DEBUG = 0
67 };
578bfd0a 68
98ee7cd3
DK
69 /** \brief add a fatal error message with errno to the list
70 *
71 * \param Function name of the function generating the error
72 * \param Description format string for the error message
73 *
74 * \return \b false
75 */
76 bool FatalE(const char *Function,const char *Description,...) __like_printf(3) __cold;
578bfd0a 77
98ee7cd3
DK
78 /** \brief add an Error message with errno to the list
79 *
80 * \param Function name of the function generating the error
81 * \param Description format string for the error message
82 *
83 * \return \b false
84 */
85 bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold;
578bfd0a 86
98ee7cd3
DK
87 /** \brief add a warning message with errno to the list
88 *
89 * A warning should be considered less severe than an error and
90 * may be ignored by the client.
91 *
92 * \param Function Name of the function generates the warning.
93 * \param Description Format string for the warning message.
94 *
95 * \return \b false
96 */
97 bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold;
578bfd0a 98
98ee7cd3
DK
99 /** \brief add a notice message with errno to the list
100 *
101 * \param Function name of the function generating the error
102 * \param Description format string for the error message
103 *
104 * \return \b false
105 */
106 bool NoticeE(const char *Function,const char *Description,...) __like_printf(3) __cold;
107
108 /** \brief add a debug message with errno to the list
109 *
110 * \param Function name of the function generating the error
111 * \param Description format string for the error message
112 *
113 * \return \b false
114 */
115 bool DebugE(const char *Function,const char *Description,...) __like_printf(3) __cold;
116
cd7bbc47
DK
117 /** \brief adds an errno message with the given type
118 *
119 * \param type of the error message
120 * \param Function which failed
121 * \param Description of the error
122 */
123 bool InsertErrno(MsgType const &type, const char* Function,
124 const char* Description,...) __like_printf(4) __cold;
125
c7873955
DK
126 /** \brief adds an errno message with the given type
127 *
128 * args needs to be initialized with va_start and terminated
129 * with va_end by the caller. msgSize is also an out-parameter
130 * in case the msgSize was not enough to store the complete message.
131 *
132 * \param type of the error message
133 * \param Function which failed
134 * \param Description is the format string for args
135 * \param args list from a printf-like function
136 * \param errsv is the errno the error is for
137 * \param msgSize is the size of the char[] used to store message
138 * \return true if the message was added, false if not - the caller
139 * should call this method again in that case
140 */
141 bool InsertErrno(MsgType type, const char* Function,
142 const char* Description, va_list &args,
143 int const errsv, size_t &msgSize);
144
98ee7cd3
DK
145 /** \brief add an fatal error message to the list
146 *
147 * Most of the stuff we consider as "error" is also "fatal" for
148 * the user as the application will not have the expected result,
149 * but a fatal message here means that it gets printed directly
150 * to stderr in addiction to adding it to the list as the error
151 * leads sometimes to crashes and a maybe duplicated message
152 * is better than "Segfault" as the only displayed text
153 *
154 * \param Description Format string for the fatal error message.
155 *
156 * \return \b false
157 */
158 bool Fatal(const char *Description,...) __like_printf(2) __cold;
159
160 /** \brief add an Error message to the list
161 *
162 * \param Description Format string for the error message.
163 *
164 * \return \b false
165 */
166 bool Error(const char *Description,...) __like_printf(2) __cold;
167
168 /** \brief add a warning message to the list
169 *
170 * A warning should be considered less severe than an error and
171 * may be ignored by the client.
172 *
173 * \param Description Format string for the message
174 *
175 * \return \b false
176 */
177 bool Warning(const char *Description,...) __like_printf(2) __cold;
178
179 /** \brief add a notice message to the list
180 *
181 * A notice should be considered less severe than an error or a
182 * warning and can be ignored by the client without further problems
183 * for some times, but he should consider fixing the problem.
184 * This error type can be used for e.g. deprecation warnings of options.
185 *
186 * \param Description Format string for the message
187 *
188 * \return \b false
189 */
190 bool Notice(const char *Description,...) __like_printf(2) __cold;
191
192 /** \brief add a debug message to the list
193 *
194 * \param Description Format string for the message
195 *
196 * \return \b false
197 */
198 bool Debug(const char *Description,...) __like_printf(2) __cold;
199
cd7bbc47
DK
200 /** \brief adds an error message with the given type
201 *
202 * \param type of the error message
203 * \param Description of the error
204 */
205 bool Insert(MsgType const &type, const char* Description,...) __like_printf(3) __cold;
206
c7873955
DK
207 /** \brief adds an error message with the given type
208 *
209 * args needs to be initialized with va_start and terminated
210 * with va_end by the caller. msgSize is also an out-parameter
211 * in case the msgSize was not enough to store the complete message.
212 *
213 * \param type of the error message
214 * \param Description is the format string for args
215 * \param args list from a printf-like function
216 * \param msgSize is the size of the char[] used to store message
217 * \return true if the message was added, false if not - the caller
218 * should call this method again in that case
219 */
220 bool Insert(MsgType type, const char* Description,
221 va_list &args, size_t &msgSize) __cold;
222
98ee7cd3
DK
223 /** \brief is an error in the list?
224 *
225 * \return \b true if an error is included in the list, \b false otherwise
226 */
227 inline bool PendingError() const {return PendingFlag;};
228
229 /** \brief is the list empty?
230 *
231 * The default checks if the list is empty or contains only notices,
232 * if you want to check if also no notices happend set the parameter
233 * flag to \b false.
234 *
235 * \param WithoutNotice does notices count, default is \b true, so no
236 *
237 * \return \b true if an the list is empty, \b false otherwise
238 */
239 bool empty(MsgType const &trashhold = WARNING) const;
240
241 /** \brief returns and removes the first (or last) message in the list
242 *
243 * \param[out] Text message of the first/last item
244 *
245 * \return \b true if the message was an error, \b false otherwise
246 */
247 bool PopMessage(std::string &Text);
248
249 /** \brief clears the list of messages */
250 void Discard();
251
252 /** \brief outputs the list of messages to the given stream
253 *
254 * Note that all messages are discarded, also the notices
255 * displayed or not.
256 *
257 * \param[out] out output stream to write the messages in
12be8a62
MV
258 * \param threshold minimim level considered
259 * \param mergeStack
98ee7cd3 260 */
12be8a62 261 void DumpErrors(std::ostream &out, MsgType const &threshold = WARNING,
c4ba7c44 262 bool const &mergeStack = true);
98ee7cd3
DK
263
264 /** \brief dumps the list of messages to std::cerr
265 *
266 * Note that all messages are discarded, also the notices
267 * displayed or not.
268 *
12be8a62 269 * \param threshold minimum level printed
98ee7cd3 270 */
ca0d389c 271 void inline DumpErrors(MsgType const &threshold) {
12be8a62 272 DumpErrors(std::cerr, threshold);
98ee7cd3
DK
273 }
274
ca0d389c
MV
275 // mvo: we do this instead of using a default parameter in the
276 // previous declaration to avoid a (subtle) API break for
277 // e.g. sigc++ and mem_fun0
278 /** \brief dumps the messages of type WARNING or higher to std::cerr
279 *
280 * Note that all messages are discarded, displayed or not.
281 *
282 */
283 void inline DumpErrors() {
284 DumpErrors(WARNING);
285 }
286
c4ba7c44
DK
287 /** \brief put the current Messages into the stack
288 *
289 * All "old" messages will be pushed into a stack to
290 * them later back, but for now the Message query will be
291 * empty and performs as no messages were present before.
292 *
293 * The stack can be as deep as you want - all stack operations
294 * will only operate on the last element in the stack.
295 */
296 void PushToStack();
297
298 /** \brief throw away all current messages */
299 void RevertToStack();
300
301 /** \brief merge current and stack together */
302 void MergeWithStack();
303
304 /** \brief return the deep of the stack */
305 size_t StackCount() const {
306 return Stacks.size();
307 }
308
98ee7cd3
DK
309 GlobalError();
310 /*}}}*/
311private: /*{{{*/
312 struct Item {
313 std::string Text;
314 MsgType Type;
315
316 Item(char const *Text, MsgType const &Type) :
317 Text(Text), Type(Type) {};
318
319 friend std::ostream& operator<< (std::ostream &out, Item i) {
320 switch(i.Type) {
321 case FATAL:
322 case ERROR: out << "E"; break;
323 case WARNING: out << "W"; break;
324 case NOTICE: out << "N"; break;
325 case DEBUG: out << "D"; break;
326 }
327 return out << ": " << i.Text;
328 }
329 };
330
331 std::list<Item> Messages;
332 bool PendingFlag;
333
c4ba7c44
DK
334 struct MsgStack {
335 std::list<Item> const Messages;
336 bool const PendingFlag;
337
338 MsgStack(std::list<Item> const &Messages, bool const &Pending) :
339 Messages(Messages), PendingFlag(Pending) {};
340 };
341
342 std::list<MsgStack> Stacks;
98ee7cd3 343 /*}}}*/
578bfd0a 344};
98ee7cd3 345 /*}}}*/
578bfd0a 346
6f27a7fc
AL
347// The 'extra-ansi' syntax is used to help with collisions.
348GlobalError *_GetErrorObj();
349#define _error _GetErrorObj()
578bfd0a
AL
350
351#endif