diff options
| -rw-r--r-- | arg.h | 61 | ||||
| -rw-r--r-- | xtest.c | 88 | 
2 files changed, 87 insertions, 62 deletions
| @@ -10,38 +10,51 @@ extern char *argv0;  /* use main(int argc, char *argv[]) */  #define ARGBEGIN	for (argv0 = *argv, argv++, argc--;\ -					argv[0] && argv[0][0] == '-'\ -					&& argv[0][1];\ +					argv[0] && argv[0][1];\  					argc--, argv++) {\  				char argc_;\  				char **argv_;\  				int brk_;\ -				if (argv[0][1] == '-' && argv[0][2] == '\0') {\ -					argv++;\ -					argc--;\ -					break;\ -				}\ -				for (brk_ = 0, argv[0]++, argv_ = argv;\ -						argv[0][0] && !brk_;\ -						argv[0]++) {\ -					if (argv_ != argv)\ +				if (argv[0][0] == '-') {\ +					if (argv[0][1] == '-' && argv[0][2] == '\0') {\ +						argv++;\ +						argc--;\  						break;\ -					argc_ = argv[0][0];\ -					switch (argc_) +					}\ +					for (brk_ = 0, argv[0]++, argv_ = argv;\ +							argv[0][0] && !brk_;\ +							argv[0]++) {\ +						if (argv_ != argv)\ +							break;\ +						argc_ = argv[0][0];\ +						switch (argc_)  /* Handles obsolete -NUM syntax */ -#define ARGNUM				case '0':\ -					case '1':\ -					case '2':\ -					case '3':\ -					case '4':\ -					case '5':\ -					case '6':\ -					case '7':\ -					case '8':\ -					case '9' +#define ARGNUM					case '0':\ +						case '1':\ +						case '2':\ +						case '3':\ +						case '4':\ +						case '5':\ +						case '6':\ +						case '7':\ +						case '8':\ +						case '9' + +#define ARGALT(SYMBOL)			}\ +				} else if (argv[0][0] == SYMBOL) {\ +					for (brk_ = 0, argv[0]++, argv_ = argv;\ +							argv[0][0] && !brk_;\ +							argv[0]++) {\ +						if (argv_ != argv)\ +							break;\ +						argc_ = argv[0][0];\ +						switch (argc_) -#define ARGEND			}\ +#define ARGEND				}\ +				} else {\ +					break;\ +				}\  			}  #define ARGC()		argc_ @@ -13,7 +13,8 @@  char *argv0;  static char delim = '\n'; -static long int tests = 0; +static long int pos_tests = 0; +static long int neg_tests = 0;  static int test_b(char *s) { struct stat buf; if ( stat(s, &buf)) return 0; return S_ISBLK  (buf.st_mode); }  static int test_c(char *s) { struct stat buf; if ( stat(s, &buf)) return 0; return S_ISCHR  (buf.st_mode); } @@ -44,29 +45,37 @@ test_t(char *s)  	return isatty((int)fd);  } +#define LIST_TESTS\ +	X('b', test_b, 0)\ +	X('c', test_c, 1)\ +	X('d', test_d, 2)\ +	X('e', test_e, 3)\ +	X('f', test_f, 4)\ +	X('g', test_g, 5)\ +	X('h', test_h, 6)\ +	X('k', test_k, 7)\ +	X('p', test_p, 8)\ +	X('r', test_r, 9)\ +	X('S', test_S, 10)\ +	X('s', test_s, 11)\ +	X('t', test_t, 12)\ +	X('u', test_u, 13)\ +	X('w', test_w, 14)\ +	X('x', test_x, 15) + +#define LIST_SYNONYMS\ +	X('L', test_h, 6) +  static int (*testmap[])(char *) = { -	test_b, -	test_c, -	test_d, -	test_e, -	test_f, -	test_g, -	test_h, -	test_k, -	test_p, -	test_r, -	test_S, -	test_s, -	test_t, -	test_u, -	test_w, -	test_x +#define X(FLAG, FUNC, NUM) FUNC, +	LIST_TESTS +#undef X  };  static void  usage(void)  { -	fprintf(stderr, "usage: %s [-0bcdefghkLprSstuwx] file ...\n", argv0); +	fprintf(stderr, "usage: %s [-0bcdefghkLprSstuwx] [+bcdefghkLprSstuwx] file ...\n", argv0);  	exit(1);  } @@ -74,8 +83,15 @@ static void  test(char *s)  {  	long int i, j; -	for (i = 0; j = 1L << i, j <= tests; i++) { -		if ((tests & j) && testmap[i](s)) { +	for (i = 0; j = 1L << i, j <= pos_tests; i++) { +		if ((pos_tests & j) && testmap[i](s)) { +			printf("%s%c", s, delim); +			fflush(stdout); +			break; +		} +	} +	for (i = 0; j = 1L << i, j <= neg_tests; i++) { +		if ((neg_tests & j) && !testmap[i](s)) {  			printf("%s%c", s, delim);  			fflush(stdout);  			break; @@ -94,28 +110,24 @@ main(int argc, char *argv[])  	case '0':  		delim = '\0';  		break; -	case 'b': tests |= 1 << 0; break; -	case 'c': tests |= 1 << 1; break; -	case 'd': tests |= 1 << 2; break; -	case 'e': tests |= 1 << 3; break; -	case 'f': tests |= 1 << 4; break; -	case 'g': tests |= 1 << 5; break; -	case 'h': tests |= 1 << 6; break; -	case 'k': tests |= 1 << 7; break; -	case 'L': tests |= 1 << 6; break; -	case 'p': tests |= 1 << 8; break; -	case 'r': tests |= 1 << 9; break; -	case 'S': tests |= 1 << 10; break; -	case 's': tests |= 1 << 11; break; -	case 't': tests |= 1 << 12; break; -	case 'u': tests |= 1 << 13; break; -	case 'w': tests |= 1 << 14; break; -	case 'x': tests |= 1 << 15; break; +#define X(FLAG, FUNC, NUM)\ +	case FLAG: pos_tests |= 1 << NUM; break; +	LIST_TESTS +	LIST_SYNONYMS +#undef X +	default: +		usage(); +	} ARGALT('+') { +#define X(FLAG, FUNC, NUM)\ +	case FLAG: neg_tests |= 1 << NUM; break; +	LIST_TESTS +	LIST_SYNONYMS +#undef X  	default:  		usage();  	} ARGEND; -	if (!tests) { +	if (!pos_tests && !neg_tests) {  		fprintf(stderr, "%s: at least one test is required\n", argv0);  		return 1;  	} | 
