aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-01-03 22:53:53 +0100
committerMax Kellermann <max@duempel.org>2013-01-03 22:53:53 +0100
commit6837e5a6a09bfc499e09f7e5259f84a111bca8f6 (patch)
tree594a35bb656e4b38a5550a50d9656d012aa6d63d /src
parent59400d38a99ac8ffbfd7d89e021ed2f56ffbfd23 (diff)
parent9761abf3b5726cf3870ce4cb36e47c86ac8cee86 (diff)
downloadmpd-6837e5a6a09bfc499e09f7e5259f84a111bca8f6.tar.gz
mpd-6837e5a6a09bfc499e09f7e5259f84a111bca8f6.tar.xz
mpd-6837e5a6a09bfc499e09f7e5259f84a111bca8f6.zip
Merge branch 'v0.17.x'
Diffstat (limited to 'src')
-rw-r--r--src/CommandLine.cxx8
-rw-r--r--src/cue/cue_parser.c80
2 files changed, 75 insertions, 13 deletions
diff --git a/src/CommandLine.cxx b/src/CommandLine.cxx
index a784c824b..a588ad5b2 100644
--- a/src/CommandLine.cxx
+++ b/src/CommandLine.cxx
@@ -217,12 +217,12 @@ parse_cmdline(int argc, char **argv, struct options *options,
if(g_file_test(system_path,
G_FILE_TEST_IS_REGULAR)) {
ret = config_read_file(system_path,error_r);
+ g_free(system_path);
break;
- }
- ++i;;
+ } else
+ g_free(system_path);
+ ++i;
}
- g_free(system_path);
- g_free(&system_config_dirs);
}
#else /* G_OS_WIN32 */
char *path2;
diff --git a/src/cue/cue_parser.c b/src/cue/cue_parser.c
index 2b0733f00..9ccc3bcdd 100644
--- a/src/cue/cue_parser.c
+++ b/src/cue/cue_parser.c
@@ -58,9 +58,35 @@ struct cue_parser {
char *filename;
- struct song *current, *previous, *finished;
-
+ /**
+ * The song currently being edited.
+ */
+ struct song *current;
+
+ /**
+ * The previous song. It is remembered because its end_time
+ * will be set to the current song's start time.
+ */
+ struct song *previous;
+
+ /**
+ * A song that is completely finished and can be returned to
+ * the caller via cue_parser_get().
+ */
+ struct song *finished;
+
+ /**
+ * Set to true after previous.end_time has been updated to the
+ * start time of the current song.
+ */
bool last_updated;
+
+ /**
+ * Tracks whether cue_parser_finish() has been called. If
+ * true, then all remaining (partial) results will be
+ * delivered by cue_parser_get().
+ */
+ bool end;
};
struct cue_parser *
@@ -73,6 +99,7 @@ cue_parser_new(void)
parser->current = NULL;
parser->previous = NULL;
parser->finished = NULL;
+ parser->end = false;
return parser;
}
@@ -85,6 +112,9 @@ cue_parser_free(struct cue_parser *parser)
if (parser->current != NULL)
song_free(parser->current);
+ if (parser->previous != NULL)
+ song_free(parser->previous);
+
if (parser->finished != NULL)
song_free(parser->finished);
@@ -201,10 +231,32 @@ cue_parse_position(const char *p)
return minutes * 60000 + seconds * 1000 + frames * 1000 / 75;
}
+/**
+ * Commit the current song. It will be moved to "previous", so the
+ * next song may soon edit its end time (using the next song's start
+ * time).
+ */
+static void
+cue_parser_commit(struct cue_parser *parser)
+{
+ /* the caller of this library must call cue_parser_get() often
+ enough */
+ assert(parser->finished == NULL);
+ assert(!parser->end);
+
+ if (parser->current == NULL)
+ return;
+
+ parser->finished = parser->previous;
+ parser->previous = parser->current;
+ parser->current = NULL;
+}
+
static void
cue_parser_feed2(struct cue_parser *parser, char *p)
{
assert(parser != NULL);
+ assert(!parser->end);
assert(p != NULL);
const char *command = cue_next_token(&p);
@@ -235,7 +287,7 @@ cue_parser_feed2(struct cue_parser *parser, char *p)
else if (parser->state == TRACK)
cue_add_tag(parser->current->tag, TAG_TITLE, p);
} else if (strcmp(command, "FILE") == 0) {
- cue_parser_finish(parser);
+ cue_parser_commit(parser);
const char *filename = cue_next_value(&p);
if (filename == NULL)
@@ -258,7 +310,7 @@ cue_parser_feed2(struct cue_parser *parser, char *p)
} else if (parser->state == IGNORE_FILE) {
return;
} else if (strcmp(command, "TRACK") == 0) {
- cue_parser_finish(parser);
+ cue_parser_commit(parser);
const char *nr = cue_next_token(&p);
if (nr == NULL)
@@ -310,6 +362,7 @@ void
cue_parser_feed(struct cue_parser *parser, const char *line)
{
assert(parser != NULL);
+ assert(!parser->end);
assert(line != NULL);
char *allocated = g_strdup(line);
@@ -320,12 +373,12 @@ cue_parser_feed(struct cue_parser *parser, const char *line)
void
cue_parser_finish(struct cue_parser *parser)
{
- if (parser->finished != NULL)
- song_free(parser->finished);
+ if (parser->end)
+ /* has already been called, ignore */
+ return;
- parser->finished = parser->previous;
- parser->previous = parser->current;
- parser->current = NULL;
+ cue_parser_commit(parser);
+ parser->end = true;
}
struct song *
@@ -333,6 +386,15 @@ cue_parser_get(struct cue_parser *parser)
{
assert(parser != NULL);
+ if (parser->finished == NULL && parser->end) {
+ /* cue_parser_finish() has been called already:
+ deliver all remaining (partial) results */
+ assert(parser->current == NULL);
+
+ parser->finished = parser->previous;
+ parser->previous = NULL;
+ }
+
struct song *song = parser->finished;
parser->finished = NULL;
return song;