From fed719197c7014151710c4aae9174990fd131d59 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Sun, 4 Jan 2009 19:09:34 +0100
Subject: song: allocate the result of song_get_url()

---
 src/decoder/wavpack_plugin.c |  7 +++---
 src/decoder_api.c            |  5 ++---
 src/decoder_api.h            |  8 ++++++-
 src/decoder_thread.c         |  7 ++----
 src/locate.c                 | 16 +++++++++-----
 src/player_control.c         | 32 ++++++++++++++++-----------
 src/player_thread.c          | 19 +++++++++-------
 src/playlist.c               | 52 ++++++++++++++++++++++++--------------------
 src/playlist_save.c          | 12 +++++-----
 src/song.c                   | 10 ++++-----
 src/song.h                   | 13 ++++++-----
 src/stored_playlist.c        |  8 +++----
 src/update.c                 |  6 +++--
 13 files changed, 110 insertions(+), 85 deletions(-)

(limited to 'src')

diff --git a/src/decoder/wavpack_plugin.c b/src/decoder/wavpack_plugin.c
index 11b856224..e08ec1dfc 100644
--- a/src/decoder/wavpack_plugin.c
+++ b/src/decoder/wavpack_plugin.c
@@ -455,8 +455,7 @@ static bool
 wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc,
 		 struct wavpack_input *wpi)
 {
-	char tmp[MPD_PATH_MAX];
-	const char *utf8url;
+	char *utf8url;
 	char *wvc_url = NULL;
 	bool ret;
 	char first_byte;
@@ -466,12 +465,14 @@ wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc,
 	 * As we use dc->utf8url, this function will be bad for
 	 * single files. utf8url is not absolute file path :/
 	 */
-	utf8url = decoder_get_url(decoder, tmp);
+	utf8url = decoder_get_uri(decoder);
 	if (utf8url == NULL) {
 		return false;
 	}
 
 	wvc_url = g_strconcat(utf8url, "c", NULL);
+	g_free(utf8url);
+
 	ret = input_stream_open(is_wvc, wvc_url);
 	g_free(wvc_url);
 
diff --git a/src/decoder_api.c b/src/decoder_api.c
index 1f5db3b72..76bf05754 100644
--- a/src/decoder_api.c
+++ b/src/decoder_api.c
@@ -57,10 +57,9 @@ void decoder_initialized(struct decoder * decoder,
 	notify_signal(&pc.notify);
 }
 
-const char *decoder_get_url(G_GNUC_UNUSED struct decoder * decoder,
-			    char * buffer)
+char *decoder_get_uri(G_GNUC_UNUSED struct decoder *decoder)
 {
-	return song_get_url(dc.current_song, buffer);
+	return song_get_uri(dc.current_song);
 }
 
 enum decoder_command decoder_get_command(G_GNUC_UNUSED struct decoder * decoder)
diff --git a/src/decoder_api.h b/src/decoder_api.h
index 88705651a..4e24c7b05 100644
--- a/src/decoder_api.h
+++ b/src/decoder_api.h
@@ -108,7 +108,13 @@ void decoder_initialized(struct decoder * decoder,
 			 const struct audio_format *audio_format,
 			 bool seekable, float total_time);
 
-const char *decoder_get_url(struct decoder * decoder, char * buffer);
+/**
+ * Returns the URI of the current song in UTF-8 encoding.
+ *
+ * The return value is allocated on the heap, and must be freed by the
+ * caller.
+ */
+char *decoder_get_uri(struct decoder *decoder);
 
 enum decoder_command decoder_get_command(struct decoder * decoder);
 
diff --git a/src/decoder_thread.c b/src/decoder_thread.c
index 061048d94..a856c1f00 100644
--- a/src/decoder_thread.c
+++ b/src/decoder_thread.c
@@ -208,11 +208,8 @@ static void decoder_run(void)
 
 	if (song_is_file(song))
 		uri = map_song_fs(song);
-	else {
-		char buffer[MPD_PATH_MAX];
-
-		uri = g_strdup(song_get_url(song, buffer));
-	}
+	else
+		uri = song_get_uri(song);
 
 	if (uri == NULL) {
 		dc.state = DECODE_STATE_ERROR;
diff --git a/src/locate.c b/src/locate.c
index fb57c2cd0..55163b1e4 100644
--- a/src/locate.c
+++ b/src/locate.c
@@ -135,10 +135,12 @@ strstrSearchTag(struct song *song, enum tag_type type, char *str)
 	int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 };
 
 	if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
-		char path_max_tmp[MPD_PATH_MAX], *p;
+		char *uri, *p;
+
+		uri = song_get_uri(song);
+		p = g_utf8_casefold(uri, -1);
+		g_free(uri);
 
-		song_get_url(song, path_max_tmp);
-		p = g_utf8_casefold(path_max_tmp, -1);
 		if (strstr(p, str))
 			ret = 1;
 		g_free(p);
@@ -196,9 +198,13 @@ tagItemFoundAndMatches(struct song *song, enum tag_type type, char *str)
 	int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 };
 
 	if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
-		char path_max_tmp[MPD_PATH_MAX];
-		if (0 == strcmp(str, song_get_url(song, path_max_tmp)))
+		char *uri = song_get_uri(song);
+		bool matches = strcmp(str, uri);
+		g_free(uri);
+
+		if (matches)
 			return 1;
+
 		if (type == LOCATE_TAG_FILE_TYPE)
 			return 0;
 	}
diff --git a/src/player_control.c b/src/player_control.c
index bb687f8ad..e30ce6ec4 100644
--- a/src/player_control.c
+++ b/src/player_control.c
@@ -150,15 +150,10 @@ enum player_error getPlayerError(void)
 	return pc.error;
 }
 
-static const char *
+static char *
 pc_errored_song_uri(void)
 {
-	char path_max_tmp[MPD_PATH_MAX];
-
-	if (pc.errored_song == NULL)
-		return "?";
-
-	return song_get_url(pc.errored_song, path_max_tmp);
+	return song_get_uri(pc.errored_song);
 }
 
 char *getPlayerErrorStr(void)
@@ -166,6 +161,8 @@ char *getPlayerErrorStr(void)
 	/* static OK here, only one user in main task */
 	static char error[MPD_PATH_MAX + 64]; /* still too much */
 	static const size_t errorlen = sizeof(error);
+	char *uri;
+
 	*error = '\0'; /* likely */
 
 	switch (pc.error) {
@@ -173,23 +170,32 @@ char *getPlayerErrorStr(void)
 		break;
 
 	case PLAYER_ERROR_FILENOTFOUND:
+		uri = pc_errored_song_uri();
 		snprintf(error, errorlen,
-			 "file \"%s\" does not exist or is inaccessible",
-			 pc_errored_song_uri());
+			 "file \"%s\" does not exist or is inaccessible", uri);
+		g_free(uri);
 		break;
+
 	case PLAYER_ERROR_FILE:
-		snprintf(error, errorlen, "problems decoding \"%s\"",
-			 pc_errored_song_uri());
+		uri = pc_errored_song_uri();
+		snprintf(error, errorlen, "problems decoding \"%s\"", uri);
+		g_free(uri);
 		break;
+
 	case PLAYER_ERROR_AUDIO:
 		strcpy(error, "problems opening audio device");
 		break;
+
 	case PLAYER_ERROR_SYSTEM:
 		strcpy(error, "system error occured");
 		break;
+
 	case PLAYER_ERROR_UNKTYPE:
-		snprintf(error, errorlen, "file type of \"%s\" is unknown",
-			 pc_errored_song_uri());
+		uri = pc_errored_song_uri();
+		snprintf(error, errorlen,
+			 "file type of \"%s\" is unknown", uri);
+		g_free(uri);
+		break;
 	}
 	return *error ? error : NULL;
 }
diff --git a/src/player_thread.c b/src/player_thread.c
index acaf7e123..98cc64441 100644
--- a/src/player_thread.c
+++ b/src/player_thread.c
@@ -178,13 +178,15 @@ static void player_process_command(struct player *player)
 			if (openAudioDevice(NULL)) {
 				pc.state = PLAYER_STATE_PLAY;
 			} else {
-				char tmp[MPD_PATH_MAX];
+				char *uri = song_get_uri(dc.next_song);
+				g_warning("problems opening audio device "
+					  "while playing \"%s\"", uri);
+				g_free(uri);
+
 				assert(dc.next_song == NULL || dc.next_song->url != NULL);
 				pc.errored_song = dc.next_song;
 				pc.error = PLAYER_ERROR_AUDIO;
-				g_warning("problems opening audio device "
-					  "while playing \"%s\"",
-					  song_get_url(dc.next_song, tmp));
+
 				player->paused = true;
 			}
 		}
@@ -335,13 +337,14 @@ static void do_play(void)
 				/* the decoder is ready and ok */
 				player.decoder_starting = false;
 				if (!openAudioDevice(&dc.out_audio_format)) {
-					char tmp[MPD_PATH_MAX];
+					char *uri = song_get_uri(dc.next_song);
+					g_warning("problems opening audio device "
+						  "while playing \"%s\"", uri);
+					g_free(uri);
+
 					assert(dc.next_song == NULL || dc.next_song->url != NULL);
 					pc.errored_song = dc.next_song;
 					pc.error = PLAYER_ERROR_AUDIO;
-					g_warning("problems opening audio device "
-						  "while playing \"%s\"",
-						  song_get_url(dc.next_song, tmp));
 					break;
 				}
 
diff --git a/src/playlist.c b/src/playlist.c
index 414e5a63a..df60fe99b 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -224,20 +224,20 @@ void clearPlaylist(void)
 
 void showPlaylist(struct client *client)
 {
-	char path_max_tmp[MPD_PATH_MAX];
-
-	for (unsigned i = 0; i < playlist.length; i++)
-		client_printf(client, "%i:%s\n", i,
-			      song_get_url(playlist.songs[i], path_max_tmp));
+	for (unsigned i = 0; i < playlist.length; i++) {
+		char *uri = song_get_uri(playlist.songs[i]);
+		client_printf(client, "%i:%s\n", i, uri);
+		g_free(uri);
+	}
 }
 
 static void playlist_save(FILE *fp)
 {
-	char path_max_tmp[MPD_PATH_MAX];
-
-	for (unsigned i = 0; i < playlist.length; i++)
-		fprintf(fp, "%i:%s\n", i,
-			song_get_url(playlist.songs[i], path_max_tmp));
+	for (unsigned i = 0; i < playlist.length; i++) {
+		char *uri = song_get_uri(playlist.songs[i]);
+		fprintf(fp, "%i:%s\n", i, uri);
+		g_free(uri);
+	}
 }
 
 void savePlaylistState(FILE *fp)
@@ -483,26 +483,30 @@ static void swapSongs(unsigned song1, unsigned song2)
 
 static void queueNextSongInPlaylist(void)
 {
-	char path_max_tmp[MPD_PATH_MAX];
-
 	if (playlist.current < (int)playlist.length - 1) {
+		char *uri;
+
 		playlist.queued = playlist.current + 1;
+
+		uri = song_get_uri(playlist. songs[playlist.order[playlist.queued]]);
 		g_debug("playlist: queue song %i:\"%s\"",
-			playlist.queued,
-			song_get_url(playlist.
-				     songs[playlist.order[playlist.queued]],
-				     path_max_tmp));
+			playlist.queued, uri);
+		g_free(uri);
+
 		queueSong(playlist.songs[playlist.order[playlist.queued]]);
 	} else if (playlist.length && playlist.repeat) {
+		char *uri;
+
 		if (playlist.length > 1 && playlist.random) {
 			randomizeOrder(0, playlist.length - 1);
 		}
 		playlist.queued = 0;
+
+		uri = song_get_uri(playlist. songs[playlist.order[playlist.queued]]);
 		g_debug("playlist: queue song %i:\"%s\"",
-			playlist.queued,
-			song_get_url(playlist.
-				     songs[playlist.order[playlist.queued]],
-				     path_max_tmp));
+			playlist.queued, uri);
+		g_free(uri);
+
 		queueSong(playlist.songs[playlist.order[playlist.queued]]);
 	}
 }
@@ -783,15 +787,15 @@ void stopPlaylist(void)
 
 static void playPlaylistOrderNumber(int orderNum)
 {
-	char path_max_tmp[MPD_PATH_MAX];
+	char *uri;
 
 	playlist_state = PLAYLIST_STATE_PLAY;
 	playlist_noGoToNext = 0;
 	playlist.queued = -1;
 
-	g_debug("playlist: play %i:\"%s\"", orderNum,
-		song_get_url(playlist.songs[playlist.order[orderNum]],
-			     path_max_tmp));
+	uri = song_get_uri(playlist.songs[playlist.order[orderNum]]);
+	g_debug("playlist: play %i:\"%s\"", orderNum, uri);
+	g_free(uri);
 
 	playerPlay(playlist.songs[playlist.order[orderNum]]);
 	playlist.current = orderNum;
diff --git a/src/playlist_save.c b/src/playlist_save.c
index dbe389a96..054ba73f4 100644
--- a/src/playlist_save.c
+++ b/src/playlist_save.c
@@ -29,8 +29,6 @@
 void
 playlist_print_song(FILE *file, const struct song *song)
 {
-	char tmp1[MPD_PATH_MAX], tmp2[MPD_PATH_MAX];
-
 	if (playlist_saveAbsolutePaths && song_in_database(song)) {
 		char *path = map_song_fs(song);
 		if (path != NULL) {
@@ -38,9 +36,13 @@ playlist_print_song(FILE *file, const struct song *song)
 			g_free(path);
 		}
 	} else {
-		song_get_url(song, tmp1);
-		utf8_to_fs_charset(tmp2, tmp1);
-		fprintf(file, "%s\n", tmp2);
+		char *uri = song_get_uri(song);
+		char tmp2[MPD_PATH_MAX];
+
+		utf8_to_fs_charset(tmp2, uri);
+		g_free(uri);
+
+		fprintf(file, "%s\n", uri);
 	}
 }
 
diff --git a/src/song.c b/src/song.c
index 9cbd859f5..b56c798cb 100644
--- a/src/song.c
+++ b/src/song.c
@@ -176,16 +176,14 @@ song_file_update_inarchive(struct song *song)
 }
 
 char *
-song_get_url(const struct song *song, char *path_max_tmp)
+song_get_uri(const struct song *song)
 {
 	assert(song != NULL);
 	assert(*song->url);
 
 	if (!song_in_database(song) || directory_is_root(song->parent))
-		strcpy(path_max_tmp, song->url);
+		return g_strdup(song->url);
 	else
-		pfx_dir(path_max_tmp, song->url, strlen(song->url),
-			directory_get_path(song->parent),
-			strlen(directory_get_path(song->parent)));
-	return path_max_tmp;
+		return g_strconcat(directory_get_path(song->parent),
+				   "/", song->url, NULL);
 }
diff --git a/src/song.h b/src/song.h
index 7f40b7e9f..a4c72cf67 100644
--- a/src/song.h
+++ b/src/song.h
@@ -61,14 +61,15 @@ song_file_update(struct song *song);
 bool
 song_file_update_inarchive(struct song *song);
 
-/*
- * song_get_url - Returns a path of a song in UTF8-encoded form
- * path_max_tmp is the argument that the URL is written to, this
- * buffer is assumed to be MPD_PATH_MAX or greater (including
- * terminating '\0').
+/**
+ * Returns the URI of the song in UTF-8 encoding, including its
+ * location within the music directory.
+ *
+ * The return value is allocated on the heap, and must be freed by the
+ * caller.
  */
 char *
-song_get_url(const struct song *song, char *path_max_tmp);
+song_get_uri(const struct song *song);
 
 static inline bool
 song_in_database(const struct song *song)
diff --git a/src/stored_playlist.c b/src/stored_playlist.c
index fd2f6fc01..3504c0a26 100644
--- a/src/stored_playlist.c
+++ b/src/stored_playlist.c
@@ -141,7 +141,6 @@ spl_load(const char *utf8path)
 	FILE *file;
 	GPtrArray *list;
 	char buffer[MPD_PATH_MAX];
-	char path_max_tmp[MPD_PATH_MAX];
 	char *path_fs;
 
 	if (!is_valid_playlist_name(utf8path))
@@ -177,10 +176,11 @@ spl_load(const char *utf8path)
 			if (song == NULL)
 				continue;
 
-			s = song_get_url(song, path_max_tmp);
-		}
+			s = song_get_uri(song);
+		} else
+			s = g_strdup(s);
 
-		g_ptr_array_add(list, g_strdup(s));
+		g_ptr_array_add(list, s);
 
 		if (list->len >= playlist_max_length)
 			break;
diff --git a/src/update.c b/src/update.c
index ec9890f31..f792b3c3c 100644
--- a/src/update.c
+++ b/src/update.c
@@ -699,8 +699,10 @@ static void reap_update_task(void)
 
 	cond_enter(&delete_cond);
 	if (delete) {
-		char tmp[MPD_PATH_MAX];
-		g_debug("removing: %s", song_get_url(delete, tmp));
+		char *tmp = song_get_uri(delete);
+		g_debug("removing: %s", tmp);
+		g_free(tmp);
+
 		deleteASongFromPlaylist(delete);
 		delete = NULL;
 		cond_signal_sync(&delete_cond);
-- 
cgit v1.2.3