mtglist
changeset 1:7211fa8db425 tip
added filters
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 03 Nov 2014 01:20:40 +0200 |
parents | 0a45dfe93e66 |
children | |
files | src/mtg.c src/mtg.h src/mtglist.c |
diffstat | 3 files changed, 146 insertions(+), 28 deletions(-) [+] |
line diff
1.1 --- a/src/mtg.c Sun Nov 02 11:07:45 2014 +0200 1.2 +++ b/src/mtg.c Mon Nov 03 01:20:40 2014 +0200 1.3 @@ -195,11 +195,6 @@ 1.4 return bits > 1; 1.5 } 1.6 1.7 -static void dbgprint(struct rbnode *node, void *cls) 1.8 -{ 1.9 - fprintf(stderr, "%s\n", (char*)rb_node_key(node)); 1.10 -} 1.11 - 1.12 static int load_editions(void) 1.13 { 1.14 FILE *fp; 1.15 @@ -222,13 +217,11 @@ 1.16 rb_insert(editions, strdup(code), strdup(name)); 1.17 } 1.18 1.19 - rb_foreach(editions, dbgprint, 0); 1.20 - 1.21 fclose(fp); 1.22 return 0; 1.23 } 1.24 1.25 -static unsigned int parse_multicolor(const char *str) 1.26 +unsigned int mtg_parse_multicolor(const char *str) 1.27 { 1.28 int i; 1.29 unsigned int mask = 0; 1.30 @@ -259,12 +252,12 @@ 1.31 } 1.32 cstr[i] = 0; 1.33 1.34 - if((res = parse_multicolor(colstr))) { 1.35 + if((res = mtg_parse_multicolor(colstr))) { 1.36 return res; 1.37 } 1.38 1.39 if(strcmp(cstr, "*") == 0) { 1.40 - if((res = parse_multicolor(notes))) { 1.41 + if((res = mtg_parse_multicolor(notes))) { 1.42 return res; 1.43 } 1.44 return MTG_COL_MULTI;
2.1 --- a/src/mtg.h Sun Nov 02 11:07:45 2014 +0200 2.2 +++ b/src/mtg.h Mon Nov 03 01:20:40 2014 +0200 2.3 @@ -47,6 +47,7 @@ 2.4 const char *mtg_edition(const char *edcode); 2.5 2.6 int mtg_is_multicolor(unsigned int color); 2.7 +unsigned int mtg_parse_multicolor(const char *str); 2.8 2.9 2.10 #endif /* MTG_H_ */
3.1 --- a/src/mtglist.c Sun Nov 02 11:07:45 2014 +0200 3.2 +++ b/src/mtglist.c Mon Nov 03 01:20:40 2014 +0200 3.3 @@ -1,40 +1,164 @@ 3.4 #include <stdio.h> 3.5 #include <stdlib.h> 3.6 #include <string.h> 3.7 +#include <ctype.h> 3.8 #include "mtg.h" 3.9 3.10 +static void print_usage(const char *argv0); 3.11 +static const char *strstr_lower(const char *str, const char *sub); 3.12 + 3.13 +int opt_list; 3.14 +int opt_count; 3.15 +unsigned int opt_color_filter; 3.16 +int opt_color_filter_excl; 3.17 +enum mtg_card_type opt_type_filter = MTG_TYPE_UNKNOWN; 3.18 +const char *opt_ed_filter; 3.19 + 3.20 int main(int argc, char **argv) 3.21 { 3.22 const struct mtg_card *card; 3.23 - const char *fname = "cardlist"; 3.24 - int ncards; 3.25 - 3.26 - if(argv[1]) fname = argv[1]; 3.27 + int i, ncards, num_done = 0; 3.28 3.29 if(mtg_init() == -1) { 3.30 return 1; 3.31 } 3.32 3.33 - if(mtg_load_cards(fname) == -1) { 3.34 - mtg_destroy(); 3.35 + for(i=1; i<argc; i++) { 3.36 + if(argv[i][0] == '-') { 3.37 + if(argv[i][2] != 0) { 3.38 + fprintf(stderr, "invalid option: %s\n", argv[i]); 3.39 + return 1; 3.40 + } 3.41 + switch(argv[i][1]) { 3.42 + case 'l': 3.43 + opt_list = 1; 3.44 + break; 3.45 + 3.46 + case 'n': 3.47 + opt_count = 1; 3.48 + break; 3.49 + 3.50 + case 'c': 3.51 + { 3.52 + unsigned int c = mtg_parse_multicolor(argv[++i]); 3.53 + if(mtg_is_multicolor(c)) { 3.54 + opt_color_filter = c; 3.55 + opt_color_filter_excl = 1; 3.56 + } else { 3.57 + opt_color_filter |= c; 3.58 + opt_color_filter_excl = 0; 3.59 + } 3.60 + if(strstr(argv[i], "!")) { 3.61 + opt_color_filter_excl = 1; 3.62 + } 3.63 + } 3.64 + break; 3.65 + 3.66 + case 't': 3.67 + if((opt_type_filter = mtg_str_type(argv[++i])) == MTG_TYPE_UNKNOWN) { 3.68 + fprintf(stderr, "invalid type: %s\n", argv[i]); 3.69 + return 1; 3.70 + } 3.71 + break; 3.72 + 3.73 + case 'e': 3.74 + opt_ed_filter = argv[++i]; 3.75 + break; 3.76 + 3.77 + case 'h': 3.78 + print_usage(argv[0]); 3.79 + return 0; 3.80 + 3.81 + default: 3.82 + fprintf(stderr, "invalid option: %s\n", argv[i]); 3.83 + return 1; 3.84 + } 3.85 + } else { 3.86 + unsigned int card_mask = opt_color_filter ? opt_color_filter : 0xffff; 3.87 + 3.88 + if(mtg_load_cards(argv[i]) == -1) { 3.89 + mtg_destroy(); 3.90 + return 1; 3.91 + } 3.92 + 3.93 + ncards = 0; 3.94 + 3.95 + mtg_iter_begin(); 3.96 + while((card = mtg_iter_next())) { 3.97 + if(opt_color_filter_excl) { 3.98 + if(card_mask != card->color) { 3.99 + continue; 3.100 + } 3.101 + } else { 3.102 + if(!(card_mask & card->color)) { 3.103 + continue; 3.104 + } 3.105 + } 3.106 + 3.107 + if(opt_type_filter != MTG_TYPE_UNKNOWN && opt_type_filter != card->type) { 3.108 + continue; 3.109 + } 3.110 + 3.111 + if(opt_ed_filter && !strstr_lower(card->edition, opt_ed_filter)) { 3.112 + continue; 3.113 + } 3.114 + 3.115 + if(opt_list) { 3.116 + printf("%3d ", card->count); 3.117 + printf("%-11s ", mtg_color_str(card->color)); 3.118 + printf("%-32s ", card->name); 3.119 + printf("%-12s ", mtg_type_str(card->type)); 3.120 + printf("%s\n", card->edition); 3.121 + } 3.122 + 3.123 + ncards += card->count; 3.124 + } 3.125 + 3.126 + if(opt_count) { 3.127 + printf("Total cards: %d\n", ncards); 3.128 + } 3.129 + 3.130 + mtg_destroy(); 3.131 + num_done++; 3.132 + } 3.133 + } 3.134 + 3.135 + if(num_done == 0) { 3.136 + fprintf(stderr, "you must specify a cardlist\n"); 3.137 return 1; 3.138 } 3.139 3.140 - ncards = 0; 3.141 + return 0; 3.142 +} 3.143 3.144 - mtg_iter_begin(); 3.145 - while((card = mtg_iter_next())) { 3.146 - printf("%3d ", card->count); 3.147 - printf("%-11s ", mtg_color_str(card->color)); 3.148 - printf("%-32s ", card->name); 3.149 - printf("%-12s ", mtg_type_str(card->type)); 3.150 - printf("%s\n", card->edition); 3.151 +static void print_usage(const char *argv0) 3.152 +{ 3.153 + printf("Usage: %s [options] <cardlist>\n", argv0); 3.154 + printf("Options:\n"); 3.155 + printf(" -c <color> match specified color (eg: \"red\", \"red/green\")\n"); 3.156 + printf(" use ! to exclude multi (eg: \"red!\" doesn't match \"red/black\")\n"); 3.157 + printf(" -t <type> match specified card type (creature, instant, etc)\n"); 3.158 + printf(" -e <edition> match specified edition (substring matching: \"5th\", \"5\",\n"); 3.159 + printf(" and \"5th edition\" all match the 5th edition)\n"); 3.160 + printf(" -l print list of cards matching filters (or all)\n"); 3.161 + printf(" -n print a count of matched cards\n"); 3.162 +} 3.163 3.164 - ncards += card->count; 3.165 +static const char *strstr_lower(const char *str, const char *sub) 3.166 +{ 3.167 + int i, sublen = strlen(sub); 3.168 + 3.169 + while(*str) { 3.170 + for(i=0; i<sublen; i++) { 3.171 + if(tolower(str[i]) != tolower(sub[i])) { 3.172 + break; 3.173 + } 3.174 + } 3.175 + if(i == sublen) { 3.176 + return str; 3.177 + } 3.178 + ++str; 3.179 } 3.180 3.181 - printf("Total cards: %d\n", ncards); 3.182 - 3.183 - mtg_destroy(); 3.184 return 0; 3.185 }