autoresume: Match full directory path names only in autoresumable()

Removed genre-tag matching (considered too fragile for real-world use).

Removed substring matching for file names.  To avoid unintended
matches, the search pattern now must match the file's full dir name
(or a parent directory thereof), anchored in the root directory.

Search strings now must be delimited with ":" rather than ",".  The
default list of directories is "/podcast:/podcasts" (case-insensitive).

Made implementation somewhat more efficient (don't use strtok -> no
need to copy the string to private storage (stack) before tokenizing
it).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29280 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Hohmuth 2011-02-11 00:20:03 +00:00
parent bdec638b9b
commit a5303765ec
4 changed files with 44 additions and 28 deletions

View file

@ -403,7 +403,7 @@ static int autoresume_nexttrack_callback(int action,
break; break;
case ACTION_EXIT_MENUITEM: case ACTION_EXIT_MENUITEM:
if (global_settings.autoresume_automatic == AUTORESUME_NEXTTRACK_CUSTOM if (global_settings.autoresume_automatic == AUTORESUME_NEXTTRACK_CUSTOM
&& kbd_input ((char*) &global_settings.autoresume_strpat, && kbd_input ((char*) &global_settings.autoresume_paths,
MAX_PATHNAME+1) < 0) MAX_PATHNAME+1) < 0)
{ {
global_settings.autoresume_automatic = oldval; global_settings.autoresume_automatic = oldval;

View file

@ -435,39 +435,55 @@ enum { AUTORESUMABLE_UNKNOWN = 0, AUTORESUMABLE_TRUE, AUTORESUMABLE_FALSE };
bool autoresumable(struct mp3entry *id3) bool autoresumable(struct mp3entry *id3)
{ {
unsigned char search[MAX_PATHNAME+1]; char *endp, *path;
char *saveptr, *substr; size_t len;
bool is_resumable; bool is_resumable;
if (id3->autoresumable) /* result cached? */ if (id3->autoresumable) /* result cached? */
return id3->autoresumable == AUTORESUMABLE_TRUE; return id3->autoresumable == AUTORESUMABLE_TRUE;
is_resumable = true;
strcpy(search, global_settings.autoresume_strpat);
for (substr = strtok_r(search, ",", &saveptr);
substr;
substr = strtok_r(NULL, ",", &saveptr))
{
if (id3->path && strcasestr(id3->path, substr))
goto out;
if (id3->genre_string && strcasestr(id3->genre_string, substr))
goto out;
}
is_resumable = false; is_resumable = false;
out: if (id3->path)
{
for (path = global_settings.autoresume_paths;
*path; /* search terms left? */
path++)
{
if (*path == ':') /* Skip empty search patterns */
continue;
/* FIXME: As soon as strcspn or strchrnul are made available in
the core, the following can be made more efficient. */
endp = strchr(path, ':');
if (endp)
len = endp - path;
else
len = strlen(path);
/* Note: At this point, len is always > 0 */
if (strncasecmp(id3->path, path, len) == 0)
{
/* Full directory-name matches only. Trailing '/' in
search path OK. */
if (id3->path[len] == '/' || id3->path[len - 1] == '/')
{
is_resumable = true;
break;
}
}
path += len - 1;
}
}
/* cache result */ /* cache result */
id3->autoresumable = id3->autoresumable =
is_resumable ? AUTORESUMABLE_TRUE : AUTORESUMABLE_FALSE; is_resumable ? AUTORESUMABLE_TRUE : AUTORESUMABLE_FALSE;
logf("autoresumable: %s with genre %s is%s resumable", logf("autoresumable: %s is%s resumable",
id3->path, id3->path, is_resumable ? "" : " not");
id3->genre_string ? id3->genre_string : "(NULL)",
is_resumable ? "" : " not");
return is_resumable; return is_resumable;
} }

View file

@ -583,7 +583,7 @@ struct user_settings
bool autoresume_enable; /* enable auto-resume feature? */ bool autoresume_enable; /* enable auto-resume feature? */
int autoresume_automatic; /* resume next track? 0=never, 1=always, int autoresume_automatic; /* resume next track? 0=never, 1=always,
2=custom */ 2=custom */
unsigned char autoresume_strpat[MAX_PATHNAME+1]; /* comma-separated list */ unsigned char autoresume_paths[MAX_PATHNAME+1]; /* colon-separated list */
bool runtimedb; /* runtime database active? */ bool runtimedb; /* runtime database active? */
#endif /* HAVE_TAGCACHE */ #endif /* HAVE_TAGCACHE */

View file

@ -1268,8 +1268,8 @@ const struct settings_list settings[] = {
ID2P(LANG_SET_BOOL_NO), ID2P(LANG_SET_BOOL_NO),
ID2P(LANG_ALWAYS), ID2P(LANG_ALWAYS),
ID2P(LANG_AUTORESUME_CUSTOM)), ID2P(LANG_AUTORESUME_CUSTOM)),
TEXT_SETTING(0, autoresume_strpat, "autoresume next track patterns", TEXT_SETTING(0, autoresume_paths, "autoresume next track paths",
"podcast", NULL, NULL), "/podcast:/podcasts", NULL, NULL),
#endif #endif
OFFON_SETTING(0, runtimedb, LANG_RUNTIMEDB_ACTIVE, false, OFFON_SETTING(0, runtimedb, LANG_RUNTIMEDB_ACTIVE, false,