apt @VERSION@

error.h

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