Commit 4faef28c authored by Max Kellermann's avatar Max Kellermann

Merge tag 'v0.20.7'

release v0.20.7
parents 89b90043 b4c9d9c2
......@@ -9,9 +9,12 @@ ver 0.21 (not yet released)
* output
- alsa: non-blocking mode
ver 0.20.7 (not yet released)
ver 0.20.7 (2017/05/15)
* database
- simple: fix false positive directory loop detection with NFS
* enforce a reasonable minimum audio_buffer_size setting
* cap buffer_before_play at 80% to prevent deadlock
* fix random crashes when compiled with clang
ver 0.20.6 (2017/03/10)
* input
......
......@@ -15,7 +15,7 @@ For basic installation instructions
- [Manual](http://www.musicpd.org/doc/user/)
- [Forum](http://forum.musicpd.org/)
- [IRC](irc://chat.freenode.net/#mpd)
- [Bug tracker](http://bugs.musicpd.org/)
- [Bug tracker](https://github.com/MusicPlayerDaemon/MPD/issues/)
# Developers
......
......@@ -97,20 +97,20 @@ Foo(const char *abc, int xyz)
<para>
MPD sources are managed in a git repository on <ulink
url="http://git.musicpd.org/">git.musicpd.org</ulink>.
url="https://github.com/MusicPlayerDaemon/">GitHub</ulink>.
</para>
<para>
Always write your code against the latest git:
</para>
<programlisting>git clone git://git.musicpd.org/master/mpd.git</programlisting>
<programlisting>git clone git://github.com/MusicPlayerDaemon/MPD</programlisting>
<para>
If you already have a clone, update it:
</para>
<programlisting>git pull --rebase git://git.musicpd.org/master/mpd.git master</programlisting>
<programlisting>git pull --rebase git://github.com/MusicPlayerDaemon/MPD master</programlisting>
<para>
You can do without "--rebase", but we recommend that you rebase
......@@ -188,17 +188,7 @@ Foo(const char *abc, int xyz)
</para>
<para>
<command>git pull</command> requests are preferred. Regular
contributors can get <ulink
url="http://git.musicpd.org/account-policy.html">an account on
git.musicpd.org</ulink>, but any public git repository will do.
</para>
<para>
There is <ulink url="https://github.com/MaxKellermann/MPD">a
mirror of the <application>MPD</application> git repository on
GitHub</ulink>, and you can use that as well to submit pull
requests.
<command>git pull</command> requests are preferred.
</para>
</chapter>
......
......@@ -48,7 +48,7 @@ mpd.conf(5), mpc(1)
.SH BUGS
If you find a bug, please report it at
.br
<\fBhttp://bugs.musicpd.org/bug_report_page.php\fP>.
<\fBhttps://github.com/MusicPlayerDaemon/MPD/issues/\fP>.
.SH AUTHORS
Max Kellermann <max.kellermann@gmail.com>
......
......@@ -1857,7 +1857,7 @@ buffer_size: 16384</programlisting>
<para>
If you believe you found a bug in
<application>MPD</application>, report it on <ulink
url="https://bugs.musicpd.org/my_view_page.php">the bug
url="https://github.com/MusicPlayerDaemon/MPD/issues/">the bug
tracker</ulink>.
</para>
......
......@@ -24,7 +24,7 @@
#include <stdio.h>
void
AudioFormat::ApplyMask(AudioFormat mask)
AudioFormat::ApplyMask(AudioFormat mask) noexcept
{
assert(IsValid());
assert(mask.IsMaskValid());
......@@ -42,7 +42,7 @@ AudioFormat::ApplyMask(AudioFormat mask)
}
StringBuffer<24>
ToString(const AudioFormat af)
ToString(const AudioFormat af) noexcept
{
StringBuffer<24> buffer;
......
......@@ -124,7 +124,7 @@ struct AudioFormat {
return !(*this == other);
}
void ApplyMask(AudioFormat mask);
void ApplyMask(AudioFormat mask) noexcept;
gcc_pure
AudioFormat WithMask(AudioFormat mask) const {
......@@ -223,6 +223,6 @@ AudioFormat::GetTimeToSize() const
*/
gcc_const
StringBuffer<24>
ToString(AudioFormat af);
ToString(AudioFormat af) noexcept;
#endif
......@@ -25,8 +25,6 @@
#ifndef MPD_AUDIO_PARSER_HXX
#define MPD_AUDIO_PARSER_HXX
#include "Compiler.h"
struct AudioFormat;
/**
......@@ -38,7 +36,6 @@ struct AudioFormat;
* @param src the input string
* @param mask if true, then "*" is allowed for any number of items
*/
gcc_pure
AudioFormat
ParseAudioFormat(const char *src, bool mask);
......
......@@ -45,19 +45,19 @@ DetachedSong::operator LightSong() const
}
bool
DetachedSong::IsRemote() const
DetachedSong::IsRemote() const noexcept
{
return uri_has_scheme(GetRealURI());
}
bool
DetachedSong::IsAbsoluteFile() const
DetachedSong::IsAbsoluteFile() const noexcept
{
return PathTraitsUTF8::IsAbsolute(GetRealURI());
}
bool
DetachedSong::IsInDatabase() const
DetachedSong::IsInDatabase() const noexcept
{
/* here, we use GetURI() and not GetRealURI() because
GetRealURI() is never relative */
......@@ -67,7 +67,7 @@ DetachedSong::IsInDatabase() const
}
SignedSongTime
DetachedSong::GetDuration() const
DetachedSong::GetDuration() const noexcept
{
SongTime a = start_time, b = end_time;
if (!b.IsPositive()) {
......
......@@ -111,7 +111,7 @@ public:
explicit operator LightSong() const;
gcc_pure
const char *GetURI() const {
const char *GetURI() const noexcept {
return uri.c_str();
}
......@@ -125,7 +125,7 @@ public:
* displayed URI?
*/
gcc_pure
bool HasRealURI() const {
bool HasRealURI() const noexcept {
return !real_uri.empty();
}
......@@ -134,7 +134,7 @@ public:
* GetURI().
*/
gcc_pure
const char *GetRealURI() const {
const char *GetRealURI() const noexcept {
return (HasRealURI() ? real_uri : uri).c_str();
}
......@@ -148,19 +148,19 @@ public:
* song.
*/
gcc_pure
bool IsSame(const DetachedSong &other) const {
bool IsSame(const DetachedSong &other) const noexcept {
return uri == other.uri &&
start_time == other.start_time &&
end_time == other.end_time;
}
gcc_pure gcc_nonnull_all
bool IsURI(const char *other_uri) const {
bool IsURI(const char *other_uri) const noexcept {
return uri == other_uri;
}
gcc_pure
bool IsRemote() const;
bool IsRemote() const noexcept;
gcc_pure
bool IsFile() const {
......@@ -168,10 +168,10 @@ public:
}
gcc_pure
bool IsAbsoluteFile() const;
bool IsAbsoluteFile() const noexcept;
gcc_pure
bool IsInDatabase() const;
bool IsInDatabase() const noexcept;
const Tag &GetTag() const {
return tag;
......@@ -226,7 +226,7 @@ public:
}
gcc_pure
SignedSongTime GetDuration() const;
SignedSongTime GetDuration() const noexcept;
/**
* Update the #tag and #mtime.
......
......@@ -47,13 +47,13 @@ static const char *const idle_names[] = {
};
const char*const*
idle_get_names(void)
idle_get_names() noexcept
{
return idle_names;
}
unsigned
idle_parse_name(const char *name)
idle_parse_name(const char *name) noexcept
{
#if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */
......
......@@ -73,8 +73,9 @@ static constexpr unsigned IDLE_PARTITION = 0x2000;
/**
* Get idle names
*/
gcc_const
const char*const*
idle_get_names();
idle_get_names() noexcept;
/**
* Parse an idle name and return its mask. Returns 0 if the given
......@@ -82,6 +83,6 @@ idle_get_names();
*/
gcc_nonnull_all gcc_pure
unsigned
idle_parse_name(const char *name);
idle_parse_name(const char *name) noexcept;
#endif
......@@ -128,7 +128,6 @@ struct Instance final
* DatabaseError if this MPD configuration has no database (no
* music_directory was configured).
*/
gcc_pure
const Database &GetDatabaseOrThrow() const;
#endif
......
......@@ -116,7 +116,13 @@
#include <limits.h>
static constexpr unsigned DEFAULT_BUFFER_SIZE = 4096;
static constexpr size_t KILOBYTE = 1024;
static constexpr size_t MEGABYTE = 1024 * KILOBYTE;
static constexpr size_t DEFAULT_BUFFER_SIZE = 4 * MEGABYTE;
static constexpr size_t MIN_BUFFER_SIZE = std::max(CHUNK_SIZE * 32,
64 * KILOBYTE);
static constexpr unsigned DEFAULT_BUFFER_BEFORE_PLAY = 10;
#ifdef ANDROID
......@@ -129,7 +135,6 @@ struct Config {
ReplayGainConfig replay_gain;
};
gcc_const
static Config
LoadConfig()
{
......@@ -306,12 +311,17 @@ initialize_decoder_and_player(const ReplayGainConfig &replay_gain_config)
FormatFatalError("buffer size \"%s\" is not a "
"positive integer, line %i",
param->value.c_str(), param->line);
buffer_size = tmp;
buffer_size = tmp * KILOBYTE;
if (buffer_size < MIN_BUFFER_SIZE) {
FormatWarning(config_domain, "buffer size %lu is too small, using %lu bytes instead",
(unsigned long)buffer_size,
(unsigned long)MIN_BUFFER_SIZE);
buffer_size = MIN_BUFFER_SIZE;
}
} else
buffer_size = DEFAULT_BUFFER_SIZE;
buffer_size *= 1024;
const unsigned buffered_chunks = buffer_size / CHUNK_SIZE;
if (buffered_chunks >= 1 << 15)
......@@ -329,6 +339,19 @@ initialize_decoder_and_player(const ReplayGainConfig &replay_gain_config)
"than 100 percent, line %i",
param->value.c_str(), param->line);
}
if (perc > 80) {
/* this upper limit should avoid deadlocks
which can occur because the DecoderThread
cannot ever fill the music buffer to
exactly 100%; a few chunks always need to
be available to generate silence in
Player::SendSilence() */
FormatError(config_domain,
"buffer_before_play is too large (%f%%), capping at 80%%; please fix your configuration",
perc);
perc = 80;
}
} else
perc = DEFAULT_BUFFER_BEFORE_PLAY;
......
......@@ -59,14 +59,14 @@ mapper_init(AllocatedPath &&_playlist_dir)
}
void
mapper_finish()
mapper_finish() noexcept
{
}
#ifdef ENABLE_DATABASE
AllocatedPath
map_uri_fs(const char *uri)
map_uri_fs(const char *uri) noexcept
{
assert(uri != nullptr);
assert(*uri != '/');
......@@ -86,7 +86,7 @@ map_uri_fs(const char *uri)
}
std::string
map_fs_to_utf8(Path path_fs)
map_fs_to_utf8(Path path_fs) noexcept
{
if (path_fs.IsAbsolute()) {
if (instance->storage == nullptr)
......@@ -109,13 +109,13 @@ map_fs_to_utf8(Path path_fs)
#endif
const AllocatedPath &
map_spl_path()
map_spl_path() noexcept
{
return playlist_dir_fs;
}
AllocatedPath
map_spl_utf8_to_fs(const char *name)
map_spl_utf8_to_fs(const char *name) noexcept
{
if (playlist_dir_fs.IsNull())
return AllocatedPath::Null();
......
......@@ -37,7 +37,7 @@ void
mapper_init(AllocatedPath &&playlist_dir);
void
mapper_finish();
mapper_finish() noexcept;
#ifdef ENABLE_DATABASE
......@@ -48,7 +48,7 @@ mapper_finish();
*/
gcc_pure
AllocatedPath
map_uri_fs(const char *uri);
map_uri_fs(const char *uri) noexcept;
/**
* Maps a file system path (relative to the music directory or
......@@ -60,7 +60,7 @@ map_uri_fs(const char *uri);
*/
gcc_pure
std::string
map_fs_to_utf8(Path path_fs);
map_fs_to_utf8(Path path_fs) noexcept;
#endif
......@@ -69,7 +69,7 @@ map_fs_to_utf8(Path path_fs);
*/
gcc_const
const AllocatedPath &
map_spl_path();
map_spl_path() noexcept;
/**
* Maps a playlist name (without the ".m3u" suffix) to a file system
......@@ -79,6 +79,6 @@ map_spl_path();
*/
gcc_pure
AllocatedPath
map_spl_utf8_to_fs(const char *name);
map_spl_utf8_to_fs(const char *name) noexcept;
#endif
......@@ -23,19 +23,19 @@
#include <assert.h>
MusicBuffer::MusicBuffer(unsigned num_chunks)
MusicBuffer::MusicBuffer(unsigned num_chunks) noexcept
:buffer(num_chunks) {
}
MusicChunk *
MusicBuffer::Allocate()
MusicBuffer::Allocate() noexcept
{
const std::lock_guard<Mutex> protect(mutex);
return buffer.Allocate();
}
void
MusicBuffer::Return(MusicChunk *chunk)
MusicBuffer::Return(MusicChunk *chunk) noexcept
{
assert(chunk != nullptr);
......
......@@ -41,7 +41,7 @@ public:
* @param num_chunks the number of #MusicChunk reserved in
* this buffer
*/
MusicBuffer(unsigned num_chunks);
MusicBuffer(unsigned num_chunks) noexcept;
#ifndef NDEBUG
/**
......@@ -71,13 +71,13 @@ public:
* @return an empty chunk or nullptr if there are no chunks
* available
*/
MusicChunk *Allocate();
MusicChunk *Allocate() noexcept;
/**
* Returns a chunk to the buffer. It can be reused by
* Allocate() then.
*/
void Return(MusicChunk *chunk);
void Return(MusicChunk *chunk) noexcept;
};
#endif
......@@ -31,7 +31,7 @@ MusicChunk::~MusicChunk()
#ifndef NDEBUG
bool
MusicChunk::CheckFormat(const AudioFormat other_format) const
MusicChunk::CheckFormat(const AudioFormat other_format) const noexcept
{
assert(other_format.IsValid());
......@@ -41,7 +41,7 @@ MusicChunk::CheckFormat(const AudioFormat other_format) const
WritableBuffer<void>
MusicChunk::Write(const AudioFormat af,
SongTime data_time, uint16_t _bit_rate)
SongTime data_time, uint16_t _bit_rate) noexcept
{
assert(CheckFormat(af));
assert(length == 0 || audio_format.IsValid());
......@@ -64,7 +64,7 @@ MusicChunk::Write(const AudioFormat af,
}
bool
MusicChunk::Expand(const AudioFormat af, size_t _length)
MusicChunk::Expand(const AudioFormat af, size_t _length) noexcept
{
const size_t frame_size = af.GetFrameSize();
......
......@@ -111,7 +111,7 @@ struct MusicChunk {
* specified audio_format.
*/
gcc_pure
bool CheckFormat(AudioFormat audio_format) const;
bool CheckFormat(AudioFormat audio_format) const noexcept;
#endif
/**
......@@ -127,7 +127,7 @@ struct MusicChunk {
*/
WritableBuffer<void> Write(AudioFormat af,
SongTime data_time,
uint16_t bit_rate);
uint16_t bit_rate) noexcept;
/**
* Increases the length of the chunk after the caller has written to
......@@ -138,7 +138,7 @@ struct MusicChunk {
* @param length the number of bytes which were appended
* @return true if the chunk is full
*/
bool Expand(AudioFormat af, size_t length);
bool Expand(AudioFormat af, size_t length) noexcept;
};
#endif
......@@ -25,7 +25,7 @@
#ifndef NDEBUG
bool
MusicPipe::Contains(const MusicChunk *chunk) const
MusicPipe::Contains(const MusicChunk *chunk) const noexcept
{
const std::lock_guard<Mutex> protect(mutex);
......
......@@ -86,7 +86,7 @@ public:
* Checks if the specified chunk is enqueued in the music pipe.
*/
gcc_pure
bool Contains(const MusicChunk *chunk) const;
bool Contains(const MusicChunk *chunk) const noexcept;
#endif
/**
......
......@@ -205,7 +205,6 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
*/
const Database *GetDatabase() const;
gcc_pure
const Database &GetDatabaseOrThrow() const;
/**
......
......@@ -49,7 +49,6 @@ static std::map<std::string, unsigned> permission_passwords;
static unsigned permission_default;
gcc_pure
static unsigned
ParsePermission(const char *p)
{
......
......@@ -24,7 +24,7 @@
#include <math.h>
float
ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const
ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const noexcept
{
float scale;
......
......@@ -40,23 +40,23 @@ struct ReplayGainTuple {
}
gcc_pure
float CalculateScale(const ReplayGainConfig &config) const;
float CalculateScale(const ReplayGainConfig &config) const noexcept;
};
struct ReplayGainInfo {
ReplayGainTuple track, album;
constexpr bool IsDefined() const {
constexpr bool IsDefined() const noexcept {
return track.IsDefined() || album.IsDefined();
}
const ReplayGainTuple &Get(ReplayGainMode mode) const {
const ReplayGainTuple &Get(ReplayGainMode mode) const noexcept {
return mode == ReplayGainMode::ALBUM
? (album.IsDefined() ? album : track)
: (track.IsDefined() ? track : album);
}
void Clear() {
void Clear() noexcept {
track.Clear();
album.Clear();
}
......
......@@ -25,7 +25,7 @@
#include <string.h>
const char *
ToString(ReplayGainMode mode)
ToString(ReplayGainMode mode) noexcept
{
switch (mode) {
case ReplayGainMode::AUTO:
......
......@@ -36,13 +36,12 @@ enum class ReplayGainMode : uint8_t {
*/
gcc_pure
const char *
ToString(ReplayGainMode mode);
ToString(ReplayGainMode mode) noexcept;
/**
* Parse a string to a #ReplayGainMode. Throws std::runtime_error on
* error.
*/
gcc_pure
ReplayGainMode
FromString(const char *s);
......
......@@ -39,7 +39,7 @@
#define LOCATE_TAG_ANY_KEY "any"
unsigned
locate_parse_type(const char *str)
locate_parse_type(const char *str) noexcept
{
if (StringEqualsCaseASCII(str, LOCATE_TAG_FILE_KEY) ||
StringEqualsCaseASCII(str, LOCATE_TAG_FILE_KEY_OLD))
......@@ -57,7 +57,6 @@ locate_parse_type(const char *str)
return tag_name_parse_i(str);
}
gcc_pure
static AllocatedString<>
ImportString(const char *p, bool fold_case)
{
......@@ -78,7 +77,7 @@ SongFilter::Item::Item(unsigned _tag, time_t _time)
}
bool
SongFilter::Item::StringMatch(const char *s) const
SongFilter::Item::StringMatch(const char *s) const noexcept
{
#if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */
......@@ -97,14 +96,14 @@ SongFilter::Item::StringMatch(const char *s) const
}
bool
SongFilter::Item::Match(const TagItem &item) const
SongFilter::Item::Match(const TagItem &item) const noexcept
{
return (tag == LOCATE_TAG_ANY_TYPE || (unsigned)item.type == tag) &&
StringMatch(item.value);
}
bool
SongFilter::Item::Match(const Tag &_tag) const
SongFilter::Item::Match(const Tag &_tag) const noexcept
{
bool visited_types[TAG_NUM_OF_ITEM_TYPES];
std::fill_n(visited_types, size_t(TAG_NUM_OF_ITEM_TYPES), false);
......@@ -140,7 +139,7 @@ SongFilter::Item::Match(const Tag &_tag) const
}
bool
SongFilter::Item::Match(const DetachedSong &song) const
SongFilter::Item::Match(const DetachedSong &song) const noexcept
{
if (tag == LOCATE_TAG_BASE_TYPE)
return uri_is_child_or_same(value.c_str(), song.GetURI());
......@@ -155,7 +154,7 @@ SongFilter::Item::Match(const DetachedSong &song) const
}
bool
SongFilter::Item::Match(const LightSong &song) const
SongFilter::Item::Match(const LightSong &song) const noexcept
{
if (tag == LOCATE_TAG_BASE_TYPE) {
const auto uri = song.GetURI();
......@@ -185,7 +184,7 @@ SongFilter::~SongFilter()
gcc_pure
static time_t
ParseTimeStamp(const char *s)
ParseTimeStamp(const char *s) noexcept
{
assert(s != nullptr);
......@@ -246,7 +245,7 @@ SongFilter::Parse(ConstBuffer<const char *> args, bool fold_case)
}
bool
SongFilter::Match(const DetachedSong &song) const
SongFilter::Match(const DetachedSong &song) const noexcept
{
for (const auto &i : items)
if (!i.Match(song))
......@@ -256,7 +255,7 @@ SongFilter::Match(const DetachedSong &song) const
}
bool
SongFilter::Match(const LightSong &song) const
SongFilter::Match(const LightSong &song) const noexcept
{
for (const auto &i : items)
if (!i.Match(song))
......@@ -266,7 +265,7 @@ SongFilter::Match(const LightSong &song) const
}
bool
SongFilter::HasOtherThanBase() const
SongFilter::HasOtherThanBase() const noexcept
{
for (const auto &i : items)
if (i.GetTag() != LOCATE_TAG_BASE_TYPE)
......@@ -276,7 +275,7 @@ SongFilter::HasOtherThanBase() const
}
const char *
SongFilter::GetBase() const
SongFilter::GetBase() const noexcept
{
for (const auto &i : items)
if (i.GetTag() == LOCATE_TAG_BASE_TYPE)
......
......@@ -80,19 +80,19 @@ public:
}
gcc_pure gcc_nonnull(2)
bool StringMatch(const char *s) const;
bool StringMatch(const char *s) const noexcept;
gcc_pure
bool Match(const TagItem &tag_item) const;
bool Match(const TagItem &tag_item) const noexcept;
gcc_pure
bool Match(const Tag &tag) const;
bool Match(const Tag &tag) const noexcept;
gcc_pure
bool Match(const DetachedSong &song) const;
bool Match(const DetachedSong &song) const noexcept;
gcc_pure
bool Match(const LightSong &song) const;
bool Match(const LightSong &song) const noexcept;
};
private:
......@@ -112,20 +112,20 @@ public:
bool Parse(ConstBuffer<const char *> args, bool fold_case=false);
gcc_pure
bool Match(const Tag &tag) const;
bool Match(const Tag &tag) const noexcept;
gcc_pure
bool Match(const DetachedSong &song) const;
bool Match(const DetachedSong &song) const noexcept;
gcc_pure
bool Match(const LightSong &song) const;
bool Match(const LightSong &song) const noexcept;
const std::list<Item> &GetItems() const {
const std::list<Item> &GetItems() const noexcept {
return items;
}
gcc_pure
bool IsEmpty() const {
bool IsEmpty() const noexcept {
return items.empty();
}
......@@ -133,7 +133,7 @@ public:
* Is there at least one item with "fold case" enabled?
*/
gcc_pure
bool HasFoldCase() const {
bool HasFoldCase() const noexcept {
for (const auto &i : items)
if (i.GetFoldCase())
return true;
......@@ -145,14 +145,14 @@ public:
* Does this filter contain constraints other than "base"?
*/
gcc_pure
bool HasOtherThanBase() const;
bool HasOtherThanBase() const noexcept;
/**
* Returns the "base" specification (if there is one) or
* nullptr.
*/
gcc_pure
const char *GetBase() const;
const char *GetBase() const noexcept;
};
/**
......@@ -160,6 +160,6 @@ public:
*/
gcc_pure
unsigned
locate_parse_type(const char *str);
locate_parse_type(const char *str) noexcept;
#endif
......@@ -50,7 +50,7 @@ StateFile::StateFile(AllocatedPath &&_path,
}
void
StateFile::RememberVersions()
StateFile::RememberVersions() noexcept
{
prev_volume_version = sw_volume_state_get_hash();
prev_output_version = audio_output_state_get_version();
......@@ -59,7 +59,7 @@ StateFile::RememberVersions()
}
bool
StateFile::IsModified() const
StateFile::IsModified() const noexcept
{
return prev_volume_version != sw_volume_state_get_hash() ||
prev_output_version != audio_output_state_get_version() ||
......
......@@ -67,14 +67,14 @@ private:
/**
* Save the current state versions for use with IsModified().
*/
void RememberVersions();
void RememberVersions() noexcept;
/**
* Check if MPD's state was modified since the last
* RememberVersions() call.
*/
gcc_pure
bool IsModified() const;
bool IsModified() const noexcept;
/* virtual methods from TimeoutMonitor */
void OnTimeout() override;
......
......@@ -40,7 +40,7 @@
gcc_pure
static bool
CheckDecoderPlugin(const DecoderPlugin &plugin,
const char *suffix, const char *mime)
const char *suffix, const char *mime) noexcept
{
return (mime != nullptr && plugin.SupportsMimeType(mime)) ||
(suffix != nullptr && plugin.SupportsSuffix(suffix));
......
......@@ -28,7 +28,7 @@
gcc_pure
static char *
FindSlash(char *p, size_t i)
FindSlash(char *p, size_t i) noexcept
{
for (; i > 0; --i)
if (p[i] == '/')
......@@ -39,7 +39,7 @@ FindSlash(char *p, size_t i)
gcc_pure
static const char *
FindSuffix(const char *p, const char *i)
FindSuffix(const char *p, const char *i) noexcept
{
for (; i > p; --i) {
if (*i == '.')
......
......@@ -93,7 +93,7 @@ public:
~Bzip2InputStream();
/* virtual methods from InputStream */
bool IsEOF() override;
bool IsEOF() noexcept override;
size_t Read(void *ptr, size_t size) override;
private:
......@@ -205,7 +205,7 @@ Bzip2InputStream::Read(void *ptr, size_t length)
}
bool
Bzip2InputStream::IsEOF()
Bzip2InputStream::IsEOF() noexcept
{
return eof;
}
......
......@@ -162,7 +162,7 @@ public:
}
/* virtual methods from InputStream */
bool IsEOF() override;
bool IsEOF() noexcept override;
size_t Read(void *ptr, size_t size) override;
};
......@@ -213,7 +213,7 @@ Iso9660InputStream::Read(void *ptr, size_t read_size)
}
bool
Iso9660InputStream::IsEOF()
Iso9660InputStream::IsEOF() noexcept
{
return offset == size;
}
......
......@@ -116,7 +116,7 @@ struct ZzipInputStream final : public InputStream {
}
/* virtual methods from InputStream */
bool IsEOF() override;
bool IsEOF() noexcept override;
size_t Read(void *ptr, size_t size) override;
void Seek(offset_type offset) override;
};
......@@ -147,7 +147,7 @@ ZzipInputStream::Read(void *ptr, size_t read_size)
}
bool
ZzipInputStream::IsEOF()
ZzipInputStream::IsEOF() noexcept
{
return offset_type(zzip_tell(file)) == size;
}
......
......@@ -46,7 +46,7 @@ Client::GetPlayerControl()
#ifdef ENABLE_DATABASE
const Database *
Client::GetDatabase() const
Client::GetDatabase() const noexcept
{
return partition->instance.GetDatabase();
}
......@@ -58,7 +58,7 @@ Client::GetDatabaseOrThrow() const
}
const Storage *
Client::GetStorage() const
Client::GetStorage() const noexcept
{
return partition->instance.storage;
}
......
......@@ -166,7 +166,7 @@ public:
};
gcc_pure
bool IsSubscribed(const char *channel_name) const {
bool IsSubscribed(const char *channel_name) const noexcept {
return subscriptions.find(channel_name) != subscriptions.end();
}
......@@ -211,16 +211,15 @@ public:
* Wrapper for Instance::GetDatabase().
*/
gcc_pure
const Database *GetDatabase() const;
const Database *GetDatabase() const noexcept;
/**
* Wrapper for Instance::GetDatabaseOrThrow().
*/
gcc_pure
const Database &GetDatabaseOrThrow() const;
gcc_pure
const Storage *GetStorage() const;
const Storage *GetStorage() const noexcept;
private:
/* virtual methods from class BufferedSocket */
......
......@@ -23,14 +23,14 @@
gcc_const
static bool
valid_channel_char(const char ch)
valid_channel_char(const char ch) noexcept
{
return IsAlphaNumericASCII(ch) ||
ch == '_' || ch == '-' || ch == '.' || ch == ':';
}
bool
client_message_valid_channel_name(const char *name)
client_message_valid_channel_name(const char *name) noexcept
{
do {
if (!valid_channel_char(*name))
......
......@@ -53,6 +53,6 @@ public:
gcc_pure
bool
client_message_valid_channel_name(const char *name);
client_message_valid_channel_name(const char *name) noexcept;
#endif
......@@ -54,7 +54,7 @@
gcc_const
static enum ack
ToAck(PlaylistResult result)
ToAck(PlaylistResult result) noexcept
{
switch (result) {
case PlaylistResult::SUCCESS:
......@@ -90,7 +90,7 @@ ToAck(PlaylistResult result)
#ifdef ENABLE_DATABASE
gcc_const
static enum ack
ToAck(DatabaseErrorCode code)
ToAck(DatabaseErrorCode code) noexcept
{
switch (code) {
case DatabaseErrorCode::DISABLED:
......@@ -107,7 +107,7 @@ ToAck(DatabaseErrorCode code)
gcc_pure
static enum ack
ToAck(std::exception_ptr ep)
ToAck(std::exception_ptr ep) noexcept
{
try {
std::rethrow_exception(ep);
......
......@@ -44,7 +44,7 @@
gcc_pure
static bool
SkipNameFS(PathTraitsFS::const_pointer_type name_fs)
SkipNameFS(PathTraitsFS::const_pointer_type name_fs) noexcept
{
return name_fs[0] == '.' &&
(name_fs[1] == 0 ||
......@@ -53,7 +53,7 @@ SkipNameFS(PathTraitsFS::const_pointer_type name_fs)
gcc_pure
static bool
skip_path(Path name_fs)
skip_path(Path name_fs) noexcept
{
return name_fs.HasNewline();
}
......@@ -107,7 +107,7 @@ handle_listfiles_local(Response &r, Path path_fs)
gcc_pure
static bool
IsValidName(const char *p)
IsValidName(const char *p) noexcept
{
if (!IsAlphaASCII(*p))
return false;
......@@ -123,7 +123,7 @@ IsValidName(const char *p)
gcc_pure
static bool
IsValidValue(const char *p)
IsValidValue(const char *p) noexcept
{
while (*p) {
const char ch = *p++;
......
......@@ -29,7 +29,7 @@
#include <string>
bool
neighbor_commands_available(const Instance &instance)
neighbor_commands_available(const Instance &instance) noexcept
{
return instance.neighbors != nullptr;
}
......
......@@ -30,7 +30,7 @@ class Response;
gcc_pure
bool
neighbor_commands_available(const Instance &instance);
neighbor_commands_available(const Instance &instance) noexcept;
CommandResult
handle_listneighbors(Client &client, Request request, Response &response);
......
......@@ -39,7 +39,7 @@
#include "util/ConstBuffer.hxx"
bool
playlist_commands_available()
playlist_commands_available() noexcept
{
return !map_spl_path().IsNull();
}
......
......@@ -29,7 +29,7 @@ class Response;
gcc_const
bool
playlist_commands_available();
playlist_commands_available() noexcept;
CommandResult
handle_save(Client &client, Request request, Response &response);
......
......@@ -45,7 +45,7 @@
gcc_pure
static bool
skip_path(const char *name_utf8)
skip_path(const char *name_utf8) noexcept
{
return strchr(name_utf8, '\n') != nullptr;
}
......
......@@ -68,7 +68,7 @@ ConfigBlock::~ConfigBlock()
}
const BlockParam *
ConfigBlock::GetBlockParam(const char *name) const
ConfigBlock::GetBlockParam(const char *name) const noexcept
{
for (const auto &i : block_params) {
if (i.name == name) {
......@@ -81,7 +81,8 @@ ConfigBlock::GetBlockParam(const char *name) const
}
const char *
ConfigBlock::GetBlockValue(const char *name, const char *default_value) const
ConfigBlock::GetBlockValue(const char *name,
const char *default_value) const noexcept
{
const BlockParam *bp = GetBlockParam(name);
if (bp == nullptr)
......@@ -128,7 +129,6 @@ ConfigBlock::GetBlockValue(const char *name, unsigned default_value) const
return bp->GetUnsignedValue();
}
gcc_pure
bool
ConfigBlock::GetBlockValue(const char *name, bool default_value) const
{
......
......@@ -44,13 +44,10 @@ struct BlockParam {
BlockParam(const char *_name, const char *_value, int _line=-1)
:name(_name), value(_value), line(_line), used(false) {}
gcc_pure
int GetIntValue() const;
gcc_pure
unsigned GetUnsignedValue() const;
gcc_pure
bool GetBoolValue() const;
};
......@@ -101,11 +98,11 @@ struct ConfigBlock {
}
gcc_nonnull_all gcc_pure
const BlockParam *GetBlockParam(const char *_name) const;
const BlockParam *GetBlockParam(const char *_name) const noexcept;
gcc_pure
const char *GetBlockValue(const char *name,
const char *default_value=nullptr) const;
const char *default_value=nullptr) const noexcept;
/**
* Same as config_get_path(), but looks up the setting in the
......@@ -116,13 +113,10 @@ struct ConfigBlock {
AllocatedPath GetPath(const char *name,
const char *default_value=nullptr) const;
gcc_pure
int GetBlockValue(const char *name, int default_value) const;
gcc_pure
unsigned GetBlockValue(const char *name, unsigned default_value) const;
gcc_pure
bool GetBlockValue(const char *name, bool default_value) const;
};
......
......@@ -75,7 +75,7 @@ void config_global_check(void)
}
const ConfigParam *
config_get_param(ConfigOption option)
config_get_param(ConfigOption option) noexcept
{
auto *param = config_data.params[unsigned(option)];
if (param != nullptr)
......@@ -84,7 +84,7 @@ config_get_param(ConfigOption option)
}
const ConfigBlock *
config_get_block(ConfigBlockOption option)
config_get_block(ConfigBlockOption option) noexcept
{
ConfigBlock *block = config_data.blocks[unsigned(option)];
if (block != nullptr)
......@@ -110,7 +110,7 @@ config_find_block(ConfigBlockOption option, const char *key, const char *value)
}
const char *
config_get_string(ConfigOption option, const char *default_value)
config_get_string(ConfigOption option, const char *default_value) noexcept
{
const auto *param = config_get_param(option);
......
......@@ -48,11 +48,11 @@ ReadConfigFile(Path path);
gcc_pure
const ConfigParam *
config_get_param(enum ConfigOption option);
config_get_param(enum ConfigOption option) noexcept;
gcc_pure
const ConfigBlock *
config_get_block(enum ConfigBlockOption option);
config_get_block(enum ConfigBlockOption option) noexcept;
/**
* Find a block with a matching attribute.
......@@ -61,20 +61,12 @@ config_get_block(enum ConfigBlockOption option);
* @param key the attribute name
* @param value the expected attribute value
*/
gcc_pure
const ConfigBlock *
config_find_block(ConfigBlockOption option, const char *key, const char *value);
/* Note on gcc_pure: Some of the functions declared pure are not
really pure in strict sense. They have side effect such that they
validate parameter's value and signal an error if it's invalid.
However, if the argument was already validated or we don't care
about the argument at all, this may be ignored so in the end, we
should be fine with calling those functions pure. */
gcc_pure
const char *
config_get_string(enum ConfigOption option, const char *default_value=nullptr);
config_get_string(enum ConfigOption option,
const char *default_value=nullptr) noexcept;
/**
* Returns an optional configuration variable which contains an
......@@ -86,11 +78,9 @@ config_get_string(enum ConfigOption option, const char *default_value=nullptr);
AllocatedPath
config_get_path(enum ConfigOption option);
gcc_pure
unsigned
config_get_unsigned(enum ConfigOption option, unsigned default_value);
gcc_pure
static inline std::chrono::steady_clock::duration
config_get_unsigned(ConfigOption option,
std::chrono::steady_clock::duration default_value)
......@@ -100,11 +90,9 @@ config_get_unsigned(ConfigOption option,
return std::chrono::steady_clock::duration(u);
}
gcc_pure
unsigned
config_get_positive(enum ConfigOption option, unsigned default_value);
gcc_pure
static inline std::chrono::steady_clock::duration
config_get_positive(ConfigOption option,
std::chrono::steady_clock::duration default_value)
......@@ -114,7 +102,6 @@ config_get_positive(ConfigOption option,
return std::chrono::steady_clock::duration(u);
}
gcc_pure
bool config_get_bool(enum ConfigOption option, bool default_value);
#endif
......@@ -102,13 +102,13 @@ enum class ConfigBlockOption {
*/
gcc_pure
enum ConfigOption
ParseConfigOptionName(const char *name);
ParseConfigOptionName(const char *name) noexcept;
/**
* @return #ConfigOption::MAX if not found
*/
gcc_pure
enum ConfigBlockOption
ParseConfigBlockOptionName(const char *name);
ParseConfigBlockOptionName(const char *name) noexcept;
#endif
......@@ -101,7 +101,7 @@ static_assert(n_config_block_templates == unsigned(ConfigBlockOption::MAX),
gcc_pure
static inline unsigned
ParseConfigTemplateName(const ConfigTemplate templates[], unsigned count,
const char *name)
const char *name) noexcept
{
unsigned i = 0;
for (; i < count; ++i)
......@@ -112,7 +112,7 @@ ParseConfigTemplateName(const ConfigTemplate templates[], unsigned count,
}
ConfigOption
ParseConfigOptionName(const char *name)
ParseConfigOptionName(const char *name) noexcept
{
return ConfigOption(ParseConfigTemplateName(config_param_templates,
n_config_param_templates,
......@@ -120,7 +120,7 @@ ParseConfigOptionName(const char *name)
}
ConfigBlockOption
ParseConfigBlockOptionName(const char *name)
ParseConfigBlockOptionName(const char *name) noexcept
{
return ConfigBlockOption(ParseConfigTemplateName(config_block_templates,
n_config_block_templates,
......
......@@ -71,7 +71,6 @@ struct ConfigParam {
*
* Throws #std::runtime_error on error.
*/
gcc_pure
AllocatedPath GetPath() const;
};
......
......@@ -45,7 +45,7 @@ extern ThreadId db_mutex_holder;
*/
gcc_pure
static inline bool
holding_db_lock(void)
holding_db_lock() noexcept
{
return db_mutex_holder.IsInside();
}
......
......@@ -31,7 +31,6 @@ class DetachedSong;
* "Detach" the #Song object, i.e. convert it to a #DetachedSong
* instance.
*/
gcc_pure
DetachedSong
DatabaseDetachSong(const Storage *storage, const LightSong &song);
......
......@@ -21,7 +21,7 @@
#include "tag/Tag.hxx"
SignedSongTime
LightSong::GetDuration() const
LightSong::GetDuration() const noexcept
{
SongTime a = start_time, b = end_time;
if (!b.IsPositive()) {
......
......@@ -76,7 +76,7 @@ struct LightSong {
SongTime end_time;
gcc_pure
std::string GetURI() const {
std::string GetURI() const noexcept {
if (directory == nullptr)
return std::string(uri);
......@@ -87,7 +87,7 @@ struct LightSong {
}
gcc_pure
SignedSongTime GetDuration() const;
SignedSongTime GetDuration() const noexcept;
};
#endif
......@@ -26,7 +26,7 @@
#include <assert.h>
PlaylistVector::iterator
PlaylistVector::find(const char *name)
PlaylistVector::find(const char *name) noexcept
{
assert(holding_db_lock());
assert(name != nullptr);
......
......@@ -31,7 +31,7 @@ protected:
* Caller must lock the #db_mutex.
*/
gcc_pure
iterator find(const char *name);
iterator find(const char *name) noexcept;
public:
using std::list<PlaylistInfo>::empty;
......
......@@ -38,7 +38,7 @@ const DatabasePlugin *const database_plugins[] = {
};
const DatabasePlugin *
GetDatabasePluginByName(const char *name)
GetDatabasePluginByName(const char *name) noexcept
{
for (auto i = database_plugins; *i != nullptr; ++i)
if (strcmp((*i)->name, name) == 0)
......
......@@ -32,6 +32,6 @@ extern const DatabasePlugin *const database_plugins[];
gcc_pure
const DatabasePlugin *
GetDatabasePluginByName(const char *name);
GetDatabasePluginByName(const char *name) noexcept;
#endif
......@@ -34,19 +34,19 @@ DatabaseSelection::DatabaseSelection(const char *_uri, bool _recursive,
}
bool
DatabaseSelection::IsEmpty() const
DatabaseSelection::IsEmpty() const noexcept
{
return uri.empty() && (filter == nullptr || filter->IsEmpty());
}
bool
DatabaseSelection::HasOtherThanBase() const
DatabaseSelection::HasOtherThanBase() const noexcept
{
return filter != nullptr && filter->HasOtherThanBase();
}
bool
DatabaseSelection::Match(const LightSong &song) const
DatabaseSelection::Match(const LightSong &song) const noexcept
{
return filter == nullptr || filter->Match(song);
}
......@@ -45,16 +45,16 @@ struct DatabaseSelection {
const SongFilter *_filter=nullptr);
gcc_pure
bool IsEmpty() const;
bool IsEmpty() const noexcept;
/**
* Does this selection contain constraints other than "base"?
*/
gcc_pure
bool HasOtherThanBase() const;
bool HasOtherThanBase() const noexcept;
gcc_pure
bool Match(const LightSong &song) const;
bool Match(const LightSong &song) const noexcept;
};
#endif
......@@ -220,7 +220,7 @@ ProxySong::ProxySong(const mpd_song *song)
gcc_const
static enum mpd_tag_type
Convert(TagType tag_type)
Convert(TagType tag_type) noexcept
{
for (auto i = &tag_table[0]; i->d != TAG_NUM_OF_ITEM_TYPES; ++i)
if (i->d == tag_type)
......@@ -578,7 +578,7 @@ Visit(struct mpd_connection *connection,
gcc_pure
static bool
Match(const SongFilter *filter, const LightSong &song)
Match(const SongFilter *filter, const LightSong &song) noexcept
{
return filter == nullptr || filter->Match(song);
}
......@@ -721,7 +721,7 @@ SearchSongs(struct mpd_connection *connection,
*/
gcc_pure
static bool
ServerSupportsSearchBase(const struct mpd_connection *connection)
ServerSupportsSearchBase(const struct mpd_connection *connection) noexcept
{
#if LIBMPDCLIENT_CHECK_VERSION(2,9,0)
return mpd_connection_cmp_server_version(connection, 0, 18, 0) >= 0;
......
......@@ -62,7 +62,7 @@ Directory::Delete()
}
const char *
Directory::GetName() const
Directory::GetName() const noexcept
{
assert(!IsRoot());
......@@ -86,7 +86,7 @@ Directory::CreateChild(const char *name_utf8)
}
const Directory *
Directory::FindChild(const char *name) const
Directory::FindChild(const char *name) const noexcept
{
assert(holding_db_lock());
......@@ -98,7 +98,7 @@ Directory::FindChild(const char *name) const
}
void
Directory::PruneEmpty()
Directory::PruneEmpty() noexcept
{
assert(holding_db_lock());
......@@ -115,7 +115,7 @@ Directory::PruneEmpty()
}
Directory::LookupResult
Directory::LookupDirectory(const char *uri)
Directory::LookupDirectory(const char *uri) noexcept
{
assert(holding_db_lock());
assert(uri != nullptr);
......@@ -170,7 +170,7 @@ Directory::AddSong(Song *song)
}
void
Directory::RemoveSong(Song *song)
Directory::RemoveSong(Song *song) noexcept
{
assert(holding_db_lock());
assert(song != nullptr);
......@@ -180,7 +180,7 @@ Directory::RemoveSong(Song *song)
}
const Song *
Directory::FindSong(const char *name_utf8) const
Directory::FindSong(const char *name_utf8) const noexcept
{
assert(holding_db_lock());
assert(name_utf8 != nullptr);
......@@ -197,13 +197,13 @@ Directory::FindSong(const char *name_utf8) const
gcc_pure
static bool
directory_cmp(const Directory &a, const Directory &b)
directory_cmp(const Directory &a, const Directory &b) noexcept
{
return IcuCollate(a.path.c_str(), b.path.c_str()) < 0;
}
void
Directory::Sort()
Directory::Sort() noexcept
{
assert(holding_db_lock());
......@@ -258,7 +258,7 @@ Directory::Walk(bool recursive, const SongFilter *filter,
}
LightDirectory
Directory::Export() const
Directory::Export() const noexcept
{
return LightDirectory(GetPath(), mtime);
}
......@@ -134,10 +134,10 @@ public:
* Caller must lock the #db_mutex.
*/
gcc_pure
const Directory *FindChild(const char *name) const;
const Directory *FindChild(const char *name) const noexcept;
gcc_pure
Directory *FindChild(const char *name) {
Directory *FindChild(const char *name) noexcept {
const Directory *cthis = this;
return const_cast<Directory *>(cthis->FindChild(name));
}
......@@ -177,10 +177,10 @@ public:
* @return the Directory, or nullptr if none was found
*/
gcc_pure
LookupResult LookupDirectory(const char *uri);
LookupResult LookupDirectory(const char *uri) noexcept;
gcc_pure
bool IsEmpty() const {
bool IsEmpty() const noexcept {
return children.empty() &&
songs.empty() &&
playlists.empty();
......@@ -195,13 +195,13 @@ public:
* Returns the base name of the directory.
*/
gcc_pure
const char *GetName() const;
const char *GetName() const noexcept;
/**
* Is this the root directory of the music database?
*/
gcc_pure
bool IsRoot() const {
bool IsRoot() const noexcept {
return parent == nullptr;
}
......@@ -229,10 +229,10 @@ public:
* Caller must lock the #db_mutex.
*/
gcc_pure
const Song *FindSong(const char *name_utf8) const;
const Song *FindSong(const char *name_utf8) const noexcept;
gcc_pure
Song *FindSong(const char *name_utf8) {
Song *FindSong(const char *name_utf8) noexcept {
const Directory *cthis = this;
return const_cast<Song *>(cthis->FindSong(name_utf8));
}
......@@ -248,19 +248,19 @@ public:
* invalidates the song object, because the "parent" attribute becomes
* stale), but does not free it.
*/
void RemoveSong(Song *song);
void RemoveSong(Song *song) noexcept;
/**
* Caller must lock the #db_mutex.
*/
void PruneEmpty();
void PruneEmpty() noexcept;
/**
* Sort all directory entries recursively.
*
* Caller must lock the #db_mutex.
*/
void Sort();
void Sort() noexcept;
/**
* Caller must lock #db_mutex.
......@@ -270,7 +270,7 @@ public:
VisitPlaylist visit_playlist) const;
gcc_pure
LightDirectory Export() const;
LightDirectory Export() const noexcept;
};
#endif
......@@ -40,7 +40,7 @@
gcc_const
static const char *
DeviceToTypeString(unsigned device)
DeviceToTypeString(unsigned device) noexcept
{
switch (device) {
case DEVICE_INARCHIVE:
......@@ -56,7 +56,7 @@ DeviceToTypeString(unsigned device)
gcc_pure
static unsigned
ParseTypeString(const char *type)
ParseTypeString(const char *type) noexcept
{
if (strcmp(type, "archive") == 0)
return DEVICE_INARCHIVE;
......
......@@ -77,7 +77,7 @@ Song::Free()
}
std::string
Song::GetURI() const
Song::GetURI() const noexcept
{
assert(*uri);
......@@ -96,7 +96,7 @@ Song::GetURI() const
}
LightSong
Song::Export() const
Song::Export() const noexcept
{
LightSong dest;
dest.directory = parent->IsRoot()
......
......@@ -123,10 +123,10 @@ struct Song {
* location within the music directory.
*/
gcc_pure
std::string GetURI() const;
std::string GetURI() const noexcept;
gcc_pure
LightSong Export() const;
LightSong Export() const noexcept;
};
typedef boost::intrusive::list<Song,
......
......@@ -26,7 +26,7 @@
#include <stdlib.h>
static int
compare_utf8_string(const char *a, const char *b)
compare_utf8_string(const char *a, const char *b) noexcept
{
if (a == nullptr)
return b == nullptr ? 0 : -1;
......@@ -42,8 +42,7 @@ compare_utf8_string(const char *a, const char *b)
* nullptr.
*/
static int
compare_string_tag_item(const Tag &a, const Tag &b,
TagType type)
compare_string_tag_item(const Tag &a, const Tag &b, TagType type) noexcept
{
return compare_utf8_string(a.GetValue(type),
b.GetValue(type));
......@@ -54,7 +53,7 @@ compare_string_tag_item(const Tag &a, const Tag &b,
* (e.g. disc or track number). Either one may be nullptr.
*/
static int
compare_number_string(const char *a, const char *b)
compare_number_string(const char *a, const char *b) noexcept
{
long ai = a == nullptr ? 0 : strtol(a, nullptr, 10);
long bi = b == nullptr ? 0 : strtol(b, nullptr, 10);
......@@ -69,7 +68,7 @@ compare_number_string(const char *a, const char *b)
}
static int
compare_tag_item(const Tag &a, const Tag &b, TagType type)
compare_tag_item(const Tag &a, const Tag &b, TagType type) noexcept
{
return compare_number_string(a.GetValue(type),
b.GetValue(type));
......@@ -78,7 +77,7 @@ compare_tag_item(const Tag &a, const Tag &b, TagType type)
/* Only used for sorting/searchin a songvec, not general purpose compares */
gcc_pure
static bool
song_cmp(const Song &a, const Song &b)
song_cmp(const Song &a, const Song &b) noexcept
{
int ret;
......@@ -102,7 +101,7 @@ song_cmp(const Song &a, const Song &b)
}
void
song_list_sort(SongList &songs)
song_list_sort(SongList &songs) noexcept
{
songs.sort(song_cmp);
}
......@@ -23,6 +23,6 @@
#include "Song.hxx"
void
song_list_sort(SongList &songs);
song_list_sort(SongList &songs) noexcept;
#endif
......@@ -39,7 +39,7 @@ UPnPDirContent::~UPnPDirContent()
gcc_pure
static UPnPDirObject::ItemClass
ParseItemClass(StringView name)
ParseItemClass(StringView name) noexcept
{
if (name.EqualsLiteral("object.item.audioItem.musicTrack"))
return UPnPDirObject::ItemClass::MUSIC;
......@@ -51,7 +51,7 @@ ParseItemClass(StringView name)
gcc_pure
static SignedSongTime
ParseDuration(const char *duration)
ParseDuration(const char *duration) noexcept
{
char *endptr;
......@@ -81,7 +81,7 @@ ParseDuration(const char *duration)
*/
gcc_pure
static std::string &&
TitleToPathSegment(std::string &&s)
TitleToPathSegment(std::string &&s) noexcept
{
std::replace(s.begin(), s.end(), '/', '_');
return std::move(s);
......
......@@ -40,7 +40,7 @@ public:
~UPnPDirContent();
gcc_pure
UPnPDirObject *FindObject(const char *name) {
UPnPDirObject *FindObject(const char *name) noexcept {
for (auto &o : objects)
if (o.name == name)
return &o;
......
......@@ -56,7 +56,7 @@ InotifyQueue::OnTimeout()
gcc_pure
static bool
path_in(const char *path, const char *possible_parent)
path_in(const char *path, const char *possible_parent) noexcept
{
if (StringIsEmpty(path))
return true;
......
......@@ -62,10 +62,10 @@ struct WatchDirectory {
WatchDirectory &operator=(const WatchDirectory &) = delete;
gcc_pure
unsigned GetDepth() const;
unsigned GetDepth() const noexcept;
gcc_pure
AllocatedPath GetUriFS() const;
AllocatedPath GetUriFS() const noexcept;
};
static InotifySource *inotify_source;
......@@ -132,7 +132,7 @@ remove_watch_directory(WatchDirectory *directory)
}
AllocatedPath
WatchDirectory::GetUriFS() const
WatchDirectory::GetUriFS() const noexcept
{
if (parent == nullptr)
return AllocatedPath::Null();
......@@ -225,7 +225,7 @@ recursive_watch_subdirectories(WatchDirectory *directory,
gcc_pure
unsigned
WatchDirectory::GetDepth() const
WatchDirectory::GetDepth() const noexcept
{
const WatchDirectory *d = this;
unsigned depth = 0;
......@@ -331,7 +331,7 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update,
}
void
mpd_inotify_finish(void)
mpd_inotify_finish(void) noexcept
{
if (inotify_source == nullptr)
return;
......
......@@ -32,6 +32,6 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update,
unsigned max_depth);
void
mpd_inotify_finish();
mpd_inotify_finish() noexcept;
#endif
......@@ -32,7 +32,7 @@
#include <errno.h>
bool
GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info)
GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info) noexcept
try {
info = storage.GetInfo(uri_utf8, true);
return true;
......@@ -42,7 +42,7 @@ try {
}
bool
GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info)
GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info) noexcept
try {
info = reader.GetInfo(true);
return true;
......@@ -52,7 +52,7 @@ try {
}
bool
DirectoryExists(Storage &storage, const Directory &directory)
DirectoryExists(Storage &storage, const Directory &directory) noexcept
{
StorageFileInfo info;
......@@ -79,7 +79,7 @@ GetDirectoryChildInfo(Storage &storage, const Directory &directory,
bool
directory_child_is_regular(Storage &storage, const Directory &directory,
const char *name_utf8)
const char *name_utf8) noexcept
try {
return GetDirectoryChildInfo(storage, directory, name_utf8)
.IsRegular();
......@@ -89,7 +89,7 @@ try {
bool
directory_child_access(Storage &storage, const Directory &directory,
const char *name, int mode)
const char *name, int mode) noexcept
{
#ifdef WIN32
/* CheckAccess() is useless on WIN32 */
......
......@@ -33,23 +33,23 @@ class StorageDirectoryReader;
* returning them.
*/
bool
GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info);
GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info) noexcept;
/**
* Wrapper for LocalDirectoryReader::GetInfo() that logs errors
* instead of returning them.
*/
bool
GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info);
GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info) noexcept;
gcc_pure
bool
DirectoryExists(Storage &storage, const Directory &directory);
DirectoryExists(Storage &storage, const Directory &directory) noexcept;
gcc_pure
bool
directory_child_is_regular(Storage &storage, const Directory &directory,
const char *name_utf8);
const char *name_utf8) noexcept;
/**
* Checks if the given permissions on the mapped file are given.
......@@ -57,6 +57,6 @@ directory_child_is_regular(Storage &storage, const Directory &directory,
gcc_pure
bool
directory_child_access(Storage &storage, const Directory &directory,
const char *name, int mode);
const char *name, int mode) noexcept;
#endif
......@@ -248,7 +248,7 @@ try {
/* we don't look at "." / ".." nor files with newlines in their name */
gcc_pure
static bool
skip_path(const char *name_utf8)
skip_path(const char *name_utf8) noexcept
{
return strchr(name_utf8, '\n') != nullptr;
}
......@@ -256,7 +256,7 @@ skip_path(const char *name_utf8)
gcc_pure
bool
UpdateWalk::SkipSymlink(const Directory *directory,
const char *utf8_name) const
const char *utf8_name) const noexcept
{
#ifndef WIN32
const auto path_fs = storage.MapChildFS(directory->GetPath(),
......
......@@ -78,7 +78,7 @@ public:
private:
gcc_pure
bool SkipSymlink(const Directory *directory,
const char *utf8_name) const;
const char *utf8_name) const noexcept;
void RemoveExcludedFromDirectory(Directory &directory,
const ExcludeList &exclude_list);
......
......@@ -54,7 +54,7 @@ DecoderBridge::~DecoderBridge()
}
bool
DecoderBridge::CheckCancelRead() const
DecoderBridge::CheckCancelRead() const noexcept
{
if (error)
/* this translates to DecoderCommand::STOP */
......@@ -78,7 +78,7 @@ DecoderBridge::CheckCancelRead() const
* one.
*/
static DecoderCommand
need_chunks(DecoderControl &dc)
need_chunks(DecoderControl &dc) noexcept
{
if (dc.command == DecoderCommand::NONE)
dc.Wait();
......@@ -87,14 +87,14 @@ need_chunks(DecoderControl &dc)
}
static DecoderCommand
LockNeedChunks(DecoderControl &dc)
LockNeedChunks(DecoderControl &dc) noexcept
{
const std::lock_guard<Mutex> protect(dc.mutex);
return need_chunks(dc);
}
MusicChunk *
DecoderBridge::GetChunk()
DecoderBridge::GetChunk() noexcept
{
DecoderCommand cmd;
......@@ -177,7 +177,7 @@ DecoderBridge::PrepareInitialSeek()
}
DecoderCommand
DecoderBridge::GetVirtualCommand()
DecoderBridge::GetVirtualCommand() noexcept
{
if (error)
/* an error has occurred: stop the decoder plugin */
......@@ -192,7 +192,7 @@ DecoderBridge::GetVirtualCommand()
}
DecoderCommand
DecoderBridge::LockGetVirtualCommand()
DecoderBridge::LockGetVirtualCommand() noexcept
{
const std::lock_guard<Mutex> protect(dc.mutex);
return GetVirtualCommand();
......
......@@ -114,7 +114,7 @@ public:
* Caller must lock the #DecoderControl object.
*/
gcc_pure
bool CheckCancelRead() const;
bool CheckCancelRead() const noexcept;
/**
* Returns the current chunk the decoder writes to, or allocates a new
......@@ -122,7 +122,7 @@ public:
*
* @return the chunk, or NULL if we have received a decoder command
*/
MusicChunk *GetChunk();
MusicChunk *GetChunk() noexcept;
/**
* Flushes the current chunk.
......@@ -161,8 +161,8 @@ private:
* "virtual" synthesized command, e.g. to seek to the
* beginning of the CUE track.
*/
DecoderCommand GetVirtualCommand();
DecoderCommand LockGetVirtualCommand();
DecoderCommand GetVirtualCommand() noexcept;
DecoderCommand LockGetVirtualCommand() noexcept;
/**
* Sends a #Tag as-is to the #MusicPipe. Flushes the current
......
......@@ -75,7 +75,7 @@ DecoderControl::SetReady(const AudioFormat audio_format,
}
bool
DecoderControl::IsCurrentSong(const DetachedSong &_song) const
DecoderControl::IsCurrentSong(const DetachedSong &_song) const noexcept
{
switch (state) {
case DecoderState::STOP:
......
......@@ -305,10 +305,10 @@ struct DecoderControl {
* Caller must lock the object.
*/
gcc_pure
bool IsCurrentSong(const DetachedSong &_song) const;
bool IsCurrentSong(const DetachedSong &_song) const noexcept;
gcc_pure
bool LockIsCurrentSong(const DetachedSong &_song) const {
bool LockIsCurrentSong(const DetachedSong &_song) const noexcept {
const std::lock_guard<Mutex> protect(mutex);
return IsCurrentSong(_song);
}
......
......@@ -118,7 +118,7 @@ static constexpr unsigned num_decoder_plugins =
bool decoder_plugins_enabled[num_decoder_plugins];
const struct DecoderPlugin *
decoder_plugin_from_name(const char *name)
decoder_plugin_from_name(const char *name) noexcept
{
return decoder_plugins_find([=](const DecoderPlugin &plugin){
return strcmp(plugin.name, name) == 0;
......@@ -154,7 +154,7 @@ void decoder_plugin_deinit_all(void)
}
bool
decoder_plugins_supports_suffix(const char *suffix)
decoder_plugins_supports_suffix(const char *suffix) noexcept
{
return decoder_plugins_try([suffix](const DecoderPlugin &plugin){
return plugin.SupportsSuffix(suffix);
......
......@@ -31,7 +31,7 @@ extern bool decoder_plugins_enabled[];
gcc_pure
const struct DecoderPlugin *
decoder_plugin_from_name(const char *name);
decoder_plugin_from_name(const char *name) noexcept;
/* this is where we "load" all the "plugins" ;-) */
void
......@@ -86,6 +86,6 @@ decoder_plugins_for_each_enabled(F f)
*/
gcc_pure gcc_nonnull_all
bool
decoder_plugins_supports_suffix(const char *suffix);
decoder_plugins_supports_suffix(const char *suffix) noexcept;
#endif
......@@ -24,7 +24,7 @@
#include <assert.h>
bool
DecoderPlugin::SupportsSuffix(const char *suffix) const
DecoderPlugin::SupportsSuffix(const char *suffix) const noexcept
{
#if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */
......@@ -36,7 +36,7 @@ DecoderPlugin::SupportsSuffix(const char *suffix) const
}
bool
DecoderPlugin::SupportsMimeType(const char *mime_type) const
DecoderPlugin::SupportsMimeType(const char *mime_type) const noexcept
{
#if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */
......
......@@ -168,13 +168,13 @@ struct DecoderPlugin {
* Does the plugin announce the specified file name suffix?
*/
gcc_pure gcc_nonnull_all
bool SupportsSuffix(const char *suffix) const;
bool SupportsSuffix(const char *suffix) const noexcept;
/**
* Does the plugin announce the specified MIME type?
*/
gcc_pure gcc_nonnull_all
bool SupportsMimeType(const char *mime_type) const;
bool SupportsMimeType(const char *mime_type) const noexcept;
};
#endif
......@@ -170,7 +170,8 @@ decoder_file_decode(const DecoderPlugin &plugin,
gcc_pure
static bool
decoder_check_plugin_mime(const DecoderPlugin &plugin, const InputStream &is)
decoder_check_plugin_mime(const DecoderPlugin &plugin,
const InputStream &is) noexcept
{
assert(plugin.stream_decode != nullptr);
......@@ -181,7 +182,8 @@ decoder_check_plugin_mime(const DecoderPlugin &plugin, const InputStream &is)
gcc_pure
static bool
decoder_check_plugin_suffix(const DecoderPlugin &plugin, const char *suffix)
decoder_check_plugin_suffix(const DecoderPlugin &plugin,
const char *suffix) noexcept
{
assert(plugin.stream_decode != nullptr);
......@@ -191,7 +193,7 @@ decoder_check_plugin_suffix(const DecoderPlugin &plugin, const char *suffix)
gcc_pure
static bool
decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
const char *suffix)
const char *suffix) noexcept
{
return plugin.stream_decode != nullptr &&
(decoder_check_plugin_mime(plugin, is) ||
......
......@@ -66,7 +66,7 @@ struct AudioFileInputStream {
gcc_pure
static SongTime
audiofile_get_duration(AFfilehandle fh)
audiofile_get_duration(AFfilehandle fh) noexcept
{
return SongTime::FromScale<uint64_t>(afGetFrameCount(fh, AF_DEFAULT_TRACK),
afGetRate(fh, AF_DEFAULT_TRACK));
......@@ -239,7 +239,7 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is)
gcc_pure
static SignedSongTime
audiofile_get_duration(InputStream &is)
audiofile_get_duration(InputStream &is) noexcept
{
if (!is.IsSeekable() || !is.KnownSize())
return SignedSongTime::Negative();
......
......@@ -39,7 +39,7 @@
#include <stdlib.h>
bool
DsdId::Equals(const char *s) const
DsdId::Equals(const char *s) const noexcept
{
assert(s != nullptr);
assert(strlen(s) == sizeof(value));
......@@ -95,7 +95,7 @@ dsdlib_skip(DecoderClient *client, InputStream &is,
}
bool
dsdlib_valid_freq(uint32_t samplefreq)
dsdlib_valid_freq(uint32_t samplefreq) noexcept
{
switch (samplefreq) {
case 2822400: /* DSD64, 64xFs, Fs = 44.100kHz */
......
......@@ -34,7 +34,7 @@ struct DsdId {
char value[4];
gcc_pure
bool Equals(const char *s) const;
bool Equals(const char *s) const noexcept;
};
class DsdUint64 {
......@@ -72,7 +72,7 @@ dsdlib_skip(DecoderClient *client, InputStream &is,
**/
gcc_const
bool
dsdlib_valid_freq(uint32_t samplefreq);
dsdlib_valid_freq(uint32_t samplefreq) noexcept;
/**
* Add tags from ID3 tag. All tags commonly found in the ID3 tags of
......
......@@ -112,14 +112,14 @@ ffmpeg_finish()
gcc_pure
static const AVCodecParameters &
GetCodecParameters(const AVStream &stream)
GetCodecParameters(const AVStream &stream) noexcept
{
return *stream.codecpar;
}
gcc_pure
static AVSampleFormat
GetSampleFormat(const AVCodecParameters &codec_params)
GetSampleFormat(const AVCodecParameters &codec_params) noexcept
{
return AVSampleFormat(codec_params.format);
}
......@@ -128,14 +128,14 @@ GetSampleFormat(const AVCodecParameters &codec_params)
gcc_pure
static const AVCodecContext &
GetCodecParameters(const AVStream &stream)
GetCodecParameters(const AVStream &stream) noexcept
{
return *stream.codec;
}
gcc_pure
static AVSampleFormat
GetSampleFormat(const AVCodecContext &codec_context)
GetSampleFormat(const AVCodecContext &codec_context) noexcept
{
return codec_context.sample_fmt;
}
......@@ -144,14 +144,14 @@ GetSampleFormat(const AVCodecContext &codec_context)
gcc_pure
static bool
IsAudio(const AVStream &stream)
IsAudio(const AVStream &stream) noexcept
{
return GetCodecParameters(stream).codec_type == AVMEDIA_TYPE_AUDIO;
}
gcc_pure
static int
ffmpeg_find_audio_stream(const AVFormatContext &format_context)
ffmpeg_find_audio_stream(const AVFormatContext &format_context) noexcept
{
for (unsigned i = 0; i < format_context.nb_streams; ++i)
if (IsAudio(*format_context.streams[i]))
......@@ -220,7 +220,7 @@ copy_interleave_frame(const AVCodecContext &codec_context,
*/
gcc_pure
static int64_t
StreamRelativePts(const AVPacket &packet, const AVStream &stream)
StreamRelativePts(const AVPacket &packet, const AVStream &stream) noexcept
{
auto pts = packet.pts;
if (pts < 0 || pts == int64_t(AV_NOPTS_VALUE))
......@@ -237,7 +237,7 @@ StreamRelativePts(const AVPacket &packet, const AVStream &stream)
gcc_pure
static uint64_t
PtsToPcmFrame(uint64_t pts, const AVStream &stream,
const AVCodecContext &codec_context)
const AVCodecContext &codec_context) noexcept
{
return av_rescale_q(pts, stream.time_base, codec_context.time_base);
}
......@@ -437,7 +437,7 @@ ffmpeg_send_packet(DecoderClient &client, InputStream &is,
gcc_const
static SampleFormat
ffmpeg_sample_format(enum AVSampleFormat sample_fmt)
ffmpeg_sample_format(enum AVSampleFormat sample_fmt) noexcept
{
switch (sample_fmt) {
case AV_SAMPLE_FMT_S16:
......
......@@ -67,7 +67,7 @@ flac_parse_mixramp(const FLAC__StreamMetadata_VorbisComment &vc)
*/
static const char *
flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
const char *name)
const char *name) noexcept
{
return vorbis_comment_value((const char *)entry->entry, name);
}
......@@ -126,7 +126,7 @@ flac_scan_comments(const FLAC__StreamMetadata_VorbisComment *comment,
gcc_pure
static inline SongTime
flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info)
flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info) noexcept
{
assert(stream_info->sample_rate > 0);
......
......@@ -74,7 +74,7 @@ gme_plugin_init(gcc_unused const ConfigBlock &block)
gcc_pure
static unsigned
ParseSubtuneName(const char *base)
ParseSubtuneName(const char *base) noexcept
{
if (memcmp(base, SUBTUNE_PREFIX, sizeof(SUBTUNE_PREFIX) - 1) != 0)
return 0;
......
......@@ -71,7 +71,7 @@ static bool gapless_playback;
gcc_const
static SongTime
ToSongTime(mad_timer_t t)
ToSongTime(mad_timer_t t) noexcept
{
return SongTime::FromMS(mad_timer_count(t, MAD_UNITS_MILLISECONDS));
}
......@@ -155,10 +155,10 @@ struct MadDecoder {
enum mp3_action DecodeNextFrame();
gcc_pure
offset_type ThisFrameOffset() const;
offset_type ThisFrameOffset() const noexcept;
gcc_pure
offset_type RestIncludingThisFrame() const;
offset_type RestIncludingThisFrame() const noexcept;
/**
* Attempt to calulcate the length of the song from filesize
......@@ -177,7 +177,7 @@ struct MadDecoder {
}
gcc_pure
long TimeToFrame(SongTime t) const;
long TimeToFrame(SongTime t) const noexcept;
void UpdateTimerNextFrame();
......@@ -291,7 +291,7 @@ parse_id3_replay_gain_info(ReplayGainInfo &rgi,
#ifdef ENABLE_ID3TAG
gcc_pure
static MixRampInfo
parse_id3_mixramp(struct id3_tag *tag)
parse_id3_mixramp(struct id3_tag *tag) noexcept
{
MixRampInfo result;
......@@ -710,7 +710,7 @@ mp3_frame_duration(const struct mad_frame *frame)
}
inline offset_type
MadDecoder::ThisFrameOffset() const
MadDecoder::ThisFrameOffset() const noexcept
{
auto offset = input_stream.GetOffset();
......@@ -723,7 +723,7 @@ MadDecoder::ThisFrameOffset() const
}
inline offset_type
MadDecoder::RestIncludingThisFrame() const
MadDecoder::RestIncludingThisFrame() const noexcept
{
return input_stream.GetSize() - ThisFrameOffset();
}
......@@ -846,7 +846,7 @@ mad_decoder_total_file_time(InputStream &is)
}
long
MadDecoder::TimeToFrame(SongTime t) const
MadDecoder::TimeToFrame(SongTime t) const noexcept
{
unsigned long i;
......
......@@ -31,7 +31,7 @@
gcc_pure
static TagType
ParseOpusTagName(const char *name)
ParseOpusTagName(const char *name) noexcept
{
TagType type = tag_name_parse_i(name);
if (type != TAG_NUM_OF_ITEM_TYPES)
......
......@@ -116,7 +116,7 @@ struct SidplayContainerPath {
gcc_pure
static unsigned
ParseSubtuneName(const char *base)
ParseSubtuneName(const char *base) noexcept
{
if (memcmp(base, SUBTUNE_PREFIX, sizeof(SUBTUNE_PREFIX) - 1) != 0)
return 0;
......@@ -390,7 +390,7 @@ sidplay_file_decode(DecoderClient &client, Path path_fs)
gcc_pure
static const char *
GetInfoString(const SidTuneInfo &info, unsigned i)
GetInfoString(const SidTuneInfo &info, unsigned i) noexcept
{
#ifdef HAVE_SIDPLAYFP
return info.numberOfInfoStrings() > i
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment