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 <es...@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 ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to