Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 May 2009 06:20:04 GMT
From:      dfilter@FreeBSD.org (dfilter service)
To:        freebsd-standards@FreeBSD.org
Subject:   Re: standards/133369: commit references a PR
Message-ID:  <200905270620.n4R6K4JW056473@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR standards/133369; it has been noted by GNATS.

From: dfilter@FreeBSD.org (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: standards/133369: commit references a PR
Date: Tue, 26 May 2009 22:33:20 +0000 (UTC)

 Author: jilles
 Date: Tue May 26 22:33:10 2009
 New Revision: 192862
 URL: http://svn.freebsd.org/changeset/base/192862
 
 Log:
   Fix various cases with 3 or 4 parameters in test(1) to be POSIX compliant.
   More precisely, this gives precedence to an interpretation not using the
   '(', ')', '-a' and '-o' in their special meaning, if possible. For example,
   it is now safe to write [ "$a" = "$b" ] and assume it compares the two
   strings.
   
   The man page already says that test(1) works this way, so does not need to
   be changed.
   
   Interpretation of input with more parameters tries a bit harder to find a
   valid parse in some cases.
   
   Add various additional test cases to TEST.sh.
   
   PR:		standards/133369
   Approved by:	ed (mentor)
 
 Modified:
   head/bin/test/TEST.sh
   head/bin/test/test.c
 
 Modified: head/bin/test/TEST.sh
 ==============================================================================
 --- head/bin/test/TEST.sh	Tue May 26 22:21:53 2009	(r192861)
 +++ head/bin/test/TEST.sh	Tue May 26 22:33:10 2009	(r192862)
 @@ -133,5 +133,45 @@ t 0 '"a" -a ! ""'
  t 1 '""'
  t 0 '! ""'
  
 +t 0 '!'
 +t 0 '\('
 +t 0 '\)'
 +
 +t 1 '\( = \)'
 +t 0 '\( != \)'
 +t 0 '\( ! \)'
 +t 0 '\( \( \)'
 +t 0 '\( \) \)'
 +t 0 '! = !'
 +t 1 '! != !'
 +t 1 '-n = \)'
 +t 0 '! != \)'
 +t 1 '! = a'
 +t 0 '! != -n'
 +t 0 '! -c /etc/passwd'
 +
 +t 0 '! \( = \)'
 +t 1 '! \( != \)'
 +t 1 '! = = ='
 +t 0 '! = = \)'
 +t 0 '! "" -o ""'
 +t 1 '! "x" -o ""'
 +t 1 '! "" -o "x"'
 +t 1 '! "x" -o "x"'
 +t 0 '\( -f /etc/passwd \)'
 +t 1 '\( ! = \)'
 +t 0 '\( ! "" \)'
 +t 1 '\( ! -e \)'
 +
 +t 0 '0 -eq 0 -a -d /'
 +t 0 '-s = "" -o "" = ""'
 +t 0 '"" = "" -o -s = ""'
 +t 1 '-s = "" -o -s = ""'
 +t 0 '-z x -o x = "#" -o x = x'
 +t 1 '-z y -o y = "#" -o y = x'
 +t 0 '0 -ne 0 -o ! -f /'
 +t 0 '1 -ne 0 -o ! -f /etc/passwd'
 +t 1 '0 -ne 0 -o ! -f /etc/passwd'
 +
  echo ""
  echo "Syntax errors: $ERROR Failed: $FAILED"
 
 Modified: head/bin/test/test.c
 ==============================================================================
 --- head/bin/test/test.c	Tue May 26 22:21:53 2009	(r192861)
 +++ head/bin/test/test.c	Tue May 26 22:33:10 2009	(r192862)
 @@ -163,6 +163,7 @@ struct t_op {
  struct t_op const *t_wp_op;
  int nargc;
  char **t_wp;
 +int parenlevel;
  
  static int	aexpr(enum token);
  static int	binop(void);
 @@ -171,7 +172,9 @@ static int	filstat(char *, enum token);
  static int	getn(const char *);
  static intmax_t	getq(const char *);
  static int	intcmp(const char *, const char *);
 -static int	isoperand(void);
 +static int	isunopoperand(void);
 +static int	islparenoperand(void);
 +static int	isrparenoperand(void);
  static int	newerf(const char *, const char *);
  static int	nexpr(enum token);
  static int	oexpr(enum token);
 @@ -205,7 +208,14 @@ main(int argc, char **argv)
  #endif
  	nargc = argc;
  	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 (--nargc > 0)
  		syntax(*t_wp, "unexpected operator");
 @@ -268,12 +278,16 @@ primary(enum token n)
  	if (n == EOI)
  		return 0;		/* missing expression */
  	if (n == LPAREN) {
 +		parenlevel++;
  		if ((nn = t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL)) ==
 -		    RPAREN)
 +		    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) {
 @@ -410,8 +424,10 @@ t_lex(char *s)
  	}
  	while (op->op_text) {
  		if (strcmp(s, op->op_text) == 0) {
 -			if ((op->op_type == UNOP && isoperand()) ||
 -			    (op->op_num == LPAREN && nargc == 1))
 +			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 op->op_num;
 @@ -423,7 +439,7 @@ t_lex(char *s)
  }
  
  static int
 -isoperand(void)
 +isunopoperand(void)
  {
  	struct t_op const *op = ops;
  	char *s;
 @@ -431,19 +447,53 @@ isoperand(void)
  
  	if (nargc == 1)
  		return 1;
 -	if (nargc == 2)
 -		return 0;
  	s = *(t_wp + 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 &&
 -			    (t[0] != ')' || t[1] != '\0');
 +			    (parenlevel == 0 || t[0] != ')' || t[1] != '\0');
 +		op++;
 +	}
 +	return 0;
 +}
 +
 +static int
 +islparenoperand(void)
 +{
 +	struct t_op const *op = ops;
 +	char *s;
 +
 +	if (nargc == 1)
 +		return 1;
 +	s = *(t_wp + 1);
 +	if (nargc == 2)
 +		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;
  }
  
 +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;
 +}
 +
  /* atoi with error detection */
  static int
  getn(const char *s)
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905270620.n4R6K4JW056473>