Module Name:    src
Committed By:   joerg
Date:           Thu Apr  7 01:40:02 UTC 2011

Modified Files:
        src/usr.bin/make: make.1 var.c
        src/usr.bin/make/unit-tests: Makefile test.exp
Added Files:
        src/usr.bin/make/unit-tests: hash

Log Message:
Add the :hash modifier to compute a 32bit hash of an variable.
This uses MurmurHash3 to get a reasonable collission-free hash with
small code. The result is endian neutral.


To generate a diff of this commit:
cvs rdiff -u -r1.185 -r1.186 src/usr.bin/make/make.1
cvs rdiff -u -r1.162 -r1.163 src/usr.bin/make/var.c
cvs rdiff -u -r1.31 -r1.32 src/usr.bin/make/unit-tests/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.bin/make/unit-tests/hash
cvs rdiff -u -r1.35 -r1.36 src/usr.bin/make/unit-tests/test.exp

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/make.1
diff -u src/usr.bin/make/make.1:1.185 src/usr.bin/make/make.1:1.186
--- src/usr.bin/make/make.1:1.185	Sun Mar 27 19:47:46 2011
+++ src/usr.bin/make/make.1	Thu Apr  7 01:40:01 2011
@@ -1,4 +1,4 @@
-.\"	$NetBSD: make.1,v 1.185 2011/03/27 19:47:46 sjg Exp $
+.\"	$NetBSD: make.1,v 1.186 2011/04/07 01:40:01 joerg Exp $
 .\"
 .\" Copyright (c) 1990, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"	from: @(#)make.1	8.4 (Berkeley) 3/19/94
 .\"
-.Dd March 27, 2011
+.Dd April 2, 2011
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -1042,6 +1042,8 @@
 .Nm .
 .It Cm \&:R
 Replaces each word in the variable with everything but its suffix.
+.It Cm \&:hash
+Compute a 32bit hash of the value and encode it as hex digits.
 .It Cm \&:tA
 Attempt to convert variable to an absolute path using
 .Xr realpath 3 ,

Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.162 src/usr.bin/make/var.c:1.163
--- src/usr.bin/make/var.c:1.162	Sun Mar  6 00:02:15 2011
+++ src/usr.bin/make/var.c	Thu Apr  7 01:40:01 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.162 2011/03/06 00:02:15 sjg Exp $	*/
+/*	$NetBSD: var.c,v 1.163 2011/04/07 01:40:01 joerg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.162 2011/03/06 00:02:15 sjg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.163 2011/04/07 01:40:01 joerg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)var.c	8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: var.c,v 1.162 2011/03/06 00:02:15 sjg Exp $");
+__RCSID("$NetBSD: var.c,v 1.163 2011/04/07 01:40:01 joerg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -129,6 +129,7 @@
 #include    <regex.h>
 #endif
 #include    <ctype.h>
+#include    <inttypes.h>
 #include    <stdlib.h>
 #include    <limits.h>
 
@@ -302,6 +303,7 @@
 			   VarPattern *);
 static char *VarQuote(char *);
 static char *VarChangeCase(char *, int);
+static char *VarHash(char *);
 static char *VarModify(GNode *, Var_Parse_State *,
     const char *,
     Boolean (*)(GNode *, Var_Parse_State *, char *, Boolean, Buffer *, void *),
@@ -2262,6 +2264,79 @@
 
 /*-
  *-----------------------------------------------------------------------
+ * VarHash --
+ *      Hash the string using the MurmurHash3 algorithm.
+ *      Output is computed using 32bit Little Endian arithmetic.
+ *
+ * Input:
+ *	str		String to modify
+ *
+ * Results:
+ *      Hash value of str, encoded as 8 hex digits.
+ *
+ * Side Effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarHash(char *str)
+{
+    static const char    hexdigits[16] = "0123456789abcdef";
+    Buffer         buf;
+    size_t         len, len2;
+    unsigned char  *ustr = (unsigned char *)str;
+    uint32_t       h, k, c1, c2;
+    int            done;
+
+    done = 1;
+    h  = 0x971e137bU;
+    c1 = 0x95543787U;
+    c2 = 0x2ad7eb25U;
+    len2 = strlen(str);
+
+    for (len = len2; len; ) {
+	k = 0;
+	switch (len) {
+	default:
+	    k = (ustr[3] << 24) | (ustr[2] << 16) | (ustr[1] << 8) | ustr[0];
+	    len -= 4;
+	    ustr += 4;
+	    break;
+	case 3:
+	    k |= (ustr[2] << 16);
+	case 2:
+	    k |= (ustr[1] << 8);
+	case 1:
+	    k |= ustr[0];
+	    len = 0;
+	}
+	c1 = c1 * 5 + 0x7b7d159cU;
+	c2 = c2 * 5 + 0x6bce6396U;
+	k *= c1;
+	k = (k << 11) ^ (k >> 21);
+	k *= c2;
+	h = (h << 13) ^ (h >> 19);
+	h = h * 5 + 0x52dce729U;
+	h ^= k;
+   } while (!done);
+   h ^= len2;
+   h *= 0x85ebca6b;
+   h ^= h >> 13;
+   h *= 0xc2b2ae35;
+   h ^= h >> 16;
+
+   Buf_Init(&buf, 0);
+   for (len = 0; len < 8; ++len) {
+       Buf_AddByte(&buf, hexdigits[h & 15]);
+       h >>= 4;
+   }
+
+   return Buf_Destroy(&buf, FALSE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
  * VarChangeCase --
  *      Change the string to all uppercase or all lowercase
  *
@@ -2821,6 +2896,17 @@
 		}
 
 	    }
+	case 'h':
+	    cp = tstr + 1;	/* make sure it is set */
+	    if (strncmp(tstr, "hash", 4) == 0 &&
+		(tstr[4] == endc || tstr[4] == ':')) {
+		newStr = VarHash(nstr);
+		cp = tstr + 4;
+		termc = *cp;
+	    } else {
+		goto bad_modifier;
+	    }
+	    break;
 	case 't':
 	    {
 		cp = tstr + 1;	/* make sure it is set */

Index: src/usr.bin/make/unit-tests/Makefile
diff -u src/usr.bin/make/unit-tests/Makefile:1.31 src/usr.bin/make/unit-tests/Makefile:1.32
--- src/usr.bin/make/unit-tests/Makefile:1.31	Sun Mar  6 00:02:14 2011
+++ src/usr.bin/make/unit-tests/Makefile	Thu Apr  7 01:40:02 2011
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.31 2011/03/06 00:02:14 sjg Exp $
+# $NetBSD: Makefile,v 1.32 2011/04/07 01:40:02 joerg Exp $
 #
 # Unit tests for make(1)
 # The main targets are:
@@ -27,6 +27,7 @@
 	doterror \
 	dotwait \
 	forsubst \
+	hash \
 	misc \
 	moderrs \
 	modmatch \

Index: src/usr.bin/make/unit-tests/test.exp
diff -u src/usr.bin/make/unit-tests/test.exp:1.35 src/usr.bin/make/unit-tests/test.exp:1.36
--- src/usr.bin/make/unit-tests/test.exp:1.35	Sun Mar  6 00:02:14 2011
+++ src/usr.bin/make/unit-tests/test.exp	Thu Apr  7 01:40:02 2011
@@ -81,6 +81,14 @@
 cycle.1.99
 cycle.1.99
 .for with :S;... OK
+b2af338b
+3360ac65
+7747f046
+9ca87054
+880fe816
+208fcbd3
+d5d376eb
+de41416c
 Expect: Unknown modifier 'Z'
 make: Unknown modifier 'Z'
 VAR:Z=

Added files:

Index: src/usr.bin/make/unit-tests/hash
diff -u /dev/null src/usr.bin/make/unit-tests/hash:1.1
--- /dev/null	Thu Apr  7 01:40:02 2011
+++ src/usr.bin/make/unit-tests/hash	Thu Apr  7 01:40:02 2011
@@ -0,0 +1,18 @@
+STR1=
+STR2=	a
+STR3=	ab
+STR4=	abc
+STR5=	abcd
+STR6=	abcde
+STR7=	abcdef
+STR8=	abcdefghijklmnopqrstuvwxyz
+
+all:
+	@echo ${STR1:hash}
+	@echo ${STR2:hash}
+	@echo ${STR3:hash}
+	@echo ${STR4:hash}
+	@echo ${STR5:hash}
+	@echo ${STR6:hash}
+	@echo ${STR7:hash}
+	@echo ${STR8:hash}

Reply via email to