summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/tagtree.c77
1 files changed, 35 insertions, 42 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 4983231663..60f8a795e3 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -191,19 +191,12 @@ struct menu_entry {
191}; 191};
192 192
193struct menu_root { 193struct menu_root {
194 char title[64]; 194 char title[MENUENTRY_MAX_NAME];
195 char id[MAX_MENU_ID_SIZE]; 195 char id[MAX_MENU_ID_SIZE];
196 int itemcount; 196 int itemcount;
197 struct menu_entry *items[TAGMENU_MAX_ITEMS]; 197 struct menu_entry *items[TAGMENU_MAX_ITEMS];
198}; 198};
199 199
200struct match
201{
202 const char* str;
203 uint16_t len;
204 uint16_t symbol;
205};
206
207/* Statusbar text of the current view. */ 200/* Statusbar text of the current view. */
208static char current_title[MAX_TAGS][128]; 201static char current_title[MAX_TAGS][128];
209 202
@@ -355,12 +348,13 @@ static int get_token_str(char *buf, int size)
355static int get_tag(int *tag) 348static int get_tag(int *tag)
356{ 349{
357 #define TAG_MATCH(str, tag) {str, sizeof(str) - 1, tag} 350 #define TAG_MATCH(str, tag) {str, sizeof(str) - 1, tag}
351 struct match {const char* str; uint16_t len; uint16_t symbol;};
358 static const struct match get_tag_match[] = 352 static const struct match get_tag_match[] =
359 { 353 {
360 TAG_MATCH("Lm", tag_virt_length_min), 354 TAG_MATCH("lm", tag_virt_length_min),
361 TAG_MATCH("Ls", tag_virt_length_sec), 355 TAG_MATCH("ls", tag_virt_length_sec),
362 TAG_MATCH("Pm", tag_virt_playtime_min), 356 TAG_MATCH("pm", tag_virt_playtime_min),
363 TAG_MATCH("Ps", tag_virt_playtime_sec), 357 TAG_MATCH("ps", tag_virt_playtime_sec),
364 TAG_MATCH("->", menu_next), 358 TAG_MATCH("->", menu_next),
365 TAG_MATCH("~>", menu_shuffle_songs), 359 TAG_MATCH("~>", menu_shuffle_songs),
366 360
@@ -383,7 +377,6 @@ static int get_tag(int *tag)
383 TAG_MATCH("comment", tag_comment), 377 TAG_MATCH("comment", tag_comment),
384 TAG_MATCH("discnum", tag_discnumber), 378 TAG_MATCH("discnum", tag_discnumber),
385 TAG_MATCH("%format", var_format), 379 TAG_MATCH("%format", var_format),
386 TAG_MATCH("%byfirstletter", menu_byfirstletter),
387 TAG_MATCH("%reload", menu_reload), 380 TAG_MATCH("%reload", menu_reload),
388 381
389 TAG_MATCH("filename", tag_filename), 382 TAG_MATCH("filename", tag_filename),
@@ -407,13 +400,15 @@ static int get_tag(int *tag)
407 TAG_MATCH("lastelapsed", tag_lastelapsed), 400 TAG_MATCH("lastelapsed", tag_lastelapsed),
408 TAG_MATCH("%menu_start", var_menu_start), 401 TAG_MATCH("%menu_start", var_menu_start),
409 402
403 TAG_MATCH("%byfirstletter", menu_byfirstletter),
410 TAG_MATCH("canonicalartist", tag_virt_canonicalartist), 404 TAG_MATCH("canonicalartist", tag_virt_canonicalartist),
405
411 TAG_MATCH("", 0) /* sentinel */ 406 TAG_MATCH("", 0) /* sentinel */
412 }; 407 };
413 #undef TAG_MATCH 408 #undef TAG_MATCH
414 const size_t max_cmd_sz = 32; /* needs to be >= to len of longest tagstr */ 409 const size_t max_cmd_sz = 32; /* needs to be >= to len of longest tagstr */
415 const char *tagstr; 410 const char *tagstr;
416 unsigned int tagstr_len; 411 uint16_t tagstr_len;
417 const struct match *match; 412 const struct match *match;
418 413
419 /* Find the start. */ 414 /* Find the start. */
@@ -1059,10 +1054,11 @@ int tagtree_import(void)
1059 return 0; 1054 return 0;
1060} 1055}
1061 1056
1062static bool parse_menu(const char *filename); 1057static bool alloc_menu_parse_buf(char *buf, int type)
1063
1064static bool alloc_menu_item(void)
1065{ 1058{
1059 /* allocate a new menu item (if needed) initialize it with data parsed
1060 from buf Note: allows setting menu type, type ignored when < 0
1061 */
1066 /* Allocate */ 1062 /* Allocate */
1067 if (menu->items[menu->itemcount] == NULL) 1063 if (menu->items[menu->itemcount] == NULL)
1068 menu->items[menu->itemcount] = tagtree_alloc0(sizeof(struct menu_entry)); 1064 menu->items[menu->itemcount] = tagtree_alloc0(sizeof(struct menu_entry));
@@ -1071,18 +1067,17 @@ static bool alloc_menu_item(void)
1071 logf("tagtree failed to allocate %s", "menu items"); 1067 logf("tagtree failed to allocate %s", "menu items");
1072 return false; 1068 return false;
1073 } 1069 }
1074 return true;
1075}
1076 1070
1077static void firstletter_parse_buf(char *buf) 1071 /* Initialize */
1078{
1079 core_pin(tagtree_handle); 1072 core_pin(tagtree_handle);
1080 if (parse_search(menu->items[menu->itemcount], buf)) 1073 if (parse_search(menu->items[menu->itemcount], buf))
1081 { 1074 {
1082 menu->items[menu->itemcount]->type = menu_byfirstletter; 1075 if (type >= 0)
1076 menu->items[menu->itemcount]->type = type;
1083 menu->itemcount++; 1077 menu->itemcount++;
1084 } 1078 }
1085 core_unpin(tagtree_handle);; 1079 core_unpin(tagtree_handle);
1080 return true;
1086} 1081}
1087 1082
1088static void build_firstletter_menu(char *buf, size_t bufsz) 1083static void build_firstletter_menu(char *buf, size_t bufsz)
@@ -1092,32 +1087,32 @@ static void build_firstletter_menu(char *buf, size_t bufsz)
1092 buf+=l; 1087 buf+=l;
1093 bufsz-=l; 1088 bufsz-=l;
1094 1089
1095 const char *showalbum = ""; 1090 const char * const fmt ="\"%s\"-> %s ? %s %c\"%c\"-> %s =\"fmt_title\"";
1096 const char * const fmt ="\"%s\" -> %s ? %s %c \"%c\" -> %s title = \"fmt_title\""; 1091 const char * const showsub = /* album subitem for canonicalartist */
1097 if (!alloc_menu_item()) 1092 ((strcasestr(subitem, "artist") == NULL) ? "title" : "album -> title");
1098 return;
1099
1100 if (strcasestr(subitem, "artist") != NULL)
1101 showalbum = "album ->"; /* album subitem for canonicalartist */
1102 1093
1103 /* Numeric ex: "Numeric" -> album ? album < "A" -> title = "fmt_title" */ 1094 /* Numeric ex: "Numeric" -> album ? album < "A" -> title = "fmt_title" */
1104 snprintf(buf, bufsz, fmt, 1095 snprintf(buf, bufsz, fmt,
1105 str(LANG_DISPLAY_NUMERIC), subitem, subitem,'<', 'A', showalbum); 1096 str(LANG_DISPLAY_NUMERIC), subitem, subitem,'<', 'A', showsub);
1106 1097
1107 firstletter_parse_buf(buf); 1098 if (!alloc_menu_parse_buf(buf, menu_byfirstletter))
1099 {
1100 return;
1101 }
1108 1102
1109 for (int i = 0; i < 26; i++) 1103 for (int i = 0; i < 26; i++)
1110 { 1104 {
1111 if (!alloc_menu_item()) 1105 snprintf(buf, bufsz, fmt, "#", subitem, subitem,'^', 'A' + i, showsub);
1112 return;
1113
1114 snprintf(buf, bufsz, fmt, "#", subitem, subitem,'^', 'A' + i, showalbum);
1115 buf[1] = 'A' + i; /* overwrite the placeholder # with the current letter */ 1106 buf[1] = 'A' + i; /* overwrite the placeholder # with the current letter */
1116 /* ex: "A" -> title ? title ^ "A" -> title = "fmt_title" */ 1107 /* ex: "A" -> title ? title ^ "A" -> title = "fmt_title" */
1117 firstletter_parse_buf(buf); 1108 if (!alloc_menu_parse_buf(buf, menu_byfirstletter))
1109 {
1110 return;
1111 }
1118 } 1112 }
1119} 1113}
1120 1114
1115static bool parse_menu(const char *filename);
1121static int parse_line(int n, char *buf, void *parameters) 1116static int parse_line(int n, char *buf, void *parameters)
1122{ 1117{
1123 char data[256]; 1118 char data[256];
@@ -1275,12 +1270,10 @@ static int parse_line(int n, char *buf, void *parameters)
1275 return 0; 1270 return 0;
1276 } 1271 }
1277 1272
1278 if (!alloc_menu_item()) 1273 if (!alloc_menu_parse_buf(buf, -1))
1274 {
1279 return -2; 1275 return -2;
1280 core_pin(tagtree_handle); 1276 }
1281 if (parse_search(menu->items[menu->itemcount], buf))
1282 menu->itemcount++;
1283 core_unpin(tagtree_handle);
1284 1277
1285 return 0; 1278 return 0;
1286} 1279}