]>
git.saurik.com Git - apt.git/blob - apt-pkg/contrib/error.h
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: error.h,v 1.8 2001/05/07 05:06:52 jgg Exp $
4 /* ######################################################################
6 Global Erorr Class - Global error mechanism
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.
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
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
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..
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:
33 return _error->Errno(..);
35 This source is placed in the Public Domain, do with it what you will
36 It was originally written by Jason Gunthorpe.
38 ##################################################################### */
40 #ifndef PKGLIB_ERROR_H
41 #define PKGLIB_ERROR_H
43 #include <apt-pkg/macros.h>
52 class GlobalError
/*{{{*/
55 /** \brief a message can have one of following severity */
57 /** \brief Message will be printed instantly as it is likely that
58 this error will lead to a complete crash */
60 /** \brief An error does hinder the correct execution and should be corrected */
62 /** \brief indicates problem that can lead to errors later on */
64 /** \brief deprecation warnings, old fallback behavior, … */
66 /** \brief for developers only in areas it is hard to print something directly */
70 /** \brief add a fatal error message with errno to the list
72 * \param Function name of the function generating the error
73 * \param Description format string for the error message
77 bool FatalE(const char *Function
,const char *Description
,...) APT_PRINTF(3) APT_COLD
;
79 /** \brief add an Error message with errno to the list
81 * \param Function name of the function generating the error
82 * \param Description format string for the error message
86 bool Errno(const char *Function
,const char *Description
,...) APT_PRINTF(3) APT_COLD
;
88 /** \brief add a warning message with errno to the list
90 * A warning should be considered less severe than an error and
91 * may be ignored by the client.
93 * \param Function Name of the function generates the warning.
94 * \param Description Format string for the warning message.
98 bool WarningE(const char *Function
,const char *Description
,...) APT_PRINTF(3) APT_COLD
;
100 /** \brief add a notice message with errno to the list
102 * \param Function name of the function generating the error
103 * \param Description format string for the error message
107 bool NoticeE(const char *Function
,const char *Description
,...) APT_PRINTF(3) APT_COLD
;
109 /** \brief add a debug message with errno to the list
111 * \param Function name of the function generating the error
112 * \param Description format string for the error message
116 bool DebugE(const char *Function
,const char *Description
,...) APT_PRINTF(3) APT_COLD
;
118 /** \brief adds an errno message with the given type
120 * \param type of the error message
121 * \param Function which failed
122 * \param Description of the error
124 bool InsertErrno(MsgType
const &type
, const char* Function
,
125 const char* Description
,...) APT_PRINTF(4) APT_COLD
;
127 /** \brief adds an errno message with the given type
129 * args needs to be initialized with va_start and terminated
130 * with va_end by the caller. msgSize is also an out-parameter
131 * in case the msgSize was not enough to store the complete message.
133 * \param type of the error message
134 * \param Function which failed
135 * \param Description is the format string for args
136 * \param args list from a printf-like function
137 * \param errsv is the errno the error is for
138 * \param msgSize is the size of the char[] used to store message
139 * \return true if the message was added, false if not - the caller
140 * should call this method again in that case
142 bool InsertErrno(MsgType type
, const char* Function
,
143 const char* Description
, va_list &args
,
144 int const errsv
, size_t &msgSize
) APT_COLD
;
146 /** \brief add an fatal error message to the list
148 * Most of the stuff we consider as "error" is also "fatal" for
149 * the user as the application will not have the expected result,
150 * but a fatal message here means that it gets printed directly
151 * to stderr in addition to adding it to the list as the error
152 * leads sometimes to crashes and a maybe duplicated message
153 * is better than "Segfault" as the only displayed text
155 * \param Description Format string for the fatal error message.
159 bool Fatal(const char *Description
,...) APT_PRINTF(2) APT_COLD
;
161 /** \brief add an Error message to the list
163 * \param Description Format string for the error message.
167 bool Error(const char *Description
,...) APT_PRINTF(2) APT_COLD
;
169 /** \brief add a warning message to the list
171 * A warning should be considered less severe than an error and
172 * may be ignored by the client.
174 * \param Description Format string for the message
178 bool Warning(const char *Description
,...) APT_PRINTF(2) APT_COLD
;
180 /** \brief add a notice message to the list
182 * A notice should be considered less severe than an error or a
183 * warning and can be ignored by the client without further problems
184 * for some times, but he should consider fixing the problem.
185 * This error type can be used for e.g. deprecation warnings of options.
187 * \param Description Format string for the message
191 bool Notice(const char *Description
,...) APT_PRINTF(2) APT_COLD
;
193 /** \brief add a debug message to the list
195 * \param Description Format string for the message
199 bool Debug(const char *Description
,...) APT_PRINTF(2) APT_COLD
;
201 /** \brief adds an error message with the given type
203 * \param type of the error message
204 * \param Description of the error
206 bool Insert(MsgType
const &type
, const char* Description
,...) APT_PRINTF(3) APT_COLD
;
208 /** \brief adds an error message with the given type
210 * args needs to be initialized with va_start and terminated
211 * with va_end by the caller. msgSize is also an out-parameter
212 * in case the msgSize was not enough to store the complete message.
214 * \param type of the error message
215 * \param Description is the format string for args
216 * \param args list from a printf-like function
217 * \param msgSize is the size of the char[] used to store message
218 * \return true if the message was added, false if not - the caller
219 * should call this method again in that case
221 bool Insert(MsgType type
, const char* Description
,
222 va_list &args
, size_t &msgSize
) APT_COLD
;
224 /** \brief is an error in the list?
226 * \return \b true if an error is included in the list, \b false otherwise
228 inline bool PendingError() const APT_PURE
{return PendingFlag
;};
230 /** \brief is the list empty?
232 * Can be used to check if the current stack level doesn't include
233 * anything equal or more severe than a given threshold, defaulting
234 * to warning level for historic reasons.
236 * \param threshold minimum level considered
238 * \return \b true if the list is empty, \b false otherwise
240 bool empty(MsgType
const &threshold
= WARNING
) const APT_PURE
;
242 /** \brief returns and removes the first (or last) message in the list
244 * \param[out] Text message of the first/last item
246 * \return \b true if the message was an error, \b false otherwise
248 bool PopMessage(std::string
&Text
);
250 /** \brief clears the list of messages */
253 /** \brief outputs the list of messages to the given stream
255 * Note that all messages are discarded, even undisplayed ones.
257 * \param[out] out output stream to write the messages in
258 * \param threshold minimum level considered
259 * \param mergeStack if true recursively dumps the entire stack
261 void DumpErrors(std::ostream
&out
, MsgType
const &threshold
= WARNING
,
262 bool const &mergeStack
= true);
264 /** \brief dumps the list of messages to std::cerr
266 * Note that all messages are discarded, also the notices
269 * \param threshold minimum level printed
271 void inline DumpErrors(MsgType
const &threshold
) {
272 DumpErrors(std::cerr
, threshold
);
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
280 * Note that all messages are discarded, displayed or not.
283 void inline DumpErrors() {
287 /** \brief put the current Messages into the stack
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.
293 * The stack can be as deep as you want - all stack operations
294 * will only operate on the last element in the stack.
298 /** \brief throw away all current messages */
299 void RevertToStack();
301 /** \brief merge current and stack together */
302 void MergeWithStack();
304 /** \brief return the deep of the stack */
305 size_t StackCount() const APT_PURE
{
306 return Stacks
.size();
316 Item(char const *Text
, MsgType
const &Type
) :
317 Text(Text
), Type(Type
) {};
319 APT_HIDDEN
friend std::ostream
& operator<< (std::ostream
&out
, Item i
) {
322 case ERROR
: out
<< 'E'; break;
323 case WARNING
: out
<< 'W'; break;
324 case NOTICE
: out
<< 'N'; break;
325 case DEBUG
: out
<< 'D'; break;
328 std::string::size_type line_start
= 0;
329 std::string::size_type line_end
;
330 while ((line_end
= i
.Text
.find_first_of("\n\r", line_start
)) != std::string::npos
) {
332 out
<< std::endl
<< " ";
333 out
<< i
.Text
.substr(line_start
, line_end
- line_start
);
334 line_start
= i
.Text
.find_first_not_of("\n\r", line_end
+ 1);
335 if (line_start
== std::string::npos
)
340 else if (line_start
!= std::string::npos
)
341 out
<< std::endl
<< " " << i
.Text
.substr(line_start
);
346 std::list
<Item
> Messages
;
350 std::list
<Item
> Messages
;
351 bool const PendingFlag
;
353 MsgStack(std::list
<Item
> const &Messages
, bool const &Pending
) :
354 Messages(Messages
), PendingFlag(Pending
) {};
357 std::list
<MsgStack
> Stacks
;
362 // The 'extra-ansi' syntax is used to help with collisions.
363 GlobalError
*_GetErrorObj();
364 #define _error _GetErrorObj()