+ ret = pl_get_def_by_name(name, &playlist_def);
+ if (ret < 0)
+ goto err;
+ pi = zalloc(sizeof(*pi));
+ if (result)
+ score_open(&pi->score_table);
+ ret = for_each_line(FELF_READ_ONLY, playlist_def.data,
+ playlist_def.size, add_playlist_entry, pi);
+ osl_close_disk_object(&playlist_def);
+ if (ret < 0)
+ goto close_score_table;
+ ret = -E_PLAYLIST_EMPTY;
+ if (pi->length == 0)
+ goto close_score_table;
+ /* success */
+ if (msg)
+ *msg = make_message("loaded playlist %s (%u files)\n", name,
+ pi->length);
+ pi->name = para_strdup(name);
+ if (result)
+ *result = pi;
+ else {
+ playlist_unload(NULL);
+ current_playlist = *pi;
+ }
+ return pi->length;
+close_score_table:
+ if (result)
+ score_close(pi->score_table);
+ free(pi);
+err:
+ PARA_NOTICE_LOG("unable to load playlist %s\n", name);
+ if (msg)
+ *msg = make_message("unable to load playlist %s\n", name);
+ return ret;
+}
+
+/**
+ * Iterate over all admissible audio files of a playlist instance.
+ *
+ * This wrapper around \ref score_loop() is the playlist counterpart of \ref
+ * mood_loop().
+ *
+ * \param pi Determines the score table to iterate. Must not be NULL.
+ * \param func See \ref score_loop().
+ * \param data See \ref score_loop().
+ *
+ * \return See \ref score_loop(), \ref mood_loop().
+ */
+int playlist_loop(struct playlist_instance *pi, osl_rbtree_loop_func *func, void *data)
+{
+ return score_loop(func, pi->score_table, data);