Путь: Toys/POSIX, команды версии: Ver.4 Ver.9 Комментарии в файле test.c : Команд: 2 test
test_glue _КЛЕЙ логический по умолчанию г зависит от ТЕСТ || Ш _GLUE bool default y depends on TEST || SH Исходный текст в файле test.c #include "toys.h" // Consume 3, 2, or 1 argument test, returning result and *count used. static int do_test(char **args, int *count) { char c, *s; int i; if (*count>=3) { *count = 3; char *s = args[1], *ss = "eqnegtgeltle"; // TODO shell integration case insensitivity if (!strcmp(s, "=") || !strcmp(s, "==")) return !strcmp(args[0], args[2]); if (!strcmp(s, "!=")) return strcmp(args[0], args[2]); if (!strcmp(s, "=~")) { regex_t reg; // TODO: regex needs integrated quoting support with the shell. // Ala [[ abc =~ "1"* ]] matches but [[ abc =~ 1"*" ]] does not xregcomp(®, args[2], REG_NOSUB); // REG_EXTENDED? REG_ICASE? i = regexec(®, args[0], 0, 0, 0); regfree(®); return !i; } if ((*s=='<' || *s=='>') && !s[1]) { i = strcmp(args[0], args[2]); return (*s=='<') ? i<0 : i>0; } if (*s=='-' && strlen(s)==3 && (s = strstr(ss, s+1)) && !((i = s-ss)&1)) { long long a = atolx(args[0]), b = atolx(args[2]); if (!i) return a == b; if (i==2) return a != b; if (i==4) return a > b; if (i==6) return a >= b; if (i==8) return a < b; if (i==10) return a<= b; } } s = *args; if (*count>=2 && *s == '-' && s[1] && !s[2]) { *count = 2; c = s[1]; if (c=='a') c = 'e'; if (-1 != (i = stridx("hLbcdefgkpSusxwr", c))) { struct stat st; if (i>=13) return !access(args[1], 1<<(i-13)); // stat or lstat, check s if (-1 == ((i<2) ? lstat : stat)(args[1], &st)) return 0; if (c == 's') return !!st.st_size; // otherwise 1<<32 == 0 // handle file type checking and SUID/SGID if ((i = ((char []){80,80,48,16,32,0,64,2,1,8,96,4}[i])<<9)>=4096) return (st.st_mode&S_IFMT) == i; else return (st.st_mode & i) == i; } else if (c == 'z') return !*args[1]; else if (c == 'n') return *args[1]; else if (c == 't') return isatty(atolx(args[1])); } return *count = 0; } #define NOT 1 // Most recent test had an odd number of preceding ! #define AND 2 // test before -a failed since -o or ( so force false #define OR 4 // test before -o succeeded since ( so force true void test_main(void) { char *s = (void *)1; int pos, paren, pstack, result = 0; toys.exitval = 2; if (CFG_TOYBOX && *toys.which->name=='[') { if (toys.optc) for (s = toys.optargs[--toys.optc]; *s==']'; s++); if (*s) error_exit("Missing ']'"); } // loop through command line arguments if (toys.optc) for (pos = paren = pstack = 0; ; pos++) { int len = toys.optc-pos; if (!len) perror_exit("need arg @%d", pos); // Evaluate next test result = do_test(toys.optargs+pos, &len); pos += len; // Single argument could be ! ( or nonempty if (!len) { if (toys.optargs[pos+1]) { if (!strcmp("!", toys.optargs[pos])) { pstack ^= NOT; continue; } if (!strcmp("(", toys.optargs[pos])) { if (++paren>9) perror_exit("bad ("); pstack <<= 3; continue; } } result = *toys.optargs[pos++]; } s = toys.optargs[pos]; for (;;) { // Handle pending ! -a -o (the else means -o beats -a) if (pstack&NOT) result = !result; pstack &= ~NOT; if (pstack&OR) result = 1; else if (pstack&AND) result = 0; // Do it again for every ) if (!paren || pos==toys.optc || strcmp(")", s)) break; paren--; pstack >>= 3; s = toys.optargs[++pos]; } // Out of arguments? if (pos==toys.optc) { if (paren) perror_exit("need )"); break; } // are we followed by -a or -o? if (!strcmp("-a", s)) { if (!result) pstack |= AND; } else if (!strcmp("-o", s)) { // -o flushes -a even if previous test was false pstack &=~AND; if (result) pstack |= OR; } else error_exit("too many arguments"); } // Invert C logic to get shell logic toys.exitval = !result; } |