From ba69ade024f7b927ad888ac7fb4f22d917df102a Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Fri, 28 Nov 2014 19:09:21 +0100
Subject: [PATCH 01/10] Compiler.h: add macro CLANG_OR_GCC_VERSION()

---
 src/Compiler.h                                   | 15 +++++++++++----
 src/db/Helpers.cxx                               |  4 ++--
 src/db/plugins/upnp/UpnpDatabasePlugin.cxx       |  2 +-
 src/neighbor/plugins/SmbclientNeighborPlugin.cxx |  2 +-
 src/output/plugins/httpd/HttpdInternal.hxx       |  2 +-
 src/storage/CompositeStorage.cxx                 |  2 +-
 src/tag/Set.cxx                                  |  2 +-
 src/tag/TagPool.cxx                              |  2 +-
 src/util/Cast.hxx                                |  4 ++--
 src/util/Manual.hxx                              |  4 ++--
 10 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/src/Compiler.h b/src/Compiler.h
index 5a28c3da2..33540368e 100644
--- a/src/Compiler.h
+++ b/src/Compiler.h
@@ -31,6 +31,13 @@
 #define GCC_CHECK_VERSION(major, minor) \
 	(defined(__GNUC__) && GCC_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
 
+/**
+ * Are we building with clang (any version) or at least the specified
+ * gcc version?
+ */
+#define CLANG_OR_GCC_VERSION(major, minor) \
+	(defined(__clang__) || GCC_CHECK_VERSION(major, minor))
+
 /**
  * Are we building with gcc (not clang or any other compiler) and a
  * version older than the specified one?
@@ -59,7 +66,7 @@
 	(defined(__clang__) && \
 	 CLANG_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
 
-#if GCC_CHECK_VERSION(4,0)
+#if CLANG_OR_GCC_VERSION(4,0)
 
 /* GCC 4.x */
 
@@ -119,7 +126,7 @@
 
 #endif
 
-#if GCC_CHECK_VERSION(4,3)
+#if CLANG_OR_GCC_VERSION(4,3)
 
 #define gcc_hot __attribute__((hot))
 #define gcc_cold __attribute__((cold))
@@ -140,7 +147,7 @@
 #ifndef __cplusplus
 /* plain C99 has "restrict" */
 #define gcc_restrict restrict
-#elif GCC_CHECK_VERSION(4,0)
+#elif CLANG_OR_GCC_VERSION(4,0)
 /* "__restrict__" is a GCC extension for C++ */
 #define gcc_restrict __restrict__
 #else
@@ -158,7 +165,7 @@
 #define final
 #endif
 
-#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
+#if CLANG_OR_GCC_VERSION(4,8)
 #define gcc_alignas(T, fallback) alignas(T)
 #else
 #define gcc_alignas(T, fallback) gcc_aligned(fallback)
diff --git a/src/db/Helpers.cxx b/src/db/Helpers.cxx
index add4bb98e..27bfb7c01 100644
--- a/src/db/Helpers.cxx
+++ b/src/db/Helpers.cxx
@@ -46,7 +46,7 @@ StatsVisitTag(DatabaseStats &stats, StringSet &artists, StringSet &albums,
 	for (const auto &item : tag) {
 		switch (item.type) {
 		case TAG_ARTIST:
-#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
+#if CLANG_OR_GCC_VERSION(4,8)
 			artists.emplace(item.value);
 #else
 			artists.insert(item.value);
@@ -54,7 +54,7 @@ StatsVisitTag(DatabaseStats &stats, StringSet &artists, StringSet &albums,
 			break;
 
 		case TAG_ALBUM:
-#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
+#if CLANG_OR_GCC_VERSION(4,8)
 			albums.emplace(item.value);
 #else
 			albums.insert(item.value);
diff --git a/src/db/plugins/upnp/UpnpDatabasePlugin.cxx b/src/db/plugins/upnp/UpnpDatabasePlugin.cxx
index 9970cdcf3..11b5da85b 100644
--- a/src/db/plugins/upnp/UpnpDatabasePlugin.cxx
+++ b/src/db/plugins/upnp/UpnpDatabasePlugin.cxx
@@ -749,7 +749,7 @@ UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection,
 
 			const char *value = dirent.tag.GetValue(tag);
 			if (value != nullptr) {
-#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
+#if CLANG_OR_GCC_VERSION(4,8)
 				values.emplace(value);
 #else
 				values.insert(value);
diff --git a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
index 2701b0ccd..0e31c6e52 100644
--- a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
+++ b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
@@ -216,7 +216,7 @@ SmbclientNeighborExplorer::Run()
 			prev = i;
 		} else {
 			/* can't see it anymore: move to "lost" */
-#if defined(__clang__) || GCC_CHECK_VERSION(4,7)
+#if CLANG_OR_GCC_VERSION(4,7)
 			lost.splice_after(lost.before_begin(), list, prev);
 #else
 			/* the forward_list::splice_after() lvalue
diff --git a/src/output/plugins/httpd/HttpdInternal.hxx b/src/output/plugins/httpd/HttpdInternal.hxx
index 20ff15e42..303170268 100644
--- a/src/output/plugins/httpd/HttpdInternal.hxx
+++ b/src/output/plugins/httpd/HttpdInternal.hxx
@@ -153,7 +153,7 @@ public:
 	HttpdOutput(EventLoop &_loop);
 	~HttpdOutput();
 
-#if defined(__clang__) || GCC_CHECK_VERSION(4,7)
+#if CLANG_OR_GCC_VERSION(4,7)
 	constexpr
 #endif
 	static HttpdOutput *Cast(AudioOutput *ao) {
diff --git a/src/storage/CompositeStorage.cxx b/src/storage/CompositeStorage.cxx
index 89a2fc756..ce9c1e8b1 100644
--- a/src/storage/CompositeStorage.cxx
+++ b/src/storage/CompositeStorage.cxx
@@ -137,7 +137,7 @@ CompositeStorage::Directory::Make(const char *uri)
 	Directory *directory = this;
 	while (*uri != 0) {
 		const std::string name = NextSegment(uri);
-#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
+#if CLANG_OR_GCC_VERSION(4,8)
 		auto i = directory->children.emplace(std::move(name),
 						     Directory());
 #else
diff --git a/src/tag/Set.cxx b/src/tag/Set.cxx
index 6a55a450f..157060d0c 100644
--- a/src/tag/Set.cxx
+++ b/src/tag/Set.cxx
@@ -75,7 +75,7 @@ TagSet::InsertUnique(const Tag &src, TagType type, const char *value,
 	else
 		builder.AddItem(type, value);
 	CopyTagMask(builder, src, group_mask);
-#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
+#if CLANG_OR_GCC_VERSION(4,8)
 	emplace(builder.Commit());
 #else
 	insert(builder.Commit());
diff --git a/src/tag/TagPool.cxx b/src/tag/TagPool.cxx
index 97015b497..16f44f46e 100644
--- a/src/tag/TagPool.cxx
+++ b/src/tag/TagPool.cxx
@@ -91,7 +91,7 @@ calc_hash(TagType type, const char *p)
 	return hash ^ type;
 }
 
-#if defined(__clang__) || GCC_CHECK_VERSION(4,7)
+#if CLANG_OR_GCC_VERSION(4,7)
 	constexpr
 #endif
 static inline TagPoolSlot *
diff --git a/src/util/Cast.hxx b/src/util/Cast.hxx
index 887137da4..647171970 100644
--- a/src/util/Cast.hxx
+++ b/src/util/Cast.hxx
@@ -84,7 +84,7 @@ ContainerAttributeOffset(const A C::*p)
  * Cast the given pointer to a struct member to its parent structure.
  */
 template<class C, class A>
-#if defined(__clang__) || GCC_CHECK_VERSION(4,7)
+#if CLANG_OR_GCC_VERSION(4,7)
 constexpr
 #endif
 static inline C &
@@ -97,7 +97,7 @@ ContainerCast(A &a, A C::*member)
  * Cast the given pointer to a struct member to its parent structure.
  */
 template<class C, class A>
-#if defined(__clang__) || GCC_CHECK_VERSION(4,7)
+#if CLANG_OR_GCC_VERSION(4,7)
 constexpr
 #endif
 static inline const C &
diff --git a/src/util/Manual.hxx b/src/util/Manual.hxx
index 75cffac06..153851aba 100644
--- a/src/util/Manual.hxx
+++ b/src/util/Manual.hxx
@@ -41,7 +41,7 @@
 
 #include <assert.h>
 
-#if defined(__clang__) || GCC_CHECK_VERSION(4,7)
+#if CLANG_OR_GCC_VERSION(4,7)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
 #endif
@@ -114,7 +114,7 @@ public:
 	}
 };
 
-#if defined(__clang__) || GCC_VERSION >= 40700
+#if CLANG_OR_GCC_VERSION(4,7)
 #pragma GCC diagnostic pop
 #endif
 

From b855f2fcc2e8e021e630efc1ec545772d292c091 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 23 Aug 2016 09:50:46 +0200
Subject: [PATCH 02/10] Chrono: use macro GCC_OLDER_THAN()

---
 src/Chrono.hxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Chrono.hxx b/src/Chrono.hxx
index cc87c5ba1..960a6364c 100644
--- a/src/Chrono.hxx
+++ b/src/Chrono.hxx
@@ -26,7 +26,7 @@
 #include <utility>
 #include <cstdint>
 
-#if defined(__GNUC__) && !GCC_CHECK_VERSION(4,7) && !defined(__clang__)
+#if GCC_OLDER_THAN(4,7)
 /* std::chrono::duration operators are "constexpr" since gcc 4.7 */
 #define chrono_constexpr gcc_pure
 #else

From cd6c5cfd4ca0ece2737a7e8c39da2aaa9908cd88 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Fri, 28 Nov 2014 19:33:09 +0100
Subject: [PATCH 03/10] Compiler.h: exclude clang from GCC_CHECK_VERSION()

---
 src/Compiler.h           | 9 +++++++--
 src/fs/AllocatedPath.cxx | 2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/Compiler.h b/src/Compiler.h
index 33540368e..ddd1e474f 100644
--- a/src/Compiler.h
+++ b/src/Compiler.h
@@ -28,8 +28,13 @@
 #define GCC_VERSION 0
 #endif
 
+/**
+ * Are we building with the specified version of gcc (not clang or any
+ * other compiler) or newer?
+ */
 #define GCC_CHECK_VERSION(major, minor) \
-	(defined(__GNUC__) && GCC_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
+	(defined(__GNUC__) && !defined(__clang__) && \
+	 GCC_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
 
 /**
  * Are we building with clang (any version) or at least the specified
@@ -138,7 +143,7 @@
 
 #endif /* ! GCC_UNUSED >= 40300 */
 
-#if GCC_CHECK_VERSION(4,6) && !defined(__clang__)
+#if GCC_CHECK_VERSION(4,6)
 #define gcc_flatten __attribute__((flatten))
 #else
 #define gcc_flatten
diff --git a/src/fs/AllocatedPath.cxx b/src/fs/AllocatedPath.cxx
index ceaad73ea..0f394dd6e 100644
--- a/src/fs/AllocatedPath.cxx
+++ b/src/fs/AllocatedPath.cxx
@@ -111,7 +111,7 @@ AllocatedPath::ChopSeparators()
 	while (l >= 2 && PathTraitsFS::IsSeparator(p[l - 1])) {
 		--l;
 
-#if GCC_CHECK_VERSION(4,7) && !defined(__clang__)
+#if GCC_CHECK_VERSION(4,7)
 		value.pop_back();
 #else
 		value.erase(value.end() - 1, value.end());

From e84e4169f97e14e5c7d1be4f63a742c9597d7b2c Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 23 Aug 2016 09:46:13 +0200
Subject: [PATCH 04/10] Compiler.h: remove redundant __GNUC__ check

GCC_VERSION>0 implies defined(__GNUC__).
---
 src/Compiler.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Compiler.h b/src/Compiler.h
index ddd1e474f..07654f12b 100644
--- a/src/Compiler.h
+++ b/src/Compiler.h
@@ -33,7 +33,7 @@
  * other compiler) or newer?
  */
 #define GCC_CHECK_VERSION(major, minor) \
-	(defined(__GNUC__) && !defined(__clang__) && \
+	(!defined(__clang__) && \
 	 GCC_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
 
 /**

From 093abaad29ed2408808a53b619999f25847a2ab8 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Tue, 23 Aug 2016 09:45:37 +0200
Subject: [PATCH 05/10] Compiler.h: always define CLANG_VERSION

---
 src/Compiler.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/Compiler.h b/src/Compiler.h
index 07654f12b..ab10f6f8f 100644
--- a/src/Compiler.h
+++ b/src/Compiler.h
@@ -28,6 +28,12 @@
 #define GCC_VERSION 0
 #endif
 
+#ifdef __clang__
+#  define CLANG_VERSION GCC_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
+#elif defined(__GNUC__)
+#  define CLANG_VERSION 0
+#endif
+
 /**
  * Are we building with the specified version of gcc (not clang or any
  * other compiler) or newer?
@@ -52,7 +58,6 @@
 	 GCC_VERSION < GCC_MAKE_VERSION(major, minor, 0))
 
 #ifdef __clang__
-#  define CLANG_VERSION GCC_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
 #  if __clang_major__ < 3
 #    error Sorry, your clang version is too old.  You need at least version 3.1.
 #  endif
@@ -68,8 +73,7 @@
  * Are we building with the specified version of clang or newer?
  */
 #define CLANG_CHECK_VERSION(major, minor) \
-	(defined(__clang__) && \
-	 CLANG_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
+	(CLANG_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
 
 #if CLANG_OR_GCC_VERSION(4,0)
 

From b05beb000fe708c42defdfef32050dd7123caf7c Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 23 Aug 2016 09:55:59 +0200
Subject: [PATCH 06/10] Compiler.h: work around clang 3.9 warning
 -Wexpansion-to-defined

Check {GCC,CLANG}_VERSION==0 or >0 instead of using defined(), which
may render undefined behavior.
---
 NEWS           | 1 +
 src/Compiler.h | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 5ab83d1e7..65f8950a6 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ ver 0.19.19 (not yet released)
   - wildmidi: support libWildMidi 0.4
 * output
   - pulse: support 32 bit, 24 bit and floating point playback
+* fix clang 3.9 warnings
 
 ver 0.19.18 (2016/08/05)
 * decoder
diff --git a/src/Compiler.h b/src/Compiler.h
index ab10f6f8f..5a51e33f8 100644
--- a/src/Compiler.h
+++ b/src/Compiler.h
@@ -39,7 +39,7 @@
  * other compiler) or newer?
  */
 #define GCC_CHECK_VERSION(major, minor) \
-	(!defined(__clang__) && \
+	(CLANG_VERSION == 0 && \
 	 GCC_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
 
 /**
@@ -47,14 +47,14 @@
  * gcc version?
  */
 #define CLANG_OR_GCC_VERSION(major, minor) \
-	(defined(__clang__) || GCC_CHECK_VERSION(major, minor))
+	(CLANG_VERSION > 0 || GCC_CHECK_VERSION(major, minor))
 
 /**
  * Are we building with gcc (not clang or any other compiler) and a
  * version older than the specified one?
  */
 #define GCC_OLDER_THAN(major, minor) \
-	(defined(__GNUC__) && !defined(__clang__) && \
+	(GCC_VERSION > 0 && CLANG_VERSION == 0 && \
 	 GCC_VERSION < GCC_MAKE_VERSION(major, minor, 0))
 
 #ifdef __clang__

From 05de0ecec3ef32a04ffcf91fe7c690529735d59f Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Tue, 23 Aug 2016 09:37:19 +0200
Subject: [PATCH 07/10] decoder/ffmpeg: call avcodec_parameters_to_context()

These bug reports describe problems with some FFmpeg codecs:

 https://bugs.musicpd.org/view.php?id=4564
 https://bugs.musicpd.org/view.php?id=4568
 https://bugs.musicpd.org/view.php?id=4572

According to the FFmpeg bug tracker, a call to
avcodec_parameters_to_context() is required after
avcodec_alloc_context3():

 https://trac.ffmpeg.org/ticket/5781

This requirement was previously undocumented.
---
 NEWS                                        | 1 +
 src/decoder/plugins/FfmpegDecoderPlugin.cxx | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/NEWS b/NEWS
index 65f8950a6..33ab0f476 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,6 @@
 ver 0.19.19 (not yet released)
 * decoder
+  - ffmpeg: bug fix for FFmpeg 3.1 support
   - wildmidi: support libWildMidi 0.4
 * output
   - pulse: support 32 bit, 24 bit and floating point playback
diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
index 7695dcb4f..ca1f3c0f8 100644
--- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx
+++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
@@ -547,6 +547,8 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
 	AtScopeExit(&codec_context) {
 		avcodec_free_context(&codec_context);
 	};
+
+	avcodec_parameters_to_context(codec_context, av_stream.codecpar);
 #endif
 
 	const SampleFormat sample_format =

From 4204d4928be664377385f679b7c0915133238ade Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 23 Aug 2016 10:14:59 +0200
Subject: [PATCH 08/10] decoder/ffmpeg: no avcodec_parameters_to_context() with
 FFmpeg 3.0

This function exists since FFmpeg 3.1.  Fix a build failure with
FFmpeg 3.0.
---
 src/decoder/plugins/FfmpegDecoderPlugin.cxx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
index ca1f3c0f8..e27ec797f 100644
--- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx
+++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
@@ -548,7 +548,9 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
 		avcodec_free_context(&codec_context);
 	};
 
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 25, 0) /* FFmpeg 3.1 */
 	avcodec_parameters_to_context(codec_context, av_stream.codecpar);
+#endif
 #endif
 
 	const SampleFormat sample_format =

From de0752fd566b3cf6ee0813bfe00808f9766f832c Mon Sep 17 00:00:00 2001
From: Thomas Klausner <tk@giga.or.at>
Date: Sun, 5 Apr 2015 16:29:48 -0700
Subject: [PATCH 09/10] system/ByteOrder: gssupport non-x86 NetBSD

---
 NEWS                     | 1 +
 src/system/ByteOrder.hxx | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 33ab0f476..1f6ce52a1 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ ver 0.19.19 (not yet released)
   - wildmidi: support libWildMidi 0.4
 * output
   - pulse: support 32 bit, 24 bit and floating point playback
+* support non-x86 NetBSD
 * fix clang 3.9 warnings
 
 ver 0.19.18 (2016/08/05)
diff --git a/src/system/ByteOrder.hxx b/src/system/ByteOrder.hxx
index 42181fe2c..6f0d291c7 100644
--- a/src/system/ByteOrder.hxx
+++ b/src/system/ByteOrder.hxx
@@ -40,7 +40,7 @@
 /* well-known big-endian */
 #  define IS_LITTLE_ENDIAN false
 #  define IS_BIG_ENDIAN true
-#elif defined(__APPLE__)
+#elif defined(__APPLE__) || defined(__NetBSD__)
 /* compile-time check for MacOS */
 #  include <machine/endian.h>
 #  if BYTE_ORDER == LITTLE_ENDIAN

From d4db873716a97382551c699e97713649ab25f890 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max.kellermann@gmail.com>
Date: Tue, 23 Aug 2016 10:19:10 +0200
Subject: [PATCH 10/10] release v0.19.19

---
 NEWS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 1f6ce52a1..9da6019ba 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-ver 0.19.19 (not yet released)
+ver 0.19.19 (2016/08/23)
 * decoder
   - ffmpeg: bug fix for FFmpeg 3.1 support
   - wildmidi: support libWildMidi 0.4