ref: f8a238ccfdd7199fc1ba016d89a6943605839456
parent: 4009ef3e4222f85f9cb60d5b6d7b75d8b9c4c689
author: robs <robs>
date: Sun Mar 11 17:34:01 EDT 2007
.pls files might work now; you may need -tmp3 and quotes, e.g. play -t mp3 'http://www.shoutcast.com/sbin/shoutcast-playlist.pls?rn=1218&file=filename.pls'
--- a/src/sox.c
+++ b/src/sox.c
@@ -267,15 +267,21 @@
}
}
+static sox_bool strcaseends(char const * str, char const * end)
+{
+ size_t str_len = strlen(str), end_len = strlen(end);
+ return str_len >= end_len && !strcasecmp(str + str_len - end_len, end);
+}
+
static sox_bool is_playlist(char const * filename)
{
- size_t i = strlen(filename);
- return i >= sizeof(".m3u") - 1 &&
- strcasecmp(filename + i - (sizeof(".m3u") - 1), ".m3u") == 0;
+ return strcaseends(filename, ".m3u") || strcaseends(filename, ".pls");
}
static void parse_playlist(const file_t f0, char const * const filename)
{
+ sox_bool is_pls = strcaseends(filename, ".pls");
+ int comment_char = "#;"[is_pls];
size_t text_length = 100;
char * text = xmalloc(text_length + 1);
char * dirname = xstrdup(filename);
@@ -299,29 +305,36 @@
do {
size_t i = 0;
- char * last = NULL;
+ size_t begin = 0, end = 0;
while (isspace(c = getc(file)));
if (c == EOF)
break;
- while (c != EOF && !strchr("#\r\n", c)) {
+ while (c != EOF && !strchr("\r\n", c) && c != comment_char) {
if (i == text_length)
text = xrealloc(text, (text_length <<= 1) + 1);
- text[i] = c;
+ text[i++] = c;
if (!strchr(" \t\f", c))
- last = text + i;
- ++i;
+ end = i;
c = getc(file);
}
if (ferror(file))
break;
- if (c == '#') {
+ if (c == comment_char) {
do c = getc(file);
while (c != EOF && !strchr("\r\n", c));
if (ferror(file))
break;
}
- if (last) {
+ text[end] = '\0';
+ if (is_pls) {
+ char dummy;
+ if (!strncasecmp(text, "file", 4) && sscanf(text + 4, "%*u=%c", &dummy) == 1)
+ begin = strchr(text + 5, '=') - text + 1;
+ else end = 0;
+ }
+ if (begin != end) {
+ char const * id = text + begin;
file_t f;
if (file_count >= MAX_FILES) {
@@ -329,18 +342,17 @@
exit(1);
}
- last[1] = '\0';
f = new_file();
*f = *f0;
- if (!dirname[0] || is_uri(text)
+ if (!dirname[0] || is_uri(id)
#if defined(DOS) || defined(WIN32)
- || text[0] == '\\' || text[1] == ':'
+ || id[0] == '\\' || id[1] == ':'
#endif
- || text[0] == '/')
- f->filename = xstrdup(text);
+ || id[0] == '/')
+ f->filename = xstrdup(id);
else {
- f->filename = xmalloc(strlen(dirname) + strlen(text) + 2);
- sprintf(f->filename, "%s/%s", dirname, text);
+ f->filename = xmalloc(strlen(dirname) + strlen(id) + 2);
+ sprintf(f->filename, "%s/%s", dirname, id);
}
if (is_playlist(f->filename)) {
parse_playlist(f, f->filename);
@@ -1863,7 +1875,7 @@
while (*names++)
formats++;
}
- ++formats;
+ formats += 2;
format_list = (const char **)xmalloc(formats * sizeof(char *));
for (i = 0, formats = 0; sox_format_fns[i]; i++) {
char const * const *names = sox_format_fns[i]()->names;
@@ -1871,6 +1883,7 @@
format_list[formats++] = *names++;
}
format_list[formats++] = "m3u";
+ format_list[formats++] = "pls";
qsort(format_list, formats, sizeof(char *), strcmp_p);
for (i = 0; i < formats; i++)
printf(" %s", format_list[i]);