svn commit: r269162 - in head/usr.bin/m4: . lib

Baptiste Daroussin bapt at FreeBSD.org
Sun Jul 27 22:54:16 UTC 2014


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 <espie at 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 <espie at 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 <espie at 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 <espie at 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 ***


More information about the svn-src-all mailing list