Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Nov 2011 13:32:39 +0000 (UTC)
From:      Baptiste Daroussin <bapt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r228063 - in head/usr.bin/m4: . lib
Message-ID:  <201111281332.pASDWdq6092980@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bapt (ports committer)
Date: Mon Nov 28 13:32:39 2011
New Revision: 228063
URL: http://svn.freebsd.org/changeset/base/228063

Log:
  Synchronize with laster version of m4 from OpenBSD and NetBSD
  This bring better compatibility with gnum4
  
  Reviewed by:	cognet
  Approved by:	cognet
  Obtained from:	OpenBSD, NetBSD

Added:
  head/usr.bin/m4/lib/
  head/usr.bin/m4/lib/ohash.h   (contents, props changed)
  head/usr.bin/m4/lib/ohash_create_entry.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_delete.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_do.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_entries.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_enum.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_init.3   (contents, props changed)
  head/usr.bin/m4/lib/ohash_init.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_int.h   (contents, props changed)
  head/usr.bin/m4/lib/ohash_interval.3   (contents, props changed)
  head/usr.bin/m4/lib/ohash_interval.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_lookup_interval.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_lookup_memory.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_qlookup.c   (contents, props changed)
  head/usr.bin/m4/lib/ohash_qlookupi.c   (contents, props changed)
  head/usr.bin/m4/parser.y   (contents, props changed)
  head/usr.bin/m4/tokenizer.l   (contents, props changed)
Modified:
  head/usr.bin/m4/Makefile
  head/usr.bin/m4/eval.c
  head/usr.bin/m4/expr.c
  head/usr.bin/m4/extern.h
  head/usr.bin/m4/gnum4.c
  head/usr.bin/m4/look.c
  head/usr.bin/m4/m4.1
  head/usr.bin/m4/main.c
  head/usr.bin/m4/mdef.h
  head/usr.bin/m4/misc.c
  head/usr.bin/m4/pathnames.h
  head/usr.bin/m4/stdd.h
  head/usr.bin/m4/trace.c

Modified: head/usr.bin/m4/Makefile
==============================================================================
--- head/usr.bin/m4/Makefile	Mon Nov 28 13:30:14 2011	(r228062)
+++ head/usr.bin/m4/Makefile	Mon Nov 28 13:32:39 2011	(r228063)
@@ -5,8 +5,20 @@
 # 	if you want the paste & spaste macros.
 
 PROG=	m4
-CFLAGS+=-DEXTENDED
+CFLAGS+=-DEXTENDED -I${.CURDIR}/lib
+LDADD=	-ly -ll
+# 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
+
+tokenizer.o: parser.h
+
+CLEANFILES+=	parser.c parser.h tokenizer.o
 
 .include <bsd.prog.mk>

Modified: head/usr.bin/m4/eval.c
==============================================================================
--- head/usr.bin/m4/eval.c	Mon Nov 28 13:30:14 2011	(r228062)
+++ head/usr.bin/m4/eval.c	Mon Nov 28 13:32:39 2011	(r228063)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: eval.c,v 1.44 2002/04/26 16:15:16 espie Exp $	*/
+/*	$OpenBSD: eval.c,v 1.69 2011/03/24 11:23:08 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,7 +265,7 @@ 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]))
@@ -271,7 +281,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 +289,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 +321,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 +357,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 +368,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 +402,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 +448,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 +496,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 +519,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 +543,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 +554,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 +562,8 @@ expand_macro(const char *argv[], int arg
 				}
                                 break;
 			default:
-				PUTBACK(*p);
-				PUTBACK('$');
+				PUSHBACK(*p);
+				PUSHBACK('$');
 				break;
 			}
 			p--;
@@ -564,42 +571,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 +594,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 +618,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 +651,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 +703,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 +724,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 +808,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 +836,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 +877,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 +885,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 +898,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 +934,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 +978,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: head/usr.bin/m4/expr.c
==============================================================================
--- head/usr.bin/m4/expr.c	Mon Nov 28 13:30:14 2011	(r228062)
+++ head/usr.bin/m4/expr.c	Mon Nov 28 13:32:39 2011	(r228063)
@@ -1,640 +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    :       exponent { ("*" | "/" | "%") exponent }
- *      exponent:       unary { "**" unary }
- *      unary   :       factor
- *              |       ("+" | "-" | "~" | "!") unary
- *      factor  :       constant
- *              |       "(" query ")"
- *      constant:       num
- *              |       "'" CHAR "'"
- *      num     :       DIGIT
- *              |       DIGIT num
- *
- *
- *      This expression evaluator is lifted from a public-domain
- *      C Pre-Processor included with the DECUS C Compiler distribution.
- *      It is hacked somewhat to be suitable for m4.
- *
- *      Originally by:  Mike Lutz
- *                      Bob Harper
- */
-
-#define EQL     0
-#define NEQ     1
-#define LSS     2
-#define LEQ     3
-#define GTR     4
-#define GEQ     5
-#define OCTAL   8
-#define DECIMAL 10
-#define HEX	16
-
-static const char *nxtch;		       /* Parser scan pointer */
-static const char *where;
-
-static int query(int mayeval);
-static int lor(int mayeval);
-static int land(int mayeval);
-static int bor(int mayeval);
-static int xor(int mayeval);
-static int band(int mayeval);
-static int eqrel(int mayeval);
-static int nerel(int mayeval);
-static int shift(int mayeval);
-static int primary(int mayeval);
-static int term(int mayeval);
-static int exponent(int mayeval);
-static int unary(int mayeval);
-static int factor(int mayeval);
-static int constant(int mayeval);
-static int num(int mayeval);
-static int skipws(void);
-static void experr(const char *);
-
-/*
- * For longjmp
- */
-#include <setjmp.h>
-static jmp_buf expjump;
+int32_t end_result;
+const char *copy_toeval;
+int yyerror(const char *msg);
 
-/*
- * macros:
- *      ungetch - Put back the last character examined.
- *      getch   - return the next character from expr string.
- */
-#define ungetch()       nxtch--
-#define getch()         *nxtch++
+extern void yy_scan_string(const char *);
+extern int yyparse(void);
 
 int
-expr(const char *expbuf)
-{
-	int rval;
-
-	nxtch = expbuf;
-	where = expbuf;
-	if (setjmp(expjump) != 0)
-		return FALSE;
-
-	rval = query(1);
-	if (skipws() == EOS)
-		return rval;
-
-	printf("m4: ill-formed expression.\n");
-	return FALSE;
-}
-
-/*
- * query : lor | lor '?' query ':' query
- */
-static int
-query(int mayeval)
-{
-	int result, true_val, false_val;
-
-	result = lor(mayeval);
-	if (skipws() != '?') {
-		ungetch();
-		return result;
-	}
-
-	true_val = query(result);
-	if (skipws() != ':')
-		experr("bad query: missing \":\"");
-
-	false_val = query(!result);
-	return result ? true_val : false_val;
-}
-
-/*
- * lor : land { '||' land }
- */
-static int
-lor(int mayeval)
-{
-	int c, vl, vr;
-
-	vl = land(mayeval);
-	while ((c = skipws()) == '|') {
-		if (getch() != '|') {
-			ungetch();

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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