summaryrefslogtreecommitdiffstats
path: root/apps/tagtree.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-07-18 18:55:20 +0000
committerThomas Martitz <kugel@rockbox.org>2011-07-18 18:55:20 +0000
commit74ab227b58ee3eae152c1142eb9144ee5332a7d9 (patch)
tree0a3b90bc96169a3ed00fc51120d5009d443bd8c0 /apps/tagtree.c
parente0970817b0d8b426f4b26090017868067d0f516e (diff)
downloadrockbox-74ab227b58ee3eae152c1142eb9144ee5332a7d9.tar.gz
rockbox-74ab227b58ee3eae152c1142eb9144ee5332a7d9.tar.bz2
rockbox-74ab227b58ee3eae152c1142eb9144ee5332a7d9.zip
Introduce bsearch() and use it in tagtree.c.
bsearch() is a general purpose binary search function for arrays. It's supposedly faster than looping over arrays. The array needs to be sorted in ascending order under the provided comparison function. If the key and array element are of the same kind, then the same compare function can be used for qsort() and bsearch(). Code taken from glibc. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30155 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/tagtree.c')
-rw-r--r--apps/tagtree.c134
1 files changed, 69 insertions, 65 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 3df8d9db2b..1bdc0550a6 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "string-extra.h"
+#include "bsearch.h"
#include "config.h"
#include "system.h"
#include "kernel.h"
@@ -160,6 +161,13 @@ struct match
int symbol;
};
+static int compare_match(const void* _key, const void* _elem)
+{
+ const char* key = _key;
+ const struct match *elem = _elem;
+ return strcasecmp(key, elem->str);
+}
+
/* Statusbar text of the current view. */
static char current_title[MAX_TAGS][128];
@@ -221,42 +229,42 @@ static int get_token_str(char *buf, int size)
static int get_tag(int *tag)
{
static const struct match get_tag_match[] =
- {
- {"album", tag_album},
- {"artist", tag_artist},
- {"bitrate", tag_bitrate},
- {"composer", tag_composer},
- {"comment", tag_comment},
- {"albumartist", tag_albumartist},
- {"ensemble", tag_albumartist},
- {"grouping", tag_grouping},
- {"genre", tag_genre},
- {"length", tag_length},
- {"Lm", tag_virt_length_min},
- {"Ls", tag_virt_length_sec},
- {"Pm", tag_virt_playtime_min},
- {"Ps", tag_virt_playtime_sec},
- {"title", tag_title},
- {"filename", tag_filename},
- {"tracknum", tag_tracknumber},
- {"discnum", tag_discnumber},
- {"year", tag_year},
- {"playcount", tag_playcount},
- {"rating", tag_rating},
- {"lastplayed", tag_lastplayed},
- {"lastoffset", tag_lastoffset},
- {"commitid", tag_commitid},
- {"entryage", tag_virt_entryage},
- {"autoscore", tag_virt_autoscore},
- {"%sort", var_sorttype},
- {"%limit", var_limit},
- {"%strip", var_strip},
- {"%menu_start", var_menu_start},
- {"%include", var_include},
- {"%root_menu", var_rootmenu},
- {"%format", var_format},
- {"->", menu_next},
- {"==>", menu_load}
+ { /* sorted by ascii (case insensitive) for bsearch */
+ { "%format", var_format },
+ { "%include", var_include },
+ { "%limit", var_limit },
+ {"%menu_start",var_menu_start},
+ {"%root_menu",var_rootmenu},
+ { "%sort", var_sorttype },
+ { "%strip", var_strip },
+ {"->",menu_next},
+ { "==>", menu_load },
+ { "album", tag_album },
+ { "albumartist", tag_albumartist },
+ { "artist", tag_artist },
+ { "autoscore", tag_virt_autoscore },
+ { "bitrate", tag_bitrate },
+ { "comment", tag_comment },
+ { "commitid", tag_commitid },
+ { "composer", tag_composer },
+ { "discnum", tag_discnumber },
+ { "ensemble", tag_albumartist },
+ { "entryage", tag_virt_entryage },
+ { "filename", tag_filename },
+ { "genre", tag_genre },
+ { "grouping", tag_grouping },
+ { "lastoffset", tag_lastoffset },
+ { "lastplayed", tag_lastplayed },
+ { "length", tag_length },
+ { "Lm", tag_virt_length_min },
+ { "Ls", tag_virt_length_sec },
+ { "playcount", tag_playcount },
+ { "Pm", tag_virt_playtime_min },
+ { "Ps", tag_virt_playtime_sec },
+ { "rating", tag_rating },
+ { "title", tag_title },
+ { "tracknum", tag_tracknumber },
+ { "year", tag_year },
};
char buf[128];
unsigned int i;
@@ -277,15 +285,13 @@ static int get_tag(int *tag)
}
buf[i] = '\0';
- for (i = 0; i < ARRAYLEN(get_tag_match); i++)
+ struct match *elem = bsearch(buf, get_tag_match, ARRAYLEN(get_tag_match),
+ sizeof(struct match), compare_match);
+ if (elem)
{
- if (!strcasecmp(buf, get_tag_match[i].str))
- {
- *tag = get_tag_match[i].symbol;
- return 1;
- }
+ *tag = elem->symbol;
+ return 1;
}
-
logf("NO MATCH: %s\n", buf);
if (buf[0] == '?')
return 0;
@@ -296,21 +302,21 @@ static int get_tag(int *tag)
static int get_clause(int *condition)
{
static const struct match get_clause_match[] =
- {
- {"=", clause_is},
- {"==", clause_is},
- {"!=", clause_is_not},
- {">", clause_gt},
- {">=", clause_gteq},
- {"<", clause_lt},
- {"<=", clause_lteq},
- {"~", clause_contains},
- {"!~", clause_not_contains},
- {"^", clause_begins_with},
- {"!^", clause_not_begins_with},
- {"$", clause_ends_with},
- {"!$", clause_not_ends_with},
- {"@", clause_oneof}
+ { /* sorted by ascii (case insensitive) for bsearch */
+ { "!$", clause_not_ends_with },
+ { "!=", clause_is_not },
+ { "!^", clause_not_begins_with },
+ { "!~", clause_not_contains },
+ { "$", clause_ends_with },
+ { "<", clause_lt },
+ { "<=", clause_lteq },
+ { "=", clause_is },
+ { "==", clause_is },
+ { ">", clause_gt },
+ { ">=", clause_gteq },
+ { "@", clause_oneof },
+ { "^", clause_begins_with },
+ { "~", clause_contains },
};
char buf[4];
@@ -332,15 +338,13 @@ static int get_clause(int *condition)
}
buf[i] = '\0';
- for (i = 0; i < ARRAYLEN(get_clause_match); i++)
+ struct match *elem = bsearch(buf, get_clause_match, ARRAYLEN(get_clause_match),
+ sizeof(struct match), compare_match);
+ if (elem)
{
- if (!strcasecmp(buf, get_clause_match[i].str))
- {
- *condition = get_clause_match[i].symbol;
- return 1;
- }
+ *condition = elem->symbol;
+ return 1;
}
-
return 0;
}