diff --git a/src/db/update/Playlist.cxx b/src/db/update/Playlist.cxx index 052d55e6d..7b3930801 100644 --- a/src/db/update/Playlist.cxx +++ b/src/db/update/Playlist.cxx @@ -17,9 +17,10 @@ #include "storage/FileInfo.hxx" #include "storage/StorageInterface.hxx" #include "fs/Traits.hxx" -#include "util/StringFormat.hxx" #include "Log.hxx" +#include + inline void UpdateWalk::UpdatePlaylistFile(Directory &directory, SongEnumerator &contents) noexcept @@ -41,8 +42,7 @@ UpdateWalk::UpdatePlaylistFile(Directory &directory, the virtual directory (DEVICE_PLAYLIST) to the containing directory */ : "../" + db_song->filename; - db_song->filename = StringFormat<64>("track%04u", - ++track); + db_song->filename = fmt::format("track{:04}", ++track); { const ScopeDatabaseLock protect; diff --git a/src/decoder/Thread.cxx b/src/decoder/Thread.cxx index 2ab2f7ee7..c21dff06a 100644 --- a/src/decoder/Thread.cxx +++ b/src/decoder/Thread.cxx @@ -54,7 +54,7 @@ DecoderUriDecode(const DecoderPlugin &plugin, { const ScopeUnlock unlock(bridge.dc.mutex); - FormatThreadName("decoder:%s", plugin.name); + FmtThreadName("decoder:{}", plugin.name); plugin.UriDecode(bridge, uri); @@ -98,7 +98,7 @@ decoder_stream_decode(const DecoderPlugin &plugin, { const ScopeUnlock unlock(bridge.dc.mutex); - FormatThreadName("decoder:%s", plugin.name); + FmtThreadName("decoder:{}", plugin.name); plugin.StreamDecode(bridge, input_stream); @@ -135,7 +135,7 @@ decoder_file_decode(const DecoderPlugin &plugin, { const ScopeUnlock unlock(bridge.dc.mutex); - FormatThreadName("decoder:%s", plugin.name); + FmtThreadName("decoder:{}", plugin.name); plugin.FileDecode(bridge, path); diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx index 87fa6952b..6986517a1 100644 --- a/src/decoder/plugins/GmeDecoderPlugin.cxx +++ b/src/decoder/plugins/GmeDecoderPlugin.cxx @@ -12,14 +12,16 @@ #include "fs/AllocatedPath.hxx" #include "fs/FileSystem.hxx" #include "fs/NarrowPath.hxx" +#include "lib/fmt/PathFormatter.hxx" #include "util/ScopeExit.hxx" #include "util/StringCompare.hxx" -#include "util/StringFormat.hxx" #include "util/Domain.hxx" #include "Log.hxx" #include +#include + #include #include @@ -228,16 +230,16 @@ ScanGmeInfo(const gme_info_t &info, unsigned song_num, int track_count, )); if (track_count > 1) - handler.OnTag(TAG_TRACK, StringFormat<16>("%u", song_num + 1).c_str()); + handler.OnTag(TAG_TRACK, fmt::format_int{song_num + 1}.c_str()); if (!StringIsEmpty(info.song)) { if (track_count > 1) { /* start numbering subtunes from 1 */ const auto tag_title = - StringFormat<1024>("%s (%u/%d)", - info.song, song_num + 1, - track_count); - handler.OnTag(TAG_TITLE, tag_title.c_str()); + fmt::format("{} ({}/{})", + info.song, song_num + 1, + track_count); + handler.OnTag(TAG_TITLE, tag_title); } else handler.OnTag(TAG_TITLE, info.song); } @@ -306,7 +308,7 @@ gme_container_scan(Path path_fs) if (num_songs < 2) return list; - const auto *subtune_suffix = path_fs.GetExtension(); + const Path subtune_suffix = Path::FromFS(path_fs.GetExtension()); TagBuilder tag_builder; @@ -315,10 +317,9 @@ gme_container_scan(Path path_fs) AddTagHandler h(tag_builder); ScanMusicEmu(emu, i, h); - const auto track_name = - StringFormat<64>(SUBTUNE_PREFIX "%03u.%s", i+1, - subtune_suffix); - tail = list.emplace_after(tail, track_name, + auto track_name = fmt::format(SUBTUNE_PREFIX "{:03}.{}", + i + 1, subtune_suffix); + tail = list.emplace_after(tail, std::move(track_name), tag_builder.Commit()); } diff --git a/src/decoder/plugins/SidplayDecoderPlugin.cxx b/src/decoder/plugins/SidplayDecoderPlugin.cxx index f889d4768..006472529 100644 --- a/src/decoder/plugins/SidplayDecoderPlugin.cxx +++ b/src/decoder/plugins/SidplayDecoderPlugin.cxx @@ -15,7 +15,6 @@ #ifdef HAVE_SIDPLAYFP #include "io/FileReader.hxx" #endif -#include "util/StringFormat.hxx" #include "util/Domain.hxx" #include "util/AllocatedString.hxx" #include "util/CharUtil.hxx" @@ -38,6 +37,8 @@ #include #endif +#include + #include #include @@ -510,8 +511,8 @@ ScanSidTuneInfo(const SidTuneInfo &info, unsigned track, unsigned n_tracks, if (n_tracks > 1) { const auto tag_title = - StringFormat<1024>("%s (%u/%u)", - album.c_str(), track, n_tracks); + fmt::format("{} ({}/{})", + album.c_str(), track, n_tracks); handler.OnTag(TAG_TITLE, tag_title.c_str()); } else handler.OnTag(TAG_TITLE, album.c_str()); @@ -532,7 +533,7 @@ ScanSidTuneInfo(const SidTuneInfo &info, unsigned track, unsigned n_tracks, handler.OnTag(TAG_DATE, date.c_str()); /* track */ - handler.OnTag(TAG_TRACK, StringFormat<16>("%u", track).c_str()); + handler.OnTag(TAG_TRACK, fmt::format_int{track}.c_str()); } static bool @@ -611,7 +612,7 @@ sidplay_container_scan(Path path_fs) /* Construct container/tune path names, eg. Delta.sid/tune_001.sid */ tail = list.emplace_after(tail, - StringFormat<32>(SUBTUNE_PREFIX "%03u.sid", i), + fmt::format(SUBTUNE_PREFIX "{:03}.sid", i), tag_builder.Commit()); } diff --git a/src/decoder/plugins/WildmidiDecoderPlugin.cxx b/src/decoder/plugins/WildmidiDecoderPlugin.cxx index b3f1efd76..7c41c1c87 100644 --- a/src/decoder/plugins/WildmidiDecoderPlugin.cxx +++ b/src/decoder/plugins/WildmidiDecoderPlugin.cxx @@ -5,11 +5,12 @@ #include "../DecoderAPI.hxx" #include "tag/Handler.hxx" #include "util/ScopeExit.hxx" -#include "util/StringFormat.hxx" #include "fs/AllocatedPath.hxx" #include "fs/FileSystem.hxx" #include "fs/Path.hxx" #include "fs/NarrowPath.hxx" +#include "lib/fmt/ToBuffer.hxx" +#include "lib/fmt/PathFormatter.hxx" #include "PluginUnavailable.hxx" #ifdef _WIN32 @@ -31,11 +32,9 @@ wildmidi_init(const ConfigBlock &block) block.GetPath("config_file", "/etc/timidity/timidity.cfg"); - if (!FileExists(path)) { - const auto utf8 = path.ToUTF8(); - throw PluginUnavailable(StringFormat<1024>("configuration file does not exist: %s", - utf8.c_str())); - } + if (!FileExists(path)) + throw PluginUnavailable{FmtBuffer<1024>("configuration file does not exist: {}", + path)}; #ifdef LIBWILDMIDI_VERSION /* WildMidi_ClearError() requires libwildmidi 0.4 */ diff --git a/src/input/ThreadInputStream.cxx b/src/input/ThreadInputStream.cxx index c844bda60..a9517a42d 100644 --- a/src/input/ThreadInputStream.cxx +++ b/src/input/ThreadInputStream.cxx @@ -51,7 +51,7 @@ ThreadInputStream::Start() inline void ThreadInputStream::ThreadFunc() noexcept { - FormatThreadName("input:%s", plugin); + FmtThreadName("input:{}", plugin); std::unique_lock lock(mutex); diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index be34ca231..409bdf88e 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -16,10 +16,10 @@ #include "config/Block.hxx" #include "tag/Builder.hxx" #include "tag/Tag.hxx" +#include "lib/fmt/ToBuffer.hxx" #include "event/Call.hxx" #include "event/Loop.hxx" #include "util/ASCII.hxx" -#include "util/StringFormat.hxx" #include "util/NumberParser.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -33,6 +33,8 @@ #include "util/UriQueryParser.hxx" #endif +#include + #include #include @@ -261,8 +263,8 @@ CurlInputStream::OnHeaders(unsigned status, if (status < 200 || status >= 300) throw HttpStatusError(status, - StringFormat<40>("got HTTP status %u", - status).c_str()); + FmtBuffer<40>("got HTTP status {}", + status).c_str()); const std::scoped_lock protect(mutex); @@ -475,8 +477,8 @@ CurlInputStream::InitEasy() if (proxy_user != nullptr && proxy_password != nullptr) request->SetOption(CURLOPT_PROXYUSERPWD, - StringFormat<1024>("%s:%s", proxy_user, - proxy_password).c_str()); + FmtBuffer<1024>("{}:{}", proxy_user, + proxy_password).c_str()); if (cacert != nullptr) request->SetOption(CURLOPT_CAINFO, cacert); @@ -532,8 +534,7 @@ CurlInputStream::SeekInternal(offset_type new_offset) if (offset > 0) request->SetOption(CURLOPT_RANGE, - StringFormat<40>("%" PRIoffset "-", - offset).c_str()); + fmt::format_int{offset}.c_str()); StartRequest(); } diff --git a/src/io/FileOutputStream.cxx b/src/io/FileOutputStream.cxx index 39e05dd3d..58cde80ac 100644 --- a/src/io/FileOutputStream.cxx +++ b/src/io/FileOutputStream.cxx @@ -4,7 +4,7 @@ #include "FileOutputStream.hxx" #include "lib/fmt/PathFormatter.hxx" #include "lib/fmt/SystemError.hxx" -#include "util/StringFormat.hxx" +#include "lib/fmt/ToBuffer.hxx" #ifdef _WIN32 #include @@ -282,7 +282,7 @@ try { /* hard-link the temporary file to the final path */ if (linkat(AT_FDCWD, - StringFormat<64>("/proc/self/fd/%d", fd.Get()), + FmtBuffer<64>("/proc/self/fd/{}", fd.Get()), directory_fd.Get(), path.c_str(), AT_SYMLINK_FOLLOW) < 0) throw FmtErrno("Failed to commit {}", path); diff --git a/src/lib/ffmpeg/LogCallback.cxx b/src/lib/ffmpeg/LogCallback.cxx index 843a37f54..d17a918bb 100644 --- a/src/lib/ffmpeg/LogCallback.cxx +++ b/src/lib/ffmpeg/LogCallback.cxx @@ -6,8 +6,8 @@ #include "LogCallback.hxx" #include "Domain.hxx" +#include "lib/fmt/ToBuffer.hxx" #include "util/Domain.hxx" -#include "util/StringFormat.hxx" #include "Log.hxx" extern "C" { @@ -40,9 +40,9 @@ FfmpegLogCallback(void *ptr, int level, const char *fmt, std::va_list vl) if (cls != nullptr) { const auto domain = - StringFormat<64>("%s/%s", - ffmpeg_domain.GetName(), - cls->item_name(ptr)); + FmtBuffer<64>("{}/{}", + ffmpeg_domain.GetName(), + cls->item_name(ptr)); const Domain d(domain); char msg[1024]; diff --git a/src/lib/nfs/Error.cxx b/src/lib/nfs/Error.cxx index 97a94aec7..98f0b2bc6 100644 --- a/src/lib/nfs/Error.cxx +++ b/src/lib/nfs/Error.cxx @@ -3,7 +3,7 @@ // author: Max Kellermann #include "Error.hxx" -#include "util/StringFormat.hxx" +#include "lib/fmt/ToBuffer.hxx" extern "C" { #include @@ -13,20 +13,20 @@ extern "C" { #include -static StringBuffer<256> +static auto FormatNfsClientError(struct nfs_context *nfs, const char *msg) noexcept { assert(msg != nullptr); const char *msg2 = nfs_get_error(nfs); - return StringFormat<256>("%s: %s", msg, msg2); + return FmtBuffer<256>("{}: {}", msg, msg2); } NfsClientError::NfsClientError(struct nfs_context *nfs, const char *msg) noexcept :std::runtime_error(FormatNfsClientError(nfs, msg).c_str()), code(0) {} -static StringBuffer<256> +static auto FormatNfsClientError(int err, struct nfs_context *nfs, void *data, const char *msg) noexcept { @@ -40,7 +40,7 @@ FormatNfsClientError(int err, struct nfs_context *nfs, void *data, msg2 = strerror(-err); } - return StringFormat<256>("%s: %s", msg, msg2); + return FmtBuffer<256>("{}: {}", msg, msg2); } NfsClientError::NfsClientError(int err, struct nfs_context *nfs, void *data, diff --git a/src/lib/sqlite/Database.cxx b/src/lib/sqlite/Database.cxx index eec66f13e..bbafb02a0 100644 --- a/src/lib/sqlite/Database.cxx +++ b/src/lib/sqlite/Database.cxx @@ -3,7 +3,7 @@ #include "Database.hxx" #include "Error.hxx" -#include "util/StringFormat.hxx" +#include "lib/fmt/ToBuffer.hxx" namespace Sqlite { @@ -12,8 +12,8 @@ Database::Database(const char *path) int result = sqlite3_open(path, &db); if (result != SQLITE_OK) throw SqliteError(db, result, - StringFormat<1024>("Failed to open sqlite database '%s'", - path)); + FmtBuffer<1024>("Failed to open sqlite database '{}'", + path)); } } // namespace Sqlite diff --git a/src/output/Init.cxx b/src/output/Init.cxx index d19805e2f..3a1509ed4 100644 --- a/src/output/Init.cxx +++ b/src/output/Init.cxx @@ -22,9 +22,10 @@ #include "filter/plugins/VolumeFilterPlugin.hxx" #include "filter/plugins/NormalizeFilterPlugin.hxx" #include "util/StringAPI.hxx" -#include "util/StringFormat.hxx" #include "Log.hxx" +#include + #include #include @@ -153,7 +154,7 @@ FilteredAudioOutput::Configure(const ConfigBlock &block, config_audio_format.Clear(); } - log_name = StringFormat<256>("\"%s\" (%s)", name, plugin_name); + log_name = fmt::format("\"{}\" ({})", name, plugin_name); /* create the normalization filter (if configured) */ diff --git a/src/output/Thread.cxx b/src/output/Thread.cxx index 87343cdf8..25611435d 100644 --- a/src/output/Thread.cxx +++ b/src/output/Thread.cxx @@ -405,7 +405,7 @@ AudioOutputControl::InternalDrain() noexcept void AudioOutputControl::Task() noexcept { - FormatThreadName("output:%s", GetName().c_str()); + FmtThreadName("output:{}", GetName()); try { SetThreadRealtime(); diff --git a/src/output/plugins/OSXOutputPlugin.cxx b/src/output/plugins/OSXOutputPlugin.cxx index 45fcdf8a9..ef40fb883 100644 --- a/src/output/plugins/OSXOutputPlugin.cxx +++ b/src/output/plugins/OSXOutputPlugin.cxx @@ -10,6 +10,7 @@ #include "../OutputAPI.hxx" #include "mixer/plugins/OSXMixerPlugin.hxx" #include "lib/fmt/RuntimeError.hxx" +#include "lib/fmt/ToBuffer.hxx" #include "util/Domain.hxx" #include "util/Manual.hxx" #include "pcm/Export.hxx" @@ -20,7 +21,6 @@ #include "util/RingBuffer.hxx" #include "util/StringAPI.hxx" #include "util/StringBuffer.hxx" -#include "util/StringFormat.hxx" #include "Log.hxx" #include @@ -42,20 +42,20 @@ static constexpr unsigned MPD_OSX_BUFFER_TIME_MS = 100; -static StringBuffer<64> -StreamDescriptionToString(const AudioStreamBasicDescription desc) +static auto +StreamDescriptionToString(const AudioStreamBasicDescription desc) noexcept { // Only convert the lpcm formats (nothing else supported / used by MPD) assert(desc.mFormatID == kAudioFormatLinearPCM); - return StringFormat<64>("%u channel %s %sinterleaved %u-bit %s %s (%uHz)", - desc.mChannelsPerFrame, - (desc.mFormatFlags & kAudioFormatFlagIsNonMixable) ? "" : "mixable", - (desc.mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? "non-" : "", - desc.mBitsPerChannel, - (desc.mFormatFlags & kAudioFormatFlagIsFloat) ? "Float" : "SInt", - (desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE", - (UInt32)desc.mSampleRate); + return FmtBuffer<256>("{} channel {} {}interleaved {}-bit {} {} ({}Hz)", + desc.mChannelsPerFrame, + (desc.mFormatFlags & kAudioFormatFlagIsNonMixable) ? "" : "mixable", + (desc.mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? "non-" : "", + desc.mBitsPerChannel, + (desc.mFormatFlags & kAudioFormatFlagIsFloat) ? "Float" : "SInt", + (desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE", + desc.mSampleRate); } diff --git a/src/output/plugins/ShoutOutputPlugin.cxx b/src/output/plugins/ShoutOutputPlugin.cxx index 1f772ae41..a2a377730 100644 --- a/src/output/plugins/ShoutOutputPlugin.cxx +++ b/src/output/plugins/ShoutOutputPlugin.cxx @@ -9,11 +9,12 @@ #include "util/Domain.hxx" #include "util/ScopeExit.hxx" #include "util/StringAPI.hxx" -#include "util/StringFormat.hxx" #include "Log.hxx" #include +#include + #include #include #include @@ -99,10 +100,10 @@ static void ShoutSetAudioInfo(shout_t *shout_conn, const AudioFormat &audio_format) { shout_set_audio_info(shout_conn, SHOUT_AI_CHANNELS, - StringFormat<11>("%u", audio_format.channels)); + fmt::format_int{static_cast(audio_format.channels)}.c_str()); shout_set_audio_info(shout_conn, SHOUT_AI_SAMPLERATE, - StringFormat<11>("%u", audio_format.sample_rate)); + fmt::format_int{audio_format.sample_rate}.c_str()); } #ifdef SHOUT_TLS diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx index 799a64bb2..6ebb1bd1c 100644 --- a/src/storage/plugins/CurlStorage.cxx +++ b/src/storage/plugins/CurlStorage.cxx @@ -15,6 +15,7 @@ #include "lib/curl/Escape.hxx" #include "lib/expat/ExpatParser.hxx" #include "lib/fmt/RuntimeError.hxx" +#include "lib/fmt/ToBuffer.hxx" #include "fs/Traits.hxx" #include "event/InjectEvent.hxx" #include "thread/Mutex.hxx" @@ -22,7 +23,6 @@ #include "util/ASCII.hxx" #include "util/SpanCast.hxx" #include "util/StringCompare.hxx" -#include "util/StringFormat.hxx" #include "util/StringSplit.hxx" #include "util/UriExtract.hxx" @@ -252,7 +252,7 @@ public: username/password are specified */ request.SetOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC); - request_headers.Append(StringFormat<40>("depth: %u", depth)); + request_headers.Append(FmtBuffer<40>("depth: {}", depth)); request_headers.Append("content-type: text/xml"); request.SetOption(CURLOPT_HTTPHEADER, request_headers.Get()); diff --git a/src/thread/Name.hxx b/src/thread/Name.hxx index 9daea8f16..113713d90 100644 --- a/src/thread/Name.hxx +++ b/src/thread/Name.hxx @@ -17,7 +17,7 @@ #endif #ifdef HAVE_THREAD_NAME -#include "util/StringFormat.hxx" +#include "lib/fmt/ToBuffer.hxx" #endif static inline void @@ -42,10 +42,10 @@ SetThreadName(const char *name) noexcept template static inline void -FormatThreadName(const char *fmt, [[maybe_unused]] Args&&... args) noexcept +FmtThreadName(const char *fmt, [[maybe_unused]] Args&&... args) noexcept { #ifdef HAVE_THREAD_NAME - SetThreadName(StringFormat<16>(fmt, args...)); + SetThreadName(FmtBuffer<16>(fmt, args...)); #else (void)fmt; #endif diff --git a/src/util/StringFormat.hxx b/src/util/StringFormat.hxx deleted file mode 100644 index 81adf98c4..000000000 --- a/src/util/StringFormat.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -// author: Max Kellermann - -#ifndef STRING_FORMAT_HXX -#define STRING_FORMAT_HXX - -#include "StringBuffer.hxx" // IWYU pragma: export - -#include - -template -static inline void -StringFormat(char *buffer, std::size_t size, - const char *fmt, Args&&... args) noexcept -{ - snprintf(buffer, size, fmt, args...); -} - -template -static inline void -StringFormat(StringBuffer &buffer, - const char *fmt, Args&&... args) noexcept -{ - StringFormat(buffer.data(), buffer.capacity(), fmt, args...); -} - -template -static inline StringBuffer -StringFormat(const char *fmt, Args&&... args) noexcept -{ - StringBuffer result; - StringFormat(result, fmt, args...); - return result; -} - -template -static inline void -StringFormatUnsafe(char *buffer, const char *fmt, Args&&... args) noexcept -{ - sprintf(buffer, fmt, args...); -} - -#endif