X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/115ba31b90e0d6643670d7d079f9f27b0e05f1c2..cc9745a0d81a3e1aa5ef6f99f7ad638d26bdb950:/apt-pkg/contrib/error.cc?ds=sidebyside diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc index 8cee21c9c..8a87e16e9 100644 --- a/apt-pkg/contrib/error.cc +++ b/apt-pkg/contrib/error.cc @@ -13,18 +13,23 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include +#include +#include +#include #include #include #include +#include #include - #include #include +#include -#include "config.h" - /*}}}*/ + /*}}}*/ // Global Error Object /*{{{*/ /* If the implementation supports posix threads then the accessor function @@ -57,93 +62,114 @@ // GlobalError::GlobalError - Constructor /*{{{*/ GlobalError::GlobalError() : PendingFlag(false) {} /*}}}*/ -// GlobalError::FatalE - Get part of the error string from errno /*{{{*/ -bool GlobalError::FatalE(const char *Function,const char *Description,...) { - va_list args; - va_start(args,Description); - return InsertErrno(FATAL, Function, Description, args); -} - /*}}}*/ -// GlobalError::Errno - Get part of the error string from errno /*{{{*/ -bool GlobalError::Errno(const char *Function,const char *Description,...) { - va_list args; - va_start(args,Description); - return InsertErrno(ERROR, Function, Description, args); -} - /*}}}*/ -// GlobalError::WarningE - Get part of the warning string from errno /*{{{*/ -bool GlobalError::WarningE(const char *Function,const char *Description,...) { - va_list args; - va_start(args,Description); - return InsertErrno(WARNING, Function, Description, args); +// GlobalError::FatalE, Errno, WarningE, NoticeE and DebugE - Add to the list/*{{{*/ +#define GEMessage(NAME, TYPE) \ +bool GlobalError::NAME (const char *Function, const char *Description,...) { \ + va_list args; \ + size_t msgSize = 400; \ + int const errsv = errno; \ + while (true) { \ + va_start(args,Description); \ + bool const retry = InsertErrno(TYPE, Function, Description, args, errsv, msgSize); \ + va_end(args); \ + if (retry == false) \ + break; \ + } \ + return false; \ } +GEMessage(FatalE, FATAL) +GEMessage(Errno, ERROR) +GEMessage(WarningE, WARNING) +GEMessage(NoticeE, NOTICE) +GEMessage(DebugE, DEBUG) +#undef GEMessage /*}}}*/ -// GlobalError::NoticeE - Get part of the notice string from errno /*{{{*/ -bool GlobalError::NoticeE(const char *Function,const char *Description,...) { +// GlobalError::InsertErrno - Get part of the errortype string from errno/*{{{*/ +bool GlobalError::InsertErrno(MsgType const &type, const char *Function, + const char *Description,...) { va_list args; - va_start(args,Description); - return InsertErrno(NOTICE, Function, Description, args); -} - /*}}}*/ -// GlobalError::DebugE - Get part of the debug string from errno /*{{{*/ -bool GlobalError::DebugE(const char *Function,const char *Description,...) { - va_list args; - va_start(args,Description); - return InsertErrno(DEBUG, Function, Description, args); + size_t msgSize = 400; + int const errsv = errno; + while (true) { + va_start(args,Description); + bool const retry = InsertErrno(type, Function, Description, args, errsv, msgSize); + va_end(args); + if (retry == false) + break; + } + return false; } /*}}}*/ // GlobalError::InsertErrno - formats an error message with the errno /*{{{*/ bool GlobalError::InsertErrno(MsgType type, const char* Function, - const char* Description, va_list const &args) { - char S[400]; - vsnprintf(S,sizeof(S),Description,args); - snprintf(S + strlen(S),sizeof(S) - strlen(S), - " - %s (%i: %s)", Function, errno, strerror(errno)); - return Insert(type, S, args); -} - /*}}}*/ -// GlobalError::Fatal - Add a fatal error to the list /*{{{*/ -bool GlobalError::Fatal(const char *Description,...) { - va_list args; - va_start(args,Description); - return Insert(FATAL, Description, args); -} - /*}}}*/ -// GlobalError::Error - Add an error to the list /*{{{*/ -bool GlobalError::Error(const char *Description,...) { - va_list args; - va_start(args,Description); - return Insert(ERROR, Description, args); -} - /*}}}*/ -// GlobalError::Warning - Add a warning to the list /*{{{*/ -bool GlobalError::Warning(const char *Description,...) { - va_list args; - va_start(args,Description); - return Insert(WARNING, Description, args); + const char* Description, va_list &args, + int const errsv, size_t &msgSize) { + char* S = (char*) malloc(msgSize); + int const n = snprintf(S, msgSize, "%s - %s (%i: %s)", Description, + Function, errsv, strerror(errsv)); + if (n > -1 && ((unsigned int) n) < msgSize); + else { + if (n > -1) + msgSize = n + 1; + else + msgSize *= 2; + free(S); + return true; + } + + bool const geins = Insert(type, S, args, msgSize); + free(S); + return geins; } /*}}}*/ -// GlobalError::Notice - Add a notice to the list /*{{{*/ -bool GlobalError::Notice(const char *Description,...) -{ - va_list args; - va_start(args,Description); - return Insert(NOTICE, Description, args); +// GlobalError::Fatal, Error, Warning, Notice and Debug - Add to the list/*{{{*/ +#define GEMessage(NAME, TYPE) \ +bool GlobalError::NAME (const char *Description,...) { \ + va_list args; \ + size_t msgSize = 400; \ + while (true) { \ + va_start(args,Description); \ + if (Insert(TYPE, Description, args, msgSize) == false) \ + break; \ + va_end(args); \ + } \ + return false; \ } +GEMessage(Fatal, FATAL) +GEMessage(Error, ERROR) +GEMessage(Warning, WARNING) +GEMessage(Notice, NOTICE) +GEMessage(Debug, DEBUG) +#undef GEMessage /*}}}*/ -// GlobalError::Debug - Add a debug to the list /*{{{*/ -bool GlobalError::Debug(const char *Description,...) +// GlobalError::Insert - Add a errotype message to the list /*{{{*/ +bool GlobalError::Insert(MsgType const &type, const char *Description,...) { va_list args; - va_start(args,Description); - return Insert(DEBUG, Description, args); + size_t msgSize = 400; + while (true) { + va_start(args,Description); + if (Insert(type, Description, args, msgSize) == false) + break; + va_end(args); + } + return false; } /*}}}*/ // GlobalError::Insert - Insert a new item at the end /*{{{*/ bool GlobalError::Insert(MsgType type, const char* Description, - va_list const &args) { - char S[400]; - vsnprintf(S,sizeof(S),Description,args); + va_list &args, size_t &msgSize) { + char* S = (char*) malloc(msgSize); + int const n = vsnprintf(S, msgSize, Description, args); + if (n > -1 && ((unsigned int) n) < msgSize); + else { + if (n > -1) + msgSize = n + 1; + else + msgSize *= 2; + free(S); + return true; + } Item const m(S, type); Messages.push_back(m); @@ -154,6 +180,7 @@ bool GlobalError::Insert(MsgType type, const char* Description, if (type == FATAL || type == DEBUG) std::clog << m << std::endl; + free(S); return false; } /*}}}*/ @@ -172,7 +199,7 @@ bool GlobalError::PopMessage(std::string &Text) { // check if another error message is pending for (std::list::const_iterator m = Messages.begin(); - m != Messages.end(); m++) + m != Messages.end(); ++m) if (m->Type == ERROR || m->Type == FATAL) return Ret; @@ -181,17 +208,18 @@ bool GlobalError::PopMessage(std::string &Text) { } /*}}}*/ // GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/ -void GlobalError::DumpErrors(std::ostream &out, MsgType const &trashhold, +void GlobalError::DumpErrors(std::ostream &out, MsgType const &threshold, bool const &mergeStack) { if (mergeStack == true) for (std::list::const_reverse_iterator s = Stacks.rbegin(); s != Stacks.rend(); ++s) - Messages.insert(Messages.begin(), s->Messages.begin(), s->Messages.end()); + std::copy(s->Messages.begin(), s->Messages.end(), std::front_inserter(Messages)); + + std::for_each(Messages.begin(), Messages.end(), [&threshold, &out](Item const &m) { + if (m.Type >= threshold) + out << m << std::endl; + }); - for (std::list::const_iterator m = Messages.begin(); - m != Messages.end(); m++) - if (m->Type >= trashhold) - out << (*m) << std::endl; Discard(); } /*}}}*/ @@ -199,28 +227,24 @@ void GlobalError::DumpErrors(std::ostream &out, MsgType const &trashhold, void GlobalError::Discard() { Messages.clear(); PendingFlag = false; -}; +} /*}}}*/ // GlobalError::empty - does our error list include anything? /*{{{*/ -bool GlobalError::empty(MsgType const &trashhold) const { +bool GlobalError::empty(MsgType const &threshold) const { if (PendingFlag == true) return false; if (Messages.empty() == true) return true; - for (std::list::const_iterator m = Messages.begin(); - m != Messages.end(); m++) - if (m->Type >= trashhold) - return false; - - return true; + return std::find_if(Messages.begin(), Messages.end(), [&threshold](Item const &m) { + return m.Type >= threshold; + }) == Messages.end(); } /*}}}*/ // GlobalError::PushToStack /*{{{*/ void GlobalError::PushToStack() { - MsgStack pack(Messages, PendingFlag); - Stacks.push_back(pack); + Stacks.emplace_back(Messages, PendingFlag); Discard(); } /*}}}*/ @@ -236,7 +260,7 @@ void GlobalError::RevertToStack() { // GlobalError::MergeWithStack /*{{{*/ void GlobalError::MergeWithStack() { MsgStack pack = Stacks.back(); - Messages.insert(Messages.begin(), pack.Messages.begin(), pack.Messages.end()); + Messages.splice(Messages.begin(), pack.Messages); PendingFlag = PendingFlag || pack.PendingFlag; Stacks.pop_back(); }