From tege@hehe.gmplib.org  Mon Apr 16 14:43:10 2012
Return-Path: <tege@hehe.gmplib.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 441AC1065672
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Apr 2012 14:43:10 +0000 (UTC)
	(envelope-from tege@hehe.gmplib.org)
Received: from hehe.gmplib.org (gmplib-00.nada.kth.se [130.237.222.240])
	by mx1.freebsd.org (Postfix) with ESMTP id 00FA38FC0C
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Apr 2012 14:43:09 +0000 (UTC)
Received: from hehe.gmplib.org (localhost [127.0.0.1])
	by hehe.gmplib.org (Postfix) with ESMTP id A009F30D7B
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Apr 2012 16:35:41 +0200 (CEST)
Received: (from tege@localhost)
	by hehe.gmplib.org (8.14.5/8.14.5/Submit) id q3GEZflL022237;
	Mon, 16 Apr 2012 16:35:41 +0200 (CEST)
	(envelope-from tege)
Message-Id: <201204161435.q3GEZflL022237@hehe.gmplib.org>
Date: Mon, 16 Apr 2012 16:35:41 +0200 (CEST)
From: TG <tg@gmplib.org>
Reply-To: tg@gmplib.org
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: m4's eval function ignores documented 2nd and 3rd arguments
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         166994
>Category:       bin
>Synopsis:       m4(1): m4's eval function ignores documented 2nd and 3rd arguments
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    tijl
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 16 14:50:10 UTC 2012
>Closed-Date:    Thu Dec 12 16:14:32 CET 2013
>Last-Modified:  Thu Dec 12 16:14:32 CET 2013
>Originator:     tege
>Release:        FreeBSD 9.0-RELEASE amd64
>Organization:
KTH
>Environment:
System: FreeBSD hehe.gmplib.org 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan 3 07:46:30 UTC 2012 root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64


	
>Description:

The eval() function of /usr/bin/m4 seem to completely ignore the 2nd
(radix) and 3rd (width) arguments.  The man page documents these
arguments, and other implementations of m4 handle them (Solaris, GNU).
This leads to the conclusion that the BSD implementation of eval is
broken in this respect.

>How-To-Repeat:

Execute from sh:

   echo 'eval(12245853,16,10)' | m4

FreeBSD 9.0 (as well as e.g. 8.1) incorrectly outputs "12245853".
Expected output is "0000BADB5D".

>Fix:

I was about to fix it, but found that the license of the code in
question was unacceptable to me.  I only contribute to Free Software,
not to Open Source code bearing a license analogous to a law system
that permits people to sell themselves as slaves.  ;-)
>Release-Note:
>Audit-Trail:

From: Mark Johnston <markjdb@gmail.com>
To: bug-followup@FreeBSD.org, tg@gmplib.org
Cc:  
Subject: Re: bin/166994: m4(1): m4&#39;s eval function ignores documented 2nd
 and 3rd arguments
Date: Wed, 2 May 2012 02:20:16 -0400

 It looks like this was fixed in r228063, which brought in changes from
 NetBSD and OpenBSD:
 
 $ echo 'eval(12245853,16,10)' | m4
 0000badb5d
 
 Unfortunately, that change went in right after the 9.0 branch was created.
 It's on HEAD, but hasn't been merged yet, maybe for some compatibility reasons.
State-Changed-From-To: open->patched 
State-Changed-By: tijl 
State-Changed-When: Fri Oct 25 12:29:51 CEST 2013 
State-Changed-Why:  
Fixed FreeBSD 10 in r228063. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=166994 

From: Torbjorn Granlund <tg@gmplib.org>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/166994: m4(1): m4's eval function ignores documented 2nd and 3rd arguments
Date: Mon, 11 Nov 2013 13:29:18 +0100

 This bug report is for FreeBSD 9.  It is NOT patched.
 
 The m4 command malfunctions in 8.x for any x and 9.y for any y.  The
 documentation nevertheless continues to mention 3 arguments for the eval
 functions.  It is not a bug that the 2nd and 3rd arguments are ignored;
 there is simply no code in m4 that attempts to implement that
 functionality.
 
 Please, please either fix eval to honour 3 arguments, or document it in
 m4's man page as accepting just 1 argument for 8-STABLE and 9-STABLE.
 
 (As things stand now, No FreeBSD release or snapshot work for me on
 Haswell: The m4 bug makes releases inappropriate, kernel panics make
 amd64 FreeBSD 10 prereleases unusable, and clang bugs make i386 FreeBSD
 10 prereleases unusable...)
 
 --=20
 Torbj=C3=B6rn

From: John Baldwin <jhb@freebsd.org>
To: bug-followup@freebsd.org,
 tg@gmplib.org
Cc: tijl@freebsd.org
Subject: Re: bin/166994: m4(1): m4&#39;s eval function ignores documented 2nd and 3rd arguments
Date: Tue, 10 Dec 2013 11:34:51 -0500

 To be clear, the 'patched' state means "fixed in HEAD, but fix still needs to 
 be MFC'd".  If someone doesn't plan on merging it they mark a bug as "closed", 
 not "patched".
 
 That said, it is odd for someone to mark a bug as patched unless they are also 
 assigning it to themselves and assuming responsibility for merging it.  Tijl, 
 are you planning on merging the fix to at least stable/9?
 
 -- 
 John Baldwin
Responsible-Changed-From-To: freebsd-bugs->tijl 
Responsible-Changed-By: tijl 
Responsible-Changed-When: Tue Dec 10 18:32:51 CET 2013 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=166994 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/166994: commit references a PR
Date: Thu, 12 Dec 2013 15:05:17 +0000 (UTC)

 Author: tijl
 Date: Thu Dec 12 15:04:59 2013
 New Revision: 259262
 URL: http://svnweb.freebsd.org/changeset/base/259262
 
 Log:
   MFC r226422, r227241, r228063, r228697, r228698, r228701, r234310, r234850,
   r250226, r250926.
   
   This brings m4 up to date with the version in head and fixes the eval
   command when called with a 2nd and 3rd argument.  The only differences
   remaining are related to the updated flex and byacc in head.
   
   PR:		bin/166994
 
 Added:
   stable/9/usr.bin/m4/lib/
      - copied from r228063, head/usr.bin/m4/lib/
   stable/9/usr.bin/m4/parser.y
      - copied, changed from r228697, head/usr.bin/m4/parser.y
   stable/9/usr.bin/m4/tokenizer.l
      - copied, changed from r228697, head/usr.bin/m4/tokenizer.l
 Modified:
   stable/9/usr.bin/m4/Makefile
   stable/9/usr.bin/m4/TEST/ack.m4
   stable/9/usr.bin/m4/TEST/hanoi.m4
   stable/9/usr.bin/m4/TEST/hash.m4
   stable/9/usr.bin/m4/TEST/sqroot.m4
   stable/9/usr.bin/m4/TEST/string.m4
   stable/9/usr.bin/m4/TEST/test.m4
   stable/9/usr.bin/m4/eval.c
   stable/9/usr.bin/m4/expr.c
   stable/9/usr.bin/m4/extern.h
   stable/9/usr.bin/m4/gnum4.c
   stable/9/usr.bin/m4/look.c
   stable/9/usr.bin/m4/m4.1
   stable/9/usr.bin/m4/main.c
   stable/9/usr.bin/m4/mdef.h
   stable/9/usr.bin/m4/misc.c
   stable/9/usr.bin/m4/pathnames.h
   stable/9/usr.bin/m4/stdd.h
   stable/9/usr.bin/m4/trace.c
 Directory Properties:
   stable/9/usr.bin/m4/   (props changed)
 
 Modified: stable/9/usr.bin/m4/Makefile
 ==============================================================================
 --- stable/9/usr.bin/m4/Makefile	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/Makefile	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -5,10 +5,21 @@
  # 	if you want the paste & spaste macros.
  
  PROG=	m4
 -CFLAGS+=-DEXTENDED
 +CFLAGS+=-DEXTENDED -I${.CURDIR}/lib
 +DPADD=	${LIBY} ${LIBL} ${LIBM}
 +LDADD=	-ly -ll -lm
 +# clang needs 1 while with gcc we can use 2
 +#WARNS=	1
  
 -SRCS=	eval.c expr.c look.c main.c misc.c gnum4.c trace.c
 +SRCS=	eval.c expr.c look.c main.c misc.c gnum4.c trace.c parser.y tokenizer.l
 +.PATH: ${.CURDIR}/lib
 +SRCS+=	ohash_create_entry.c ohash_delete.c ohash_do.c ohash_entries.c \
 +	ohash_enum.c ohash_init.c ohash_int.h ohash_interval.c \
 +	ohash_lookup_interval.c ohash_lookup_memory.c ohash_qlookup.c \
 +	ohash_qlookupi.c
  
 -WARNS?=	0
 +tokenizer.o: parser.h
 +
 +CLEANFILES+=	parser.c parser.h tokenizer.o
  
  .include <bsd.prog.mk>
 
 Modified: stable/9/usr.bin/m4/TEST/ack.m4
 ==============================================================================
 --- stable/9/usr.bin/m4/TEST/ack.m4	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/TEST/ack.m4	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -1,4 +1,4 @@
 -#	$OpenBSD: ack.m4,v 1.2 1996/06/26 05:36:18 deraadt Exp $
 +#	$OpenBSD: ack.m4,v 1.3 2003/06/03 02:56:11 millert Exp $
  #	$NetBSD: ack.m4,v 1.4 1995/09/28 05:37:54 tls Exp $
  #
  # Copyright (c) 1989, 1993
 @@ -15,7 +15,7 @@
  # 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.
 -# 4. Neither the name of the University nor the names of its contributors
 +# 3. 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.
  #
 
 Modified: stable/9/usr.bin/m4/TEST/hanoi.m4
 ==============================================================================
 --- stable/9/usr.bin/m4/TEST/hanoi.m4	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/TEST/hanoi.m4	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -1,4 +1,4 @@
 -#	$OpenBSD: hanoi.m4,v 1.2 1996/06/26 05:36:19 deraadt Exp $
 +#	$OpenBSD: hanoi.m4,v 1.3 2003/06/03 02:56:11 millert Exp $
  #	$NetBSD: hanoi.m4,v 1.4 1995/09/28 05:37:56 tls Exp $
  #
  # Copyright (c) 1989, 1993
 @@ -15,7 +15,7 @@
  # 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.
 -# 4. Neither the name of the University nor the names of its contributors
 +# 3. 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.
  #
 
 Modified: stable/9/usr.bin/m4/TEST/hash.m4
 ==============================================================================
 --- stable/9/usr.bin/m4/TEST/hash.m4	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/TEST/hash.m4	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -1,4 +1,4 @@
 -#	$OpenBSD: hash.m4,v 1.2 1996/06/26 05:36:19 deraadt Exp $
 +#	$OpenBSD: hash.m4,v 1.3 2003/06/03 02:56:11 millert Exp $
  #	$NetBSD: hash.m4,v 1.4 1995/09/28 05:37:58 tls Exp $
  #
  # Copyright (c) 1989, 1993
 @@ -15,7 +15,7 @@
  # 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.
 -# 4. Neither the name of the University nor the names of its contributors
 +# 3. 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.
  #
 
 Modified: stable/9/usr.bin/m4/TEST/sqroot.m4
 ==============================================================================
 --- stable/9/usr.bin/m4/TEST/sqroot.m4	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/TEST/sqroot.m4	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -1,4 +1,4 @@
 -#	$OpenBSD: sqroot.m4,v 1.2 1996/06/26 05:36:20 deraadt Exp $
 +#	$OpenBSD: sqroot.m4,v 1.3 2003/06/03 02:56:11 millert Exp $
  #	$NetBSD: sqroot.m4,v 1.4 1995/09/28 05:38:01 tls Exp $
  #
  # Copyright (c) 1989, 1993
 @@ -15,7 +15,7 @@
  # 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.
 -# 4. Neither the name of the University nor the names of its contributors
 +# 3. 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.
  #
 
 Modified: stable/9/usr.bin/m4/TEST/string.m4
 ==============================================================================
 --- stable/9/usr.bin/m4/TEST/string.m4	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/TEST/string.m4	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -1,4 +1,4 @@
 -#	$OpenBSD: string.m4,v 1.2 1996/06/26 05:36:20 deraadt Exp $
 +#	$OpenBSD: string.m4,v 1.3 2003/06/03 02:56:11 millert Exp $
  #	$NetBSD: string.m4,v 1.4 1995/09/28 05:38:03 tls Exp $
  #
  # Copyright (c) 1989, 1993
 @@ -15,7 +15,7 @@
  # 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.
 -# 4. Neither the name of the University nor the names of its contributors
 +# 3. 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.
  #
 
 Modified: stable/9/usr.bin/m4/TEST/test.m4
 ==============================================================================
 --- stable/9/usr.bin/m4/TEST/test.m4	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/TEST/test.m4	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -1,4 +1,4 @@
 -#	$OpenBSD: test.m4,v 1.2 1996/06/26 05:36:21 deraadt Exp $
 +#	$OpenBSD: test.m4,v 1.3 2003/06/03 02:56:11 millert Exp $
  #	$NetBSD: test.m4,v 1.4 1995/09/28 05:38:05 tls Exp $
  #
  # Copyright (c) 1989, 1993
 @@ -15,7 +15,7 @@
  # 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.
 -# 4. Neither the name of the University nor the names of its contributors
 +# 3. 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.
  #
 
 Modified: stable/9/usr.bin/m4/eval.c
 ==============================================================================
 --- stable/9/usr.bin/m4/eval.c	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/eval.c	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -1,4 +1,4 @@
 -/*	$OpenBSD: eval.c,v 1.44 2002/04/26 16:15:16 espie Exp $	*/
 +/*	$OpenBSD: eval.c,v 1.70 2012/04/12 17:00:11 espie Exp $	*/
  /*	$NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $	*/
  
  /*
 @@ -16,7 +16,7 @@
   * 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.
 - * 4. Neither the name of the University nor the names of its contributors
 + * 3. 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.
   *
 @@ -33,19 +33,10 @@
   * SUCH DAMAGE.
   */
  
 -#ifndef lint
 -#if 0
 -static char sccsid[] = "@(#)eval.c	8.2 (Berkeley) 4/27/95";
 -#else
 -#if 0
 -static char rcsid[] = "$OpenBSD: eval.c,v 1.44 2002/04/26 16:15:16 espie Exp $";
 -#endif
 -#endif
 -#endif /* not lint */
 -
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
  
 +
  /*
   * eval.c
   * Facility: m4 macro processor
 @@ -53,21 +44,21 @@ __FBSDID("$FreeBSD$");
   */
  
  #include <sys/types.h>
 +#include <err.h>
  #include <errno.h>
 +#include <limits.h>
  #include <unistd.h>
 +#include <stdint.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <stddef.h>
  #include <string.h>
  #include <fcntl.h>
 -#include <err.h>
  #include "mdef.h"
  #include "stdd.h"
  #include "extern.h"
  #include "pathnames.h"
  
 -#define BUILTIN_MARKER	"__builtin_"
 -
  static void	dodefn(const char *);
  static void	dopushdef(const char *, const char *);
  static void	dodump(const char *[], int);
 @@ -75,10 +66,9 @@ static void	dotrace(const char *[], int,
  static void	doifelse(const char *[], int);
  static int	doincl(const char *);
  static int	dopaste(const char *);
 -static void	gnu_dochq(const char *[], int);
  static void	dochq(const char *[], int);
 -static void	gnu_dochc(const char *[], int);
  static void	dochc(const char *[], int);
 +static void	dom4wrap(const char *);
  static void	dodiv(int);
  static void	doundiv(const char *[], int);
  static void	dosub(const char *[], int);
 @@ -86,7 +76,7 @@ static void	map(char *, const char *, co
  static const char *handledash(char *, char *, const char *);
  static void	expand_builtin(const char *[], int, int);
  static void	expand_macro(const char *[], int);
 -static void	dump_one_def(ndptr);
 +static void	dump_one_def(const char *, struct macro_definition *);
  
  unsigned long	expansion_id;
  
 @@ -95,7 +85,7 @@ unsigned long	expansion_id;
   *	  argc - number of elements in argv.
   *	  argv - element vector :
   *			argv[0] = definition of a user
 - *				  macro or nil if built-in.
 + *				  macro or NULL if built-in.
   *			argv[1] = name of the macro or
   *				  built-in.
   *			argv[2] = parameters to user-defined
 @@ -110,21 +100,20 @@ unsigned long	expansion_id;
   * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin
   */
  void
 -eval(const char *argv[], int argc, int td)
 +eval(const char *argv[], int argc, int td, int is_traced)
  {
 -	ssize_t mark = -1;
 +	size_t mark = SIZE_MAX;
  
  	expansion_id++;
  	if (td & RECDEF)
 -		errx(1, "%s at line %lu: expanding recursive definition for %s",
 -			CURRENT_NAME, CURRENT_LINE, argv[1]);
 -	if (traced_macros && is_traced(argv[1]))
 +		m4errx(1, "expanding recursive definition for %s.", argv[1]);
 +	if (is_traced)
  		mark = trace(argv, argc, infile+ilevel);
  	if (td == MACRTYPE)
  		expand_macro(argv, argc);
  	else
  		expand_builtin(argv, argc, td);
 -    	if (mark != -1)
 +	if (mark != SIZE_MAX)
  		finish_trace(mark);
  }
  
 @@ -150,9 +139,12 @@ expand_builtin(const char *argv[], int a
    * have macro-or-builtin() type call. We adjust
    * argc to avoid further checking..
    */
 -  	ac = argc;
 + /* we keep the initial value for those built-ins that differentiate
 +  * between builtin() and builtin.
 +  */
 +	ac = argc;
  
 -	if (argc == 3 && !*(argv[2]))
 +	if (argc == 3 && !*(argv[2]) && !mimic_gnu)
  		argc--;
  
  	switch (td & TYPEMASK) {
 @@ -184,9 +176,27 @@ expand_builtin(const char *argv[], int a
  	 * doexpr - evaluate arithmetic
  	 * expression
  	 */
 +	{
 +		int base = 10;
 +		int maxdigits = 0;
 +		const char *errstr;
 +
 +		if (argc > 3) {
 +			base = strtonum(argv[3], 2, 36, &errstr);
 +			if (errstr) {
 +				m4errx(1, "expr: base %s invalid.", argv[3]);
 +			}
 +		}
 +		if (argc > 4) {
 +			maxdigits = strtonum(argv[4], 0, INT_MAX, &errstr);
 +			if (errstr) {
 +				m4errx(1, "expr: maxdigits %s invalid.", argv[4]);
 +			}
 +		}
  		if (argc > 2)
 -			pbnum(expr(argv[2]));
 +			pbnumbase(expr(argv[2]), base, maxdigits);
  		break;
 +	}
  
  	case IFELTYPE:
  		if (argc > 4)
 @@ -200,7 +210,7 @@ expand_builtin(const char *argv[], int a
  	 * another definition
  	 */
  		if (argc > 3) {
 -			if (lookup(argv[2]) != nil)
 +			if (lookup_macro_definition(argv[2]) != NULL)
  				pbstr(argv[3]);
  			else if (argc > 4)
  				pbstr(argv[4]);
 @@ -238,7 +248,7 @@ expand_builtin(const char *argv[], int a
  	 * dosys - execute system command
  	 */
  		if (argc > 2) {
 -			fflush(NULL);
 +			fflush(stdout);
  			sysval = system(argv[2]);
  		}
  		break;
 @@ -255,12 +265,18 @@ expand_builtin(const char *argv[], int a
  	case ESYSCMDTYPE:
  		if (argc > 2)
  			doesyscmd(argv[2]);
 -	    	break;
 +		break;
  	case INCLTYPE:
  		if (argc > 2)
 -			if (!doincl(argv[2]))
 -				err(1, "%s at line %lu: include(%s)",
 -				    CURRENT_NAME, CURRENT_LINE, argv[2]);
 +			if (!doincl(argv[2])) {
 +				if (mimic_gnu) {
 +					warn("%s at line %lu: include(%s)",
 +					    CURRENT_NAME, CURRENT_LINE, argv[2]);
 +					exit_code = 1;
 +				} else
 +					err(1, "%s at line %lu: include(%s)",
 +					    CURRENT_NAME, CURRENT_LINE, argv[2]);
 +			}
  		break;
  
  	case SINCTYPE:
 @@ -271,7 +287,7 @@ expand_builtin(const char *argv[], int a
  	case PASTTYPE:
  		if (argc > 2)
  			if (!dopaste(argv[2]))
 -				err(1, "%s at line %lu: paste(%s)",
 +				err(1, "%s at line %lu: paste(%s)", 
  				    CURRENT_NAME, CURRENT_LINE, argv[2]);
  		break;
  
 @@ -279,19 +295,16 @@ expand_builtin(const char *argv[], int a
  		if (argc > 2)
  			(void) dopaste(argv[2]);
  		break;
 +	case FORMATTYPE:
 +		doformat(argv, argc);
 +		break;
  #endif
  	case CHNQTYPE:
 -		if (mimic_gnu)
 -			gnu_dochq(argv, ac);
 -		else
 -			dochq(argv, argc);
 +		dochq(argv, ac);
  		break;
  
  	case CHNCTYPE:
 -		if (mimic_gnu)
 -			gnu_dochc(argv, ac);
 -		else
 -			dochc(argv, argc);
 +		dochc(argv, argc);
  		break;
  
  	case SUBSTYPE:
 @@ -314,7 +327,7 @@ expand_builtin(const char *argv[], int a
  				pbstr(rquote);
  				pbstr(argv[n]);
  				pbstr(lquote);
 -				putback(COMMA);
 +				pushback(COMMA);
  			}
  			pbstr(rquote);
  			pbstr(argv[3]);
 @@ -350,7 +363,7 @@ expand_builtin(const char *argv[], int a
  	 */
  		if (argc > 2)
  			for (n = 2; n < argc; n++)
 -				remhash(argv[n], ALL);
 +				macro_undefine(argv[n]);
  		break;
  
  	case POPDTYPE:
 @@ -361,7 +374,7 @@ expand_builtin(const char *argv[], int a
  	 */
  		if (argc > 2)
  			for (n = 2; n < argc; n++)
 -				remhash(argv[n], TOP);
 +				macro_popdef(argv[n]);
  		break;
  
  	case MKTMTYPE:
 @@ -395,7 +408,7 @@ expand_builtin(const char *argv[], int a
  		if (argc > 3) {
  			char *temp;
  
 -			temp = xalloc(strlen(argv[2])+1);
 +			temp = xalloc(strlen(argv[2])+1, NULL);
  			if (argc > 4)
  				map(temp, argv[2], argv[3], argv[4]);
  			else
 @@ -441,7 +454,8 @@ expand_builtin(const char *argv[], int a
  	 * dom4wrap - set up for
  	 * wrap-up/wind-down activity
  	 */
 -		m4wraps = (argc > 2) ? xstrdup(argv[2]) : null;
 +		if (argc > 2)
 +			dom4wrap(argv[2]);
  		break;
  
  	case EXITTYPE:
 @@ -488,8 +502,7 @@ expand_builtin(const char *argv[], int a
  		pbstr(lquote);
  		break;
  	default:
 -		errx(1, "%s at line %lu: eval: major botch.",
 -			CURRENT_NAME, CURRENT_LINE);
 +		m4errx(1, "eval: major botch.");
  		break;
  	}
  }
 @@ -512,7 +525,7 @@ expand_macro(const char *argv[], int arg
  	p--;			       /* last character of defn */
  	while (p > t) {
  		if (*(p - 1) != ARGFLAG)
 -			PUTBACK(*p);
 +			PUSHBACK(*p);
  		else {
  			switch (*p) {
  
 @@ -536,10 +549,10 @@ expand_macro(const char *argv[], int arg
  				if (argc > 2) {
  					for (n = argc - 1; n > 2; n--) {
  						pbstr(argv[n]);
 -						putback(COMMA);
 +						pushback(COMMA);
  					}
  					pbstr(argv[2]);
 -			    	}
 +				}
  				break;
                          case '@':
  				if (argc > 2) {
 @@ -547,7 +560,7 @@ expand_macro(const char *argv[], int arg
  						pbstr(rquote);
  						pbstr(argv[n]);
  						pbstr(lquote);
 -						putback(COMMA);
 +						pushback(COMMA);
  					}
  					pbstr(rquote);
  					pbstr(argv[2]);
 @@ -555,8 +568,8 @@ expand_macro(const char *argv[], int arg
  				}
                                  break;
  			default:
 -				PUTBACK(*p);
 -				PUTBACK('$');
 +				PUSHBACK(*p);
 +				PUSHBACK('$');
  				break;
  			}
  			p--;
 @@ -564,42 +577,20 @@ expand_macro(const char *argv[], int arg
  		p--;
  	}
  	if (p == t)		       /* do last character */
 -		PUTBACK(*p);
 +		PUSHBACK(*p);
  }
  
 +
  /*
   * dodefine - install definition in the table
   */
  void
  dodefine(const char *name, const char *defn)
  {
 -	ndptr p;
 -	int n;
 -
 -	if (!*name)
 -		errx(1, "%s at line %lu: null definition.", CURRENT_NAME,
 -		    CURRENT_LINE);
 -	if ((p = lookup(name)) == nil)
 -		p = addent(name);
 -	else if (p->defn != null)
 -		free((char *) p->defn);
 -	if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0) {
 -		n = builtin_type(defn+sizeof(BUILTIN_MARKER)-1);
 -		if (n != -1) {
 -			p->type = n & TYPEMASK;
 -			if ((n & NOARGS) == 0)
 -				p->type |= NEEDARGS;
 -			p->defn = null;
 -			return;
 -		}
 -	}
 -	if (!*defn)
 -		p->defn = null;
 +	if (!*name && !mimic_gnu)
 +		m4errx(1, "null definition.");
  	else
 -		p->defn = xstrdup(defn);
 -	p->type = MACRTYPE;
 -	if (STREQ(name, defn))
 -		p->type |= RECDEF;
 +		macro_define(name, defn);
  }
  
  /*
 @@ -609,16 +600,15 @@ dodefine(const char *name, const char *d
  static void
  dodefn(const char *name)
  {
 -	ndptr p;
 -	const char *real;
 +	struct macro_definition *p;
  
 -	if ((p = lookup(name)) != nil) {
 -		if (p->defn != null) {
 +	if ((p = lookup_macro_definition(name)) != NULL) {
 +		if ((p->type & TYPEMASK) == MACRTYPE) {
  			pbstr(rquote);
  			pbstr(p->defn);
  			pbstr(lquote);
 -		} else if ((real = builtin_realname(p->type)) != NULL) {
 -			pbstr(real);
 +		} else {
 +			pbstr(p->defn);
  			pbstr(BUILTIN_MARKER);
  		}
  	}
 @@ -634,40 +624,28 @@ dodefn(const char *name)
  static void
  dopushdef(const char *name, const char *defn)
  {
 -	ndptr p;
 -
 -	if (!*name)
 -		errx(1, "%s at line %lu: null definition", CURRENT_NAME,
 -		    CURRENT_LINE);
 -	p = addent(name);
 -	if (!*defn)
 -		p->defn = null;
 +	if (!*name && !mimic_gnu)
 +		m4errx(1, "null definition.");
  	else
 -		p->defn = xstrdup(defn);
 -	p->type = MACRTYPE;
 -	if (STREQ(name, defn))
 -		p->type |= RECDEF;
 +		macro_pushdef(name, defn);
  }
  
  /*
   * dump_one_def - dump the specified definition.
   */
  static void
 -dump_one_def(ndptr p)
 +dump_one_def(const char *name, struct macro_definition *p)
  {
 -	const char *real;
 -
 +	if (!traceout)
 +		traceout = stderr;
  	if (mimic_gnu) {
  		if ((p->type & TYPEMASK) == MACRTYPE)
 -			fprintf(traceout, "%s:\t%s\n", p->name, p->defn);
 +			fprintf(traceout, "%s:\t%s\n", name, p->defn);
  		else {
 -			real = builtin_realname(p->type);
 -			if (real == NULL)
 -				real = null;
 -			fprintf(traceout, "%s:\t<%s>\n", p->name, real);
 -	    	}
 +			fprintf(traceout, "%s:\t<%s>\n", name, p->defn);
 +		}
  	} else
 -		fprintf(traceout, "`%s'\t`%s'\n", p->name, p->defn);
 +		fprintf(traceout, "`%s'\t`%s'\n", name, p->defn);
  }
  
  /*
 @@ -679,17 +657,14 @@ static void
  dodump(const char *argv[], int argc)
  {
  	int n;
 -	ndptr p;
 +	struct macro_definition *p;
  
  	if (argc > 2) {
  		for (n = 2; n < argc; n++)
 -			if ((p = lookup(argv[n])) != nil)
 -				dump_one_def(p);
 -	} else {
 -		for (n = 0; n < HASHSIZE; n++)
 -			for (p = hashtab[n]; p != nil; p = p->nxtptr)
 -				dump_one_def(p);
 -	}
 +			if ((p = lookup_macro_definition(argv[n])) != NULL)
 +				dump_one_def(argv[n], p);
 +	} else
 +		macro_for_all(dump_one_def);
  }
  
  /*
 @@ -734,15 +709,10 @@ static int
  doincl(const char *ifile)
  {
  	if (ilevel + 1 == MAXINP)
 -		errx(1, "%s at line %lu: too many include files.",
 -		    CURRENT_NAME, CURRENT_LINE);
 +		m4errx(1, "too many include files.");
  	if (fopen_trypath(infile+ilevel+1, ifile) != NULL) {
  		ilevel++;
 -		if ((inname[ilevel] = strdup(ifile)) == NULL)
 -			err(1, NULL);
 -		inlineno[ilevel] = 1;
  		bbase[ilevel] = bufbase = bp;
 -		emitline();
  		return (1);
  	} else
  		return (0);
 @@ -760,97 +730,74 @@ dopaste(const char *pfile)
  	int c;
  
  	if ((pf = fopen(pfile, "r")) != NULL) {
 -		fprintf(active, "#line 1 \"%s\"\n", pfile);
 +		if (synch_lines)
 +		    fprintf(active, "#line 1 \"%s\"\n", pfile);
  		while ((c = getc(pf)) != EOF)
  			putc(c, active);
  		(void) fclose(pf);
 -		emitline();
 +		emit_synchline();
  		return (1);
  	} else
  		return (0);
  }
  #endif
  
 +/*
 + * dochq - change quote characters
 + */
  static void
 -gnu_dochq(const char *argv[], int ac)
 +dochq(const char *argv[], int ac)
  {
 -	/* In gnu-m4 mode, the only way to restore quotes is to have no
 -	 * arguments at all. */
  	if (ac == 2) {
 -		lquote[0] = LQUOTE, lquote[1] = EOS;
 -		rquote[0] = RQUOTE, rquote[1] = EOS;
 +		lquote[0] = LQUOTE; lquote[1] = EOS;
 +		rquote[0] = RQUOTE; rquote[1] = EOS;
  	} else {
  		strlcpy(lquote, argv[2], sizeof(lquote));
 -		if(ac > 3)
 +		if (ac > 3) {
  			strlcpy(rquote, argv[3], sizeof(rquote));
 -		else
 -			rquote[0] = EOS;
 +		} else {
 +			rquote[0] = ECOMMT; rquote[1] = EOS;
 +		}
  	}
  }
  
  /*
 - * dochq - change quote characters
 + * dochc - change comment characters
   */
  static void
 -dochq(const char *argv[], int argc)
 -{
 -	if (argc > 2) {
 -		if (*argv[2])
 -			strlcpy(lquote, argv[2], sizeof(lquote));
 -		else {
 -			lquote[0] = LQUOTE;
 -			lquote[1] = EOS;
 -		}
 -		if (argc > 3) {
 -			if (*argv[3])
 -				strlcpy(rquote, argv[3], sizeof(rquote));
 -		} else
 -			strcpy(rquote, lquote);
 -	} else {
 -		lquote[0] = LQUOTE, lquote[1] = EOS;
 -		rquote[0] = RQUOTE, rquote[1] = EOS;
 -	}
 -}
 -
 -static void
 -gnu_dochc(const char *argv[], int ac)
 +dochc(const char *argv[], int argc)
  {
 -	/* In gnu-m4 mode, no arguments mean no comment
 -	 * arguments at all. */
 -	if (ac == 2) {
 +/* XXX Note that there is no difference between no argument and a single
 + * empty argument.
 + */
 +	if (argc == 2) {
  		scommt[0] = EOS;
  		ecommt[0] = EOS;
  	} else {
 -		if (*argv[2])
 -			strlcpy(scommt, argv[2], sizeof(scommt));
 -		else
 -			scommt[0] = SCOMMT, scommt[1] = EOS;
 -		if(ac > 3 && *argv[3])
 +		strlcpy(scommt, argv[2], sizeof(scommt));
 +		if (argc == 3) {
 +			ecommt[0] = ECOMMT; ecommt[1] = EOS;
 +		} else {
  			strlcpy(ecommt, argv[3], sizeof(ecommt));
 -		else
 -			ecommt[0] = ECOMMT, ecommt[1] = EOS;
 +		}
  	}
  }
 +
  /*
 - * dochc - change comment characters
 + * dom4wrap - expand text at EOF
   */
  static void
 -dochc(const char *argv[], int argc)
 +dom4wrap(const char *text)
  {
 -	if (argc > 2) {
 -		if (*argv[2])
 -			strlcpy(scommt, argv[2], sizeof(scommt));
 -		if (argc > 3) {
 -			if (*argv[3])
 -				strlcpy(ecommt, argv[3], sizeof(ecommt));
 -		}
 +	if (wrapindex >= maxwraps) {
 +		if (maxwraps == 0)
 +			maxwraps = 16;
  		else
 -			ecommt[0] = ECOMMT, ecommt[1] = EOS;
 -	}
 -	else {
 -		scommt[0] = SCOMMT, scommt[1] = EOS;
 -		ecommt[0] = ECOMMT, ecommt[1] = EOS;
 +			maxwraps *= 2;
 +		m4wraps = xrealloc(m4wraps, maxwraps * sizeof(*m4wraps),
 +		   "too many m4wraps");
  	}
 +	m4wraps[wrapindex++] = xstrdup(text);
  }
  
  /*
 @@ -867,14 +814,14 @@ dodiv(int n)
  			resizedivs(n + 10);
  		else
  			n = 0;		/* bitbucket */
 -    	}
 +	}
  
  	if (n < 0)
  		n = 0;		       /* bitbucket */
  	if (outfile[n] == NULL) {
  		char fname[] = _PATH_DIVNAME;
  
 -		if ((fd = mkstemp(fname)) < 0 ||
 +		if ((fd = mkstemp(fname)) < 0 || 
  			(outfile[n] = fdopen(fd, "w+")) == NULL)
  				err(1, "%s: cannot divert", fname);
  		if (unlink(fname) == -1)
 @@ -895,10 +842,15 @@ doundiv(const char *argv[], int argc)
  
  	if (argc > 2) {
  		for (ind = 2; ind < argc; ind++) {
 -			n = atoi(argv[ind]);
 -			if (n > 0 && n < maxout && outfile[n] != NULL)
 -				getdiv(n);
 -
 +			const char *errstr;
 +			n = strtonum(argv[ind], 1, INT_MAX, &errstr);
 +			if (errstr) {
 +				if (errno == EINVAL && mimic_gnu)
 +					getdivfile(argv[ind]);
 +			} else {
 +				if (n < maxout && outfile[n] != NULL)
 +					getdiv(n);
 +			}
  		}
  	}
  	else
 @@ -931,7 +883,7 @@ dosub(const char *argv[], int argc)
  #endif
  	if (fc >= ap && fc < ap + strlen(ap))
  		for (k = fc + nc - 1; k >= fc; k--)
 -			putback(*k);
 +			pushback(*k);
  }
  
  /*
 @@ -939,25 +891,11 @@ dosub(const char *argv[], int argc)
   * map every character of s1 that is specified in from
   * into s3 and replace in s. (source s1 remains untouched)
   *
 - * This is a standard implementation of map(s,from,to) function of ICON
 - * language. Within mapvec, we replace every character of "from" with
 - * the corresponding character in "to". If "to" is shorter than "from",
 - * than the corresponding entries are null, which means that those
 - * characters dissapear altogether. Furthermore, imagine
 - * map(dest, "sourcestring", "srtin", "rn..*") type call. In this case,
 - * `s' maps to `r', `r' maps to `n' and `n' maps to `*'. Thus, `s'
 - * ultimately maps to `*'. In order to achieve this effect in an efficient
 - * manner (i.e. without multiple passes over the destination string), we
 - * loop over mapvec, starting with the initial source character. if the
 - * character value (dch) in this location is different than the source
 - * character (sch), sch becomes dch, once again to index into mapvec, until
 - * the character value stabilizes (i.e. sch = dch, in other words
 - * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
 - * character, it will stabilize, since mapvec[0] == 0 at all times. At the
 - * end, we restore mapvec* back to normal where mapvec[n] == n for
 - * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
 - * about 5 times faster than any algorithm that makes multiple passes over
 - * destination string.
 + * This is derived from the a standard implementation of map(s,from,to) 
 + * function of ICON language. Within mapvec, we replace every character 
 + * of "from" with the corresponding character in "to". 
 + * If "to" is shorter than "from", than the corresponding entries are null, 
 + * which means that those characters dissapear altogether. 
   */
  static void
  map(char *dest, const char *src, const char *from, const char *to)
 @@ -966,6 +904,8 @@ map(char *dest, const char *src, const c
  	unsigned char sch, dch;
  	static char frombis[257];
  	static char tobis[257];
 +	int i;
 +	char seen[256];
  	static unsigned char mapvec[256] = {
  	    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
  	    19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
 @@ -1000,17 +940,21 @@ map(char *dest, const char *src, const c
  	 * create a mapping between "from" and
  	 * "to"
  	 */
 -		while (*from)
 -			mapvec[(unsigned char)(*from++)] = (*to) ?
 -				(unsigned char)(*to++) : 0;
 +		for (i = 0; i < 256; i++)
 +			seen[i] = 0;
 +		while (*from) {
 +			if (!seen[(unsigned char)(*from)]) {
 +				mapvec[(unsigned char)(*from)] = (unsigned char)(*to);
 +				seen[(unsigned char)(*from)] = 1;
 +			}
 +			from++;
 +			if (*to)
 +				to++;
 +		}
  
  		while (*src) {
  			sch = (unsigned char)(*src++);
  			dch = mapvec[sch];
 -			while (dch != sch) {
 -				sch = dch;
 -				dch = mapvec[sch];
 -			}
  			if ((*dest = (char)dch))
  				dest++;
  		}
 @@ -1040,12 +984,23 @@ handledash(char *buffer, char *end, cons
  	while(*src) {
  		if (src[1] == '-' && src[2]) {
  			unsigned char i;
 -			for (i = (unsigned char)src[0];
 -			    i <= (unsigned char)src[2]; i++) {
 -				*p++ = i;
 -				if (p == end) {
 -					*p = '\0';
 -					return buffer;
 +			if ((unsigned char)src[0] <= (unsigned char)src[2]) {
 +				for (i = (unsigned char)src[0]; 
 +				    i <= (unsigned char)src[2]; i++) {
 +					*p++ = i;
 +					if (p == end) {
 +						*p = '\0';
 +						return buffer;
 +					}
 +				}
 +			} else {
 +				for (i = (unsigned char)src[0]; 
 +				    i >= (unsigned char)src[2]; i--) {
 +					*p++ = i;
 +					if (p == end) {
 +						*p = '\0';
 +						return buffer;
 +					}
  				}
  			}
  			src += 3;
 
 Modified: stable/9/usr.bin/m4/expr.c
 ==============================================================================
 --- stable/9/usr.bin/m4/expr.c	Thu Dec 12 14:49:26 2013	(r259261)
 +++ stable/9/usr.bin/m4/expr.c	Thu Dec 12 15:04:59 2013	(r259262)
 @@ -1,641 +1,47 @@
 -/*	$OpenBSD: expr.c,v 1.14 2002/04/26 16:15:16 espie Exp $	*/
 -/*	$NetBSD: expr.c,v 1.7 1995/09/28 05:37:31 tls Exp $	*/
 -
 +/* $OpenBSD: expr.c,v 1.18 2010/09/07 19:58:09 marco Exp $ */
  /*
 - * Copyright (c) 1989, 1993
 - *	The Regents of the University of California.  All rights reserved.
 - *
 - * This code is derived from software contributed to Berkeley by
 - * Ozan Yigit at York University.
 - *
 - * 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.
 - * 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.
 + * Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org>
   *
 - * 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.
 + * Permission to use, copy, modify, and distribute this software for any
 + * purpose with or without fee is hereby granted, provided that the above
 + * copyright notice and this permission notice appear in all copies.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */
 -
 -#ifndef lint
 -#if 0
 -static char sccsid[] = "@(#)expr.c	8.2 (Berkeley) 4/29/95";
 -#else
 -#if 0
 -static char rcsid[] = "$OpenBSD: expr.c,v 1.14 2002/04/26 16:15:16 espie Exp $";
 -#endif
 -#endif
 -#endif /* not lint */
 -
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
  
 -#include <sys/types.h>
 -#include <ctype.h>
 -#include <err.h>
 -#include <stddef.h>
 +#include <stdint.h>
  #include <stdio.h>
 +#include <stddef.h>
  #include "mdef.h"
  #include "extern.h"
  
 -/*
 - *      expression evaluator: performs a standard recursive
 - *      descent parse to evaluate any expression permissible
 - *      within the following grammar:
 - *
 - *      expr    :       query EOS
 - *      query   :       lor
 - *              |       lor "?" query ":" query
 - *      lor     :       land { "||" land }
 - *      land    :       bor { "&&" bor }
 - *      bor     :       xor { "|" xor }
 - *      xor     :       band { "^" eqrel }
 - *      band    :       eqrel { "&" eqrel }
 - *      eqrel   :       nerel { ("==" | "!=") nerel }
 - *      nerel   :       shift { ("<" | ">" | "<=" | ">=") shift }
 - *      shift   :       primary { ("<<" | ">>") primary }
 - *      primary :       term { ("+" | "-") term }
 - *      term    :       exp { ("*" | "/" | "%") exp }
 - *      exp     :       unary { "**" unary }
 - *      unary   :       factor
 - *              |       ("+" | "-" | "~" | "!") unary
 - *      factor  :       constant
 
 *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
 _______________________________________________
 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"
 
State-Changed-From-To: patched->closed 
State-Changed-By: tijl 
State-Changed-When: Thu Dec 12 16:13:28 CET 2013 
State-Changed-Why:  
Fixed in stable/9 as of r259262. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=166994 
>Unformatted:
