lib/fmt: drop use of FMT_STRING
When compiling with libfmt-11.1.0 and newer the following compile errors occur: In file included from ../src/decoder/DecoderPrint.cxx:23: ../src/client/Response.hxx: In instantiation of 'bool Response::Fmt(const S&, Args&& ...) [with S = decoder_plugin_print(Response&, const DecoderPlugin&)::<lambda()>::FMT_COMPILE_STRING; Args = {const char* const&}]': ../src/decoder/DecoderPrint.cxx:38:7: required from here 38 | r.Fmt(FMT_STRING("plugin: {}\n"), plugin.name); | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../src/client/Response.hxx:86:28: error: cannot convert 'const decoder_plugin_print(Response&, const DecoderPlugin&)::<lambda()>::FMT_COMPILE_STRING' to 'fmt::v11::string_view' {aka 'fmt::v11::basic_string_view<char>'} 86 | return VFmt(format_str, | ~~~~^~~~~~~~~~~~ 87 | fmt::make_format_args(args...)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../src/client/Response.hxx:81:36: note: initializing argument 1 of 'bool Response::VFmt(fmt::v11::string_view, fmt::v11::format_args)' 81 | bool VFmt(fmt::string_view format_str, fmt::format_args args) noexcept; | ~~~~~~~~~~~~~~~~~^~~~~~~~~~ ../src/client/Response.hxx: In instantiation of 'bool Response::Fmt(const S&, Args&& ...) [with S = decoder_plugin_print(Response&, const DecoderPlugin&)::<lambda()>::FMT_COMPILE_STRING; Args = {const char* const&}]': The error is due to the use of FMT_STRING. The libfmt team shared the following: The correct way of using FMT_STRING is to wrap a format string when passing to a function with compile-time checks (i.e. that takes format_string) as documented in https://fmt.dev/11.1/api/#legacy-compile-time-checks. Noting that FMT_STRING is a legacy API and has been superseded by consteval-based API starting from version 8: https://github.com/fmtlib/fmt/releases/tag/8.0.0. It looks like MPD is trying to emulate {fmt}'s old way of implementing compile-time checks which was never properly documented because it was basically a hack. So the correct fix is to switch to format_string and, possibly, remove usage of FMT_STRING. The old way of doing compile-time checks (fmt::make_args_checked) was documented in https://fmt.dev/7.1/api.html#argument-lists but it looks like MPD is not using that API so the problematic uses of FMT_STRING have no effect and can just be removed. The FMT_STRING has been removed in this change based on the fmt-7.1 API and now MPD is successfully compile against the current libfmt-11.1.0 which highlighted the issue that had been present in the codebase as it is now triggering the error, is legacy and was not using the API for which FMT_STRING was aligned with.
This commit is contained in:
@@ -255,7 +255,7 @@ PrintAvailableCommands(Response &r, const Partition &partition,
|
||||
|
||||
if (cmd->permission == (permission & cmd->permission) &&
|
||||
command_available(partition, cmd))
|
||||
r.Fmt(FMT_STRING("command: {}\n"), cmd->cmd);
|
||||
r.Fmt("command: {}\n", cmd->cmd);
|
||||
}
|
||||
|
||||
return CommandResult::OK;
|
||||
@@ -268,7 +268,7 @@ PrintUnavailableCommands(Response &r, unsigned permission) noexcept
|
||||
const struct command *cmd = &i;
|
||||
|
||||
if (cmd->permission != (permission & cmd->permission))
|
||||
r.Fmt(FMT_STRING("command: {}\n"), cmd->cmd);
|
||||
r.Fmt("command: {}\n", cmd->cmd);
|
||||
}
|
||||
|
||||
return CommandResult::OK;
|
||||
@@ -326,7 +326,7 @@ command_check_request(const struct command *cmd, Response &r,
|
||||
{
|
||||
if (cmd->permission != (permission & cmd->permission)) {
|
||||
r.FmtError(ACK_ERROR_PERMISSION,
|
||||
FMT_STRING("you don't have permission for \"{}\""),
|
||||
"you don't have permission for \"{}\"",
|
||||
cmd->cmd);
|
||||
return false;
|
||||
}
|
||||
@@ -339,17 +339,17 @@ command_check_request(const struct command *cmd, Response &r,
|
||||
|
||||
if (min == max && unsigned(max) != args.size) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("wrong number of arguments for \"{}\""),
|
||||
"wrong number of arguments for \"{}\"",
|
||||
cmd->cmd);
|
||||
return false;
|
||||
} else if (args.size < unsigned(min)) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("too few arguments for \"{}\""),
|
||||
"too few arguments for \"{}\"",
|
||||
cmd->cmd);
|
||||
return false;
|
||||
} else if (max >= 0 && args.size > unsigned(max)) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("too many arguments for \"{}\""),
|
||||
"too many arguments for \"{}\"",
|
||||
cmd->cmd);
|
||||
return false;
|
||||
} else
|
||||
@@ -363,7 +363,7 @@ command_checked_lookup(Response &r, unsigned permission,
|
||||
const struct command *cmd = command_lookup(cmd_name);
|
||||
if (cmd == nullptr) {
|
||||
r.FmtError(ACK_ERROR_UNKNOWN,
|
||||
FMT_STRING("unknown command \"{}\""), cmd_name);
|
||||
"unknown command \"{}\"", cmd_name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@@ -243,7 +243,7 @@ handle_count(Client &client, Request args, Response &r)
|
||||
group = tag_name_parse_i(s);
|
||||
if (group == TAG_NUM_OF_ITEM_TYPES) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("Unknown tag type: {}"), s);
|
||||
"Unknown tag type: {}", s);
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ handle_list(Client &client, Request args, Response &r)
|
||||
const auto tagType = tag_name_parse_i(tag_name);
|
||||
if (tagType == TAG_NUM_OF_ITEM_TYPES) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("Unknown tag type: {}"), tag_name);
|
||||
"Unknown tag type: {}", tag_name);
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ handle_list(Client &client, Request args, Response &r)
|
||||
/* for compatibility with < 0.12.0 */
|
||||
if (tagType != TAG_ALBUM) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("should be \"{}\" for 3 arguments"),
|
||||
"should be \"{}\" for 3 arguments",
|
||||
tag_item_names[TAG_ALBUM]);
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
@@ -341,7 +341,7 @@ handle_list(Client &client, Request args, Response &r)
|
||||
const auto group = tag_name_parse_i(s);
|
||||
if (group == TAG_NUM_OF_ITEM_TYPES) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("Unknown tag type: {}"), s);
|
||||
"Unknown tag type: {}", s);
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
||||
|
@@ -85,12 +85,12 @@ handle_listfiles_local(Response &r, Path path_fs)
|
||||
continue;
|
||||
|
||||
if (fi.IsRegular())
|
||||
r.Fmt(FMT_STRING("file: {}\n"
|
||||
"size: {}\n"),
|
||||
r.Fmt("file: {}\n"
|
||||
"size: {}\n",
|
||||
name_utf8,
|
||||
fi.GetSize());
|
||||
else if (fi.IsDirectory())
|
||||
r.Fmt(FMT_STRING("directory: {}\n"), name_utf8);
|
||||
r.Fmt("directory: {}\n", name_utf8);
|
||||
else
|
||||
continue;
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
void OnPair(StringView _key, StringView _value) noexcept override {
|
||||
const std::string_view key{_key}, value{_value};
|
||||
if (IsValidName(key) && IsValidValue(value))
|
||||
response.Fmt(FMT_STRING("{}: {}\n"), key, value);
|
||||
response.Fmt("{}: {}\n", key, value);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -218,7 +218,7 @@ read_stream_art(Response &r, const std::string_view art_directory,
|
||||
read_size = is->Read(lock, buffer.get(), buffer_size);
|
||||
}
|
||||
|
||||
r.Fmt(FMT_STRING("size: {}\n"), art_file_size);
|
||||
r.Fmt("size: {}\n", art_file_size);
|
||||
|
||||
r.WriteBinary({buffer.get(), read_size});
|
||||
|
||||
@@ -348,10 +348,10 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
response.Fmt(FMT_STRING("size: {}\n"), buffer.size);
|
||||
response.Fmt("size: {}\n", buffer.size);
|
||||
|
||||
if (mime_type != nullptr)
|
||||
response.Fmt(FMT_STRING("type: {}\n"), mime_type);
|
||||
response.Fmt("type: {}\n", mime_type);
|
||||
|
||||
buffer.size -= offset;
|
||||
|
||||
|
@@ -87,7 +87,7 @@ handle_channels(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
}
|
||||
|
||||
for (const auto &channel : channels)
|
||||
r.Fmt(FMT_STRING("channel: {}\n"), channel);
|
||||
r.Fmt("channel: {}\n", channel);
|
||||
|
||||
return CommandResult::OK;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ handle_read_messages(Client &client,
|
||||
assert(args.empty());
|
||||
|
||||
client.ConsumeMessages([&r](const auto &msg){
|
||||
r.Fmt(FMT_STRING("channel: {}\nmessage: {}\n"),
|
||||
r.Fmt("channel: {}\nmessage: {}\n",
|
||||
msg.GetChannel(), msg.GetMessage());
|
||||
});
|
||||
|
||||
|
@@ -62,7 +62,7 @@ static void
|
||||
print_spl_list(Response &r, const PlaylistVector &list)
|
||||
{
|
||||
for (const auto &i : list) {
|
||||
r.Fmt(FMT_STRING("playlist: {}\n"), i.name);
|
||||
r.Fmt("playlist: {}\n", i.name);
|
||||
|
||||
if (!IsNegative(i.mtime))
|
||||
time_print(r, "Last-Modified", i.mtime);
|
||||
@@ -249,7 +249,7 @@ handle_update(Response &r, UpdateService &update,
|
||||
const char *uri_utf8, bool discard)
|
||||
{
|
||||
unsigned ret = update.Enqueue(uri_utf8, discard);
|
||||
r.Fmt(FMT_STRING("updating_db: {}\n"), ret);
|
||||
r.Fmt("updating_db: {}\n", ret);
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ handle_update(Response &r, Database &db,
|
||||
{
|
||||
unsigned id = db.Update(uri_utf8, discard);
|
||||
if (id > 0) {
|
||||
r.Fmt(FMT_STRING("updating_db: {}\n"), id);
|
||||
r.Fmt("updating_db: {}\n", id);
|
||||
return CommandResult::OK;
|
||||
} else {
|
||||
/* Database::Update() has returned 0 without setting
|
||||
@@ -326,7 +326,7 @@ handle_getvol(Client &client, Request, Response &r)
|
||||
|
||||
const auto volume = partition.mixer_memento.GetVolume(partition.outputs);
|
||||
if (volume >= 0)
|
||||
r.Fmt(FMT_STRING("volume: {}\n"), volume);
|
||||
r.Fmt("volume: {}\n", volume);
|
||||
|
||||
return CommandResult::OK;
|
||||
}
|
||||
@@ -391,7 +391,7 @@ handle_config(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
const Storage *storage = client.GetStorage();
|
||||
if (storage != nullptr) {
|
||||
const auto path = storage->MapUTF8("");
|
||||
r.Fmt(FMT_STRING("music_directory: {}\n"), path);
|
||||
r.Fmt("music_directory: {}\n", path);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -406,7 +406,7 @@ handle_idle(Client &client, Request args, Response &r)
|
||||
unsigned event = idle_parse_name(i);
|
||||
if (event == 0) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("Unrecognized idle event: {}"),
|
||||
"Unrecognized idle event: {}",
|
||||
i);
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
@@ -48,7 +48,7 @@ CommandResult
|
||||
handle_listpartitions(Client &client, Request, Response &r)
|
||||
{
|
||||
for (const auto &partition : client.GetInstance().partitions) {
|
||||
r.Fmt(FMT_STRING("partition: {}\n"), partition.name);
|
||||
r.Fmt("partition: {}\n", partition.name);
|
||||
}
|
||||
|
||||
return CommandResult::OK;
|
||||
|
@@ -133,17 +133,17 @@ handle_status(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
|
||||
const auto volume = partition.mixer_memento.GetVolume(partition.outputs);
|
||||
if (volume >= 0)
|
||||
r.Fmt(FMT_STRING("volume: {}\n"), volume);
|
||||
r.Fmt("volume: {}\n", volume);
|
||||
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_REPEAT ": {}\n"
|
||||
COMMAND_STATUS_RANDOM ": {}\n"
|
||||
COMMAND_STATUS_SINGLE ": {}\n"
|
||||
COMMAND_STATUS_CONSUME ": {}\n"
|
||||
"partition: {}\n"
|
||||
COMMAND_STATUS_PLAYLIST ": {}\n"
|
||||
COMMAND_STATUS_PLAYLIST_LENGTH ": {}\n"
|
||||
COMMAND_STATUS_MIXRAMPDB ": {}\n"
|
||||
COMMAND_STATUS_STATE ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_REPEAT ": {}\n"
|
||||
COMMAND_STATUS_RANDOM ": {}\n"
|
||||
COMMAND_STATUS_SINGLE ": {}\n"
|
||||
COMMAND_STATUS_CONSUME ": {}\n"
|
||||
"partition: {}\n"
|
||||
COMMAND_STATUS_PLAYLIST ": {}\n"
|
||||
COMMAND_STATUS_PLAYLIST_LENGTH ": {}\n"
|
||||
COMMAND_STATUS_MIXRAMPDB ": {}\n"
|
||||
COMMAND_STATUS_STATE ": {}\n",
|
||||
(unsigned)playlist.GetRepeat(),
|
||||
(unsigned)playlist.GetRandom(),
|
||||
SingleToString(playlist.GetSingle()),
|
||||
@@ -155,24 +155,24 @@ handle_status(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
state);
|
||||
|
||||
if (pc.GetCrossFade() > FloatDuration::zero())
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_CROSSFADE ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_CROSSFADE ": {}\n",
|
||||
lround(pc.GetCrossFade().count()));
|
||||
|
||||
if (pc.GetMixRampDelay() > FloatDuration::zero())
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_MIXRAMPDELAY ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_MIXRAMPDELAY ": {}\n",
|
||||
pc.GetMixRampDelay().count());
|
||||
|
||||
song = playlist.GetCurrentPosition();
|
||||
if (song >= 0) {
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_SONG ": {}\n"
|
||||
COMMAND_STATUS_SONGID ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_SONG ": {}\n"
|
||||
COMMAND_STATUS_SONGID ": {}\n",
|
||||
song, playlist.PositionToId(song));
|
||||
}
|
||||
|
||||
if (player_status.state != PlayerState::STOP) {
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_TIME ": {}:{}\n"
|
||||
"elapsed: {:1.3f}\n"
|
||||
COMMAND_STATUS_BITRATE ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_TIME ": {}:{}\n"
|
||||
"elapsed: {:1.3f}\n"
|
||||
COMMAND_STATUS_BITRATE ": {}\n",
|
||||
player_status.elapsed_time.RoundS(),
|
||||
player_status.total_time.IsNegative()
|
||||
? 0U
|
||||
@@ -181,11 +181,11 @@ handle_status(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
player_status.bit_rate);
|
||||
|
||||
if (!player_status.total_time.IsNegative())
|
||||
r.Fmt(FMT_STRING("duration: {:1.3f}\n"),
|
||||
r.Fmt("duration: {:1.3f}\n",
|
||||
player_status.total_time.ToDoubleS());
|
||||
|
||||
if (player_status.audio_format.IsDefined())
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_AUDIO ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_AUDIO ": {}\n",
|
||||
player_status.audio_format);
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ handle_status(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
? update_service->GetId()
|
||||
: 0;
|
||||
if (updateJobId != 0) {
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_UPDATING_DB ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_UPDATING_DB ": {}\n",
|
||||
updateJobId);
|
||||
}
|
||||
#endif
|
||||
@@ -203,14 +203,14 @@ handle_status(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
try {
|
||||
pc.LockCheckRethrowError();
|
||||
} catch (...) {
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_ERROR ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_ERROR ": {}\n",
|
||||
GetFullMessage(std::current_exception()));
|
||||
}
|
||||
|
||||
song = playlist.GetNextPosition();
|
||||
if (song >= 0)
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_NEXTSONG ": {}\n"
|
||||
COMMAND_STATUS_NEXTSONGID ": {}\n"),
|
||||
r.Fmt(COMMAND_STATUS_NEXTSONG ": {}\n"
|
||||
COMMAND_STATUS_NEXTSONGID ": {}\n",
|
||||
song, playlist.PositionToId(song));
|
||||
|
||||
return CommandResult::OK;
|
||||
@@ -353,7 +353,7 @@ CommandResult
|
||||
handle_replay_gain_status(Client &client, [[maybe_unused]] Request args,
|
||||
Response &r)
|
||||
{
|
||||
r.Fmt(FMT_STRING("replay_gain_mode: {}\n"),
|
||||
r.Fmt("replay_gain_mode: {}\n",
|
||||
ToString(client.GetPartition().replay_gain_mode));
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
@@ -57,7 +57,7 @@ static void
|
||||
print_spl_list(Response &r, const PlaylistVector &list)
|
||||
{
|
||||
for (const auto &i : list) {
|
||||
r.Fmt(FMT_STRING("playlist: {}\n"), i.name);
|
||||
r.Fmt("playlist: {}\n", i.name);
|
||||
|
||||
if (!IsNegative(i.mtime))
|
||||
time_print(r, "Last-Modified", i.mtime);
|
||||
|
@@ -155,7 +155,7 @@ handle_addid(Client &client, Request args, Response &r)
|
||||
|
||||
partition.instance.LookupRemoteTag(uri);
|
||||
|
||||
r.Fmt(FMT_STRING("Id: {}\n"), added_id);
|
||||
r.Fmt("Id: {}\n", added_id);
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
|
@@ -67,14 +67,14 @@ handle_listfiles_storage(Response &r, StorageDirectoryReader &reader)
|
||||
continue;
|
||||
|
||||
case StorageFileInfo::Type::REGULAR:
|
||||
r.Fmt(FMT_STRING("file: {}\n"
|
||||
"size: {}\n"),
|
||||
r.Fmt("file: {}\n"
|
||||
"size: {}\n",
|
||||
name_utf8,
|
||||
info.size);
|
||||
break;
|
||||
|
||||
case StorageFileInfo::Type::DIRECTORY:
|
||||
r.Fmt(FMT_STRING("directory: {}\n"), name_utf8);
|
||||
r.Fmt("directory: {}\n", name_utf8);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ print_storage_uri(Client &client, Response &r, const Storage &storage)
|
||||
uri = std::move(allocated);
|
||||
}
|
||||
|
||||
r.Fmt(FMT_STRING("storage: {}\n"), uri);
|
||||
r.Fmt("storage: {}\n", uri);
|
||||
}
|
||||
|
||||
CommandResult
|
||||
@@ -143,7 +143,7 @@ handle_listmounts(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
|
||||
const auto visitor = [&client, &r](const char *mount_uri,
|
||||
const Storage &storage){
|
||||
r.Fmt(FMT_STRING("mount: {}\n"), mount_uri);
|
||||
r.Fmt("mount: {}\n", mount_uri);
|
||||
print_storage_uri(client, r, storage);
|
||||
};
|
||||
|
||||
|
@@ -35,7 +35,7 @@ handle_addtagid(Client &client, Request args, Response &r)
|
||||
const char *const tag_name = args[1];
|
||||
const TagType tag_type = tag_name_parse_i(tag_name);
|
||||
if (tag_type == TAG_NUM_OF_ITEM_TYPES) {
|
||||
r.FmtError(ACK_ERROR_ARG, FMT_STRING("Unknown tag type: {}"),
|
||||
r.FmtError(ACK_ERROR_ARG, "Unknown tag type: {}",
|
||||
tag_name);
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ handle_cleartagid(Client &client, Request args, Response &r)
|
||||
tag_type = tag_name_parse_i(tag_name);
|
||||
if (tag_type == TAG_NUM_OF_ITEM_TYPES) {
|
||||
r.FmtError(ACK_ERROR_ARG,
|
||||
FMT_STRING("Unknown tag type: {}"),
|
||||
"Unknown tag type: {}",
|
||||
tag_name);
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
Reference in New Issue
Block a user