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  }