From owner-freebsd-performance@FreeBSD.ORG Sat Apr 19 18:34:05 2003 Return-Path: Delivered-To: freebsd-performance@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DCE4537B401; Sat, 19 Apr 2003 18:34:05 -0700 (PDT) Received: from snark.ratmir.ru (snark.ratmir.ru [213.24.248.177]) by mx1.FreeBSD.org (Postfix) with ESMTP id B53A043F3F; Sat, 19 Apr 2003 18:34:03 -0700 (PDT) (envelope-from freebsd@snark.ratmir.ru) Received: from snark.ratmir.ru (freebsd@localhost [127.0.0.1]) by snark.ratmir.ru (8.12.9/8.12.9) with ESMTP id h3K1Y0C2073365; Sun, 20 Apr 2003 05:34:00 +0400 (MSD) (envelope-from freebsd@snark.ratmir.ru) Received: (from freebsd@localhost) by snark.ratmir.ru (8.12.9/8.12.9/Submit) id h3K1Y0gn073364; Sun, 20 Apr 2003 05:34:00 +0400 (MSD) Date: Sun, 20 Apr 2003 05:34:00 +0400 From: Alex Semenyaka To: Alex Semenyaka Message-ID: <20030420013400.GB52428@snark.ratmir.ru> References: <20030420011039.GC52081@snark.ratmir.ru> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20030420011039.GC52081@snark.ratmir.ru> User-Agent: Mutt/1.5.4i cc: freebsd-current@freebsd.org cc: ru@freebsd.org cc: tjr@freebsd.org cc: imp@freebsd.org cc: freebsd-hackers@freebsd.org cc: freebsd-performance@freebsd.org cc: freebsd-standards@freebsd.org Subject: Re: /bin/sh and 32-bit arithmetics [CORRECTED] X-BeenThere: freebsd-performance@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Performance/tuning List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Apr 2003 01:34:06 -0000 ...ghmmm... sorry and sorry... and here the patch, it is pretty small: diff -u -r -U 2 -b ../sh.old/Makefile ./Makefile --- ../sh.old/Makefile Sat Apr 19 23:22:31 2003 +++ ./Makefile Sun Apr 20 02:47:41 2003 @@ -19,5 +19,5 @@ LFLAGS= -8 # 8-bit lex scanner for arithmetic -CFLAGS+=-DSHELL -I. -I${.CURDIR} +CFLAGS+=-DSHELL -I. -I${.CURDIR} -DOVERFLOW # for debug: #CFLAGS+= -g -DDEBUG=2 -pg diff -u -r -U 2 -b ../sh.old/arith.h ./arith.h --- ../sh.old/arith.h Fri Jul 19 08:38:51 2002 +++ ./arith.h Sun Apr 20 02:37:37 2003 @@ -35,4 +35,7 @@ */ -int arith(char *); +/* XXX some day probably should go to /usr/include/machine/_inttypes.h */ +#define MAXINT_LEN 20 + +intmax_t arith(char *); int expcmd(int , char **); diff -u -r -U 2 -b ../sh.old/arith.y ./arith.y --- ../sh.old/arith.y Fri Jul 19 08:38:51 2002 +++ ./arith.y Sun Apr 20 03:52:31 2003 @@ -1,2 +1,13 @@ +%{ +#include +#ifdef OVERFLOW +#include "options.h" +#endif + +#define YYSTYPE intmax_t + +static intmax_t arith_res; +%} + %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN @@ -15,5 +26,6 @@ exp: expr = { - return ($1); + arith_res = $1; + return (0); } ; @@ -34,7 +46,25 @@ | expr ARITH_LSHIFT expr = { $$ = $1 << $3; } | expr ARITH_RSHIFT expr = { $$ = $1 >> $3; } - | expr ARITH_ADD expr = { $$ = $1 + $3; } - | expr ARITH_SUB expr = { $$ = $1 - $3; } - | expr ARITH_MUL expr = { $$ = $1 * $3; } + | expr ARITH_ADD expr = { + $$ = $1 + $3; +#ifdef OVERFLOW + if (Oflag && is_add_overflow($1, $3, $$)) + yyerror("overflow in"); +#endif + } + | expr ARITH_SUB expr = { + $$ = $1 - $3; +#ifdef OVERFLOW + if (Oflag && is_add_overflow($1, -$3, $$)) + yyerror("overflow in"); +#endif + } + | expr ARITH_MUL expr = { + $$ = $1 * $3; +#ifdef OVERFLOW + if (Oflag && $$/$1 != $3 ) + yyerror("overflow in"); +#endif + } | expr ARITH_DIV expr = { if ($3 == 0) @@ -110,16 +140,24 @@ int -arith(char *s) +is_add_overflow(intmax_t a, intmax_t b, intmax_t s) { - long result; + if (a > 0 && b > 0 && s <= 0) + return 1; + if (a < 0 && b < 0 && s >= 0) + return 1; + return 0; +} +intmax_t +arith(char *s) +{ arith_buf = arith_startbuf = s; INTOFF; - result = yyparse(); + yyparse(); arith_lex_reset(); /* reprime lex */ INTON; - return (result); + return (arith_res); } @@ -143,5 +181,5 @@ char *concat; char **ap; - long i; + intmax_t i; if (argc > 1) { @@ -168,5 +206,5 @@ i = arith(p); - out1fmt("%ld\n", i); + out1fmt("%jd\n", i); return (! i); } diff -u -r -U 2 -b ../sh.old/arith_lex.l ./arith_lex.l --- ../sh.old/arith_lex.l Fri Jul 19 08:38:51 2002 +++ ./arith_lex.l Sun Apr 20 02:37:37 2003 @@ -44,8 +44,9 @@ #endif /* not lint */ +#include #include "y.tab.h" #include "error.h" -extern int yylval; +extern intmax_t yylval; extern char *arith_buf, *arith_startbuf; #undef YY_INPUT @@ -57,5 +58,5 @@ %% [ \t\n] { ; } -[0-9]+ { yylval = atol(yytext); return(ARITH_NUM); } +[0-9]+ { yylval = strtoll(yytext, NULL, 10); return(ARITH_NUM); } "(" { return(ARITH_LPAREN); } ")" { return(ARITH_RPAREN); } diff -u -r -U 2 -b ../sh.old/expand.c ./expand.c --- ../sh.old/expand.c Fri Jan 17 14:37:03 2003 +++ ./expand.c Sun Apr 20 02:37:37 2003 @@ -46,4 +46,5 @@ #include #include +#include #include #include @@ -367,5 +368,5 @@ { char *p, *start; - int result; + intmax_t result; int begoff; int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); @@ -383,8 +384,8 @@ * characters have to be processed left to right. */ -#if INT_MAX / 1000000000 >= 10 || INT_MIN / 1000000000 <= -10 -#error "integers with more than 10 digits are not supported" -#endif - CHECKSTRSPACE(12 - 2, expdest); +//#if INT_MAX / 1000000000 >= 10 || INT_MIN / 1000000000 <= -10 +//#error "integers with more than 10 digits are not supported" +//#endif + CHECKSTRSPACE(MAXINT_LEN, expdest); USTPUTC('\0', expdest); start = stackblock(); @@ -408,5 +409,5 @@ rmescapes(p+2); result = arith(p+2); - fmtstr(p, 12, "%d", result); + fmtstr(p, MAXINT_LEN + 2, "%qd", result); while (*p++) ; diff -u -r -U 2 -b ../sh.old/options.h ./options.h --- ../sh.old/options.h Tue Aug 27 05:36:28 2002 +++ ./options.h Sun Apr 20 02:24:46 2003 @@ -67,6 +67,13 @@ #define Tflag optlist[16].val #define Pflag optlist[17].val +#ifdef OVERFLOW +#define Oflag optlist[18].val +#endif +#ifdef OVERFLOW +#define NOPTS 19 +#else #define NOPTS 18 +#endif struct optent { @@ -96,4 +103,7 @@ { "trapsasync", 'T', 0 }, { "physical", 'P', 0 }, +#ifdef OVERFLOW + { "overflow", 'O', 0 }, +#endif }; #else diff -u -r -U 2 -b ../sh.old/sh.1 ./sh.1 --- ../sh.old/sh.1 Tue Feb 25 13:27:12 2003 +++ ./sh.1 Sun Apr 20 02:52:02 2003 @@ -44,5 +44,5 @@ .Sh SYNOPSIS .Nm -.Op Fl /+abCEefIimnPpsTuVvx +.Op Fl /+abCEefIimnOPpsTuVvx .Op Fl /+o Ar longname .Op Fl c Ar string @@ -226,4 +226,6 @@ execute them. This is useful for checking the syntax of shell scripts. +.It Fl O Li interactive +If compiled with the overflow checks, turn them during arithmetic operations on. .It Fl P Li physical Change the default for the