From ce06801d5537cdfef728438d22841a6cca266cf9 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sun, 14 Jul 2019 23:41:01 +0300 Subject: [PATCH] genesys: Support variadic format string in SaneException --- backend/genesys_error.cc | 42 +++++++++++++++++++++++++++++----------- backend/genesys_error.h | 16 +++++++++++---- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/backend/genesys_error.cc b/backend/genesys_error.cc index afe80c150..bb298b663 100644 --- a/backend/genesys_error.cc +++ b/backend/genesys_error.cc @@ -71,16 +71,24 @@ static unsigned num_uncaught_exceptions() SaneException::SaneException(SANE_Status status) : status_(status) { - set_msg(nullptr); + std::va_list args; + set_msg(nullptr, args); } -SaneException::SaneException(SANE_Status status, const char* msg) : status_(status) +SaneException::SaneException(SANE_Status status, const char* format, ...) : status_(status) { - set_msg(msg); + std::va_list args; + va_start(args, format); + set_msg(format, args); + va_end(args); } -SaneException::SaneException(const char* msg) : SaneException(SANE_STATUS_INVAL, msg) +SaneException::SaneException(const char* format, ...) : status_(SANE_STATUS_INVAL) { + std::va_list args; + va_start(args, format); + set_msg(format, args); + va_end(args); } SANE_Status SaneException::status() const @@ -93,22 +101,34 @@ const char* SaneException::what() const noexcept return msg_.c_str(); } -void SaneException::set_msg(const char* msg) +void SaneException::set_msg(const char* format, std::va_list vlist) { const char* status_msg = sane_strstatus(status_); std::size_t status_msg_len = std::strlen(status_msg); - if (msg) { - std::size_t msg_len = std::strlen(msg); - msg_.reserve(msg_len + status_msg_len + 3); - msg_ = msg; + if (format == nullptr) { + msg_.reserve(status_msg_len); + msg_ = status_msg; + return; + } + + int msg_len = std::vsnprintf(nullptr, 0, format, vlist); + if (msg_len < 0) { + const char* formatting_error_msg = "(error formatting arguments)"; + msg_.reserve(std::strlen(formatting_error_msg) + 3 + status_msg_len); + msg_ = formatting_error_msg; msg_ += " : "; msg_ += status_msg; return; } - msg_.reserve(status_msg_len); - msg_ = status_msg; + msg_.reserve(msg_len + status_msg_len + 3); + msg_.resize(msg_len + 1, ' '); + std::vsnprintf(&msg_[0], msg_len + 1, format, vlist); + msg_.resize(msg_len, ' '); + + msg_ += " : "; + msg_ += status_msg; } DebugMessageHelper::DebugMessageHelper(const char* func) diff --git a/backend/genesys_error.h b/backend/genesys_error.h index fd438c692..85a187f8e 100644 --- a/backend/genesys_error.h +++ b/backend/genesys_error.h @@ -49,6 +49,7 @@ #include "../include/sane/sanei_backend.h" #include +#include #include #include @@ -65,17 +66,24 @@ class SaneException : std::exception { public: SaneException(SANE_Status status); - SaneException(SANE_Status status, const char* msg); - - SaneException(const char* msg); + SaneException(SANE_Status status, const char* format, ...) + #ifdef __GNUC__ + __attribute__((format(printf, 3, 4))) + #endif + ; + SaneException(const char* format, ...) + #ifdef __GNUC__ + __attribute__((format(printf, 2, 3))) + #endif + ; SANE_Status status() const; const char* what() const noexcept override; private: - void set_msg(const char* msg); + void set_msg(const char* format, std::va_list vlist); std::string msg_; SANE_Status status_;