static arith_t primary(enum token n) { arith_t res; if (n == EOI) { syntax(NULL, "argument expected"); } if (n == LPAREN) { res = oexpr(t_lex(*++t_wp)); if (t_lex(*++t_wp) != RPAREN) syntax(NULL, "closing paren expected"); return res; } if (t_wp_op && t_wp_op->op_type == UNOP) { /* unary expression */ if (*++t_wp == NULL) syntax(t_wp_op->op_text, "argument expected"); switch (n) { case STREZ: return strlen(*t_wp) == 0; case STRNZ: return strlen(*t_wp) != 0; case FILTT: return isatty(getn(*t_wp)); default: return filstat(*t_wp, n); } } if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) { return binop(); } return strlen(*t_wp) > 0; }
int main(int argc, char **argv) { int res; char *p; if ((p = strrchr(argv[0], '/')) == NULL) p = argv[0]; else p++; if (strcmp(p, "[") == 0) { if (strcmp(argv[--argc], "]") != 0) error("missing ]"); argv[argc] = NULL; } /* no expression => false */ if (--argc <= 0) return 1; nargc = argc; t_wp = &argv[1]; parenlevel = 0; if (nargc == 4 && strcmp(*t_wp, "!") == 0) { /* Things like ! "" -o x do not fit in the normal grammar. */ --nargc; ++t_wp; res = oexpr(t_lex(*t_wp)); } else res = !oexpr(t_lex(*t_wp)); if (--nargc > 0) syntax(*t_wp, "unexpected operator"); return res; }
static arith_t primary(enum token n) { arith_t res; if (n == EOI) { syntax(NULL, "argument expected"); } if (n == LPAREN) { res = oexpr(t_lex(*++t_wp)); if (t_lex(*++t_wp) != RPAREN) syntax(NULL, "closing paren expected"); return res; } if (t_wp_op && t_wp_op->op_type == UNOP) { /* unary expression */ if (*++t_wp == NULL) syntax(t_wp_op->op_text, "argument expected"); if (n == STREZ) return t_wp[0][0] == '\0'; if (n == STRNZ) return t_wp[0][0] != '\0'; if (n == FILTT) return isatty(getn(*t_wp)); return filstat(*t_wp, n); } t_lex(t_wp[1]); if (t_wp_op && t_wp_op->op_type == BINOP) { return binop(); } return t_wp[0][0] != '\0'; }
int bb_test(int argc, char **argv) { int res; if (LONE_CHAR(argv[0], '[')) { --argc; if (NOT_LONE_CHAR(argv[argc], ']')) { bb_error_msg("missing ]"); return 2; } argv[argc] = NULL; } else if (strcmp(argv[0], "[[") == 0) { --argc; if (strcmp(argv[argc], "]]")) { bb_error_msg("missing ]]"); return 2; } argv[argc] = NULL; } res = setjmp(leaving); if (res) return res; /* resetting ngroups is probably unnecessary. it will * force a new call to getgroups(), which prevents using * group data fetched during a previous call. but the * only way the group data could be stale is if there's * been an intervening call to setgroups(), and this * isn't likely in the case of a shell. paranoia * prevails... */ ngroups = 0; /* Implement special cases from POSIX.2, section 4.62.4 */ if (argc == 1) return 1; if (argc == 2) return *argv[1] == '\0'; //assert(argc); if (LONE_CHAR(argv[1], '!')) { bool _off; if (argc == 3) return *argv[2] != '\0'; _off = argc - 4; t_lex(argv[2 + _off]); if (t_wp_op && t_wp_op->op_type == BINOP) { t_wp = &argv[1 + _off]; return binop() == 0; } } t_wp = &argv[1]; res = !oexpr(t_lex(*t_wp)); if (*t_wp != NULL && *++t_wp != NULL) { bb_error_msg("%s: unknown operand", *t_wp); return 2; } return res; }
/* The code below starts the part that still needs reworking for the * new geometry based tokens/logic */ static int primary(enum token n, struct exists_data *ed) { enum token nn; int res; if (n == EOI) return 0; /* missing expression */ if (n == LPAREN) { ed->t_wp_op = NULL; if ((nn = t_lex(*++(ed->t_wp), ed)) == RPAREN) return 0; /* missing expression */ res = oexpr(nn, ed); if (t_lex(*++(ed->t_wp), ed) != RPAREN) { bu_vls_printf(ed->message , "closing paren expected"); return 0; } return res; } if (ed->t_wp_op && ed->t_wp_op->op_type == UNOP) { /* unary expression */ if (!ed->no_op) { if (*++(ed->t_wp) == NULL) { bu_vls_printf(ed->message , "argument expected"); return 0; } } switch (n) { case OCOMB: bu_log("comb case"); /*return is_comb();*/ case OEXIST: return db_object_exists(ed); /*return db_lookup();*/ case ONULL: bu_log("null case"); /*return is_null();*/ case ONNULL: /* default case */ return db_object_exists_and_non_null(ed); case OPRIM: bu_log("primitive case"); /*return is_prim();*/ case OBVOL: bu_log("bounding volume case"); /*return has_vol();*/ default: /* not reached */ return 0; } } if (t_lex(ed->t_wp[1], ed), ed->t_wp_op && ed->t_wp_op->op_type == BINOP) { return binop(ed); } return 0; }
static arith_t aexpr(enum token n) { arith_t res; res = nexpr(n); if (t_lex(*++t_wp) == BAND) return aexpr(t_lex(*++t_wp)) && res; t_wp--; return res; }
static int oexpr(shinstance *psh, enum token n) { int res; res = aexpr(psh, n); if (t_lex(psh, *++psh->t_wp) == BOR) return oexpr(psh, t_lex(psh, *++psh->t_wp)) || res; psh->t_wp--; return res; }
static int aexpr(shinstance *psh, enum token n) { int res; res = nexpr(psh, n); if (t_lex(psh, *++psh->t_wp) == BAND) return aexpr(psh, t_lex(psh, *++psh->t_wp)) && res; psh->t_wp--; return res; }
static arith_t oexpr(enum token n) { arith_t res; res = aexpr(n); if (t_lex(*++t_wp) == BOR) { return oexpr(t_lex(*++t_wp)) || res; } t_wp--; return res; }
static int oexpr(enum token n) { int res; res = aexpr(n); if (t_lex(*++t_wp) == BOR) return oexpr(t_lex(*++t_wp)) || res; t_wp--; return res; }
static int aexpr(enum token n) { int res; res = nexpr(n); if (t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL) == BAND) return aexpr(t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL)) && res; t_wp--; nargc++; return res; }
static int oexpr(enum token n) { int res; res = aexpr(n); if (t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL) == BOR) return oexpr(t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL)) || res; t_wp--; nargc++; return res; }
int main(int argc, char **argv) { gid_t egid, gid; uid_t euid, uid; int res; char *p; if ((p = strrchr(argv[0], '/')) == NULL) p = argv[0]; else p++; if (strcmp(p, "[") == 0) { if (strcmp(argv[--argc], "]") != 0) error("missing ]"); argv[argc] = NULL; } /* no expression => false */ if (--argc <= 0) return 1; #ifndef SHELL setlocale(LC_CTYPE, ""); #endif /* XXX work around the absence of an eaccess(2) syscall */ egid = getegid(); euid = geteuid(); gid = getgid(); uid = getuid(); setregid(egid, gid); setreuid(euid, uid); nargc = argc; t_wp = &argv[1]; parenlevel = 0; if (nargc == 4 && strcmp(*t_wp, "!") == 0) { /* Things like ! "" -o x do not fit in the normal grammar. */ --nargc; ++t_wp; res = oexpr(t_lex(*t_wp)); } else res = !oexpr(t_lex(*t_wp)); if (--nargc > 0) syntax(*t_wp, "unexpected operator"); setregid(gid, egid); setreuid(uid, euid); return res; }
static int oexpr(enum token n) { int res = 0; for (;;) { res |= aexpr(n); n = t_lex(t_wp + 1); if (n != BOR) break; n = t_lex(t_wp += 2); } return res; }
int main(int argc, char *argv[]) { int res; if (strcmp(argv[0], "[") == 0) { if (strcmp(argv[--argc], "]")) errx(2, "missing ]"); argv[argc] = NULL; } /* Implement special cases from POSIX.2, section 4.62.4 */ switch (argc) { case 1: return 1; case 2: return (*argv[1] == '\0'); case 3: if (argv[1][0] == '!' && argv[1][1] == '\0') { return !(*argv[2] == '\0'); } break; case 4: if (argv[1][0] != '!' || argv[1][1] != '\0') { if (t_lex(argv[2]), t_wp_op && t_wp_op->op_type == BINOP) { t_wp = &argv[1]; return (binop() == 0); } } break; case 5: if (argv[1][0] == '!' && argv[1][1] == '\0') { if (t_lex(argv[3]), t_wp_op && t_wp_op->op_type == BINOP) { t_wp = &argv[2]; return !(binop() == 0); } } break; } t_wp = &argv[1]; res = !oexpr(t_lex(*t_wp)); if (*t_wp != NULL && *++t_wp != NULL) syntax(*t_wp, "unknown operand"); return res; }
extern int test_main(int argc, char** argv) { int res; if (strcmp(applet_name, "[") == 0) { if (strcmp(argv[--argc], "]")) error_msg_and_die("missing ]"); argv[argc] = NULL; } /* Implement special cases from POSIX.2, section 4.62.4 */ switch (argc) { case 1: exit( 1); case 2: exit (*argv[1] == '\0'); case 3: if (argv[1][0] == '!' && argv[1][1] == '\0') { exit (!(*argv[2] == '\0')); } break; case 4: if (argv[1][0] != '!' || argv[1][1] != '\0') { if (t_lex(argv[2]), t_wp_op && t_wp_op->op_type == BINOP) { t_wp = &argv[1]; exit (binop() == 0); } } break; case 5: if (argv[1][0] == '!' && argv[1][1] == '\0') { if (t_lex(argv[3]), t_wp_op && t_wp_op->op_type == BINOP) { t_wp = &argv[2]; exit (!(binop() == 0)); } } break; } t_wp = &argv[1]; res = !oexpr(t_lex(*t_wp)); if (*t_wp != NULL && *++t_wp != NULL) syntax(*t_wp, "unknown operand"); return( res); }
static int oexpr(enum token n) { int res; res = aexpr(n); if (res == -42 || *t_wp == NULL) return res; if (t_lex(*++t_wp) == BOR) { int res2 = oexpr(t_lex(*++t_wp)); return res2 != -42 ? res2 || res : res2; } t_wp--; return res; }
static int aexpr(enum token n) { int res = 1; for (;;) { if (!nexpr(n)) res = 0; n = t_lex(t_wp + 1); if (n != BAND) break; n = t_lex(t_wp += 2); } return res; }
static int oexpr(enum token n, struct exists_data *ed) { int res; res = aexpr(n, ed); if (*(ed->t_wp) == NULL) return res; if (t_lex(*++(ed->t_wp), ed) == BOR) { ed->t_wp_op = NULL; return oexpr(t_lex(*++(ed->t_wp), ed), ed) || res; } (ed->t_wp)--; return res; }
static int aexpr(enum token n) { int res; res = nexpr(n); if (res == -42 || *t_wp == NULL) return res; if (t_lex(*++t_wp) == BAND) { int res2 = aexpr(t_lex(*++t_wp)); return res2 != -42 ? res2 && res : res2; } t_wp--; return res; }
static int aexpr(enum token n, struct exists_data *ed) { int res; res = nexpr(n, ed); if (*(ed->t_wp) == NULL) return res; if (t_lex(*++(ed->t_wp), ed) == BAND) { ed->t_wp_op = NULL; return aexpr(t_lex(*++(ed->t_wp), ed), ed) && res; } (ed->t_wp)--; return res; }
static int nexpr(enum token n) { if (n == UNOT) return !nexpr(t_lex(*++t_wp)); return primary(n); }
static int nexpr(enum token n) { if (n == UNOT) return !nexpr(t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL)); return primary(n); }
static int binop(void) { const char *opnd1, *opnd2; struct t_op const *op; arith_t val1, val2; opnd1 = *t_wp; (void) t_lex(*++t_wp); op = t_wp_op; opnd2 = *++t_wp; if (opnd2 == NULL) syntax(op->op_text, "argument expected"); if (is_int_op(op->op_num)) { val1 = getn(opnd1); val2 = getn(opnd2); if (op->op_num == INTEQ) return val1 == val2; if (op->op_num == INTNE) return val1 != val2; if (op->op_num == INTGE) return val1 >= val2; if (op->op_num == INTGT) return val1 > val2; if (op->op_num == INTLE) return val1 <= val2; if (op->op_num == INTLT) return val1 < val2; } if (is_str_op(op->op_num)) { val1 = strcmp(opnd1, opnd2); if (op->op_num == STREQ) return val1 == 0; if (op->op_num == STRNE) return val1 != 0; if (op->op_num == STRLT) return val1 < 0; if (op->op_num == STRGT) return val1 > 0; } /* We are sure that these three are by now the only binops we didn't check * yet, so we do not check if the class is correct: */ /* if (is_file_op(op->op_num)) */ { struct stat b1, b2; if (stat(opnd1, &b1) || stat(opnd2, &b2)) return 0; /* false, since at least one stat failed */ if (op->op_num == FILNT) return b1.st_mtime > b2.st_mtime; if (op->op_num == FILOT) return b1.st_mtime < b2.st_mtime; if (op->op_num == FILEQ) return b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino; } return 1; /* NOTREACHED */ }
static int nexpr(shinstance *psh, enum token n) { if (n == UNOT) return !nexpr(psh, t_lex(psh, *++psh->t_wp)); return primary(psh, n); }
static int nexpr(enum token n, struct exists_data *ed) { if (n == UNOT) return !nexpr(t_lex(*++(ed->t_wp), ed), ed); return primary(n, ed); }
static int primary(enum token n) { enum token nn; int res; if (n == EOI) return 0; /* missing expression */ if (n == LPAREN) { if ((nn = t_lex(++t_wp)) == RPAREN) return 0; /* missing expression */ res = oexpr(nn); if (t_lex(++t_wp) != RPAREN) syntax(NULL, "closing paren expected"); return res; } if (t_wp_op && t_wp_op->op_type == UNOP) { /* unary expression */ if (*++t_wp == NULL) syntax(t_wp_op->op_text, "argument expected"); switch (n) { case STREZ: return strlen(*t_wp) == 0; case STRNZ: return strlen(*t_wp) != 0; case FILTT: return isatty(getn(*t_wp)); #ifdef HAVE_FACCESSAT case FILRD: return test_file_access(*t_wp, R_OK); case FILWR: return test_file_access(*t_wp, W_OK); case FILEX: return test_file_access(*t_wp, X_OK); #endif default: return filstat(*t_wp, n); } } if (t_lex(t_wp + 1), t_wp_op && t_wp_op->op_type == BINOP) { return binop(); } return strlen(*t_wp) > 0; }
int testcmd(int argc, char **argv) { const struct t_op *op; enum token n; int res = 1; if (*argv[0] == '[') { if (*argv[--argc] != ']') error("missing ]"); argv[argc] = NULL; } t_wp_op = NULL; recheck: argv++; argc--; if (argc < 1) return res; /* * POSIX prescriptions: he who wrote this deserves the Nobel * peace prize. */ switch (argc) { case 3: op = getop(argv[1]); if (op && op->op_type == BINOP) { n = OPERAND; goto eval; } /* fall through */ case 4: if (!strcmp(argv[0], "(") && !strcmp(argv[argc - 1], ")")) { argv[--argc] = NULL; argv++; argc--; } else if (!strcmp(argv[0], "!")) { res = 0; goto recheck; } } n = t_lex(argv); eval: t_wp = argv; res ^= oexpr(n); argv = t_wp; if (argv[0] != NULL && argv[1] != NULL) syntax(argv[0], "unexpected operator"); return res; }
static int nexpr(enum token n) { if (n == UNOT) { int res = nexpr(t_lex(*++t_wp)); return res != -42 ? !res : res; } return primary(n); }
static int primary(enum token n) { enum token nn; int res; if (n == EOI) return 0; /* missing expression */ if (n == LPAREN) { parenlevel++; if ((nn = t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL)) == RPAREN) { parenlevel--; return 0; /* missing expression */ } res = oexpr(nn); if (t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL) != RPAREN) syntax(NULL, "closing paren expected"); parenlevel--; return res; } if (t_wp_op && t_wp_op->op_type == UNOP) { /* unary expression */ if (--nargc == 0) syntax(t_wp_op->op_text, "argument expected"); switch (n) { case STREZ: return strlen(*++t_wp) == 0; case STRNZ: return strlen(*++t_wp) != 0; case FILTT: return isatty(getn(*++t_wp)); default: return filstat(*++t_wp, n); } } if (t_lex(nargc > 0 ? t_wp[1] : NULL), t_wp_op && t_wp_op->op_type == BINOP) { return binop(); } return strlen(*t_wp) > 0; }