apt @VERSION@
|
00001 // -*- mode: cpp; mode: fold -*- 00002 // Description /*{{{*/ 00003 // $Id: error.h,v 1.8 2001/05/07 05:06:52 jgg Exp $ 00004 /* ###################################################################### 00005 00006 Global Erorr Class - Global error mechanism 00007 00008 This class has a single global instance. When a function needs to 00009 generate an error condition, such as a read error, it calls a member 00010 in this class to add the error to a stack of errors. 00011 00012 By using a stack the problem with a scheme like errno is removed and 00013 it allows a very detailed account of what went wrong to be transmitted 00014 to the UI for display. (Errno has problems because each function sets 00015 errno to 0 if it didn't have an error thus eraseing erno in the process 00016 of cleanup) 00017 00018 Several predefined error generators are provided to handle common 00019 things like errno. The general idea is that all methods return a bool. 00020 If the bool is true then things are OK, if it is false then things 00021 should start being undone and the stack should unwind under program 00022 control. 00023 00024 A Warning should not force the return of false. Things did not fail, but 00025 they might have had unexpected problems. Errors are stored in a FIFO 00026 so Pop will return the first item.. 00027 00028 I have some thoughts about extending this into a more general UI<-> 00029 Engine interface, ie allowing the Engine to say 'The disk is full' in 00030 a dialog that says 'Panic' and 'Retry'.. The error generator functions 00031 like errno, Warning and Error return false always so this is normal: 00032 if (open(..)) 00033 return _error->Errno(..); 00034 00035 This source is placed in the Public Domain, do with it what you will 00036 It was originally written by Jason Gunthorpe. 00037 00038 ##################################################################### */ 00039 /*}}}*/ 00040 #ifndef PKGLIB_ERROR_H 00041 #define PKGLIB_ERROR_H 00042 00043 #include <apt-pkg/macros.h> 00044 00045 #include <iostream> 00046 #include <list> 00047 #include <string> 00048 00049 #include <stdarg.h> 00050 00051 class GlobalError /*{{{*/ 00052 { 00053 public: /*{{{*/ 00055 enum MsgType { 00058 FATAL = 40, 00060 ERROR = 30, 00062 WARNING = 20, 00064 NOTICE = 10, 00066 DEBUG = 0 00067 }; 00068 00076 bool FatalE(const char *Function,const char *Description,...) __like_printf(3) __cold; 00077 00085 bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold; 00086 00097 bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold; 00098 00106 bool NoticeE(const char *Function,const char *Description,...) __like_printf(3) __cold; 00107 00115 bool DebugE(const char *Function,const char *Description,...) __like_printf(3) __cold; 00116 00123 bool InsertErrno(MsgType const &type, const char* Function, 00124 const char* Description,...) __like_printf(4) __cold; 00125 00139 bool Fatal(const char *Description,...) __like_printf(2) __cold; 00140 00147 bool Error(const char *Description,...) __like_printf(2) __cold; 00148 00158 bool Warning(const char *Description,...) __like_printf(2) __cold; 00159 00171 bool Notice(const char *Description,...) __like_printf(2) __cold; 00172 00179 bool Debug(const char *Description,...) __like_printf(2) __cold; 00180 00186 bool Insert(MsgType const &type, const char* Description,...) __like_printf(3) __cold; 00187 00192 inline bool PendingError() const {return PendingFlag;}; 00193 00204 bool empty(MsgType const &trashhold = WARNING) const; 00205 00212 bool PopMessage(std::string &Text); 00213 00215 void Discard(); 00216 00226 void DumpErrors(std::ostream &out, MsgType const &threshold = WARNING, 00227 bool const &mergeStack = true); 00228 00236 void inline DumpErrors(MsgType const &threshold) { 00237 DumpErrors(std::cerr, threshold); 00238 } 00239 00240 // mvo: we do this instead of using a default parameter in the 00241 // previous declaration to avoid a (subtle) API break for 00242 // e.g. sigc++ and mem_fun0 00248 void inline DumpErrors() { 00249 DumpErrors(WARNING); 00250 } 00251 00261 void PushToStack(); 00262 00264 void RevertToStack(); 00265 00267 void MergeWithStack(); 00268 00270 size_t StackCount() const { 00271 return Stacks.size(); 00272 } 00273 00274 GlobalError(); 00275 /*}}}*/ 00276 private: /*{{{*/ 00277 struct Item { 00278 std::string Text; 00279 MsgType Type; 00280 00281 Item(char const *Text, MsgType const &Type) : 00282 Text(Text), Type(Type) {}; 00283 00284 friend std::ostream& operator<< (std::ostream &out, Item i) { 00285 switch(i.Type) { 00286 case FATAL: 00287 case ERROR: out << "E"; break; 00288 case WARNING: out << "W"; break; 00289 case NOTICE: out << "N"; break; 00290 case DEBUG: out << "D"; break; 00291 } 00292 return out << ": " << i.Text; 00293 } 00294 }; 00295 00296 std::list<Item> Messages; 00297 bool PendingFlag; 00298 00299 struct MsgStack { 00300 std::list<Item> const Messages; 00301 bool const PendingFlag; 00302 00303 MsgStack(std::list<Item> const &Messages, bool const &Pending) : 00304 Messages(Messages), PendingFlag(Pending) {}; 00305 }; 00306 00307 std::list<MsgStack> Stacks; 00308 00309 bool InsertErrno(MsgType type, const char* Function, 00310 const char* Description, va_list &args, 00311 int const errsv, size_t &msgSize); 00312 bool Insert(MsgType type, const char* Description, 00313 va_list &args, size_t &msgSize); 00314 /*}}}*/ 00315 }; 00316 /*}}}*/ 00317 00318 // The 'extra-ansi' syntax is used to help with collisions. 00319 GlobalError *_GetErrorObj(); 00320 #define _error _GetErrorObj() 00321 00322 #endif