From 59f8144c50765189594d5932fc25869f9ea6e265 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Sat, 19 Oct 2013 18:19:03 +0200
Subject: [PATCH] *: use nullptr instead of NULL

---
 src/AllCommands.cxx                    |  34 ++++----
 src/ArchiveFile.hxx                    |   2 -
 src/ArchiveList.cxx                    |  18 ++--
 src/ArchiveList.hxx                    |   2 +-
 src/ArchivePlugin.cxx                  |   6 +-
 src/ArchivePlugin.hxx                  |   8 +-
 src/ClientRead.cxx                     |   2 +-
 src/ClientSubscribe.cxx                |   6 +-
 src/CommandLine.cxx                    |  24 +++---
 src/ConfigFile.cxx                     |  18 ++--
 src/DatabaseGlue.cxx                   |  26 +++---
 src/DatabaseGlue.hxx                   |   4 +-
 src/DatabasePrint.cxx                  |   8 +-
 src/DatabaseRegistry.cxx               |   2 +-
 src/DatabaseRegistry.hxx               |   2 +-
 src/DatabaseSave.cxx                   |   8 +-
 src/DatabaseSelection.hxx              |   5 +-
 src/DecoderAPI.cxx                     |  76 ++++++++---------
 src/DecoderAPI.hxx                     |   6 +-
 src/DecoderBuffer.hxx                  |   4 +-
 src/DecoderControl.cxx                 |   6 +-
 src/DecoderInternal.cxx                |  14 +--
 src/DecoderList.cxx                    |  32 +++----
 src/DecoderList.hxx                    |   6 +-
 src/DecoderPrint.cxx                   |  12 +--
 src/DecoderThread.cxx                  |  82 +++++++++---------
 src/DespotifyUtils.cxx                 |  10 +--
 src/DespotifyUtils.hxx                 |   2 +-
 src/Directory.cxx                      |  42 ++++-----
 src/Directory.hxx                      |   6 +-
 src/DirectorySave.cxx                  |  22 ++---
 src/EncoderList.cxx                    |   4 +-
 src/EncoderList.hxx                    |   4 +-
 src/EncoderPlugin.hxx                  |  26 +++---
 src/ExcludeList.cxx                    |   6 +-
 src/FilterConfig.cxx                   |  12 +--
 src/FilterPlugin.cxx                   |  10 +--
 src/FilterPlugin.hxx                   |   8 +-
 src/FilterRegistry.cxx                 |   6 +-
 src/GlobalEvents.cxx                   |   4 +-
 src/IOThread.cxx                       |   8 +-
 src/IcyMetaDataServer.cxx              |   6 +-
 src/InotifySource.cxx                  |   4 +-
 src/InotifyUpdate.cxx                  |  24 +++---
 src/InputInit.cxx                      |  22 ++---
 src/InputInit.hxx                      |   3 -
 src/InputPlugin.hxx                    |   4 +-
 src/InputStream.cxx                    |  18 ++--
 src/InputStream.hxx                    |   8 +-
 src/Listen.cxx                         |  10 +--
 src/LogInit.cxx                        |  25 +++---
 src/MixerAll.cxx                       |   8 +-
 src/MixerControl.cxx                   |  28 +++---
 src/MixerPlugin.hxx                    |  10 +--
 src/MusicChunk.cxx                     |   2 +-
 src/MusicChunk.hxx                     |   2 +-
 src/OutputAll.cxx                      |  66 +++++++--------
 src/OutputCommand.cxx                  |   2 +-
 src/OutputControl.cxx                  |  40 ++++-----
 src/OutputFinish.cxx                   |   6 +-
 src/OutputInit.cxx                     |  70 +++++++--------
 src/OutputInternal.hxx                 |   6 +-
 src/OutputPlugin.cxx                   |  18 ++--
 src/OutputPlugin.hxx                   |  16 +---
 src/OutputThread.cxx                   |  82 +++++++++---------
 src/PlayerControl.cxx                  |   8 +-
 src/Queue.cxx                          |   2 +-
 src/QueueSave.cxx                      |   8 +-
 src/SongSave.cxx                       |  12 +--
 src/SongSort.cxx                       |  20 ++---
 src/SongSticker.cxx                    |  16 ++--
 src/SongUpdate.cxx                     |  32 +++----
 src/StickerCommands.cxx                |   2 +-
 src/StickerDatabase.cxx                | 113 +++++++++++++------------
 src/StickerDatabase.hxx                |  10 +--
 src/TagFile.cxx                        |  22 ++---
 src/TextFile.cxx                       |   8 +-
 src/TextFile.hxx                       |   2 +-
 src/TimePrint.cxx                      |   2 +-
 src/UpdateArchive.cxx                  |  12 +--
 src/UpdateContainer.cxx                |  12 +--
 src/UpdateDatabase.cxx                 |   6 +-
 src/UpdateRemove.cxx                   |   8 +-
 src/UpdateSong.cxx                     |  12 +--
 src/UpdateWalk.cxx                     |  22 ++---
 src/Volume.cxx                         |   6 +-
 src/Win32Main.cxx                      |   4 +-
 src/ZeroconfAvahi.cxx                  |  18 ++--
 src/ZeroconfBonjour.cxx                |   8 +-
 src/archive/Bzip2ArchivePlugin.cxx     |   4 +-
 src/archive/Iso9660ArchivePlugin.cxx   |   6 +-
 src/archive/ZzipArchivePlugin.cxx      |   8 +-
 src/db/SimpleDatabasePlugin.cxx        |  16 ++--
 src/decoder/FfmpegDecoderPlugin.cxx    |  34 ++++----
 src/decoder/WavpackDecoderPlugin.cxx   |  34 ++++----
 src/decoder/sidplay_decoder_plugin.cxx |  48 +++++------
 src/input/CurlInputPlugin.cxx          |  68 +++++++--------
 97 files changed, 812 insertions(+), 834 deletions(-)

diff --git a/src/AllCommands.cxx b/src/AllCommands.cxx
index e02e6df15..562bbeb49 100644
--- a/src/AllCommands.cxx
+++ b/src/AllCommands.cxx
@@ -245,7 +245,7 @@ command_lookup(const char *name)
 			a = i + 1;
 	} while (a < b);
 
-	return NULL;
+	return nullptr;
 }
 
 static bool
@@ -256,7 +256,7 @@ command_check_request(const struct command *cmd, Client *client,
 	int max = cmd->max + 1;
 
 	if (cmd->permission != (permission & cmd->permission)) {
-		if (client != NULL)
+		if (client != nullptr)
 			command_error(client, ACK_ERROR_PERMISSION,
 				      "you don't have permission for \"%s\"",
 				      cmd->cmd);
@@ -267,18 +267,18 @@ command_check_request(const struct command *cmd, Client *client,
 		return true;
 
 	if (min == max && max != argc) {
-		if (client != NULL)
+		if (client != nullptr)
 			command_error(client, ACK_ERROR_ARG,
 				      "wrong number of arguments for \"%s\"",
 				      argv[0]);
 		return false;
 	} else if (argc < min) {
-		if (client != NULL)
+		if (client != nullptr)
 			command_error(client, ACK_ERROR_ARG,
 				      "too few arguments for \"%s\"", argv[0]);
 		return false;
 	} else if (argc > max && max /* != 0 */ ) {
-		if (client != NULL)
+		if (client != nullptr)
 			command_error(client, ACK_ERROR_ARG,
 				      "too many arguments for \"%s\"", argv[0]);
 		return false;
@@ -295,20 +295,20 @@ command_checked_lookup(Client *client, unsigned permission,
 	current_command = "";
 
 	if (argc == 0)
-		return NULL;
+		return nullptr;
 
 	cmd = command_lookup(argv[0]);
-	if (cmd == NULL) {
-		if (client != NULL)
+	if (cmd == nullptr) {
+		if (client != nullptr)
 			command_error(client, ACK_ERROR_UNKNOWN,
 				      "unknown command \"%s\"", argv[0]);
-		return NULL;
+		return nullptr;
 	}
 
 	current_command = cmd->cmd;
 
 	if (!command_check_request(cmd, client, permission, argc, argv))
-		return NULL;
+		return nullptr;
 
 	return cmd;
 }
@@ -317,7 +317,7 @@ enum command_return
 command_process(Client *client, unsigned num, char *line)
 {
 	Error error;
-	char *argv[COMMAND_ARGV_MAX] = { NULL };
+	char *argv[COMMAND_ARGV_MAX] = { nullptr };
 	const struct command *cmd;
 	enum command_return ret = COMMAND_RETURN_ERROR;
 
@@ -327,7 +327,7 @@ command_process(Client *client, unsigned num, char *line)
 
 	Tokenizer tokenizer(line);
 	argv[0] = tokenizer.NextWord(error);
-	if (argv[0] == NULL) {
+	if (argv[0] == nullptr) {
 		current_command = "";
 		if (tokenizer.IsEnd())
 			command_error(client, ACK_ERROR_UNKNOWN,
@@ -336,7 +336,7 @@ command_process(Client *client, unsigned num, char *line)
 			command_error(client, ACK_ERROR_UNKNOWN,
 				      "%s", error.GetMessage());
 
-		current_command = NULL;
+		current_command = nullptr;
 
 		return COMMAND_RETURN_ERROR;
 	}
@@ -347,7 +347,7 @@ command_process(Client *client, unsigned num, char *line)
 
 	while (argc < COMMAND_ARGV_MAX &&
 	       (argv[argc] =
-		tokenizer.NextParam(error)) != NULL)
+		tokenizer.NextParam(error)) != nullptr)
 		++argc;
 
 	/* some error checks; we have to set current_command because
@@ -357,13 +357,13 @@ command_process(Client *client, unsigned num, char *line)
 
 	if (argc >= COMMAND_ARGV_MAX) {
 		command_error(client, ACK_ERROR_ARG, "Too many arguments");
-		current_command = NULL;
+		current_command = nullptr;
 		return COMMAND_RETURN_ERROR;
 	}
 
 	if (!tokenizer.IsEnd()) {
 		command_error(client, ACK_ERROR_ARG, "%s", error.GetMessage());
-		current_command = NULL;
+		current_command = nullptr;
 		return COMMAND_RETURN_ERROR;
 	}
 
@@ -374,7 +374,7 @@ command_process(Client *client, unsigned num, char *line)
 	if (cmd)
 		ret = cmd->handler(client, argc, argv);
 
-	current_command = NULL;
+	current_command = nullptr;
 	command_list_num = 0;
 
 	return ret;
diff --git a/src/ArchiveFile.hxx b/src/ArchiveFile.hxx
index 5f8dc54f5..b771409b7 100644
--- a/src/ArchiveFile.hxx
+++ b/src/ArchiveFile.hxx
@@ -49,8 +49,6 @@ public:
 	 * Opens an input_stream of a file within the archive.
 	 *
 	 * @param path the path within the archive
-	 * @param error_r location to store the error occurring, or
-	 * NULL to ignore errors
 	 */
 	virtual input_stream *OpenStream(const char *path,
 					 Mutex &mutex, Cond &cond,
diff --git a/src/ArchiveList.cxx b/src/ArchiveList.cxx
index d4d6835d1..f4a530506 100644
--- a/src/ArchiveList.cxx
+++ b/src/ArchiveList.cxx
@@ -38,7 +38,7 @@ const struct archive_plugin *const archive_plugins[] = {
 #ifdef HAVE_ISO9660
 	&iso9660_archive_plugin,
 #endif
-	NULL
+	nullptr
 };
 
 /** which plugins have been initialized successfully? */
@@ -51,15 +51,15 @@ static bool archive_plugins_enabled[ARRAY_SIZE(archive_plugins) - 1];
 const struct archive_plugin *
 archive_plugin_from_suffix(const char *suffix)
 {
-	if (suffix == NULL)
-		return NULL;
+	if (suffix == nullptr)
+		return nullptr;
 
 	archive_plugins_for_each_enabled(plugin)
-		if (plugin->suffixes != NULL &&
+		if (plugin->suffixes != nullptr &&
 		    string_array_contains(plugin->suffixes, suffix))
 			return plugin;
 
-	return NULL;
+	return nullptr;
 }
 
 const struct archive_plugin *
@@ -69,14 +69,14 @@ archive_plugin_from_name(const char *name)
 		if (strcmp(plugin->name, name) == 0)
 			return plugin;
 
-	return NULL;
+	return nullptr;
 }
 
 void archive_plugin_init_all(void)
 {
-	for (unsigned i = 0; archive_plugins[i] != NULL; ++i) {
+	for (unsigned i = 0; archive_plugins[i] != nullptr; ++i) {
 		const struct archive_plugin *plugin = archive_plugins[i];
-		if (plugin->init == NULL || archive_plugins[i]->init())
+		if (plugin->init == nullptr || archive_plugins[i]->init())
 			archive_plugins_enabled[i] = true;
 	}
 }
@@ -84,7 +84,7 @@ void archive_plugin_init_all(void)
 void archive_plugin_deinit_all(void)
 {
 	archive_plugins_for_each_enabled(plugin)
-		if (plugin->finish != NULL)
+		if (plugin->finish != nullptr)
 			plugin->finish();
 }
 
diff --git a/src/ArchiveList.hxx b/src/ArchiveList.hxx
index 057c351de..cbf159b2f 100644
--- a/src/ArchiveList.hxx
+++ b/src/ArchiveList.hxx
@@ -27,7 +27,7 @@ extern const struct archive_plugin *const archive_plugins[];
 #define archive_plugins_for_each(plugin) \
 	for (const struct archive_plugin *plugin, \
 		*const*archive_plugin_iterator = &archive_plugins[0]; \
-		(plugin = *archive_plugin_iterator) != NULL; \
+		(plugin = *archive_plugin_iterator) != nullptr; \
 		++archive_plugin_iterator)
 
 /* interface for using plugins */
diff --git a/src/ArchivePlugin.cxx b/src/ArchivePlugin.cxx
index dd2059c0f..05085fb33 100644
--- a/src/ArchivePlugin.cxx
+++ b/src/ArchivePlugin.cxx
@@ -28,9 +28,9 @@ ArchiveFile *
 archive_file_open(const struct archive_plugin *plugin, const char *path,
 		  Error &error)
 {
-	assert(plugin != NULL);
-	assert(plugin->open != NULL);
-	assert(path != NULL);
+	assert(plugin != nullptr);
+	assert(plugin->open != nullptr);
+	assert(path != nullptr);
 
 	ArchiveFile *file = plugin->open(path, error);
 	assert((file == nullptr) == error.IsDefined());
diff --git a/src/ArchivePlugin.hxx b/src/ArchivePlugin.hxx
index 38b7bccc3..cbc2e9816 100644
--- a/src/ArchivePlugin.hxx
+++ b/src/ArchivePlugin.hxx
@@ -29,14 +29,14 @@ struct archive_plugin {
 	const char *name;
 
 	/**
-	 * optional, set this to NULL if the archive plugin doesn't
+	 * optional, set this to nullptr if the archive plugin doesn't
 	 * have/need one this must false if there is an error and
 	 * true otherwise
 	 */
 	bool (*init)(void);
 
 	/**
-	 * optional, set this to NULL if the archive plugin doesn't
+	 * optional, set this to nullptr if the archive plugin doesn't
 	 * have/need one
 	 */
 	void (*finish)(void);
@@ -44,13 +44,13 @@ struct archive_plugin {
 	/**
 	 * tryes to open archive file and associates handle with archive
 	 * returns pointer to handle used is all operations with this archive
-	 * or NULL when opening fails
+	 * or nullptr when opening fails
 	 */
 	ArchiveFile *(*open)(const char *path_fs, Error &error);
 
 	/**
 	 * suffixes handled by this plugin.
-	 * last element in these arrays must always be a NULL
+	 * last element in these arrays must always be a nullptr
 	 */
 	const char *const*suffixes;
 };
diff --git a/src/ClientRead.cxx b/src/ClientRead.cxx
index af2e572a2..ed4d0285a 100644
--- a/src/ClientRead.cxx
+++ b/src/ClientRead.cxx
@@ -30,7 +30,7 @@ Client::OnSocketInput(void *data, size_t length)
 {
 	char *p = (char *)data;
 	char *newline = (char *)memchr(p, '\n', length);
-	if (newline == NULL)
+	if (newline == nullptr)
 		return InputResult::MORE;
 
 	TimeoutMonitor::ScheduleSeconds(client_timeout);
diff --git a/src/ClientSubscribe.cxx b/src/ClientSubscribe.cxx
index 918a621db..6bdb3e021 100644
--- a/src/ClientSubscribe.cxx
+++ b/src/ClientSubscribe.cxx
@@ -28,8 +28,8 @@
 enum client_subscribe_result
 client_subscribe(Client *client, const char *channel)
 {
-	assert(client != NULL);
-	assert(channel != NULL);
+	assert(client != nullptr);
+	assert(channel != nullptr);
 
 	if (!client_message_valid_channel_name(channel))
 		return CLIENT_SUBSCRIBE_INVALID;
@@ -78,7 +78,7 @@ client_unsubscribe_all(Client *client)
 bool
 client_push_message(Client *client, const ClientMessage &msg)
 {
-	assert(client != NULL);
+	assert(client != nullptr);
 
 	if (client->messages.size() >= CLIENT_MAX_MESSAGES ||
 	    !client->IsSubscribed(msg.GetChannel()))
diff --git a/src/CommandLine.cxx b/src/CommandLine.cxx
index 1f39e47aa..84fb2f5f3 100644
--- a/src/CommandLine.cxx
+++ b/src/CommandLine.cxx
@@ -79,8 +79,8 @@ static void version(void)
 		printf(" [%s]", plugin->name);
 
 		const char *const*suffixes = plugin->suffixes;
-		if (suffixes != NULL)
-			for (; *suffixes != NULL; ++suffixes)
+		if (suffixes != nullptr)
+			for (; *suffixes != nullptr; ++suffixes)
 				printf(" %s", *suffixes);
 
 		puts("");
@@ -107,8 +107,8 @@ static void version(void)
 		printf(" [%s]", plugin->name);
 
 		const char *const*suffixes = plugin->suffixes;
-		if (suffixes != NULL)
-			for (; *suffixes != NULL; ++suffixes)
+		if (suffixes != nullptr)
+			for (; *suffixes != nullptr; ++suffixes)
 				printf(" %s", *suffixes);
 
 		puts("");
@@ -156,19 +156,19 @@ parse_cmdline(int argc, char **argv, struct options *options,
 		option_no_config;
 	const GOptionEntry entries[] = {
 		{ "kill", 0, 0, G_OPTION_ARG_NONE, &options->kill,
-		  "kill the currently running mpd session", NULL },
+		  "kill the currently running mpd session", nullptr },
 		{ "no-config", 0, 0, G_OPTION_ARG_NONE, &option_no_config,
-		  "don't read from config", NULL },
+		  "don't read from config", nullptr },
 		{ "no-daemon", 0, 0, G_OPTION_ARG_NONE, &option_no_daemon,
-		  "don't detach from console", NULL },
+		  "don't detach from console", nullptr },
 		{ "stdout", 0, 0, G_OPTION_ARG_NONE, &options->log_stderr,
-		  NULL, NULL },
+		  nullptr, nullptr },
 		{ "stderr", 0, 0, G_OPTION_ARG_NONE, &options->log_stderr,
-		  "print messages to stderr", NULL },
+		  "print messages to stderr", nullptr },
 		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &options->verbose,
-		  "verbose logging", NULL },
+		  "verbose logging", nullptr },
 		{ "version", 'V', 0, G_OPTION_ARG_NONE, &option_version,
-		  "print version number", NULL },
+		  "print version number", nullptr },
 		{ nullptr, 0, 0, G_OPTION_ARG_NONE, nullptr, nullptr, nullptr }
 	};
 
@@ -178,7 +178,7 @@ parse_cmdline(int argc, char **argv, struct options *options,
 	options->verbose = false;
 
 	context = g_option_context_new("[path/to/mpd.conf]");
-	g_option_context_add_main_entries(context, entries, NULL);
+	g_option_context_add_main_entries(context, entries, nullptr);
 
 	g_option_context_set_summary(context, summary);
 
diff --git a/src/ConfigFile.cxx b/src/ConfigFile.cxx
index 5f614516e..90859a89a 100644
--- a/src/ConfigFile.cxx
+++ b/src/ConfigFile.cxx
@@ -49,13 +49,13 @@ config_read_name_value(struct config_param *param, char *input, unsigned line,
 	Tokenizer tokenizer(input);
 
 	const char *name = tokenizer.NextWord(error);
-	if (name == NULL) {
+	if (name == nullptr) {
 		assert(!tokenizer.IsEnd());
 		return false;
 	}
 
 	const char *value = tokenizer.NextString(error);
-	if (value == NULL) {
+	if (value == nullptr) {
 		if (tokenizer.IsEnd()) {
 			error.Set(config_file_domain, "Value missing");
 		} else {
@@ -71,7 +71,7 @@ config_read_name_value(struct config_param *param, char *input, unsigned line,
 	}
 
 	const struct block_param *bp = param->GetBlockParam(name);
-	if (bp != NULL) {
+	if (bp != nullptr) {
 		error.Format(config_file_domain,
 			     "\"%s\" is duplicate, first defined on line %i",
 			     name, bp->line);
@@ -91,11 +91,11 @@ config_read_block(FILE *fp, int *count, char *string, Error &error)
 		char *line;
 
 		line = fgets(string, MAX_STRING_SIZE, fp);
-		if (line == NULL) {
+		if (line == nullptr) {
 			delete ret;
 			error.Set(config_file_domain,
 				  "Expected '}' before end-of-file");
-			return NULL;
+			return nullptr;
 		}
 
 		(*count)++;
@@ -125,7 +125,7 @@ config_read_block(FILE *fp, int *count, char *string, Error &error)
 			assert(*line != 0);
 			delete ret;
 			error.FormatPrefix("line %i: ", *count);
-			return NULL;
+			return nullptr;
 		}
 	}
 }
@@ -167,7 +167,7 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, Error &error)
 
 		Tokenizer tokenizer(line);
 		name = tokenizer.NextWord(error);
-		if (name == NULL) {
+		if (name == nullptr) {
 			assert(!tokenizer.IsEnd());
 			error.FormatPrefix("line %i: ", count);
 			return false;
@@ -217,14 +217,14 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, Error &error)
 			}
 
 			param = config_read_block(fp, &count, string, error);
-			if (param == NULL) {
+			if (param == nullptr) {
 				return false;
 			}
 		} else {
 			/* a string value */
 
 			value = tokenizer.NextString(error);
-			if (value == NULL) {
+			if (value == nullptr) {
 				if (tokenizer.IsEnd())
 					error.Format(config_file_domain,
 						     "line %i: Value missing",
diff --git a/src/DatabaseGlue.cxx b/src/DatabaseGlue.cxx
index d46e3022a..7020880e0 100644
--- a/src/DatabaseGlue.cxx
+++ b/src/DatabaseGlue.cxx
@@ -45,7 +45,7 @@ static bool is_simple;
 bool
 DatabaseGlobalInit(const config_param &param, Error &error)
 {
-	assert(db == NULL);
+	assert(db == nullptr);
 	assert(!db_is_open);
 
 	const char *plugin_name =
@@ -53,14 +53,14 @@ DatabaseGlobalInit(const config_param &param, Error &error)
 	is_simple = strcmp(plugin_name, "simple") == 0;
 
 	const DatabasePlugin *plugin = GetDatabasePluginByName(plugin_name);
-	if (plugin == NULL) {
+	if (plugin == nullptr) {
 		error.Format(db_domain,
 			     "No such database plugin: %s", plugin_name);
 		return false;
 	}
 
 	db = plugin->create(param, error);
-	return db != NULL;
+	return db != nullptr;
 }
 
 void
@@ -69,14 +69,14 @@ DatabaseGlobalDeinit(void)
 	if (db_is_open)
 		db->Close();
 
-	if (db != NULL)
+	if (db != nullptr)
 		delete db;
 }
 
 const Database *
 GetDatabase()
 {
-	assert(db == NULL || db_is_open);
+	assert(db == nullptr || db_is_open);
 
 	return db;
 }
@@ -95,7 +95,7 @@ GetDatabase(Error &error)
 bool
 db_is_simple(void)
 {
-	assert(db == NULL || db_is_open);
+	assert(db == nullptr || db_is_open);
 
 	return is_simple;
 }
@@ -103,7 +103,7 @@ db_is_simple(void)
 Directory *
 db_get_root(void)
 {
-	assert(db != NULL);
+	assert(db != nullptr);
 	assert(db_is_simple());
 
 	return ((SimpleDatabase *)db)->GetRoot();
@@ -112,11 +112,11 @@ db_get_root(void)
 Directory *
 db_get_directory(const char *name)
 {
-	if (db == NULL)
-		return NULL;
+	if (db == nullptr)
+		return nullptr;
 
 	Directory *music_root = db_get_root();
-	if (name == NULL)
+	if (name == nullptr)
 		return music_root;
 
 	return music_root->LookupDirectory(name);
@@ -125,7 +125,7 @@ db_get_directory(const char *name)
 bool
 db_save(Error &error)
 {
-	assert(db != NULL);
+	assert(db != nullptr);
 	assert(db_is_open);
 	assert(db_is_simple());
 
@@ -135,7 +135,7 @@ db_save(Error &error)
 bool
 DatabaseGlobalOpen(Error &error)
 {
-	assert(db != NULL);
+	assert(db != nullptr);
 	assert(!db_is_open);
 
 	if (!db->Open(error))
@@ -151,7 +151,7 @@ DatabaseGlobalOpen(Error &error)
 time_t
 db_get_mtime(void)
 {
-	assert(db != NULL);
+	assert(db != nullptr);
 	assert(db_is_open);
 	assert(db_is_simple());
 
diff --git a/src/DatabaseGlue.hxx b/src/DatabaseGlue.hxx
index 202881382..4fcc68451 100644
--- a/src/DatabaseGlue.hxx
+++ b/src/DatabaseGlue.hxx
@@ -41,7 +41,7 @@ bool
 DatabaseGlobalOpen(Error &error);
 
 /**
- * Returns the global #Database instance.  May return NULL if this MPD
+ * Returns the global #Database instance.  May return nullptr if this MPD
  * configuration has no database (no music_directory was configured).
  */
 gcc_pure
@@ -49,7 +49,7 @@ const Database *
 GetDatabase();
 
 /**
- * Returns the global #Database instance.  May return NULL if this MPD
+ * Returns the global #Database instance.  May return nullptr if this MPD
  * configuration has no database (no music_directory was configured).
  */
 gcc_pure
diff --git a/src/DatabasePrint.cxx b/src/DatabasePrint.cxx
index c50c7686e..e6bae9942 100644
--- a/src/DatabasePrint.cxx
+++ b/src/DatabasePrint.cxx
@@ -69,11 +69,11 @@ print_playlist_in_directory(Client *client,
 static bool
 PrintSongBrief(Client *client, Song &song)
 {
-	assert(song.parent != NULL);
+	assert(song.parent != nullptr);
 
 	song_print_uri(client, &song);
 
-	if (song.tag != NULL && song.tag->has_playlist)
+	if (song.tag != nullptr && song.tag->has_playlist)
 		/* this song file has an embedded CUE sheet */
 		print_playlist_in_directory(client, *song.parent, song.uri);
 
@@ -83,11 +83,11 @@ PrintSongBrief(Client *client, Song &song)
 static bool
 PrintSongFull(Client *client, Song &song)
 {
-	assert(song.parent != NULL);
+	assert(song.parent != nullptr);
 
 	song_print_info(client, &song);
 
-	if (song.tag != NULL && song.tag->has_playlist)
+	if (song.tag != nullptr && song.tag->has_playlist)
 		/* this song file has an embedded CUE sheet */
 		print_playlist_in_directory(client, *song.parent, song.uri);
 
diff --git a/src/DatabaseRegistry.cxx b/src/DatabaseRegistry.cxx
index cf01decdd..c37d59968 100644
--- a/src/DatabaseRegistry.cxx
+++ b/src/DatabaseRegistry.cxx
@@ -29,7 +29,7 @@ const DatabasePlugin *const database_plugins[] = {
 #ifdef HAVE_LIBMPDCLIENT
 	&proxy_db_plugin,
 #endif
-	NULL
+	nullptr
 };
 
 const DatabasePlugin *
diff --git a/src/DatabaseRegistry.hxx b/src/DatabaseRegistry.hxx
index f93ddce89..01d73978c 100644
--- a/src/DatabaseRegistry.hxx
+++ b/src/DatabaseRegistry.hxx
@@ -25,7 +25,7 @@
 struct DatabasePlugin;
 
 /**
- * NULL terminated list of all database plugins which were enabled at
+ * nullptr terminated list of all database plugins which were enabled at
  * compile time.
  */
 extern const DatabasePlugin *const database_plugins[];
diff --git a/src/DatabaseSave.cxx b/src/DatabaseSave.cxx
index b7077b413..7c6e34a4e 100644
--- a/src/DatabaseSave.cxx
+++ b/src/DatabaseSave.cxx
@@ -51,7 +51,7 @@ enum {
 void
 db_save_internal(FILE *fp, const Directory *music_root)
 {
-	assert(music_root != NULL);
+	assert(music_root != nullptr);
 
 	fprintf(fp, "%s\n", DIRECTORY_INFO_BEGIN);
 	fprintf(fp, DB_FORMAT_PREFIX "%u\n", DB_FORMAT);
@@ -76,18 +76,18 @@ db_load_internal(TextFile &file, Directory *music_root, Error &error)
 	bool success;
 	bool tags[TAG_NUM_OF_ITEM_TYPES];
 
-	assert(music_root != NULL);
+	assert(music_root != nullptr);
 
 	/* get initial info */
 	line = file.ReadLine();
-	if (line == NULL || strcmp(DIRECTORY_INFO_BEGIN, line) != 0) {
+	if (line == nullptr || strcmp(DIRECTORY_INFO_BEGIN, line) != 0) {
 		error.Set(db_domain, "Database corrupted");
 		return false;
 	}
 
 	memset(tags, false, sizeof(tags));
 
-	while ((line = file.ReadLine()) != NULL &&
+	while ((line = file.ReadLine()) != nullptr &&
 	       strcmp(line, DIRECTORY_INFO_END) != 0) {
 		if (g_str_has_prefix(line, DB_FORMAT_PREFIX)) {
 			format = atoi(line + sizeof(DB_FORMAT_PREFIX) - 1);
diff --git a/src/DatabaseSelection.hxx b/src/DatabaseSelection.hxx
index 7fab2d303..8ef5b6d9c 100644
--- a/src/DatabaseSelection.hxx
+++ b/src/DatabaseSelection.hxx
@@ -23,7 +23,6 @@
 #include "Compiler.h"
 
 #include <assert.h>
-#include <stddef.h>
 
 class SongFilter;
 struct Song;
@@ -31,7 +30,7 @@ struct Song;
 struct DatabaseSelection {
 	/**
 	 * The base URI of the search (UTF-8).  Must not begin or end
-	 * with a slash.  NULL or an empty string searches the whole
+	 * with a slash.  nullptr or an empty string searches the whole
 	 * database.
 	 */
 	const char *uri;
@@ -46,7 +45,7 @@ struct DatabaseSelection {
 	DatabaseSelection(const char *_uri, bool _recursive,
 			  const SongFilter *_filter=nullptr)
 		:uri(_uri), recursive(_recursive), filter(_filter) {
-		assert(uri != NULL);
+		assert(uri != nullptr);
 	}
 
 	gcc_pure
diff --git a/src/DecoderAPI.cxx b/src/DecoderAPI.cxx
index f7716a584..7f3533233 100644
--- a/src/DecoderAPI.cxx
+++ b/src/DecoderAPI.cxx
@@ -45,10 +45,10 @@ decoder_initialized(struct decoder *decoder,
 	struct audio_format_string af_string;
 
 	assert(dc->state == DecoderState::START);
-	assert(dc->pipe != NULL);
-	assert(decoder != NULL);
-	assert(decoder->stream_tag == NULL);
-	assert(decoder->decoder_tag == NULL);
+	assert(dc->pipe != nullptr);
+	assert(decoder != nullptr);
+	assert(decoder->stream_tag == nullptr);
+	assert(decoder->decoder_tag == nullptr);
 	assert(!decoder->seeking);
 	assert(audio_format.IsDefined());
 	assert(audio_format.IsValid());
@@ -83,7 +83,7 @@ static bool
 decoder_prepare_initial_seek(struct decoder *decoder)
 {
 	const struct decoder_control *dc = decoder->dc;
-	assert(dc->pipe != NULL);
+	assert(dc->pipe != nullptr);
 
 	if (dc->state != DecoderState::DECODE)
 		/* wait until the decoder has finished initialisation
@@ -130,7 +130,7 @@ static DecoderCommand
 decoder_get_virtual_command(struct decoder *decoder)
 {
 	const struct decoder_control *dc = decoder->dc;
-	assert(dc->pipe != NULL);
+	assert(dc->pipe != nullptr);
 
 	if (decoder_prepare_initial_seek(decoder))
 		return DecoderCommand::SEEK;
@@ -156,11 +156,11 @@ decoder_command_finished(struct decoder *decoder)
 	assert(dc->command != DecoderCommand::SEEK ||
 	       decoder->initial_seek_running ||
 	       dc->seek_error || decoder->seeking);
-	assert(dc->pipe != NULL);
+	assert(dc->pipe != nullptr);
 
 	if (decoder->initial_seek_running) {
 		assert(!decoder->seeking);
-		assert(decoder->chunk == NULL);
+		assert(decoder->chunk == nullptr);
 		assert(dc->pipe->IsEmpty());
 
 		decoder->initial_seek_running = false;
@@ -174,9 +174,9 @@ decoder_command_finished(struct decoder *decoder)
 
 		/* delete frames from the old song position */
 
-		if (decoder->chunk != NULL) {
+		if (decoder->chunk != nullptr) {
 			dc->buffer->Return(decoder->chunk);
-			decoder->chunk = NULL;
+			decoder->chunk = nullptr;
 		}
 
 		dc->pipe->Clear(*dc->buffer);
@@ -193,7 +193,7 @@ double decoder_seek_where(gcc_unused struct decoder * decoder)
 {
 	const struct decoder_control *dc = decoder->dc;
 
-	assert(dc->pipe != NULL);
+	assert(dc->pipe != nullptr);
 
 	if (decoder->initial_seek_running)
 		return dc->start_ms / 1000.;
@@ -209,7 +209,7 @@ void decoder_seek_error(struct decoder * decoder)
 {
 	struct decoder_control *dc = decoder->dc;
 
-	assert(dc->pipe != NULL);
+	assert(dc->pipe != nullptr);
 
 	if (decoder->initial_seek_running) {
 		/* d'oh, we can't seek to the sub-song start position,
@@ -234,7 +234,7 @@ gcc_pure
 static inline bool
 decoder_check_cancel_read(const struct decoder *decoder)
 {
-	if (decoder == NULL)
+	if (decoder == nullptr)
 		return false;
 
 	const struct decoder_control *dc = decoder->dc;
@@ -254,13 +254,13 @@ size_t decoder_read(struct decoder *decoder,
 		    struct input_stream *is,
 		    void *buffer, size_t length)
 {
-	/* XXX don't allow decoder==NULL */
+	/* XXX don't allow decoder==nullptr */
 
-	assert(decoder == NULL ||
+	assert(decoder == nullptr ||
 	       decoder->dc->state == DecoderState::START ||
 	       decoder->dc->state == DecoderState::DECODE);
-	assert(is != NULL);
-	assert(buffer != NULL);
+	assert(is != nullptr);
+	assert(buffer != nullptr);
 
 	if (length == 0)
 		return 0;
@@ -295,7 +295,7 @@ size_t decoder_read(struct decoder *decoder,
 void
 decoder_timestamp(struct decoder *decoder, double t)
 {
-	assert(decoder != NULL);
+	assert(decoder != nullptr);
 	assert(t >= 0);
 
 	decoder->timestamp = t;
@@ -310,17 +310,17 @@ do_send_tag(struct decoder *decoder, const Tag &tag)
 {
 	struct music_chunk *chunk;
 
-	if (decoder->chunk != NULL) {
+	if (decoder->chunk != nullptr) {
 		/* there is a partial chunk - flush it, we want the
 		   tag in a new chunk */
 		decoder_flush_chunk(decoder);
 		decoder->dc->client_cond.signal();
 	}
 
-	assert(decoder->chunk == NULL);
+	assert(decoder->chunk == nullptr);
 
 	chunk = decoder_get_chunk(decoder);
-	if (chunk == NULL) {
+	if (chunk == nullptr) {
 		assert(decoder->dc->command != DecoderCommand::NONE);
 		return decoder->dc->command;
 	}
@@ -334,17 +334,17 @@ update_stream_tag(struct decoder *decoder, struct input_stream *is)
 {
 	Tag *tag;
 
-	tag = is != NULL
+	tag = is != nullptr
 		? is->LockReadTag()
-		: NULL;
-	if (tag == NULL) {
+		: nullptr;
+	if (tag == nullptr) {
 		tag = decoder->song_tag;
-		if (tag == NULL)
+		if (tag == nullptr)
 			return false;
 
 		/* no stream tag present - submit the song tag
 		   instead */
-		decoder->song_tag = NULL;
+		decoder->song_tag = nullptr;
 	}
 
 	delete decoder->stream_tag;
@@ -362,7 +362,7 @@ decoder_data(struct decoder *decoder,
 	DecoderCommand cmd;
 
 	assert(dc->state == DecoderState::DECODE);
-	assert(dc->pipe != NULL);
+	assert(dc->pipe != nullptr);
 	assert(length % dc->in_audio_format.GetFrameSize() == 0);
 
 	dc->Lock();
@@ -376,7 +376,7 @@ decoder_data(struct decoder *decoder,
 	/* send stream tags */
 
 	if (update_stream_tag(decoder, is)) {
-		if (decoder->decoder_tag != NULL) {
+		if (decoder->decoder_tag != nullptr) {
 			/* merge with tag from decoder plugin */
 			Tag *tag = Tag::Merge(*decoder->decoder_tag,
 					      *decoder->stream_tag);
@@ -397,7 +397,7 @@ decoder_data(struct decoder *decoder,
 						   dc->out_audio_format,
 						   &length,
 						   error);
-		if (data == NULL) {
+		if (data == nullptr) {
 			/* the PCM conversion has failed - stop
 			   playback, since we have no better way to
 			   bail out */
@@ -412,7 +412,7 @@ decoder_data(struct decoder *decoder,
 		bool full;
 
 		chunk = decoder_get_chunk(decoder);
-		if (chunk == NULL) {
+		if (chunk == nullptr) {
 			assert(dc->command != DecoderCommand::NONE);
 			return dc->command;
 		}
@@ -421,7 +421,7 @@ decoder_data(struct decoder *decoder,
 					  decoder->timestamp -
 					  dc->song->start_ms / 1000.0,
 					  kbit_rate, &nbytes);
-		if (dest == NULL) {
+		if (dest == nullptr) {
 			/* the chunk is full, flush it */
 			decoder_flush_chunk(decoder);
 			dc->client_cond.signal();
@@ -470,7 +470,7 @@ decoder_tag(gcc_unused struct decoder *decoder, struct input_stream *is,
 	DecoderCommand cmd;
 
 	assert(dc->state == DecoderState::DECODE);
-	assert(dc->pipe != NULL);
+	assert(dc->pipe != nullptr);
 
 	/* save the tag */
 
@@ -491,7 +491,7 @@ decoder_tag(gcc_unused struct decoder *decoder, struct input_stream *is,
 
 	/* send tag to music pipe */
 
-	if (decoder->stream_tag != NULL) {
+	if (decoder->stream_tag != nullptr) {
 		/* merge with tag from input stream */
 		Tag *merged;
 
@@ -510,9 +510,9 @@ void
 decoder_replay_gain(struct decoder *decoder,
 		    const struct replay_gain_info *replay_gain_info)
 {
-	assert(decoder != NULL);
+	assert(decoder != nullptr);
 
-	if (replay_gain_info != NULL) {
+	if (replay_gain_info != nullptr) {
 		static unsigned serial;
 		if (++serial == 0)
 			serial = 1;
@@ -532,7 +532,7 @@ decoder_replay_gain(struct decoder *decoder,
 		decoder->replay_gain_info = *replay_gain_info;
 		decoder->replay_gain_serial = serial;
 
-		if (decoder->chunk != NULL) {
+		if (decoder->chunk != nullptr) {
 			/* flush the current chunk because the new
 			   replay gain values affect the following
 			   samples */
@@ -547,9 +547,9 @@ void
 decoder_mixramp(struct decoder *decoder,
 		char *mixramp_start, char *mixramp_end)
 {
-	assert(decoder != NULL);
+	assert(decoder != nullptr);
 	struct decoder_control *dc = decoder->dc;
-	assert(dc != NULL);
+	assert(dc != nullptr);
 
 	dc->MixRampStart(mixramp_start);
 	dc->MixRampEnd(mixramp_end);
diff --git a/src/DecoderAPI.hxx b/src/DecoderAPI.hxx
index 8bd38545f..2d81884c2 100644
--- a/src/DecoderAPI.hxx
+++ b/src/DecoderAPI.hxx
@@ -146,7 +146,7 @@ decoder_tag(struct decoder *decoder, struct input_stream *is, Tag &&tag);
  * Set replay gain values for the following chunks.
  *
  * @param decoder the decoder object
- * @param rgi the replay_gain_info object; may be NULL to invalidate
+ * @param rgi the replay_gain_info object; may be nullptr to invalidate
  * the previous replay gain values
  */
 void
@@ -157,8 +157,8 @@ decoder_replay_gain(struct decoder *decoder,
  * Store MixRamp tags.
  *
  * @param decoder the decoder object
- * @param mixramp_start the mixramp_start tag; may be NULL to invalidate
- * @param mixramp_end the mixramp_end tag; may be NULL to invalidate
+ * @param mixramp_start the mixramp_start tag; may be nullptr to invalidate
+ * @param mixramp_end the mixramp_end tag; may be nullptr to invalidate
  */
 void
 decoder_mixramp(struct decoder *decoder,
diff --git a/src/DecoderBuffer.hxx b/src/DecoderBuffer.hxx
index 4f7efb29a..8411f9269 100644
--- a/src/DecoderBuffer.hxx
+++ b/src/DecoderBuffer.hxx
@@ -35,7 +35,7 @@ struct input_stream;
 /**
  * Creates a new buffer.
  *
- * @param decoder the decoder object, used for decoder_read(), may be NULL
+ * @param decoder the decoder object, used for decoder_read(), may be nullptr
  * @param is the input stream object where we should read from
  * @param size the maximum size of the buffer
  * @return the new decoder_buffer object
@@ -75,7 +75,7 @@ decoder_buffer_fill(DecoderBuffer *buffer);
  * @param buffer the decoder_buffer object
  * @param length_r pointer to a size_t where you will receive the
  * number of bytes available
- * @return a pointer to the read buffer, or NULL if there is no data
+ * @return a pointer to the read buffer, or nullptr if there is no data
  * available
  */
 const void *
diff --git a/src/DecoderControl.cxx b/src/DecoderControl.cxx
index 330c791dd..26751855d 100644
--- a/src/DecoderControl.cxx
+++ b/src/DecoderControl.cxx
@@ -38,7 +38,7 @@ decoder_control::~decoder_control()
 {
 	ClearError();
 
-	if (song != NULL)
+	if (song != nullptr)
 		song->Free();
 
 	g_free(mixramp_start);
@@ -49,7 +49,7 @@ decoder_control::~decoder_control()
 bool
 decoder_control::IsCurrentSong(const Song *_song) const
 {
-	assert(_song != NULL);
+	assert(_song != nullptr);
 
 	switch (state) {
 	case DecoderState::STOP:
@@ -70,7 +70,7 @@ decoder_control::Start(Song *_song,
 		       unsigned _start_ms, unsigned _end_ms,
 		       MusicBuffer &_buffer, MusicPipe &_pipe)
 {
-	assert(_song != NULL);
+	assert(_song != nullptr);
 	assert(_pipe.IsEmpty());
 
 	if (song != nullptr)
diff --git a/src/DecoderInternal.cxx b/src/DecoderInternal.cxx
index 307a3550b..43536686b 100644
--- a/src/DecoderInternal.cxx
+++ b/src/DecoderInternal.cxx
@@ -64,14 +64,14 @@ decoder_get_chunk(struct decoder *decoder)
 	struct decoder_control *dc = decoder->dc;
 	DecoderCommand cmd;
 
-	assert(decoder != NULL);
+	assert(decoder != nullptr);
 
-	if (decoder->chunk != NULL)
+	if (decoder->chunk != nullptr)
 		return decoder->chunk;
 
 	do {
 		decoder->chunk = dc->buffer->Allocate();
-		if (decoder->chunk != NULL) {
+		if (decoder->chunk != nullptr) {
 			decoder->chunk->replay_gain_serial =
 				decoder->replay_gain_serial;
 			if (decoder->replay_gain_serial != 0)
@@ -86,7 +86,7 @@ decoder_get_chunk(struct decoder *decoder)
 		dc->Unlock();
 	} while (cmd == DecoderCommand::NONE);
 
-	return NULL;
+	return nullptr;
 }
 
 void
@@ -94,13 +94,13 @@ decoder_flush_chunk(struct decoder *decoder)
 {
 	struct decoder_control *dc = decoder->dc;
 
-	assert(decoder != NULL);
-	assert(decoder->chunk != NULL);
+	assert(decoder != nullptr);
+	assert(decoder->chunk != nullptr);
 
 	if (decoder->chunk->IsEmpty())
 		dc->buffer->Return(decoder->chunk);
 	else
 		dc->pipe->Push(decoder->chunk);
 
-	decoder->chunk = NULL;
+	decoder->chunk = nullptr;
 }
diff --git a/src/DecoderList.cxx b/src/DecoderList.cxx
index 0cdcc07ae..fc3ef89cd 100644
--- a/src/DecoderList.cxx
+++ b/src/DecoderList.cxx
@@ -110,7 +110,7 @@ const struct decoder_plugin *const decoder_plugins[] = {
 	&gme_decoder_plugin,
 #endif
 	&pcm_decoder_plugin,
-	NULL
+	nullptr
 };
 
 static constexpr unsigned num_decoder_plugins =
@@ -142,18 +142,18 @@ const struct decoder_plugin *
 decoder_plugin_from_suffix(const char *suffix,
 			   const struct decoder_plugin *plugin)
 {
-	if (suffix == NULL)
-		return NULL;
+	if (suffix == nullptr)
+		return nullptr;
 
 	for (unsigned i = decoder_plugin_next_index(plugin);
-	     decoder_plugins[i] != NULL; ++i) {
+	     decoder_plugins[i] != nullptr; ++i) {
 		plugin = decoder_plugins[i];
 		if (decoder_plugins_enabled[i] &&
 		    decoder_plugin_supports_suffix(plugin, suffix))
 			return plugin;
 	}
 
-	return NULL;
+	return nullptr;
 }
 
 const struct decoder_plugin *
@@ -161,12 +161,12 @@ decoder_plugin_from_mime_type(const char *mimeType, unsigned int next)
 {
 	static unsigned i = num_decoder_plugins;
 
-	if (mimeType == NULL)
-		return NULL;
+	if (mimeType == nullptr)
+		return nullptr;
 
 	if (!next)
 		i = 0;
-	for (; decoder_plugins[i] != NULL; ++i) {
+	for (; decoder_plugins[i] != nullptr; ++i) {
 		const struct decoder_plugin *plugin = decoder_plugins[i];
 		if (decoder_plugins_enabled[i] &&
 		    decoder_plugin_supports_mime_type(plugin, mimeType)) {
@@ -175,7 +175,7 @@ decoder_plugin_from_mime_type(const char *mimeType, unsigned int next)
 		}
 	}
 
-	return NULL;
+	return nullptr;
 }
 
 const struct decoder_plugin *
@@ -185,23 +185,23 @@ decoder_plugin_from_name(const char *name)
 		if (strcmp(plugin->name, name) == 0)
 			return plugin;
 
-	return NULL;
+	return nullptr;
 }
 
 /**
  * Find the "decoder" configuration block for the specified plugin.
  *
  * @param plugin_name the name of the decoder plugin
- * @return the configuration block, or NULL if none was configured
+ * @return the configuration block, or nullptr if none was configured
  */
 static const struct config_param *
 decoder_plugin_config(const char *plugin_name)
 {
-	const struct config_param *param = NULL;
+	const struct config_param *param = nullptr;
 
-	while ((param = config_get_next_param(CONF_DECODER, param)) != NULL) {
+	while ((param = config_get_next_param(CONF_DECODER, param)) != nullptr) {
 		const char *name = param->GetBlockValue("plugin");
-		if (name == NULL)
+		if (name == nullptr)
 			FormatFatalError("decoder configuration without 'plugin' name in line %d",
 					 param->line);
 
@@ -209,14 +209,14 @@ decoder_plugin_config(const char *plugin_name)
 			return param;
 	}
 
-	return NULL;
+	return nullptr;
 }
 
 void decoder_plugin_init_all(void)
 {
 	struct config_param empty;
 
-	for (unsigned i = 0; decoder_plugins[i] != NULL; ++i) {
+	for (unsigned i = 0; decoder_plugins[i] != nullptr; ++i) {
 		const struct decoder_plugin *plugin = decoder_plugins[i];
 		const struct config_param *param =
 			decoder_plugin_config(plugin->name);
diff --git a/src/DecoderList.hxx b/src/DecoderList.hxx
index 8dab8724e..7beed230b 100644
--- a/src/DecoderList.hxx
+++ b/src/DecoderList.hxx
@@ -28,7 +28,7 @@ extern bool decoder_plugins_enabled[];
 #define decoder_plugins_for_each(plugin) \
 	for (const struct decoder_plugin *plugin, \
 		*const*decoder_plugin_iterator = &decoder_plugins[0]; \
-		(plugin = *decoder_plugin_iterator) != NULL; \
+		(plugin = *decoder_plugin_iterator) != nullptr; \
 		++decoder_plugin_iterator)
 
 #define decoder_plugins_for_each_enabled(plugin) \
@@ -41,8 +41,8 @@ extern bool decoder_plugins_enabled[];
  * Find the next enabled decoder plugin which supports the specified suffix.
  *
  * @param suffix the file name suffix
- * @param plugin the previous plugin, or NULL to find the first plugin
- * @return a plugin, or NULL if none matches
+ * @param plugin the previous plugin, or nullptr to find the first plugin
+ * @return a plugin, or nullptr if none matches
  */
 const struct decoder_plugin *
 decoder_plugin_from_suffix(const char *suffix,
diff --git a/src/DecoderPrint.cxx b/src/DecoderPrint.cxx
index 3f7f94937..6d5bd4f30 100644
--- a/src/DecoderPrint.cxx
+++ b/src/DecoderPrint.cxx
@@ -31,17 +31,17 @@ decoder_plugin_print(Client *client,
 {
 	const char *const*p;
 
-	assert(plugin != NULL);
-	assert(plugin->name != NULL);
+	assert(plugin != nullptr);
+	assert(plugin->name != nullptr);
 
 	client_printf(client, "plugin: %s\n", plugin->name);
 
-	if (plugin->suffixes != NULL)
-		for (p = plugin->suffixes; *p != NULL; ++p)
+	if (plugin->suffixes != nullptr)
+		for (p = plugin->suffixes; *p != nullptr; ++p)
 			client_printf(client, "suffix: %s\n", *p);
 
-	if (plugin->mime_types != NULL)
-		for (p = plugin->mime_types; *p != NULL; ++p)
+	if (plugin->mime_types != nullptr)
+		for (p = plugin->mime_types; *p != nullptr; ++p)
 			client_printf(client, "mime_type: %s\n", *p);
 }
 
diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx
index 1f85cd835..39aa4b395 100644
--- a/src/DecoderThread.cxx
+++ b/src/DecoderThread.cxx
@@ -70,7 +70,7 @@ decoder_command_finished_locked(struct decoder_control *dc)
  * Unlock the decoder before calling this function.
  *
  * @return an input_stream on success or if #DecoderCommand::STOP is
- * received, NULL on error
+ * received, nullptr on error
  */
 static struct input_stream *
 decoder_input_stream_open(struct decoder_control *dc, const char *uri)
@@ -78,11 +78,11 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
 	Error error;
 
 	input_stream *is = input_stream::Open(uri, dc->mutex, dc->cond, error);
-	if (is == NULL) {
+	if (is == nullptr) {
 		if (error.IsDefined())
 			LogError(error);
 
-		return NULL;
+		return nullptr;
 	}
 
 	/* wait for the input stream to become ready; its metadata
@@ -102,7 +102,7 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
 		dc->Unlock();
 
 		LogError(error);
-		return NULL;
+		return nullptr;
 	}
 
 	dc->Unlock();
@@ -115,12 +115,12 @@ decoder_stream_decode(const struct decoder_plugin *plugin,
 		      struct decoder *decoder,
 		      struct input_stream *input_stream)
 {
-	assert(plugin != NULL);
-	assert(plugin->stream_decode != NULL);
-	assert(decoder != NULL);
-	assert(decoder->stream_tag == NULL);
-	assert(decoder->decoder_tag == NULL);
-	assert(input_stream != NULL);
+	assert(plugin != nullptr);
+	assert(plugin->stream_decode != nullptr);
+	assert(decoder != nullptr);
+	assert(decoder->stream_tag == nullptr);
+	assert(decoder->decoder_tag == nullptr);
+	assert(input_stream != nullptr);
 	assert(input_stream->ready);
 	assert(decoder->dc->state == DecoderState::START);
 
@@ -148,12 +148,12 @@ static bool
 decoder_file_decode(const struct decoder_plugin *plugin,
 		    struct decoder *decoder, const char *path)
 {
-	assert(plugin != NULL);
-	assert(plugin->file_decode != NULL);
-	assert(decoder != NULL);
-	assert(decoder->stream_tag == NULL);
-	assert(decoder->decoder_tag == NULL);
-	assert(path != NULL);
+	assert(plugin != nullptr);
+	assert(plugin->file_decode != nullptr);
+	assert(decoder != nullptr);
+	assert(decoder->stream_tag == nullptr);
+	assert(decoder->decoder_tag == nullptr);
+	assert(path != nullptr);
 	assert(PathTraits::IsAbsoluteFS(path));
 	assert(decoder->dc->state == DecoderState::START);
 
@@ -192,7 +192,7 @@ static bool
 decoder_run_stream_mime_type(struct decoder *decoder, struct input_stream *is,
 			     GSList **tried_r)
 {
-	assert(tried_r != NULL);
+	assert(tried_r != nullptr);
 
 	const struct decoder_plugin *plugin;
 	unsigned int next = 0;
@@ -202,10 +202,10 @@ decoder_run_stream_mime_type(struct decoder *decoder, struct input_stream *is,
 
 	while ((plugin = decoder_plugin_from_mime_type(is->mime.c_str(),
 						       next++))) {
-		if (plugin->stream_decode == NULL)
+		if (plugin->stream_decode == nullptr)
 			continue;
 
-		if (g_slist_find(*tried_r, plugin) != NULL)
+		if (g_slist_find(*tried_r, plugin) != nullptr)
 			/* don't try a plugin twice */
 			continue;
 
@@ -228,19 +228,19 @@ static bool
 decoder_run_stream_suffix(struct decoder *decoder, struct input_stream *is,
 			  const char *uri, GSList **tried_r)
 {
-	assert(tried_r != NULL);
+	assert(tried_r != nullptr);
 
 	const char *suffix = uri_get_suffix(uri);
-	const struct decoder_plugin *plugin = NULL;
+	const struct decoder_plugin *plugin = nullptr;
 
-	if (suffix == NULL)
+	if (suffix == nullptr)
 		return false;
 
-	while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != NULL) {
-		if (plugin->stream_decode == NULL)
+	while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != nullptr) {
+		if (plugin->stream_decode == nullptr)
 			continue;
 
-		if (g_slist_find(*tried_r, plugin) != NULL)
+		if (g_slist_find(*tried_r, plugin) != nullptr)
 			/* don't try a plugin twice */
 			continue;
 
@@ -262,7 +262,7 @@ decoder_run_stream_fallback(struct decoder *decoder, struct input_stream *is)
 	const struct decoder_plugin *plugin;
 
 	plugin = decoder_plugin_from_name("mad");
-	return plugin != NULL && plugin->stream_decode != NULL &&
+	return plugin != nullptr && plugin->stream_decode != nullptr &&
 		decoder_stream_decode(plugin, decoder, is);
 }
 
@@ -279,14 +279,14 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
 	dc->Unlock();
 
 	input_stream = decoder_input_stream_open(dc, uri);
-	if (input_stream == NULL) {
+	if (input_stream == nullptr) {
 		dc->Lock();
 		return false;
 	}
 
 	dc->Lock();
 
-	GSList *tried = NULL;
+	GSList *tried = nullptr;
 
 	success = dc->command == DecoderCommand::STOP ||
 		/* first we try mime types: */
@@ -296,7 +296,7 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
 					  &tried) ||
 		/* fallback to mp3: this is needed for bastard streams
 		   that don't have a suffix or set the mimeType */
-		(tried == NULL &&
+		(tried == nullptr &&
 		 decoder_run_stream_fallback(decoder, input_stream));
 
 	g_slist_free(tried);
@@ -328,29 +328,29 @@ decoder_run_file(struct decoder *decoder, const char *path_fs)
 {
 	struct decoder_control *dc = decoder->dc;
 	const char *suffix = uri_get_suffix(path_fs);
-	const struct decoder_plugin *plugin = NULL;
+	const struct decoder_plugin *plugin = nullptr;
 
-	if (suffix == NULL)
+	if (suffix == nullptr)
 		return false;
 
 	dc->Unlock();
 
 	decoder_load_replay_gain(decoder, path_fs);
 
-	while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != NULL) {
-		if (plugin->file_decode != NULL) {
+	while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != nullptr) {
+		if (plugin->file_decode != nullptr) {
 			dc->Lock();
 
 			if (decoder_file_decode(plugin, decoder, path_fs))
 				return true;
 
 			dc->Unlock();
-		} else if (plugin->stream_decode != NULL) {
+		} else if (plugin->stream_decode != nullptr) {
 			struct input_stream *input_stream;
 			bool success;
 
 			input_stream = decoder_input_stream_open(dc, path_fs);
-			if (input_stream == NULL)
+			if (input_stream == nullptr)
 				continue;
 
 			dc->Lock();
@@ -378,7 +378,7 @@ decoder_run_song(struct decoder_control *dc,
 		 const Song *song, const char *uri)
 {
 	decoder decoder(dc, dc->start_ms > 0,
-			song->tag != NULL && song->IsFile()
+			song->tag != nullptr && song->IsFile()
 			? new Tag(*song->tag) : nullptr);
 	int ret;
 
@@ -394,7 +394,7 @@ decoder_run_song(struct decoder_control *dc,
 
 	/* flush the last chunk */
 
-	if (decoder.chunk != NULL)
+	if (decoder.chunk != nullptr)
 		decoder_flush_chunk(&decoder);
 
 	dc->Lock();
@@ -406,7 +406,7 @@ decoder_run_song(struct decoder_control *dc,
 
 		const char *error_uri = song->uri;
 		char *allocated = uri_remove_auth(error_uri);
-		if (allocated != NULL)
+		if (allocated != nullptr)
 			error_uri = allocated;
 
 		dc->error.Format(decoder_domain,
@@ -423,7 +423,7 @@ decoder_run(struct decoder_control *dc)
 	dc->ClearError();
 
 	const Song *song = dc->song;
-	assert(song != NULL);
+	assert(song != nullptr);
 
 	const std::string uri = song->IsFile()
 		? std::string(map_song_fs(song).c_str())
@@ -456,11 +456,11 @@ decoder_task(void *arg)
 		case DecoderCommand::START:
 			dc->MixRampStart(nullptr);
 			dc->MixRampPrevEnd(dc->mixramp_end);
-			dc->mixramp_end = NULL; /* Don't free, it's copied above. */
+			dc->mixramp_end = nullptr; /* Don't free, it's copied above. */
 			dc->replay_gain_prev_db = dc->replay_gain_db;
 			dc->replay_gain_db = 0;
 
-                        /* fall through */
+			/* fall through */
 
 		case DecoderCommand::SEEK:
 			decoder_run(dc);
diff --git a/src/DespotifyUtils.cxx b/src/DespotifyUtils.cxx
index cf95998ad..769a4e8fb 100644
--- a/src/DespotifyUtils.cxx
+++ b/src/DespotifyUtils.cxx
@@ -75,7 +75,7 @@ void mpd_despotify_unregister_callback(void (*cb)(struct despotify_session *, in
 	for (i = 0; i < sizeof(registered_callbacks) / sizeof(registered_callbacks[0]); i++) {
 
 		if (registered_callbacks[i] == cb) {
-			registered_callbacks[i] = NULL;
+			registered_callbacks[i] = nullptr;
 		}
 	}
 }
@@ -118,11 +118,11 @@ struct despotify_session *mpd_despotify_get_session(void)
 	if (g_session)
 		return g_session;
 
-	user = config_get_string(CONF_DESPOTIFY_USER, NULL);
-	passwd = config_get_string(CONF_DESPOTIFY_PASSWORD, NULL);
+	user = config_get_string(CONF_DESPOTIFY_USER, nullptr);
+	passwd = config_get_string(CONF_DESPOTIFY_PASSWORD, nullptr);
 	high_bitrate = config_get_bool(CONF_DESPOTIFY_HIGH_BITRATE, true);
 
-	if (user == NULL || passwd == NULL) {
+	if (user == nullptr || passwd == nullptr) {
 		LogDebug(despotify_domain,
 			 "disabling despotify because account is not configured");
 		return nullptr;
@@ -133,7 +133,7 @@ struct despotify_session *mpd_despotify_get_session(void)
 		return nullptr;
 	}
 
-	g_session = despotify_init_client(callback, NULL,
+	g_session = despotify_init_client(callback, nullptr,
 					  high_bitrate, true);
 	if (!g_session) {
 		LogWarning(despotify_domain,
diff --git a/src/DespotifyUtils.hxx b/src/DespotifyUtils.hxx
index b0f8f37c4..e250d148c 100644
--- a/src/DespotifyUtils.hxx
+++ b/src/DespotifyUtils.hxx
@@ -32,7 +32,7 @@ extern const class Domain despotify_domain;
  * If the session isn't initialized, this function will initialize
  * it and connect to Spotify.
  *
- * @return a pointer to the despotify session, or NULL if it can't
+ * @return a pointer to the despotify session, or nullptr if it can't
  *         be initialized (e.g., if the configuration isn't supplied)
  */
 struct despotify_session *mpd_despotify_get_session(void);
diff --git a/src/Directory.cxx b/src/Directory.cxx
index 261d16385..4cd95a40c 100644
--- a/src/Directory.cxx
+++ b/src/Directory.cxx
@@ -39,7 +39,7 @@ extern "C" {
 inline Directory *
 Directory::Allocate(const char *path)
 {
-	assert(path != NULL);
+	assert(path != nullptr);
 
 	const size_t path_size = strlen(path) + 1;
 	Directory *directory =
@@ -81,8 +81,8 @@ Directory::~Directory()
 Directory *
 Directory::NewGeneric(const char *path, Directory *parent)
 {
-	assert(path != NULL);
-	assert((*path == 0) == (parent == NULL));
+	assert(path != nullptr);
+	assert((*path == 0) == (parent == nullptr));
 
 	Directory *directory = Allocate(path);
 
@@ -117,7 +117,7 @@ Directory::GetName() const
 	const char *slash = strrchr(path, '/');
 	assert((slash == nullptr) == parent->IsRoot());
 
-	return slash != NULL
+	return slash != nullptr
 		? slash + 1
 		: path;
 }
@@ -126,17 +126,17 @@ Directory *
 Directory::CreateChild(const char *name_utf8)
 {
 	assert(holding_db_lock());
-	assert(name_utf8 != NULL);
+	assert(name_utf8 != nullptr);
 	assert(*name_utf8 != 0);
 
 	char *allocated;
 	const char *path_utf8;
 	if (IsRoot()) {
-		allocated = NULL;
+		allocated = nullptr;
 		path_utf8 = name_utf8;
 	} else {
 		allocated = g_strconcat(GetPath(),
-					"/", name_utf8, NULL);
+					"/", name_utf8, nullptr);
 		path_utf8 = allocated;
 	}
 
@@ -157,7 +157,7 @@ Directory::FindChild(const char *name) const
 		if (strcmp(child->GetName(), name) == 0)
 			return child;
 
-	return NULL;
+	return nullptr;
 }
 
 void
@@ -178,7 +178,7 @@ Directory *
 Directory::LookupDirectory(const char *uri)
 {
 	assert(holding_db_lock());
-	assert(uri != NULL);
+	assert(uri != nullptr);
 
 	if (isRootDirectory(uri))
 		return this;
@@ -189,15 +189,15 @@ Directory::LookupDirectory(const char *uri)
 	while (1) {
 		char *slash = strchr(name, '/');
 		if (slash == name) {
-			d = NULL;
+			d = nullptr;
 			break;
 		}
 
-		if (slash != NULL)
+		if (slash != nullptr)
 			*slash = '\0';
 
 		d = d->FindChild(name);
-		if (d == NULL || slash == NULL)
+		if (d == nullptr || slash == nullptr)
 			break;
 
 		name = slash + 1;
@@ -212,7 +212,7 @@ void
 Directory::AddSong(Song *song)
 {
 	assert(holding_db_lock());
-	assert(song != NULL);
+	assert(song != nullptr);
 	assert(song->parent == this);
 
 	list_add_tail(&song->siblings, &songs);
@@ -222,7 +222,7 @@ void
 Directory::RemoveSong(Song *song)
 {
 	assert(holding_db_lock());
-	assert(song != NULL);
+	assert(song != nullptr);
 	assert(song->parent == this);
 
 	list_del(&song->siblings);
@@ -232,7 +232,7 @@ const Song *
 Directory::FindSong(const char *name_utf8) const
 {
 	assert(holding_db_lock());
-	assert(name_utf8 != NULL);
+	assert(name_utf8 != nullptr);
 
 	Song *song;
 	directory_for_each_song(song, this) {
@@ -242,7 +242,7 @@ Directory::FindSong(const char *name_utf8) const
 			return song;
 	}
 
-	return NULL;
+	return nullptr;
 }
 
 Song *
@@ -251,24 +251,24 @@ Directory::LookupSong(const char *uri)
 	char *duplicated, *base;
 
 	assert(holding_db_lock());
-	assert(uri != NULL);
+	assert(uri != nullptr);
 
 	duplicated = g_strdup(uri);
 	base = strrchr(duplicated, '/');
 
 	Directory *d = this;
-	if (base != NULL) {
+	if (base != nullptr) {
 		*base++ = 0;
 		d = d->LookupDirectory(duplicated);
 		if (d == nullptr) {
 			g_free(duplicated);
-			return NULL;
+			return nullptr;
 		}
 	} else
 		base = duplicated;
 
 	Song *song = d->FindSong(base);
-	assert(song == NULL || song->parent == d);
+	assert(song == nullptr || song->parent == d);
 
 	g_free(duplicated);
 	return song;
@@ -289,7 +289,7 @@ Directory::Sort()
 {
 	assert(holding_db_lock());
 
-	list_sort(NULL, &children, directory_cmp);
+	list_sort(nullptr, &children, directory_cmp);
 	song_list_sort(&songs);
 
 	Directory *child;
diff --git a/src/Directory.hxx b/src/Directory.hxx
index d7eec3c97..2c46227c4 100644
--- a/src/Directory.hxx
+++ b/src/Directory.hxx
@@ -164,7 +164,7 @@ public:
 	 * Looks up a directory by its relative URI.
 	 *
 	 * @param uri the relative URI
-	 * @return the Directory, or NULL if none was found
+	 * @return the Directory, or nullptr if none was found
 	 */
 	gcc_pure
 	Directory *LookupDirectory(const char *uri);
@@ -192,7 +192,7 @@ public:
 	 */
 	gcc_pure
 	bool IsRoot() const {
-		return parent == NULL;
+		return parent == nullptr;
 	}
 
 	/**
@@ -215,7 +215,7 @@ public:
 	 * Caller must lock the #db_mutex.
 	 *
 	 * @param uri the relative URI
-	 * @return the song, or NULL if none was found
+	 * @return the song, or nullptr if none was found
 	 */
 	gcc_pure
 	Song *LookupSong(const char *uri);
diff --git a/src/DirectorySave.cxx b/src/DirectorySave.cxx
index c39ac1edc..621346819 100644
--- a/src/DirectorySave.cxx
+++ b/src/DirectorySave.cxx
@@ -81,41 +81,41 @@ directory_load_subdir(TextFile &file, Directory *parent, const char *name,
 	if (parent->FindChild(name) != nullptr) {
 		error.Format(directory_domain,
 			     "Duplicate subdirectory '%s'", name);
-		return NULL;
+		return nullptr;
 	}
 
 	Directory *directory = parent->CreateChild(name);
 
 	const char *line = file.ReadLine();
-	if (line == NULL) {
+	if (line == nullptr) {
 		error.Set(directory_domain, "Unexpected end of file");
 		directory->Delete();
-		return NULL;
+		return nullptr;
 	}
 
 	if (g_str_has_prefix(line, DIRECTORY_MTIME)) {
 		directory->mtime =
 			g_ascii_strtoull(line + sizeof(DIRECTORY_MTIME) - 1,
-					 NULL, 10);
+					 nullptr, 10);
 
 		line = file.ReadLine();
-		if (line == NULL) {
+		if (line == nullptr) {
 			error.Set(directory_domain, "Unexpected end of file");
 			directory->Delete();
-			return NULL;
+			return nullptr;
 		}
 	}
 
 	if (!g_str_has_prefix(line, DIRECTORY_BEGIN)) {
 		error.Format(directory_domain, "Malformed line: %s", line);
 		directory->Delete();
-		return NULL;
+		return nullptr;
 	}
 
 	success = directory_load(file, directory, error);
 	if (!success) {
 		directory->Delete();
-		return NULL;
+		return nullptr;
 	}
 
 	return directory;
@@ -126,14 +126,14 @@ directory_load(TextFile &file, Directory *directory, Error &error)
 {
 	const char *line;
 
-	while ((line = file.ReadLine()) != NULL &&
+	while ((line = file.ReadLine()) != nullptr &&
 	       !g_str_has_prefix(line, DIRECTORY_END)) {
 		if (g_str_has_prefix(line, DIRECTORY_DIR)) {
 			Directory *subdir =
 				directory_load_subdir(file, directory,
 						      line + sizeof(DIRECTORY_DIR) - 1,
 						      error);
-			if (subdir == NULL)
+			if (subdir == nullptr)
 				return false;
 		} else if (g_str_has_prefix(line, SONG_BEGIN)) {
 			const char *name = line + sizeof(SONG_BEGIN) - 1;
@@ -146,7 +146,7 @@ directory_load(TextFile &file, Directory *directory, Error &error)
 			}
 
 			song = song_load(file, directory, name, error);
-			if (song == NULL)
+			if (song == nullptr)
 				return false;
 
 			directory->AddSong(song);
diff --git a/src/EncoderList.cxx b/src/EncoderList.cxx
index 2305548b9..7760a9582 100644
--- a/src/EncoderList.cxx
+++ b/src/EncoderList.cxx
@@ -50,7 +50,7 @@ const EncoderPlugin *const encoder_plugins[] = {
 #ifdef ENABLE_FLAC_ENCODER
 	&flac_encoder_plugin,
 #endif
-	NULL
+	nullptr
 };
 
 const EncoderPlugin *
@@ -60,5 +60,5 @@ encoder_plugin_get(const char *name)
 		if (strcmp(plugin->name, name) == 0)
 			return plugin;
 
-	return NULL;
+	return nullptr;
 }
diff --git a/src/EncoderList.hxx b/src/EncoderList.hxx
index feaf7a6d1..8cbb389a4 100644
--- a/src/EncoderList.hxx
+++ b/src/EncoderList.hxx
@@ -27,14 +27,14 @@ extern const EncoderPlugin *const encoder_plugins[];
 #define encoder_plugins_for_each(plugin) \
 	for (const EncoderPlugin *plugin, \
 		*const*encoder_plugin_iterator = &encoder_plugins[0]; \
-		(plugin = *encoder_plugin_iterator) != NULL; \
+		(plugin = *encoder_plugin_iterator) != nullptr; \
 		++encoder_plugin_iterator)
 
 /**
  * Looks up an encoder plugin by its name.
  *
  * @param name the encoder name to look for
- * @return the encoder plugin with the specified name, or NULL if none
+ * @return the encoder plugin with the specified name, or nullptr if none
  * was found
  */
 const EncoderPlugin *
diff --git a/src/EncoderPlugin.hxx b/src/EncoderPlugin.hxx
index 1bca66e0a..8ad5ea0c6 100644
--- a/src/EncoderPlugin.hxx
+++ b/src/EncoderPlugin.hxx
@@ -82,8 +82,8 @@ struct EncoderPlugin {
  *
  * @param plugin the encoder plugin
  * @param param optional configuration
- * @param error location to store the error occurring, or NULL to ignore errors.
- * @return an encoder object on success, NULL on failure
+ * @param error location to store the error occurring, or nullptr to ignore errors.
+ * @return an encoder object on success, nullptr on failure
  */
 static inline Encoder *
 encoder_init(const EncoderPlugin &plugin, const config_param &param,
@@ -117,7 +117,6 @@ encoder_finish(Encoder *encoder)
  * @param encoder the encoder
  * @param audio_format the encoder's input audio format; the plugin
  * may modify the struct to adapt it to its abilities
- * @param error location to store the error occurring, or NULL to ignore errors.
  * @return true on success
  */
 static inline bool
@@ -145,7 +144,7 @@ encoder_close(Encoder *encoder)
 {
 	assert(encoder->open);
 
-	if (encoder->plugin.close != NULL)
+	if (encoder->plugin.close != nullptr)
 		encoder->plugin.close(encoder);
 
 #ifndef NDEBUG
@@ -163,7 +162,6 @@ encoder_close(Encoder *encoder)
  * called.
  *
  * @param encoder the encoder
- * @param error location to store the error occuring, or NULL to ignore errors.
  * @return true on success
  */
 static inline bool
@@ -177,7 +175,7 @@ encoder_end(Encoder *encoder, Error &error)
 #endif
 
 	/* this method is optional */
-	return encoder->plugin.end != NULL
+	return encoder->plugin.end != nullptr
 		? encoder->plugin.end(encoder, error)
 		: true;
 }
@@ -187,7 +185,6 @@ encoder_end(Encoder *encoder, Error &error)
  * buffered available by encoder_read().
  *
  * @param encoder the encoder
- * @param error location to store the error occurring, or NULL to ignore errors.
  * @return true on success
  */
 static inline bool
@@ -199,7 +196,7 @@ encoder_flush(Encoder *encoder, Error &error)
 	assert(!encoder->end);
 
 	/* this method is optional */
-	return encoder->plugin.flush != NULL
+	return encoder->plugin.flush != nullptr
 		? encoder->plugin.flush(encoder, error)
 		: true;
 }
@@ -211,7 +208,6 @@ encoder_flush(Encoder *encoder, Error &error)
  *
  * @param encoder the encoder
  * @param tag the tag object
- * @param error location to store the error occuring, or NULL to ignore errors.
  * @return true on success
  */
 static inline bool
@@ -223,7 +219,7 @@ encoder_pre_tag(Encoder *encoder, Error &error)
 	assert(!encoder->end);
 
 	/* this method is optional */
-	bool success = encoder->plugin.pre_tag != NULL
+	bool success = encoder->plugin.pre_tag != nullptr
 		? encoder->plugin.pre_tag(encoder, error)
 		: true;
 
@@ -241,7 +237,6 @@ encoder_pre_tag(Encoder *encoder, Error &error)
  *
  * @param encoder the encoder
  * @param tag the tag object
- * @param error location to store the error occurring, or NULL to ignore errors.
  * @return true on success
  */
 static inline bool
@@ -257,7 +252,7 @@ encoder_tag(Encoder *encoder, const Tag *tag, Error &error)
 #endif
 
 	/* this method is optional */
-	return encoder->plugin.tag != NULL
+	return encoder->plugin.tag != nullptr
 		? encoder->plugin.tag(encoder, tag, error)
 		: true;
 }
@@ -268,7 +263,6 @@ encoder_tag(Encoder *encoder, const Tag *tag, Error &error)
  * @param encoder the encoder
  * @param data the buffer containing PCM samples
  * @param length the length of the buffer in bytes
- * @param error location to store the error occurring, or NULL to ignore errors.
  * @return true on success
  */
 static inline bool
@@ -313,15 +307,15 @@ encoder_read(Encoder *encoder, void *dest, size_t length)
  * Get mime type of encoded content.
  *
  * @param plugin the encoder plugin
- * @return an constant string, NULL on failure
+ * @return an constant string, nullptr on failure
  */
 static inline const char *
 encoder_get_mime_type(Encoder *encoder)
 {
 	/* this method is optional */
-	return encoder->plugin.get_mime_type != NULL
+	return encoder->plugin.get_mime_type != nullptr
 		? encoder->plugin.get_mime_type(encoder)
-		: NULL;
+		: nullptr;
 }
 
 #endif
diff --git a/src/ExcludeList.cxx b/src/ExcludeList.cxx
index c6b0d1469..fbe8f8198 100644
--- a/src/ExcludeList.cxx
+++ b/src/ExcludeList.cxx
@@ -40,7 +40,7 @@ bool
 ExcludeList::LoadFile(Path path_fs)
 {
 	FILE *file = FOpen(path_fs, FOpenMode::ReadText);
-	if (file == NULL) {
+	if (file == nullptr) {
 		const int e = errno;
 		if (e != ENOENT) {
 			const auto path_utf8 = path_fs.ToUTF8();
@@ -53,9 +53,9 @@ ExcludeList::LoadFile(Path path_fs)
 	}
 
 	char line[1024];
-	while (fgets(line, sizeof(line), file) != NULL) {
+	while (fgets(line, sizeof(line), file) != nullptr) {
 		char *p = strchr(line, '#');
-		if (p != NULL)
+		if (p != nullptr)
 			*p = 0;
 
 		p = g_strstrip(line);
diff --git a/src/FilterConfig.cxx b/src/FilterConfig.cxx
index a52cf44b7..cfac1c756 100644
--- a/src/FilterConfig.cxx
+++ b/src/FilterConfig.cxx
@@ -38,20 +38,20 @@
  *
  * @param filter_template_name the name of the filter template
  * @param error space to return an error description
- * @return the configuration block, or NULL if none was configured
+ * @return the configuration block, or nullptr if none was configured
  */
 static const struct config_param *
 filter_plugin_config(const char *filter_template_name, Error &error)
 {
-	const struct config_param *param = NULL;
+	const struct config_param *param = nullptr;
 
-	while ((param = config_get_next_param(CONF_AUDIO_FILTER, param)) != NULL) {
+	while ((param = config_get_next_param(CONF_AUDIO_FILTER, param)) != nullptr) {
 		const char *name = param->GetBlockValue("name");
-		if (name == NULL) {
+		if (name == nullptr) {
 			error.Format(config_domain,
 				     "filter configuration without 'name' name in line %d",
 				     param->line);
-			return NULL;
+			return nullptr;
 		}
 
 		if (strcmp(name, filter_template_name) == 0)
@@ -61,7 +61,7 @@ filter_plugin_config(const char *filter_template_name, Error &error)
 	error.Format(config_domain,
 		     "filter template not found: %s",
 		     filter_template_name);
-	return NULL;
+	return nullptr;
 }
 
 static bool
diff --git a/src/FilterPlugin.cxx b/src/FilterPlugin.cxx
index 9afda3f73..608542f92 100644
--- a/src/FilterPlugin.cxx
+++ b/src/FilterPlugin.cxx
@@ -31,7 +31,7 @@ Filter *
 filter_new(const struct filter_plugin *plugin,
 	   const config_param &param, Error &error)
 {
-	assert(plugin != NULL);
+	assert(plugin != nullptr);
 	assert(!error.IsDefined());
 
 	return plugin->init(param, error);
@@ -43,16 +43,16 @@ filter_configured_new(const config_param &param, Error &error)
 	assert(!error.IsDefined());
 
 	const char *plugin_name = param.GetBlockValue("plugin");
-	if (plugin_name == NULL) {
+	if (plugin_name == nullptr) {
 		error.Set(config_domain, "No filter plugin specified");
-		return NULL;
+		return nullptr;
 	}
 
 	const filter_plugin *plugin = filter_plugin_by_name(plugin_name);
-	if (plugin == NULL) {
+	if (plugin == nullptr) {
 		error.Format(config_domain,
 			     "No such filter plugin: %s", plugin_name);
-		return NULL;
+		return nullptr;
 	}
 
 	return filter_new(plugin, param, error);
diff --git a/src/FilterPlugin.hxx b/src/FilterPlugin.hxx
index 88c786120..5ff4637b3 100644
--- a/src/FilterPlugin.hxx
+++ b/src/FilterPlugin.hxx
@@ -44,9 +44,9 @@ struct filter_plugin {
  *
  * @param plugin the filter plugin
  * @param param optional configuration section
- * @param error location to store the error occurring, or NULL to
+ * @param error location to store the error occurring, or nullptr to
  * ignore errors.
- * @return a new filter object, or NULL on error
+ * @return a new filter object, or nullptr on error
  */
 Filter *
 filter_new(const struct filter_plugin *plugin,
@@ -57,9 +57,9 @@ filter_new(const struct filter_plugin *plugin,
  * the specified configuration section.
  *
  * @param param the configuration section
- * @param error location to store the error occurring, or NULL to
+ * @param error location to store the error occurring, or nullptr to
  * ignore errors.
- * @return a new filter object, or NULL on error
+ * @return a new filter object, or nullptr on error
  */
 Filter *
 filter_configured_new(const config_param &param, Error &error);
diff --git a/src/FilterRegistry.cxx b/src/FilterRegistry.cxx
index c8aff8298..b3b08505e 100644
--- a/src/FilterRegistry.cxx
+++ b/src/FilterRegistry.cxx
@@ -30,15 +30,15 @@ const struct filter_plugin *const filter_plugins[] = {
 	&normalize_filter_plugin,
 	&volume_filter_plugin,
 	&replay_gain_filter_plugin,
-	NULL,
+	nullptr,
 };
 
 const struct filter_plugin *
 filter_plugin_by_name(const char *name)
 {
-	for (unsigned i = 0; filter_plugins[i] != NULL; ++i)
+	for (unsigned i = 0; filter_plugins[i] != nullptr; ++i)
 		if (strcmp(filter_plugins[i]->name, name) == 0)
 			return filter_plugins[i];
 
-	return NULL;
+	return nullptr;
 }
diff --git a/src/GlobalEvents.cxx b/src/GlobalEvents.cxx
index 0a9354bec..86bfb3e2a 100644
--- a/src/GlobalEvents.cxx
+++ b/src/GlobalEvents.cxx
@@ -49,7 +49,7 @@ static void
 InvokeGlobalEvent(GlobalEvents::Event event)
 {
 	assert((unsigned)event < GlobalEvents::MAX);
-	assert(GlobalEvents::handlers[event] != NULL);
+	assert(GlobalEvents::handlers[event] != nullptr);
 
 	GlobalEvents::handlers[event]();
 }
@@ -81,7 +81,7 @@ void
 GlobalEvents::Register(Event event, Handler callback)
 {
 	assert((unsigned)event < MAX);
-	assert(handlers[event] == NULL);
+	assert(handlers[event] == nullptr);
 
 	handlers[event] = callback;
 }
diff --git a/src/IOThread.cxx b/src/IOThread.cxx
index d8805ba7b..a14f12eb1 100644
--- a/src/IOThread.cxx
+++ b/src/IOThread.cxx
@@ -40,7 +40,7 @@ void
 io_thread_run(void)
 {
 	assert(io_thread_inside());
-	assert(io.loop != NULL);
+	assert(io.loop != nullptr);
 
 	io.loop->Run();
 }
@@ -59,7 +59,7 @@ io_thread_func(gcc_unused void *arg)
 void
 io_thread_init(void)
 {
-	assert(io.loop == NULL);
+	assert(io.loop == nullptr);
 	assert(!io.thread.IsDefined());
 
 	io.loop = new EventLoop();
@@ -68,7 +68,7 @@ io_thread_init(void)
 void
 io_thread_start()
 {
-	assert(io.loop != NULL);
+	assert(io.loop != nullptr);
 	assert(!io.thread.IsDefined());
 
 	const ScopeLock protect(io.mutex);
@@ -81,7 +81,7 @@ io_thread_start()
 void
 io_thread_quit(void)
 {
-	assert(io.loop != NULL);
+	assert(io.loop != nullptr);
 
 	io.loop->Break();
 }
diff --git a/src/IcyMetaDataServer.cxx b/src/IcyMetaDataServer.cxx
index 255f5b53f..67b20852c 100644
--- a/src/IcyMetaDataServer.cxx
+++ b/src/IcyMetaDataServer.cxx
@@ -77,7 +77,7 @@ icy_server_metadata_string(const char *stream_title, const char* stream_url)
 
 	if (meta_length > 255) {
 		delete[] icy_metadata;
-		return NULL;
+		return nullptr;
 	}
 
 	return icy_metadata;
@@ -124,8 +124,8 @@ icy_server_metadata_page(const Tag &tag, const enum tag_type *types)
 
 	icy_string = icy_server_metadata_string(stream_title, "");
 
-	if (icy_string == NULL)
-		return NULL;
+	if (icy_string == nullptr)
+		return nullptr;
 
 	Page *icy_metadata = Page::Copy(icy_string, (icy_string[0] * 16) + 1);
 
diff --git a/src/InotifySource.cxx b/src/InotifySource.cxx
index b6d43f657..8dc6b5c16 100644
--- a/src/InotifySource.cxx
+++ b/src/InotifySource.cxx
@@ -57,7 +57,7 @@ InotifySource::OnSocketReady(gcc_unused unsigned flags)
 		if (event->len > 0 && event->name[event->len - 1] == 0)
 			name = event->name;
 		else
-			name = NULL;
+			name = nullptr;
 
 		callback(event->wd, event->mask, name, callback_ctx);
 		buffer.Consume(sizeof(*event) + event->len);
@@ -85,7 +85,7 @@ InotifySource::Create(EventLoop &loop,
 	int fd = inotify_init_cloexec();
 	if (fd < 0) {
 		error.SetErrno("inotify_init() has failed");
-		return NULL;
+		return nullptr;
 	}
 
 	return new InotifySource(loop, callback, callback_ctx, fd);
diff --git a/src/InotifyUpdate.cxx b/src/InotifyUpdate.cxx
index 4a93f557b..f02843ad4 100644
--- a/src/InotifyUpdate.cxx
+++ b/src/InotifyUpdate.cxx
@@ -112,9 +112,9 @@ disable_watch_directory(WatchDirectory &directory)
 static void
 remove_watch_directory(WatchDirectory *directory)
 {
-	assert(directory != NULL);
+	assert(directory != nullptr);
 
-	if (directory->parent == NULL) {
+	if (directory->parent == nullptr) {
 		LogWarning(inotify_domain,
 			   "music directory was removed - "
 			   "cannot continue to watch it");
@@ -132,7 +132,7 @@ remove_watch_directory(WatchDirectory *directory)
 static AllocatedPath
 watch_directory_get_uri_fs(const WatchDirectory *directory)
 {
-	if (directory->parent == NULL)
+	if (directory->parent == nullptr)
 		return AllocatedPath::Null();
 
 	const auto uri = watch_directory_get_uri_fs(directory->parent);
@@ -147,7 +147,7 @@ static bool skip_path(const char *path)
 {
 	return (path[0] == '.' && path[1] == 0) ||
 		(path[0] == '.' && path[1] == '.' && path[2] == 0) ||
-		strchr(path, '\n') != NULL;
+		strchr(path, '\n') != nullptr;
 }
 
 static void
@@ -158,7 +158,7 @@ recursive_watch_subdirectories(WatchDirectory *directory,
 	DIR *dir;
 	struct dirent *ent;
 
-	assert(directory != NULL);
+	assert(directory != nullptr);
 	assert(depth <= inotify_max_depth);
 	assert(!path_fs.IsNull());
 
@@ -168,7 +168,7 @@ recursive_watch_subdirectories(WatchDirectory *directory,
 		return;
 
 	dir = opendir(path_fs.c_str());
-	if (dir == NULL) {
+	if (dir == nullptr) {
 		FormatErrno(inotify_domain,
 			    "Failed to open directory %s", path_fs.c_str());
 		return;
@@ -226,10 +226,10 @@ gcc_pure
 static unsigned
 watch_directory_depth(const WatchDirectory *d)
 {
-	assert(d != NULL);
+	assert(d != nullptr);
 
 	unsigned depth = 0;
-	while ((d = d->parent) != NULL)
+	while ((d = d->parent) != nullptr)
 		++depth;
 
 	return depth;
@@ -244,7 +244,7 @@ mpd_inotify_callback(int wd, unsigned mask,
 	/*FormatDebug(inotify_domain, "wd=%d mask=0x%x name='%s'", wd, mask, name);*/
 
 	directory = tree_find_watch_directory(wd);
-	if (directory == NULL)
+	if (directory == nullptr)
 		return;
 
 	const auto uri_fs = watch_directory_get_uri_fs(directory);
@@ -301,7 +301,7 @@ mpd_inotify_init(unsigned max_depth)
 	inotify_source = InotifySource::Create(*main_loop,
 					       mpd_inotify_callback, nullptr,
 					       error);
-	if (inotify_source == NULL) {
+	if (inotify_source == nullptr) {
 		LogError(error);
 		return;
 	}
@@ -312,7 +312,7 @@ mpd_inotify_init(unsigned max_depth)
 	if (descriptor < 0) {
 		LogError(error);
 		delete inotify_source;
-		inotify_source = NULL;
+		inotify_source = nullptr;
 		return;
 	}
 
@@ -330,7 +330,7 @@ mpd_inotify_init(unsigned max_depth)
 void
 mpd_inotify_finish(void)
 {
-	if (inotify_source == NULL)
+	if (inotify_source == nullptr)
 		return;
 
 	delete inotify_queue;
diff --git a/src/InputInit.cxx b/src/InputInit.cxx
index b488e48e3..3af1e1686 100644
--- a/src/InputInit.cxx
+++ b/src/InputInit.cxx
@@ -36,27 +36,27 @@ extern constexpr Domain input_domain("input");
  * Find the "input" configuration block for the specified plugin.
  *
  * @param plugin_name the name of the input plugin
- * @return the configuration block, or NULL if none was configured
+ * @return the configuration block, or nullptr if none was configured
  */
 static const struct config_param *
 input_plugin_config(const char *plugin_name, Error &error)
 {
-	const struct config_param *param = NULL;
+	const struct config_param *param = nullptr;
 
-	while ((param = config_get_next_param(CONF_INPUT, param)) != NULL) {
+	while ((param = config_get_next_param(CONF_INPUT, param)) != nullptr) {
 		const char *name = param->GetBlockValue("plugin");
-		if (name == NULL) {
+		if (name == nullptr) {
 			error.Format(input_domain,
 				     "input configuration without 'plugin' name in line %d",
 				     param->line);
-			return NULL;
+			return nullptr;
 		}
 
 		if (strcmp(name, plugin_name) == 0)
 			return param;
 	}
 
-	return NULL;
+	return nullptr;
 }
 
 bool
@@ -64,12 +64,12 @@ input_stream_global_init(Error &error)
 {
 	const config_param empty;
 
-	for (unsigned i = 0; input_plugins[i] != NULL; ++i) {
+	for (unsigned i = 0; input_plugins[i] != nullptr; ++i) {
 		const InputPlugin *plugin = input_plugins[i];
 
-		assert(plugin->name != NULL);
+		assert(plugin->name != nullptr);
 		assert(*plugin->name != 0);
-		assert(plugin->open != NULL);
+		assert(plugin->open != nullptr);
 
 		const struct config_param *param =
 			input_plugin_config(plugin->name, error);
@@ -82,7 +82,7 @@ input_stream_global_init(Error &error)
 			/* the plugin is disabled in mpd.conf */
 			continue;
 
-		if (plugin->init == NULL || plugin->init(*param, error))
+		if (plugin->init == nullptr || plugin->init(*param, error))
 			input_plugins_enabled[i] = true;
 		else {
 			error.FormatPrefix("Failed to initialize input plugin '%s': ",
@@ -97,6 +97,6 @@ input_stream_global_init(Error &error)
 void input_stream_global_finish(void)
 {
 	input_plugins_for_each_enabled(plugin)
-		if (plugin->finish != NULL)
+		if (plugin->finish != nullptr)
 			plugin->finish();
 }
diff --git a/src/InputInit.hxx b/src/InputInit.hxx
index 9aa2de41a..6afea1351 100644
--- a/src/InputInit.hxx
+++ b/src/InputInit.hxx
@@ -24,9 +24,6 @@ class Error;
 
 /**
  * Initializes this library and all input_stream implementations.
- *
- * @param error_r location to store the error occurring, or NULL to
- * ignore errors
  */
 bool
 input_stream_global_init(Error &error);
diff --git a/src/InputPlugin.hxx b/src/InputPlugin.hxx
index 134207584..1a867b118 100644
--- a/src/InputPlugin.hxx
+++ b/src/InputPlugin.hxx
@@ -39,8 +39,6 @@ struct InputPlugin {
 	/**
 	 * Global initialization.  This method is called when MPD starts.
 	 *
-	 * @param error_r location to store the error occurring, or
-	 * NULL to ignore errors
 	 * @return true on success, false if the plugin should be
 	 * disabled
 	 */
@@ -67,7 +65,7 @@ struct InputPlugin {
 
 	/**
 	 * Update the public attributes.  Call before access.  Can be
-	 * NULL if the plugin always keeps its attributes up to date.
+	 * nullptr if the plugin always keeps its attributes up to date.
 	 */
 	void (*update)(struct input_stream *is);
 
diff --git a/src/InputStream.cxx b/src/InputStream.cxx
index 23e535d15..52eef2caf 100644
--- a/src/InputStream.cxx
+++ b/src/InputStream.cxx
@@ -39,21 +39,21 @@ input_stream::Open(const char *url,
 		struct input_stream *is;
 
 		is = plugin->open(url, mutex, cond, error);
-		if (is != NULL) {
-			assert(is->plugin.close != NULL);
-			assert(is->plugin.read != NULL);
-			assert(is->plugin.eof != NULL);
-			assert(!is->seekable || is->plugin.seek != NULL);
+		if (is != nullptr) {
+			assert(is->plugin.close != nullptr);
+			assert(is->plugin.read != nullptr);
+			assert(is->plugin.eof != nullptr);
+			assert(!is->seekable || is->plugin.seek != nullptr);
 
 			is = input_rewind_open(is);
 
 			return is;
 		} else if (error.IsDefined())
-			return NULL;
+			return nullptr;
 	}
 
 	error.Set(input_domain, "Unrecognized URI");
-	return NULL;
+	return nullptr;
 }
 
 bool
@@ -142,7 +142,7 @@ input_stream::IsAvailable()
 size_t
 input_stream::Read(void *ptr, size_t _size, Error &error)
 {
-	assert(ptr != NULL);
+	assert(ptr != nullptr);
 	assert(_size > 0);
 
 	return plugin.read(this, ptr, _size, error);
@@ -151,7 +151,7 @@ input_stream::Read(void *ptr, size_t _size, Error &error)
 size_t
 input_stream::LockRead(void *ptr, size_t _size, Error &error)
 {
-	assert(ptr != NULL);
+	assert(ptr != nullptr);
 	assert(_size > 0);
 
 	const ScopeLock protect(mutex);
diff --git a/src/InputStream.hxx b/src/InputStream.hxx
index 2a3d7b2cd..ac774f723 100644
--- a/src/InputStream.hxx
+++ b/src/InputStream.hxx
@@ -60,7 +60,7 @@ struct input_stream {
 	/**
 	 * A cond that gets signalled when the state of this object
 	 * changes from the I/O thread.  The client of this object may
-	 * wait on it.  Optional, may be NULL.
+	 * wait on it.  Optional, may be nullptr.
 	 *
 	 * This object is allocated by the client, and the client is
 	 * responsible for freeing it.
@@ -99,7 +99,7 @@ struct input_stream {
 		 mutex(_mutex), cond(_cond),
 		 ready(false), seekable(false),
 		 size(-1), offset(0) {
-		assert(_uri != NULL);
+		assert(_uri != nullptr);
 	}
 
 	/**
@@ -109,9 +109,9 @@ struct input_stream {
 	 * @param mutex a mutex that is used to protect this object; must be
 	 * locked before calling any of the public methods
 	 * @param cond a cond that gets signalled when the state of
-	 * this object changes; may be NULL if the caller doesn't want to get
+	 * this object changes; may be nullptr if the caller doesn't want to get
 	 * notifications
-	 * @return an #input_stream object on success, NULL on error
+	 * @return an #input_stream object on success, nullptr on error
 	 */
 	gcc_nonnull_all
 	gcc_malloc
diff --git a/src/Listen.cxx b/src/Listen.cxx
index a953c80b4..d5c132545 100644
--- a/src/Listen.cxx
+++ b/src/Listen.cxx
@@ -62,7 +62,7 @@ listen_add_config_param(unsigned int port,
 			const struct config_param *param,
 			Error &error_r)
 {
-	assert(param != NULL);
+	assert(param != nullptr);
 
 	if (0 == strcmp(param->value.c_str(), "any")) {
 		return listen_socket->AddPort(port, error_r);
@@ -107,7 +107,7 @@ listen_global_init(Error &error)
 
 	int port = config_get_positive(CONF_PORT, DEFAULT_PORT);
 	const struct config_param *param =
-		config_get_next_param(CONF_BIND_TO_ADDRESS, NULL);
+		config_get_next_param(CONF_BIND_TO_ADDRESS, nullptr);
 	bool success;
 
 	listen_socket = new ClientListener();
@@ -118,7 +118,7 @@ listen_global_init(Error &error)
 	if (error.IsDefined())
 		return false;
 
-	if (param != NULL) {
+	if (param != nullptr) {
 		/* "bind_to_address" is configured, create listeners
 		   for all values */
 
@@ -133,7 +133,7 @@ listen_global_init(Error &error)
 
 			param = config_get_next_param(CONF_BIND_TO_ADDRESS,
 						      param);
-		} while (param != NULL);
+		} while (param != nullptr);
 	} else {
 		/* no "bind_to_address" configured, bind the
 		   configured port on all interfaces */
@@ -159,7 +159,7 @@ void listen_global_finish(void)
 {
 	LogDebug(listen_domain, "listen_global_finish called");
 
-	assert(listen_socket != NULL);
+	assert(listen_socket != nullptr);
 
 	delete listen_socket;
 }
diff --git a/src/LogInit.cxx b/src/LogInit.cxx
index 1b393fc3f..41d13a5e8 100644
--- a/src/LogInit.cxx
+++ b/src/LogInit.cxx
@@ -76,7 +76,7 @@ static void redirect_logs(int fd)
 static const char *log_date(void)
 {
 	static char buf[LOG_DATE_BUF_SIZE];
-	time_t t = time(NULL);
+	time_t t = time(nullptr);
 	strftime(buf, LOG_DATE_BUF_SIZE, "%b %d %H:%M : ", localtime(&t));
 	return buf;
 }
@@ -106,14 +106,15 @@ file_log_func(const gchar *domain,
 	if (log_level > log_threshold)
 		return;
 
-	if (log_charset != NULL) {
+	if (log_charset != nullptr) {
 		converted = g_convert_with_fallback(message, -1,
 						    log_charset, "utf-8",
-						    NULL, NULL, NULL, NULL);
-		if (converted != NULL)
+						    nullptr, nullptr,
+						    nullptr, nullptr);
+		if (converted != nullptr)
 			message = converted;
 	} else
-		converted = NULL;
+		converted = nullptr;
 
 	if (domain == nullptr)
 		domain = "";
@@ -129,7 +130,7 @@ file_log_func(const gchar *domain,
 static void
 log_init_stdout(void)
 {
-	g_log_set_default_handler(file_log_func, NULL);
+	g_log_set_default_handler(file_log_func, nullptr);
 }
 
 static int
@@ -153,7 +154,7 @@ log_init_file(unsigned line, Error &error)
 		return false;
 	}
 
-	g_log_set_default_handler(file_log_func, NULL);
+	g_log_set_default_handler(file_log_func, nullptr);
 	return true;
 }
 
@@ -214,7 +215,7 @@ log_init_syslog(void)
 	assert(out_path.IsNull());
 
 	openlog(PACKAGE, 0, LOG_DAEMON);
-	g_log_set_default_handler(syslog_log_func, NULL);
+	g_log_set_default_handler(syslog_log_func, nullptr);
 }
 
 #endif
@@ -253,7 +254,7 @@ log_init(bool verbose, bool use_stdout, Error &error)
 
 	if (verbose)
 		log_threshold = G_LOG_LEVEL_DEBUG;
-	else if ((param = config_get_param(CONF_LOG_LEVEL)) != NULL)
+	else if ((param = config_get_param(CONF_LOG_LEVEL)) != nullptr)
 		log_threshold = parse_log_level(param->value.c_str(),
 						param->line);
 
@@ -262,7 +263,7 @@ log_init(bool verbose, bool use_stdout, Error &error)
 		return true;
 	} else {
 		param = config_get_param(CONF_LOG_FILE);
-		if (param == NULL) {
+		if (param == nullptr) {
 #ifdef HAVE_SYSLOG
 			/* no configuration: default to syslog (if
 			   available) */
@@ -308,7 +309,7 @@ log_deinit(void)
 
 void setup_log_output(bool use_stdout)
 {
-	fflush(NULL);
+	fflush(nullptr);
 	if (!use_stdout) {
 #ifndef WIN32
 		if (out_path.IsNull())
@@ -321,7 +322,7 @@ void setup_log_output(bool use_stdout)
 		}
 
 		stdout_mode = false;
-		log_charset = NULL;
+		log_charset = nullptr;
 	}
 }
 
diff --git a/src/MixerAll.cxx b/src/MixerAll.cxx
index e9994e901..37225fd25 100644
--- a/src/MixerAll.cxx
+++ b/src/MixerAll.cxx
@@ -46,7 +46,7 @@ output_mixer_get_volume(unsigned i)
 		return -1;
 
 	Mixer *mixer = output->mixer;
-	if (mixer == NULL)
+	if (mixer == nullptr)
 		return -1;
 
 	Error error;
@@ -93,7 +93,7 @@ output_mixer_set_volume(unsigned i, unsigned volume)
 		return false;
 
 	Mixer *mixer = output->mixer;
-	if (mixer == NULL)
+	if (mixer == nullptr)
 		return false;
 
 	Error error;
@@ -133,7 +133,7 @@ output_mixer_get_software_volume(unsigned i)
 		return -1;
 
 	Mixer *mixer = output->mixer;
-	if (mixer == NULL || !mixer->IsPlugin(software_mixer_plugin))
+	if (mixer == nullptr || !mixer->IsPlugin(software_mixer_plugin))
 		return -1;
 
 	return mixer_get_volume(mixer, IgnoreError());
@@ -168,7 +168,7 @@ mixer_all_set_software_volume(unsigned volume)
 
 	for (unsigned i = 0; i < count; i++) {
 		struct audio_output *output = audio_output_get(i);
-		if (output->mixer != NULL &&
+		if (output->mixer != nullptr &&
 		    output->mixer->plugin == &software_mixer_plugin)
 			mixer_set_volume(output->mixer, volume, IgnoreError());
 	}
diff --git a/src/MixerControl.cxx b/src/MixerControl.cxx
index 2759f945a..dd4f03543 100644
--- a/src/MixerControl.cxx
+++ b/src/MixerControl.cxx
@@ -32,11 +32,11 @@ mixer_new(const struct mixer_plugin *plugin, void *ao,
 {
 	Mixer *mixer;
 
-	assert(plugin != NULL);
+	assert(plugin != nullptr);
 
 	mixer = plugin->init(ao, param, error);
 
-	assert(mixer == NULL || mixer->IsPlugin(*plugin));
+	assert(mixer == nullptr || mixer->IsPlugin(*plugin));
 
 	return mixer;
 }
@@ -44,8 +44,8 @@ mixer_new(const struct mixer_plugin *plugin, void *ao,
 void
 mixer_free(Mixer *mixer)
 {
-	assert(mixer != NULL);
-	assert(mixer->plugin != NULL);
+	assert(mixer != nullptr);
+	assert(mixer->plugin != nullptr);
 
 	/* mixers with the "global" flag set might still be open at
 	   this point (see mixer_auto_close()) */
@@ -59,14 +59,14 @@ mixer_open(Mixer *mixer, Error &error)
 {
 	bool success;
 
-	assert(mixer != NULL);
-	assert(mixer->plugin != NULL);
+	assert(mixer != nullptr);
+	assert(mixer->plugin != nullptr);
 
 	const ScopeLock protect(mixer->mutex);
 
 	if (mixer->open)
 		success = true;
-	else if (mixer->plugin->open == NULL)
+	else if (mixer->plugin->open == nullptr)
 		success = mixer->open = true;
 	else
 		success = mixer->open = mixer->plugin->open(mixer, error);
@@ -79,11 +79,11 @@ mixer_open(Mixer *mixer, Error &error)
 static void
 mixer_close_internal(Mixer *mixer)
 {
-	assert(mixer != NULL);
-	assert(mixer->plugin != NULL);
+	assert(mixer != nullptr);
+	assert(mixer->plugin != nullptr);
 	assert(mixer->open);
 
-	if (mixer->plugin->close != NULL)
+	if (mixer->plugin->close != nullptr)
 		mixer->plugin->close(mixer);
 
 	mixer->open = false;
@@ -92,8 +92,8 @@ mixer_close_internal(Mixer *mixer)
 void
 mixer_close(Mixer *mixer)
 {
-	assert(mixer != NULL);
-	assert(mixer->plugin != NULL);
+	assert(mixer != nullptr);
+	assert(mixer->plugin != nullptr);
 
 	const ScopeLock protect(mixer->mutex);
 
@@ -127,7 +127,7 @@ mixer_get_volume(Mixer *mixer, Error &error)
 {
 	int volume;
 
-	assert(mixer != NULL);
+	assert(mixer != nullptr);
 
 	if (mixer->plugin->global && !mixer->failed &&
 	    !mixer_open(mixer, error))
@@ -148,7 +148,7 @@ mixer_get_volume(Mixer *mixer, Error &error)
 bool
 mixer_set_volume(Mixer *mixer, unsigned volume, Error &error)
 {
-	assert(mixer != NULL);
+	assert(mixer != nullptr);
 	assert(volume <= 100);
 
 	if (mixer->plugin->global && !mixer->failed &&
diff --git a/src/MixerPlugin.hxx b/src/MixerPlugin.hxx
index 4dd8969b9..db6fb2471 100644
--- a/src/MixerPlugin.hxx
+++ b/src/MixerPlugin.hxx
@@ -38,8 +38,8 @@ struct mixer_plugin {
 	 * @param ao the pointer returned by audio_output_plugin.init
 	 * @param param the configuration section
 	 * @param error_r location to store the error occurring, or
-	 * NULL to ignore errors
-	 * @return a mixer object, or NULL on error
+	 * nullptr to ignore errors
+	 * @return a mixer object, or nullptr on error
 	 */
 	Mixer *(*init)(void *ao, const config_param &param,
 		       Error &error);
@@ -53,7 +53,7 @@ struct mixer_plugin {
 	 * Open mixer device
 	 *
 	 * @param error_r location to store the error occurring, or
-	 * NULL to ignore errors
+	 * nullptr to ignore errors
 	 * @return true on success, false on error
 	 */
 	bool (*open)(Mixer *data, Error &error);
@@ -67,7 +67,7 @@ struct mixer_plugin {
 	 * Reads the current volume.
 	 *
 	 * @param error_r location to store the error occurring, or
-	 * NULL to ignore errors
+	 * nullptr to ignore errors
 	 * @return the current volume (0..100 including) or -1 if
 	 * unavailable or on error (error set, mixer will be closed)
 	 */
@@ -77,7 +77,7 @@ struct mixer_plugin {
 	 * Sets the volume.
 	 *
 	 * @param error_r location to store the error occurring, or
-	 * NULL to ignore errors
+	 * nullptr to ignore errors
 	 * @param volume the new volume (0..100 including)
 	 * @return true on success, false on error
 	 */
diff --git a/src/MusicChunk.cxx b/src/MusicChunk.cxx
index 9ffe4f509..1d6081a9e 100644
--- a/src/MusicChunk.cxx
+++ b/src/MusicChunk.cxx
@@ -58,7 +58,7 @@ music_chunk::Write(const AudioFormat af,
 	const size_t frame_size = af.GetFrameSize();
 	size_t num_frames = (sizeof(data) - length) / frame_size;
 	if (num_frames == 0)
-		return NULL;
+		return nullptr;
 
 #ifndef NDEBUG
 	audio_format = af;
diff --git a/src/MusicChunk.hxx b/src/MusicChunk.hxx
index 3365b0bea..a9b4c3cfd 100644
--- a/src/MusicChunk.hxx
+++ b/src/MusicChunk.hxx
@@ -124,7 +124,7 @@ struct music_chunk {
 	 * @param bit_rate the current bit rate of the source file
 	 * @param max_length_r the maximum write length is returned
 	 * here
-	 * @return a writable buffer, or NULL if the chunk is full
+	 * @return a writable buffer, or nullptr if the chunk is full
 	 */
 	void *Write(AudioFormat af,
 		    float data_time, uint16_t bit_rate,
diff --git a/src/OutputAll.cxx b/src/OutputAll.cxx
index b8cf0ca66..6f935ed44 100644
--- a/src/OutputAll.cxx
+++ b/src/OutputAll.cxx
@@ -69,7 +69,7 @@ audio_output_get(unsigned i)
 {
 	assert(i < num_audio_outputs);
 
-	assert(audio_outputs[i] != NULL);
+	assert(audio_outputs[i] != nullptr);
 
 	return audio_outputs[i];
 }
@@ -85,7 +85,7 @@ audio_output_find(const char *name)
 	}
 
 	/* name not found */
-	return NULL;
+	return nullptr;
 }
 
 gcc_const
@@ -93,7 +93,7 @@ static unsigned
 audio_output_config_count(void)
 {
 	unsigned int nr = 0;
-	const struct config_param *param = NULL;
+	const struct config_param *param = nullptr;
 
 	while ((param = config_get_next_param(CONF_AUDIO_OUTPUT, param)))
 		nr++;
@@ -105,7 +105,7 @@ audio_output_config_count(void)
 void
 audio_output_all_init(struct player_control *pc)
 {
-	const struct config_param *param = NULL;
+	const struct config_param *param = nullptr;
 	unsigned int i;
 	Error error;
 
@@ -129,8 +129,8 @@ audio_output_all_init(struct player_control *pc)
 		}
 
 		audio_output *output = audio_output_new(*param, pc, error);
-		if (output == NULL) {
-			if (param != NULL)
+		if (output == nullptr) {
+			if (param != nullptr)
 				FormatFatalError("line %i: %s",
 						 param->line,
 						 error.GetMessage());
@@ -161,7 +161,7 @@ audio_output_all_finish(void)
 	}
 
 	g_free(audio_outputs);
-	audio_outputs = NULL;
+	audio_outputs = nullptr;
 	num_audio_outputs = 0;
 }
 
@@ -225,9 +225,9 @@ audio_output_reset_reopen(struct audio_output *ao)
 {
 	const ScopeLock protect(ao->mutex);
 
-	if (!ao->open && ao->fail_timer != NULL) {
+	if (!ao->open && ao->fail_timer != nullptr) {
 		g_timer_destroy(ao->fail_timer);
-		ao->fail_timer = NULL;
+		ao->fail_timer = nullptr;
 	}
 }
 
@@ -280,9 +280,9 @@ audio_output_all_play(struct music_chunk *chunk, Error &error)
 	bool ret;
 	unsigned int i;
 
-	assert(g_music_buffer != NULL);
-	assert(g_mp != NULL);
-	assert(chunk != NULL);
+	assert(g_music_buffer != nullptr);
+	assert(g_mp != nullptr);
+	assert(chunk != nullptr);
 	assert(chunk->CheckFormat(input_audio_format));
 
 	ret = audio_output_all_update();
@@ -308,16 +308,16 @@ audio_output_all_open(const AudioFormat audio_format,
 	bool ret = false, enabled = false;
 	unsigned int i;
 
-	assert(g_music_buffer == NULL || g_music_buffer == &buffer);
-	assert((g_mp == NULL) == (g_music_buffer == NULL));
+	assert(g_music_buffer == nullptr || g_music_buffer == &buffer);
+	assert((g_mp == nullptr) == (g_music_buffer == nullptr));
 
 	g_music_buffer = &buffer;
 
 	/* the audio format must be the same as existing chunks in the
 	   pipe */
-	assert(g_mp == NULL || g_mp->CheckFormat(audio_format));
+	assert(g_mp == nullptr || g_mp->CheckFormat(audio_format));
 
-	if (g_mp == NULL)
+	if (g_mp == nullptr)
 		g_mp = new MusicPipe();
 	else
 		/* if the pipe hasn't been cleared, the the audio
@@ -361,17 +361,17 @@ chunk_is_consumed_in(const struct audio_output *ao,
 	if (!ao->open)
 		return true;
 
-	if (ao->chunk == NULL)
+	if (ao->chunk == nullptr)
 		return false;
 
 	assert(chunk == ao->chunk || g_mp->Contains(ao->chunk));
 
 	if (chunk != ao->chunk) {
-		assert(chunk->next != NULL);
+		assert(chunk->next != nullptr);
 		return true;
 	}
 
-	return ao->chunk_finished && chunk->next == NULL;
+	return ao->chunk_finished && chunk->next == nullptr;
 }
 
 /**
@@ -398,7 +398,7 @@ chunk_is_consumed(const struct music_chunk *chunk)
 static void
 clear_tail_chunk(gcc_unused const struct music_chunk *chunk, bool *locked)
 {
-	assert(chunk->next == NULL);
+	assert(chunk->next == nullptr);
 	assert(g_mp->Contains(chunk));
 
 	for (unsigned i = 0; i < num_audio_outputs; ++i) {
@@ -416,7 +416,7 @@ clear_tail_chunk(gcc_unused const struct music_chunk *chunk, bool *locked)
 
 		assert(ao->chunk == chunk);
 		assert(ao->chunk_finished);
-		ao->chunk = NULL;
+		ao->chunk = nullptr;
 	}
 }
 
@@ -428,8 +428,8 @@ audio_output_all_check(void)
 	struct music_chunk *shifted;
 	bool locked[num_audio_outputs];
 
-	assert(g_music_buffer != NULL);
-	assert(g_mp != NULL);
+	assert(g_music_buffer != nullptr);
+	assert(g_mp != nullptr);
 
 	while ((chunk = g_mp->Peek()) != nullptr) {
 		assert(!g_mp->IsEmpty());
@@ -444,7 +444,7 @@ audio_output_all_check(void)
 			   provides a defined value */
 			audio_output_all_elapsed_time = chunk->times;
 
-		is_tail = chunk->next == NULL;
+		is_tail = chunk->next == nullptr;
 		if (is_tail)
 			/* this is the tail of the pipe - clear the
 			   chunk reference in all outputs */
@@ -520,7 +520,7 @@ audio_output_all_cancel(void)
 
 	/* clear the music pipe and return all chunks to the buffer */
 
-	if (g_mp != NULL)
+	if (g_mp != nullptr)
 		g_mp->Clear(*g_music_buffer);
 
 	/* the audio outputs are now waiting for a signal, to
@@ -541,15 +541,15 @@ audio_output_all_close(void)
 	for (i = 0; i < num_audio_outputs; ++i)
 		audio_output_close(audio_outputs[i]);
 
-	if (g_mp != NULL) {
-		assert(g_music_buffer != NULL);
+	if (g_mp != nullptr) {
+		assert(g_music_buffer != nullptr);
 
 		g_mp->Clear(*g_music_buffer);
 		delete g_mp;
-		g_mp = NULL;
+		g_mp = nullptr;
 	}
 
-	g_music_buffer = NULL;
+	g_music_buffer = nullptr;
 
 	input_audio_format.Clear();
 
@@ -564,15 +564,15 @@ audio_output_all_release(void)
 	for (i = 0; i < num_audio_outputs; ++i)
 		audio_output_release(audio_outputs[i]);
 
-	if (g_mp != NULL) {
-		assert(g_music_buffer != NULL);
+	if (g_mp != nullptr) {
+		assert(g_music_buffer != nullptr);
 
 		g_mp->Clear(*g_music_buffer);
 		delete g_mp;
-		g_mp = NULL;
+		g_mp = nullptr;
 	}
 
-	g_music_buffer = NULL;
+	g_music_buffer = nullptr;
 
 	input_audio_format.Clear();
 
diff --git a/src/OutputCommand.cxx b/src/OutputCommand.cxx
index f6b35c6ed..78c31b3ef 100644
--- a/src/OutputCommand.cxx
+++ b/src/OutputCommand.cxx
@@ -73,7 +73,7 @@ audio_output_disable_index(unsigned idx)
 	idle_add(IDLE_OUTPUT);
 
 	Mixer *mixer = ao->mixer;
-	if (mixer != NULL) {
+	if (mixer != nullptr) {
 		mixer_close(mixer);
 		idle_add(IDLE_MIXER);
 	}
diff --git a/src/OutputControl.cxx b/src/OutputControl.cxx
index 4a3552c17..bcc22e842 100644
--- a/src/OutputControl.cxx
+++ b/src/OutputControl.cxx
@@ -100,7 +100,7 @@ void
 audio_output_set_replay_gain_mode(struct audio_output *ao,
 				  enum replay_gain_mode mode)
 {
-	if (ao->replay_gain_filter != NULL)
+	if (ao->replay_gain_filter != nullptr)
 		replay_gain_filter_set_mode(ao->replay_gain_filter, mode);
 }
 
@@ -108,7 +108,7 @@ void
 audio_output_enable(struct audio_output *ao)
 {
 	if (!ao->thread.IsDefined()) {
-		if (ao->plugin->enable == NULL) {
+		if (ao->plugin->enable == nullptr) {
 			/* don't bother to start the thread now if the
 			   device doesn't even have a enable() method;
 			   just assign the variable and we're done */
@@ -126,7 +126,7 @@ void
 audio_output_disable(struct audio_output *ao)
 {
 	if (!ao->thread.IsDefined()) {
-		if (ao->plugin->disable == NULL)
+		if (ao->plugin->disable == nullptr)
 			ao->really_enabled = false;
 		else
 			/* if there's no thread yet, the device cannot
@@ -149,13 +149,13 @@ audio_output_open(struct audio_output *ao,
 {
 	bool open;
 
-	assert(ao != NULL);
+	assert(ao != nullptr);
 	assert(ao->allow_play);
 	assert(audio_format.IsValid());
 
-	if (ao->fail_timer != NULL) {
+	if (ao->fail_timer != nullptr) {
 		g_timer_destroy(ao->fail_timer);
-		ao->fail_timer = NULL;
+		ao->fail_timer = nullptr;
 	}
 
 	if (ao->open && audio_format == ao->in_audio_format) {
@@ -163,7 +163,7 @@ audio_output_open(struct audio_output *ao,
 		       (ao->always_on && ao->pause));
 
 		if (ao->pause) {
-			ao->chunk = NULL;
+			ao->chunk = nullptr;
 			ao->pipe = &mp;
 
 			/* unpause with the CANCEL command; this is a
@@ -180,7 +180,7 @@ audio_output_open(struct audio_output *ao,
 	}
 
 	ao->in_audio_format = audio_format;
-	ao->chunk = NULL;
+	ao->chunk = nullptr;
 
 	ao->pipe = &mp;
 
@@ -190,7 +190,7 @@ audio_output_open(struct audio_output *ao,
 	ao_command(ao, ao->open ? AO_COMMAND_REOPEN : AO_COMMAND_OPEN);
 	open = ao->open;
 
-	if (open && ao->mixer != NULL) {
+	if (open && ao->mixer != nullptr) {
 		Error error;
 		if (!mixer_open(ao->mixer, error))
 			FormatWarning(output_domain,
@@ -208,19 +208,19 @@ audio_output_open(struct audio_output *ao,
 static void
 audio_output_close_locked(struct audio_output *ao)
 {
-	assert(ao != NULL);
+	assert(ao != nullptr);
 	assert(ao->allow_play);
 
-	if (ao->mixer != NULL)
+	if (ao->mixer != nullptr)
 		mixer_auto_close(ao->mixer);
 
-	assert(!ao->open || ao->fail_timer == NULL);
+	assert(!ao->open || ao->fail_timer == nullptr);
 
 	if (ao->open)
 		ao_command(ao, AO_COMMAND_CLOSE);
-	else if (ao->fail_timer != NULL) {
+	else if (ao->fail_timer != nullptr) {
 		g_timer_destroy(ao->fail_timer);
-		ao->fail_timer = NULL;
+		ao->fail_timer = nullptr;
 	}
 }
 
@@ -232,8 +232,8 @@ audio_output_update(struct audio_output *ao,
 	const ScopeLock protect(ao->mutex);
 
 	if (ao->enabled && ao->really_enabled) {
-		if (ao->fail_timer == NULL ||
-		    g_timer_elapsed(ao->fail_timer, NULL) > REOPEN_AFTER) {
+		if (ao->fail_timer == nullptr ||
+		    g_timer_elapsed(ao->fail_timer, nullptr) > REOPEN_AFTER) {
 			return audio_output_open(ao, audio_format, mp);
 		}
 	} else if (audio_output_is_open(ao))
@@ -255,7 +255,7 @@ audio_output_play(struct audio_output *ao)
 
 void audio_output_pause(struct audio_output *ao)
 {
-	if (ao->mixer != NULL && ao->plugin->pause == NULL)
+	if (ao->mixer != nullptr && ao->plugin->pause == nullptr)
 		/* the device has no pause mode: close the mixer,
 		   unless its "global" flag is set (checked by
 		   mixer_auto_close()) */
@@ -309,8 +309,8 @@ audio_output_release(struct audio_output *ao)
 
 void audio_output_close(struct audio_output *ao)
 {
-	assert(ao != NULL);
-	assert(!ao->open || ao->fail_timer == NULL);
+	assert(ao != nullptr);
+	assert(!ao->open || ao->fail_timer == nullptr);
 
 	const ScopeLock protect(ao->mutex);
 	audio_output_close_locked(ao);
@@ -320,7 +320,7 @@ void audio_output_finish(struct audio_output *ao)
 {
 	audio_output_close(ao);
 
-	assert(ao->fail_timer == NULL);
+	assert(ao->fail_timer == nullptr);
 
 	if (ao->thread.IsDefined()) {
 		assert(ao->allow_play);
diff --git a/src/OutputFinish.cxx b/src/OutputFinish.cxx
index 986103a38..db6599b53 100644
--- a/src/OutputFinish.cxx
+++ b/src/OutputFinish.cxx
@@ -29,10 +29,10 @@ void
 ao_base_finish(struct audio_output *ao)
 {
 	assert(!ao->open);
-	assert(ao->fail_timer == NULL);
+	assert(ao->fail_timer == nullptr);
 	assert(!ao->thread.IsDefined());
 
-	if (ao->mixer != NULL)
+	if (ao->mixer != nullptr)
 		mixer_free(ao->mixer);
 
 	delete ao->replay_gain_filter;
@@ -44,7 +44,7 @@ void
 audio_output_free(struct audio_output *ao)
 {
 	assert(!ao->open);
-	assert(ao->fail_timer == NULL);
+	assert(ao->fail_timer == nullptr);
 	assert(!ao->thread.IsDefined());
 
 	ao_plugin_finish(ao);
diff --git a/src/OutputInit.cxx b/src/OutputInit.cxx
index 6b98ca2c3..ab525feb0 100644
--- a/src/OutputInit.cxx
+++ b/src/OutputInit.cxx
@@ -53,7 +53,7 @@ audio_output_detect(Error &error)
 	LogInfo(output_domain, "Attempt to detect audio output device");
 
 	audio_output_plugins_for_each(plugin) {
-		if (plugin->test_default_device == NULL)
+		if (plugin->test_default_device == nullptr)
 			continue;
 
 		FormatInfo(output_domain,
@@ -64,7 +64,7 @@ audio_output_detect(Error &error)
 	}
 
 	error.Set(output_domain, "Unable to detect an audio device");
-	return NULL;
+	return nullptr;
 }
 
 /**
@@ -80,7 +80,7 @@ audio_output_mixer_type(const config_param &param)
 {
 	/* read the local "mixer_type" setting */
 	const char *p = param.GetBlockValue("mixer_type");
-	if (p != NULL)
+	if (p != nullptr)
 		return mixer_type_parse(p);
 
 	/* try the local "mixer_enabled" setting next (deprecated) */
@@ -105,11 +105,11 @@ audio_output_load_mixer(struct audio_output *ao,
 	switch (audio_output_mixer_type(param)) {
 	case MIXER_TYPE_NONE:
 	case MIXER_TYPE_UNKNOWN:
-		return NULL;
+		return nullptr;
 
 	case MIXER_TYPE_HARDWARE:
-		if (plugin == NULL)
-			return NULL;
+		if (plugin == nullptr)
+			return nullptr;
 
 		return mixer_new(plugin, ao, param, error);
 
@@ -117,7 +117,7 @@ audio_output_load_mixer(struct audio_output *ao,
 		mixer = mixer_new(&software_mixer_plugin, nullptr,
 				  config_param(),
 				  IgnoreError());
-		assert(mixer != NULL);
+		assert(mixer != nullptr);
 
 		filter_chain_append(filter_chain, "software_mixer",
 				    software_mixer_get_filter(mixer));
@@ -133,23 +133,23 @@ ao_base_init(struct audio_output *ao,
 	     const struct audio_output_plugin *plugin,
 	     const config_param &param, Error &error)
 {
-	assert(ao != NULL);
-	assert(plugin != NULL);
-	assert(plugin->finish != NULL);
-	assert(plugin->open != NULL);
-	assert(plugin->close != NULL);
-	assert(plugin->play != NULL);
+	assert(ao != nullptr);
+	assert(plugin != nullptr);
+	assert(plugin->finish != nullptr);
+	assert(plugin->open != nullptr);
+	assert(plugin->close != nullptr);
+	assert(plugin->play != nullptr);
 
 	if (!param.IsNull()) {
 		ao->name = param.GetBlockValue(AUDIO_OUTPUT_NAME);
-		if (ao->name == NULL) {
+		if (ao->name == nullptr) {
 			error.Set(config_domain,
 				  "Missing \"name\" configuration");
 			return false;
 		}
 
 		const char *p = param.GetBlockValue(AUDIO_OUTPUT_FORMAT);
-		if (p != NULL) {
+		if (p != nullptr) {
 			bool success =
 				audio_format_parse(ao->config_audio_format,
 						   p, true, error);
@@ -171,12 +171,12 @@ ao_base_init(struct audio_output *ao,
 	ao->open = false;
 	ao->pause = false;
 	ao->allow_play = true;
-	ao->fail_timer = NULL;
+	ao->fail_timer = nullptr;
 
 	/* set up the filter chain */
 
 	ao->filter = filter_chain_new();
-	assert(ao->filter != NULL);
+	assert(ao->filter != nullptr);
 
 	/* create the normalization filter (if configured) */
 
@@ -184,7 +184,7 @@ ao_base_init(struct audio_output *ao,
 		Filter *normalize_filter =
 			filter_new(&normalize_filter_plugin, config_param(),
 				   IgnoreError());
-		assert(normalize_filter != NULL);
+		assert(normalize_filter != nullptr);
 
 		filter_chain_append(*ao->filter, "normalize",
 				    autoconvert_filter_new(normalize_filter));
@@ -204,9 +204,9 @@ ao_base_init(struct audio_output *ao,
 
 	ao->command = AO_COMMAND_NONE;
 
-	ao->mixer = NULL;
-	ao->replay_gain_filter = NULL;
-	ao->other_replay_gain_filter = NULL;
+	ao->mixer = nullptr;
+	ao->replay_gain_filter = nullptr;
+	ao->other_replay_gain_filter = nullptr;
 
 	/* done */
 
@@ -226,19 +226,19 @@ audio_output_setup(struct audio_output *ao, const config_param &param,
 	if (strcmp(replay_gain_handler, "none") != 0) {
 		ao->replay_gain_filter = filter_new(&replay_gain_filter_plugin,
 						    param, IgnoreError());
-		assert(ao->replay_gain_filter != NULL);
+		assert(ao->replay_gain_filter != nullptr);
 
 		ao->replay_gain_serial = 0;
 
 		ao->other_replay_gain_filter = filter_new(&replay_gain_filter_plugin,
 							  param,
 							  IgnoreError());
-		assert(ao->other_replay_gain_filter != NULL);
+		assert(ao->other_replay_gain_filter != nullptr);
 
 		ao->other_replay_gain_serial = 0;
 	} else {
-		ao->replay_gain_filter = NULL;
-		ao->other_replay_gain_filter = NULL;
+		ao->replay_gain_filter = nullptr;
+		ao->other_replay_gain_filter = nullptr;
 	}
 
 	/* set up the mixer */
@@ -247,7 +247,7 @@ audio_output_setup(struct audio_output *ao, const config_param &param,
 	ao->mixer = audio_output_load_mixer(ao, param,
 					    ao->plugin->mixer_plugin,
 					    *ao->filter, mixer_error);
-	if (ao->mixer == NULL && mixer_error.IsDefined())
+	if (ao->mixer == nullptr && mixer_error.IsDefined())
 		FormatError(mixer_error,
 			    "Failed to initialize hardware mixer for '%s'",
 			    ao->name);
@@ -255,14 +255,14 @@ audio_output_setup(struct audio_output *ao, const config_param &param,
 	/* use the hardware mixer for replay gain? */
 
 	if (strcmp(replay_gain_handler, "mixer") == 0) {
-		if (ao->mixer != NULL)
+		if (ao->mixer != nullptr)
 			replay_gain_filter_set_mixer(ao->replay_gain_filter,
 						     ao->mixer, 100);
 		else
 			FormatError(output_domain,
 				    "No such mixer for output '%s'", ao->name);
 	} else if (strcmp(replay_gain_handler, "software") != 0 &&
-		   ao->replay_gain_filter != NULL) {
+		   ao->replay_gain_filter != nullptr) {
 		error.Set(config_domain,
 			  "Invalid \"replay_gain_handler\" value");
 		return false;
@@ -272,7 +272,7 @@ audio_output_setup(struct audio_output *ao, const config_param &param,
 
 	ao->convert_filter = filter_new(&convert_filter_plugin, config_param(),
 					IgnoreError());
-	assert(ao->convert_filter != NULL);
+	assert(ao->convert_filter != nullptr);
 
 	filter_chain_append(*ao->filter, "convert", ao->convert_filter);
 
@@ -290,14 +290,14 @@ audio_output_new(const config_param &param,
 		const char *p;
 
 		p = param.GetBlockValue(AUDIO_OUTPUT_TYPE);
-		if (p == NULL) {
+		if (p == nullptr) {
 			error.Set(config_domain,
 				  "Missing \"type\" configuration");
 			return nullptr;
 		}
 
 		plugin = audio_output_plugin_get(p);
-		if (plugin == NULL) {
+		if (plugin == nullptr) {
 			error.Format(config_domain,
 				     "No such audio output plugin: %s", p);
 			return nullptr;
@@ -307,7 +307,7 @@ audio_output_new(const config_param &param,
 			   "No 'audio_output' defined in config file");
 
 		plugin = audio_output_detect(error);
-		if (plugin == NULL)
+		if (plugin == nullptr)
 			return nullptr;
 
 		FormatInfo(output_domain,
@@ -316,12 +316,12 @@ audio_output_new(const config_param &param,
 	}
 
 	struct audio_output *ao = ao_plugin_init(plugin, param, error);
-	if (ao == NULL)
-		return NULL;
+	if (ao == nullptr)
+		return nullptr;
 
 	if (!audio_output_setup(ao, param, error)) {
 		ao_plugin_finish(ao);
-		return NULL;
+		return nullptr;
 	}
 
 	ao->player_control = pc;
diff --git a/src/OutputInternal.hxx b/src/OutputInternal.hxx
index 6818dee14..db2c2b557 100644
--- a/src/OutputInternal.hxx
+++ b/src/OutputInternal.hxx
@@ -72,7 +72,7 @@ struct audio_output {
 
 	/**
 	 * The #mixer object associated with this audio output device.
-	 * May be NULL if none is available, or if software volume is
+	 * May be nullptr if none is available, or if software volume is
 	 * configured.
 	 */
 	class Mixer *mixer;
@@ -127,7 +127,7 @@ struct audio_output {
 	bool allow_play;
 
 	/**
-	 * If not NULL, the device has failed, and this timer is used
+	 * If not nullptr, the device has failed, and this timer is used
 	 * to estimate how long it should stay disabled (unless
 	 * explicitly reopened with "play").
 	 */
@@ -197,7 +197,7 @@ struct audio_output {
 	Filter *convert_filter;
 
 	/**
-	 * The thread handle, or NULL if the output thread isn't
+	 * The thread handle, or nullptr if the output thread isn't
 	 * running.
 	 */
 	Thread thread;
diff --git a/src/OutputPlugin.cxx b/src/OutputPlugin.cxx
index 038523ad9..31d9cce96 100644
--- a/src/OutputPlugin.cxx
+++ b/src/OutputPlugin.cxx
@@ -26,8 +26,8 @@ ao_plugin_init(const struct audio_output_plugin *plugin,
 	       const config_param &param,
 	       Error &error)
 {
-	assert(plugin != NULL);
-	assert(plugin->init != NULL);
+	assert(plugin != nullptr);
+	assert(plugin->init != nullptr);
 
 	return plugin->init(param, error);
 }
@@ -41,7 +41,7 @@ ao_plugin_finish(struct audio_output *ao)
 bool
 ao_plugin_enable(struct audio_output *ao, Error &error_r)
 {
-	return ao->plugin->enable != NULL
+	return ao->plugin->enable != nullptr
 		? ao->plugin->enable(ao, error_r)
 		: true;
 }
@@ -49,7 +49,7 @@ ao_plugin_enable(struct audio_output *ao, Error &error_r)
 void
 ao_plugin_disable(struct audio_output *ao)
 {
-	if (ao->plugin->disable != NULL)
+	if (ao->plugin->disable != nullptr)
 		ao->plugin->disable(ao);
 }
 
@@ -69,7 +69,7 @@ ao_plugin_close(struct audio_output *ao)
 unsigned
 ao_plugin_delay(struct audio_output *ao)
 {
-	return ao->plugin->delay != NULL
+	return ao->plugin->delay != nullptr
 		? ao->plugin->delay(ao)
 		: 0;
 }
@@ -77,7 +77,7 @@ ao_plugin_delay(struct audio_output *ao)
 void
 ao_plugin_send_tag(struct audio_output *ao, const Tag *tag)
 {
-	if (ao->plugin->send_tag != NULL)
+	if (ao->plugin->send_tag != nullptr)
 		ao->plugin->send_tag(ao, tag);
 }
 
@@ -91,19 +91,19 @@ ao_plugin_play(struct audio_output *ao, const void *chunk, size_t size,
 void
 ao_plugin_drain(struct audio_output *ao)
 {
-	if (ao->plugin->drain != NULL)
+	if (ao->plugin->drain != nullptr)
 		ao->plugin->drain(ao);
 }
 
 void
 ao_plugin_cancel(struct audio_output *ao)
 {
-	if (ao->plugin->cancel != NULL)
+	if (ao->plugin->cancel != nullptr)
 		ao->plugin->cancel(ao);
 }
 
 bool
 ao_plugin_pause(struct audio_output *ao)
 {
-	return ao->plugin->pause != NULL && ao->plugin->pause(ao);
+	return ao->plugin->pause != nullptr && ao->plugin->pause(ao);
 }
diff --git a/src/OutputPlugin.hxx b/src/OutputPlugin.hxx
index 4a2fb52bb..b9f4b7dfb 100644
--- a/src/OutputPlugin.hxx
+++ b/src/OutputPlugin.hxx
@@ -48,11 +48,9 @@ struct audio_output_plugin {
 	 * Configure and initialize the device, but do not open it
 	 * yet.
 	 *
-	 * @param param the configuration section, or NULL if there is
+	 * @param param the configuration section, or nullptr if there is
 	 * no configuration
-	 * @param error location to store the error occurring, or NULL
-	 * to ignore errors
-	 * @return NULL on error, or an opaque pointer to the plugin's
+	 * @return nullptr on error, or an opaque pointer to the plugin's
 	 * data
 	 */
 	struct audio_output *(*init)(const config_param &param,
@@ -69,8 +67,6 @@ struct audio_output_plugin {
 	 * fail: if an error occurs during that, it should be reported
 	 * by the open() method.
 	 *
-	 * @param error_r location to store the error occurring, or
-	 * NULL to ignore errors
 	 * @return true on success, false on error
 	 */
 	bool (*enable)(struct audio_output *data, Error &error);
@@ -86,8 +82,6 @@ struct audio_output_plugin {
 	 *
 	 * @param audio_format the audio format in which data is going
 	 * to be delivered; may be modified by the plugin
-	 * @param error location to store the error occurring, or NULL
-	 * to ignore errors
 	 */
 	bool (*open)(struct audio_output *data, AudioFormat &audio_format,
 		     Error &error);
@@ -116,8 +110,6 @@ struct audio_output_plugin {
 	/**
 	 * Play a chunk of audio data.
 	 *
-	 * @param error location to store the error occurring, or NULL
-	 * to ignore errors
 	 * @return the number of bytes played, or 0 on error
 	 */
 	size_t (*play)(struct audio_output *data,
@@ -150,7 +142,7 @@ struct audio_output_plugin {
 
 	/**
 	 * The mixer plugin associated with this output plugin.  This
-	 * may be NULL if no mixer plugin is implemented.  When
+	 * may be nullptr if no mixer plugin is implemented.  When
 	 * created, this mixer plugin gets the same #config_param as
 	 * this audio output device.
 	 */
@@ -160,7 +152,7 @@ struct audio_output_plugin {
 static inline bool
 ao_plugin_test_default_device(const struct audio_output_plugin *plugin)
 {
-	return plugin->test_default_device != NULL
+	return plugin->test_default_device != nullptr
 		? plugin->test_default_device()
 		: false;
 }
diff --git a/src/OutputThread.cxx b/src/OutputThread.cxx
index 5b93b04e3..c6f2e4d30 100644
--- a/src/OutputThread.cxx
+++ b/src/OutputThread.cxx
@@ -98,16 +98,16 @@ ao_filter_open(struct audio_output *ao, AudioFormat &format,
 	assert(format.IsValid());
 
 	/* the replay_gain filter cannot fail here */
-	if (ao->replay_gain_filter != NULL)
+	if (ao->replay_gain_filter != nullptr)
 		ao->replay_gain_filter->Open(format, error_r);
-	if (ao->other_replay_gain_filter != NULL)
+	if (ao->other_replay_gain_filter != nullptr)
 		ao->other_replay_gain_filter->Open(format, error_r);
 
 	const AudioFormat af = ao->filter->Open(format, error_r);
 	if (!af.IsDefined()) {
-		if (ao->replay_gain_filter != NULL)
+		if (ao->replay_gain_filter != nullptr)
 			ao->replay_gain_filter->Close();
-		if (ao->other_replay_gain_filter != NULL)
+		if (ao->other_replay_gain_filter != nullptr)
 			ao->other_replay_gain_filter->Close();
 	}
 
@@ -117,9 +117,9 @@ ao_filter_open(struct audio_output *ao, AudioFormat &format,
 static void
 ao_filter_close(struct audio_output *ao)
 {
-	if (ao->replay_gain_filter != NULL)
+	if (ao->replay_gain_filter != nullptr)
 		ao->replay_gain_filter->Close();
-	if (ao->other_replay_gain_filter != NULL)
+	if (ao->other_replay_gain_filter != nullptr)
 		ao->other_replay_gain_filter->Close();
 
 	ao->filter->Close();
@@ -133,17 +133,17 @@ ao_open(struct audio_output *ao)
 	struct audio_format_string af_string;
 
 	assert(!ao->open);
-	assert(ao->pipe != NULL);
-	assert(ao->chunk == NULL);
+	assert(ao->pipe != nullptr);
+	assert(ao->chunk == nullptr);
 	assert(ao->in_audio_format.IsValid());
 
-	if (ao->fail_timer != NULL) {
+	if (ao->fail_timer != nullptr) {
 		/* this can only happen when this
 		   output thread fails while
 		   audio_output_open() is run in the
 		   player thread */
 		g_timer_destroy(ao->fail_timer);
-		ao->fail_timer = NULL;
+		ao->fail_timer = nullptr;
 	}
 
 	/* enable the device (just in case the last enable has failed) */
@@ -204,9 +204,9 @@ ao_close(struct audio_output *ao, bool drain)
 {
 	assert(ao->open);
 
-	ao->pipe = NULL;
+	ao->pipe = nullptr;
 
-	ao->chunk = NULL;
+	ao->chunk = nullptr;
 	ao->open = false;
 
 	ao->mutex.unlock();
@@ -242,9 +242,9 @@ ao_reopen_filter(struct audio_output *ao)
 		   but we cannot call this function because we must
 		   not call filter_close(ao->filter) again */
 
-		ao->pipe = NULL;
+		ao->pipe = nullptr;
 
-		ao->chunk = NULL;
+		ao->chunk = nullptr;
 		ao->open = false;
 		ao->fail_timer = g_timer_new();
 
@@ -310,7 +310,7 @@ ao_chunk_data(struct audio_output *ao, const struct music_chunk *chunk,
 	      unsigned *replay_gain_serial_p,
 	      size_t *length_r)
 {
-	assert(chunk != NULL);
+	assert(chunk != nullptr);
 	assert(!chunk->IsEmpty());
 	assert(chunk->CheckFormat(ao->in_audio_format));
 
@@ -321,22 +321,22 @@ ao_chunk_data(struct audio_output *ao, const struct music_chunk *chunk,
 
 	assert(length % ao->in_audio_format.GetFrameSize() == 0);
 
-	if (length > 0 && replay_gain_filter != NULL) {
+	if (length > 0 && replay_gain_filter != nullptr) {
 		if (chunk->replay_gain_serial != *replay_gain_serial_p) {
 			replay_gain_filter_set_info(replay_gain_filter,
 						    chunk->replay_gain_serial != 0
 						    ? &chunk->replay_gain_info
-						    : NULL);
+						    : nullptr);
 			*replay_gain_serial_p = chunk->replay_gain_serial;
 		}
 
 		Error error;
 		data = replay_gain_filter->FilterPCM(data, length,
 						     &length, error);
-		if (data == NULL) {
+		if (data == nullptr) {
 			FormatError(error, "\"%s\" [%s] failed to filter",
 				    ao->name, ao->plugin->name);
-			return NULL;
+			return nullptr;
 		}
 	}
 
@@ -351,8 +351,8 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
 	size_t length;
 	const void *data = ao_chunk_data(ao, chunk, ao->replay_gain_filter,
 					 &ao->replay_gain_serial, &length);
-	if (data == NULL)
-		return NULL;
+	if (data == nullptr)
+		return nullptr;
 
 	if (length == 0) {
 		/* empty chunk, nothing to do */
@@ -362,15 +362,15 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
 
 	/* cross-fade */
 
-	if (chunk->other != NULL) {
+	if (chunk->other != nullptr) {
 		size_t other_length;
 		const void *other_data =
 			ao_chunk_data(ao, chunk->other,
 				      ao->other_replay_gain_filter,
 				      &ao->other_replay_gain_serial,
 				      &other_length);
-		if (other_data == NULL)
-			return NULL;
+		if (other_data == nullptr)
+			return nullptr;
 
 		if (other_length == 0) {
 			*length_r = 0;
@@ -393,7 +393,7 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
 			FormatError(output_domain,
 				    "Cannot cross-fade format %s",
 				    sample_format_to_string(ao->in_audio_format.format));
-			return NULL;
+			return nullptr;
 		}
 
 		data = dest;
@@ -404,10 +404,10 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
 
 	Error error;
 	data = ao->filter->FilterPCM(data, length, &length, error);
-	if (data == NULL) {
+	if (data == nullptr) {
 		FormatError(error, "\"%s\" [%s] failed to filter",
 			    ao->name, ao->plugin->name);
-		return NULL;
+		return nullptr;
 	}
 
 	*length_r = length;
@@ -417,10 +417,10 @@ ao_filter_chunk(struct audio_output *ao, const struct music_chunk *chunk,
 static bool
 ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
 {
-	assert(ao != NULL);
-	assert(ao->filter != NULL);
+	assert(ao != nullptr);
+	assert(ao->filter != nullptr);
 
-	if (ao->tags && gcc_unlikely(chunk->tag != NULL)) {
+	if (ao->tags && gcc_unlikely(chunk->tag != nullptr)) {
 		ao->mutex.unlock();
 		ao_plugin_send_tag(ao, chunk->tag);
 		ao->mutex.lock();
@@ -432,7 +432,7 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
 	size = 0;
 #endif
 	const char *data = (const char *)ao_filter_chunk(ao, chunk, &size);
-	if (data == NULL) {
+	if (data == nullptr) {
 		ao_close(ao, false);
 
 		/* don't automatically reopen this device for 10
@@ -461,7 +461,7 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
 
 			/* don't automatically reopen this device for
 			   10 seconds */
-			assert(ao->fail_timer == NULL);
+			assert(ao->fail_timer == nullptr);
 			ao->fail_timer = g_timer_new();
 
 			return false;
@@ -480,7 +480,7 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
 static const struct music_chunk *
 ao_next_chunk(struct audio_output *ao)
 {
-	return ao->chunk != NULL
+	return ao->chunk != nullptr
 		/* continue the previous play() call */
 		? ao->chunk->next
 		/* get the first chunk from the pipe */
@@ -501,23 +501,23 @@ ao_play(struct audio_output *ao)
 	bool success;
 	const struct music_chunk *chunk;
 
-	assert(ao->pipe != NULL);
+	assert(ao->pipe != nullptr);
 
 	chunk = ao_next_chunk(ao);
-	if (chunk == NULL)
+	if (chunk == nullptr)
 		/* no chunk available */
 		return false;
 
 	ao->chunk_finished = false;
 
-	while (chunk != NULL && ao->command == AO_COMMAND_NONE) {
+	while (chunk != nullptr && ao->command == AO_COMMAND_NONE) {
 		assert(!ao->chunk_finished);
 
 		ao->chunk = chunk;
 
 		success = ao_play_chunk(ao, chunk);
 		if (!success) {
-			assert(ao->chunk == NULL);
+			assert(ao->chunk == nullptr);
 			break;
 		}
 
@@ -596,7 +596,7 @@ audio_output_task(void *arg)
 
 		case AO_COMMAND_CLOSE:
 			assert(ao->open);
-			assert(ao->pipe != NULL);
+			assert(ao->pipe != nullptr);
 
 			ao_close(ao, false);
 			ao_command_finished(ao);
@@ -621,7 +621,7 @@ audio_output_task(void *arg)
 
 		case AO_COMMAND_DRAIN:
 			if (ao->open) {
-				assert(ao->chunk == NULL);
+				assert(ao->chunk == nullptr);
 				assert(ao->pipe->Peek() == nullptr);
 
 				ao->mutex.unlock();
@@ -633,7 +633,7 @@ audio_output_task(void *arg)
 			continue;
 
 		case AO_COMMAND_CANCEL:
-			ao->chunk = NULL;
+			ao->chunk = nullptr;
 
 			if (ao->open) {
 				ao->mutex.unlock();
@@ -645,7 +645,7 @@ audio_output_task(void *arg)
 			continue;
 
 		case AO_COMMAND_KILL:
-			ao->chunk = NULL;
+			ao->chunk = nullptr;
 			ao_command_finished(ao);
 			ao->mutex.unlock();
 			return;
diff --git a/src/PlayerControl.cxx b/src/PlayerControl.cxx
index e714429d3..96a221f6d 100644
--- a/src/PlayerControl.cxx
+++ b/src/PlayerControl.cxx
@@ -58,7 +58,7 @@ player_control::~player_control()
 void
 player_control::Play(Song *song)
 {
-	assert(song != NULL);
+	assert(song != nullptr);
 
 	Lock();
 
@@ -78,7 +78,7 @@ void
 player_control::Cancel()
 {
 	LockSynchronousCommand(PlayerCommand::CANCEL);
-	assert(next_song == NULL);
+	assert(next_song == nullptr);
 }
 
 void
@@ -203,7 +203,7 @@ player_control::ClearError()
 void
 player_control::EnqueueSong(Song *song)
 {
-	assert(song != NULL);
+	assert(song != nullptr);
 
 	Lock();
 	EnqueueSongLocked(song);
@@ -213,7 +213,7 @@ player_control::EnqueueSong(Song *song)
 bool
 player_control::Seek(Song *song, float seek_time)
 {
-	assert(song != NULL);
+	assert(song != nullptr);
 
 	Lock();
 
diff --git a/src/Queue.cxx b/src/Queue.cxx
index 6bb8175a1..4226592c0 100644
--- a/src/Queue.cxx
+++ b/src/Queue.cxx
@@ -281,7 +281,7 @@ queue::Clear()
 static void
 queue_sort_order_by_priority(struct queue *queue, unsigned start, unsigned end)
 {
-	assert(queue != NULL);
+	assert(queue != nullptr);
 	assert(queue->random);
 	assert(start <= end);
 	assert(end <= queue->length);
diff --git a/src/QueueSave.cxx b/src/QueueSave.cxx
index c45390097..43fb69846 100644
--- a/src/QueueSave.cxx
+++ b/src/QueueSave.cxx
@@ -79,10 +79,10 @@ queue_load_song(TextFile &file, const char *line, queue *queue)
 
 	uint8_t priority = 0;
 	if (g_str_has_prefix(line, PRIO_LABEL)) {
-		priority = strtoul(line + sizeof(PRIO_LABEL) - 1, NULL, 10);
+		priority = strtoul(line + sizeof(PRIO_LABEL) - 1, nullptr, 10);
 
 		line = file.ReadLine();
-		if (line == NULL)
+		if (line == nullptr)
 			return;
 	}
 
@@ -95,8 +95,8 @@ queue_load_song(TextFile &file, const char *line, queue *queue)
 			return;
 
 		Error error;
-		song = song_load(file, NULL, uri, error);
-		if (song == NULL) {
+		song = song_load(file, nullptr, uri, error);
+		if (song == nullptr) {
 			LogError(error);
 			return;
 		}
diff --git a/src/SongSave.cxx b/src/SongSave.cxx
index 4992b5ead..def4ef341 100644
--- a/src/SongSave.cxx
+++ b/src/SongSave.cxx
@@ -57,7 +57,7 @@ Song *
 song_load(TextFile &file, Directory *parent, const char *uri,
 	  Error &error)
 {
-	Song *song = parent != NULL
+	Song *song = parent != nullptr
 		? Song::NewFile(uri, parent)
 		: Song::NewRemote(uri);
 	char *line, *colon;
@@ -66,15 +66,15 @@ song_load(TextFile &file, Directory *parent, const char *uri,
 
 	TagBuilder tag;
 
-	while ((line = file.ReadLine()) != NULL &&
+	while ((line = file.ReadLine()) != nullptr &&
 	       strcmp(line, SONG_END) != 0) {
 		colon = strchr(line, ':');
-		if (colon == NULL || colon == line) {
+		if (colon == nullptr || colon == line) {
 			song->Free();
 
 			error.Format(song_save_domain,
 				     "unknown line in db: %s", line);
-			return NULL;
+			return nullptr;
 		}
 
 		*colon++ = 0;
@@ -93,13 +93,13 @@ song_load(TextFile &file, Directory *parent, const char *uri,
 
 			song->start_ms = strtoul(value, &endptr, 10);
 			if (*endptr == '-')
-				song->end_ms = strtoul(endptr + 1, NULL, 10);
+				song->end_ms = strtoul(endptr + 1, nullptr, 10);
 		} else {
 			song->Free();
 
 			error.Format(song_save_domain,
 				     "unknown line in db: %s", line);
-			return NULL;
+			return nullptr;
 		}
 	}
 
diff --git a/src/SongSort.cxx b/src/SongSort.cxx
index f1eba0439..431d629b0 100644
--- a/src/SongSort.cxx
+++ b/src/SongSort.cxx
@@ -35,18 +35,18 @@ extern "C" {
 static const char *
 tag_get_value_checked(const Tag *tag, enum tag_type type)
 {
-	return tag != NULL
+	return tag != nullptr
 		? tag->GetValue(type)
-		: NULL;
+		: nullptr;
 }
 
 static int
 compare_utf8_string(const char *a, const char *b)
 {
-	if (a == NULL)
-		return b == NULL ? 0 : -1;
+	if (a == nullptr)
+		return b == nullptr ? 0 : -1;
 
-	if (b == NULL)
+	if (b == nullptr)
 		return 1;
 
 	return g_utf8_collate(a, b);
@@ -54,7 +54,7 @@ compare_utf8_string(const char *a, const char *b)
 
 /**
  * Compare two string tag values, ignoring case.  Either one may be
- * NULL.
+ * nullptr.
  */
 static int
 compare_string_tag_item(const Tag *a, const Tag *b,
@@ -66,13 +66,13 @@ compare_string_tag_item(const Tag *a, const Tag *b,
 
 /**
  * Compare two tag values which should contain an integer value
- * (e.g. disc or track number).  Either one may be NULL.
+ * (e.g. disc or track number).  Either one may be nullptr.
  */
 static int
 compare_number_string(const char *a, const char *b)
 {
-	long ai = a == NULL ? 0 : strtol(a, NULL, 10);
-	long bi = b == NULL ? 0 : strtol(b, NULL, 10);
+	long ai = a == nullptr ? 0 : strtol(a, nullptr, 10);
+	long bi = b == nullptr ? 0 : strtol(b, nullptr, 10);
 
 	if (ai <= 0)
 		return bi <= 0 ? 0 : -1;
@@ -120,5 +120,5 @@ song_cmp(gcc_unused void *priv, struct list_head *_a, struct list_head *_b)
 void
 song_list_sort(struct list_head *songs)
 {
-	list_sort(NULL, songs, song_cmp);
+	list_sort(nullptr, songs, song_cmp);
 }
diff --git a/src/SongSticker.cxx b/src/SongSticker.cxx
index 4932e0ef8..47ddc85b0 100644
--- a/src/SongSticker.cxx
+++ b/src/SongSticker.cxx
@@ -31,7 +31,7 @@
 std::string
 sticker_song_get_value(const Song *song, const char *name)
 {
-	assert(song != NULL);
+	assert(song != nullptr);
 	assert(song->IsInDatabase());
 
 	const auto uri = song->GetURI();
@@ -42,7 +42,7 @@ bool
 sticker_song_set_value(const Song *song,
 		       const char *name, const char *value)
 {
-	assert(song != NULL);
+	assert(song != nullptr);
 	assert(song->IsInDatabase());
 
 	const auto uri = song->GetURI();
@@ -52,7 +52,7 @@ sticker_song_set_value(const Song *song,
 bool
 sticker_song_delete(const Song *song)
 {
-	assert(song != NULL);
+	assert(song != nullptr);
 	assert(song->IsInDatabase());
 
 	const auto uri = song->GetURI();
@@ -62,7 +62,7 @@ sticker_song_delete(const Song *song)
 bool
 sticker_song_delete_value(const Song *song, const char *name)
 {
-	assert(song != NULL);
+	assert(song != nullptr);
 	assert(song->IsInDatabase());
 
 	const auto uri = song->GetURI();
@@ -72,7 +72,7 @@ sticker_song_delete_value(const Song *song, const char *name)
 struct sticker *
 sticker_song_get(const Song *song)
 {
-	assert(song != NULL);
+	assert(song != nullptr);
 	assert(song->IsInDatabase());
 
 	const auto uri = song->GetURI();
@@ -100,7 +100,7 @@ sticker_song_find_cb(const char *uri, const char *value, void *user_data)
 		return;
 
 	Song *song = data->directory->LookupSong(uri + data->base_uri_length);
-	if (song != NULL)
+	if (song != nullptr)
 		data->func(song, value, data->user_data);
 }
 
@@ -120,10 +120,10 @@ sticker_song_find(Directory *directory, const char *name,
 	if (*data.base_uri != 0)
 		/* append slash to base_uri */
 		data.base_uri = allocated =
-			g_strconcat(data.base_uri, "/", NULL);
+			g_strconcat(data.base_uri, "/", nullptr);
 	else
 		/* searching in root directory - no trailing slash */
-		allocated = NULL;
+		allocated = nullptr;
 
 	data.base_uri_length = strlen(data.base_uri);
 
diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx
index 362f17e8a..8d8a2d686 100644
--- a/src/SongUpdate.cxx
+++ b/src/SongUpdate.cxx
@@ -48,21 +48,21 @@ Song::LoadFile(const char *path_utf8, Directory *parent)
 	Song *song;
 	bool ret;
 
-	assert((parent == NULL) == PathTraits::IsAbsoluteUTF8(path_utf8));
+	assert((parent == nullptr) == PathTraits::IsAbsoluteUTF8(path_utf8));
 	assert(!uri_has_scheme(path_utf8));
-	assert(strchr(path_utf8, '\n') == NULL);
+	assert(strchr(path_utf8, '\n') == nullptr);
 
 	song = NewFile(path_utf8, parent);
 
 	//in archive ?
-	if (parent != NULL && parent->device == DEVICE_INARCHIVE) {
+	if (parent != nullptr && parent->device == DEVICE_INARCHIVE) {
 		ret = song->UpdateFileInArchive();
 	} else {
 		ret = song->UpdateFile();
 	}
 	if (!ret) {
 		song->Free();
-		return NULL;
+		return nullptr;
 	}
 
 	return song;
@@ -85,18 +85,18 @@ Song::UpdateFile()
 	const char *suffix;
 	const struct decoder_plugin *plugin;
 	struct stat st;
-	struct input_stream *is = NULL;
+	struct input_stream *is = nullptr;
 
 	assert(IsFile());
 
 	/* check if there's a suffix and a plugin */
 
 	suffix = uri_get_suffix(uri);
-	if (suffix == NULL)
+	if (suffix == nullptr)
 		return false;
 
-	plugin = decoder_plugin_from_suffix(suffix, NULL);
-	if (plugin == NULL)
+	plugin = decoder_plugin_from_suffix(suffix, nullptr);
+	if (plugin == nullptr)
 		return false;
 
 	const auto path_fs = map_song_fs(this);
@@ -126,16 +126,16 @@ Song::UpdateFile()
 		tag_builder.Clear();
 
 		/* fall back to stream tag */
-		if (plugin->scan_stream != NULL) {
+		if (plugin->scan_stream != nullptr) {
 			/* open the input_stream (if not already
 			   open) */
-			if (is == NULL)
+			if (is == nullptr)
 				is = input_stream::Open(path_fs.c_str(),
 							mutex, cond,
 							IgnoreError());
 
 			/* now try the stream_tag() method */
-			if (is != NULL) {
+			if (is != nullptr) {
 				if (decoder_plugin_scan_stream(plugin, is,
 							       &full_tag_handler,
 							       &tag_builder))
@@ -148,9 +148,9 @@ Song::UpdateFile()
 		}
 
 		plugin = decoder_plugin_from_suffix(suffix, plugin);
-	} while (plugin != NULL);
+	} while (plugin != nullptr);
 
-	if (is != NULL)
+	if (is != nullptr)
 		is->Close();
 
 	if (!tag_builder.IsDefined())
@@ -175,11 +175,11 @@ Song::UpdateFileInArchive()
 	/* check if there's a suffix and a plugin */
 
 	suffix = uri_get_suffix(uri);
-	if (suffix == NULL)
+	if (suffix == nullptr)
 		return false;
 
-	plugin = decoder_plugin_from_suffix(suffix, NULL);
-	if (plugin == NULL)
+	plugin = decoder_plugin_from_suffix(suffix, nullptr);
+	if (plugin == nullptr)
 		return false;
 
 	delete tag;
diff --git a/src/StickerCommands.cxx b/src/StickerCommands.cxx
index 4c2152789..3a212a48b 100644
--- a/src/StickerCommands.cxx
+++ b/src/StickerCommands.cxx
@@ -134,7 +134,7 @@ handle_sticker_song(Client *client, int argc, char *argv[])
 
 		db_lock();
 		Directory *directory = db_get_directory(argv[3]);
-		if (directory == NULL) {
+		if (directory == nullptr) {
 			db_unlock();
 			command_error(client, ACK_ERROR_NO_EXIST,
 				      "no such directory");
diff --git a/src/StickerDatabase.cxx b/src/StickerDatabase.cxx
index 3c9bdc2a9..ca72a6024 100644
--- a/src/StickerDatabase.cxx
+++ b/src/StickerDatabase.cxx
@@ -95,12 +95,12 @@ sticker_prepare(const char *sql, Error &error)
 	int ret;
 	sqlite3_stmt *stmt;
 
-	ret = sqlite3_prepare_v2(sticker_db, sql, -1, &stmt, NULL);
+	ret = sqlite3_prepare_v2(sticker_db, sql, -1, &stmt, nullptr);
 	if (ret != SQLITE_OK) {
 		error.Format(sticker_domain, ret,
 			     "sqlite3_prepare_v2() failed: %s",
 			     sqlite3_errmsg(sticker_db));
-		return NULL;
+		return nullptr;
 	}
 
 	return stmt;
@@ -126,7 +126,8 @@ sticker_global_init(Path path, Error &error)
 
 	/* create the table and index */
 
-	ret = sqlite3_exec(sticker_db, sticker_sql_create, NULL, NULL, NULL);
+	ret = sqlite3_exec(sticker_db, sticker_sql_create,
+			   nullptr, nullptr, nullptr);
 	if (ret != SQLITE_OK) {
 		error.Format(sticker_domain, ret,
 			     "Failed to create sticker table: %s",
@@ -137,10 +138,10 @@ sticker_global_init(Path path, Error &error)
 	/* prepare the statements we're going to use */
 
 	for (unsigned i = 0; i < ARRAY_SIZE(sticker_sql); ++i) {
-		assert(sticker_sql[i] != NULL);
+		assert(sticker_sql[i] != nullptr);
 
 		sticker_stmt[i] = sticker_prepare(sticker_sql[i], error);
-		if (sticker_stmt[i] == NULL)
+		if (sticker_stmt[i] == nullptr)
 			return false;
 	}
 
@@ -150,12 +151,12 @@ sticker_global_init(Path path, Error &error)
 void
 sticker_global_finish(void)
 {
-	if (sticker_db == NULL)
+	if (sticker_db == nullptr)
 		/* not configured */
 		return;
 
 	for (unsigned i = 0; i < ARRAY_SIZE(sticker_stmt); ++i) {
-		assert(sticker_stmt[i] != NULL);
+		assert(sticker_stmt[i] != nullptr);
 
 		sqlite3_finalize(sticker_stmt[i]);
 	}
@@ -166,7 +167,7 @@ sticker_global_finish(void)
 bool
 sticker_enabled(void)
 {
-	return sticker_db != NULL;
+	return sticker_db != nullptr;
 }
 
 std::string
@@ -176,28 +177,28 @@ sticker_load_value(const char *type, const char *uri, const char *name)
 	int ret;
 
 	assert(sticker_enabled());
-	assert(type != NULL);
-	assert(uri != NULL);
-	assert(name != NULL);
+	assert(type != nullptr);
+	assert(uri != nullptr);
+	assert(name != nullptr);
 
 	if (*name == 0)
 		return std::string();
 
 	sqlite3_reset(stmt);
 
-	ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 1, type, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return std::string();
 	}
 
-	ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 2, uri, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return std::string();
 	}
 
-	ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 3, name, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return std::string();
@@ -231,19 +232,19 @@ sticker_list_values(std::map<std::string, std::string> &table,
 	sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_LIST];
 	int ret;
 
-	assert(type != NULL);
-	assert(uri != NULL);
+	assert(type != nullptr);
+	assert(uri != nullptr);
 	assert(sticker_enabled());
 
 	sqlite3_reset(stmt);
 
-	ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 1, type, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 2, uri, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
@@ -284,35 +285,35 @@ sticker_update_value(const char *type, const char *uri,
 	sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_UPDATE];
 	int ret;
 
-	assert(type != NULL);
-	assert(uri != NULL);
-	assert(name != NULL);
+	assert(type != nullptr);
+	assert(uri != nullptr);
+	assert(name != nullptr);
 	assert(*name != 0);
-	assert(value != NULL);
+	assert(value != nullptr);
 
 	assert(sticker_enabled());
 
 	sqlite3_reset(stmt);
 
-	ret = sqlite3_bind_text(stmt, 1, value, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 1, value, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 2, type, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 2, type, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 3, uri, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 3, uri, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 4, name, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 4, name, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
@@ -343,35 +344,35 @@ sticker_insert_value(const char *type, const char *uri,
 	sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_INSERT];
 	int ret;
 
-	assert(type != NULL);
-	assert(uri != NULL);
-	assert(name != NULL);
+	assert(type != nullptr);
+	assert(uri != nullptr);
+	assert(name != nullptr);
 	assert(*name != 0);
-	assert(value != NULL);
+	assert(value != nullptr);
 
 	assert(sticker_enabled());
 
 	sqlite3_reset(stmt);
 
-	ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 1, type, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 2, uri, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 3, name, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 4, value, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 4, value, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
@@ -399,10 +400,10 @@ sticker_store_value(const char *type, const char *uri,
 		    const char *name, const char *value)
 {
 	assert(sticker_enabled());
-	assert(type != NULL);
-	assert(uri != NULL);
-	assert(name != NULL);
-	assert(value != NULL);
+	assert(type != nullptr);
+	assert(uri != nullptr);
+	assert(name != nullptr);
+	assert(value != nullptr);
 
 	if (*name == 0)
 		return false;
@@ -418,18 +419,18 @@ sticker_delete(const char *type, const char *uri)
 	int ret;
 
 	assert(sticker_enabled());
-	assert(type != NULL);
-	assert(uri != NULL);
+	assert(type != nullptr);
+	assert(uri != nullptr);
 
 	sqlite3_reset(stmt);
 
-	ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 1, type, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 2, uri, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
@@ -458,24 +459,24 @@ sticker_delete_value(const char *type, const char *uri, const char *name)
 	int ret;
 
 	assert(sticker_enabled());
-	assert(type != NULL);
-	assert(uri != NULL);
+	assert(type != nullptr);
+	assert(uri != nullptr);
 
 	sqlite3_reset(stmt);
 
-	ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 1, type, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 2, uri, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 3, name, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
@@ -531,11 +532,11 @@ sticker_load(const char *type, const char *uri)
 	sticker s;
 
 	if (!sticker_list_values(s.table, type, uri))
-		return NULL;
+		return nullptr;
 
 	if (s.table.empty())
 		/* don't return empty sticker objects */
-		return NULL;
+		return nullptr;
 
 	return new sticker(std::move(s));
 }
@@ -549,29 +550,29 @@ sticker_find(const char *type, const char *base_uri, const char *name,
 	sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_FIND];
 	int ret;
 
-	assert(type != NULL);
-	assert(name != NULL);
-	assert(func != NULL);
+	assert(type != nullptr);
+	assert(name != nullptr);
+	assert(func != nullptr);
 	assert(sticker_enabled());
 
 	sqlite3_reset(stmt);
 
-	ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 1, type, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	if (base_uri == NULL)
+	if (base_uri == nullptr)
 		base_uri = "";
 
-	ret = sqlite3_bind_text(stmt, 2, base_uri, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 2, base_uri, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
 	}
 
-	ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
+	ret = sqlite3_bind_text(stmt, 3, name, -1, nullptr);
 	if (ret != SQLITE_OK) {
 		LogError(sticker_db, "sqlite3_bind_text() failed");
 		return false;
diff --git a/src/StickerDatabase.hxx b/src/StickerDatabase.hxx
index d5a81d3b1..5b50c6e6f 100644
--- a/src/StickerDatabase.hxx
+++ b/src/StickerDatabase.hxx
@@ -51,10 +51,8 @@ class Path;
 struct sticker;
 
 /**
- * Opens the sticker database (if path is not NULL).
+ * Opens the sticker database.
  *
- * @param error_r location to store the error occurring, or NULL to
- * ignore errors
  * @return true on success, false on error
  */
 bool
@@ -115,7 +113,7 @@ sticker_free(struct sticker *sticker);
  *
  * @param sticker the sticker object
  * @param name the name of the sticker
- * @return the sticker value, or NULL if none was found
+ * @return the sticker value, or nullptr if none was found
  */
 gcc_pure
 const char *
@@ -139,7 +137,7 @@ sticker_foreach(const struct sticker *sticker,
  *
  * @param type the resource type, e.g. "song"
  * @param uri the URI of the resource, e.g. the song path
- * @return a sticker object, or NULL on error or if there is no sticker
+ * @return a sticker object, or nullptr on error or if there is no sticker
  */
 struct sticker *
 sticker_load(const char *type, const char *uri);
@@ -148,7 +146,7 @@ sticker_load(const char *type, const char *uri);
  * Finds stickers with the specified name below the specified URI.
  *
  * @param type the resource type, e.g. "song"
- * @param base_uri the URI prefix of the resources, or NULL if all
+ * @param base_uri the URI prefix of the resources, or nullptr if all
  * resources should be searched
  * @param name the name of the sticker
  * @return true on success (even if no sticker was found), false on
diff --git a/src/TagFile.cxx b/src/TagFile.cxx
index 4f7284903..70a38196c 100644
--- a/src/TagFile.cxx
+++ b/src/TagFile.cxx
@@ -33,21 +33,21 @@ bool
 tag_file_scan(const char *path_fs,
 	      const struct tag_handler *handler, void *handler_ctx)
 {
-	assert(path_fs != NULL);
-	assert(handler != NULL);
+	assert(path_fs != nullptr);
+	assert(handler != nullptr);
 
 	/* check if there's a suffix and a plugin */
 
 	const char *suffix = uri_get_suffix(path_fs);
-	if (suffix == NULL)
+	if (suffix == nullptr)
 		return false;
 
 	const struct decoder_plugin *plugin =
-		decoder_plugin_from_suffix(suffix, NULL);
-	if (plugin == NULL)
+		decoder_plugin_from_suffix(suffix, nullptr);
+	if (plugin == nullptr)
 		return false;
 
-	struct input_stream *is = NULL;
+	struct input_stream *is = nullptr;
 	Mutex mutex;
 	Cond cond;
 
@@ -58,7 +58,7 @@ tag_file_scan(const char *path_fs,
 			break;
 
 		/* fall back to stream tag */
-		if (plugin->scan_stream != NULL) {
+		if (plugin->scan_stream != nullptr) {
 			/* open the input_stream (if not already
 			   open) */
 			if (is == nullptr) {
@@ -68,7 +68,7 @@ tag_file_scan(const char *path_fs,
 			}
 
 			/* now try the stream_tag() method */
-			if (is != NULL) {
+			if (is != nullptr) {
 				if (decoder_plugin_scan_stream(plugin, is,
 							       handler,
 							       handler_ctx))
@@ -79,10 +79,10 @@ tag_file_scan(const char *path_fs,
 		}
 
 		plugin = decoder_plugin_from_suffix(suffix, plugin);
-	} while (plugin != NULL);
+	} while (plugin != nullptr);
 
-	if (is != NULL)
+	if (is != nullptr)
 		is->Close();
 
-	return plugin != NULL;
+	return plugin != nullptr;
 }
diff --git a/src/TextFile.cxx b/src/TextFile.cxx
index 89df6d1bf..4a64ee963 100644
--- a/src/TextFile.cxx
+++ b/src/TextFile.cxx
@@ -45,16 +45,16 @@ TextFile::ReadLine()
 	gsize length = 0, i;
 	char *p;
 
-	assert(file != NULL);
-	assert(buffer != NULL);
+	assert(file != nullptr);
+	assert(buffer != nullptr);
 	assert(buffer->allocated_len >= step);
 
 	while (buffer->len < max_length) {
 		p = fgets(buffer->str + length,
 			  buffer->allocated_len - length, file);
-		if (p == NULL) {
+		if (p == nullptr) {
 			if (length == 0 || ferror(file))
-				return NULL;
+				return nullptr;
 			break;
 		}
 
diff --git a/src/TextFile.hxx b/src/TextFile.hxx
index 4291f2639..9d8608711 100644
--- a/src/TextFile.hxx
+++ b/src/TextFile.hxx
@@ -53,7 +53,7 @@ public:
 	 *
 	 * @param file the source file, opened in text mode
 	 * @param buffer an allocator for the buffer
-	 * @return a pointer to the line, or NULL on end-of-file or error
+	 * @return a pointer to the line, or nullptr on end-of-file or error
 	 */
 	char *ReadLine();
 };
diff --git a/src/TimePrint.cxx b/src/TimePrint.cxx
index 129fa5352..6dd4061e6 100644
--- a/src/TimePrint.cxx
+++ b/src/TimePrint.cxx
@@ -30,7 +30,7 @@ time_print(Client *client, const char *name, time_t t)
 	struct tm tm;
 	const struct tm *tm2 = gmtime_r(&t, &tm);
 #endif
-	if (tm2 == NULL)
+	if (tm2 == nullptr)
 		return;
 
 	char buffer[32];
diff --git a/src/UpdateArchive.cxx b/src/UpdateArchive.cxx
index 730dfe883..f3f4cd65e 100644
--- a/src/UpdateArchive.cxx
+++ b/src/UpdateArchive.cxx
@@ -63,9 +63,9 @@ update_archive_tree(Directory *directory, const char *name)
 		db_lock();
 		Song *song = directory->FindSong(name);
 		db_unlock();
-		if (song == NULL) {
+		if (song == nullptr) {
 			song = Song::LoadFile(name, directory);
-			if (song != NULL) {
+			if (song != nullptr) {
 				db_lock();
 				directory->AddSong(song);
 				db_unlock();
@@ -95,7 +95,7 @@ update_archive_file2(Directory *parent, const char *name,
 	Directory *directory = parent->FindChild(name);
 	db_unlock();
 
-	if (directory != NULL && directory->mtime == st->st_mtime &&
+	if (directory != nullptr && directory->mtime == st->st_mtime &&
 	    !walk_discard)
 		/* MPD has already scanned the archive, and it hasn't
 		   changed since - don't consider updating it */
@@ -106,14 +106,14 @@ update_archive_file2(Directory *parent, const char *name,
 	/* open archive */
 	Error error;
 	ArchiveFile *file = archive_file_open(plugin, path_fs.c_str(), error);
-	if (file == NULL) {
+	if (file == nullptr) {
 		LogError(error);
 		return;
 	}
 
 	FormatDebug(update_domain, "archive %s opened", path_fs.c_str());
 
-	if (directory == NULL) {
+	if (directory == nullptr) {
 		FormatDebug(update_domain,
 			    "creating archive directory: %s", name);
 		db_lock();
@@ -153,7 +153,7 @@ update_archive_file(Directory *directory,
 #ifdef ENABLE_ARCHIVE
 	const struct archive_plugin *plugin =
 		archive_plugin_from_suffix(suffix);
-	if (plugin == NULL)
+	if (plugin == nullptr)
 		return false;
 
 	update_archive_file2(directory, name, st, plugin);
diff --git a/src/UpdateContainer.cxx b/src/UpdateContainer.cxx
index 54328fe14..6e0cadfb7 100644
--- a/src/UpdateContainer.cxx
+++ b/src/UpdateContainer.cxx
@@ -37,7 +37,7 @@
 /**
  * Create the specified directory object if it does not exist already
  * or if the #stat object indicates that it has been modified since
- * the last update.  Returns NULL when it exists already and is
+ * the last update.  Returns nullptr when it exists already and is
  * unmodified.
  *
  * The caller must lock the database.
@@ -49,10 +49,10 @@ make_directory_if_modified(Directory *parent, const char *name,
 	Directory *directory = parent->FindChild(name);
 
 	// directory exists already
-	if (directory != NULL) {
+	if (directory != nullptr) {
 		if (directory->mtime == st->st_mtime && !walk_discard) {
 			/* not modified */
-			return NULL;
+			return nullptr;
 		}
 
 		delete_directory(directory);
@@ -70,12 +70,12 @@ update_container_file(Directory *directory,
 		      const struct stat *st,
 		      const struct decoder_plugin *plugin)
 {
-	if (plugin->container_scan == NULL)
+	if (plugin->container_scan == nullptr)
 		return false;
 
 	db_lock();
 	Directory *contdir = make_directory_if_modified(directory, name, st);
-	if (contdir == NULL) {
+	if (contdir == nullptr) {
 		/* not modified */
 		db_unlock();
 		return true;
@@ -89,7 +89,7 @@ update_container_file(Directory *directory,
 	char *vtrack;
 	unsigned int tnum = 0;
 	TagBuilder tag_builder;
-	while ((vtrack = plugin->container_scan(pathname.c_str(), ++tnum)) != NULL) {
+	while ((vtrack = plugin->container_scan(pathname.c_str(), ++tnum)) != nullptr) {
 		Song *song = Song::NewFile(vtrack, contdir);
 
 		// shouldn't be necessary but it's there..
diff --git a/src/UpdateDatabase.cxx b/src/UpdateDatabase.cxx
index 83bc66876..684976d68 100644
--- a/src/UpdateDatabase.cxx
+++ b/src/UpdateDatabase.cxx
@@ -70,7 +70,7 @@ clear_directory(Directory *directory)
 void
 delete_directory(Directory *directory)
 {
-	assert(directory->parent != NULL);
+	assert(directory->parent != nullptr);
 
 	clear_directory(directory);
 
@@ -85,13 +85,13 @@ delete_name_in(Directory *parent, const char *name)
 	db_lock();
 	Directory *directory = parent->FindChild(name);
 
-	if (directory != NULL) {
+	if (directory != nullptr) {
 		delete_directory(directory);
 		modified = true;
 	}
 
 	Song *song = parent->FindSong(name);
-	if (song != NULL) {
+	if (song != nullptr) {
 		delete_song(parent, song);
 		modified = true;
 	}
diff --git a/src/UpdateRemove.cxx b/src/UpdateRemove.cxx
index 6bccdafcc..bb6f36829 100644
--- a/src/UpdateRemove.cxx
+++ b/src/UpdateRemove.cxx
@@ -50,7 +50,7 @@ static Cond remove_cond;
 static void
 song_remove_event(void)
 {
-	assert(removed_song != NULL);
+	assert(removed_song != nullptr);
 
 	{
 		const auto uri = removed_song->GetURI();
@@ -67,7 +67,7 @@ song_remove_event(void)
 
 	/* clear "removed_song" and send signal to update thread */
 	remove_mutex.lock();
-	removed_song = NULL;
+	removed_song = nullptr;
 	remove_cond.signal();
 	remove_mutex.unlock();
 }
@@ -81,7 +81,7 @@ update_remove_global_init(void)
 void
 update_remove_song(const Song *song)
 {
-	assert(removed_song == NULL);
+	assert(removed_song == nullptr);
 
 	removed_song = song;
 
@@ -89,7 +89,7 @@ update_remove_song(const Song *song)
 
 	remove_mutex.lock();
 
-	while (removed_song != NULL)
+	while (removed_song != nullptr)
 		remove_cond.wait(remove_mutex);
 
 	remove_mutex.unlock();
diff --git a/src/UpdateSong.cxx b/src/UpdateSong.cxx
index 3aef2b560..d8aa80088 100644
--- a/src/UpdateSong.cxx
+++ b/src/UpdateSong.cxx
@@ -46,7 +46,7 @@ update_song_file2(Directory *directory,
 		FormatError(update_domain,
 			    "no read permissions on %s/%s",
 			    directory->GetPath(), name);
-		if (song != NULL) {
+		if (song != nullptr) {
 			db_lock();
 			delete_song(directory, song);
 			db_unlock();
@@ -55,10 +55,10 @@ update_song_file2(Directory *directory,
 		return;
 	}
 
-	if (!(song != NULL && st->st_mtime == song->mtime &&
+	if (!(song != nullptr && st->st_mtime == song->mtime &&
 	      !walk_discard) &&
 	    update_container_file(directory, name, st, plugin)) {
-		if (song != NULL) {
+		if (song != nullptr) {
 			db_lock();
 			delete_song(directory, song);
 			db_unlock();
@@ -67,11 +67,11 @@ update_song_file2(Directory *directory,
 		return;
 	}
 
-	if (song == NULL) {
+	if (song == nullptr) {
 		FormatDebug(update_domain, "reading %s/%s",
 			    directory->GetPath(), name);
 		song = Song::LoadFile(name, directory);
-		if (song == NULL) {
+		if (song == nullptr) {
 			FormatDebug(update_domain,
 				    "ignoring unrecognized file %s/%s",
 				    directory->GetPath(), name);
@@ -108,7 +108,7 @@ update_song_file(Directory *directory,
 {
 	const struct decoder_plugin *plugin =
 		decoder_plugin_from_suffix(suffix, nullptr);
-	if (plugin == NULL)
+	if (plugin == nullptr)
 		return false;
 
 	update_song_file2(directory, name, st, plugin);
diff --git a/src/UpdateWalk.cxx b/src/UpdateWalk.cxx
index 1df41e4e1..acd58f9be 100644
--- a/src/UpdateWalk.cxx
+++ b/src/UpdateWalk.cxx
@@ -222,7 +222,7 @@ update_regular_file(Directory *directory,
 		    const char *name, const struct stat *st)
 {
 	const char *suffix = uri_get_suffix(name);
-	if (suffix == NULL)
+	if (suffix == nullptr)
 		return false;
 
 	return update_song_file(directory, name, suffix, st) ||
@@ -237,7 +237,7 @@ static void
 update_directory_child(Directory *directory,
 		       const char *name, const struct stat *st)
 {
-	assert(strchr(name, '/') == NULL);
+	assert(strchr(name, '/') == nullptr);
 
 	if (S_ISREG(st->st_mode)) {
 		update_regular_file(directory, name, st);
@@ -269,7 +269,7 @@ static bool skip_path(Path path_fs)
 	const char *path = path_fs.c_str();
 	return (path[0] == '.' && path[1] == 0) ||
 		(path[0] == '.' && path[1] == '.' && path[2] == 0) ||
-		strchr(path, '\n') != NULL;
+		strchr(path, '\n') != nullptr;
 }
 
 gcc_pure
@@ -310,7 +310,7 @@ skip_symlink(const Directory *directory, const char *utf8_name)
 		if (p[1] == '.' && PathTraits::IsSeparatorFS(p[2])) {
 			/* "../" moves to parent directory */
 			directory = directory->parent;
-			if (directory == NULL) {
+			if (directory == nullptr) {
 				/* we have moved outside the music
 				   directory - skip this symlink
 				   if such symlinks are not allowed */
@@ -403,16 +403,16 @@ directory_make_child_checked(Directory *parent, const char *name_utf8)
 	Directory *directory = parent->FindChild(name_utf8);
 	db_unlock();
 
-	if (directory != NULL)
+	if (directory != nullptr)
 		return directory;
 
 	struct stat st;
 	if (stat_directory_child(parent, name_utf8, &st) < 0 ||
 	    find_inode_ancestor(parent, st.st_ino, st.st_dev))
-		return NULL;
+		return nullptr;
 
 	if (skip_symlink(parent, name_utf8))
-		return NULL;
+		return nullptr;
 
 	/* if we're adding directory paths, make sure to delete filenames
 	   with potentially the same name */
@@ -435,14 +435,14 @@ directory_make_uri_parent_checked(const char *uri)
 	char *duplicated = g_strdup(uri);
 	char *name_utf8 = duplicated, *slash;
 
-	while ((slash = strchr(name_utf8, '/')) != NULL) {
+	while ((slash = strchr(name_utf8, '/')) != nullptr) {
 		*slash = 0;
 
 		if (*name_utf8 == 0)
 			continue;
 
 		directory = directory_make_child_checked(directory, name_utf8);
-		if (directory == NULL)
+		if (directory == nullptr)
 			break;
 
 		name_utf8 = slash + 1;
@@ -456,7 +456,7 @@ static void
 update_uri(const char *uri)
 {
 	Directory *parent = directory_make_uri_parent_checked(uri);
-	if (parent == NULL)
+	if (parent == nullptr)
 		return;
 
 	char *name = g_path_get_basename(uri);
@@ -477,7 +477,7 @@ update_walk(const char *path, bool discard)
 	walk_discard = discard;
 	modified = false;
 
-	if (path != NULL && !isRootDirectory(path)) {
+	if (path != nullptr && !isRootDirectory(path)) {
 		update_uri(path);
 	} else {
 		Directory *directory = db_get_root();
diff --git a/src/Volume.cxx b/src/Volume.cxx
index b23b9688f..6c5f8dc4d 100644
--- a/src/Volume.cxx
+++ b/src/Volume.cxx
@@ -68,10 +68,10 @@ void volume_init(void)
 
 int volume_level_get(void)
 {
-	assert(hardware_volume_timer != NULL);
+	assert(hardware_volume_timer != nullptr);
 
 	if (last_hardware_volume >= 0 &&
-	    g_timer_elapsed(hardware_volume_timer, NULL) < 1.0)
+	    g_timer_elapsed(hardware_volume_timer, nullptr) < 1.0)
 		/* throttle access to hardware mixers */
 		return last_hardware_volume;
 
@@ -112,7 +112,7 @@ bool volume_level_change(unsigned volume)
 bool
 read_sw_volume_state(const char *line)
 {
-	char *end = NULL;
+	char *end = nullptr;
 	long int sv;
 
 	if (!g_str_has_prefix(line, SW_VOLUME_STATE))
diff --git a/src/Win32Main.cxx b/src/Win32Main.cxx
index 3e5ee67cd..02dc02896 100644
--- a/src/Win32Main.cxx
+++ b/src/Win32Main.cxx
@@ -44,7 +44,7 @@ service_main(DWORD argc, CHAR *argv[]);
 
 static SERVICE_TABLE_ENTRY service_registry[] = {
 	{service_name, service_main},
-	{NULL, NULL}
+	{nullptr, nullptr}
 };
 
 static void
@@ -87,7 +87,7 @@ service_main(gcc_unused DWORD argc, gcc_unused CHAR *argv[])
 
 	service_handle =
 		RegisterServiceCtrlHandlerEx(service_name,
-					     service_dispatcher, NULL);
+					     service_dispatcher, nullptr);
 
 	if (service_handle == 0) {
 		error_code = GetLastError();
diff --git a/src/ZeroconfAvahi.cxx b/src/ZeroconfAvahi.cxx
index 7a8954a56..7e044c030 100644
--- a/src/ZeroconfAvahi.cxx
+++ b/src/ZeroconfAvahi.cxx
@@ -109,7 +109,7 @@ static void avahiRegisterService(AvahiClient * c)
 	/* If this is the first time we're called,
 	 * let's create a new entry group */
 	if (!avahiGroup) {
-		avahiGroup = avahi_entry_group_new(c, avahiGroupCallback, NULL);
+		avahiGroup = avahi_entry_group_new(c, avahiGroupCallback, nullptr);
 		if (!avahiGroup) {
 			FormatError(avahi_domain,
 				    "Failed to create avahi EntryGroup: %s",
@@ -125,8 +125,8 @@ static void avahiRegisterService(AvahiClient * c)
 	ret = avahi_entry_group_add_service(avahiGroup,
 					    AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
 					    AvahiPublishFlags(0),
-					    avahiName, SERVICE_TYPE, NULL,
-					    NULL, listen_port, NULL);
+					    avahiName, SERVICE_TYPE, nullptr,
+					    nullptr, listen_port, nullptr);
 	if (ret < 0) {
 		FormatError(avahi_domain, "Failed to add service %s: %s",
 			    SERVICE_TYPE, avahi_strerror(ret));
@@ -173,14 +173,14 @@ static void avahiClientCallback(AvahiClient * c, AvahiClientState state,
 				"Client Disconnected, will reconnect shortly");
 			if (avahiGroup) {
 				avahi_entry_group_free(avahiGroup);
-				avahiGroup = NULL;
+				avahiGroup = nullptr;
 			}
 			if (avahiClient)
 				avahi_client_free(avahiClient);
 			avahiClient =
 			    avahi_client_new(avahi_poll,
 					     AVAHI_CLIENT_NO_FAIL,
-					     avahiClientCallback, NULL,
+					     avahiClientCallback, nullptr,
 					     &reason);
 			if (!avahiClient) {
 				FormatWarning(avahi_domain,
@@ -246,7 +246,7 @@ AvahiInit(EventLoop &loop, const char *serviceName)
 
 	int error;
 	avahiClient = avahi_client_new(avahi_poll, AVAHI_CLIENT_NO_FAIL,
-				       avahiClientCallback, NULL, &error);
+				       avahiClientCallback, nullptr, &error);
 
 	if (!avahiClient) {
 		FormatError(avahi_domain, "Failed to create client: %s",
@@ -262,17 +262,17 @@ AvahiDeinit(void)
 
 	if (avahiGroup) {
 		avahi_entry_group_free(avahiGroup);
-		avahiGroup = NULL;
+		avahiGroup = nullptr;
 	}
 
 	if (avahiClient) {
 		avahi_client_free(avahiClient);
-		avahiClient = NULL;
+		avahiClient = nullptr;
 	}
 
 	delete avahi_poll;
 	avahi_poll = nullptr;
 
 	avahi_free(avahiName);
-	avahiName = NULL;
+	avahiName = nullptr;
 }
diff --git a/src/ZeroconfBonjour.cxx b/src/ZeroconfBonjour.cxx
index 4c3efe5b5..73e84fbc2 100644
--- a/src/ZeroconfBonjour.cxx
+++ b/src/ZeroconfBonjour.cxx
@@ -82,11 +82,11 @@ BonjourInit(EventLoop &loop, const char *service_name)
 	DNSServiceRef dnsReference;
 	DNSServiceErrorType error = DNSServiceRegister(&dnsReference,
 						       0, 0, service_name,
-						       SERVICE_TYPE, NULL, NULL,
+						       SERVICE_TYPE, nullptr, nullptr,
 						       g_htons(listen_port), 0,
-						       NULL,
+						       nullptr,
 						       dnsRegisterCallback,
-						       NULL);
+						       nullptr);
 
 	if (error != kDNSServiceErr_NoError) {
 		LogError(bonjour_domain,
@@ -94,7 +94,7 @@ BonjourInit(EventLoop &loop, const char *service_name)
 
 		if (dnsReference) {
 			DNSServiceRefDeallocate(dnsReference);
-			dnsReference = NULL;
+			dnsReference = nullptr;
 		}
 		return;
 	}
diff --git a/src/archive/Bzip2ArchivePlugin.cxx b/src/archive/Bzip2ArchivePlugin.cxx
index 61e31a671..6c5bba8be 100644
--- a/src/archive/Bzip2ArchivePlugin.cxx
+++ b/src/archive/Bzip2ArchivePlugin.cxx
@@ -185,7 +185,7 @@ Bzip2ArchiveFile::OpenStream(const char *path,
 	Bzip2InputStream *bis = new Bzip2InputStream(*this, path, mutex, cond);
 	if (!bis->Open(error)) {
 		delete bis;
-		return NULL;
+		return nullptr;
 	}
 
 	return &bis->base;
@@ -273,7 +273,7 @@ bz2_is_eof(struct input_stream *is)
 
 static const char *const bz2_extensions[] = {
 	"bz2",
-	NULL
+	nullptr
 };
 
 const InputPlugin bz2_inputplugin = {
diff --git a/src/archive/Iso9660ArchivePlugin.cxx b/src/archive/Iso9660ArchivePlugin.cxx
index 4359256e5..1cfac3a43 100644
--- a/src/archive/Iso9660ArchivePlugin.cxx
+++ b/src/archive/Iso9660ArchivePlugin.cxx
@@ -118,7 +118,7 @@ iso9660_archive_open(const char *pathname, Error &error)
 	if (iso == nullptr) {
 		error.Format(iso9660_domain,
 			     "Failed to open ISO9660 file %s", pathname);
-		return NULL;
+		return nullptr;
 	}
 
 	return new Iso9660ArchiveFile(iso);
@@ -168,7 +168,7 @@ Iso9660ArchiveFile::OpenStream(const char *pathname,
 	if (statbuf == nullptr) {
 		error.Format(iso9660_domain,
 			     "not found in the ISO file: %s", pathname);
-		return NULL;
+		return nullptr;
 	}
 
 	Iso9660InputStream *iis =
@@ -236,7 +236,7 @@ iso9660_input_eof(struct input_stream *is)
 
 static const char *const iso9660_archive_extensions[] = {
 	"iso",
-	NULL
+	nullptr
 };
 
 const InputPlugin iso9660_input_plugin = {
diff --git a/src/archive/ZzipArchivePlugin.cxx b/src/archive/ZzipArchivePlugin.cxx
index 35730d078..436afc417 100644
--- a/src/archive/ZzipArchivePlugin.cxx
+++ b/src/archive/ZzipArchivePlugin.cxx
@@ -75,11 +75,11 @@ static constexpr Domain zzip_domain("zzip");
 static ArchiveFile *
 zzip_archive_open(const char *pathname, Error &error)
 {
-	ZZIP_DIR *dir = zzip_dir_open(pathname, NULL);
+	ZZIP_DIR *dir = zzip_dir_open(pathname, nullptr);
 	if (dir == nullptr) {
 		error.Format(zzip_domain, "Failed to open ZIP file %s",
 			     pathname);
-		return NULL;
+		return nullptr;
 	}
 
 	return new ZzipArchiveFile(dir);
@@ -137,7 +137,7 @@ ZzipArchiveFile::OpenStream(const char *pathname,
 	if (_file == nullptr) {
 		error.Format(zzip_domain, "not found in the ZIP file: %s",
 			     pathname);
-		return NULL;
+		return nullptr;
 	}
 
 	ZzipInputStream *zis =
@@ -199,7 +199,7 @@ zzip_input_seek(struct input_stream *is, InputPlugin::offset_type offset,
 
 static const char *const zzip_archive_extensions[] = {
 	"zip",
-	NULL
+	nullptr
 };
 
 const InputPlugin zzip_input_plugin = {
diff --git a/src/db/SimpleDatabasePlugin.cxx b/src/db/SimpleDatabasePlugin.cxx
index 567c62b6f..8f2571878 100644
--- a/src/db/SimpleDatabasePlugin.cxx
+++ b/src/db/SimpleDatabasePlugin.cxx
@@ -44,7 +44,7 @@ SimpleDatabase::Create(const config_param &param, Error &error)
 	SimpleDatabase *db = new SimpleDatabase();
 	if (!db->Configure(param, error)) {
 		delete db;
-		db = NULL;
+		db = nullptr;
 	}
 
 	return db;
@@ -136,7 +136,7 @@ bool
 SimpleDatabase::Load(Error &error)
 {
 	assert(!path.IsNull());
-	assert(root != NULL);
+	assert(root != nullptr);
 
 	TextFile file(path);
 	if (file.HasFailed()) {
@@ -183,7 +183,7 @@ SimpleDatabase::Open(Error &error)
 void
 SimpleDatabase::Close()
 {
-	assert(root != NULL);
+	assert(root != nullptr);
 	assert(borrowed_song_count == 0);
 
 	root->Free();
@@ -192,12 +192,12 @@ SimpleDatabase::Close()
 Song *
 SimpleDatabase::GetSong(const char *uri, Error &error) const
 {
-	assert(root != NULL);
+	assert(root != nullptr);
 
 	db_lock();
 	Song *song = root->LookupSong(uri);
 	db_unlock();
-	if (song == NULL)
+	if (song == nullptr)
 		error.Format(db_domain, DB_NOT_FOUND,
 			     "No such song: %s", uri);
 #ifndef NDEBUG
@@ -223,8 +223,8 @@ gcc_pure
 const Directory *
 SimpleDatabase::LookupDirectory(const char *uri) const
 {
-	assert(root != NULL);
-	assert(uri != NULL);
+	assert(root != nullptr);
+	assert(uri != nullptr);
 
 	ScopeDatabaseLock protect;
 	return root->LookupDirectory(uri);
@@ -240,7 +240,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
 	ScopeDatabaseLock protect;
 
 	const Directory *directory = root->LookupDirectory(selection.uri);
-	if (directory == NULL) {
+	if (directory == nullptr) {
 		if (visit_song) {
 			Song *song = root->LookupSong(selection.uri);
 			if (song != nullptr)
diff --git a/src/decoder/FfmpegDecoderPlugin.cxx b/src/decoder/FfmpegDecoderPlugin.cxx
index 5ad01c675..a93b5cc70 100644
--- a/src/decoder/FfmpegDecoderPlugin.cxx
+++ b/src/decoder/FfmpegDecoderPlugin.cxx
@@ -76,12 +76,12 @@ static void
 mpd_ffmpeg_log_callback(gcc_unused void *ptr, int level,
 			const char *fmt, va_list vl)
 {
-	const AVClass * cls = NULL;
+	const AVClass * cls = nullptr;
 
-	if (ptr != NULL)
+	if (ptr != nullptr)
 		cls = *(const AVClass *const*)ptr;
 
-	if (cls != NULL) {
+	if (cls != nullptr) {
 		char domain[64];
 		snprintf(domain, sizeof(domain), "%s/%s",
 			 ffmpeg_domain.GetName(), cls->item_name(ptr));
@@ -155,12 +155,12 @@ mpd_ffmpeg_open_input(AVFormatContext **ic_ptr,
 		      AVInputFormat *fmt)
 {
 	AVFormatContext *context = avformat_alloc_context();
-	if (context == NULL)
+	if (context == nullptr)
 		return AVERROR(ENOMEM);
 
 	context->pb = pb;
 	*ic_ptr = context;
-	return avformat_open_input(ic_ptr, filename, fmt, NULL);
+	return avformat_open_input(ic_ptr, filename, fmt, nullptr);
 }
 
 static bool
@@ -329,7 +329,7 @@ ffmpeg_sample_format(enum AVSampleFormat sample_fmt)
 	char buffer[64];
 	const char *name = av_get_sample_fmt_string(buffer, sizeof(buffer),
 						    sample_fmt);
-	if (name != NULL)
+	if (name != nullptr)
 		FormatError(ffmpeg_domain,
 			    "Unsupported libavcodec SampleFormat value: %s (%d)",
 			    name, sample_fmt);
@@ -373,7 +373,7 @@ static void
 ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
 {
 	AVInputFormat *input_format = ffmpeg_probe(decoder, input);
-	if (input_format == NULL)
+	if (input_format == nullptr)
 		return;
 
 	FormatDebug(ffmpeg_domain, "detected input format '%s' (%s)",
@@ -386,7 +386,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
 	}
 
 	//ffmpeg works with ours "fileops" helper
-	AVFormatContext *format_context = NULL;
+	AVFormatContext *format_context = nullptr;
 	if (mpd_ffmpeg_open_input(&format_context, stream.io,
 				  input->uri.c_str(),
 				  input_format) != 0) {
@@ -395,7 +395,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
 	}
 
 	const int find_result =
-		avformat_find_stream_info(format_context, NULL);
+		avformat_find_stream_info(format_context, nullptr);
 	if (find_result < 0) {
 		LogError(ffmpeg_domain, "Couldn't find stream info");
 		avformat_close_input(&format_context);
@@ -445,7 +445,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
 	   values into AVCodecContext.channels - a change that will be
 	   reverted later by avcodec_decode_audio3() */
 
-	const int open_result = avcodec_open2(codec_context, codec, NULL);
+	const int open_result = avcodec_open2(codec_context, codec, nullptr);
 	if (open_result < 0) {
 		LogError(ffmpeg_domain, "Could not open codec");
 		avformat_close_input(&format_context);
@@ -466,7 +466,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
 		return;
 	}
 
-	uint8_t *interleaved_buffer = NULL;
+	uint8_t *interleaved_buffer = nullptr;
 	int interleaved_buffer_size = 0;
 
 	DecoderCommand cmd;
@@ -518,21 +518,21 @@ static bool
 ffmpeg_scan_stream(struct input_stream *is,
 		   const struct tag_handler *handler, void *handler_ctx)
 {
-	AVInputFormat *input_format = ffmpeg_probe(NULL, is);
-	if (input_format == NULL)
+	AVInputFormat *input_format = ffmpeg_probe(nullptr, is);
+	if (input_format == nullptr)
 		return false;
 
 	AvioStream stream(nullptr, is);
 	if (!stream.Open())
 		return false;
 
-	AVFormatContext *f = NULL;
+	AVFormatContext *f = nullptr;
 	if (mpd_ffmpeg_open_input(&f, stream.io, is->uri.c_str(),
 				  input_format) != 0)
 		return false;
 
 	const int find_result =
-		avformat_find_stream_info(f, NULL);
+		avformat_find_stream_info(f, nullptr);
 	if (find_result < 0) {
 		avformat_close_input(&f);
 		return false;
@@ -576,7 +576,7 @@ static const char *const ffmpeg_suffixes[] = {
 	"tsp", "tta", "xa", "xvid", "uv", "uv2", "vb", "vid", "vob", "voc",
 	"vp6", "vmd", "wav", "webm", "wma", "wmv", "wsaud", "wsvga", "wv",
 	"wve",
-	NULL
+	nullptr
 };
 
 static const char *const ffmpeg_mime_types[] = {
@@ -664,7 +664,7 @@ static const char *const ffmpeg_mime_types[] = {
 	   plugin */
 	"audio/x-mpd-ffmpeg",
 
-	NULL
+	nullptr
 };
 
 const struct decoder_plugin ffmpeg_decoder_plugin = {
diff --git a/src/decoder/WavpackDecoderPlugin.cxx b/src/decoder/WavpackDecoderPlugin.cxx
index 8c6d9f927..56b6efc51 100644
--- a/src/decoder/WavpackDecoderPlugin.cxx
+++ b/src/decoder/WavpackDecoderPlugin.cxx
@@ -206,7 +206,7 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
 		format_samples(bytes_per_sample, chunk,
 			       samples_got * audio_format.channels);
 
-		cmd = decoder_data(decoder, NULL, chunk,
+		cmd = decoder_data(decoder, nullptr, chunk,
 				   samples_got * output_sample_size,
 				   bitrate);
 	}
@@ -295,7 +295,7 @@ wavpack_scan_file(const char *fname,
 	char error[ERRORLEN];
 
 	wpc = WavpackOpenFileInput(fname, error, OPEN_TAGS, 0);
-	if (wpc == NULL) {
+	if (wpc == nullptr) {
 		FormatError(wavpack_domain,
 			    "failed to open WavPack file \"%s\": %s",
 			    fname, error);
@@ -311,16 +311,16 @@ wavpack_scan_file(const char *fname,
 
 	for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) {
 		const char *name = tag_item_names[i];
-		if (name != NULL)
+		if (name != nullptr)
 			wavpack_scan_tag_item(wpc, name, (enum tag_type)i,
 					      handler, handler_ctx);
 	}
 
-	for (const struct tag_table *i = ape_tags; i->name != NULL; ++i)
+	for (const struct tag_table *i = ape_tags; i->name != nullptr; ++i)
 		wavpack_scan_tag_item(wpc, i->name, i->type,
 				      handler, handler_ctx);
 
-	if (handler->pair != NULL) {
+	if (handler->pair != nullptr) {
 		char name[64];
 
 		for (int i = 0, n = WavpackGetNumTagItems(wpc);
@@ -463,7 +463,7 @@ wavpack_open_wvc(struct decoder *decoder, const char *uri,
 		 struct wavpack_input *wpi)
 {
 	struct input_stream *is_wvc;
-	char *wvc_url = NULL;
+	char *wvc_url = nullptr;
 	char first_byte;
 	size_t nbytes;
 
@@ -471,16 +471,16 @@ wavpack_open_wvc(struct decoder *decoder, const char *uri,
 	 * As we use dc->utf8url, this function will be bad for
 	 * single files. utf8url is not absolute file path :/
 	 */
-	if (uri == NULL)
+	if (uri == nullptr)
 		return nullptr;
 
-	wvc_url = g_strconcat(uri, "c", NULL);
+	wvc_url = g_strconcat(uri, "c", nullptr);
 
 	is_wvc = input_stream::Open(wvc_url, mutex, cond, IgnoreError());
 	g_free(wvc_url);
 
-	if (is_wvc == NULL)
-		return NULL;
+	if (is_wvc == nullptr)
+		return nullptr;
 
 	/*
 	 * And we try to buffer in order to get know
@@ -491,7 +491,7 @@ wavpack_open_wvc(struct decoder *decoder, const char *uri,
 	);
 	if (nbytes == 0) {
 		is_wvc->Close();
-		return NULL;
+		return nullptr;
 	}
 
 	/* push it back */
@@ -516,7 +516,7 @@ wavpack_streamdecode(struct decoder * decoder, struct input_stream *is)
 	is_wvc = wavpack_open_wvc(decoder, is->uri.c_str(),
 				  is->mutex, is->cond,
 				  &isp_wvc);
-	if (is_wvc != NULL) {
+	if (is_wvc != nullptr) {
 		open_flags |= OPEN_WVC;
 		can_seek &= is_wvc->seekable;
 	}
@@ -528,11 +528,11 @@ wavpack_streamdecode(struct decoder * decoder, struct input_stream *is)
 	wavpack_input_init(&isp, decoder, is);
 	wpc = WavpackOpenFileInputEx(
 		&mpd_is_reader, &isp,
-		open_flags & OPEN_WVC ? &isp_wvc : NULL,
+		open_flags & OPEN_WVC ? &isp_wvc : nullptr,
 		error, open_flags, 23
 	);
 
-	if (wpc == NULL) {
+	if (wpc == nullptr) {
 		FormatError(wavpack_domain,
 			    "failed to open WavPack stream: %s", error);
 		return;
@@ -559,7 +559,7 @@ wavpack_filedecode(struct decoder *decoder, const char *fname)
 		fname, error,
 		OPEN_TAGS | OPEN_WVC | OPEN_NORMALIZE, 23
 	);
-	if (wpc == NULL) {
+	if (wpc == nullptr) {
 		FormatWarning(wavpack_domain,
 			      "failed to open WavPack file \"%s\": %s",
 			      fname, error);
@@ -577,12 +577,12 @@ wavpack_filedecode(struct decoder *decoder, const char *fname)
 
 static char const *const wavpack_suffixes[] = {
 	"wv",
-	NULL
+	nullptr
 };
 
 static char const *const wavpack_mime_types[] = {
 	"audio/x-wavpack",
-	NULL
+	nullptr
 };
 
 const struct decoder_plugin wavpack_decoder_plugin = {
diff --git a/src/decoder/sidplay_decoder_plugin.cxx b/src/decoder/sidplay_decoder_plugin.cxx
index 7d6ee91ac..3dbede9b5 100644
--- a/src/decoder/sidplay_decoder_plugin.cxx
+++ b/src/decoder/sidplay_decoder_plugin.cxx
@@ -49,7 +49,7 @@ static bool filter_setting;
 static GKeyFile *
 sidplay_load_songlength_db(const char *path)
 {
-	GError *error = NULL;
+	GError *error = nullptr;
 	gchar *data;
 	gsize size;
 
@@ -58,7 +58,7 @@ sidplay_load_songlength_db(const char *path)
 			    "unable to read songlengths file %s: %s",
 			    path, error->message);
 		g_error_free(error);
-		return NULL;
+		return nullptr;
 	}
 
 	/* replace any ; comment characters with # */
@@ -76,7 +76,7 @@ sidplay_load_songlength_db(const char *path)
 			    path, error->message);
 		g_error_free(error);
 		g_key_file_free(db);
-		return NULL;
+		return nullptr;
 	}
 
 	g_key_file_set_list_separator(db, ' ');
@@ -88,7 +88,7 @@ sidplay_init(const config_param &param)
 {
 	/* read the songlengths database file */
 	songlength_file = param.GetBlockValue("songlength_database");
-	if (songlength_file != NULL)
+	if (songlength_file != nullptr)
 		songlength_database = sidplay_load_songlength_db(songlength_file);
 
 	default_songlength = param.GetBlockValue("default_songlength", 0u);
@@ -123,7 +123,7 @@ get_container_name(const char *path_fs)
 	char *path_container=g_strdup(path_fs);
 
 	if(!g_pattern_match(path_with_subtune,
-		strlen(path_container), path_container, NULL))
+		strlen(path_container), path_container, nullptr))
 		return path_container;
 
 	char *ptr=g_strrstr(path_container, "/" SUBTUNE_PREFIX);
@@ -140,12 +140,12 @@ static unsigned
 get_song_num(const char *path_fs)
 {
 	if(g_pattern_match(path_with_subtune,
-		strlen(path_fs), path_fs, NULL)) {
+		strlen(path_fs), path_fs, nullptr)) {
 		char *sub=g_strrstr(path_fs, "/" SUBTUNE_PREFIX);
 		if(!sub) return 1;
 
 		sub+=strlen("/" SUBTUNE_PREFIX);
-		int song_num=strtol(sub, NULL, 10);
+		int song_num=strtol(sub, nullptr, 10);
 
 		if (errno == EINVAL)
 			return 1;
@@ -159,7 +159,7 @@ get_song_num(const char *path_fs)
 static int
 get_song_length(const char *path_fs)
 {
-	if (songlength_database == NULL)
+	if (songlength_database == nullptr)
 		return -1;
 
 	gchar *sid_file=get_container_name(path_fs);
@@ -177,19 +177,19 @@ get_song_length(const char *path_fs)
 
 	gsize num_items;
 	gchar **values=g_key_file_get_string_list(songlength_database,
-		"Database", md5sum, &num_items, NULL);
+		"Database", md5sum, &num_items, nullptr);
 	if(!values || song_num>num_items) {
 		g_strfreev(values);
 		return -1;
 	}
 
-	int minutes=strtol(values[song_num-1], NULL, 10);
+	int minutes=strtol(values[song_num-1], nullptr, 10);
 	if(errno==EINVAL) minutes=0;
 
 	int seconds;
 	char *ptr=strchr(values[song_num-1], ':');
 	if(ptr) {
-		seconds=strtol(ptr+1, NULL, 10);
+		seconds=strtol(ptr+1, nullptr, 10);
 		if(errno==EINVAL) seconds=0;
 	} else
 		seconds=0;
@@ -207,7 +207,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
 	/* load the tune */
 
 	char *path_container=get_container_name(path_fs);
-	SidTune tune(path_container, NULL, true);
+	SidTune tune(path_container, nullptr, true);
 	g_free(path_container);
 	if (!tune) {
 		LogWarning(sidplay_domain, "failed to load file");
@@ -307,7 +307,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
 
 		decoder_timestamp(decoder, (double)player.time() / timebase);
 
-		cmd = decoder_data(decoder, NULL, buffer, nbytes, 0);
+		cmd = decoder_data(decoder, nullptr, buffer, nbytes, 0);
 
 		if (cmd == DecoderCommand::SEEK) {
 			unsigned data_time = player.time();
@@ -344,7 +344,7 @@ sidplay_scan_file(const char *path_fs,
 	int song_num=get_song_num(path_fs);
 	char *path_container=get_container_name(path_fs);
 
-	SidTune tune(path_container, NULL, true);
+	SidTune tune(path_container, nullptr, true);
 	g_free(path_container);
 	if (!tune)
 		return false;
@@ -353,7 +353,7 @@ sidplay_scan_file(const char *path_fs,
 
 	/* title */
 	const char *title;
-	if (info.numberOfInfoStrings > 0 && info.infoString[0] != NULL)
+	if (info.numberOfInfoStrings > 0 && info.infoString[0] != nullptr)
 		title=info.infoString[0];
 	else
 		title="";
@@ -369,7 +369,7 @@ sidplay_scan_file(const char *path_fs,
 		tag_handler_invoke_tag(handler, handler_ctx, TAG_TITLE, title);
 
 	/* artist */
-	if (info.numberOfInfoStrings > 1 && info.infoString[1] != NULL)
+	if (info.numberOfInfoStrings > 1 && info.infoString[1] != nullptr)
 		tag_handler_invoke_tag(handler, handler_ctx, TAG_ARTIST,
 				       info.infoString[1]);
 
@@ -389,16 +389,16 @@ sidplay_scan_file(const char *path_fs,
 static char *
 sidplay_container_scan(const char *path_fs, const unsigned int tnum)
 {
-	SidTune tune(path_fs, NULL, true);
+	SidTune tune(path_fs, nullptr, true);
 	if (!tune)
-		return NULL;
+		return nullptr;
 
 	const SidTuneInfo &info=tune.getInfo();
 
 	/* Don't treat sids containing a single tune
 		as containers */
 	if(!all_files_are_containers && info.songs<2)
-		return NULL;
+		return nullptr;
 
 	/* Construct container/tune path names, eg.
 		Delta.sid/tune_001.sid */
@@ -407,7 +407,7 @@ sidplay_container_scan(const char *path_fs, const unsigned int tnum)
 			SUBTUNE_PREFIX "%03u.sid", tnum);
 		return subtune;
 	} else
-		return NULL;
+		return nullptr;
 }
 
 static const char *const sidplay_suffixes[] = {
@@ -416,7 +416,7 @@ static const char *const sidplay_suffixes[] = {
 	"str",
 	"prg",
 	"P00",
-	NULL
+	nullptr
 };
 
 extern const struct decoder_plugin sidplay_decoder_plugin;
@@ -424,11 +424,11 @@ const struct decoder_plugin sidplay_decoder_plugin = {
 	"sidplay",
 	sidplay_init,
 	sidplay_finish,
-	NULL, /* stream_decode() */
+	nullptr, /* stream_decode() */
 	sidplay_file_decode,
 	sidplay_scan_file,
-	NULL, /* stream_tag() */
+	nullptr, /* stream_tag() */
 	sidplay_container_scan,
 	sidplay_suffixes,
-	NULL, /* mime_types */
+	nullptr, /* mime_types */
 };
diff --git a/src/input/CurlInputPlugin.cxx b/src/input/CurlInputPlugin.cxx
index d5e8a0038..da1dec5bd 100644
--- a/src/input/CurlInputPlugin.cxx
+++ b/src/input/CurlInputPlugin.cxx
@@ -232,7 +232,7 @@ input_curl_find_request(CURL *easy)
 		if (c->easy == easy)
 			return c;
 
-	return NULL;
+	return nullptr;
 }
 
 static void
@@ -323,9 +323,9 @@ static bool
 input_curl_easy_add(struct input_curl *c, Error &error)
 {
 	assert(io_thread_inside());
-	assert(c != NULL);
-	assert(c->easy != NULL);
-	assert(input_curl_find_request(c->easy) == NULL);
+	assert(c != nullptr);
+	assert(c->easy != nullptr);
+	assert(input_curl_find_request(c->easy) == nullptr);
 
 	curl.requests.push_front(c);
 
@@ -349,8 +349,8 @@ input_curl_easy_add(struct input_curl *c, Error &error)
 static bool
 input_curl_easy_add_indirect(struct input_curl *c, Error &error)
 {
-	assert(c != NULL);
-	assert(c->easy != NULL);
+	assert(c != nullptr);
+	assert(c->easy != nullptr);
 
 	bool result;
 	BlockingCall(io_thread_get(), [c, &error, &result](){
@@ -369,19 +369,19 @@ static void
 input_curl_easy_free(struct input_curl *c)
 {
 	assert(io_thread_inside());
-	assert(c != NULL);
+	assert(c != nullptr);
 
-	if (c->easy == NULL)
+	if (c->easy == nullptr)
 		return;
 
 	curl.requests.remove(c);
 
 	curl_multi_remove_handle(curl.multi, c->easy);
 	curl_easy_cleanup(c->easy);
-	c->easy = NULL;
+	c->easy = nullptr;
 
 	curl_slist_free_all(c->request_headers);
-	c->request_headers = NULL;
+	c->request_headers = nullptr;
 }
 
 /**
@@ -398,7 +398,7 @@ input_curl_easy_free_indirect(struct input_curl *c)
 			curl.sockets->InvalidateSockets();
 		});
 
-	assert(c->easy == NULL);
+	assert(c->easy == nullptr);
 }
 
 /**
@@ -437,8 +437,8 @@ static void
 input_curl_request_done(struct input_curl *c, CURLcode result, long status)
 {
 	assert(io_thread_inside());
-	assert(c != NULL);
-	assert(c->easy == NULL);
+	assert(c != nullptr);
+	assert(c->easy == nullptr);
 	assert(!c->postponed_error.IsDefined());
 
 	const ScopeLock protect(c->base.mutex);
@@ -461,7 +461,7 @@ static void
 input_curl_handle_done(CURL *easy_handle, CURLcode result)
 {
 	struct input_curl *c = input_curl_find_request(easy_handle);
-	assert(c != NULL);
+	assert(c != nullptr);
 
 	long status = 0;
 	curl_easy_getinfo(easy_handle, CURLINFO_RESPONSE_CODE, &status);
@@ -484,7 +484,7 @@ input_curl_info_read(void)
 	int msgs_in_queue;
 
 	while ((msg = curl_multi_info_read(curl.multi,
-					   &msgs_in_queue)) != NULL) {
+					   &msgs_in_queue)) != nullptr) {
 		if (msg->msg == CURLMSG_DONE)
 			input_curl_handle_done(msg->easy_handle, msg->data.result);
 	}
@@ -573,17 +573,17 @@ input_curl_init(const config_param &param, Error &error)
 	proxy_user = param.GetBlockValue("proxy_user");
 	proxy_password = param.GetBlockValue("proxy_password");
 
-	if (proxy == NULL) {
+	if (proxy == nullptr) {
 		/* deprecated proxy configuration */
-		proxy = config_get_string(CONF_HTTP_PROXY_HOST, NULL);
+		proxy = config_get_string(CONF_HTTP_PROXY_HOST, nullptr);
 		proxy_port = config_get_positive(CONF_HTTP_PROXY_PORT, 0);
-		proxy_user = config_get_string(CONF_HTTP_PROXY_USER, NULL);
+		proxy_user = config_get_string(CONF_HTTP_PROXY_USER, nullptr);
 		proxy_password = config_get_string(CONF_HTTP_PROXY_PASSWORD,
 						   "");
 	}
 
 	curl.multi = curl_multi_init();
-	if (curl.multi == NULL) {
+	if (curl.multi == nullptr) {
 		error.Set(curl_domain, 0, "curl_multi_init() failed");
 		return false;
 	}
@@ -654,14 +654,14 @@ input_curl_tag(struct input_stream *is)
 	struct input_curl *c = (struct input_curl *)is;
 	Tag *tag = c->tag;
 
-	c->tag = NULL;
+	c->tag = nullptr;
 	return tag;
 }
 
 static bool
 fill_buffer(struct input_curl *c, Error &error)
 {
-	while (c->easy != NULL && c->buffers.empty())
+	while (c->easy != nullptr && c->buffers.empty())
 		c->base.cond.wait(c->base.mutex);
 
 	if (c->postponed_error.IsDefined()) {
@@ -728,7 +728,7 @@ copy_icy_tag(struct input_curl *c)
 {
 	Tag *tag = c->icy.ReadTag();
 
-	if (tag == NULL)
+	if (tag == nullptr)
 		return;
 
 	delete c->tag;
@@ -744,7 +744,7 @@ input_curl_available(struct input_stream *is)
 {
 	struct input_curl *c = (struct input_curl *)is;
 
-	return c->postponed_error.IsDefined() || c->easy == NULL ||
+	return c->postponed_error.IsDefined() || c->easy == nullptr ||
 		!c->buffers.empty();
 }
 
@@ -806,7 +806,7 @@ input_curl_eof(gcc_unused struct input_stream *is)
 {
 	struct input_curl *c = (struct input_curl *)is;
 
-	return c->easy == NULL && c->buffers.empty();
+	return c->easy == nullptr && c->buffers.empty();
 }
 
 /** called by curl when new data is available */
@@ -822,7 +822,7 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream)
 	const char *end = header + size;
 
 	const char *value = (const char *)memchr(header, ':', size);
-	if (value == NULL || (size_t)(value - header) >= sizeof(name))
+	if (value == nullptr || (size_t)(value - header) >= sizeof(name))
 		return size;
 
 	memcpy(name, header, value - header);
@@ -853,7 +853,7 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream)
 		memcpy(buffer, value, end - value);
 		buffer[end - value] = 0;
 
-		c->base.size = c->base.offset + g_ascii_strtoull(buffer, NULL, 10);
+		c->base.size = c->base.offset + g_ascii_strtoull(buffer, nullptr, 10);
 	} else if (g_ascii_strcasecmp(name, "content-type") == 0) {
 		c->base.mime.assign(value, end);
 	} else if (g_ascii_strcasecmp(name, "icy-name") == 0 ||
@@ -876,7 +876,7 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream)
 		memcpy(buffer, value, end - value);
 		buffer[end - value] = 0;
 
-		icy_metaint = g_ascii_strtoull(buffer, NULL, 10);
+		icy_metaint = g_ascii_strtoull(buffer, nullptr, 10);
 		FormatDebug(curl_domain, "icy-metaint=%zu", icy_metaint);
 
 		if (icy_metaint > 0) {
@@ -921,7 +921,7 @@ input_curl_easy_init(struct input_curl *c, Error &error)
 	CURLcode code;
 
 	c->easy = curl_easy_init();
-	if (c->easy == NULL) {
+	if (c->easy == nullptr) {
 		error.Set(curl_domain, "curl_easy_init() failed");
 		return false;
 	}
@@ -944,13 +944,13 @@ input_curl_easy_init(struct input_curl *c, Error &error)
 	curl_easy_setopt(c->easy, CURLOPT_NOSIGNAL, 1l);
 	curl_easy_setopt(c->easy, CURLOPT_CONNECTTIMEOUT, 10l);
 
-	if (proxy != NULL)
+	if (proxy != nullptr)
 		curl_easy_setopt(c->easy, CURLOPT_PROXY, proxy);
 
 	if (proxy_port > 0)
 		curl_easy_setopt(c->easy, CURLOPT_PROXYPORT, (long)proxy_port);
 
-	if (proxy_user != NULL && proxy_password != NULL) {
+	if (proxy_user != nullptr && proxy_password != nullptr) {
 		char proxy_auth_str[1024];
 		snprintf(proxy_auth_str, sizeof(proxy_auth_str),
 			 "%s:%s",
@@ -966,7 +966,7 @@ input_curl_easy_init(struct input_curl *c, Error &error)
 		return false;
 	}
 
-	c->request_headers = NULL;
+	c->request_headers = nullptr;
 	c->request_headers = curl_slist_append(c->request_headers,
 					       "Icy-Metadata: 1");
 	curl_easy_setopt(c->easy, CURLOPT_HTTPHEADER, c->request_headers);
@@ -1085,18 +1085,18 @@ input_curl_open(const char *url, Mutex &mutex, Cond &cond,
 {
 	if (memcmp(url, "http://",  7) != 0 &&
 	    memcmp(url, "https://", 8) != 0)
-		return NULL;
+		return nullptr;
 
 	struct input_curl *c = new input_curl(url, mutex, cond);
 
 	if (!input_curl_easy_init(c, error)) {
 		delete c;
-		return NULL;
+		return nullptr;
 	}
 
 	if (!input_curl_easy_add_indirect(c, error)) {
 		delete c;
-		return NULL;
+		return nullptr;
 	}
 
 	return &c->base;