Project

General

Profile

Bug #3248 » 0004-test-1-sync-with-FreeBSD-up-to-93028985.patch

piecuch, 09/16/2020 11:16 AM

View differences:

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
(10-10/10)