From 0185d58a2bd0d9ad3081725abc87be2b3d45b0ef Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 23 Jun 2021 21:55:08 +0200 Subject: [PATCH] Log: add libfmt support --- meson.build | 2 + src/Log.cxx | 11 +++++ src/Log.hxx | 68 ++++++++++++++++++++++++++++ src/db/plugins/meson.build | 1 + src/decoder/meson.build | 3 ++ src/decoder/plugins/meson.build | 1 + src/filter/plugins/meson.build | 2 +- src/input/meson.build | 1 + src/lib/ffmpeg/meson.build | 1 + src/lib/fmt/AudioFormatFormatter.hxx | 48 ++++++++++++++++++++ src/lib/fmt/ExceptionFormatter.hxx | 46 +++++++++++++++++++ src/lib/fmt/PathFormatter.hxx | 40 ++++++++++++++++ src/lib/nfs/meson.build | 1 + src/lib/xiph/meson.build | 1 + src/mixer/meson.build | 3 ++ src/output/plugins/meson.build | 1 + src/storage/meson.build | 1 + src/system/meson.build | 3 ++ 18 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 src/lib/fmt/AudioFormatFormatter.hxx create mode 100644 src/lib/fmt/ExceptionFormatter.hxx create mode 100644 src/lib/fmt/PathFormatter.hxx diff --git a/meson.build b/meson.build index 625a0eb63..fa9a79934 100644 --- a/meson.build +++ b/meson.build @@ -241,10 +241,12 @@ log = static_library( 'src/Log.cxx', 'src/LogBackend.cxx', include_directories: inc, + dependencies: fmt_dep, ) log_dep = declare_dependency( link_with: log, + dependencies: fmt_dep, ) sources = [ diff --git a/src/Log.cxx b/src/Log.cxx index d5a22ef26..fb82703e6 100644 --- a/src/Log.cxx +++ b/src/Log.cxx @@ -21,6 +21,8 @@ #include "util/Domain.hxx" #include "util/Exception.hxx" +#include + #include #include @@ -28,6 +30,15 @@ static constexpr Domain exception_domain("exception"); +void +LogVFmt(LogLevel level, const Domain &domain, + fmt::string_view format_str, fmt::format_args args) noexcept +{ + fmt::memory_buffer buffer; + fmt::vformat_to(buffer, format_str, args); + Log(level, domain, {buffer.data(), buffer.size()}); +} + void LogFormatV(LogLevel level, const Domain &domain, const char *fmt, std::va_list ap) noexcept diff --git a/src/Log.hxx b/src/Log.hxx index 127fbfc1d..53c6775ac 100644 --- a/src/Log.hxx +++ b/src/Log.hxx @@ -23,6 +23,11 @@ #include "LogLevel.hxx" #include "util/Compiler.h" +#include +#if FMT_VERSION < 70000 +#include +#endif + #include #include @@ -31,6 +36,66 @@ class Domain; void Log(LogLevel level, const Domain &domain, std::string_view msg) noexcept; +void +LogVFmt(LogLevel level, const Domain &domain, + fmt::string_view format_str, fmt::format_args args) noexcept; + +template +void +LogFmt(LogLevel level, const Domain &domain, + const S &format_str, Args&&... args) noexcept +{ +#if FMT_VERSION >= 70000 + return LogVFmt(level, domain, fmt::to_string_view(format_str), + fmt::make_args_checked(format_str, + args...)); +#else + /* expensive fallback for older libfmt versions */ + const auto result = fmt::format(format_str, args...); + return Log(level, domain, result); +#endif +} + +template +void +FmtDebug(const Domain &domain, + const S &format_str, Args&&... args) noexcept +{ + LogFmt(LogLevel::DEBUG, domain, format_str, args...); +} + +template +void +FmtInfo(const Domain &domain, + const S &format_str, Args&&... args) noexcept +{ + LogFmt(LogLevel::INFO, domain, format_str, args...); +} + +template +void +FmtNotice(const Domain &domain, + const S &format_str, Args&&... args) noexcept +{ + LogFmt(LogLevel::NOTICE, domain, format_str, args...); +} + +template +void +FmtWarning(const Domain &domain, + const S &format_str, Args&&... args) noexcept +{ + LogFmt(LogLevel::WARNING, domain, format_str, args...); +} + +template +void +FmtError(const Domain &domain, + const S &format_str, Args&&... args) noexcept +{ + LogFmt(LogLevel::ERROR, domain, format_str, args...); +} + gcc_printf(3,4) void LogFormat(LogLevel level, const Domain &domain, const char *fmt, ...) noexcept; @@ -67,6 +132,9 @@ gcc_printf(2,3) void FormatDebug(const Domain &domain, const char *fmt, ...) noexcept; +void +FormatDebug(const Domain &domain, const char *fmt, ...) noexcept; + static inline void LogInfo(const Domain &domain, const char *msg) noexcept { diff --git a/src/db/plugins/meson.build b/src/db/plugins/meson.build index fdfd3d501..8ea565348 100644 --- a/src/db/plugins/meson.build +++ b/src/db/plugins/meson.build @@ -36,6 +36,7 @@ db_plugins = static_library( dependencies: [ upnp_dep, libmpdclient_dep, + log_dep, ], ) diff --git a/src/decoder/meson.build b/src/decoder/meson.build index b8bec5787..062d5cf1f 100644 --- a/src/decoder/meson.build +++ b/src/decoder/meson.build @@ -28,6 +28,9 @@ decoder_glue = static_library( 'decoder_glue', 'DecoderList.cxx', include_directories: inc, + dependencies: [ + log_dep, + ], ) decoder_glue_dep = declare_dependency( diff --git a/src/decoder/plugins/meson.build b/src/decoder/plugins/meson.build index 6dfb5de7a..2322eeaaa 100644 --- a/src/decoder/plugins/meson.build +++ b/src/decoder/plugins/meson.build @@ -208,6 +208,7 @@ decoder_plugins = static_library( ogg_dep, wavpack_dep, wildmidi_dep, + log_dep, ], ) diff --git a/src/filter/plugins/meson.build b/src/filter/plugins/meson.build index cf313f20b..b0dfb3708 100644 --- a/src/filter/plugins/meson.build +++ b/src/filter/plugins/meson.build @@ -1,5 +1,5 @@ filter_plugins_sources = [] -filter_plugins_deps = [] +filter_plugins_deps = [fmt_dep] if libavfilter_dep.found() filter_plugins_sources += [ diff --git a/src/input/meson.build b/src/input/meson.build index 03795b21b..282474ba6 100644 --- a/src/input/meson.build +++ b/src/input/meson.build @@ -45,6 +45,7 @@ input_glue = static_library( include_directories: inc, dependencies: [ boost_dep, + log_dep, ], ) diff --git a/src/lib/ffmpeg/meson.build b/src/lib/ffmpeg/meson.build index 31eda8167..43ceef505 100644 --- a/src/lib/ffmpeg/meson.build +++ b/src/lib/ffmpeg/meson.build @@ -41,6 +41,7 @@ ffmpeg = static_library( libavcodec_dep, libavfilter_dep, libavutil_dep, + log_dep, ], ) diff --git a/src/lib/fmt/AudioFormatFormatter.hxx b/src/lib/fmt/AudioFormatFormatter.hxx new file mode 100644 index 000000000..30206ff1d --- /dev/null +++ b/src/lib/fmt/AudioFormatFormatter.hxx @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AUDIO_FORMAT_FORMATTER_HXX +#define AUDIO_FORMAT_FORMATTER_HXX + +#include "pcm/AudioFormat.hxx" +#include "util/StringBuffer.hxx" + +#include + +template<> +struct fmt::formatter : formatter +{ + template + auto format(const AudioFormat &af, FormatContext &ctx) { + return formatter::format(ToString(af).c_str(), + ctx); + } +}; + +#endif diff --git a/src/lib/fmt/ExceptionFormatter.hxx b/src/lib/fmt/ExceptionFormatter.hxx new file mode 100644 index 000000000..31c9f0df2 --- /dev/null +++ b/src/lib/fmt/ExceptionFormatter.hxx @@ -0,0 +1,46 @@ +/* + * Copyright 2021 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef EXCEPTION_FORMATTER_HXX +#define EXCEPTION_FORMATTER_HXX + +#include "util/Exception.hxx" + +#include + +template<> +struct fmt::formatter : formatter +{ + template + auto format(std::exception_ptr e, FormatContext &ctx) { + return formatter::format(GetFullMessage(e), ctx); + } +}; + +#endif diff --git a/src/lib/fmt/PathFormatter.hxx b/src/lib/fmt/PathFormatter.hxx new file mode 100644 index 000000000..91aca6c7c --- /dev/null +++ b/src/lib/fmt/PathFormatter.hxx @@ -0,0 +1,40 @@ +/* + * Copyright 2003-2021 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef PATH_FORMATTER_HXX +#define PATH_FORMATTER_HXX + +#include "fs/Path.hxx" +#include "fs/AllocatedPath.hxx" + +#include + +template<> +struct fmt::formatter : formatter +{ + template + auto format(Path path, FormatContext &ctx) { + return formatter::format(path.ToUTF8(), ctx); + } +}; + +template<> +struct fmt::formatter : formatter {}; + +#endif diff --git a/src/lib/nfs/meson.build b/src/lib/nfs/meson.build index 3d52e0107..467da596b 100644 --- a/src/lib/nfs/meson.build +++ b/src/lib/nfs/meson.build @@ -16,6 +16,7 @@ nfs = static_library( include_directories: inc, dependencies: [ nfs_dep, + log_dep, ], ) diff --git a/src/lib/xiph/meson.build b/src/lib/xiph/meson.build index 4666d28fc..7f56c76e0 100644 --- a/src/lib/xiph/meson.build +++ b/src/lib/xiph/meson.build @@ -124,6 +124,7 @@ if libflac_dep.found() include_directories: inc, dependencies: [ libflac_dep, + log_dep, ], ) diff --git a/src/mixer/meson.build b/src/mixer/meson.build index 54a4bbb8b..748895b7b 100644 --- a/src/mixer/meson.build +++ b/src/mixer/meson.build @@ -8,6 +8,9 @@ mixer_glue = static_library( 'MixerType.cxx', 'MixerAll.cxx', include_directories: inc, + dependencies: [ + log_dep, + ], ) mixer_glue_dep = declare_dependency( diff --git a/src/output/plugins/meson.build b/src/output/plugins/meson.build index 0e51d86b5..a50146021 100644 --- a/src/output/plugins/meson.build +++ b/src/output/plugins/meson.build @@ -183,6 +183,7 @@ output_plugins = static_library( winmm_dep, wasapi_dep, boost_dep, + output_plugins_deps, ], ) diff --git a/src/storage/meson.build b/src/storage/meson.build index 6f5095c76..5aa214f01 100644 --- a/src/storage/meson.build +++ b/src/storage/meson.build @@ -20,6 +20,7 @@ storage_glue = static_library( include_directories: inc, dependencies: [ boost_dep, + log_dep, ], ) diff --git a/src/system/meson.build b/src/system/meson.build index e9ee888b1..eae95655b 100644 --- a/src/system/meson.build +++ b/src/system/meson.build @@ -17,6 +17,9 @@ system = static_library( 'system', system_sources, include_directories: inc, + dependencies: [ + log_dep, + ], ) if is_windows