/* Test if the current token is a whatever. Accepts the current token if * it is. Returns 0 if it is not, non-zero if it is (in the case of * TM_UNOP and TM_BINOP, the returned value is a Test_op). */ static int ptest_isa(Test_env *te, Test_meta meta) { /* Order important - indexed by Test_meta values */ static const char *const tokens[] = { "-o", "-a", "!", "(", ")" }; int ret; if (te->pos.wp >= te->wp_end) return meta == TM_END; if (meta == TM_UNOP || meta == TM_BINOP) ret = (int) test_isop(te, meta, *te->pos.wp); else if (meta == TM_END) ret = 0; else ret = strcmp(*te->pos.wp, tokens[(int) meta]) == 0; /* Accept the token? */ if (ret) te->pos.wp++; return ret; }
static int test_primary(Test_env *te, int do_eval) { const char *opnd1, *opnd2; int res; Test_op op; if (te->flags & TEF_ERROR) return 0; if ((*te->isa)(te, TM_OPAREN)) { res = test_oexpr(te, do_eval); if (te->flags & TEF_ERROR) return 0; if (!(*te->isa)(te, TM_CPAREN)) { (*te->error)(te, 0, "missing closing paren"); return 0; } return res; } /* * Binary should have precedence over unary in this case * so that something like test \( -f = -f \) is accepted */ if ((te->flags & TEF_DBRACKET) || (&te->pos.wp[1] < te->wp_end && !test_isop(te, TM_BINOP, te->pos.wp[1]))) { if ((op = (Test_op) (*te->isa)(te, TM_UNOP))) { /* unary expression */ opnd1 = (*te->getopnd)(te, op, do_eval); if (!opnd1) { (*te->error)(te, -1, "missing argument"); return 0; } return (*te->eval)(te, op, opnd1, (const char *) 0, do_eval); } } opnd1 = (*te->getopnd)(te, TO_NONOP, do_eval); if (!opnd1) { (*te->error)(te, 0, "expression expected"); return 0; } if ((op = (Test_op) (*te->isa)(te, TM_BINOP))) { /* binary expression */ opnd2 = (*te->getopnd)(te, op, do_eval); if (!opnd2) { (*te->error)(te, -1, "missing second argument"); return 0; } return (*te->eval)(te, op, opnd1, opnd2, do_eval); } if (te->flags & TEF_DBRACKET) { (*te->error)(te, -1, "missing expression operator"); return 0; } return (*te->eval)(te, TO_STNZE, opnd1, (const char *) 0, do_eval); }
/* * Test if the current token is a whatever. Accepts the current token if * it is. Returns 0 if it is not, non-zero if it is (in the case of * TM_UNOP and TM_BINOP, the returned value is a Test_op). */ static Test_op dbteste_isa(Test_env *te, Test_meta meta) { Test_op ret = TO_NONOP; int uqword; const char *p; if (!*te->pos.wp) return (meta == TM_END ? TO_NONNULL : TO_NONOP); /* unquoted word? */ for (p = *te->pos.wp; *p == CHAR; p += 2) ; uqword = *p == EOS; if (meta == TM_UNOP || meta == TM_BINOP) { if (uqword) { /* longer than the longest operator */ char buf[8]; char *q = buf; p = *te->pos.wp; while (*p++ == CHAR && (size_t)(q - buf) < sizeof(buf) - 1) *q++ = *p++; *q = '\0'; ret = test_isop(meta, buf); } } else if (meta == TM_END) ret = TO_NONOP; else ret = (uqword && !strcmp(*te->pos.wp, dbtest_tokens[(int)meta])) ? TO_NONNULL : TO_NONOP; /* Accept the token? */ if (ret != TO_NONOP) te->pos.wp++; return (ret); }