Source-Changes-D archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: CVS commit: src/distrib
On Sep 21, 10:01pm, david%l8s.co.uk@localhost (David Laight) wrote:
-- Subject: Re: CVS commit: src/distrib
| On Sun, Sep 20, 2009 at 05:32:17PM -0400, Christos Zoulas wrote:
| >
| > | Although posix defines strict rules for expressions with small
| > | numbers of arguments, netbsd'd parser doesn't obey them!
| >
| > Really? Can you give me an example.
|
| See PR/34646
|
| $ test ! = foo
This should prolly fix it... From FreeBSD.
christos
Index: test.c
===================================================================
RCS file: /cvsroot/src/bin/test/test.c,v
retrieving revision 1.37
diff -u -u -r1.37 test.c
--- test.c 10 Sep 2008 19:00:51 -0000 1.37
+++ test.c 21 Sep 2009 22:37:06 -0000
@@ -153,8 +153,10 @@
{"z", STREZ, UNOP},
};
+static int nargc;
static char **t_wp;
static struct t_op const *t_wp_op;
+static int parenlevel;
static void syntax(const char *, const char *);
static int oexpr(enum token);
@@ -165,8 +167,10 @@
static int test_access(struct stat *, mode_t);
static int filstat(char *, enum token);
static enum token t_lex(char *);
-static int isoperand(void);
static long long getn(const char *);
+static int isunopoperand(void);
+static int islparenoperand(void);
+static int isrparenoperand(void);
static int newerf(const char *, const char *);
static int olderf(const char *, const char *);
static int equalf(const char *, const char *);
@@ -200,6 +204,8 @@
}
#endif
+#define GETARG (nargc > 0 ? (--nargc, *++t_wp) : NULL)
+
#ifdef SHELL
int testcmd(int, char **);
@@ -228,13 +234,21 @@
argv[argc] = NULL;
}
- if (argc < 2)
+ if (--argc <= 0)
return 1;
+ nargc = argc - 1;
t_wp = &argv[1];
- res = !oexpr(t_lex(*t_wp));
+ 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 (*t_wp != NULL && *++t_wp != NULL)
+ if (--nargc > 0)
syntax(*t_wp, "unexpected operator");
return res;
@@ -258,9 +272,10 @@
res = aexpr(n);
if (*t_wp == NULL)
return res;
- if (t_lex(*++t_wp) == BOR)
- return oexpr(t_lex(*++t_wp)) || res;
+ if (t_lex(GETARG) == BOR)
+ return oexpr(t_lex(GETARG)) || res;
t_wp--;
+ nargc++;
return res;
}
@@ -272,9 +287,10 @@
res = nexpr(n);
if (*t_wp == NULL)
return res;
- if (t_lex(*++t_wp) == BAND)
- return aexpr(t_lex(*++t_wp)) && res;
+ if (t_lex(GETARG) == BAND)
+ return aexpr(t_lex(GETARG)) && res;
t_wp--;
+ nargc++;
return res;
}
@@ -283,7 +299,7 @@
{
if (n == UNOT)
- return !nexpr(t_lex(*++t_wp));
+ return !nexpr(t_lex(GETARG));
return primary(n);
}
@@ -296,30 +312,35 @@
if (n == EOI)
return 0; /* missing expression */
if (n == LPAREN) {
- if ((nn = t_lex(*++t_wp)) == RPAREN)
+ parenlevel++;
+ if ((nn = t_lex(GETARG)) == RPAREN) {
+ parenlevel--;
return 0; /* missing expression */
+ }
res = oexpr(nn);
- if (t_lex(*++t_wp) != RPAREN)
+ if (t_lex(GETARG) != RPAREN)
syntax(NULL, "closing paren expected");
+ parenlevel--;
return res;
}
if (t_wp_op && t_wp_op->op_type == UNOP) {
/* unary expression */
- if (*++t_wp == NULL)
+ if (--nargc == 0)
syntax(t_wp_op->op_text, "argument expected");
switch (n) {
case STREZ:
- return strlen(*t_wp) == 0;
+ return strlen(*++t_wp) == 0;
case STRNZ:
- return strlen(*t_wp) != 0;
+ return strlen(*++t_wp) != 0;
case FILTT:
- return isatty((int)getn(*t_wp));
+ return isatty((int)getn(*++t_wp));
default:
- return filstat(*t_wp, n);
+ return filstat(*++t_wp, n);
}
}
- if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) {
+ if (t_lex(nargc > 0 ? t_wp[1] : NULL), t_wp_op && t_wp_op->op_type ==
+ BINOP) {
return binop();
}
@@ -333,10 +354,10 @@
struct t_op const *op;
opnd1 = *t_wp;
- (void) t_lex(*++t_wp);
+ (void) t_lex(GETARG);
op = t_wp_op;
- if ((opnd2 = *++t_wp) == NULL)
+ if ((opnd2 = GETARG) == NULL)
syntax(op->op_text, "argument expected");
switch (op->op_num) {
@@ -639,28 +660,67 @@
}
if ((op = findop(s)) != NULL) {
- if (!((op->op_type == UNOP && isoperand()) ||
- (op->op_num == LPAREN && *(t_wp+1) == 0))) {
- t_wp_op = op;
- return op->op_num;
- }
+ if (((op->op_type == UNOP || op->op_type == BUNOP)
+ && isunopoperand()) ||
+ (op->op_num == LPAREN && islparenoperand()) ||
+ (op->op_num == RPAREN && isrparenoperand()))
+ goto out;
+ t_wp_op = op;
+ return op->op_num;
}
+out:
t_wp_op = NULL;
return OPERAND;
}
static int
-isoperand(void)
+isunopoperand(void)
+{
+ struct t_op const *op;
+ char *s;
+ char *t;
+
+ if (nargc == 1)
+ return 1;
+ s = *(t_wp + 1);
+ if (nargc == 2)
+ return parenlevel == 1 && strcmp(s, ")") == 0;
+ t = *(t_wp + 2);
+ if ((op = findop(s)) != NULL) {
+ return op->op_type == BINOP &&
+ (parenlevel == 0 || t[0] != ')' || t[1] != '\0');
+ }
+ return 0;
+}
+
+static int
+islparenoperand(void)
{
struct t_op const *op;
- char *s, *t;
+ char *s;
- if ((s = *(t_wp+1)) == 0)
+ if (nargc == 1)
return 1;
- if ((t = *(t_wp+2)) == 0)
+ s = *(t_wp + 1);
+ if (nargc == 2)
+ return parenlevel == 1 && strcmp(s, ")") == 0;
+ if (nargc != 3)
return 0;
if ((op = findop(s)) != NULL)
- return op->op_type == BINOP && (t[0] != ')' || t[1] != '\0');
+ return op->op_type == BINOP;
+ return 0;
+}
+
+static int
+isrparenoperand(void)
+{
+ char *s;
+
+ if (nargc == 1)
+ return 0;
+ s = *(t_wp + 1);
+ if (nargc == 2)
+ return parenlevel == 1 && strcmp(s, ")") == 0;
return 0;
}
Home |
Main Index |
Thread Index |
Old Index