summaryrefslogtreecommitdiff
path: root/apps/tagtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tagtree.c')
-rw-r--r--apps/tagtree.c233
1 files changed, 174 insertions, 59 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c
index d8d8597d68..a360098aee 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -56,6 +56,7 @@ enum variables {
56 var_menu_start, 56 var_menu_start,
57 var_include, 57 var_include,
58 var_rootmenu, 58 var_rootmenu,
59 var_format,
59 menu_next, 60 menu_next,
60 menu_load, 61 menu_load,
61}; 62};
@@ -82,8 +83,11 @@ static bool sort_inverse;
82 * sort_inverse = true 83 * sort_inverse = true
83 */ 84 */
84struct display_format { 85struct display_format {
85 bool valid; 86 char name[32];
86 char formatstr[64]; 87 struct tagcache_search_clause *clause[TAGCACHE_MAX_CLAUSES];
88 int clause_count;
89 char *formatstr;
90 int group_id;
87 int tags[MAX_TAGS]; 91 int tags[MAX_TAGS];
88 int tag_count; 92 int tag_count;
89 93
@@ -92,12 +96,15 @@ struct display_format {
92 bool sort_inverse; 96 bool sort_inverse;
93}; 97};
94 98
99static struct display_format *formats[TAGMENU_MAX_FMTS];
100static int format_count;
101
95struct search_instruction { 102struct search_instruction {
96 char name[64]; 103 char name[64];
97 int tagorder[MAX_TAGS]; 104 int tagorder[MAX_TAGS];
98 int tagorder_count; 105 int tagorder_count;
99 struct tagcache_search_clause clause[MAX_TAGS][TAGCACHE_MAX_CLAUSES]; 106 struct tagcache_search_clause *clause[MAX_TAGS][TAGCACHE_MAX_CLAUSES];
100 struct display_format format[MAX_TAGS]; 107 int format_id[MAX_TAGS];
101 int clause_count[MAX_TAGS]; 108 int clause_count[MAX_TAGS];
102 int result_seek[MAX_TAGS]; 109 int result_seek[MAX_TAGS];
103}; 110};
@@ -130,6 +137,7 @@ static int root_menu;
130static int current_offset; 137static int current_offset;
131static int current_entry_count; 138static int current_entry_count;
132 139
140static int format_count;
133static struct tree_context *tc; 141static struct tree_context *tc;
134 142
135static int get_token_str(char *buf, int size) 143static int get_token_str(char *buf, int size)
@@ -200,6 +208,7 @@ static int get_tag(int *tag)
200 MATCH(tag, buf, "%menu_start", var_menu_start); 208 MATCH(tag, buf, "%menu_start", var_menu_start);
201 MATCH(tag, buf, "%include", var_include); 209 MATCH(tag, buf, "%include", var_include);
202 MATCH(tag, buf, "%root_menu", var_rootmenu); 210 MATCH(tag, buf, "%root_menu", var_rootmenu);
211 MATCH(tag, buf, "%format", var_format);
203 MATCH(tag, buf, "->", menu_next); 212 MATCH(tag, buf, "->", menu_next);
204 MATCH(tag, buf, "==>", menu_load); 213 MATCH(tag, buf, "==>", menu_load);
205 214
@@ -249,45 +258,36 @@ static int get_clause(int *condition)
249 return 0; 258 return 0;
250} 259}
251 260
252static bool add_clause(struct search_instruction *inst, 261static bool read_clause(struct tagcache_search_clause *clause)
253 int tag, int type, const char *str)
254{ 262{
255 int len = strlen(str); 263 char buf[256];
256 struct tagcache_search_clause *clause;
257 264
258 if (inst->clause_count[inst->tagorder_count] >= TAGCACHE_MAX_CLAUSES) 265 if (get_tag(&clause->tag) <= 0)
259 {
260 logf("Too many clauses");
261 return false; 266 return false;
262 }
263 267
264 clause = &inst->clause[inst->tagorder_count] 268 if (get_clause(&clause->type) <= 0)
265 [inst->clause_count[inst->tagorder_count]];
266 if (len >= (int)sizeof(clause->str) - 1)
267 {
268 logf("Too long str in condition");
269 return false; 269 return false;
270 }
271 270
272 clause->tag = tag; 271 if (get_token_str(buf, sizeof buf) < 0)
273 clause->type = type; 272 return false;
274 if (len == 0) 273
274 clause->str = buffer_alloc(strlen(buf)+1);
275 strcpy(clause->str, buf);
276
277 logf("got clause: %d/%d [%s]", clause->tag, clause->type, clause->str);
278
279 if (*(clause->str) == '\0')
275 clause->input = true; 280 clause->input = true;
276 else 281 else
277 clause->input = false; 282 clause->input = false;
278 283
279 if (tagcache_is_numeric_tag(tag)) 284 if (tagcache_is_numeric_tag(clause->tag))
280 { 285 {
281 clause->numeric = true; 286 clause->numeric = true;
282 clause->numeric_data = atoi(str); 287 clause->numeric_data = atoi(clause->str);
283 } 288 }
284 else 289 else
285 {
286 clause->numeric = false; 290 clause->numeric = false;
287 strcpy(clause->str, str);
288 }
289
290 inst->clause_count[inst->tagorder_count]++;
291 291
292 return true; 292 return true;
293} 293}
@@ -313,12 +313,38 @@ static int get_format_str(struct display_format *fmt)
313{ 313{
314 int ret; 314 int ret;
315 char buf[128]; 315 char buf[128];
316 int i;
316 317
317 memset(fmt, 0, sizeof(struct display_format)); 318 memset(fmt, 0, sizeof(struct display_format));
318 319
319 if (get_token_str(fmt->formatstr, sizeof fmt->formatstr) < 0) 320 if (get_token_str(fmt->name, sizeof fmt->name) < 0)
321 return -10;
322
323 /* Determine the group id */
324 fmt->group_id = 0;
325 for (i = 0; i < format_count; i++)
326 {
327 if (!strcasecmp(formats[i]->name, fmt->name))
328 {
329 fmt->group_id = formats[i]->group_id;
330 break;
331 }
332
333 if (formats[i]->group_id > fmt->group_id)
334 fmt->group_id = formats[i]->group_id;
335 }
336
337 if (i == format_count)
338 fmt->group_id++;
339
340 logf("format: (%d) %s", fmt->group_id, fmt->name);
341
342 if (get_token_str(buf, sizeof buf) < 0)
320 return -10; 343 return -10;
321 344
345 fmt->formatstr = buffer_alloc(strlen(buf) + 1);
346 strcpy(fmt->formatstr, buf);
347
322 while (fmt->tag_count < MAX_TAGS) 348 while (fmt->tag_count < MAX_TAGS)
323 { 349 {
324 ret = get_tag(&fmt->tags[fmt->tag_count]); 350 ret = get_tag(&fmt->tags[fmt->tag_count]);
@@ -353,27 +379,79 @@ static int get_format_str(struct display_format *fmt)
353 } 379 }
354 } 380 }
355 381
356 fmt->valid = true; 382 return 1;
383}
384
385static int add_format(const char *buf)
386{
387 strp = buf;
388
389 if (formats[format_count] == NULL)
390 formats[format_count] = buffer_alloc(sizeof(struct display_format));
391
392 memset(formats[format_count], 0, sizeof(struct display_format));
393 if (get_format_str(formats[format_count]) < 0)
394 {
395 logf("get_format_str() parser failed!");
396 return -4;
397 }
398
399 while (*strp != '\0' && *strp != '?')
400 strp++;
401
402 if (*strp == '?')
403 {
404 int clause_count = 0;
405 strp++;
406
407 while (1)
408 {
409 formats[format_count]->clause[clause_count] =
410 buffer_alloc(sizeof(struct tagcache_search_clause));
411
412 if (!read_clause(formats[format_count]->clause[clause_count]))
413 break;
414
415 clause_count++;
416 }
417
418 formats[format_count]->clause_count = clause_count;
419 }
420
421 format_count++;
357 422
358 return 1; 423 return 1;
359} 424}
360 425
361static int get_condition(struct search_instruction *inst) 426static int get_condition(struct search_instruction *inst)
362{ 427{
363 int tag; 428 int clause_count;
364 int condition;
365 char buf[128]; 429 char buf[128];
366 430
367 switch (*strp) 431 switch (*strp)
368 { 432 {
369 case '=': 433 case '=':
370 if (get_format_str(&inst->format[inst->tagorder_count]) < 0) 434 {
435 int i;
436
437 if (get_token_str(buf, sizeof buf) < 0)
438 return -1;
439
440 for (i = 0; i < format_count; i++)
371 { 441 {
372 logf("get_format_str() parser failed!"); 442 if (!strcasecmp(formats[i]->name, buf))
373 return -4; 443 break;
374 } 444 }
445
446 if (i == format_count)
447 {
448 logf("format not found: %s", buf);
449 return -2;
450 }
451
452 inst->format_id[inst->tagorder_count] = formats[i]->group_id;
375 return 1; 453 return 1;
376 454 }
377 case '?': 455 case '?':
378 case ' ': 456 case ' ':
379 case '&': 457 case '&':
@@ -384,17 +462,20 @@ static int get_condition(struct search_instruction *inst)
384 return 0; 462 return 0;
385 } 463 }
386 464
387 if (get_tag(&tag) <= 0) 465 clause_count = inst->clause_count[inst->tagorder_count];
388 return -1; 466 if (clause_count >= TAGCACHE_MAX_CLAUSES)
467 {
468 logf("Too many clauses");
469 return false;
470 }
389 471
390 if (get_clause(&condition) <= 0) 472 inst->clause[inst->tagorder_count][clause_count] =
391 return -2; 473 buffer_alloc(sizeof(struct tagcache_search_clause));
392 474
393 if (get_token_str(buf, sizeof buf) < 0) 475 if (!read_clause(inst->clause[inst->tagorder_count][clause_count]))
394 return -3; 476 return -1;
395 477
396 logf("got clause: %d/%d [%s]", tag, condition, buf); 478 inst->clause_count[inst->tagorder_count]++;
397 add_clause(inst, tag, condition, buf);
398 479
399 return 1; 480 return 1;
400} 481}
@@ -465,7 +546,9 @@ static bool parse_search(struct menu_entry *entry, const char *str)
465 546
466 logf("tag: %d", inst->tagorder[inst->tagorder_count]); 547 logf("tag: %d", inst->tagorder[inst->tagorder_count]);
467 548
468 while (get_condition(inst) > 0) ; 549 while ( (ret = get_condition(inst)) > 0 ) ;
550 if (ret < 0)
551 return false;
469 552
470 inst->tagorder_count++; 553 inst->tagorder_count++;
471 554
@@ -658,6 +741,13 @@ static bool parse_menu(const char *filename)
658 741
659 switch (variable) 742 switch (variable)
660 { 743 {
744 case var_format:
745 if (add_format(strp) < 0)
746 {
747 logf("Format add fail: %s", data);
748 }
749 break;
750
661 case var_include: 751 case var_include:
662 if (get_token_str(data, sizeof(data)) < 0) 752 if (get_token_str(data, sizeof(data)) < 0)
663 { 753 {
@@ -731,9 +821,9 @@ static bool parse_menu(const char *filename)
731 menu->items[menu->itemcount] = buffer_alloc(sizeof(struct menu_entry)); 821 menu->items[menu->itemcount] = buffer_alloc(sizeof(struct menu_entry));
732 memset(menu->items[menu->itemcount], 0, sizeof(struct menu_entry)); 822 memset(menu->items[menu->itemcount], 0, sizeof(struct menu_entry));
733 menu->items[menu->itemcount]->si = buffer_alloc(sizeof(struct search_instruction)); 823 menu->items[menu->itemcount]->si = buffer_alloc(sizeof(struct search_instruction));
734 memset(menu->items[menu->itemcount]->si, 0, sizeof(struct search_instruction));
735 } 824 }
736 825
826 memset(menu->items[menu->itemcount]->si, 0, sizeof(struct search_instruction));
737 if (!parse_search(menu->items[menu->itemcount], buf)) 827 if (!parse_search(menu->items[menu->itemcount], buf))
738 continue; 828 continue;
739 829
@@ -746,6 +836,7 @@ static bool parse_menu(const char *filename)
746 836
747void tagtree_init(void) 837void tagtree_init(void)
748{ 838{
839 format_count = 0;
749 menu_count = 0; 840 menu_count = 0;
750 menu = NULL; 841 menu = NULL;
751 root_menu = 0; 842 root_menu = 0;
@@ -852,14 +943,21 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
852 int j; 943 int j;
853 944
854 for (j = 0; j < csi->clause_count[i]; j++) 945 for (j = 0; j < csi->clause_count[i]; j++)
855 tagcache_search_add_clause(tcs, &csi->clause[i][j]); 946 tagcache_search_add_clause(tcs, csi->clause[i][j]);
856 } 947 }
857 948
858 current_offset = offset; 949 current_offset = offset;
859 current_entry_count = 0; 950 current_entry_count = 0;
860 c->dirfull = false; 951 c->dirfull = false;
861 fmt = &csi->format[level]; 952
862 if (fmt->valid) 953 fmt = NULL;
954 for (i = 0; i < format_count; i++)
955 {
956 if (formats[i]->group_id == csi->format_id[level])
957 fmt = formats[i];
958 }
959
960 if (fmt)
863 { 961 {
864 sort_inverse = fmt->sort_inverse; 962 sort_inverse = fmt->sort_inverse;
865 sort_limit = fmt->limit; 963 sort_limit = fmt->limit;
@@ -900,12 +998,27 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
900 else 998 else
901 dptr->extraseek = tcs->result_seek; 999 dptr->extraseek = tcs->result_seek;
902 1000
903 if (!tcs->ramresult || fmt->valid) 1001 fmt = NULL;
1002 /* Check the format */
1003 for (i = 0; i < format_count; i++)
1004 {
1005 if (formats[i]->group_id != csi->format_id[level])
1006 continue;
1007
1008 if (tagcache_check_clauses(tcs, formats[i]->clause,
1009 formats[i]->clause_count))
1010 {
1011 fmt = formats[i];
1012 break;
1013 }
1014 }
1015
1016 if (!tcs->ramresult || fmt)
904 { 1017 {
905 char buf[MAX_PATH]; 1018 char buf[MAX_PATH];
906 int buf_pos = 0; 1019 int buf_pos = 0;
907 1020
908 if (fmt->valid) 1021 if (fmt)
909 { 1022 {
910 char fmtbuf[8]; 1023 char fmtbuf[8];
911 bool read_format = false; 1024 bool read_format = false;
@@ -968,7 +1081,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
968 } 1081 }
969 1082
970 dptr->name = &c->name_buffer[namebufused]; 1083 dptr->name = &c->name_buffer[namebufused];
971 if (fmt->valid) 1084 if (fmt)
972 namebufused += buf_pos; 1085 namebufused += buf_pos;
973 else 1086 else
974 namebufused += tcs->result_len; 1087 namebufused += tcs->result_len;
@@ -980,7 +1093,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs,
980 sort = false; 1093 sort = false;
981 break ; 1094 break ;
982 } 1095 }
983 if (fmt->valid) 1096 if (fmt)
984 strcpy(dptr->name, buf); 1097 strcpy(dptr->name, buf);
985 else 1098 else
986 strcpy(dptr->name, tcs->result); 1099 strcpy(dptr->name, tcs->result);
@@ -1192,7 +1305,7 @@ int tagtree_enter(struct tree_context* c)
1192 { 1305 {
1193 for (j = 0; j < csi->clause_count[i]; j++) 1306 for (j = 0; j < csi->clause_count[i]; j++)
1194 { 1307 {
1195 if (!csi->clause[i][j].input) 1308 if (!csi->clause[i][j]->input)
1196 continue; 1309 continue;
1197 1310
1198 rc = kbd_input(searchstring, sizeof(searchstring)); 1311 rc = kbd_input(searchstring, sizeof(searchstring));
@@ -1202,11 +1315,11 @@ int tagtree_enter(struct tree_context* c)
1202 return 0; 1315 return 0;
1203 } 1316 }
1204 1317
1205 if (csi->clause[i][j].numeric) 1318 if (csi->clause[i][j]->numeric)
1206 csi->clause[i][j].numeric_data = atoi(searchstring); 1319 csi->clause[i][j]->numeric_data = atoi(searchstring);
1207 else 1320 else
1208 strncpy(csi->clause[i][j].str, searchstring, 1321 strncpy(csi->clause[i][j]->str, searchstring,
1209 sizeof(csi->clause[i][j].str)-1); 1322 sizeof(csi->clause[i][j]->str)-1);
1210 } 1323 }
1211 } 1324 }
1212 } 1325 }
@@ -1297,6 +1410,7 @@ bool insert_all_playlist(struct tree_context *c, int position, bool queue)
1297 int i; 1410 int i;
1298 char buf[MAX_PATH]; 1411 char buf[MAX_PATH];
1299 int from, to, direction; 1412 int from, to, direction;
1413 int files_left = c->filesindir;
1300 1414
1301 cpu_boost_id(true, CPUBOOSTID_TAGTREE); 1415 cpu_boost_id(true, CPUBOOSTID_TAGTREE);
1302 if (!tagcache_search(&tcs, tag_filename)) 1416 if (!tagcache_search(&tcs, tag_filename))
@@ -1321,7 +1435,8 @@ bool insert_all_playlist(struct tree_context *c, int position, bool queue)
1321 1435
1322 for (i = from; i != to; i += direction) 1436 for (i = from; i != to; i += direction)
1323 { 1437 {
1324 if (!show_search_progress(false, i)) 1438 /* Count back to zero */
1439 if (!show_search_progress(false, files_left--))
1325 break; 1440 break;
1326 1441
1327 if (!tagcache_retrieve(&tcs, tagtree_get_entry(c, i)->extraseek, 1442 if (!tagcache_retrieve(&tcs, tagtree_get_entry(c, i)->extraseek,