]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/error.h
don't leak an FD in lz4 (de)compression
[apt.git] / apt-pkg / contrib / error.h
index e5517c2da784d1153877871fc6bf04b8f1a87bbc..e56999b141ed269cf43c5ff9ba874985e0e67574 100644 (file)
@@ -46,6 +46,7 @@
 #include <list>
 #include <string>
 
+#include <stddef.h>
 #include <stdarg.h>
 
 class GlobalError                                                      /*{{{*/
@@ -73,7 +74,7 @@ public:                                                                       /*{{{*/
         *
         *  \return \b false
         */
-       bool FatalE(const char *Function,const char *Description,...) __like_printf(3) __cold;
+       bool FatalE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
 
        /** \brief add an Error message with errno to the list
         *
@@ -82,7 +83,7 @@ public:                                                                       /*{{{*/
         *
         *  \return \b false
         */
-       bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold;
+       bool Errno(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
 
        /** \brief add a warning message with errno to the list
         *
@@ -94,7 +95,7 @@ public:                                                                       /*{{{*/
         *
         *  \return \b false
         */
-       bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold;
+       bool WarningE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
 
        /** \brief add a notice message with errno to the list
         *
@@ -103,7 +104,7 @@ public:                                                                     /*{{{*/
         *
         *  \return \b false
         */
-       bool NoticeE(const char *Function,const char *Description,...) __like_printf(3) __cold;
+       bool NoticeE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
 
        /** \brief add a debug message with errno to the list
         *
@@ -112,14 +113,42 @@ public:                                                                   /*{{{*/
         *
         *  \return \b false
         */
-       bool DebugE(const char *Function,const char *Description,...) __like_printf(3) __cold;
+       bool DebugE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
+
+       /** \brief adds an errno message with the given type
+        *
+        * \param type of the error message
+        * \param Function which failed
+        * \param Description of the error
+        */
+       bool InsertErrno(MsgType const &type, const char* Function,
+                        const char* Description,...) APT_PRINTF(4) APT_COLD;
+
+       /** \brief adds an errno message with the given type
+        *
+        * args needs to be initialized with va_start and terminated
+        * with va_end by the caller. msgSize is also an out-parameter
+        * in case the msgSize was not enough to store the complete message.
+        *
+        * \param type of the error message
+        * \param Function which failed
+        * \param Description is the format string for args
+        * \param args list from a printf-like function
+        * \param errsv is the errno the error is for
+        * \param msgSize is the size of the char[] used to store message
+        * \return true if the message was added, false if not - the caller
+        * should call this method again in that case
+        */
+       bool InsertErrno(MsgType type, const char* Function,
+                        const char* Description, va_list &args,
+                        int const errsv, size_t &msgSize) APT_COLD;
 
        /** \brief add an fatal error message to the list
         *
         *  Most of the stuff we consider as "error" is also "fatal" for
         *  the user as the application will not have the expected result,
         *  but a fatal message here means that it gets printed directly
-        *  to stderr in addiction to adding it to the list as the error
+        *  to stderr in addition to adding it to the list as the error
         *  leads sometimes to crashes and a maybe duplicated message
         *  is better than "Segfault" as the only displayed text
         *
@@ -127,7 +156,7 @@ public:                                                                     /*{{{*/
         *
         *  \return \b false
         */
-       bool Fatal(const char *Description,...) __like_printf(2) __cold;
+       bool Fatal(const char *Description,...) APT_PRINTF(2) APT_COLD;
 
        /** \brief add an Error message to the list
         *
@@ -135,7 +164,7 @@ public:                                                                     /*{{{*/
         *
         *  \return \b false
         */
-       bool Error(const char *Description,...) __like_printf(2) __cold;
+       bool Error(const char *Description,...) APT_PRINTF(2) APT_COLD;
 
        /** \brief add a warning message to the list
         *
@@ -146,7 +175,7 @@ public:                                                                     /*{{{*/
         *
         *  \return \b false
         */
-       bool Warning(const char *Description,...) __like_printf(2) __cold;
+       bool Warning(const char *Description,...) APT_PRINTF(2) APT_COLD;
 
        /** \brief add a notice message to the list
         *
@@ -159,7 +188,7 @@ public:                                                                     /*{{{*/
         *
         *  \return \b false
         */
-       bool Notice(const char *Description,...) __like_printf(2) __cold;
+       bool Notice(const char *Description,...) APT_PRINTF(2) APT_COLD;
 
        /** \brief add a debug message to the list
         *
@@ -167,25 +196,48 @@ public:                                                                   /*{{{*/
         *
         *  \return \b false
         */
-       bool Debug(const char *Description,...) __like_printf(2) __cold;
+       bool Debug(const char *Description,...) APT_PRINTF(2) APT_COLD;
+
+       /** \brief adds an error message with the given type
+        *
+        * \param type of the error message
+        * \param Description of the error
+        */
+       bool Insert(MsgType const &type, const char* Description,...) APT_PRINTF(3) APT_COLD;
+
+       /** \brief adds an error message with the given type
+        *
+        * args needs to be initialized with va_start and terminated
+        * with va_end by the caller. msgSize is also an out-parameter
+        * in case the msgSize was not enough to store the complete message.
+        *
+        * \param type of the error message
+        * \param Description is the format string for args
+        * \param args list from a printf-like function
+        * \param msgSize is the size of the char[] used to store message
+        * \return true if the message was added, false if not - the caller
+        * should call this method again in that case
+        */
+       bool Insert(MsgType type, const char* Description,
+                        va_list &args, size_t &msgSize) APT_COLD;
 
        /** \brief is an error in the list?
         *
         *  \return \b true if an error is included in the list, \b false otherwise
         */
-       inline bool PendingError() const {return PendingFlag;};
+       inline bool PendingError() const APT_PURE {return PendingFlag;};
 
        /** \brief is the list empty?
         *
-        *  The default checks if the list is empty or contains only notices,
-        *  if you want to check if also no notices happend set the parameter
-        *  flag to \b false.
+        *  Can be used to check if the current stack level doesn't include
+        *  anything equal or more severe than a given threshold, defaulting
+        *  to warning level for historic reasons.
         *
-        *  \param WithoutNotice does notices count, default is \b true, so no
+        *  \param threshold minimum level considered
         *
-        *  \return \b true if an the list is empty, \b false otherwise
+        *  \return \b true if the list is empty, \b false otherwise
         */
-       bool empty(MsgType const &trashhold = WARNING) const;
+       bool empty(MsgType const &threshold = WARNING) const APT_PURE;
 
        /** \brief returns and removes the first (or last) message in the list
         *
@@ -200,13 +252,13 @@ public:                                                                   /*{{{*/
 
        /** \brief outputs the list of messages to the given stream
         *
-        *  Note that all messages are discarded, also the notices
-        *  displayed or not.
+        *  Note that all messages are discarded, even undisplayed ones.
         *
         *  \param[out] out output stream to write the messages in
-        *  \param WithoutNotice output notices or not
+        *  \param threshold minimum level considered
+        *  \param mergeStack if true recursively dumps the entire stack
         */
-       void DumpErrors(std::ostream &out, MsgType const &trashhold = WARNING,
+       void DumpErrors(std::ostream &out, MsgType const &threshold = WARNING,
                        bool const &mergeStack = true);
 
        /** \brief dumps the list of messages to std::cerr
@@ -214,10 +266,22 @@ public:                                                                   /*{{{*/
         *  Note that all messages are discarded, also the notices
         *  displayed or not.
         *
-        *  \param WithoutNotice print notices or not
+        *  \param threshold minimum level printed
+        */
+       void inline DumpErrors(MsgType const &threshold) {
+               DumpErrors(std::cerr, threshold);
+       }
+
+        // mvo: we do this instead of using a default parameter in the
+        //      previous declaration to avoid a (subtle) API break for
+        //      e.g. sigc++ and mem_fun0
+       /** \brief dumps the messages of type WARNING or higher to std::cerr
+        *
+        *  Note that all messages are discarded, displayed or not.
+        *
         */
-       void inline DumpErrors(MsgType const &trashhold = WARNING) {
-               DumpErrors(std::cerr, trashhold);
+       void inline DumpErrors() {
+                DumpErrors(WARNING);
        }
 
        /** \brief put the current Messages into the stack
@@ -238,7 +302,7 @@ public:                                                                     /*{{{*/
        void MergeWithStack();
 
        /** \brief return the deep of the stack */
-       size_t StackCount() const {
+       size_t StackCount() const APT_PURE {
                return Stacks.size();
        }
 
@@ -252,15 +316,30 @@ private:                                                          /*{{{*/
                Item(char const *Text, MsgType const &Type) :
                        Text(Text), Type(Type) {};
 
-               friend std::ostream& operator<< (std::ostream &out, Item i) {
+               APT_HIDDEN friend std::ostream& operator<< (std::ostream &out, Item i) {
                        switch(i.Type) {
                        case FATAL:
-                       case ERROR: out << "E"; break;
-                       case WARNING: out << "W"; break;
-                       case NOTICE: out << "N"; break;
-                       case DEBUG: out << "D"; break;
+                       case ERROR: out << 'E'; break;
+                       case WARNING: out << 'W'; break;
+                       case NOTICE: out << 'N'; break;
+                       case DEBUG: out << 'D'; break;
+                       }
+                       out << ": ";
+                       std::string::size_type line_start = 0;
+                       std::string::size_type line_end;
+                       while ((line_end = i.Text.find_first_of("\n\r", line_start)) != std::string::npos) {
+                               if (line_start != 0)
+                                  out << std::endl << "   ";
+                               out << i.Text.substr(line_start, line_end - line_start);
+                               line_start = i.Text.find_first_not_of("\n\r", line_end + 1);
+                               if (line_start == std::string::npos)
+                                  break;
                        }
-                       return out << ": " << i.Text;
+                       if (line_start == 0)
+                          out << i.Text;
+                       else if (line_start != std::string::npos)
+                          out << std::endl << "   " << i.Text.substr(line_start);
+                       return out;
                }
        };
 
@@ -268,7 +347,7 @@ private:                                                            /*{{{*/
        bool PendingFlag;
 
        struct MsgStack {
-               std::list<Item> const Messages;
+               std::list<Item> Messages;
                bool const PendingFlag;
 
                MsgStack(std::list<Item> const &Messages, bool const &Pending) :
@@ -276,11 +355,6 @@ private:                                                           /*{{{*/
        };
 
        std::list<MsgStack> Stacks;
-
-       bool InsertErrno(MsgType type, const char* Function,
-                        const char* Description, va_list &args);
-       bool Insert(MsgType type, const char* Description,
-                        va_list &args);
                                                                        /*}}}*/
 };
                                                                        /*}}}*/