mtglist

diff src/mtglist.c @ 1:7211fa8db425

added filters
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 03 Nov 2014 01:20:40 +0200
parents 0a45dfe93e66
children
line diff
     1.1 --- a/src/mtglist.c	Sun Nov 02 11:07:45 2014 +0200
     1.2 +++ b/src/mtglist.c	Mon Nov 03 01:20:40 2014 +0200
     1.3 @@ -1,40 +1,164 @@
     1.4  #include <stdio.h>
     1.5  #include <stdlib.h>
     1.6  #include <string.h>
     1.7 +#include <ctype.h>
     1.8  #include "mtg.h"
     1.9  
    1.10 +static void print_usage(const char *argv0);
    1.11 +static const char *strstr_lower(const char *str, const char *sub);
    1.12 +
    1.13 +int opt_list;
    1.14 +int opt_count;
    1.15 +unsigned int opt_color_filter;
    1.16 +int opt_color_filter_excl;
    1.17 +enum mtg_card_type opt_type_filter = MTG_TYPE_UNKNOWN;
    1.18 +const char *opt_ed_filter;
    1.19 +
    1.20  int main(int argc, char **argv)
    1.21  {
    1.22  	const struct mtg_card *card;
    1.23 -	const char *fname = "cardlist";
    1.24 -	int ncards;
    1.25 -
    1.26 -	if(argv[1]) fname = argv[1];
    1.27 +	int i, ncards, num_done = 0;
    1.28  
    1.29  	if(mtg_init() == -1) {
    1.30  		return 1;
    1.31  	}
    1.32  
    1.33 -	if(mtg_load_cards(fname) == -1) {
    1.34 -		mtg_destroy();
    1.35 +	for(i=1; i<argc; i++) {
    1.36 +		if(argv[i][0] == '-') {
    1.37 +			if(argv[i][2] != 0) {
    1.38 +				fprintf(stderr, "invalid option: %s\n", argv[i]);
    1.39 +				return 1;
    1.40 +			}
    1.41 +			switch(argv[i][1]) {
    1.42 +			case 'l':
    1.43 +				opt_list = 1;
    1.44 +				break;
    1.45 +
    1.46 +			case 'n':
    1.47 +				opt_count = 1;
    1.48 +				break;
    1.49 +
    1.50 +			case 'c':
    1.51 +				{
    1.52 +					unsigned int c = mtg_parse_multicolor(argv[++i]);
    1.53 +					if(mtg_is_multicolor(c)) {
    1.54 +						opt_color_filter = c;
    1.55 +						opt_color_filter_excl = 1;
    1.56 +					} else {
    1.57 +						opt_color_filter |= c;
    1.58 +						opt_color_filter_excl = 0;
    1.59 +					}
    1.60 +					if(strstr(argv[i], "!")) {
    1.61 +						opt_color_filter_excl = 1;
    1.62 +					}
    1.63 +				}
    1.64 +				break;
    1.65 +
    1.66 +			case 't':
    1.67 +				if((opt_type_filter = mtg_str_type(argv[++i])) == MTG_TYPE_UNKNOWN) {
    1.68 +					fprintf(stderr, "invalid type: %s\n", argv[i]);
    1.69 +					return 1;
    1.70 +				}
    1.71 +				break;
    1.72 +
    1.73 +			case 'e':
    1.74 +				opt_ed_filter = argv[++i];
    1.75 +				break;
    1.76 +
    1.77 +			case 'h':
    1.78 +				print_usage(argv[0]);
    1.79 +				return 0;
    1.80 +
    1.81 +			default:
    1.82 +				fprintf(stderr, "invalid option: %s\n", argv[i]);
    1.83 +				return 1;
    1.84 +			}
    1.85 +		} else {
    1.86 +			unsigned int card_mask = opt_color_filter ? opt_color_filter : 0xffff;
    1.87 +
    1.88 +			if(mtg_load_cards(argv[i]) == -1) {
    1.89 +				mtg_destroy();
    1.90 +				return 1;
    1.91 +			}
    1.92 +
    1.93 +			ncards = 0;
    1.94 +
    1.95 +			mtg_iter_begin();
    1.96 +			while((card = mtg_iter_next())) {
    1.97 +				if(opt_color_filter_excl) {
    1.98 +					if(card_mask != card->color) {
    1.99 +						continue;
   1.100 +					}
   1.101 +				} else {
   1.102 +					if(!(card_mask & card->color)) {
   1.103 +						continue;
   1.104 +					}
   1.105 +				}
   1.106 +
   1.107 +				if(opt_type_filter != MTG_TYPE_UNKNOWN && opt_type_filter != card->type) {
   1.108 +					continue;
   1.109 +				}
   1.110 +
   1.111 +				if(opt_ed_filter && !strstr_lower(card->edition, opt_ed_filter)) {
   1.112 +					continue;
   1.113 +				}
   1.114 +
   1.115 +				if(opt_list) {
   1.116 +					printf("%3d  ", card->count);
   1.117 +					printf("%-11s ", mtg_color_str(card->color));
   1.118 +					printf("%-32s ", card->name);
   1.119 +					printf("%-12s ", mtg_type_str(card->type));
   1.120 +					printf("%s\n", card->edition);
   1.121 +				}
   1.122 +
   1.123 +				ncards += card->count;
   1.124 +			}
   1.125 +
   1.126 +			if(opt_count) {
   1.127 +				printf("Total cards: %d\n", ncards);
   1.128 +			}
   1.129 +
   1.130 +			mtg_destroy();
   1.131 +			num_done++;
   1.132 +		}
   1.133 +	}
   1.134 +
   1.135 +	if(num_done == 0) {
   1.136 +		fprintf(stderr, "you must specify a cardlist\n");
   1.137  		return 1;
   1.138  	}
   1.139  
   1.140 -	ncards = 0;
   1.141 +	return 0;
   1.142 +}
   1.143  
   1.144 -	mtg_iter_begin();
   1.145 -	while((card = mtg_iter_next())) {
   1.146 -		printf("%3d  ", card->count);
   1.147 -		printf("%-11s ", mtg_color_str(card->color));
   1.148 -		printf("%-32s ", card->name);
   1.149 -		printf("%-12s ", mtg_type_str(card->type));
   1.150 -		printf("%s\n", card->edition);
   1.151 +static void print_usage(const char *argv0)
   1.152 +{
   1.153 +	printf("Usage: %s [options] <cardlist>\n", argv0);
   1.154 +	printf("Options:\n");
   1.155 +	printf(" -c <color>   match specified color (eg: \"red\", \"red/green\")\n");
   1.156 +	printf("              use ! to exclude multi (eg: \"red!\" doesn't match \"red/black\")\n");
   1.157 +	printf(" -t <type>    match specified card type (creature, instant, etc)\n");
   1.158 +	printf(" -e <edition> match specified edition (substring matching: \"5th\", \"5\",\n");
   1.159 +	printf("              and \"5th edition\" all match the 5th edition)\n");
   1.160 +	printf(" -l           print list of cards matching filters (or all)\n");
   1.161 +	printf(" -n           print a count of matched cards\n");
   1.162 +}
   1.163  
   1.164 -		ncards += card->count;
   1.165 +static const char *strstr_lower(const char *str, const char *sub)
   1.166 +{
   1.167 +	int i, sublen = strlen(sub);
   1.168 +
   1.169 +	while(*str) {
   1.170 +		for(i=0; i<sublen; i++) {
   1.171 +			if(tolower(str[i]) != tolower(sub[i])) {
   1.172 +				break;
   1.173 +			}
   1.174 +		}
   1.175 +		if(i == sublen) {
   1.176 +			return str;
   1.177 +		}
   1.178 +		++str;
   1.179  	}
   1.180  
   1.181 -	printf("Total cards: %d\n", ncards);
   1.182 -
   1.183 -	mtg_destroy();
   1.184  	return 0;
   1.185  }