From owner-freebsd-bugs@FreeBSD.ORG Sun Jun 12 19:30:21 2005 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E6D0816A41C for ; Sun, 12 Jun 2005 19:30:21 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 95FC843D49 for ; Sun, 12 Jun 2005 19:30:21 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.3/8.13.3) with ESMTP id j5CJUL3m094490 for ; Sun, 12 Jun 2005 19:30:21 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.3/8.13.1/Submit) id j5CJUL1l094487; Sun, 12 Jun 2005 19:30:21 GMT (envelope-from gnats) Resent-Date: Sun, 12 Jun 2005 19:30:21 GMT Resent-Message-Id: <200506121930.j5CJUL1l094487@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Derik van Zuetphen Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7077E16A41C for ; Sun, 12 Jun 2005 19:29:04 +0000 (GMT) (envelope-from dz@426.ch) Received: from smtp2.netcologne.de (smtp2.netcologne.de [194.8.194.218]) by mx1.FreeBSD.org (Postfix) with ESMTP id E204943D4C for ; Sun, 12 Jun 2005 19:29:03 +0000 (GMT) (envelope-from dz@426.ch) Received: from trevize.426.ch (xdsl-81-173-169-181.netcologne.de [81.173.169.181]) by smtp2.netcologne.de (Postfix) with ESMTP id 238CD452B for ; Sun, 12 Jun 2005 21:29:02 +0200 (MEST) Received: by trevize.a.426.ch (Postfix, from userid 1000) id 13F80678E6; Sun, 12 Jun 2005 21:29:12 +0200 (CEST) Message-Id: <20050612192912.13F80678E6@trevize.a.426.ch> Date: Sun, 12 Jun 2005 21:29:12 +0200 (CEST) From: Derik van Zuetphen To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: bin/82170: m4's eval does not work as documented X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Jun 2005 19:30:22 -0000 >Number: 82170 >Category: bin >Synopsis: m4's eval does not work as documented >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Jun 12 19:30:21 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Derik van Zuetphen >Release: FreeBSD 5.4-RELEASE-p1 i386 >Organization: >Environment: System: FreeBSD trevize.a.426.ch 5.4-RELEASE-p1 FreeBSD 5.4-RELEASE-p1 #15: Mon May 30 14:32:58 CEST 2005 root@trevize.a.426.ch:/usr/obj/usr/src/sys/TREVIZE i386 >Description: >From the manpage: --- eval [...] The second argument (if any) specifies the radix for the result, and the third argu- ment (if any) specifies the minimum number of digits in the result. --- This is not implemented. The attached patch fixes this. See also my PR bin/82161. This patch includes the patch from bin/82161! >How-To-Repeat: % echo "eval(16,16,4)"|/usr/bin/m4 16 Correct output should be: % echo "eval(16,16,4)"|./m4 0010 >Fix: diff -ruN --exclude=CVS current/TEST/radix.m4 my/TEST/radix.m4 --- current/TEST/radix.m4 Thu Jan 1 01:00:00 1970 +++ my/TEST/radix.m4 Sun Jun 12 20:57:34 2005 @@ -0,0 +1,65 @@ +define(row,`$1 eval($1,16,2) eval($1,8) eval($1,2,4) eval($1,36)')dnl +Base 10 Base 16 Base 8 Base 2 Base 36 + (>=2 digits) (>=4 digits) +------------------------------------------------------------------------- +row(0) +row(1) +row(2) +row(3) +row(4) +row(5) +row(6) +row(7) +row(8) +row(010) +row(9) +row(10) +row(11) +row(12) +row(13) +row(14) +row(15) +row(0xf) +row(16) +row(17) +row(18) +row(19) +row(20) +row(21) +row(22) +row(23) +row(24) +row(25) +row(26) +row(27) +row(28) +row(29) +row(30) +row(31) +row(32) +row(33) +row(34) +row(35) +row(36) +row(37) +row(100) +row(101) +row(102) +row(1001) +row(-1) +row(-2) +row(-15) +row(-16) +row(-35) +row(-36) +row(-37) +row(-72) +row(-73) + +Margin values on i386, gcc 3.4.2 +-------------------------------- +-INT_MAX +row(-0x7fffffff) + +INT_MAX +row(0x7fffffff) diff -ruN --exclude=CVS current/eval.c my/eval.c --- current/eval.c Mon Aug 16 16:18:21 2004 +++ my/eval.c Thu Feb 24 17:11:48 2005 @@ -76,6 +76,7 @@ static void dopushdef(const char *, const char *); static void dodump(const char *[], int); static void dotrace(const char *[], int, int); +static void doexpr(const char *[], int); static void doifelse(const char *[], int); static int doincl(const char *); static int dopaste(const char *); @@ -189,7 +190,7 @@ * expression */ if (argc > 2) - pbnum(expr(argv[2])); + doexpr(argv, argc); break; case IFELTYPE: @@ -709,6 +710,25 @@ mark_traced(argv[n], on); } else mark_traced(NULL, on); +} + +/* + * doexpr - evaluate arithmetic expression + */ +static void +doexpr(const char *argv[], int argc) +{ + switch (argc) { + case 3: + pbnum(expr(argv[2])); + break; + case 4: + pbnum_radix(expr(argv[2]),atoi(argv[3]),0); + break; + default: /* >= 5 */ + pbnum_radix(expr(argv[2]),atoi(argv[3]),atoi(argv[4])); + break; + } } /* diff -ruN --exclude=CVS current/expr.c my/expr.c --- current/expr.c Sat May 1 05:59:43 2004 +++ my/expr.c Sun May 22 23:11:37 2005 @@ -50,6 +50,7 @@ #include __FBSDID("$FreeBSD: src/usr.bin/m4/expr.c,v 1.14 2004/05/01 03:59:43 smkelly Exp $"); +#include #include #include #include @@ -568,7 +569,8 @@ static int num(int mayeval) { - int rval, c, base; + unsigned int rval; + int c, base; int ndig; rval = 0; @@ -614,10 +616,10 @@ bad_digit: ungetch(); - if (ndig == 0) + if (ndig == 0 || rval > INT_MAX) experr("bad constant"); - return rval; + return (int)rval; } /* diff -ruN --exclude=CVS current/misc.c my/misc.c --- current/misc.c Mon Jul 15 04:15:12 2002 +++ my/misc.c Sun May 22 20:51:51 2005 @@ -122,21 +122,53 @@ } /* - * pbnum - convert number to string, push back on input. + * pbnum_radix - convert number to string, push back on input. */ void -pbnum(int n) +pbnum_radix(int n,int radix,int length) { - int num; + int num,i; + + if (n < 0) { + num = -n; + length--; + } else { + num = n; + } + + if (radix < 2) + radix = 10; + if (radix > 36) + radix = 10; + if (length < 0) + length = 0; - num = (n < 0) ? -n : n; do { - putback(num % 10 + '0'); + i = num % radix; + if (i<10) + putback(i+'0'); + else + putback(i-10+'A'); + if (length > 0) + length--; } - while ((num /= 10) > 0); + while ((num /= radix) > 0); + while (length > 0) { + putback('0'); + length--; + } if (n < 0) putback('-'); +} + +/* + * pbnum - convert number to string, push back on input. + */ +void +pbnum(int n) +{ + pbnum_radix(n,10,0); } /* >Release-Note: >Audit-Trail: >Unformatted: