diff --git a/src/TagPrint.cxx b/src/TagPrint.cxx index e204a21e6..812bdb452 100644 --- a/src/TagPrint.cxx +++ b/src/TagPrint.cxx @@ -2,6 +2,7 @@ // Copyright The Music Player Daemon Project #include "TagPrint.hxx" +#include "tag/Names.hxx" #include "tag/Tag.hxx" #include "tag/Settings.hxx" #include "client/Response.hxx" diff --git a/src/TagSave.cxx b/src/TagSave.cxx index f04d11544..00709712d 100644 --- a/src/TagSave.cxx +++ b/src/TagSave.cxx @@ -2,6 +2,7 @@ // Copyright The Music Player Daemon Project #include "TagSave.hxx" +#include "tag/Names.hxx" #include "tag/Tag.hxx" #include "io/BufferedOutputStream.hxx" diff --git a/src/command/DatabaseCommands.cxx b/src/command/DatabaseCommands.cxx index c4cf4496f..51cece639 100644 --- a/src/command/DatabaseCommands.cxx +++ b/src/command/DatabaseCommands.cxx @@ -13,6 +13,7 @@ #include "protocol/RangeArg.hxx" #include "client/Client.hxx" #include "client/Response.hxx" +#include "tag/Names.hxx" #include "tag/ParseName.hxx" #include "util/Exception.hxx" #include "util/StringAPI.hxx" diff --git a/src/db/DatabasePrint.cxx b/src/db/DatabasePrint.cxx index 91a10ed5d..d6f3d1c69 100644 --- a/src/db/DatabasePrint.cxx +++ b/src/db/DatabasePrint.cxx @@ -8,6 +8,7 @@ #include "client/Response.hxx" #include "Partition.hxx" #include "song/LightSong.hxx" +#include "tag/Names.hxx" #include "tag/Tag.hxx" #include "LightDirectory.hxx" #include "PlaylistInfo.hxx" diff --git a/src/db/plugins/simple/DatabaseSave.cxx b/src/db/plugins/simple/DatabaseSave.cxx index 2893c6136..d4004b8cf 100644 --- a/src/db/plugins/simple/DatabaseSave.cxx +++ b/src/db/plugins/simple/DatabaseSave.cxx @@ -7,6 +7,7 @@ #include "lib/fmt/RuntimeError.hxx" #include "io/BufferedOutputStream.hxx" #include "io/LineReader.hxx" +#include "tag/Names.hxx" #include "tag/ParseName.hxx" #include "tag/Settings.hxx" #include "fs/Charset.hxx" diff --git a/src/decoder/plugins/FfmpegMetaData.cxx b/src/decoder/plugins/FfmpegMetaData.cxx index 99545ce9d..ef2060782 100644 --- a/src/decoder/plugins/FfmpegMetaData.cxx +++ b/src/decoder/plugins/FfmpegMetaData.cxx @@ -5,6 +5,7 @@ #define __STDC_CONSTANT_MACROS #include "FfmpegMetaData.hxx" +#include "tag/Names.hxx" #include "tag/Table.hxx" #include "tag/Handler.hxx" #include "tag/Id3MusicBrainz.hxx" diff --git a/src/encoder/plugins/FlacEncoderPlugin.cxx b/src/encoder/plugins/FlacEncoderPlugin.cxx index 6ad51ee19..25d721619 100644 --- a/src/encoder/plugins/FlacEncoderPlugin.cxx +++ b/src/encoder/plugins/FlacEncoderPlugin.cxx @@ -3,6 +3,7 @@ #include "FlacEncoderPlugin.hxx" #include "../EncoderAPI.hxx" +#include "tag/Names.hxx" #include "pcm/AudioFormat.hxx" #include "pcm/Buffer.hxx" #include "lib/fmt/RuntimeError.hxx" diff --git a/src/encoder/plugins/OpusEncoderPlugin.cxx b/src/encoder/plugins/OpusEncoderPlugin.cxx index 2c977b180..117ad8b62 100644 --- a/src/encoder/plugins/OpusEncoderPlugin.cxx +++ b/src/encoder/plugins/OpusEncoderPlugin.cxx @@ -3,6 +3,7 @@ #include "OpusEncoderPlugin.hxx" #include "OggEncoder.hxx" +#include "tag/Names.hxx" #include "pcm/AudioFormat.hxx" #include "util/ByteOrder.hxx" #include "util/StringUtil.hxx" diff --git a/src/encoder/plugins/VorbisEncoderPlugin.cxx b/src/encoder/plugins/VorbisEncoderPlugin.cxx index 7c2322616..b258932ac 100644 --- a/src/encoder/plugins/VorbisEncoderPlugin.cxx +++ b/src/encoder/plugins/VorbisEncoderPlugin.cxx @@ -5,6 +5,7 @@ #include "OggEncoder.hxx" #include "lib/fmt/RuntimeError.hxx" #include "lib/xiph/VorbisComment.hxx" +#include "tag/Names.hxx" #include "pcm/AudioFormat.hxx" #include "config/Domain.hxx" #include "util/StringUtil.hxx" diff --git a/src/lib/xiph/ScanVorbisComment.cxx b/src/lib/xiph/ScanVorbisComment.cxx index 444bcf442..5c618c2fd 100644 --- a/src/lib/xiph/ScanVorbisComment.cxx +++ b/src/lib/xiph/ScanVorbisComment.cxx @@ -3,6 +3,7 @@ #include "ScanVorbisComment.hxx" #include "XiphTags.hxx" +#include "tag/Names.hxx" #include "tag/Table.hxx" #include "tag/Handler.hxx" #include "tag/VorbisComment.hxx" diff --git a/src/song/TagSongFilter.cxx b/src/song/TagSongFilter.cxx index b0a1f2e3d..13b5d48b0 100644 --- a/src/song/TagSongFilter.cxx +++ b/src/song/TagSongFilter.cxx @@ -4,6 +4,7 @@ #include "TagSongFilter.hxx" #include "Escape.hxx" #include "LightSong.hxx" +#include "tag/Names.hxx" #include "tag/Tag.hxx" #include "tag/Fallback.hxx" diff --git a/src/tag/GenParseName.cxx b/src/tag/GenParseName.cxx index 5dac15fc6..1a96ea69c 100644 --- a/src/tag/GenParseName.cxx +++ b/src/tag/GenParseName.cxx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The Music Player Daemon Project -#include "Type.h" +#include "Names.hxx" #include #include diff --git a/src/tag/Names.c b/src/tag/Names.c deleted file mode 100644 index 3b6606fd6..000000000 --- a/src/tag/Names.c +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The Music Player Daemon Project - -#include "Type.h" - -const char *const tag_item_names[TAG_NUM_OF_ITEM_TYPES] = { - [TAG_ARTIST] = "Artist", - [TAG_ARTIST_SORT] = "ArtistSort", - [TAG_ALBUM] = "Album", - [TAG_ALBUM_SORT] = "AlbumSort", - [TAG_ALBUM_ARTIST] = "AlbumArtist", - [TAG_ALBUM_ARTIST_SORT] = "AlbumArtistSort", - [TAG_TITLE] = "Title", - [TAG_TITLE_SORT] = "TitleSort", - [TAG_TRACK] = "Track", - [TAG_NAME] = "Name", - [TAG_GENRE] = "Genre", - [TAG_MOOD] = "Mood", - [TAG_DATE] = "Date", - [TAG_ORIGINAL_DATE] = "OriginalDate", - [TAG_COMPOSER] = "Composer", - [TAG_COMPOSERSORT] = "ComposerSort", - [TAG_PERFORMER] = "Performer", - [TAG_CONDUCTOR] = "Conductor", - [TAG_WORK] = "Work", - [TAG_MOVEMENT] = "Movement", - [TAG_MOVEMENTNUMBER] = "MovementNumber", - [TAG_ENSEMBLE] = "Ensemble", - [TAG_LOCATION] = "Location", - [TAG_GROUPING] = "Grouping", - [TAG_COMMENT] = "Comment", - [TAG_DISC] = "Disc", - [TAG_LABEL] = "Label", - - /* MusicBrainz tags from http://musicbrainz.org/doc/MusicBrainzTag */ - [TAG_MUSICBRAINZ_ARTISTID] = "MUSICBRAINZ_ARTISTID", - [TAG_MUSICBRAINZ_ALBUMID] = "MUSICBRAINZ_ALBUMID", - [TAG_MUSICBRAINZ_ALBUMARTISTID] = "MUSICBRAINZ_ALBUMARTISTID", - [TAG_MUSICBRAINZ_TRACKID] = "MUSICBRAINZ_TRACKID", - [TAG_MUSICBRAINZ_RELEASETRACKID] = "MUSICBRAINZ_RELEASETRACKID", - [TAG_MUSICBRAINZ_WORKID] = "MUSICBRAINZ_WORKID", -}; diff --git a/src/tag/Names.cxx b/src/tag/Names.cxx new file mode 100644 index 000000000..f6e1fbcaa --- /dev/null +++ b/src/tag/Names.cxx @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The Music Player Daemon Project + +#include "Names.hxx" +#include "Table.hxx" + +#include + +static constexpr struct tag_table tag_item_names_init[] = { + {"Artist", TAG_ARTIST}, + {"ArtistSort", TAG_ARTIST_SORT}, + {"Album", TAG_ALBUM}, + {"AlbumSort", TAG_ALBUM_SORT}, + {"AlbumArtist", TAG_ALBUM_ARTIST}, + {"AlbumArtistSort", TAG_ALBUM_ARTIST_SORT}, + {"Title", TAG_TITLE}, + {"TitleSort", TAG_TITLE_SORT}, + {"Track", TAG_TRACK}, + {"Name", TAG_NAME}, + {"Genre", TAG_GENRE}, + {"Mood", TAG_MOOD}, + {"Date", TAG_DATE}, + {"OriginalDate", TAG_ORIGINAL_DATE}, + {"Composer", TAG_COMPOSER}, + {"ComposerSort", TAG_COMPOSERSORT}, + {"Performer", TAG_PERFORMER}, + {"Conductor", TAG_CONDUCTOR}, + {"Work", TAG_WORK}, + {"Movement", TAG_MOVEMENT}, + {"MovementNumber", TAG_MOVEMENTNUMBER}, + {"Ensemble", TAG_ENSEMBLE}, + {"Location", TAG_LOCATION}, + {"Grouping", TAG_GROUPING}, + {"Comment", TAG_COMMENT}, + {"Disc", TAG_DISC}, + {"Label", TAG_LABEL}, + + /* MusicBrainz tags from http://musicbrainz.org/doc/MusicBrainzTag */ + {"MUSICBRAINZ_ARTISTID", TAG_MUSICBRAINZ_ARTISTID}, + {"MUSICBRAINZ_ALBUMID", TAG_MUSICBRAINZ_ALBUMID}, + {"MUSICBRAINZ_ALBUMARTISTID", TAG_MUSICBRAINZ_ALBUMARTISTID}, + {"MUSICBRAINZ_TRACKID", TAG_MUSICBRAINZ_TRACKID}, + {"MUSICBRAINZ_RELEASETRACKID", TAG_MUSICBRAINZ_RELEASETRACKID}, + {"MUSICBRAINZ_WORKID", TAG_MUSICBRAINZ_WORKID}, +}; + +/** + * This function converts the #tag_item_names_init array to an + * associative array at compile time. This is a kludge because C++20 + * doesn't support designated initializers for arrays, unlike C99. + */ +static constexpr auto +MakeTagNames() noexcept +{ + std::array result{}; + + static_assert(std::size(tag_item_names_init) == result.size()); + + for (const auto &i : tag_item_names_init) { + /* no duplicates allowed */ + assert(result[i.type] == nullptr); + + result[i.type] = i.name; + } + + return result; +} + +constinit const std::array tag_item_names = MakeTagNames(); diff --git a/src/tag/Names.hxx b/src/tag/Names.hxx new file mode 100644 index 000000000..8cc98d773 --- /dev/null +++ b/src/tag/Names.hxx @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The Music Player Daemon Project + +#pragma once + +#include "Type.h" + +#include + +/** + * An array of strings, which map the #TagType to its machine + * readable name (specific to the MPD protocol). + */ +extern const std::array tag_item_names; diff --git a/src/tag/ParseName.cxx b/src/tag/ParseName.cxx index b7d88a9b5..333a0faaf 100644 --- a/src/tag/ParseName.cxx +++ b/src/tag/ParseName.cxx @@ -2,6 +2,7 @@ // Copyright The Music Player Daemon Project #include "ParseName.hxx" +#include "Names.hxx" #include "util/ASCII.hxx" #include "util/StringCompare.hxx" diff --git a/src/tag/Type.h b/src/tag/Type.h index 05b2f6f98..823a37c6e 100644 --- a/src/tag/Type.h +++ b/src/tag/Type.h @@ -57,10 +57,4 @@ enum TagType TAG_NUM_OF_ITEM_TYPES }; -/** - * An array of strings, which map the #TagType to its machine - * readable name (specific to the MPD protocol). - */ -extern const char *const tag_item_names[]; - #endif diff --git a/src/tag/meson.build b/src/tag/meson.build index b643e1cf5..ac1bfe2ce 100644 --- a/src/tag/meson.build +++ b/src/tag/meson.build @@ -1,7 +1,7 @@ generate_parse_name = executable( 'GenParseName', 'GenParseName.cxx', - 'Names.c', + 'Names.cxx', native: true, ) @@ -22,7 +22,7 @@ tag_sources = [ 'Config.cxx', 'ParseName.cxx', parse_name_cxx, - 'Names.c', + 'Names.cxx', 'FixString.cxx', 'Pool.cxx', 'Table.cxx', diff --git a/test/DumpDecoderClient.cxx b/test/DumpDecoderClient.cxx index b51cb24f4..4dacc56fa 100644 --- a/test/DumpDecoderClient.cxx +++ b/test/DumpDecoderClient.cxx @@ -4,6 +4,7 @@ #include "DumpDecoderClient.hxx" #include "decoder/DecoderAPI.hxx" #include "input/InputStream.hxx" +#include "tag/Names.hxx" #include "util/StringBuffer.hxx" #include "util/Compiler.h" diff --git a/test/read_tags.cxx b/test/read_tags.cxx index da0220372..35b52a5c2 100644 --- a/test/read_tags.cxx +++ b/test/read_tags.cxx @@ -10,6 +10,7 @@ #include "input/InputStream.hxx" #include "tag/Handler.hxx" #include "tag/Generic.hxx" +#include "tag/Names.hxx" #include "fs/Path.hxx" #include "fs/NarrowPath.hxx" #include "pcm/AudioFormat.hxx" diff --git a/test/test_translate_song.cxx b/test/test_translate_song.cxx index 962ae550f..2626f79a1 100644 --- a/test/test_translate_song.cxx +++ b/test/test_translate_song.cxx @@ -8,6 +8,7 @@ #include "SongLoader.hxx" #include "client/Client.hxx" #include "tag/Builder.hxx" +#include "tag/Names.hxx" #include "tag/Tag.hxx" #include "util/Domain.hxx" #include "fs/AllocatedPath.hxx"