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; } |