Author: bapt
Date: Sun Jul 27 22:54:13 2014
New Revision: 269162
URL: http://svnweb.freebsd.org/changeset/base/269162

Log:
  Sync with OpenBSD
  This brings:
  - check for integer overflows in custom allocs
  - fix potential integer overflows in memory allocation
  - annotate regexp error messages with source string
  - better error handling in mkstemp/unlink/fdopen logic

Added:
  head/usr.bin/m4/lib/ohash.c   (contents, props changed)
Deleted:
  head/usr.bin/m4/lib/ohash_create_entry.c
  head/usr.bin/m4/lib/ohash_delete.c
  head/usr.bin/m4/lib/ohash_do.c
  head/usr.bin/m4/lib/ohash_entries.c
  head/usr.bin/m4/lib/ohash_enum.c
  head/usr.bin/m4/lib/ohash_init.c
  head/usr.bin/m4/lib/ohash_interval.c
  head/usr.bin/m4/lib/ohash_lookup_interval.c
  head/usr.bin/m4/lib/ohash_lookup_memory.c
  head/usr.bin/m4/lib/ohash_qlookup.c
  head/usr.bin/m4/lib/ohash_qlookupi.c
Modified:
  head/usr.bin/m4/Makefile
  head/usr.bin/m4/eval.c
  head/usr.bin/m4/extern.h
  head/usr.bin/m4/gnum4.c
  head/usr.bin/m4/lib/ohash.h
  head/usr.bin/m4/lib/ohash_init.3
  head/usr.bin/m4/lib/ohash_interval.3
  head/usr.bin/m4/look.c
  head/usr.bin/m4/m4.1
  head/usr.bin/m4/main.c
  head/usr.bin/m4/misc.c

Modified: head/usr.bin/m4/Makefile
==============================================================================
--- head/usr.bin/m4/Makefile    Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/Makefile    Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.10 2002/04/26 13:13:41 espie Exp $
+#      $OpenBSD: Makefile,v 1.13 2014/05/12 19:11:19 espie Exp $
 # $FreeBSD$
 
 # -DEXTENDED 
@@ -15,10 +15,7 @@ NO_WMISSING_VARIABLE_DECLARATIONS=
 
 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
+SRCS+= ohash.c
 
 tokenizer.o: parser.h
 

Modified: head/usr.bin/m4/eval.c
==============================================================================
--- head/usr.bin/m4/eval.c      Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/eval.c      Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: eval.c,v 1.70 2012/04/12 17:00:11 espie Exp $ */
+/*     $OpenBSD: eval.c,v 1.73 2014/07/11 21:04:17 espie Exp $ */
 /*     $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $      */
 
 /*
@@ -267,7 +267,7 @@ expand_builtin(const char *argv[], int a
                        doesyscmd(argv[2]);
                break;
        case INCLTYPE:
-               if (argc > 2)
+               if (argc > 2) {
                        if (!doincl(argv[2])) {
                                if (mimic_gnu) {
                                        warn("%s at line %lu: include(%s)",
@@ -277,6 +277,7 @@ expand_builtin(const char *argv[], int a
                                        err(1, "%s at line %lu: include(%s)",
                                            CURRENT_NAME, CURRENT_LINE, 
argv[2]);
                        }
+               }
                break;
 
        case SINCTYPE:
@@ -794,7 +795,7 @@ dom4wrap(const char *text)
                        maxwraps = 16;
                else
                        maxwraps *= 2;
-               m4wraps = xrealloc(m4wraps, maxwraps * sizeof(*m4wraps),
+               m4wraps = xreallocarray(m4wraps, maxwraps, sizeof(*m4wraps),
                   "too many m4wraps");
        }
        m4wraps[wrapindex++] = xstrdup(text);
@@ -821,11 +822,10 @@ dodiv(int n)
        if (outfile[n] == NULL) {
                char fname[] = _PATH_DIVNAME;
 
-               if ((fd = mkstemp(fname)) < 0 || 
-                       (outfile[n] = fdopen(fd, "w+")) == NULL)
-                               err(1, "%s: cannot divert", fname);
-               if (unlink(fname) == -1)
-                       err(1, "%s: cannot unlink", fname);
+               if ((fd = mkstemp(fname)) < 0 ||
+                   unlink(fname) == -1 ||
+                   (outfile[n] = fdopen(fd, "w+")) == NULL)
+                       err(1, "%s: cannot divert", fname);
        }
        active = outfile[n];
 }

Modified: head/usr.bin/m4/extern.h
==============================================================================
--- head/usr.bin/m4/extern.h    Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/extern.h    Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.52 2012/04/12 17:00:11 espie Exp $       */
+/*     $OpenBSD: extern.h,v 1.54 2014/05/12 19:11:19 espie Exp $ */
 /*     $NetBSD: extern.h,v 1.3 1996/01/13 23:25:24 pk Exp $    */
 
 /*-
@@ -104,8 +104,10 @@ extern void        pbnumbase(int, int, int);
 extern void    pbunsigned(unsigned long);
 extern void    pbstr(const char *);
 extern void    pushback(int);
-extern void    *xalloc(size_t, const char *fmt, ...);
-extern void    *xrealloc(void *, size_t, const char *fmt, ...);
+extern void    *xalloc(size_t, const char *, ...);
+extern void    *xcalloc(size_t, size_t, const char *, ...);
+extern void    *xrealloc(void *, size_t, const char *, ...);
+extern void    *xreallocarray(void *, size_t, size_t, const char *, ...);
 extern char    *xstrdup(const char *);
 extern void    usage(void);
 extern void    resizedivs(int);

Modified: head/usr.bin/m4/gnum4.c
==============================================================================
--- head/usr.bin/m4/gnum4.c     Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/gnum4.c     Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,4 +1,4 @@
-/* $OpenBSD: gnum4.c,v 1.42 2011/11/06 12:25:43 espie Exp $ */
+/* $OpenBSD: gnum4.c,v 1.46 2014/07/10 14:12:31 espie Exp $ */
 
 /*
  * Copyright (c) 1999 Marc Espie
@@ -196,10 +196,12 @@ static void addchars(const char *, size_
 static void addchar(int);
 static char *twiddle(const char *);
 static char *getstring(void);
-static void exit_regerror(int, regex_t *);
-static void do_subst(const char *, regex_t *, const char *, regmatch_t *);
-static void do_regexpindex(const char *, regex_t *, regmatch_t *);
-static void do_regexp(const char *, regex_t *, const char *, regmatch_t *);
+static void exit_regerror(int, regex_t *, const char *);
+static void do_subst(const char *, regex_t *, const char *, const char *,
+    regmatch_t *);
+static void do_regexpindex(const char *, regex_t *, const char *, regmatch_t 
*);
+static void do_regexp(const char *, regex_t *, const char *, const char *,
+    regmatch_t *);
 static void add_sub(int, const char *, regex_t *, regmatch_t *);
 static void add_replace(const char *, regex_t *, const char *, regmatch_t *);
 #define addconstantstring(s) addchars((s), sizeof(s)-1)
@@ -243,7 +245,7 @@ getstring(void)
 
 
 static void
-exit_regerror(int er, regex_t *re)
+exit_regerror(int er, regex_t *re, const char *source)
 {
        size_t  errlen;
        char    *errbuf;
@@ -252,7 +254,7 @@ exit_regerror(int er, regex_t *re)
        errbuf = xalloc(errlen,
            "malloc in regerror: %lu", (unsigned long)errlen);
        regerror(er, re, errbuf, errlen);
-       m4errx(1, "regular expression error: %s.", errbuf);
+       m4errx(1, "regular expression error in %s: %s.", source, errbuf);
 }
 
 static void
@@ -296,7 +298,7 @@ add_replace(const char *string, regex_t 
                                p++;
                                continue;
                        }
-                       if (isdigit(p[1])) {
+                       if (isdigit((unsigned char)p[1])) {
                                add_sub(*(++p) - '0', string, re, pm);
                                continue;
                        }
@@ -306,7 +308,8 @@ add_replace(const char *string, regex_t 
 }
 
 static void
-do_subst(const char *string, regex_t *re, const char *replace, regmatch_t *pm)
+do_subst(const char *string, regex_t *re, const char *source,
+    const char *replace, regmatch_t *pm)
 {
        int error;
        int flags = 0;
@@ -341,12 +344,13 @@ do_subst(const char *string, regex_t *re
                string += pm[0].rm_eo;
        }
        if (error != REG_NOMATCH)
-               exit_regerror(error, re);
+               exit_regerror(error, re, source);
        pbstr(string);
 }
 
 static void
-do_regexp(const char *string, regex_t *re, const char *replace, regmatch_t *pm)
+do_regexp(const char *string, regex_t *re, const char *source,
+    const char *replace, regmatch_t *pm)
 {
        int error;
 
@@ -358,12 +362,13 @@ do_regexp(const char *string, regex_t *r
        case REG_NOMATCH:
                break;
        default:
-               exit_regerror(error, re);
+               exit_regerror(error, re, source);
        }
 }
 
 static void
-do_regexpindex(const char *string, regex_t *re, regmatch_t *pm)
+do_regexpindex(const char *string, regex_t *re, const char *source,
+    regmatch_t *pm)
 {
        int error;
 
@@ -375,7 +380,7 @@ do_regexpindex(const char *string, regex
                pbnum(-1);
                break;
        default:
-               exit_regerror(error, re);
+               exit_regerror(error, re, source);
        }
 }
 
@@ -459,6 +464,7 @@ dopatsubst(const char *argv[], int argc)
                regex_t re;
                regmatch_t *pmatch;
                int mode = REG_EXTENDED;
+               const char *source;
                size_t l = strlen(argv[3]);
 
                if (!mimic_gnu ||
@@ -466,13 +472,14 @@ dopatsubst(const char *argv[], int argc)
                    (l > 0 && argv[3][l-1] == '$'))
                        mode |= REG_NEWLINE;
 
-               error = regcomp(&re, mimic_gnu ? twiddle(argv[3]) : argv[3],
-                   mode);
+               source = mimic_gnu ? twiddle(argv[3]) : argv[3];
+               error = regcomp(&re, source, mode);
                if (error != 0)
-                       exit_regerror(error, &re);
+                       exit_regerror(error, &re, source);
 
-               pmatch = xalloc(sizeof(regmatch_t) * (re.re_nsub+1), NULL);
-               do_subst(argv[2], &re,
+               pmatch = xreallocarray(NULL, re.re_nsub+1, sizeof(regmatch_t),
+                   NULL);
+               do_subst(argv[2], &re, source,
                    argc > 4 && argv[4] != NULL ? argv[4] : "", pmatch);
                free(pmatch);
                regfree(&re);
@@ -486,6 +493,7 @@ doregexp(const char *argv[], int argc)
        int error;
        regex_t re;
        regmatch_t *pmatch;
+       const char *source;
 
        if (argc <= 3) {
                warnx("Too few arguments to regexp");
@@ -498,16 +506,16 @@ doregexp(const char *argv[], int argc)
                else
                        pbstr(argv[4]);
        }
-       error = regcomp(&re, mimic_gnu ? twiddle(argv[3]) : argv[3],
-           REG_EXTENDED|REG_NEWLINE);
+       source = mimic_gnu ? twiddle(argv[3]) : argv[3];
+       error = regcomp(&re, source, REG_EXTENDED|REG_NEWLINE);
        if (error != 0)
-               exit_regerror(error, &re);
+               exit_regerror(error, &re, source);
 
-       pmatch = xalloc(sizeof(regmatch_t) * (re.re_nsub+1), NULL);
+       pmatch = xreallocarray(NULL, re.re_nsub+1, sizeof(regmatch_t), NULL);
        if (argc == 4 || argv[4] == NULL)
-               do_regexpindex(argv[2], &re, pmatch);
+               do_regexpindex(argv[2], &re, source, pmatch);
        else
-               do_regexp(argv[2], &re, argv[4], pmatch);
+               do_regexp(argv[2], &re, source, argv[4], pmatch);
        free(pmatch);
        regfree(&re);
 }

Added: head/usr.bin/m4/lib/ohash.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/usr.bin/m4/lib/ohash.c Sun Jul 27 22:54:13 2014        (r269162)
@@ -0,0 +1,330 @@
+/* $OpenBSD: src/lib/libutil/ohash.c,v 1.1 2014/06/02 18:52:03 deraadt Exp $ */
+
+/* Copyright (c) 1999, 2004 Marc Espie <es...@openbsd.org>
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "ohash.h"
+
+struct _ohash_record {
+       uint32_t        hv;
+       const char      *p;
+};
+
+#define DELETED                ((const char *)h)
+#define NONE           (h->size)
+
+/* Don't bother changing the hash table if the change is small enough.  */
+#define MINSIZE                (1UL << 4)
+#define MINDELETED     4
+
+static void ohash_resize(struct ohash *);
+
+
+/* This handles the common case of variable length keys, where the
+ * key is stored at the end of the record.
+ */
+void *
+ohash_create_entry(struct ohash_info *i, const char *start, const char **end)
+{
+       char *p;
+
+       if (!*end)
+               *end = start + strlen(start);
+       p = (i->alloc)(i->key_offset + (*end - start) + 1, i->data);
+       if (p) {
+               memcpy(p+i->key_offset, start, *end-start);
+               p[i->key_offset + (*end - start)] = '\0';
+       }
+       return (void *)p;
+}
+
+/* hash_delete only frees the hash structure. Use hash_first/hash_next
+ * to free entries as well.  */
+void
+ohash_delete(struct ohash *h)
+{
+       (h->info.free)(h->t, h->info.data);
+#ifndef NDEBUG
+       h->t = NULL;
+#endif
+}
+
+static void
+ohash_resize(struct ohash *h)
+{
+       struct _ohash_record *n;
+       size_t ns;
+       unsigned int    j;
+       unsigned int    i, incr;
+
+       if (4 * h->deleted < h->total) {
+               if (h->size >= (UINT_MAX >> 1U))
+                       ns = UINT_MAX;
+               else
+                       ns = h->size << 1U;
+       } else if (3 * h->deleted > 2 * h->total)
+               ns = h->size >> 1U;
+       else
+               ns = h->size;
+       if (ns < MINSIZE)
+               ns = MINSIZE;
+#ifdef STATS_HASH
+       STAT_HASH_EXPAND++;
+       STAT_HASH_SIZE += ns - h->size;
+#endif
+
+       n = (h->info.calloc)(ns, sizeof(struct _ohash_record), h->info.data);
+       if (!n)
+               return;
+
+       for (j = 0; j < h->size; j++) {
+               if (h->t[j].p != NULL && h->t[j].p != DELETED) {
+                       i = h->t[j].hv % ns;
+                       incr = ((h->t[j].hv % (ns - 2)) & ~1) + 1;
+                       while (n[i].p != NULL) {
+                               i += incr;
+                               if (i >= ns)
+                                       i -= ns;
+                       }
+                       n[i].hv = h->t[j].hv;
+                       n[i].p = h->t[j].p;
+               }
+       }
+       (h->info.free)(h->t, h->info.data);
+       h->t = n;
+       h->size = ns;
+       h->total -= h->deleted;
+       h->deleted = 0;
+}
+
+void *
+ohash_remove(struct ohash *h, unsigned int i)
+{
+       void            *result = (void *)h->t[i].p;
+
+       if (result == NULL || result == DELETED)
+               return NULL;
+
+#ifdef STATS_HASH
+       STAT_HASH_ENTRIES--;
+#endif
+       h->t[i].p = DELETED;
+       h->deleted++;
+       if (h->deleted >= MINDELETED && 4 * h->deleted > h->total)
+               ohash_resize(h);
+       return result;
+}
+
+void *
+ohash_find(struct ohash *h, unsigned int i)
+{
+       if (h->t[i].p == DELETED)
+               return NULL;
+       else
+               return (void *)h->t[i].p;
+}
+
+void *
+ohash_insert(struct ohash *h, unsigned int i, void *p)
+{
+#ifdef STATS_HASH
+       STAT_HASH_ENTRIES++;
+#endif
+       if (h->t[i].p == DELETED) {
+               h->deleted--;
+               h->t[i].p = p;
+       } else {
+               h->t[i].p = p;
+               /* Arbitrary resize boundary.  Tweak if not efficient enough.  
*/
+               if (++h->total * 4 > h->size * 3)
+                       ohash_resize(h);
+       }
+       return p;
+}
+
+unsigned int
+ohash_entries(struct ohash *h)
+{
+       return h->total - h->deleted;
+}
+
+void *
+ohash_first(struct ohash *h, unsigned int *pos)
+{
+       *pos = 0;
+       return ohash_next(h, pos);
+}
+
+void *
+ohash_next(struct ohash *h, unsigned int *pos)
+{
+       for (; *pos < h->size; (*pos)++)
+               if (h->t[*pos].p != DELETED && h->t[*pos].p != NULL)
+                       return (void *)h->t[(*pos)++].p;
+       return NULL;
+}
+
+void
+ohash_init(struct ohash *h, unsigned int size, struct ohash_info *info)
+{
+       h->size = 1UL << size;
+       if (h->size < MINSIZE)
+               h->size = MINSIZE;
+#ifdef STATS_HASH
+       STAT_HASH_CREATION++;
+       STAT_HASH_SIZE += h->size;
+#endif
+       /* Copy info so that caller may free it.  */
+       h->info.key_offset = info->key_offset;
+       h->info.calloc = info->calloc;
+       h->info.free = info->free;
+       h->info.alloc = info->alloc;
+       h->info.data = info->data;
+       h->t = (h->info.calloc)(h->size, sizeof(struct _ohash_record),
+                   h->info.data);
+       h->total = h->deleted = 0;
+}
+
+uint32_t
+ohash_interval(const char *s, const char **e)
+{
+       uint32_t k;
+
+       if (!*e)
+               *e = s + strlen(s);
+       if (s == *e)
+               k = 0;
+       else
+               k = *s++;
+       while (s != *e)
+               k =  ((k << 2) | (k >> 30)) ^ *s++;
+       return k;
+}
+
+unsigned int
+ohash_lookup_interval(struct ohash *h, const char *start, const char *end,
+    uint32_t hv)
+{
+       unsigned int    i, incr;
+       unsigned int    empty;
+
+#ifdef STATS_HASH
+       STAT_HASH_LOOKUP++;
+#endif
+       empty = NONE;
+       i = hv % h->size;
+       incr = ((hv % (h->size-2)) & ~1) + 1;
+       while (h->t[i].p != NULL) {
+#ifdef STATS_HASH
+               STAT_HASH_LENGTH++;
+#endif
+               if (h->t[i].p == DELETED) {
+                       if (empty == NONE)
+                               empty = i;
+               } else if (h->t[i].hv == hv &&
+                   strncmp(h->t[i].p+h->info.key_offset, start,
+                       end - start) == 0 &&
+                   (h->t[i].p+h->info.key_offset)[end-start] == '\0') {
+                       if (empty != NONE) {
+                               h->t[empty].hv = hv;
+                               h->t[empty].p = h->t[i].p;
+                               h->t[i].p = DELETED;
+                               return empty;
+                       } else {
+#ifdef STATS_HASH
+                               STAT_HASH_POSITIVE++;
+#endif
+                               return i;
+                       }
+               }
+               i += incr;
+               if (i >= h->size)
+                       i -= h->size;
+       }
+
+       /* Found an empty position.  */
+       if (empty != NONE)
+               i = empty;
+       h->t[i].hv = hv;
+       return i;
+}
+
+unsigned int
+ohash_lookup_memory(struct ohash *h, const char *k, size_t size, uint32_t hv)
+{
+       unsigned int    i, incr;
+       unsigned int    empty;
+
+#ifdef STATS_HASH
+       STAT_HASH_LOOKUP++;
+#endif
+       empty = NONE;
+       i = hv % h->size;
+       incr = ((hv % (h->size-2)) & ~1) + 1;
+       while (h->t[i].p != NULL) {
+#ifdef STATS_HASH
+               STAT_HASH_LENGTH++;
+#endif
+               if (h->t[i].p == DELETED) {
+                       if (empty == NONE)
+                               empty = i;
+               } else if (h->t[i].hv == hv &&
+                   memcmp(h->t[i].p+h->info.key_offset, k, size) == 0) {
+                       if (empty != NONE) {
+                               h->t[empty].hv = hv;
+                               h->t[empty].p = h->t[i].p;
+                               h->t[i].p = DELETED;
+                               return empty;
+                       } else {
+#ifdef STATS_HASH
+                               STAT_HASH_POSITIVE++;
+#endif
+                       }       return i;
+               }
+               i += incr;
+               if (i >= h->size)
+                       i -= h->size;
+       }
+
+       /* Found an empty position.  */
+       if (empty != NONE)
+               i = empty;
+       h->t[i].hv = hv;
+       return i;
+}
+
+unsigned int
+ohash_qlookup(struct ohash *h, const char *s)
+{
+       const char *e = NULL;
+       return ohash_qlookupi(h, s, &e);
+}
+
+unsigned int
+ohash_qlookupi(struct ohash *h, const char *s, const char **e)
+{
+       uint32_t hv;
+
+       hv = ohash_interval(s, e);
+       return ohash_lookup_interval(h, s, *e, hv);
+}

Modified: head/usr.bin/m4/lib/ohash.h
==============================================================================
--- head/usr.bin/m4/lib/ohash.h Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/lib/ohash.h Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,8 +1,4 @@
-#ifndef OHASH_H
-#define OHASH_H
-/* $OpenBSD: ohash.h,v 1.8 2005/12/29 18:54:47 jaredy Exp $ */
-/* ex:ts=8 sw=4: 
- */
+/* $OpenBSD: src/lib/libutil/ohash.h,v 1.2 2014/06/02 18:52:03 deraadt Exp $ */
 
 /* Copyright (c) 1999, 2004 Marc Espie <es...@openbsd.org>
  *
@@ -21,21 +17,26 @@
  * $FreeBSD$
  */
 
+#ifndef OHASH_H
+#define OHASH_H
+
 /* Open hashing support. 
  * Open hashing was chosen because it is much lighter than other hash
  * techniques, and more efficient in most cases.
  */
 
+/* user-visible data structure */
 struct ohash_info {
        ptrdiff_t key_offset;
        void *data;     /* user data */
-       void *(*halloc)(size_t, void *);
-       void (*hfree)(void *, size_t, void *);
+       void *(*calloc)(size_t, size_t, void *);
+       void (*free)(void *, void *);
        void *(*alloc)(size_t, void *);
 };
 
 struct _ohash_record;
 
+/* private structure. It's there just so you can do a sizeof */
 struct ohash {
        struct _ohash_record    *t;
        struct ohash_info       info;
@@ -55,9 +56,10 @@ void ohash_init(struct ohash *, unsigned
 void ohash_delete(struct ohash *);
 
 unsigned int ohash_lookup_interval(struct ohash *, const char *,
-           const char *, u_int32_t);
+           const char *, uint32_t);
 unsigned int ohash_lookup_memory(struct ohash *, const char *,
-           size_t, u_int32_t);
+           size_t, uint32_t)
+               __attribute__ ((__bounded__(__string__,2,3)));
 void *ohash_find(struct ohash *, unsigned int);
 void *ohash_remove(struct ohash *, unsigned int);
 void *ohash_insert(struct ohash *, unsigned int, void *);
@@ -66,10 +68,9 @@ void *ohash_next(struct ohash *, unsigne
 unsigned int ohash_entries(struct ohash *);
 
 void *ohash_create_entry(struct ohash_info *, const char *, const char **);
-u_int32_t ohash_interval(const char *, const char **);
+uint32_t ohash_interval(const char *, const char **);
 
 unsigned int ohash_qlookupi(struct ohash *, const char *, const char **);
 unsigned int ohash_qlookup(struct ohash *, const char *);
 __END_DECLS
 #endif
-

Modified: head/usr.bin/m4/lib/ohash_init.3
==============================================================================
--- head/usr.bin/m4/lib/ohash_init.3    Sun Jul 27 20:55:47 2014        
(r269161)
+++ head/usr.bin/m4/lib/ohash_init.3    Sun Jul 27 22:54:13 2014        
(r269162)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ohash_init.3,v 1.14 2007/05/31 19:19:30 jmc Exp $
+.\"    $OpenBSD: ohash_init.3,v 1.2 2014/05/13 14:01:41 jmc Exp $
 .\" Copyright (c) 1999 Marc Espie <es...@openbsd.org>
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -15,8 +15,8 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd $Mdocdate: May 31 2007 $
-.Dt OPEN_HASH 3
+.Dd May 12 2014
+.Dt OHASH_INIT 3
 .Os
 .Sh NAME
 .Nm ohash_init ,
@@ -71,11 +71,46 @@ initializes the table to store roughly 2
 .Fa size
 elements.
 .Fa info
-holds the position of the key in each record, and two pointers to
+is a pointer to a
+.Fa struct ohash_info .
+.Bd -literal -offset indent
+struct ohash_info {
+       ptrdiff_t key_offset;
+       void *data;     /* user data */
+       void *(*calloc)(size_t, size_t, void *);
+       void (*free)(void *, void *);
+       void *(*alloc)(size_t, void *);
+};
+.Ed
+.Pp
+The
+.Va offset
+field holds the position of the key in each record;
+the
+.Va calloc
+and
+.Va free
+fields are pointers to
 .Xr calloc 3
 and
 .Xr free 3 Ns -like
-functions, to use for managing the table internal storage.
+functions, used for managing the table internal storage;
+the
+.Va alloc
+field is only used by the utility function
+.Xr ohash_create_entry 3 .
+.Pp
+Each of these functions are called similarly to their standard counterpart,
+but with an extra
+.Ft void *
+parameter corresponding to the content of the field
+.Fa data ,
+which can be used to communicate specific information to the functions.
+.Pp
+.Fn ohash_init
+stores a copy of those fields internally, so
+.Fa info
+can be reclaimed after initialization.
 .Pp
 .Fn ohash_delete
 frees storage internal to
@@ -166,7 +201,7 @@ for (n = ohash_first(h, &i); n != NULL; 
 points to an auxiliary unsigned integer used to record the current position
 in the ohash table.
 Those functions are safe to use even while entries are added to/removed
-from the table, but in such a case they do not guarantee that new entries
+from the table, but in such a case they don't guarantee that new entries
 will be returned.
 As a special case, they can safely be used to free elements in the table.
 .Pp
@@ -179,7 +214,13 @@ Only
 .Fn ohash_remove
 and
 .Fn ohash_delete
-may call the user-supplied memory functions.
+may call the user-supplied memory functions:
+.Bd -literal -offset indent
+p = (*info->calloc)(n, sizeof_record, info->data);
+/* copy data from old to p */
+(*info->free)(old, info->data);
+.Ed
+.Pp
 It is the responsibility of the user memory allocation code to verify
 that those calls did not fail.
 .Pp
@@ -213,6 +254,7 @@ call.
 .Pp
 Multi-threaded applications should explicitly protect ohash table access.
 .Sh SEE ALSO
+.Xr hcreate 3 ,
 .Xr ohash_interval 3
 .Rs
 .%A Donald E. Knuth

Modified: head/usr.bin/m4/lib/ohash_interval.3
==============================================================================
--- head/usr.bin/m4/lib/ohash_interval.3        Sun Jul 27 20:55:47 2014        
(r269161)
+++ head/usr.bin/m4/lib/ohash_interval.3        Sun Jul 27 22:54:13 2014        
(r269162)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ohash_interval.3,v 1.11 2007/05/31 19:19:30 jmc Exp $
+.\"    $OpenBSD: ohash_interval.3,v 1.1 2014/05/12 19:09:00 espie Exp $
 .\" Copyright (c) 2001 Marc Espie <es...@openbsd.org>
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -15,8 +15,8 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd $Mdocdate: May 31 2007 $
-.Dt OPEN_HASH_HELPER 3
+.Dd June 5 2013
+.Dt OHASH_INTERVAL 3
 .Os
 .Sh NAME
 .Nm ohash_interval ,
@@ -68,7 +68,10 @@ the alloc field of
 .Fa info
 should point to a
 .Xr malloc 3 Ns -like
-function to allocate the storage.
+function to allocate the storage:
+.Bd -literal -offset indent
+p = (*info->alloc)(sz, info->data);
+.Ed
 .Pp
 .Fn ohash_qlookupi
 is a wrapper function that simply calls

Modified: head/usr.bin/m4/look.c
==============================================================================
--- head/usr.bin/m4/look.c      Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/look.c      Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: look.c,v 1.22 2010/09/07 19:58:09 marco Exp $ */
+/*     $OpenBSD: look.c,v 1.23 2014/05/12 19:11:19 espie Exp $ */
 
 /*
  * Copyright (c) 1989, 1993
@@ -51,36 +51,34 @@ __FBSDID("$FreeBSD$");
 #include "stdd.h"
 #include "extern.h"
 
-static void *hash_alloc(size_t, void *);
-static void hash_free(void *, size_t, void *);
+static void *hash_calloc(size_t, size_t, void *);
+static void hash_free(void *, void *);
 static void *element_alloc(size_t, void *);
 static void setup_definition(struct macro_definition *, const char *,
     const char *);
 
 static struct ohash_info macro_info = {
        offsetof(struct ndblock, name),
-       NULL, hash_alloc, hash_free, element_alloc };
+       NULL, hash_calloc, hash_free, element_alloc };
 
 struct ohash macros;
 
 /* Support routines for hash tables.  */
 void *
-hash_alloc(size_t s, __unused void *u)
+hash_calloc(size_t n, size_t s, void *u __unused)
 {
-       void *storage = xalloc(s, "hash alloc");
-       if (storage)
-               memset(storage, 0, s);
+       void *storage = xcalloc(n, s, "hash alloc");
        return storage;
 }
 
 void
-hash_free(void *p, __unused size_t s, __unused void *u)
+hash_free(void *p, void *u __unused)
 {
        free(p);
 }
 
 void *
-element_alloc(size_t s, __unused void *u)
+element_alloc(size_t s, void *u __unused)
 {
        return xalloc(s, "element alloc");
 }

Modified: head/usr.bin/m4/m4.1
==============================================================================
--- head/usr.bin/m4/m4.1        Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/m4.1        Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,5 +1,5 @@
 .\"    $NetBSD: m4.1,v 1.23 2012/04/08 22:00:39 wiz Exp $
-.\"    @(#) $OpenBSD: m4.1,v 1.59 2010/10/21 13:20:51 jmc Exp $
+.\"    @(#) $OpenBSD: m4.1,v 1.62 2014/04/14 07:00:47 jmc Exp $
 .\"
 .\" Copyright (c) 1989, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -33,7 +33,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 21, 2010
+.Dd January 12 2014 $
 .Dt M4 1
 .Os
 .Sh NAME
@@ -88,9 +88,7 @@ In arguments to macros, leading unquoted
 .Pq Sq \en
 characters are ignored.
 To quote strings, use left and right single quotes
-.Po e.g.,\ \&
-.Sq "\ this is a string with a leading space"
-.Pc .
+.Pq e.g., Sq \ \&this is a string with a leading space .
 You can change the quote characters with the
 .Ic changequote
 built-in macro.
@@ -258,15 +256,17 @@ Prints the first argument on the standar
 Passes its first argument to a shell and returns the shell's standard output.
 Note that the shell shares its standard input and standard error with
 .Nm .
-.It Fn eval expr
+.It Fn eval expr[,radix[,minimum]]
 Computes the first argument as an arithmetic expression using 32-bit
 arithmetic.
 Operators are the standard C ternary, arithmetic, logical,
 shift, relational, bitwise, and parentheses operators.
 You can specify
 octal, decimal, and hexadecimal numbers as in C.
-The second argument (if any)
-specifies the radix for the result and the third argument (if any)
+The optional second argument
+.Fa radix
+specifies the radix for the result and the optional third argument
+.Fa minimum
 specifies the minimum number of digits in the result.
 .It Fn expr expr
 This is an alias for
@@ -441,12 +441,12 @@ macro can modify the exit status.
 .Sh STANDARDS
 The
 .Nm
-utility is mostly compliant with the
+utility is compliant with the
 .St -p1003.1-2008
 specification.
 .Pp
 The flags
-.Op Fl dgIot
+.Op Fl dgIPot
 and the macros
 .Ic builtin ,
 .Ic esyscmd ,
@@ -467,9 +467,13 @@ are extensions to that specification.
 is not supposed to be a synonym for
 .Ic mkstemp ,
 but instead to be an insecure temporary file name creation function.
-The change causes no known compatibility issues.
+It is marked by
+.St -p1003.1-2008
+as being obsolescent and should not be used if portability is a concern.
 .Pp
-The output format of tracing and of
+The output format of
+.Ic traceon
+and
 .Ic dumpdef
 are not specified in any standard,
 are likely to change and should not be relied upon.

Modified: head/usr.bin/m4/main.c
==============================================================================
--- head/usr.bin/m4/main.c      Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/main.c      Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.81 2012/04/12 17:00:11 espie Exp $ */
+/*     $OpenBSD: main.c,v 1.83 2014/05/12 19:11:19 espie Exp $ */
 /*     $NetBSD: main.c,v 1.12 1997/02/08 23:54:49 cgd Exp $    */
 
 /*-
@@ -180,8 +180,8 @@ main(int argc, char *argv[])
        initspaces();
        STACKMAX = INITSTACKMAX;
 
-       mstack = (stae *)xalloc(sizeof(stae) * STACKMAX, NULL);
-       sstack = (char *)xalloc(STACKMAX, NULL);
+       mstack = xreallocarray(NULL, STACKMAX, sizeof(stae), NULL);
+       sstack = xalloc(STACKMAX, NULL);
 
        maxout = 0;
        outfile = NULL;
@@ -415,7 +415,8 @@ macro(void)
                                }
                        }
                } else if (t == EOF) {
-                       if (sp > -1 && ilevel <= 0) {
+                       if (!mimic_gnu /* you can puke right there */
+                           && sp > -1 && ilevel <= 0) {
                                warnx( "unexpected end of input, unclosed 
parenthesis:");
                                dump_stack(paren, PARLEV);
                                exit(1);
@@ -625,7 +626,7 @@ static void
 enlarge_stack(void)
 {
        STACKMAX += STACKMAX/2;
-       mstack = xrealloc(mstack, sizeof(stae) * STACKMAX,
+       mstack = xreallocarray(mstack, STACKMAX, sizeof(stae),
            "Evaluation stack overflow (%lu)",
            (unsigned long)STACKMAX);
        sstack = xrealloc(sstack, STACKMAX,

Modified: head/usr.bin/m4/misc.c
==============================================================================
--- head/usr.bin/m4/misc.c      Sun Jul 27 20:55:47 2014        (r269161)
+++ head/usr.bin/m4/misc.c      Sun Jul 27 22:54:13 2014        (r269162)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: misc.c,v 1.42 2010/09/07 19:58:09 marco Exp $ */
+/*     $OpenBSD: misc.c,v 1.44 2014/05/12 19:11:19 espie Exp $ */
 /*     $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $     */
 
 /*
@@ -32,6 +32,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
@@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <unistd.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
@@ -165,7 +167,7 @@ initspaces(void)
        strspace = xalloc(strsize+1, NULL);
        ep = strspace;
        endest = strspace+strsize;
-       buf = (unsigned char *)xalloc(bufsize, NULL);
+       buf = xalloc(bufsize, NULL);
        bufbase = buf;
        bp = buf;
        endpbb = buf + bufsize;
@@ -239,7 +241,7 @@ getdiv(int n)
 }
 
 void
-onintr(__unused int signo)
+onintr(int signo __unused)
 {
 #define intrmessage    "m4: interrupted.\n"
        write(STDERR_FILENO, intrmessage, sizeof(intrmessage)-1);
@@ -263,7 +265,7 @@ killdiv(void)
 extern char *__progname;
 
 void

*** 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-unsubscr...@freebsd.org"

Reply via email to