From patchwork Fri Feb 8 14:45:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 550 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 390B66101F for ; Fri, 8 Feb 2019 15:45:45 +0100 (CET) Received: from pendragon.ideasonboard.com (d51A4137F.access.telenet.be [81.164.19.127]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B6995F9 for ; Fri, 8 Feb 2019 15:45:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549637144; bh=S7QKr3bt37u0JJIVa6LLliKnTdpxqLDVlTrplif6/Lo=; h=From:To:Subject:Date:From; b=T/0mAGds8QvsN5/QBhuGasHlK6f6M7LK4FZ4beCADiKETIagKpwnCQH5egs55YqrT wnLX9VsUm+gmYDRrar7D4dhLziDJHN0/oRWy4GYoWyfx+JMmTL5I8jHd3QDyHvBdNb RZSDKMILtMP9hWCDAhaE7crKSJFCg81Fo/yGd/QY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 8 Feb 2019 16:45:39 +0200 Message-Id: <20190208144540.15529-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/2] libcamera: log: Allow extending log messages X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Feb 2019 14:45:45 -0000 Introduce a base Loggable class that can be inherited from by other classes to support adding per-instance information to the log messages. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/libcamera/include/log.h | 23 ++++++- src/libcamera/log.cpp | 124 ++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 2 deletions(-) diff --git a/src/libcamera/include/log.h b/src/libcamera/include/log.h index ad8f8452c333..8ea5a1eb673a 100644 --- a/src/libcamera/include/log.h +++ b/src/libcamera/include/log.h @@ -54,6 +54,7 @@ public: LogMessage(const char *fileName, unsigned int line, const LogCategory &category, LogSeverity severity); LogMessage(const LogMessage &) = delete; + LogMessage(LogMessage &&); ~LogMessage(); std::ostream &stream() { return msgStream_; } @@ -66,13 +67,31 @@ private: LogSeverity severity_; }; +class Loggable +{ +public: + virtual ~Loggable(); + +protected: + virtual std::string logPrefix() const = 0; + + LogMessage _log(const char *file, unsigned int line, + LogSeverity severity); + LogMessage _log(const char *file, unsigned int line, + const LogCategory &category, LogSeverity severity); +}; + +LogMessage _log(const char *file, unsigned int line, LogSeverity severity); +LogMessage _log(const char *file, unsigned int line, + const LogCategory &category, LogSeverity severity); + #ifndef __DOXYGEN__ #define _LOG_CATEGORY(name) logCategory##name #define _LOG1(severity) \ - LogMessage(__FILE__, __LINE__, Log##severity).stream() + _log(__FILE__, __LINE__, Log##severity).stream() #define _LOG2(category, severity) \ - LogMessage(__FILE__, __LINE__, _LOG_CATEGORY(category)(), Log##severity).stream() + _log(__FILE__, __LINE__, _LOG_CATEGORY(category)(), Log##severity).stream() /* * Expand the LOG() macro to _LOG1() or _LOG2() based on the number of diff --git a/src/libcamera/log.cpp b/src/libcamera/log.cpp index edeb5eabb264..26ebf410a7a9 100644 --- a/src/libcamera/log.cpp +++ b/src/libcamera/log.cpp @@ -405,6 +405,25 @@ LogMessage::LogMessage(const char *fileName, unsigned int line, init(fileName, line); } +/** + * \brief Move-construct a log message + * \param[in] other The other message + * + * The move constructor is meant to support the _log() functions. Thanks to copy + * elision it will likely never be called, but C++11 only permits copy elision, + * it doesn't enforce it unlike C++17. To avoid potential link errors depending + * on the compiler type and version, and optimization level, the move + * constructor is defined even if it will likely never be called, and ensures + * that the destructor of the \a other message will not output anything to the + * log by setting the severity to -1. + */ +LogMessage::LogMessage(LogMessage &&other) + : msgStream_(std::move(other.msgStream_)), category_(other.category_), + severity_(other.severity_) +{ + other.severity_ = static_cast(-1); +} + void LogMessage::init(const char *fileName, unsigned int line) { /* Log the timestamp, severity and file information. */ @@ -424,6 +443,10 @@ void LogMessage::init(const char *fileName, unsigned int line) LogMessage::~LogMessage() { + /* Don't print anything if we have been moved to another LogMessage. */ + if (severity_ == -1) + return; + msgStream_ << std::endl; if (severity_ >= category_.severity()) { @@ -445,6 +468,107 @@ LogMessage::~LogMessage() * \return A reference to the log message stream */ +/** + * \class Loggable + * \brief Base class to support log message extensions + * + * The Loggable class allows classes to extend log messages without any change + * to the way the LOG() macro is invoked. By inheriting from Loggable and + * implementing the logPrefix() virtual method, a class can specify extra + * information to be automatically added to messages logged from class member + * methods. + */ + +Loggable::~Loggable() +{ +} + +/** + * \fn Loggable::logPrefix() + * \brief Retrieve a string to be prefixed to the log message + * + * This method allows classes inheriting from the Loggable class to extend the + * logger with an object-specific prefix output right before the log message + * contents. + * + * \return A string to be prefixed to the log message + */ + +/** + * \brief Create a temporary LogMessage object to log a message + * \param[in] fileName The file name where the message is logged from + * \param[in] line The line number where the message is logged from + * \param[in] severity The log message severity + * + * This method is used as a backeng by the LOG() macro to create a log message + * for locations inheriting from the Loggable class. + * + * \return A log message + */ +LogMessage Loggable::_log(const char *fileName, unsigned int line, + LogSeverity severity) +{ + LogMessage msg(fileName, line, severity); + + msg.stream() << logPrefix() << ": "; + return msg; +} + +/** + * \brief Create a temporary LogMessage object to log a message + * \param[in] fileName The file name where the message is logged from + * \param[in] line The line number where the message is logged from + * \param[in] category The log message category + * \param[in] severity The log message severity + * + * This method is used as a backeng by the LOG() macro to create a log message + * for locations inheriting from the Loggable class. + * + * \return A log message + */ +LogMessage Loggable::_log(const char *fileName, unsigned int line, + const LogCategory &category, LogSeverity severity) +{ + LogMessage msg(fileName, line, category, severity); + + msg.stream() << logPrefix() << ": "; + return msg; +} + +/** + * \brief Create a temporary LogMessage object to log a message + * \param[in] fileName The file name where the message is logged from + * \param[in] line The line number where the message is logged from + * \param[in] severity The log message severity + * + * This function is used as a backeng by the LOG() macro to create a log + * message for locations not inheriting from the Loggable class. + * + * \return A log message + */ +LogMessage _log(const char *fileName, unsigned int line, LogSeverity severity) +{ + return LogMessage(fileName, line, severity); +} + +/** + * \brief Create a temporary LogMessage object to log a message + * \param[in] fileName The file name where the message is logged from + * \param[in] line The line number where the message is logged from + * \param[in] category The log message category + * \param[in] severity The log message severity + * + * This function is used as a backeng by the LOG() macro to create a log + * message for locations not inheriting from the Loggable class. + * + * \return A log message + */ +LogMessage _log(const char *fileName, unsigned int line, + const LogCategory &category, LogSeverity severity) +{ + return LogMessage(fileName, line, category, severity); +} + /** * \def LOG_DECLARE_CATEGORY(name) * \hideinitializer From patchwork Fri Feb 8 14:45:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 551 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 823016101F for ; Fri, 8 Feb 2019 15:45:45 +0100 (CET) Received: from pendragon.ideasonboard.com (d51A4137F.access.telenet.be [81.164.19.127]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F23572E4 for ; Fri, 8 Feb 2019 15:45:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549637145; bh=kkYP1rswu/B3HjKfSzc+NMur8lmJWJrBBeSgpRs76AA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tcxMIRD+jevS+s0f8AWJBFFklKhwEcQdv4Ixw7xs3qVAtZ0B6z6SS3mzgILP9Jkv9 9ulqj/+DltpkawofhaBKHyct+y12kGEc0QSDEuMyuzLZYqXKSQXmzIiUjVMlWSTwaY c1Bzl2PKuPWMte32pVFh5fCXu0pVnwjCsS4pU7t4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 8 Feb 2019 16:45:40 +0200 Message-Id: <20190208144540.15529-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190208144540.15529-1-laurent.pinchart@ideasonboard.com> References: <20190208144540.15529-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/2] libcamera: v4l2_device: Inherit from Loggable to print device node name X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Feb 2019 14:45:45 -0000 Automate printing of device node name in log messages by inheriting from the Loggable class. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/libcamera/include/v4l2_device.h | 7 ++++++- src/libcamera/v4l2_device.cpp | 16 +++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 988e646c5de1..983b9d900aea 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -15,6 +15,8 @@ #include +#include "log.h" + namespace libcamera { class Buffer; @@ -76,7 +78,7 @@ public: unsigned int planesCount; }; -class V4L2Device +class V4L2Device : protected Loggable { public: explicit V4L2Device(const std::string &deviceNode); @@ -106,6 +108,9 @@ public: int streamOn(); int streamOff(); +protected: + std::string logPrefix() const; + private: int getFormatSingleplane(V4L2DeviceFormat *format); int setFormatSingleplane(V4L2DeviceFormat *format); diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 64325ff9f5d9..23c0da295905 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -262,8 +262,7 @@ int V4L2Device::open() if (ret < 0) { ret = -errno; LOG(V4L2, Error) - << "Failed to open V4L2 device '" << deviceNode_ - << "': " << strerror(-ret); + << "Failed to open V4L2 device: " << strerror(-ret); return ret; } fd_ = ret; @@ -278,9 +277,8 @@ int V4L2Device::open() } LOG(V4L2, Debug) - << "Opened '" << deviceNode_ << "' " - << caps_.bus_info() << ": " << caps_.driver() - << ": " << caps_.card(); + << "Opened device " << caps_.bus_info() << ": " + << caps_.driver() << ": " << caps_.card(); if (!caps_.isCapture() && !caps_.isOutput()) { LOG(V4L2, Debug) << "Device is not a supported type"; @@ -350,6 +348,11 @@ void V4L2Device::close() * \return The string containing the device location */ +std::string V4L2Device::logPrefix() const +{ + return deviceNode_; +} + /** * \brief Retrieve the image format set on the V4L2 device * \param[out] format The image format applied on the device @@ -519,8 +522,7 @@ int V4L2Device::requestBuffers(unsigned int count) return ret; } - LOG(V4L2, Debug) - << deviceNode_ << ":" << rb.count << " buffers requested."; + LOG(V4L2, Debug) << rb.count << " buffers requested."; return rb.count; }