Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Aug 2003 15:40:19 -0700 (PDT)
From:      Wartan Hachaturow <wart@tepkom.ru>
To:        freebsd-standards@FreeBSD.org
Subject:   Re: standards/52972: /bin/sh arithmetic not POSIX compliant
Message-ID:  <200308222240.h7MMeJSO013813@freefall.freebsd.org>

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

From: Wartan Hachaturow <wart@tepkom.ru>
To: Jens Schweikhardt <schweikh@schweikhardt.net>
Cc: GNATS Bug Followup <bug-followup@FreeBSD.org>, tjr@FreeBSD.org
Subject: Re: standards/52972: /bin/sh arithmetic not POSIX compliant
Date: Sat, 23 Aug 2003 02:27:21 +0400

 --Kj7319i9nmIyA2yE
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 This version of patch (hopefully :) fixes the issues tjr pointed to,
 and adds hexal and octal constants which are required by SUSv3.
 I've even successfully built 5.1's world with it.
 
 -- 
 Regards, Wartan.
 "Computers are not intelligent. They only think they are."
 
 --Kj7319i9nmIyA2yE
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="ash.patch"
 
 diff -u ./FreeBSD_ASH_HEAD.orig/arith.h ./FreeBSD_ASH_HEAD/arith.h
 --- ./FreeBSD_ASH_HEAD.orig/arith.h	Thu Aug  7 14:17:27 2003
 +++ ./FreeBSD_ASH_HEAD/arith.h	Thu Aug  7 14:17:43 2003
 @@ -31,8 +31,9 @@
   * SUCH DAMAGE.
   *
   *	@(#)arith.h	1.1 (Berkeley) 5/4/95
 - * $FreeBSD: src/bin/sh/arith.h,v 1.6 2002/02/02 06:50:45 imp Exp $
 + * $FreeBSD: src/bin/sh/arith.h,v 1.5.2.1 2002/07/19 04:38:51 tjr Exp $
   */
  
 +int arith_assign(char *, arith_t);
  int arith(char *);
  int expcmd(int , char **);
 diff -u ./FreeBSD_ASH_HEAD.orig/arith.y ./FreeBSD_ASH_HEAD/arith.y
 --- ./FreeBSD_ASH_HEAD.orig/arith.y	Thu Aug  7 14:17:27 2003
 +++ ./FreeBSD_ASH_HEAD/arith.y	Fri Aug 22 16:23:05 2003
 @@ -1,5 +1,65 @@
 -%token ARITH_NUM ARITH_LPAREN ARITH_RPAREN
 +%{
 +/*-
 + * Copyright (c) 1993
 + *	The Regents of the University of California.  All rights reserved.
 + *
 + * This code is derived from software contributed to Berkeley by
 + * Kenneth Almquist.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. All advertising materials mentioning features or use of this software
 + *    must display the following acknowledgement:
 + *	This product includes software developed by the University of
 + *	California, Berkeley and its contributors.
 + * 4. Neither the name of the University nor the names of its contributors
 + *    may be used to endorse or promote products derived from this software
 + *    without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 + * SUCH DAMAGE.
 + */
  
 +#ifndef lint
 +#if 0
 +static char sccsid[] = "@(#)arith.y	8.3 (Berkeley) 5/4/95";
 +#endif
 +#endif /* not lint */
 +#include <sys/cdefs.h>
 +__FBSDID("$FreeBSD: src/bin/sh/arith.y,v 1.10.2.2 2002/07/19 04:38:51 tjr Exp $");
 +
 +#include <limits.h>
 +#include "shell.h"
 +#include "var.h"
 +%}
 +%union {
 +	arith_t l_value;
 +	char* s_value;
 +}
 +%token <l_value> ARITH_NUM ARITH_LPAREN ARITH_RPAREN
 +%token <s_value> ARITH_VAR
 +
 +%type <l_value>	expr
 +%right ARITH_ASSIGN
 +%right ARITH_ADDASSIGN ARITH_SUBASSIGN
 +%right ARITH_MULASSIGN ARITH_DIVASSIGN ARITH_REMASSIGN
 +%right ARITH_RSHASSIGN ARITH_LSHASSIGN
 +%right ARITH_BANDASSIGN ARITH_BXORASSIGN ARITH_BORASSIGN
  %left ARITH_OR
  %left ARITH_AND
  %left ARITH_BOR
 @@ -18,7 +78,6 @@
  		}
  	;
  
 -
  expr:	ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; }
  	| expr ARITH_OR expr	= { $$ = $1 ? $1 : $3 ? $3 : 0; }
  	| expr ARITH_AND expr	= { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; }
 @@ -51,62 +110,139 @@
  	| ARITH_SUB expr %prec ARITH_UNARYMINUS = { $$ = -($2); }
  	| ARITH_ADD expr %prec ARITH_UNARYPLUS = { $$ = $2; }
  	| ARITH_NUM
 +	| ARITH_VAR 	{
 +				char *p;
 +				arith_t arith_val;
 +				char *str_val;
 +
 +				if (lookupvar($1) == NULL)
 +					setvarsafe($1, "0", 0);
 +				str_val = lookupvar($1);
 +				arith_val = strtoarith_t(str_val, &p, 0);
 +				/*
 +				 * Conversion is successful only in case
 +				 * we've converted _all_ characters.
 +				 */
 +				if (*p != '\0')
 +					yyerror("variable conversion error");
 +				$$ = arith_val;
 +			}
 +	| ARITH_VAR ARITH_ASSIGN expr {
 +						if (arith_assign($1, $3) != 1)
 +							yyerror("variable assignment error");
 +						$$ = $3;
 +					}
 +	| ARITH_VAR ARITH_ADDASSIGN expr {
 +						arith_t value;
 +
 +						value = atoarith_t(lookupvar($1)) + $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_SUBASSIGN expr {
 +						arith_t value;
 +
 +						value = atoarith_t(lookupvar($1)) - $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_MULASSIGN expr {
 +						arith_t value;
 +
 +						value = atoarith_t(lookupvar($1)) * $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_DIVASSIGN expr {
 +						arith_t value;
 +
 +						if ($3 == 0)
 +							yyerror("division by zero");
 +
 +						value = atoarith_t(lookupvar($1)) / $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_REMASSIGN expr {
 +						arith_t value;
 +
 +						if ($3 == 0)
 +							yyerror("division by zero");
 +
 +						value = atoarith_t(lookupvar($1)) % $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_RSHASSIGN expr {
 +						arith_t value;
 +
 +						value = atoarith_t(lookupvar($1)) >> $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_LSHASSIGN expr {
 +						arith_t value;
 +
 +						value = atoarith_t(lookupvar($1)) << $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_BANDASSIGN expr {
 +						arith_t value;
 +
 +						value = atoarith_t(lookupvar($1)) & $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_BXORASSIGN expr {
 +						arith_t value;
 +
 +						value = atoarith_t(lookupvar($1)) ^ $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
 +	| ARITH_VAR ARITH_BORASSIGN expr {
 +						arith_t value;
 +
 +						value = atoarith_t(lookupvar($1)) | $3;
 +						if (arith_assign($1, value) != 0)
 +							yyerror("variable assignment error");
 +						$$ = value;
 +					}
  	;
  %%
 -/*-
 - * Copyright (c) 1993
 - *	The Regents of the University of California.  All rights reserved.
 - *
 - * This code is derived from software contributed to Berkeley by
 - * Kenneth Almquist.
 - *
 - * Redistribution and use in source and binary forms, with or without
 - * modification, are permitted provided that the following conditions
 - * are met:
 - * 1. Redistributions of source code must retain the above copyright
 - *    notice, this list of conditions and the following disclaimer.
 - * 2. Redistributions in binary form must reproduce the above copyright
 - *    notice, this list of conditions and the following disclaimer in the
 - *    documentation and/or other materials provided with the distribution.
 - * 3. All advertising materials mentioning features or use of this software
 - *    must display the following acknowledgement:
 - *	This product includes software developed by the University of
 - *	California, Berkeley and its contributors.
 - * 4. Neither the name of the University nor the names of its contributors
 - *    may be used to endorse or promote products derived from this software
 - *    without specific prior written permission.
 - *
 - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 - * SUCH DAMAGE.
 - */
 -
 -#ifndef lint
 -#if 0
 -static char sccsid[] = "@(#)arith.y	8.3 (Berkeley) 5/4/95";
 -#endif
 -#endif /* not lint */
 -#include <sys/cdefs.h>
 -__FBSDID("$FreeBSD: src/bin/sh/arith.y,v 1.14 2003/05/01 16:58:56 obrien Exp $");
 -
 -#include "shell.h"
  #include "error.h"
  #include "output.h"
  #include "memalloc.h"
  
 +#define lstrlen(var) (3 + (2 + CHAR_BIT * sizeof((var))) / 3)
 +
  char *arith_buf, *arith_startbuf;
  extern void arith_lex_reset();
  
  int yylex(void);
  int yyparse(void);
 +
 +int
 +arith_assign(char *name, arith_t value) {
 +	char *str;
 +	int ret;
 +
 +	str = (char *)ckmalloc(lstrlen(value));
 +	sprintf(str, ARITH_FORMAT_STR, value);
 +	ret = setvarsafe(name, str, 0);
 +	free(str);
 +	return ret;
 +}
  
  int
  arith(char *s)
 diff -u ./FreeBSD_ASH_HEAD.orig/arith_lex.l ./FreeBSD_ASH_HEAD/arith_lex.l
 --- ./FreeBSD_ASH_HEAD.orig/arith_lex.l	Thu Aug  7 14:17:27 2003
 +++ ./FreeBSD_ASH_HEAD/arith_lex.l	Fri Aug 22 16:30:51 2003
 @@ -41,12 +41,14 @@
  #endif
  #endif /* not lint */
  #include <sys/cdefs.h>
 -__FBSDID("$FreeBSD: src/bin/sh/arith_lex.l,v 1.18 2003/05/01 16:58:56 obrien Exp $");
 +__FBSDID("$FreeBSD: src/bin/sh/arith_lex.l,v 1.14.2.2 2002/07/19 04:38:51 tjr Exp $");
  
 +#include "shell.h"
  #include "y.tab.h"
  #include "error.h"
 +#include "var.h"
 +#include "memalloc.h"
  
 -extern int yylval;
  extern char *arith_buf, *arith_startbuf;
  #undef YY_INPUT
  #define YY_INPUT(buf,result,max) \
 @@ -56,7 +58,36 @@
  
  %%
  [ \t\n]	{ ; }
 -[0-9]+	{ yylval = atol(yytext); return(ARITH_NUM); }
 +
 +0x[a-fA-F0-9]+	{
 +		yylval.l_value = strtoarith_t(yytext, NULL, 16);
 +		return(ARITH_NUM);
 +		}
 +
 +0[0-7]+	{
 +		yylval.l_value = strtoarith_t(yytext, NULL, 8);
 +		return(ARITH_NUM);
 +		}
 +
 +[0-9]+		{
 +		yylval.l_value = strtoarith_t(yytext, NULL, 10);
 +		return(ARITH_NUM);
 +		}
 +
 +
 +[A-Za-z][A-Za-z0-9_]*	{
 +			/*
 +			 * If variable doesn't exist, we should  initialize
 +			 * it to zero.
 +			 */
 +			char *temp;
 +			if (lookupvar(yytext) == NULL)
 +				setvarsafe(yytext, "0", 0);
 +			temp = (char *)ckmalloc(strlen(yytext) + 1);
 +			yylval.s_value = strcpy(temp, yytext);
 +
 +			return(ARITH_VAR);
 +		}
  "("	{ return(ARITH_LPAREN); }
  ")"	{ return(ARITH_RPAREN); }
  "||"	{ return(ARITH_OR); }
 @@ -79,6 +110,17 @@
  "-"	{ return(ARITH_SUB); }
  "~"	{ return(ARITH_BNOT); }
  "!"	{ return(ARITH_NOT); }
 +"="	{ return(ARITH_ASSIGN); }
 +"+="	{ return(ARITH_ADDASSIGN); }
 +"-="	{ return(ARITH_SUBASSIGN); }
 +"*="	{ return(ARITH_MULASSIGN); }
 +"/="	{ return(ARITH_DIVASSIGN); }
 +"%="	{ return(ARITH_REMASSIGN); }
 +">>="	{ return(ARITH_RSHASSIGN); }
 +"<<="	{ return(ARITH_LSHASSIGN); }
 +"&="	{ return(ARITH_BANDASSIGN); }
 +"^="	{ return(ARITH_BXORASSIGN); }
 +"|="	{ return(ARITH_BORASSIGN); }
  .	{ error("arith: syntax error: \"%s\"\n", arith_startbuf); }
  %%
  
 Common subdirectories: ./FreeBSD_ASH_HEAD.orig/bltin and ./FreeBSD_ASH_HEAD/bltin
 Common subdirectories: ./FreeBSD_ASH_HEAD.orig/funcs and ./FreeBSD_ASH_HEAD/funcs
 diff -u ./FreeBSD_ASH_HEAD.orig/shell.h ./FreeBSD_ASH_HEAD/shell.h
 --- ./FreeBSD_ASH_HEAD.orig/shell.h	Thu Aug  7 14:17:27 2003
 +++ ./FreeBSD_ASH_HEAD/shell.h	Fri Aug 22 16:29:39 2003
 @@ -51,6 +51,14 @@
  #define JOBS 1
  /* #define DEBUG 1 */
  
 +/*
 + * Type of used arithmetics. SUSv3 requires us to have at least signed long.
 + */
 +typedef long arith_t;
 +#define strtoarith_t(nptr, endptr, base)	strtol(nptr, endptr, base)
 +#define atoarith_t(arg)				strtol(arg, NULL, 0)
 +#define ARITH_FORMAT_STR					"%ld"
 +
  typedef void *pointer;
  #define STATIC  static
  #define MKINIT	/* empty */
 
 --Kj7319i9nmIyA2yE--


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