Bug #3248 » 0004-test-1-sync-with-FreeBSD-up-to-93028985.patch
| bin/test/test.c | ||
|---|---|---|
|
operand ::= <any legal UNIX file name>
|
||
|
*/
|
||
|
enum token_types {
|
||
|
UNOP = 0x100,
|
||
|
BINOP = 0x200,
|
||
|
BUNOP = 0x300,
|
||
|
BBINOP = 0x400,
|
||
|
PAREN = 0x500
|
||
|
};
|
||
|
enum token {
|
||
|
EOI,
|
||
|
FILRD,
|
||
|
OPERAND,
|
||
|
FILRD = UNOP + 1,
|
||
|
FILWR,
|
||
|
FILEX,
|
||
|
FILEXIST,
|
||
| ... | ... | |
|
FILSUID,
|
||
|
FILSGID,
|
||
|
FILSTCK,
|
||
|
FILNT,
|
||
|
FILOT,
|
||
|
FILEQ,
|
||
|
FILUID,
|
||
|
FILGID,
|
||
|
STREZ,
|
||
|
STRNZ,
|
||
|
FILUID,
|
||
|
FILGID,
|
||
|
FILNT = BINOP + 1,
|
||
|
FILOT,
|
||
|
FILEQ,
|
||
|
STREQ,
|
||
|
STRNE,
|
||
|
STRLT,
|
||
| ... | ... | |
|
INTGT,
|
||
|
INTLE,
|
||
|
INTLT,
|
||
|
UNOT,
|
||
|
BAND,
|
||
|
UNOT = BUNOP + 1,
|
||
|
BAND = BBINOP + 1,
|
||
|
BOR,
|
||
|
LPAREN,
|
||
|
LPAREN = PAREN + 1,
|
||
|
RPAREN,
|
||
|
OPERAND
|
||
|
};
|
||
|
enum token_types {
|
||
|
UNOP,
|
||
|
BINOP,
|
||
|
BUNOP,
|
||
|
BBINOP,
|
||
|
PAREN
|
||
|
};
|
||
|
static struct t_op {
|
||
|
char op_text[4];
|
||
|
short op_num, op_type;
|
||
|
} const ops [] = {
|
||
|
{"-r", FILRD, UNOP},
|
||
|
{"-w", FILWR, UNOP},
|
||
|
{"-x", FILEX, UNOP},
|
||
|
{"-e", FILEXIST,UNOP},
|
||
|
{"-f", FILREG, UNOP},
|
||
|
{"-d", FILDIR, UNOP},
|
||
|
{"-c", FILCDEV,UNOP},
|
||
|
{"-b", FILBDEV,UNOP},
|
||
|
{"-p", FILFIFO,UNOP},
|
||
|
{"-u", FILSUID,UNOP},
|
||
|
{"-g", FILSGID,UNOP},
|
||
|
{"-k", FILSTCK,UNOP},
|
||
|
{"-s", FILGZ, UNOP},
|
||
|
{"-t", FILTT, UNOP},
|
||
|
{"-z", STREZ, UNOP},
|
||
|
{"-n", STRNZ, UNOP},
|
||
|
{"-h", FILSYM, UNOP}, /* for backwards compat */
|
||
|
{"-O", FILUID, UNOP},
|
||
|
{"-G", FILGID, UNOP},
|
||
|
{"-L", FILSYM, UNOP},
|
||
|
{"-S", FILSOCK,UNOP},
|
||
|
{"=", STREQ, BINOP},
|
||
|
{"==", STREQ, BINOP},
|
||
|
{"!=", STRNE, BINOP},
|
||
|
{"<", STRLT, BINOP},
|
||
|
{">", STRGT, BINOP},
|
||
|
{"-eq", INTEQ, BINOP},
|
||
|
{"-ne", INTNE, BINOP},
|
||
|
{"-ge", INTGE, BINOP},
|
||
|
{"-gt", INTGT, BINOP},
|
||
|
{"-le", INTLE, BINOP},
|
||
|
{"-lt", INTLT, BINOP},
|
||
|
{"-nt", FILNT, BINOP},
|
||
|
{"-ot", FILOT, BINOP},
|
||
|
{"-ef", FILEQ, BINOP},
|
||
|
{"!", UNOT, BUNOP},
|
||
|
{"-a", BAND, BBINOP},
|
||
|
{"-o", BOR, BBINOP},
|
||
|
{"(", LPAREN, PAREN},
|
||
|
{")", RPAREN, PAREN},
|
||
|
{"", 0, 0}
|
||
|
#define TOKEN_TYPE(token) ((token & 0xff00))
|
||
|
static const struct t_op {
|
||
|
char op_text[2];
|
||
|
short op_num;
|
||
|
} ops1[] = {
|
||
|
{"=", STREQ},
|
||
|
{"<", STRLT},
|
||
|
{">", STRGT},
|
||
|
{"!", UNOT},
|
||
|
{"(", LPAREN},
|
||
|
{")", RPAREN},
|
||
|
}, opsm1[] = {
|
||
|
{"r", FILRD},
|
||
|
{"w", FILWR},
|
||
|
{"x", FILEX},
|
||
|
{"e", FILEXIST},
|
||
|
{"f", FILREG},
|
||
|
{"d", FILDIR},
|
||
|
{"c", FILCDEV},
|
||
|
{"b", FILBDEV},
|
||
|
{"p", FILFIFO},
|
||
|
{"u", FILSUID},
|
||
|
{"g", FILSGID},
|
||
|
{"k", FILSTCK},
|
||
|
{"s", FILGZ},
|
||
|
{"t", FILTT},
|
||
|
{"z", STREZ},
|
||
|
{"n", STRNZ},
|
||
|
{"h", FILSYM}, /* for backwards compat */
|
||
|
{"O", FILUID},
|
||
|
{"G", FILGID},
|
||
|
{"L", FILSYM},
|
||
|
{"S", FILSOCK},
|
||
|
{"a", BAND},
|
||
|
{"o", BOR},
|
||
|
}, ops2[] = {
|
||
|
{"==", STREQ},
|
||
|
{"!=", STRNE},
|
||
|
}, opsm2[] = {
|
||
|
{"eq", INTEQ},
|
||
|
{"ne", INTNE},
|
||
|
{"ge", INTGE},
|
||
|
{"gt", INTGT},
|
||
|
{"le", INTLE},
|
||
|
{"lt", INTLT},
|
||
|
{"nt", FILNT},
|
||
|
{"ot", FILOT},
|
||
|
{"ef", FILEQ},
|
||
|
};
|
||
|
static struct t_op const *t_wp_op;
|
||
|
static int nargc;
|
||
|
static char **t_wp;
|
||
|
static int parenlevel;
|
||
|
static int aexpr(enum token);
|
||
|
static int binop(void);
|
||
|
static int binop(enum token);
|
||
|
static int equalf(const char *, const char *);
|
||
|
static int filstat(char *, enum token);
|
||
|
static int getn(const char *);
|
||
| ... | ... | |
|
parenlevel--;
|
||
|
return res;
|
||
|
}
|
||
|
if (t_wp_op && t_wp_op->op_type == UNOP) {
|
||
|
if (TOKEN_TYPE(n) == UNOP) {
|
||
|
/* unary expression */
|
||
|
if (--nargc == 0)
|
||
|
syntax(t_wp_op->op_text, "argument expected");
|
||
|
syntax(NULL, "argument expected"); /* impossible */
|
||
|
switch (n) {
|
||
|
case STREZ:
|
||
|
return strlen(*++t_wp) == 0;
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
if (t_lex(nargc > 0 ? t_wp[1] : NULL), t_wp_op && t_wp_op->op_type ==
|
||
|
BINOP) {
|
||
|
return binop();
|
||
|
}
|
||
|
nn = t_lex(nargc > 0 ? t_wp[1] : NULL);
|
||
|
if (TOKEN_TYPE(nn) == BINOP)
|
||
|
return binop(nn);
|
||
|
return strlen(*t_wp) > 0;
|
||
|
}
|
||
|
static int
|
||
|
binop(void)
|
||
|
binop(enum token n)
|
||
|
{
|
||
|
const char *opnd1, *opnd2;
|
||
|
struct t_op const *op;
|
||
|
const char *opnd1, *op, *opnd2;
|
||
|
opnd1 = *t_wp;
|
||
|
t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL);
|
||
|
op = t_wp_op;
|
||
|
op = nargc > 0 ? (--nargc, *++t_wp) : NULL;
|
||
|
if ((opnd2 = nargc > 0 ? (--nargc, *++t_wp) : NULL) == NULL)
|
||
|
syntax(op->op_text, "argument expected");
|
||
|
syntax(op, "argument expected");
|
||
|
switch (op->op_num) {
|
||
|
switch (n) {
|
||
|
case STREQ:
|
||
|
return strcmp(opnd1, opnd2) == 0;
|
||
|
case STRNE:
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
static enum token
|
||
|
t_lex(char *s)
|
||
|
static int
|
||
|
find_op_1char(const struct t_op *op, const struct t_op *end, const char *s)
|
||
|
{
|
||
|
struct t_op const *op = ops;
|
||
|
char c;
|
||
|
if (s == NULL) {
|
||
|
t_wp_op = NULL;
|
||
|
return EOI;
|
||
|
c = s[0];
|
||
|
while (op != end) {
|
||
|
if (c == *op-> op_text)
|
||
|
return op->op_num;
|
||
|
op++;
|
||
|
}
|
||
|
while (*op->op_text) {
|
||
|
if (strcmp(s, op->op_text) == 0) {
|
||
|
if (((op->op_type == UNOP || op->op_type == BUNOP)
|
||
|
&& isunopoperand()) ||
|
||
|
(op->op_num == LPAREN && islparenoperand()) ||
|
||
|
(op->op_num == RPAREN && isrparenoperand()))
|
||
|
break;
|
||
|
t_wp_op = op;
|
||
|
return OPERAND;
|
||
|
}
|
||
|
static int
|
||
|
find_op_2char(const struct t_op *op, const struct t_op *end, const char *s)
|
||
|
{
|
||
|
while (op != end) {
|
||
|
if (s[0] == op->op_text[0] && s[1] == op->op_text[1])
|
||
|
return op->op_num;
|
||
|
}
|
||
|
op++;
|
||
|
}
|
||
|
t_wp_op = NULL;
|
||
|
return OPERAND;
|
||
|
}
|
||
|
static int
|
||
|
find_op(const char *s)
|
||
|
{
|
||
|
if (s[0] == '\0')
|
||
|
return OPERAND;
|
||
|
else if (s[1] == '\0')
|
||
|
return find_op_1char(ops1, (&ops1)[1], s);
|
||
|
else if (s[2] == '\0')
|
||
|
return s[0] == '-' ? find_op_1char(opsm1, (&opsm1)[1], s + 1) :
|
||
|
find_op_2char(ops2, (&ops2)[1], s);
|
||
|
else if (s[3] == '\0')
|
||
|
return s[0] == '-' ? find_op_2char(opsm2, (&opsm2)[1], s + 1) :
|
||
|
OPERAND;
|
||
|
else
|
||
|
return OPERAND;
|
||
|
}
|
||
|
static enum token
|
||
|
t_lex(char *s)
|
||
|
{
|
||
|
int num;
|
||
|
if (s == 0) {
|
||
|
return EOI;
|
||
|
}
|
||
|
num = find_op(s);
|
||
|
if (((TOKEN_TYPE(num) == UNOP || TOKEN_TYPE(num) == BUNOP)
|
||
|
&& isunopoperand()) ||
|
||
|
(num == LPAREN && islparenoperand()) ||
|
||
|
(num == RPAREN && isrparenoperand()))
|
||
|
return OPERAND;
|
||
|
return num;
|
||
|
}
|
||
|
static int
|
||
|
isunopoperand(void)
|
||
|
{
|
||
|
struct t_op const *op = ops;
|
||
|
char *s;
|
||
|
char *t;
|
||
|
int num;
|
||
|
if (nargc == 1)
|
||
|
return 1;
|
||
| ... | ... | |
|
if (nargc == 2)
|
||
|
return parenlevel == 1 && strcmp(s, ")") == 0;
|
||
|
t = *(t_wp + 2);
|
||
|
while (*op->op_text) {
|
||
|
if (strcmp(s, op->op_text) == 0)
|
||
|
return op->op_type == BINOP &&
|
||
|
(parenlevel == 0 || t[0] != ')' || t[1] != '\0');
|
||
|
op++;
|
||
|
}
|
||
|
return 0;
|
||
|
num = find_op(s);
|
||
|
return TOKEN_TYPE(num) == BINOP &&
|
||
|
(parenlevel == 0 || t[0] != ')' || t[1] != '\0');
|
||
|
}
|
||
|
static int
|
||
|
islparenoperand(void)
|
||
|
{
|
||
|
struct t_op const *op = ops;
|
||
|
char *s;
|
||
|
int num;
|
||
|
if (nargc == 1)
|
||
|
return 1;
|
||
| ... | ... | |
|
return parenlevel == 1 && strcmp(s, ")") == 0;
|
||
|
if (nargc != 3)
|
||
|
return 0;
|
||
|
while (*op->op_text) {
|
||
|
if (strcmp(s, op->op_text) == 0)
|
||
|
return op->op_type == BINOP;
|
||
|
op++;
|
||
|
}
|
||
|
return 0;
|
||
|
num = find_op(s);
|
||
|
return TOKEN_TYPE(num) == BINOP;
|
||
|
}
|
||
|
static int
|
||
- « Previous
- 1
- …
- 8
- 9
- 10
- Next »