Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make Add the :hash modifier to compute a 32bit hash ...



details:   https://anonhg.NetBSD.org/src/rev/e930f0350432
branches:  trunk
changeset: 763916:e930f0350432
user:      joerg <joerg%NetBSD.org@localhost>
date:      Thu Apr 07 01:40:01 2011 +0000

description:
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.

diffstat:

 usr.bin/make/make.1              |   6 +-
 usr.bin/make/unit-tests/Makefile |   3 +-
 usr.bin/make/unit-tests/hash     |  18 +++++++
 usr.bin/make/unit-tests/test.exp |   8 +++
 usr.bin/make/var.c               |  92 ++++++++++++++++++++++++++++++++++++++-
 5 files changed, 121 insertions(+), 6 deletions(-)

diffs (224 lines):

diff -r 3c88e899bb45 -r e930f0350432 usr.bin/make/make.1
--- a/usr.bin/make/make.1       Thu Apr 07 01:20:31 2011 +0000
+++ b/usr.bin/make/make.1       Thu Apr 07 01:40:01 2011 +0000
@@ -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 ,
diff -r 3c88e899bb45 -r e930f0350432 usr.bin/make/unit-tests/Makefile
--- a/usr.bin/make/unit-tests/Makefile  Thu Apr 07 01:20:31 2011 +0000
+++ b/usr.bin/make/unit-tests/Makefile  Thu Apr 07 01:40:01 2011 +0000
@@ -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 \
diff -r 3c88e899bb45 -r e930f0350432 usr.bin/make/unit-tests/hash
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/hash      Thu Apr 07 01:40:01 2011 +0000
@@ -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}
diff -r 3c88e899bb45 -r e930f0350432 usr.bin/make/unit-tests/test.exp
--- a/usr.bin/make/unit-tests/test.exp  Thu Apr 07 01:20:31 2011 +0000
+++ b/usr.bin/make/unit-tests/test.exp  Thu Apr 07 01:40:01 2011 +0000
@@ -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=
diff -r 3c88e899bb45 -r e930f0350432 usr.bin/make/var.c
--- a/usr.bin/make/var.c        Thu Apr 07 01:20:31 2011 +0000
+++ b/usr.bin/make/var.c        Thu Apr 07 01:40:01 2011 +0000
@@ -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 */



Home | Main Index | Thread Index | Old Index