diff options
author | Drashna Jael're <drashna@live.com> | 2022-11-08 17:14:27 -0800 |
---|---|---|
committer | Drashna Jael're <drashna@live.com> | 2022-11-08 17:14:27 -0800 |
commit | 64f04b30c2f48fc0e7c49ca043443f03dc56df94 (patch) | |
tree | e0f374d3b92bacefd22c31e7bda8ee1c6fcb37de /lib | |
parent | d9f575fa86ca10b990958d4e677c6a0a387dc7c3 (diff) | |
parent | 96c48a5f4aa461ed31fd4ee61151ac206e16fb5f (diff) |
Merge tag '0.18.16' into firmware22
Diffstat (limited to 'lib')
47 files changed, 6079 insertions, 343 deletions
diff --git a/lib/chibios b/lib/chibios -Subproject 257302333c31f1f710800c2b97acf3550de043e +Subproject f836d24b06d7265696a33d1cea010bd6a931791 diff --git a/lib/chibios-contrib b/lib/chibios-contrib -Subproject 2a6b73ff51baf89083a220b6692a04ca2cae875 +Subproject d03aa9cc2f76468e431c71421015102956dd6ad diff --git a/lib/fnv/Makefile b/lib/fnv/Makefile new file mode 100644 index 0000000000..c0673ded40 --- /dev/null +++ b/lib/fnv/Makefile @@ -0,0 +1,304 @@ +#!/bin/make +# +# hash - makefile for FNV hash tools +# +# @(#) $Revision: 5.2 $ +# @(#) $Id: Makefile,v 5.2 2012/03/21 01:42:15 chongo Exp $ +# @(#) $Source: /usr/local/src/cmd/fnv/RCS/Makefile,v $ +# +# See: +# http://www.isthe.com/chongo/tech/comp/fnv/index.html +# +# for the most up to date copy of this code and the FNV hash home page. +# +# Please do not copyright this code. This code is in the public domain. +# +# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. +# +# By: +# chongo <Landon Curt Noll> /\oo/\ +# http://www.isthe.com/chongo/ +# +# Share and Enjoy! :-) + +# make tools +# +SHELL= /bin/sh +CFLAGS= -O3 -g3 +#CFLAGS= -O2 -g3 +#CC= cc +AR= ar +TAR= tar +EGREP= egrep +GZIP_BIN= gzip +INSTALL= install + +# If your system needs ranlib use: +# RANLIB= ranlib +# otherwise use: +# RANLIB= : +# +#RANLIB= ranlib +RANLIB= : + +# where to install things +# +DESTBIN= /usr/local/bin +DESTLIB= /usr/local/lib +DESTINC= /usr/local/include + +# what to build +# +SRC= hash_32.c hash_32a.c hash_64.c hash_64a.c \ + fnv32.c fnv64.c \ + have_ulong64.c test_fnv.c +NO64BIT_SRC= no64bit_fnv64.c no64bit_hash_64.c \ + no64bit_hash_64a.c no64bit_test_fnv.c +HSRC= fnv.h \ + longlong.h +ALL= ${SRC} ${HSRC} \ + README Makefile +PROGS= fnv032 fnv064 fnv132 fnv164 fnv1a32 fnv1a64 +OBSOLETE_PROGS= fnv0_32 fnv0_64 fnv1_32 fnv1_64 fnv1a_32 fnv1a_64 +NO64BIT_PROGS= no64bit_fnv064 no64bit_fnv164 no64bit_fnv1a64 +LIBS= libfnv.a +LIBOBJ= hash_32.o hash_64.o hash_32a.o hash_64a.o test_fnv.o +NO64BIT_OBJ= no64bit_fnv64.o no64bit_hash_64.o \ + no64bit_hash_64a.o no64bit_test_fnv.o +OTHEROBJ= fnv32.o fnv64.o +TARGETS= ${LIBOBJ} ${LIBS} ${PROGS} + +# default rule +# +all: ${TARGETS} + +# things to build +# +hash_32.o: hash_32.c longlong.h fnv.h + ${CC} ${CFLAGS} hash_32.c -c + +hash_64.o: hash_64.c longlong.h fnv.h + ${CC} ${CFLAGS} hash_64.c -c + +hash_32a.o: hash_32a.c longlong.h fnv.h + ${CC} ${CFLAGS} hash_32a.c -c + +hash_64a.o: hash_64a.c longlong.h fnv.h + ${CC} ${CFLAGS} hash_64a.c -c + +test_fnv.o: test_fnv.c longlong.h fnv.h + ${CC} ${CFLAGS} test_fnv.c -c + +fnv32.o: fnv32.c longlong.h fnv.h + ${CC} ${CFLAGS} fnv32.c -c + +fnv032: fnv32.o libfnv.a + ${CC} fnv32.o libfnv.a -o fnv032 + +fnv64.o: fnv64.c longlong.h fnv.h + ${CC} ${CFLAGS} fnv64.c -c + +fnv064: fnv64.o libfnv.a + ${CC} fnv64.o libfnv.a -o fnv064 + +libfnv.a: ${LIBOBJ} + rm -f $@ + ${AR} rv $@ ${LIBOBJ} + ${RANLIB} $@ + +fnv132: fnv032 + -rm -f $@ + -cp -f $? $@ + +fnv1a32: fnv032 + -rm -f $@ + -cp -f $? $@ + +fnv164: fnv064 + -rm -f $@ + -cp -f $? $@ + +fnv1a64: fnv064 + -rm -f $@ + -cp -f $? $@ + +longlong.h: have_ulong64.c Makefile + -@rm -f have_ulong64 have_ulong64.o ll_tmp longlong.h + @echo 'forming longlong.h' + @echo '/*' > longlong.h + @echo ' * DO NOT EDIT -- generated by the Makefile' >> longlong.h + @echo ' */' >> longlong.h + @echo '' >> longlong.h + @echo '#if !defined(__LONGLONG_H__)' >> longlong.h + @echo '#define __LONGLONG_H__' >> longlong.h + @echo '' >> longlong.h + @echo '/* do we have/want to use a long long type? */' >> longlong.h + -@rm -f have_ulong64.o have_ulong64 + -@${CC} ${CFLAGS} have_ulong64.c -c 2>/dev/null; true + -@${CC} ${CFLAGS} have_ulong64.o -o have_ulong64 2>/dev/null; true + -@${SHELL} -c "./have_ulong64 > ll_tmp 2>/dev/null" \ + >/dev/null 2>&1; true + -@if [ -s ll_tmp ]; then \ + cat ll_tmp >> longlong.h; \ + else \ + echo '#undef HAVE_64BIT_LONG_LONG /* no */' >> longlong.h; \ + fi + @echo '' >> longlong.h + @echo '/*' >> longlong.h + @echo ' * NO64BIT_LONG_LONG undef HAVE_64BIT_LONG_LONG' >> longlong.h + @echo ' */' >> longlong.h + @echo '#if defined(NO64BIT_LONG_LONG)' >> longlong.h + @echo '#undef HAVE_64BIT_LONG_LONG' >> longlong.h + @echo '#endif /* NO64BIT_LONG_LONG */' >> longlong.h + @echo '' >> longlong.h + @echo '#endif /* !__LONGLONG_H__ */' >> longlong.h + -@rm -f have_ulong64 have_ulong64.o ll_tmp + @echo 'longlong.h formed' + +# utilities +# +install: all + -@if [ -d "${DESTBIN}" ]; then \ + echo " mkdir -p ${DESTBIN}"; \ + mkdir -p ${DESTBIN}; \ + fi + -@if [ -d "${DESTLIB}" ]; then \ + echo " mkdir -p ${DESTLIB}"; \ + mkdir -p ${DESTLIB}; \ + fi + -@if [ -d "${DESTINC}" ]; then \ + echo " mkdir -p ${DESTINC}"; \ + mkdir -p ${DESTINC}; \ + fi + ${INSTALL} -m 0755 ${PROGS} ${DESTBIN} + ${INSTALL} -m 0644 ${LIBS} ${DESTLIB} + ${RANLIB} ${DESTLIB}/libfnv.a + ${INSTALL} -m 0644 ${HSRC} ${DESTINC} + @# remove osolete programs + for i in ${OBSOLETE_PROGS}; do \ + if [ -f "${DESTBIN}/$$i" ]; then \ + echo "rm -f ${DESTBIN}/$$i"; \ + rm -f "${DESTBIN}/$$i"; \ + fi; \ + done + +clean: + -rm -f have_ulong64 have_ulong64.o ll_tmp ll_tmp2 longlong.h + -rm -f ${LIBOBJ} + -rm -f ${OTHEROBJ} + +clobber: clean + -rm -f ${TARGETS} + -rm -f ${OBSOLETE_PROGS} lltmp lltmp2 ll_tmp + -rm -f ${NO64BIT_SRC} + -rm -f ${NO64BIT_OBJ} + -rm -f ${NO64BIT_PROGS} + -rm -f vector.c + +check: ${PROGS} + @echo -n "FNV-0 32 bit tests: " + @./fnv032 -t 1 -v + @echo -n "FNV-1 32 bit tests: " + @./fnv132 -t 1 -v + @echo -n "FNV-1a 32 bit tests: " + @./fnv1a32 -t 1 -v + @echo -n "FNV-0 64 bit tests: " + @./fnv064 -t 1 -v + @echo -n "FNV-1 64 bit tests: " + @./fnv164 -t 1 -v + @echo -n "FNV-1a 64 bit tests: " + @./fnv1a64 -t 1 -v + +############################### +# generate test vector source # +############################### + +no64bit_fnv64.c: fnv64.c + -rm -f $@ + -cp -f $? $@ + +no64bit_hash_64.c: hash_64.c + -rm -f $@ + -cp -f $? $@ + +no64bit_hash_64a.c: hash_64a.c + -rm -f $@ + -cp -f $? $@ + +no64bit_test_fnv.c: test_fnv.c + -rm -f $@ + -cp -f $? $@ + +no64bit_fnv64.o: no64bit_fnv64.c longlong.h fnv.h + ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_fnv64.c -c + +no64bit_hash_64.o: no64bit_hash_64.c longlong.h fnv.h + ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_hash_64.c -c + +no64bit_hash_64a.o: no64bit_hash_64a.c longlong.h fnv.h + ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_hash_64a.c -c + +no64bit_test_fnv.o: no64bit_test_fnv.c longlong.h fnv.h + ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_test_fnv.c -c + +no64bit_fnv064: no64bit_fnv64.o no64bit_hash_64.o \ + no64bit_hash_64a.o no64bit_test_fnv.o + ${CC} ${CFLAGS} no64bit_fnv64.o no64bit_hash_64.o \ + no64bit_hash_64a.o no64bit_test_fnv.o -o $@ + +no64bit_fnv164: no64bit_fnv064 + -rm -f $@ + -cp -f $? $@ + +no64bit_fnv1a64: no64bit_fnv064 + -rm -f $@ + -cp -f $? $@ + +vector.c: ${PROGS} ${NO64BIT_PROGS} + -rm -f $@ + echo '/* start of output generated by make $@ */' >> $@ + echo '' >> $@ + #@ + echo '/* FNV-0 32 bit test vectors */' >> $@ + ./fnv032 -t 0 >> $@ + echo '' >> $@ + #@ + echo '/* FNV-1 32 bit test vectors */' >> $@ + ./fnv132 -t 0 >> $@ + echo '' >> $@ + #@ + echo '/* FNV-1a 32 bit test vectors */' >> $@ + ./fnv1a32 -t 0 >> $@ + echo '' >> $@ + #@ + echo '/* FNV-0 64 bit test vectors */' >> $@ + echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@ + ./fnv064 -t 0 >> $@ + echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@ + ./no64bit_fnv064 -t 0 >> $@ + echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@ + echo '' >> $@ + #@ + echo '/* FNV-1 64 bit test vectors */' >> $@ + echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@ + ./fnv164 -t 0 >> $@ + echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@ + ./no64bit_fnv164 -t 0 >> $@ + echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@ + echo '' >> $@ + #@ + echo '/* FNV-1a 64 bit test vectors */' >> $@ + echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@ + ./fnv1a64 -t 0 >> $@ + echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@ + ./no64bit_fnv1a64 -t 0 >> $@ + echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@ + echo '' >> $@ + #@ + echo '/* end of output generated by make $@ */' >> $@ diff --git a/lib/fnv/README b/lib/fnv/README new file mode 100644 index 0000000000..60aa9aaf61 --- /dev/null +++ b/lib/fnv/README @@ -0,0 +1,158 @@ +#=====================# +# Fowler/Noll/Vo hash # +#=====================# + +The basis of this hash algorithm was taken from an idea sent +as reviewer comments to the IEEE POSIX P1003.2 committee by: + + Phong Vo (http://www.research.att.com/info/kpv) + Glenn Fowler (http://www.research.att.com/~gsf/) + +In a subsequent ballot round: + + Landon Curt Noll (http://www.isthe.com/chongo) + +improved on their algorithm. Some people tried this hash +and found that it worked rather well. In an EMail message +to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + +FNV hashes are designed to be fast while maintaining a low +collision rate. The FNV speed allows one to quickly hash lots +of data while maintaining a reasonable collision rate. See: + + http://www.isthe.com/chongo/tech/comp/fnv/index.html + +for more details as well as other forms of the FNV hash. +Comments, questions, bug fixes and suggestions welcome at +the address given in the above URL. + + +#==================# +# FNV hash utility # +#==================# + +Two hash utilities (32 bit and 64 bit) are provided: + + fnv032 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] + fnv132 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] + fnv1a32 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] + + fnv064 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] + fnv164 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] + fnv1a64 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...] + + -b bcnt mask off all but the lower bcnt bits (default: 32) + -m multiple hashes, one per line for each arg + -s hash arg as a string (ignoring terminating NUL bytes) + -t code 0 ==> generate test vectors, 1 ==> test FNV hash + -v verbose mode, print arg after hash (implies -m) + arg string (if -s was given) or filename (default stdin) + +The fnv032, fnv064 implement the historic FNV-0 hash. +The fnv132, fnv164 implement the recommended FNV-1 hash. +The fnv1a32, fnv1a64 implement the recommended FNV-1a hash. + +This is the original historic FNV algorithm with a 0 offset basis. +It is recommended that FNV-1, with a non-0 offset basis be used instead. + +To test FNV hashes, try: + + fnv032 -t 1 -v + fnv132 -t 1 -v + fnv1a32 -t 1 -v + + fnv064 -t 1 -v + fnv164 -t 1 -v + fnv1a64 -t 1 -v + +If you are compiling, try: + + make check + + +#==================# +# FNV hash library # +#==================# + +The libfnv.a library implements both a 32 bit and a 64 bit FNV hash +on collections of bytes, a NUL terminated strings or on an open file +descriptor. + +Here is the 32 bit FNV 1 hash: + + Fnv32_t fnv_32_buf(void *buf, int len, Fnv32_t hval); /* byte buf */ + Fnv32_t fnv_32_str(char *string, Fnv32_t hval); /* string */ + +Here is the 32 bit FNV 1a hash: + + Fnv32_t fnv_32a_buf(void *buf, int len, Fnv32_t hval); /* byte buf */ + Fnv32_t fnv_32a_str(char *string, Fnv32_t hval); /* string */ + +Here is the 64 bit FNV 1 hash: + + Fnv64_t fnv_64_buf(void *buf, int len, Fnv64_t hval); /* byte buf */ + Fnv64_t fnv_64_str(char *string, Fnv64_t hval); /* string */ + +Here is the 64 bit FNV 1a hash: + + Fnv64_t fnv_64a_buf(void *buf, int len, Fnv64_t hval); /* byte buf */ + Fnv64_t fnv_64a_str(char *string, Fnv64_t hval); /* string */ + +On the first call to a hash function, one must supply the initial basis +that is appropriate for the hash in question: + + FNV-0: (not recommended) + + FNV0_32_INIT /* 32 bit FNV-0 initial basis */ + FNV0_64_INIT /* 64 bit FNV-0 initial basis */ + + FNV-1: + + FNV1_32_INIT /* 32 bit FNV-1 initial basis */ + FNV1_64_INIT /* 64 bit FNV-1 initial basis */ + + FNV-1a: + + FNV1A_32_INIT /* 32 bit FNV-1a initial basis */ + FNV1A_64_INIT /* 64 bit FNV-1a initial basis */ + +For example to perform a 64 bit FNV-1 hash: + + #include "fnv.h" + + Fnv64_t hash_val; + + hash_val = fnv_64_str("a string", FNV1_64_INIT); + hash_val = fnv_64_str("more string", hash_val); + +produces the same final hash value as: + + hash_val = fnv_64_str("a stringmore string", FNV1_64_INIT); + +NOTE: If one used 'FNV0_64_INIT' instead of 'FNV1_64_INIT' one would get the + historic FNV-0 hash instead recommended FNV-1 hash. + +To perform a 32 bit FNV-1 hash: + + #include "fnv.h" + + Fnv32_t hash_val; + + hash_val = fnv_32_buf(buf, length_of_buf, FNV1_32_INIT); + hash_val = fnv_32_str("more data", hash_val); + +To perform a 64 bit FNV-1a hash: + + #include "fnv.h" + + Fnv64_t hash_val; + + hash_val = fnv_64a_buf(buf, length_of_buf, FNV1_64_INIT); + hash_val = fnv_64a_str("more data", hash_val); + +=-= + +chongo <Landon Curt Noll> /\oo/\ +http://www.isthe.com/chongo + +Share and Enjoy! diff --git a/lib/fnv/fnv.h b/lib/fnv/fnv.h new file mode 100644 index 0000000000..5249366731 --- /dev/null +++ b/lib/fnv/fnv.h @@ -0,0 +1,250 @@ +/* + * fnv - Fowler/Noll/Vo- hash code + * + * @(#) $Revision: 5.4 $ + * @(#) $Id: fnv.h,v 5.4 2009/07/30 22:49:13 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv.h,v $ + * + *** + * + * Fowler/Noll/Vo- hash + * + * The basis of this hash algorithm was taken from an idea sent + * as reviewer comments to the IEEE POSIX P1003.2 committee by: + * + * Phong Vo (http://www.research.att.com/info/kpv/) + * Glenn Fowler (http://www.research.att.com/~gsf/) + * + * In a subsequent ballot round: + * + * Landon Curt Noll (http://www.isthe.com/chongo/) + * + * improved on their algorithm. Some people tried this hash + * and found that it worked rather well. In an EMail message + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + * + * FNV hashes are designed to be fast while maintaining a low + * collision rate. The FNV speed allows one to quickly hash lots + * of data while maintaining a reasonable collision rate. See: + * + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + * + * for more details as well as other forms of the FNV hash. + * + *** + * + * NOTE: The FNV-0 historic hash is not recommended. One should use + * the FNV-1 hash instead. + * + * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the + * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). + * + * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the + * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). + * + * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the + * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). + * + * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the + * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). + * + * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the + * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str(). + * + * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the + * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str(). + * + *** + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +#if !defined(__FNV_H__) +#define __FNV_H__ + +#include <stdlib.h> +#include <stdint.h> + +#define FNV_VERSION "5.0.2" /* @(#) FNV Version */ + + +/* + * 32 bit FNV-0 hash type + */ +typedef uint32_t Fnv32_t; + + +/* + * 32 bit FNV-0 zero initial basis + * + * This historic hash is not recommended. One should use + * the FNV-1 hash and initial basis instead. + */ +#define FNV0_32_INIT ((Fnv32_t)0) + + +/* + * 32 bit FNV-1 and FNV-1a non-zero initial basis + * + * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets: + * + * chongo <Landon Curt Noll> /\../\ + * + * NOTE: The \'s above are not back-slashing escape characters. + * They are literal ASCII backslash 0x5c characters. + * + * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. + */ +#define FNV1_32_INIT ((Fnv32_t)0x811c9dc5) +#define FNV1_32A_INIT FNV1_32_INIT + + +/* + * determine how 64 bit unsigned values are represented + */ +#include "longlong.h" + + +/* + * 64 bit FNV-0 hash + */ +#if defined(HAVE_64BIT_LONG_LONG) +typedef uint64_t Fnv64_t; +#else /* HAVE_64BIT_LONG_LONG */ +typedef struct { + uint32_t w32[2]; /* w32[0] is low order, w32[1] is high order word */ +} Fnv64_t; +#endif /* HAVE_64BIT_LONG_LONG */ + + +/* + * 64 bit FNV-0 zero initial basis + * + * This historic hash is not recommended. One should use + * the FNV-1 hash and initial basis instead. + */ +#if defined(HAVE_64BIT_LONG_LONG) +#define FNV0_64_INIT ((Fnv64_t)0) +#else /* HAVE_64BIT_LONG_LONG */ +extern const Fnv64_t fnv0_64_init; +#define FNV0_64_INIT (fnv0_64_init) +#endif /* HAVE_64BIT_LONG_LONG */ + + +/* + * 64 bit FNV-1 non-zero initial basis + * + * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets: + * + * chongo <Landon Curt Noll> /\../\ + * + * NOTE: The \'s above are not back-slashing escape characters. + * They are literal ASCII backslash 0x5c characters. + * + * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. + */ +#if defined(HAVE_64BIT_LONG_LONG) +#define FNV1_64_INIT ((Fnv64_t)0xcbf29ce484222325ULL) +#define FNV1A_64_INIT FNV1_64_INIT +#else /* HAVE_64BIT_LONG_LONG */ +extern const fnv1_64_init; +extern const Fnv64_t fnv1a_64_init; +#define FNV1_64_INIT (fnv1_64_init) +#define FNV1A_64_INIT (fnv1a_64_init) +#endif /* HAVE_64BIT_LONG_LONG */ + + +/* + * hash types + */ +enum fnv_type { + FNV_NONE = 0, /* invalid FNV hash type */ + FNV0_32 = 1, /* FNV-0 32 bit hash */ + FNV1_32 = 2, /* FNV-1 32 bit hash */ + FNV1a_32 = 3, /* FNV-1a 32 bit hash */ + FNV0_64 = 4, /* FNV-0 64 bit hash */ + FNV1_64 = 5, /* FNV-1 64 bit hash */ + FNV1a_64 = 6, /* FNV-1a 64 bit hash */ +}; + + +/* + * these test vectors are used as part o the FNV test suite + */ +struct test_vector { + void *buf; /* start of test vector buffer */ + int len; /* length of test vector */ +}; +struct fnv0_32_test_vector { + struct test_vector *test; /* test vector buffer to hash */ + Fnv32_t fnv0_32; /* expected FNV-0 32 bit hash value */ +}; +struct fnv1_32_test_vector { + struct test_vector *test; /* test vector buffer to hash */ + Fnv32_t fnv1_32; /* expected FNV-1 32 bit hash value */ +}; +struct fnv1a_32_test_vector { + struct test_vector *test; /* test vector buffer to hash */ + Fnv32_t fnv1a_32; /* expected FNV-1a 32 bit hash value */ +}; +struct fnv0_64_test_vector { + struct test_vector *test; /* test vector buffer to hash */ + Fnv64_t fnv0_64; /* expected FNV-0 64 bit hash value */ +}; +struct fnv1_64_test_vector { + struct test_vector *test; /* test vector buffer to hash */ + Fnv64_t fnv1_64; /* expected FNV-1 64 bit hash value */ +}; +struct fnv1a_64_test_vector { + struct test_vector *test; /* test vector buffer to hash */ + Fnv64_t fnv1a_64; /* expected FNV-1a 64 bit hash value */ +}; + + +/* + * external functions + */ +/* hash_32.c */ +extern Fnv32_t fnv_32_buf(void *buf, size_t len, Fnv32_t hashval); +extern Fnv32_t fnv_32_str(char *buf, Fnv32_t hashval); + +/* hash_32a.c */ +extern Fnv32_t fnv_32a_buf(void *buf, size_t len, Fnv32_t hashval); +extern Fnv32_t fnv_32a_str(char *buf, Fnv32_t hashval); + +/* hash_64.c */ +extern Fnv64_t fnv_64_buf(void *buf, size_t len, Fnv64_t hashval); +extern Fnv64_t fnv_64_str(char *buf, Fnv64_t hashval); + +/* hash_64a.c */ +extern Fnv64_t fnv_64a_buf(void *buf, size_t len, Fnv64_t hashval); +extern Fnv64_t fnv_64a_str(char *buf, Fnv64_t hashval); + +/* test_fnv.c */ +extern struct test_vector fnv_test_str[]; +extern struct fnv0_32_test_vector fnv0_32_vector[]; +extern struct fnv1_32_test_vector fnv1_32_vector[]; +extern struct fnv1a_32_test_vector fnv1a_32_vector[]; +extern struct fnv0_64_test_vector fnv0_64_vector[]; +extern struct fnv1_64_test_vector fnv1_64_vector[]; +extern struct fnv1a_64_test_vector fnv1a_64_vector[]; +extern void unknown_hash_type(char *prog, enum fnv_type type, int code); +extern void print_fnv32(Fnv32_t hval, Fnv32_t mask, int verbose, char *arg); +extern void print_fnv64(Fnv64_t hval, Fnv64_t mask, int verbose, char *arg); + + +#endif /* __FNV_H__ */ diff --git a/lib/fnv/fnv32.c b/lib/fnv/fnv32.c new file mode 100644 index 0000000000..58c61f03fc --- /dev/null +++ b/lib/fnv/fnv32.c @@ -0,0 +1,467 @@ +/* + * fnv32 - 32 bit Fowler/Noll/Vo hash of a buffer or string + * + * @(#) $Revision: 5.5 $ + * @(#) $Id: fnv32.c,v 5.5 2012/03/21 01:38:12 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv32.c,v $ + * + *** + * + * Fowler/Noll/Vo hash + * + * The basis of this hash algorithm was taken from an idea sent + * as reviewer comments to the IEEE POSIX P1003.2 committee by: + * + * Phong Vo (http://www.research.att.com/info/kpv/) + * Glenn Fowler (http://www.research.att.com/~gsf/) + * + * In a subsequent ballot round: + * + * Landon Curt Noll (http://www.isthe.com/chongo/) + * + * improved on their algorithm. Some people tried this hash + * and found that it worked rather well. In an EMail message + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + * + * FNV hashes are designed to be fast while maintaining a low + * collision rate. The FNV speed allows one to quickly hash lots + * of data while maintaining a reasonable collision rate. See: + * + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + * + * for more details as well as other forms of the FNV hash. + * + *** + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include "longlong.h" +#include "fnv.h" + +#define WIDTH 32 /* bit width of hash */ + +#define BUF_SIZE (32*1024) /* number of bytes to hash at a time */ + +static char *usage = +"usage: %s [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]\n" +"\n" +"\t-b bcnt\tmask off all but the lower bcnt bits (default 32)\n" +"\t-m\tmultiple hashes, one per line for each arg\n" +"\t-s\thash arg as a string (ignoring terminating NUL bytes)\n" +"\t-t code\t test hash code: (0 ==> generate test vectors\n" +"\t\t\t\t 1 ==> validate against FNV test vectors)\n" +"\t-v\tverbose mode, print arg after hash (implies -m)\n" +"\targ\tstring (if -s was given) or filename (default stdin)\n" +"\n" +"\tNOTE: Programs that begin with fnv0 implement the FNV-0 hash.\n" +"\t The FNV-0 hash is historic FNV algorithm that is now deprecated.\n" +"\n" +"\tSee http://www.isthe.com/chongo/tech/comp/fnv/index.html for more info.\n" +"\n" +"\t@(#) FNV Version: %s\n"; +static char *program; /* our name */ + + +/* + * test_fnv32 - test the FNV32 hash + * + * given: + * hash_type type of FNV hash to test + * init_hval initial hash value + * mask lower bit mask + * v_flag 1 => print test failure info on stderr + * code 0 ==> generate FNV test vectors + * 1 ==> validate against FNV test vectors + * + * returns: 0 ==> OK, else test vector failure number + */ +static int +test_fnv32(enum fnv_type hash_type, Fnv32_t init_hval, + Fnv32_t mask, int v_flag, int code) +{ + struct test_vector *t; /* FNV test vestor */ + Fnv32_t hval; /* current hash value */ + int tstnum; /* test vector that failed, starting at 1 */ + + /* + * print preamble if generating test vectors + */ + if (code == 0) { + switch (hash_type) { + case FNV0_32: + printf("struct fnv0_32_test_vector fnv0_32_vector[] = {\n"); + break; + case FNV1_32: + printf("struct fnv1_32_test_vector fnv1_32_vector[] = {\n"); + break; + case FNV1a_32: + printf("struct fnv1a_32_test_vector fnv1a_32_vector[] = {\n"); + break; + default: + unknown_hash_type(program, hash_type, 12); /* exit(12) */ + /*NOTREACHED*/ + } + } + + /* + * loop thru all test vectors + */ + for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) { + + /* + * compute the FNV hash + */ + hval = init_hval; + switch (hash_type) { + case FNV0_32: + case FNV1_32: + hval = fnv_32_buf(t->buf, t->len, hval); + break; + case FNV1a_32: + hval = fnv_32a_buf(t->buf, t->len, hval); + break; + default: + unknown_hash_type(program, hash_type, 13); /* exit(13) */ + /*NOTREACHED*/ + } + + /* + * print the vector + */ + switch (code) { + case 0: /* generate the test vector */ + printf(" { &fnv_test_str[%d], (Fnv32_t) 0x%08lxUL },\n", + tstnum-1, hval & mask); + break; + case 1: /* validate against test vector */ + switch (hash_type) { + case FNV0_32: + if ((hval&mask) != (fnv0_32_vector[tstnum-1].fnv0_32 & mask)) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv0_32 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%08lx != generated: 0x%08lx\n", + program, (hval&mask), + (fnv0_32_vector[tstnum-1].fnv0_32 & mask)); + } + return tstnum; + } + break; + case FNV1_32: + if ((hval&mask) != (fnv1_32_vector[tstnum-1].fnv1_32 & mask)) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv1_32 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%08lx != generated: 0x%08lx\n", + program, (hval&mask), + (fnv1_32_vector[tstnum-1].fnv1_32 & mask)); + } + return tstnum; + } + break; + case FNV1a_32: + if ((hval&mask) != (fnv1a_32_vector[tstnum-1].fnv1a_32 &mask)) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv1a_32 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%08lx != generated: 0x%08lx\n", + program, (hval&mask), + (fnv1a_32_vector[tstnum-1].fnv1a_32 & mask)); + } + return tstnum; + } + break; + } + break; + default: + fprintf(stderr, "%s: -m %d not implemented yet\n", program, code); + exit(14); + } + } + + /* + * print completion if generating test vectors + */ + if (code == 0) { + printf(" { NULL, 0 }\n"); + printf("};\n"); + } + + /* + * no failures, return code 0 ==> all OK + */ + return 0; +} + + +/* + * main - the main function + * + * See the above usage for details. + */ +int +main(int argc, char *argv[]) +{ + char buf[BUF_SIZE+1]; /* read buffer */ + int readcnt; /* number of characters written */ + Fnv32_t hval; /* current hash value */ + int s_flag = 0; /* 1 => -s was given, hash args as strings */ + int m_flag = 0; /* 1 => print multiple hashes, one per arg */ + int v_flag = 0; /* 1 => verbose hash print */ + int b_flag = WIDTH; /* -b flag value */ + int t_flag = -1; /* FNV test vector code (0=>print, 1=>test) */ + enum fnv_type hash_type = FNV_NONE; /* type of FNV hash to perform */ + Fnv32_t bmask; /* mask to apply to output */ + extern char *optarg; /* option argument */ + extern int optind; /* argv index of the next arg */ + int fd; /* open file to process */ + char *p; + int i; + + /* + * parse args + */ + program = argv[0]; + while ((i = getopt(argc, argv, "b:mst:v")) != -1) { + switch (i) { + case 'b': /* bcnt bit mask count */ + b_flag = atoi(optarg); + break; + case 'm': /* print multiple hashes, one per arg */ + m_flag = 1; + break; + case 's': /* hash args as strings */ + s_flag = 1; + break; + case 't': /* FNV test vector code */ + t_flag = atoi(optarg); + if (t_flag < 0 || t_flag > 1) { + fprintf(stderr, "%s: -t code must be 0 or 1\n", program); + fprintf(stderr, usage, program, FNV_VERSION); + exit(1); + } + m_flag = 1; + break; + case 'v': /* verbose hash print */ + m_flag = 1; + v_flag = 1; + break; + default: + fprintf(stderr, usage, program, FNV_VERSION); + exit(1); + } + } + /* -t code incompatible with -b, -m and args */ + if (t_flag >= 0) { + if (b_flag != WIDTH) { + fprintf(stderr, "%s: -t code incompatible with -b\n", program); + exit(2); + } + if (s_flag != 0) { + fprintf(stderr, "%s: -t code incompatible with -s\n", program); + exit(3); + } + if (optind < argc) { + fprintf(stderr, "%s: -t code incompatible args\n", program); + exit(4); + } + } + /* -s requires at least 1 arg */ + if (s_flag && optind >= argc) { + fprintf(stderr, usage, program, FNV_VERSION); + exit(5); + } + /* limit -b values */ + if (b_flag < 0 || b_flag > WIDTH) { + fprintf(stderr, "%s: -b bcnt: %d must be >= 0 and < %d\n", + program, b_flag, WIDTH); + exit(6); + } + if (b_flag == WIDTH) { + bmask = (Fnv32_t)0xffffffff; + } else { + bmask = (Fnv32_t)((1 << b_flag) - 1); + } + + /* + * start with the initial basis depending on the hash type + */ + p = strrchr(program, '/'); + if (p == NULL) { + p = program; + } else { + ++p; + } + if (strcmp(p, "fnv032") == 0) { + /* using non-recommended FNV-0 and zero initial basis */ + hval = FNV0_32_INIT; + hash_type = FNV0_32; + } else if (strcmp(p, "fnv132") == 0) { + /* using FNV-1 and non-zero initial basis */ + hval = FNV1_32_INIT; + hash_type = FNV1_32; + } else if (strcmp(p, "fnv1a32") == 0) { + /* start with the FNV-1a initial basis */ + hval = FNV1_32A_INIT; + hash_type = FNV1a_32; + } else { + fprintf(stderr, "%s: unknown program name, unknown hash type\n", + program); + exit(7); + } + + /* + * FNV test vector processing, if needed + */ + if (t_flag >= 0) { + int code; /* test vector that failed, starting at 1 */ + + /* + * perform all tests + */ + code = test_fnv32(hash_type, hval, bmask, v_flag, t_flag); + + /* + * evaluate the tests + */ + if (code == 0) { + if (v_flag) { + printf("passed\n"); + } + exit(0); + } else { + printf("failed vector (1 is 1st test): %d\n", code); + exit(8); + } + } + + /* + * string hashing + */ + if (s_flag) { + + /* hash any other strings */ + for (i=optind; i < argc; ++i) { + switch (hash_type) { + case FNV0_32: + case FNV1_32: + hval = fnv_32_str(argv[i], hval); + break; + case FNV1a_32: + hval = fnv_32a_str(argv[i], hval); + break; + default: + unknown_hash_type(program, hash_type, 9); /* exit(9) */ + /*NOTREACHED*/ + } + if (m_flag) { + print_fnv32(hval, bmask, v_flag, argv[i]); + } + } + + + /* + * file hashing + */ + } else { + + /* + * case: process only stdin + */ + if (optind >= argc) { + + /* case: process only stdin */ + while ((readcnt = read(0, buf, BUF_SIZE)) > 0) { + switch (hash_type) { + case FNV0_32: + case FNV1_32: + hval = fnv_32_buf(buf, readcnt, hval); + break; + case FNV1a_32: + hval = fnv_32a_buf(buf, readcnt, hval); + break; + default: + unknown_hash_type(program, hash_type, 10); /* exit(10) */ + /*NOTREACHED*/ + } + } + if (m_flag) { + print_fnv32(hval, bmask, v_flag, "(stdin)"); + } + + } else { + + /* + * process any other files + */ + for (i=optind; i < argc; ++i) { + + /* open the file */ + fd = open(argv[i], O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: unable to open file: %s\n", + program, argv[i]); + exit(4); + } + + /* hash the file */ + while ((readcnt = read(fd, buf, BUF_SIZE)) > 0) { + switch (hash_type) { + case FNV0_32: + case FNV1_32: + hval = fnv_32_buf(buf, readcnt, hval); + break; + case FNV1a_32: + hval = fnv_32a_buf(buf, readcnt, hval); + break; + default: + unknown_hash_type(program, hash_type, 11);/* exit(11) */ + /*NOTREACHED*/ + } + } + + /* finish processing the file */ + if (m_flag) { + print_fnv32(hval, bmask, v_flag, argv[i]); + } + close(fd); + } + } + } + + /* + * report hash and exit + */ + if (!m_flag) { + print_fnv32(hval, bmask, v_flag, ""); + } + return 0; /* exit(0); */ +} diff --git a/lib/fnv/fnv64.c b/lib/fnv/fnv64.c new file mode 100644 index 0000000000..0662d4d657 --- /dev/null +++ b/lib/fnv/fnv64.c @@ -0,0 +1,591 @@ +/* + * fnv_64 - 64 bit Fowler/Noll/Vo hash of a buffer or string + * + * @(#) $Revision: 5.5 $ + * @(#) $Id: fnv64.c,v 5.5 2012/03/21 01:38:12 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv64.c,v $ + * + *** + * + * Fowler/Noll/Vo hash + * + * The basis of this hash algorithm was taken from an idea sent + * as reviewer comments to the IEEE POSIX P1003.2 committee by: + * + * Phong Vo (http://www.research.att.com/info/kpv/) + * Glenn Fowler (http://www.research.att.com/~gsf/) + * + * In a subsequent ballot round: + * + * Landon Curt Noll (http://www.isthe.com/chongo/) + * + * improved on their algorithm. Some people tried this hash + * and found that it worked rather well. In an EMail message + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + * + * FNV hashes are designed to be fast while maintaining a low + * collision rate. The FNV speed allows one to quickly hash lots + * of data while maintaining a reasonable collision rate. See: + * + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + * + * for more details as well as other forms of the FNV hash. + * + *** + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include "longlong.h" +#include "fnv.h" + +#define WIDTH 64 /* bit width of hash */ + +#define BUF_SIZE (32*1024) /* number of bytes to hash at a time */ + +static char *usage = +"usage: %s [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]\n" +"\n" +"\t-b bcnt\tmask off all but the lower bcnt bits (default 64)\n" +"\t-m\tmultiple hashes, one per line for each arg\n" +"\t-s\thash arg as a string (ignoring terminating NUL bytes)\n" +"\t-t code\t test hash code: (0 ==> generate test vectors\n" +"\t\t\t\t 1 ==> validate against FNV test vectors)\n" +"\t-v\tverbose mode, print arg after hash (implies -m)\n" +"\targ\tstring (if -s was given) or filename (default stdin)\n" +"\n" +"\tNOTE: Programs that begin with fnv0 implement the FNV-0 hash.\n" +"\t The FNV-0 hash is historic FNV algorithm that is now deprecated.\n" +"\n" +"\tSee http://www.isthe.com/chongo/tech/comp/fnv/index.html for more info.\n" +"\n" +"\t@(#) FNV Version: %s\n"; +static char *program; /* our name */ + + +/* + * test_fnv64 - test the FNV64 hash + * + * given: + * hash_type type of FNV hash to test + * init_hval initial hash value + * mask lower bit mask + * v_flag 1 => print test failure info on stderr + * code 0 ==> generate FNV test vectors + * 1 ==> validate against FNV test vectors + * + * returns: 0 ==> OK, else test vector failure number + */ +static int +test_fnv64(enum fnv_type hash_type, Fnv64_t init_hval, + Fnv64_t mask, int v_flag, int code) +{ + struct test_vector *t; /* FNV test vestor */ + Fnv64_t hval; /* current hash value */ + int tstnum; /* test vector that failed, starting at 1 */ + + /* + * print preamble if generating test vectors + */ + if (code == 0) { + switch (hash_type) { + case FNV0_64: + printf("struct fnv0_64_test_vector fnv0_64_vector[] = {\n"); + break; + case FNV1_64: + printf("struct fnv1_64_test_vector fnv1_64_vector[] = {\n"); + break; + case FNV1a_64: + printf("struct fnv1a_64_test_vector fnv1a_64_vector[] = {\n"); + break; + default: + unknown_hash_type(program, hash_type, 12); /* exit(12) */ + /*NOTREACHED*/ + } + } + + /* + * loop thru all test vectors + */ + for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) { + + /* + * compute the FNV hash + */ + hval = init_hval; + switch (hash_type) { + case FNV0_64: + case FNV1_64: + hval = fnv_64_buf(t->buf, t->len, hval); + break; + case FNV1a_64: + hval = fnv_64a_buf(t->buf, t->len, hval); + break; + default: + unknown_hash_type(program, hash_type, 13); /* exit(13) */ + /*NOTREACHED*/ + } + + /* + * print the vector + */ +#if defined(HAVE_64BIT_LONG_LONG) + /* + * HAVE_64BIT_LONG_LONG testing + */ + switch (code) { + case 0: /* generate the test vector */ + printf(" { &fnv_test_str[%d], (Fnv64_t) 0x%016llxULL },\n", + tstnum-1, hval & mask); + break; + + case 1: /* validate against test vector */ + switch (hash_type) { + case FNV0_64: + if ((hval&mask) != (fnv0_64_vector[tstnum-1].fnv0_64 & mask)) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv0_64 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%016llx != generated: 0x%016llx\n", + program, + (hval&mask), + (fnv0_64_vector[tstnum-1].fnv0_64 & mask)); + } + return tstnum; + } + break; + case FNV1_64: + if ((hval&mask) != (fnv1_64_vector[tstnum-1].fnv1_64 & mask)) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv1_64 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%016llx != generated: 0x%016llx\n", + program, + (hval&mask), + (fnv1_64_vector[tstnum-1].fnv1_64 & mask)); + } + return tstnum; + } + break; + case FNV1a_64: + if ((hval&mask) != (fnv1a_64_vector[tstnum-1].fnv1a_64 &mask)) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv1a_64 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%016llx != generated: 0x%016llx\n", + program, + (hval&mask), + (fnv1a_64_vector[tstnum-1].fnv1a_64 & mask)); + } + return tstnum; + } + break; + } + break; + + default: + fprintf(stderr, "%s: -m %d not implemented yet\n", program, code); + exit(14); + } +#else /* HAVE_64BIT_LONG_LONG */ + /* + * non HAVE_64BIT_LONG_LONG testing + */ + switch (code) { + case 0: /* generate the test vector */ + printf(" { &fnv_test_str[%d], " + "(Fnv64_t) {0x%08lxUL, 0x%08lxUL} },\n", + tstnum-1, + (hval.w32[0] & mask.w32[0]), + (hval.w32[1] & mask.w32[1])); + break; + + case 1: /* validate against test vector */ + switch (hash_type) { + case FNV0_64: + if (((hval.w32[0] & mask.w32[0]) != + (fnv0_64_vector[tstnum-1].fnv0_64.w32[0] & + mask.w32[0])) && + ((hval.w32[1] & mask.w32[1]) != + (fnv0_64_vector[tstnum-1].fnv0_64.w32[1] & + mask.w32[1]))) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv0_64 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%08llx%08llx != " + "generated: 0x%08llx%08llx\n", + program, + (hval.w32[0] & mask.w32[0]), + (hval.w32[1] & mask.w32[1]), + ((fnv0_64_vector[tstnum-1].fnv0_64.w32[0] & + mask.w32[0])), + ((fnv0_64_vector[tstnum-1].fnv0_64.w32[1] & + mask.w32[1]))); + } + return tstnum; + } + break; + case FNV1_64: + if (((hval.w32[0] & mask.w32[0]) != + (fnv1_64_vector[tstnum-1].fnv1_64.w32[0] & + mask.w32[0])) && + ((hval.w32[1] & mask.w32[1]) != + (fnv1_64_vector[tstnum-1].fnv1_64.w32[1] & + mask.w32[1]))) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv1_64 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%08llx%08llx != " + "generated: 0x%08llx%08llx\n", + program, + (hval.w32[0] & mask.w32[0]), + (hval.w32[1] & mask.w32[1]), + ((fnv1_64_vector[tstnum-1].fnv1_64.w32[0] & + mask.w32[0])), + ((fnv1_64_vector[tstnum-1].fnv1_64.w32[1] & + mask.w32[1]))); + } + return tstnum; + } + break; + case FNV1a_64: + if (((hval.w32[0] & mask.w32[0]) != + (fnv1a_64_vector[tstnum-1].fnv1a_64.w32[0] & + mask.w32[0])) && + ((hval.w32[1] & mask.w32[1]) != + (fnv1a_64_vector[tstnum-1].fnv1a_64.w32[1] & + mask.w32[1]))) { + if (v_flag) { + fprintf(stderr, "%s: failed fnv1a_64 test # %d\n", + program, tstnum); + fprintf(stderr, "%s: test # 1 is 1st test\n", program); + fprintf(stderr, + "%s: expected 0x%08llx%08llx != " + "generated: 0x%08llx%08llx\n", + program, + (hval.w32[0] & mask.w32[0]), + (hval.w32[1] & mask.w32[1]), + ((fnv1a_64_vector[tstnum-1].fnv1a_64.w32[0] & + mask.w32[0])), + ((fnv1a_64_vector[tstnum-1].fnv1a_64.w32[1] & + mask.w32[1]))); + } + return tstnum; + } + break; + } + break; + + default: + fprintf(stderr, "%s: -m %d not implemented yet\n", program, code); + exit(15); + } +#endif /* HAVE_64BIT_LONG_LONG */ + } + + /* + * print completion if generating test vectors + */ + if (code == 0) { +#if defined(HAVE_64BIT_LONG_LONG) + printf(" { NULL, (Fnv64_t) 0 }\n"); +#else /* HAVE_64BIT_LONG_LONG */ + printf(" { NULL, (Fnv64_t) {0,0} }\n"); +#endif /* HAVE_64BIT_LONG_LONG */ + printf("};\n"); + } + + /* + * no failures, return code 0 ==> all OK + */ + return 0; +} + + +/* + * main - the main function + * + * See the above usage for details. + */ +int +main(int argc, char *argv[]) +{ + char buf[BUF_SIZE+1]; /* read buffer */ + int readcnt; /* number of characters written */ + Fnv64_t hval; /* current hash value */ + int s_flag = 0; /* 1 => -s was given, hash args as strings */ + int m_flag = 0; /* 1 => print multiple hashes, one per arg */ + int v_flag = 0; /* 1 => verbose hash print */ + int b_flag = WIDTH; /* -b flag value */ + int t_flag = -1; /* FNV test vector code (0=>print, 1=>test) */ + enum fnv_type hash_type = FNV_NONE; /* type of FNV hash to perform */ + Fnv64_t bmask; /* mask to apply to output */ + extern char *optarg; /* option argument */ + extern int optind; /* argv index of the next arg */ + int fd; /* open file to process */ + char *p; + int i; + + /* + * parse args + */ + program = argv[0]; + while ((i = getopt(argc, argv, "b:mst:v")) != -1) { + switch (i) { + case 'b': /* bcnt bit mask count */ + b_flag = atoi(optarg); + break; + case 'm': /* print multiple hashes, one per arg */ + m_flag = 1; + break; + case 's': /* hash args as strings */ + s_flag = 1; + break; + case 't': /* FNV test vector code */ + t_flag = atoi(optarg); + if (t_flag < 0 || t_flag > 1) { + fprintf(stderr, "%s: -t code must be 0 or 1\n", program); + fprintf(stderr, usage, program, FNV_VERSION); + exit(1); + } + m_flag = 1; + break; + case 'v': /* verbose hash print */ + m_flag = 1; + v_flag = 1; + break; + default: + fprintf(stderr, usage, program, FNV_VERSION); + exit(1); + } + } + /* -t code incompatible with -b, -m and args */ + if (t_flag >= 0) { + if (b_flag != WIDTH) { + fprintf(stderr, "%s: -t code incompatible with -b\n", program); + exit(2); + } + if (s_flag != 0) { + fprintf(stderr, "%s: -t code incompatible with -s\n", program); + exit(3); + } + if (optind < argc) { + fprintf(stderr, "%s: -t code incompatible args\n", program); + exit(4); + } + } + /* -s requires at least 1 arg */ + if (s_flag && optind >= argc) { + fprintf(stderr, usage, program, FNV_VERSION); + exit(5); + } + /* limit -b values */ + if (b_flag < 0 || b_flag > WIDTH) { + fprintf(stderr, "%s: -b bcnt: %d must be >= 0 and < %d\n", + program, b_flag, WIDTH); + exit(6); + } +#if defined(HAVE_64BIT_LONG_LONG) + if (b_flag == WIDTH) { + bmask = (Fnv64_t)0xffffffffffffffffULL; + } else { + bmask = (Fnv64_t)((1ULL << b_flag) - 1ULL); + } +#else /* HAVE_64BIT_LONG_LONG */ + if (b_flag == WIDTH) { + bmask.w32[0] = 0xffffffffUL; + bmask.w32[1] = 0xffffffffUL; + } else if (b_flag >= WIDTH/2) { + bmask.w32[0] = 0xffffffffUL; + bmask.w32[1] = ((1UL << (b_flag-(WIDTH/2))) - 1UL); + } else { + bmask.w32[0] = ((1UL << b_flag) - 1UL); + bmask.w32[1] = 0UL; + } +#endif /* HAVE_64BIT_LONG_LONG */ + + /* + * start with the initial basis depending on the hash type + */ + p = strrchr(program, '/'); + if (p == NULL) { + p = program; + } else { + ++p; + } + if (strcmp(p, "fnv064") == 0 || strcmp(p, "no64bit_fnv064") == 0) { + /* using non-recommended FNV-0 and zero initial basis */ + hval = FNV0_64_INIT; + hash_type = FNV0_64; + } else if (strcmp(p, "fnv164") == 0 || strcmp(p, "no64bit_fnv164") == 0) { + /* using FNV-1 and non-zero initial basis */ + hval = FNV1_64_INIT; + hash_type = FNV1_64; + } else if (strcmp(p, "fnv1a64") == 0 || strcmp(p, "no64bit_fnv1a64") == 0) { + /* start with the FNV-1a initial basis */ + hval = FNV1A_64_INIT; + hash_type = FNV1a_64; + } else { + fprintf(stderr, "%s: unknown program name, unknown hash type\n", + program); + exit(7); + } + + /* + * FNV test vector processing, if needed + */ + if (t_flag >= 0) { + int code; /* test vector that failed, starting at 1 */ + + /* + * perform all tests + */ + code = test_fnv64(hash_type, hval, bmask, v_flag, t_flag); + + /* + * evaluate the tests + */ + if (code == 0) { + if (v_flag) { + printf("passed\n"); + } + exit(0); + } else { + printf("failed vector (1 is 1st test): %d\n", code); + exit(8); + } + } + + /* + * string hashing + */ + if (s_flag) { + + /* hash any other strings */ + for (i=optind; i < argc; ++i) { + switch (hash_type) { + case FNV0_64: + case FNV1_64: + hval = fnv_64_str(argv[i], hval); + break; + case FNV1a_64: + hval = fnv_64a_str(argv[i], hval); + break; + default: + unknown_hash_type(program, hash_type, 9); /* exit(9) */ + /*NOTREACHED*/ + } + if (m_flag) { + print_fnv64(hval, bmask, v_flag, argv[i]); + } + } + + + /* + * file hashing + */ + } else { + + /* + * case: process only stdin + */ + if (optind >= argc) { + + /* case: process only stdin */ + while ((readcnt = read(0, buf, BUF_SIZE)) > 0) { + switch (hash_type) { + case FNV0_64: + case FNV1_64: + hval = fnv_64_buf(buf, readcnt, hval); + break; + case FNV1a_64: + hval = fnv_64a_buf(buf, readcnt, hval); + break; + default: + unknown_hash_type(program, hash_type, 10); /* exit(10) */ + /*NOTREACHED*/ + } + } + if (m_flag) { + print_fnv64(hval, bmask, v_flag, "(stdin)"); + } + + } else { + + /* + * process any other files + */ + for (i=optind; i < argc; ++i) { + + /* open the file */ + fd = open(argv[i], O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: unable to open file: %s\n", + program, argv[i]); + exit(4); + } + + /* hash the file */ + while ((readcnt = read(fd, buf, BUF_SIZE)) > 0) { + switch (hash_type) { + case FNV0_64: + case FNV1_64: + hval = fnv_64_buf(buf, readcnt, hval); + break; + case FNV1a_64: + hval = fnv_64a_buf(buf, readcnt, hval); + break; + default: + unknown_hash_type(program, hash_type, 11);/* exit(11) */ + /*NOTREACHED*/ + } + } + + /* finish processing the file */ + if (m_flag) { + print_fnv64(hval, bmask, v_flag, argv[i]); + } + close(fd); + } + } + } + + /* + * report hash and exit + */ + if (!m_flag) { + print_fnv64(hval, bmask, v_flag, ""); + } + return 0; /* exit(0); */ +} diff --git a/lib/fnv/hash_32.c b/lib/fnv/hash_32.c new file mode 100644 index 0000000000..077170ff6d --- /dev/null +++ b/lib/fnv/hash_32.c @@ -0,0 +1,156 @@ +/* + * hash_32 - 32 bit Fowler/Noll/Vo hash code + * + * @(#) $Revision: 5.1 $ + * @(#) $Id: hash_32.c,v 5.1 2009/06/30 09:13:32 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32.c,v $ + * + *** + * + * Fowler/Noll/Vo hash + * + * The basis of this hash algorithm was taken from an idea sent + * as reviewer comments to the IEEE POSIX P1003.2 committee by: + * + * Phong Vo (http://www.research.att.com/info/kpv/) + * Glenn Fowler (http://www.research.att.com/~gsf/) + * + * In a subsequent ballot round: + * + * Landon Curt Noll (http://www.isthe.com/chongo/) + * + * improved on their algorithm. Some people tried this hash + * and found that it worked rather well. In an EMail message + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + * + * FNV hashes are designed to be fast while maintaining a low + * collision rate. The FNV speed allows one to quickly hash lots + * of data while maintaining a reasonable collision rate. See: + * + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + * + * for more details as well as other forms of the FNV hash. + *** + * + * NOTE: The FNV-0 historic hash is not recommended. One should use + * the FNV-1 hash instead. + * + * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the + * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). + * + * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the + * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). + * + *** + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +#include <stdlib.h> +#include "fnv.h" + + +/* + * 32 bit magic FNV-0 and FNV-1 prime + */ +#define FNV_32_PRIME ((Fnv32_t)0x01000193) + + +/* + * fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer + * + * input: + * buf - start of buffer to hash + * len - length of buffer in octets + * hval - previous hash value or 0 if first call + * + * returns: + * 32 bit hash as a static hash type + * + * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval + * argument on the first call to either fnv_32_buf() or fnv_32_str(). + * + * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval + * argument on the first call to either fnv_32_buf() or fnv_32_str(). + */ +Fnv32_t +fnv_32_buf(void *buf, size_t len, Fnv32_t hval) +{ + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ + unsigned char *be = bp + len; /* beyond end of buffer */ + + /* + * FNV-1 hash each octet in the buffer + */ + while (bp < be) { + + /* multiply by the 32 bit FNV magic prime mod 2^32 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_32_PRIME; +#else + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); +#endif + + /* xor the bottom with the current octet */ + hval ^= (Fnv32_t)*bp++; + } + + /* return our new hash value */ + return hval; +} + + +/* + * fnv_32_str - perform a 32 bit Fowler/Noll/Vo hash on a string + * + * input: + * str - string to hash + * hval - previous hash value or 0 if first call + * + * returns: + * 32 bit hash as a static hash type + * + * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval + * argument on the first call to either fnv_32_buf() or fnv_32_str(). + * + * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval + * argument on the first call to either fnv_32_buf() or fnv_32_str(). + */ +Fnv32_t +fnv_32_str(char *str, Fnv32_t hval) +{ + unsigned char *s = (unsigned char *)str; /* unsigned string */ + + /* + * FNV-1 hash each octet in the buffer + */ + while (*s) { + + /* multiply by the 32 bit FNV magic prime mod 2^32 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_32_PRIME; +#else + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); +#endif + + /* xor the bottom with the current octet */ + hval ^= (Fnv32_t)*s++; + } + + /* return our new hash value */ + return hval; +} diff --git a/lib/fnv/hash_32a.c b/lib/fnv/hash_32a.c new file mode 100644 index 0000000000..8b10acf3e2 --- /dev/null +++ b/lib/fnv/hash_32a.c @@ -0,0 +1,144 @@ +/* + * hash_32 - 32 bit Fowler/Noll/Vo FNV-1a hash code + * + * @(#) $Revision: 5.1 $ + * @(#) $Id: hash_32a.c,v 5.1 2009/06/30 09:13:32 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32a.c,v $ + * + *** + * + * Fowler/Noll/Vo hash + * + * The basis of this hash algorithm was taken from an idea sent + * as reviewer comments to the IEEE POSIX P1003.2 committee by: + * + * Phong Vo (http://www.research.att.com/info/kpv/) + * Glenn Fowler (http://www.research.att.com/~gsf/) + * + * In a subsequent ballot round: + * + * Landon Curt Noll (http://www.isthe.com/chongo/) + * + * improved on their algorithm. Some people tried this hash + * and found that it worked rather well. In an EMail message + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + * + * FNV hashes are designed to be fast while maintaining a low + * collision rate. The FNV speed allows one to quickly hash lots + * of data while maintaining a reasonable collision rate. See: + * + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + * + * for more details as well as other forms of the FNV hash. + *** + * + * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the + * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str(). + * + *** + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +#include <stdlib.h> +#include "fnv.h" + + +/* + * 32 bit magic FNV-1a prime + */ +#define FNV_32_PRIME ((Fnv32_t)0x01000193) + + +/* + * fnv_32a_buf - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a buffer + * + * input: + * buf - start of buffer to hash + * len - length of buffer in octets + * hval - previous hash value or 0 if first call + * + * returns: + * 32 bit hash as a static hash type + * + * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the + * hval arg on the first call to either fnv_32a_buf() or fnv_32a_str(). + */ +Fnv32_t +fnv_32a_buf(void *buf, size_t len, Fnv32_t hval) +{ + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ + unsigned char *be = bp + len; /* beyond end of buffer */ + + /* + * FNV-1a hash each octet in the buffer + */ + while (bp < be) { + + /* xor the bottom with the current octet */ + hval ^= (Fnv32_t)*bp++; + + /* multiply by the 32 bit FNV magic prime mod 2^32 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_32_PRIME; +#else + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); +#endif + } + + /* return our new hash value */ + return hval; +} + + +/* + * fnv_32a_str - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a string + * + * input: + * str - string to hash + * hval - previous hash value or 0 if first call + * + * returns: + * 32 bit hash as a static hash type + * + * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the + * hval arg on the first call to either fnv_32a_buf() or fnv_32a_str(). + */ +Fnv32_t +fnv_32a_str(char *str, Fnv32_t hval) +{ + unsigned char *s = (unsigned char *)str; /* unsigned string */ + + /* + * FNV-1a hash each octet in the buffer + */ + while (*s) { + + /* xor the bottom with the current octet */ + hval ^= (Fnv32_t)*s++; + + /* multiply by the 32 bit FNV magic prime mod 2^32 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_32_PRIME; +#else + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); +#endif + } + + /* return our new hash value */ + return hval; +} diff --git a/lib/fnv/hash_64.c b/lib/fnv/hash_64.c new file mode 100644 index 0000000000..4338605dca --- /dev/null +++ b/lib/fnv/hash_64.c @@ -0,0 +1,312 @@ +/* + * hash_64 - 64 bit Fowler/Noll/Vo-0 hash code + * + * @(#) $Revision: 5.1 $ + * @(#) $Id: hash_64.c,v 5.1 2009/06/30 09:01:38 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64.c,v $ + * + *** + * + * Fowler/Noll/Vo hash + * + * The basis of this hash algorithm was taken from an idea sent + * as reviewer comments to the IEEE POSIX P1003.2 committee by: + * + * Phong Vo (http://www.research.att.com/info/kpv/) + * Glenn Fowler (http://www.research.att.com/~gsf/) + * + * In a subsequent ballot round: + * + * Landon Curt Noll (http://www.isthe.com/chongo/) + * + * improved on their algorithm. Some people tried this hash + * and found that it worked rather well. In an EMail message + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + * + * FNV hashes are designed to be fast while maintaining a low + * collision rate. The FNV speed allows one to quickly hash lots + * of data while maintaining a reasonable collision rate. See: + * + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + * + * for more details as well as other forms of the FNV hash. + * + *** + * + * NOTE: The FNV-0 historic hash is not recommended. One should use + * the FNV-1 hash instead. + * + * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the + * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). + * + * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the + * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). + * + *** + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +#include <stdlib.h> +#include "fnv.h" + + +/* + * FNV-0 defines the initial basis to be zero + */ +#if !defined(HAVE_64BIT_LONG_LONG) +const Fnv64_t fnv0_64_init = { 0UL, 0UL }; +#endif /* ! HAVE_64BIT_LONG_LONG */ + + +/* + * FNV-1 defines the initial basis to be non-zero + */ +#if !defined(HAVE_64BIT_LONG_LONG) +const Fnv64_t fnv1_64_init = { 0x84222325UL, 0xcbf29ce4UL }; +#endif /* ! HAVE_64BIT_LONG_LONG */ + + +/* + * 64 bit magic FNV-0 and FNV-1 prime + */ +#if defined(HAVE_64BIT_LONG_LONG) +#define FNV_64_PRIME ((Fnv64_t)0x100000001b3ULL) +#else /* HAVE_64BIT_LONG_LONG */ +#define FNV_64_PRIME_LOW ((unsigned long)0x1b3) /* lower bits of FNV prime */ +#define FNV_64_PRIME_SHIFT (8) /* top FNV prime shift above 2^32 */ +#endif /* HAVE_64BIT_LONG_LONG */ + + +/* + * fnv_64_buf - perform a 64 bit Fowler/Noll/Vo hash on a buffer + * + * input: + * buf - start of buffer to hash + * len - length of buffer in octets + * hval - previous hash value or 0 if first call + * + * returns: + * 64 bit hash as a static hash type + * + * NOTE: To use the 64 bit FNV-0 historic hash, use FNV0_64_INIT as the hval + * argument on the first call to either fnv_64_buf() or fnv_64_str(). + * + * NOTE: To use the recommended 64 bit FNV-1 hash, use FNV1_64_INIT as the hval + * argument on the first call to either fnv_64_buf() or fnv_64_str(). + */ +Fnv64_t +fnv_64_buf(void *buf, size_t len, Fnv64_t hval) +{ + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ + unsigned char *be = bp + len; /* beyond end of buffer */ + +#if defined(HAVE_64BIT_LONG_LONG) + + /* + * FNV-1 hash each octet of the buffer + */ + while (bp < be) { + + /* multiply by the 64 bit FNV magic prime mod 2^64 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_64_PRIME; +#else /* NO_FNV_GCC_OPTIMIZATION */ + hval += (hval << 1) + (hval << 4) + (hval << 5) + + (hval << 7) + (hval << 8) + (hval << 40); +#endif /* NO_FNV_GCC_OPTIMIZATION */ + + /* xor the bottom with the current octet */ + hval ^= (Fnv64_t)*bp++; + } + +#else /* HAVE_64BIT_LONG_LONG */ + + unsigned long val[4]; /* hash value in base 2^16 */ + unsigned long tmp[4]; /* tmp 64 bit value */ + + /* + * Convert Fnv64_t hval into a base 2^16 array + */ + val[0] = hval.w32[0]; + val[1] = (val[0] >> 16); + val[0] &= 0xffff; + val[2] = hval.w32[1]; + val[3] = (val[2] >> 16); + val[2] &= 0xffff; + + /* + * FNV-1 hash each octet of the buffer + */ + while (bp < be) { + + /* + * multiply by the 64 bit FNV magic prime mod 2^64 + * + * Using 0x100000001b3 we have the following digits base 2^16: + * + * 0x0 0x100 0x0 0x1b3 + * + * which is the same as: + * + * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW + */ + /* multiply by the lowest order digit base 2^16 */ + tmp[0] = val[0] * FNV_64_PRIME_LOW; + tmp[1] = val[1] * FNV_64_PRIME_LOW; + tmp[2] = val[2] * FNV_64_PRIME_LOW; + tmp[3] = val[3] * FNV_64_PRIME_LOW; + /* multiply by the other non-zero digit */ + tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */ + tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */ + /* propagate carries */ + tmp[1] += (tmp[0] >> 16); + val[0] = tmp[0] & 0xffff; + tmp[2] += (tmp[1] >> 16); + val[1] = tmp[1] & 0xffff; + val[3] = tmp[3] + (tmp[2] >> 16); + val[2] = tmp[2] & 0xffff; + /* + * Doing a val[3] &= 0xffff; is not really needed since it simply + * removes multiples of 2^64. We can discard these excess bits + * outside of the loop when we convert to Fnv64_t. + */ + + /* xor the bottom with the current octet */ + val[0] ^= (unsigned long)*bp++; + } + + /* + * Convert base 2^16 array back into an Fnv64_t + */ + hval.w32[1] = ((val[3]<<16) | val[2]); + hval.w32[0] = ((val[1]<<16) | val[0]); + +#endif /* HAVE_64BIT_LONG_LONG */ + + /* return our new hash value */ + return hval; +} + + +/* + * fnv_64_str - perform a 64 bit Fowler/Noll/Vo hash on a buffer + * + * input: + * buf - start of buffer to hash + * hval - previous hash value or 0 if first call + * + * returns: + * 64 bit hash as a static hash type + * + * NOTE: To use the 64 bit FNV-0 historic hash, use FNV0_64_INIT as the hval + * argument on the first call to either fnv_64_buf() or fnv_64_str(). + * + * NOTE: To use the recommended 64 bit FNV-1 hash, use FNV1_64_INIT as the hval + * argument on the first call to either fnv_64_buf() or fnv_64_str(). + */ +Fnv64_t +fnv_64_str(char *str, Fnv64_t hval) +{ + unsigned char *s = (unsigned char *)str; /* unsigned string */ + +#if defined(HAVE_64BIT_LONG_LONG) + + /* + * FNV-1 hash each octet of the string + */ + while (*s) { + + /* multiply by the 64 bit FNV magic prime mod 2^64 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_64_PRIME; +#else /* NO_FNV_GCC_OPTIMIZATION */ + hval += (hval << 1) + (hval << 4) + (hval << 5) + + (hval << 7) + (hval << 8) + (hval << 40); +#endif /* NO_FNV_GCC_OPTIMIZATION */ + + /* xor the bottom with the current octet */ + hval ^= (Fnv64_t)*s++; + } + +#else /* !HAVE_64BIT_LONG_LONG */ + + unsigned long val[4]; /* hash value in base 2^16 */ + unsigned long tmp[4]; /* tmp 64 bit value */ + + /* + * Convert Fnv64_t hval into a base 2^16 array + */ + val[0] = hval.w32[0]; + val[1] = (val[0] >> 16); + val[0] &= 0xffff; + val[2] = hval.w32[1]; + val[3] = (val[2] >> 16); + val[2] &= 0xffff; + + /* + * FNV-1 hash each octet of the string + */ + while (*s) { + + /* + * multiply by the 64 bit FNV magic prime mod 2^64 + * + * Using 1099511628211, we have the following digits base 2^16: + * + * 0x0 0x100 0x0 0x1b3 + * + * which is the same as: + * + * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW + */ + /* multiply by the lowest order digit base 2^16 */ + tmp[0] = val[0] * FNV_64_PRIME_LOW; + tmp[1] = val[1] * FNV_64_PRIME_LOW; + tmp[2] = val[2] * FNV_64_PRIME_LOW; + tmp[3] = val[3] * FNV_64_PRIME_LOW; + /* multiply by the other non-zero digit */ + tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */ + tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */ + /* propagate carries */ + tmp[1] += (tmp[0] >> 16); + val[0] = tmp[0] & 0xffff; + tmp[2] += (tmp[1] >> 16); + val[1] = tmp[1] & 0xffff; + val[3] = tmp[3] + (tmp[2] >> 16); + val[2] = tmp[2] & 0xffff; + /* + * Doing a val[3] &= 0xffff; is not really needed since it simply + * removes multiples of 2^64. We can discard these excess bits + * outside of the loop when we convert to Fnv64_t. + */ + + /* xor the bottom with the current octet */ + val[0] ^= (unsigned long)(*s++); + } + + /* + * Convert base 2^16 array back into an Fnv64_t + */ + hval.w32[1] = ((val[3]<<16) | val[2]); + hval.w32[0] = ((val[1]<<16) | val[0]); + +#endif /* !HAVE_64BIT_LONG_LONG */ + + /* return our new hash value */ + return hval; +} diff --git a/lib/fnv/hash_64a.c b/lib/fnv/hash_64a.c new file mode 100644 index 0000000000..6660f92ddf --- /dev/null +++ b/lib/fnv/hash_64a.c @@ -0,0 +1,291 @@ +/* + * hash_64 - 64 bit Fowler/Noll/Vo-0 FNV-1a hash code + * + * @(#) $Revision: 5.1 $ + * @(#) $Id: hash_64a.c,v 5.1 2009/06/30 09:01:38 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64a.c,v $ + * + *** + * + * Fowler/Noll/Vo hash + * + * The basis of this hash algorithm was taken from an idea sent + * as reviewer comments to the IEEE POSIX P1003.2 committee by: + * + * Phong Vo (http://www.research.att.com/info/kpv/) + * Glenn Fowler (http://www.research.att.com/~gsf/) + * + * In a subsequent ballot round: + * + * Landon Curt Noll (http://www.isthe.com/chongo/) + * + * improved on their algorithm. Some people tried this hash + * and found that it worked rather well. In an EMail message + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + * + * FNV hashes are designed to be fast while maintaining a low + * collision rate. The FNV speed allows one to quickly hash lots + * of data while maintaining a reasonable collision rate. See: + * + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + * + * for more details as well as other forms of the FNV hash. + * + *** + * + * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the + * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str(). + * + *** + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +#include <stdlib.h> +#include "fnv.h" + + +/* + * FNV-1a defines the initial basis to be non-zero + */ +#if !defined(HAVE_64BIT_LONG_LONG) +const Fnv64_t fnv1a_64_init = { 0x84222325, 0xcbf29ce4 }; +#endif /* ! HAVE_64BIT_LONG_LONG */ + + +/* + * 64 bit magic FNV-1a prime + */ +#if defined(HAVE_64BIT_LONG_LONG) +#define FNV_64_PRIME ((Fnv64_t)0x100000001b3ULL) +#else /* HAVE_64BIT_LONG_LONG */ +#define FNV_64_PRIME_LOW ((unsigned long)0x1b3) /* lower bits of FNV prime */ +#define FNV_64_PRIME_SHIFT (8) /* top FNV prime shift above 2^32 */ +#endif /* HAVE_64BIT_LONG_LONG */ + + +/* + * fnv_64a_buf - perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer + * + * input: + * buf - start of buffer to hash + * len - length of buffer in octets + * hval - previous hash value or 0 if first call + * + * returns: + * 64 bit hash as a static hash type + * + * NOTE: To use the recommended 64 bit FNV-1a hash, use FNV1A_64_INIT as the + * hval arg on the first call to either fnv_64a_buf() or fnv_64a_str(). + */ +Fnv64_t +fnv_64a_buf(void *buf, size_t len, Fnv64_t hval) +{ + unsigned char *bp = (unsigned char *)buf; /* start of buffer */ + unsigned char *be = bp + len; /* beyond end of buffer */ + +#if defined(HAVE_64BIT_LONG_LONG) + /* + * FNV-1a hash each octet of the buffer + */ + while (bp < be) { + + /* xor the bottom with the current octet */ + hval ^= (Fnv64_t)*bp++; + + /* multiply by the 64 bit FNV magic prime mod 2^64 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_64_PRIME; +#else /* NO_FNV_GCC_OPTIMIZATION */ + hval += (hval << 1) + (hval << 4) + (hval << 5) + + (hval << 7) + (hval << 8) + (hval << 40); +#endif /* NO_FNV_GCC_OPTIMIZATION */ + } + +#else /* HAVE_64BIT_LONG_LONG */ + + unsigned long val[4]; /* hash value in base 2^16 */ + unsigned long tmp[4]; /* tmp 64 bit value */ + + /* + * Convert Fnv64_t hval into a base 2^16 array + */ + val[0] = hval.w32[0]; + val[1] = (val[0] >> 16); + val[0] &= 0xffff; + val[2] = hval.w32[1]; + val[3] = (val[2] >> 16); + val[2] &= 0xffff; + + /* + * FNV-1a hash each octet of the buffer + */ + while (bp < be) { + + /* xor the bottom with the current octet */ + val[0] ^= (unsigned long)*bp++; + + /* + * multiply by the 64 bit FNV magic prime mod 2^64 + * + * Using 0x100000001b3 we have the following digits base 2^16: + * + * 0x0 0x100 0x0 0x1b3 + * + * which is the same as: + * + * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW + */ + /* multiply by the lowest order digit base 2^16 */ + tmp[0] = val[0] * FNV_64_PRIME_LOW; + tmp[1] = val[1] * FNV_64_PRIME_LOW; + tmp[2] = val[2] * FNV_64_PRIME_LOW; + tmp[3] = val[3] * FNV_64_PRIME_LOW; + /* multiply by the other non-zero digit */ + tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */ + tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */ + /* propagate carries */ + tmp[1] += (tmp[0] >> 16); + val[0] = tmp[0] & 0xffff; + tmp[2] += (tmp[1] >> 16); + val[1] = tmp[1] & 0xffff; + val[3] = tmp[3] + (tmp[2] >> 16); + val[2] = tmp[2] & 0xffff; + /* + * Doing a val[3] &= 0xffff; is not really needed since it simply + * removes multiples of 2^64. We can discard these excess bits + * outside of the loop when we convert to Fnv64_t. + */ + } + + /* + * Convert base 2^16 array back into an Fnv64_t + */ + hval.w32[1] = ((val[3]<<16) | val[2]); + hval.w32[0] = ((val[1]<<16) | val[0]); + +#endif /* HAVE_64BIT_LONG_LONG */ + + /* return our new hash value */ + return hval; +} + + +/* + * fnv_64a_str - perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer + * + * input: + * buf - start of buffer to hash + * hval - previous hash value or 0 if first call + * + * returns: + * 64 bit hash as a static hash type + * + * NOTE: To use the recommended 64 bit FNV-1a hash, use FNV1A_64_INIT as the + * hval arg on the first call to either fnv_64a_buf() or fnv_64a_str(). + */ +Fnv64_t +fnv_64a_str(char *str, Fnv64_t hval) +{ + unsigned char *s = (unsigned char *)str; /* unsigned string */ + +#if defined(HAVE_64BIT_LONG_LONG) + + /* + * FNV-1a hash each octet of the string + */ + while (*s) { + + /* xor the bottom with the current octet */ + hval ^= (Fnv64_t)*s++; + + /* multiply by the 64 bit FNV magic prime mod 2^64 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_64_PRIME; +#else /* NO_FNV_GCC_OPTIMIZATION */ + hval += (hval << 1) + (hval << 4) + (hval << 5) + + (hval << 7) + (hval << 8) + (hval << 40); +#endif /* NO_FNV_GCC_OPTIMIZATION */ + } + +#else /* !HAVE_64BIT_LONG_LONG */ + + unsigned long val[4]; /* hash value in base 2^16 */ + unsigned long tmp[4]; /* tmp 64 bit value */ + + /* + * Convert Fnv64_t hval into a base 2^16 array + */ + val[0] = hval.w32[0]; + val[1] = (val[0] >> 16); + val[0] &= 0xffff; + val[2] = hval.w32[1]; + val[3] = (val[2] >> 16); + val[2] &= 0xffff; + + /* + * FNV-1a hash each octet of the string + */ + while (*s) { + + /* xor the bottom with the current octet */ + + /* + * multiply by the 64 bit FNV magic prime mod 2^64 + * + * Using 1099511628211, we have the following digits base 2^16: + * + * 0x0 0x100 0x0 0x1b3 + * + * which is the same as: + * + * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW + */ + /* multiply by the lowest order digit base 2^16 */ + tmp[0] = val[0] * FNV_64_PRIME_LOW; + tmp[1] = val[1] * FNV_64_PRIME_LOW; + tmp[2] = val[2] * FNV_64_PRIME_LOW; + tmp[3] = val[3] * FNV_64_PRIME_LOW; + /* multiply by the other non-zero digit */ + tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */ + tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */ + /* propagate carries */ + tmp[1] += (tmp[0] >> 16); + val[0] = tmp[0] & 0xffff; + tmp[2] += (tmp[1] >> 16); + val[1] = tmp[1] & 0xffff; + val[3] = tmp[3] + (tmp[2] >> 16); + val[2] = tmp[2] & 0xffff; + /* + * Doing a val[3] &= 0xffff; is not really needed since it simply + * removes multiples of 2^64. We can discard these excess bits + * outside of the loop when we convert to Fnv64_t. + */ + val[0] ^= (unsigned long)(*s++); + } + + /* + * Convert base 2^16 array back into an Fnv64_t + */ + hval.w32[1] = ((val[3]<<16) | val[2]); + hval.w32[0] = ((val[1]<<16) | val[0]); + +#endif /* !HAVE_64BIT_LONG_LONG */ + + /* return our new hash value */ + return hval; +} diff --git a/lib/fnv/have_ulong64.c b/lib/fnv/have_ulong64.c new file mode 100644 index 0000000000..5c06262388 --- /dev/null +++ b/lib/fnv/have_ulong64.c @@ -0,0 +1,58 @@ +/* + * have_ulong64 - Determine if we have a 64 bit unsigned long long + * + * usage: + * have_ulong64 > longlong.h + * + * Not all systems have a 'long long type' so this may not compile on + * your system. + * + * This prog outputs the define: + * + * HAVE_64BIT_LONG_LONG + * defined ==> we have a 64 bit unsigned long long + * undefined ==> we must simulate a 64 bit unsigned long long + */ +/* + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +/* + * have the compiler try its hand with unsigned and signed long longs + */ +#if ! defined(NO64BIT_LONG_LONG) +unsigned long long val = 1099511628211ULL; +#endif /* NO64BIT_LONG_LONG */ + +int +main(void) +{ + /* + * ensure that the length of long long val is what we expect + */ +#if defined(NO64BIT_LONG_LONG) + printf("#undef HAVE_64BIT_LONG_LONG\t/* no */\n"); +#else /* NO64BIT_LONG_LONG */ + if (val == 1099511628211ULL && sizeof(val) == 8) { + printf("#define HAVE_64BIT_LONG_LONG\t/* yes */\n"); + } +#endif /* NO64BIT_LONG_LONG */ + + /* exit(0); */ + return 0; +} diff --git a/lib/fnv/longlong.h b/lib/fnv/longlong.h new file mode 100644 index 0000000000..c8cfe48f29 --- /dev/null +++ b/lib/fnv/longlong.h @@ -0,0 +1,18 @@ +/* + * DO NOT EDIT -- generated by the Makefile + */ + +#if !defined(__LONGLONG_H__) +#define __LONGLONG_H__ + +/* do we have/want to use a long long type? */ +#define HAVE_64BIT_LONG_LONG /* yes */ + +/* + * NO64BIT_LONG_LONG undef HAVE_64BIT_LONG_LONG + */ +#if defined(NO64BIT_LONG_LONG) +#undef HAVE_64BIT_LONG_LONG +#endif /* NO64BIT_LONG_LONG */ + +#endif /* !__LONGLONG_H__ */ diff --git a/lib/fnv/qmk_fnv_type_validation.c b/lib/fnv/qmk_fnv_type_validation.c new file mode 100644 index 0000000000..e8576617ba --- /dev/null +++ b/lib/fnv/qmk_fnv_type_validation.c @@ -0,0 +1,14 @@ +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#include "fnv.h" + +// This library was originally sourced from: +// http://www.isthe.com/chongo/tech/comp/fnv/index.html +// +// Version at the time of retrieval on 2022-06-26: v5.0.3 + +_Static_assert(sizeof(long long) == 8, "long long should be 64 bits"); +_Static_assert(sizeof(unsigned long long) == 8, "unsigned long long should be 64 bits"); + +_Static_assert(sizeof(Fnv32_t) == 4, "Fnv32_t should be 32 bits"); +_Static_assert(sizeof(Fnv64_t) == 8, "Fnv64_t should be 64 bits"); diff --git a/lib/fnv/test_fnv.c b/lib/fnv/test_fnv.c new file mode 100644 index 0000000000..efec3dec1d --- /dev/null +++ b/lib/fnv/test_fnv.c @@ -0,0 +1,2237 @@ +/* + * test_fnv - FNV test suite + * + * @(#) $Revision: 5.3 $ + * @(#) $Id: test_fnv.c,v 5.3 2009/06/30 11:50:41 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/fnv/RCS/test_fnv.c,v $ + * + *** + * + * Fowler/Noll/Vo hash + * + * The basis of this hash algorithm was taken from an idea sent + * as reviewer comments to the IEEE POSIX P1003.2 committee by: + * + * Phong Vo (http://www.research.att.com/info/kpv/) + * Glenn Fowler (http://www.research.att.com/~gsf/) + * + * In a subsequent ballot round: + * + * Landon Curt Noll (http://www.isthe.com/chongo/) + * + * improved on their algorithm. Some people tried this hash + * and found that it worked rather well. In an EMail message + * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. + * + * FNV hashes are designed to be fast while maintaining a low + * collision rate. The FNV speed allows one to quickly hash lots + * of data while maintaining a reasonable collision rate. See: + * + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + * + * for more details as well as other forms of the FNV hash. + * + *** + * + * Please do not copyright this code. This code is in the public domain. + * + * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, 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. + * + * By: + * chongo <Landon Curt Noll> /\oo/\ + * http://www.isthe.com/chongo/ + * + * Share and Enjoy! :-) + */ + +#include <stdio.h> +#include "longlong.h" +#include "fnv.h" + +#define LEN(x) (sizeof(x)-1) +/* TEST macro does not include trailing NUL byte in the test vector */ +#define TEST(x) {x, LEN(x)} +/* TEST0 macro includes the trailing NUL byte in the test vector */ +#define TEST0(x) {x, sizeof(x)} +/* REPEAT500 - repeat a string 500 times */ +#define R500(x) R100(x)R100(x)R100(x)R100(x)R100(x) +#define R100(x) R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x) +#define R10(x) x x x x x x x x x x + +/* + * FNV test vectors + * + * NOTE: A NULL pointer marks beyond the end of the test vectors. + * + * NOTE: The order of the fnv_test_str[] test vectors is 1-to-1 with: + * + * struct fnv0_32_test_vector fnv0_32_vector[]; + * struct fnv1_32_test_vector fnv1_32_vector[]; + * struct fnv1a_32_test_vector fnv1a_32_vector[]; + * struct fnv0_64_test_vector fnv0_64_vector[]; + * struct fnv1_64_test_vector fnv1_64_vector[]; + * struct fnv1a_64_test_vector fnv1a_64_vector[]; + * + * IMPORTANT NOTE: + * + * If you change the fnv_test_str[] array, you need + * to also change ALL of the above fnv*_vector arrays!!! + * + * To rebuild, try: + * + * make vector.c + * + * and then fold the results into the source file. + * Of course, you better make sure that the vaules + * produced by the above command are valid, otherwise + * you will be testing against invalid vectors! + */ +struct test_vector fnv_test_str[] = { + TEST(""), + TEST("a"), + TEST("b"), + TEST("c"), + TEST("d"), + TEST("e"), + TEST("f"), + TEST("fo"), + TEST("foo"), + TEST("foob"), + TEST("fooba"), + TEST("foobar"), + TEST0(""), + TEST0("a"), + TEST0("b"), + TEST0("c"), + TEST0("d"), + TEST0("e"), + TEST0("f"), + TEST0("fo"), + TEST0("foo"), + TEST0("foob"), + TEST0("fooba"), + TEST0("foobar"), + TEST("ch"), + TEST("cho"), + TEST("chon"), + TEST("chong"), + TEST("chongo"), + TEST("chongo "), + TEST("chongo w"), + TEST("chongo wa"), + TEST("chongo was"), + TEST("chongo was "), + TEST("chongo was h"), + TEST("chongo was he"), + TEST("chongo was her"), + TEST("chongo was here"), + TEST("chongo was here!"), + TEST("chongo was here!\n"), + TEST0("ch"), + TEST0("cho"), + TEST0("chon"), + TEST0("chong"), + TEST0("chongo"), + TEST0("chongo "), + TEST0("chongo w"), + TEST0("chongo wa"), + TEST0("chongo was"), + TEST0("chongo was "), + TEST0("chongo was h"), + TEST0("chongo was he"), + TEST0("chongo was her"), + TEST0("chongo was here"), + TEST0("chongo was here!"), + TEST0("chongo was here!\n"), + TEST("cu"), + TEST("cur"), + TEST("curd"), + TEST("curds"), + TEST("curds "), + TEST("curds a"), + TEST("curds an"), + TEST("curds and"), + TEST("curds and "), + TEST("curds and w"), + TEST("curds and wh"), + TEST("curds and whe"), + TEST("curds and whey"), + TEST("curds and whey\n"), + TEST0("cu"), + TEST0("cur"), + TEST0("curd"), + TEST0("curds"), + TEST0("curds "), + TEST0("curds a"), + TEST0("curds an"), + TEST0("curds and"), + TEST0("curds and "), + TEST0("curds and w"), + TEST0("curds and wh"), + TEST0("curds and whe"), + TEST0("curds and whey"), + TEST0("curds and whey\n"), + TEST("hi"), TEST0("hi"), + TEST("hello"), TEST0("hello"), + TEST("\xff\x00\x00\x01"), TEST("\x01\x00\x00\xff"), + TEST("\xff\x00\x00\x02"), TEST("\x02\x00\x00\xff"), + TEST("\xff\x00\x00\x03"), TEST("\x03\x00\x00\xff"), + TEST("\xff\x00\x00\x04"), TEST("\x04\x00\x00\xff"), + TEST("\x40\x51\x4e\x44"), TEST("\x44\x4e\x51\x40"), + TEST("\x40\x51\x4e\x4a"), TEST("\x4a\x4e\x51\x40"), + TEST("\x40\x51\x4e\x54"), TEST("\x54\x4e\x51\x40"), + TEST("127.0.0.1"), TEST0("127.0.0.1"), + TEST("127.0.0.2"), TEST0("127.0.0.2"), + TEST("127.0.0.3"), TEST0("127.0.0.3"), + TEST("64.81.78.68"), TEST0("64.81.78.68"), + TEST("64.81.78.74"), TEST0("64.81.78.74"), + TEST("64.81.78.84"), TEST0("64.81.78.84"), + TEST("feedface"), TEST0("feedface"), + TEST("feedfacedaffdeed"), TEST0("feedfacedaffdeed"), + TEST("feedfacedeadbeef"), TEST0("feedfacedeadbeef"), + TEST("line 1\nline 2\nline 3"), + TEST("chongo <Landon Curt Noll> /\\../\\"), + TEST0("chongo <Landon Curt Noll> /\\../\\"), + TEST("chongo (Landon Curt Noll) /\\../\\"), + TEST0("chongo (Landon Curt Noll) /\\../\\"), + TEST("http://antwrp.gsfc.nasa.gov/apod/astropix.html"), + TEST("http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash"), + TEST("http://epod.usra.edu/"), + TEST("http://exoplanet.eu/"), + TEST("http://hvo.wr.usgs.gov/cam3/"), + TEST("http://hvo.wr.usgs.gov/cams/HMcam/"), + TEST("http://hvo.wr.usgs.gov/kilauea/update/deformation.html"), + TEST("http://hvo.wr.usgs.gov/kilauea/update/images.html"), + TEST("http://hvo.wr.usgs.gov/kilauea/update/maps.html"), + TEST("http://hvo.wr.usgs.gov/volcanowatch/current_issue.html"), + TEST("http://neo.jpl.nasa.gov/risk/"), + TEST("http://norvig.com/21-days.html"), + TEST("http://primes.utm.edu/curios/home.php"), + TEST("http://slashdot.org/"), + TEST("http://tux.wr.usgs.gov/Maps/155.25-19.5.html"), + TEST("http://volcano.wr.usgs.gov/kilaueastatus.php"), + TEST("http://www.avo.alaska.edu/activity/Redoubt.php"), + TEST("http://www.dilbert.com/fast/"), + TEST("http://www.fourmilab.ch/gravitation/orbits/"), + TEST("http://www.fpoa.net/"), + TEST("http://www.ioccc.org/index.html"), + TEST("http://www.isthe.com/cgi-bin/number.cgi"), + TEST("http://www.isthe.com/chongo/bio.html"), + TEST("http://www.isthe.com/chongo/index.html"), + TEST("http://www.isthe.com/chongo/src/calc/lucas-calc"), + TEST("http://www.isthe.com/chongo/tech/astro/venus2004.html"), + TEST("http://www.isthe.com/chongo/tech/astro/vita.html"), + TEST("http://www.isthe.com/chongo/tech/comp/c/expert.html"), + TEST("http://www.isthe.com/chongo/tech/comp/calc/index.html"), + TEST("http://www.isthe.com/chongo/tech/comp/fnv/index.html"), + TEST("http://www.isthe.com/chongo/tech/math/number/howhigh.html"), + TEST("http://www.isthe.com/chongo/tech/math/number/number.html"), + TEST("http://www.isthe.com/chongo/tech/math/prime/mersenne.html"), + TEST("http://www.isthe.com/chongo/tech/math/prime/mersenne.html#largest"), + TEST("http://www.lavarnd.org/cgi-bin/corpspeak.cgi"), + TEST("http://www.lavarnd.org/cgi-bin/haiku.cgi"), + TEST("http://www.lavarnd.org/cgi-bin/rand-none.cgi"), + TEST("http://www.lavarnd.org/cgi-bin/randdist.cgi"), + TEST("http://www.lavarnd.org/index.html"), + TEST("http://www.lavarnd.org/what/nist-test.html"), + TEST("http://www.macosxhints.com/"), + TEST("http://www.mellis.com/"), + TEST("http://www.nature.nps.gov/air/webcams/parks/havoso2alert/havoalert.cfm"), + TEST("http://www.nature.nps.gov/air/webcams/parks/havoso2alert/timelines_24.cfm"), + TEST("http://www.paulnoll.com/"), + TEST("http://www.pepysdiary.com/"), + TEST("http://www.sciencenews.org/index/home/activity/view"), + TEST("http://www.skyandtelescope.com/"), + TEST("http://www.sput.nl/~rob/sirius.html"), + TEST("http://www.systemexperts.com/"), + TEST("http://www.tq-international.com/phpBB3/index.php"), + TEST("http://www.travelquesttours.com/index.htm"), + TEST("http://www.wunderground.com/global/stations/89606.html"), + TEST(R10("21701")), + TEST(R10("M21701")), + TEST(R10("2^21701-1")), + TEST(R10("\x54\xc5")), + TEST(R10("\xc5\x54")), + TEST(R10("23209")), + TEST(R10("M23209")), + TEST(R10("2^23209-1")), + TEST(R10("\x5a\xa9")), + TEST(R10("\xa9\x5a")), + TEST(R10("391581216093")), + TEST(R10("391581*2^216093-1")), + TEST(R10("\x05\xf9\x9d\x03\x4c\x81")), + TEST(R10("FEDCBA9876543210")), + TEST(R10("\xfe\xdc\xba\x98\x76\x54\x32\x10")), + TEST(R10("EFCDAB8967452301")), + TEST(R10("\xef\xcd\xab\x89\x67\x45\x23\x01")), + TEST(R10("0123456789ABCDEF")), + TEST(R10("\x01\x23\x45\x67\x89\xab\xcd\xef")), + TEST(R10("1032547698BADCFE")), + TEST(R10("\x10\x32\x54\x76\x98\xba\xdc\xfe")), + TEST(R500("\x00")), + TEST(R500("\x07")), + TEST(R500("~")), + TEST(R500("\x7f")), + {NULL, 0} /* MUST BE LAST */ +}; + + +/* + * insert the contents of vector.c below + * + * make vector.c + * :r vector.c + */ +/* start of output generated by make vector.c */ + +/* FNV-0 32 bit test vectors */ +struct fnv0_32_test_vector fnv0_32_vector[] = { + { &fnv_test_str[0], (Fnv32_t) 0x00000000UL }, + { &fnv_test_str[1], (Fnv32_t) 0x00000061UL }, + { &fnv_test_str[2], (Fnv32_t) 0x00000062UL }, + { &fnv_test_str[3], (Fnv32_t) 0x00000063UL }, + { &fnv_test_str[4], (Fnv32_t) 0x00000064UL }, + { &fnv_test_str[5], (Fnv32_t) 0x00000065UL }, + { &fnv_test_str[6], (Fnv32_t) 0x00000066UL }, + { &fnv_test_str[7], (Fnv32_t) 0x6600a0fdUL }, + { &fnv_test_str[8], (Fnv32_t) 0x8ffd6e28UL }, + { &fnv_test_str[9], (Fnv32_t) 0xd3f4689aUL }, + { &fnv_test_str[10], (Fnv32_t) 0x43c0aa0fUL }, + { &fnv_test_str[11], (Fnv32_t) 0xb74bb5efUL }, + { &fnv_test_str[12], (Fnv32_t) 0x00000000UL }, + { &fnv_test_str[13], (Fnv32_t) 0x610098b3UL }, + { &fnv_test_str[14], (Fnv32_t) 0x62009a46UL }, + { &fnv_test_str[15], (Fnv32_t) 0x63009bd9UL }, + { &fnv_test_str[16], (Fnv32_t) 0x64009d6cUL }, + { &fnv_test_str[17], (Fnv32_t) 0x65009effUL }, + { &fnv_test_str[18], (Fnv32_t) 0x6600a092UL }, + { &fnv_test_str[19], (Fnv32_t) 0x8ffd6e47UL }, + { &fnv_test_str[20], (Fnv32_t) 0xd3f468f8UL }, + { &fnv_test_str[21], (Fnv32_t) 0x43c0aa6eUL }, + { &fnv_test_str[22], (Fnv32_t) 0xb74bb59dUL }, + { &fnv_test_str[23], (Fnv32_t) 0x7b2f673dUL }, + { &fnv_test_str[24], (Fnv32_t) 0x63009bb1UL }, + { &fnv_test_str[25], (Fnv32_t) 0x8af517ccUL }, + { &fnv_test_str[26], (Fnv32_t) 0x8bd4764aUL }, + { &fnv_test_str[27], (Fnv32_t) 0x69763619UL }, + { &fnv_test_str[28], (Fnv32_t) 0x1e172934UL }, + { &fnv_test_str[29], (Fnv32_t) 0x9275dcfcUL }, + { &fnv_test_str[30], (Fnv32_t) 0x8b8ae0c3UL }, + { &fnv_test_str[31], (Fnv32_t) 0x6e9fd298UL }, + { &fnv_test_str[32], (Fnv32_t) 0xbd98853bUL }, + { &fnv_test_str[33], (Fnv32_t) 0xb219bbc1UL }, + { &fnv_test_str[34], (Fnv32_t) 0x1f8290bbUL }, + { &fnv_test_str[35], (Fnv32_t) 0x5589d604UL }, + { &fnv_test_str[36], (Fnv32_t) 0xabfbe83eUL }, + { &fnv_test_str[37], (Fnv32_t) 0xfb8e99ffUL }, + { &fnv_test_str[38], (Fnv32_t) 0x007c6c4cUL }, + { &fnv_test_str[39], (Fnv32_t) 0x0fde7baeUL }, + { &fnv_test_str[40], (Fnv32_t) 0x8af517a3UL }, + { &fnv_test_str[41], (Fnv32_t) 0x8bd47624UL }, + { &fnv_test_str[42], (Fnv32_t) 0x6976367eUL }, + { &fnv_test_str[43], (Fnv32_t) 0x1e17295bUL }, + { &fnv_test_str[44], (Fnv32_t) 0x9275dcdcUL }, + { &fnv_test_str[45], (Fnv32_t) 0x8b8ae0b4UL }, + { &fnv_test_str[46], (Fnv32_t) 0x6e9fd2f9UL }, + { &fnv_test_str[47], (Fnv32_t) 0xbd988548UL }, + { &fnv_test_str[48], (Fnv32_t) 0xb219bbe1UL }, + { &fnv_test_str[49], (Fnv32_t) 0x1f8290d3UL }, + { &fnv_test_str[50], (Fnv32_t) 0x5589d661UL }, + { &fnv_test_str[51], (Fnv32_t) 0xabfbe84cUL }, + { &fnv_test_str[52], (Fnv32_t) 0xfb8e999aUL }, + { &fnv_test_str[53], (Fnv32_t) 0x007c6c6dUL }, + { &fnv_test_str[54], (Fnv32_t) 0x0fde7ba4UL }, + { &fnv_test_str[55], (Fnv32_t) 0xa93cb2eaUL }, + { &fnv_test_str[56], (Fnv32_t) 0x63009bacUL }, + { &fnv_test_str[57], (Fnv32_t) 0x85f50fb6UL }, + { &fnv_test_str[58], (Fnv32_t) 0x96c7bbe6UL }, + { &fnv_test_str[59], (Fnv32_t) 0x426ccb61UL }, + { &fnv_test_str[60], (Fnv32_t) 0xf2442993UL }, + { &fnv_test_str[61], (Fnv32_t) 0xf44d7208UL }, + { &fnv_test_str[62], (Fnv32_t) 0x9dea82f6UL }, + { &fnv_test_str[63], (Fnv32_t) 0x8e2c2926UL }, + { &fnv_test_str[64], (Fnv32_t) 0xf584c6f2UL }, + { &fnv_test_str[65], (Fnv32_t) 0x72052e81UL }, + { &fnv_test_str[66], (Fnv32_t) 0xff28357bUL }, + { &fnv_test_str[67], (Fnv32_t) 0x274c30c4UL }, + { &fnv_test_str[68], (Fnv32_t) 0xa0f0c4f5UL }, + { &fnv_test_str[69], (Fnv32_t) 0x50060da5UL }, + { &fnv_test_str[70], (Fnv32_t) 0x85f50fc4UL }, + { &fnv_test_str[71], (Fnv32_t) 0x96c7bb82UL }, + { &fnv_test_str[72], (Fnv32_t) 0x426ccb12UL }, + { &fnv_test_str[73], (Fnv32_t) 0xf24429b3UL }, + { &fnv_test_str[74], (Fnv32_t) 0xf44d7269UL }, + { &fnv_test_str[75], (Fnv32_t) 0x9dea8298UL }, + { &fnv_test_str[76], (Fnv32_t) 0x8e2c2942UL }, + { &fnv_test_str[77], (Fnv32_t) 0xf584c6d2UL }, + { &fnv_test_str[78], (Fnv32_t) 0x72052ef6UL }, + { &fnv_test_str[79], (Fnv32_t) 0xff283513UL }, + { &fnv_test_str[80], (Fnv32_t) 0x274c30a1UL }, + { &fnv_test_str[81], (Fnv32_t) 0xa0f0c48cUL }, + { &fnv_test_str[82], (Fnv32_t) 0x50060dafUL }, + { &fnv_test_str[83], (Fnv32_t) 0x9e877abfUL }, + { &fnv_test_str[84], (Fnv32_t) 0x6800a3d1UL }, + { &fnv_test_str[85], (Fnv32_t) 0x8a01e203UL }, + { &fnv_test_str[86], (Fnv32_t) 0xec6d6be8UL }, + { &fnv_test_str[87], (Fnv32_t) 0x1840de38UL }, + { &fnv_test_str[88], (Fnv32_t) 0xa7cc97b4UL }, + { &fnv_test_str[89], (Fnv32_t) 0x3ee6b3b4UL }, + { &fnv_test_str[90], (Fnv32_t) 0xa7cc97b7UL }, + { &fnv_test_str[91], (Fnv32_t) 0x7dcd6669UL }, + { &fnv_test_str[92], (Fnv32_t) 0xa7cc97b6UL }, + { &fnv_test_str[93], (Fnv32_t) 0xbcb4191eUL }, + { &fnv_test_str[94], (Fnv32_t) 0xa7cc97b1UL }, + { &fnv_test_str[95], (Fnv32_t) 0xfb9acdd3UL }, + { &fnv_test_str[96], (Fnv32_t) 0x89380433UL }, + { &fnv_test_str[97], (Fnv32_t) 0x8acd2855UL }, + { &fnv_test_str[98], (Fnv32_t) 0x8938043dUL }, + { &fnv_test_str[99], (Fnv32_t) 0xcaeed493UL }, + { &fnv_test_str[100], (Fnv32_t) 0x89380423UL }, + { &fnv_test_str[101], (Fnv32_t) 0x59382a25UL }, + { &fnv_test_str[102], (Fnv32_t) 0x567f75d7UL }, + { &fnv_test_str[103], (Fnv32_t) 0x01a68175UL }, + { &fnv_test_str[104], (Fnv32_t) 0x567f75d4UL }, + { &fnv_test_str[105], (Fnv32_t) 0xfea67cbcUL }, + { &fnv_test_str[106], (Fnv32_t) 0x567f75d5UL }, + { &fnv_test_str[107], (Fnv32_t) 0xffa67e4fUL }, + { &fnv_test_str[108], (Fnv32_t) 0xd131b668UL }, + { &fnv_test_str[109], (Fnv32_t) 0xb94225b8UL }, + { &fnv_test_str[110], (Fnv32_t) 0xd231b7d7UL }, + { &fnv_test_str[111], (Fnv32_t) 0xbb446775UL }, + { &fnv_test_str[112], (Fnv32_t) 0xdf31cc6eUL }, + { &fnv_test_str[113], (Fnv32_t) 0xc964d12aUL }, + { &fnv_test_str[114], (Fnv32_t) 0x23af8f9fUL }, + { &fnv_test_str[115], (Fnv32_t) 0xcc5f174dUL }, + { &fnv_test_str[116], (Fnv32_t) 0x96b29b8cUL }, + { &fnv_test_str[117], (Fnv32_t) 0xc72add64UL }, + { &fnv_test_str[118], (Fnv32_t) 0x528fb7efUL }, + { &fnv_test_str[119], (Fnv32_t) 0xe73e8d3dUL }, + { &fnv_test_str[120], (Fnv32_t) 0x876386feUL }, + { &fnv_test_str[121], (Fnv32_t) 0x811c9dc5UL }, + { &fnv_test_str[122], (Fnv32_t) 0x050c5d1fUL }, + { &fnv_test_str[123], (Fnv32_t) 0x14bf7238UL }, + { &fnv_test_str[124], (Fnv32_t) 0xe160ce28UL }, + { &fnv_test_str[125], (Fnv32_t) 0x89dc5a75UL }, + { &fnv_test_str[126], (Fnv32_t) 0xd89b69a0UL }, + { &fnv_test_str[127], (Fnv32_t) 0x94471a88UL }, + { &fnv_test_str[128], (Fnv32_t) 0xe78db65fUL }, + { &fnv_test_str[129], (Fnv32_t) 0x0c3009a2UL }, + { &fnv_test_str[130], (Fnv32_t) 0x122dff03UL }, + { &fnv_test_str[131], (Fnv32_t) 0xb4cd8875UL }, + { &fnv_test_str[132], (Fnv32_t) 0xf4dba725UL }, + { &fnv_test_str[133], (Fnv32_t) 0x41a16560UL }, + { &fnv_test_str[134], (Fnv32_t) 0x9c0f941fUL }, + { &fnv_test_str[135], (Fnv32_t) 0x451a5348UL }, + { &fnv_test_str[136], (Fnv32_t) 0x3f1d1d89UL }, + { &fnv_test_str[137], (Fnv32_t) 0x1b91b57aUL }, + { &fnv_test_str[138], (Fnv32_t) 0x3e99b577UL }, + { &fnv_test_str[139], (Fnv32_t) 0x4c9de07aUL }, + { &fnv_test_str[140], (Fnv32_t) 0x1ddf7572UL }, + { &fnv_test_str[141], (Fnv32_t) 0x64e81976UL }, + { &fnv_test_str[142], (Fnv32_t) 0x1106a888UL }, + { &fnv_test_str[143], (Fnv32_t) 0xa498d8e5UL }, + { &fnv_test_str[144], (Fnv32_t) 0x3c03d2e3UL }, + { &fnv_test_str[145], (Fnv32_t) 0x26568b28UL }, + { &fnv_test_str[146], (Fnv32_t) 0x70d7fb42UL }, + { &fnv_test_str[147], (Fnv32_t) 0xd3ae1d22UL }, + { &fnv_test_str[148], (Fnv32_t) 0xac8ea5f4UL }, + { &fnv_test_str[149], (Fnv32_t) 0x4d0abd60UL }, + { &fnv_test_str[150], (Fnv32_t) 0x48f5e086UL }, + { &fnv_test_str[151], (Fnv32_t) 0xa8f6241bUL }, + { &fnv_test_str[152], (Fnv32_t) 0x572f864fUL }, + { &fnv_test_str[153], (Fnv32_t) 0xa5340803UL }, + { &fnv_test_str[154], (Fnv32_t) 0x22881aa8UL }, + { &fnv_test_str[155], (Fnv32_t) 0xc2e2f5a2UL }, + { &fnv_test_str[156], (Fnv32_t) 0xebf5aec7UL }, + { &fnv_test_str[157], (Fnv32_t) 0x3cdbfb85UL }, + { &fnv_test_str[158], (Fnv32_t) 0xbb859704UL }, + { &fnv_test_str[159], (Fnv32_t) 0xc956fe11UL }, + { &fnv_test_str[160], (Fnv32_t) 0x8f11a7c9UL }, + { &fnv_test_str[161], (Fnv32_t) 0x36c48ecfUL }, + { &fnv_test_str[162], (Fnv32_t) 0x24bfa27eUL }, + { &fnv_test_str[163], (Fnv32_t) 0xf2596ad1UL }, + { &fnv_test_str[164], (Fnv32_t) 0xf14a9b45UL }, + { &fnv_test_str[165], (Fnv32_t) 0x7d45835aUL }, + { &fnv_test_str[166], (Fnv32_t) 0x6e49334dUL }, + { &fnv_test_str[167], (Fnv32_t) 0x71767337UL }, + { &fnv_test_str[168], (Fnv32_t) 0x858a1a8aUL }, + { &fnv_test_str[169], (Fnv32_t) 0x16e75ac2UL }, + { &fnv_test_str[170], (Fnv32_t) 0x409f99dfUL }, + { &fnv_test_str[171], (Fnv32_t) 0x6d6652ddUL }, + { &fnv_test_str[172], (Fnv32_t) 0x2761a9ffUL }, + { &fnv_test_str[173], (Fnv32_t) 0x41f0d616UL }, + { &fnv_test_str[174], (Fnv32_t) 0x0e2d0d0fUL }, + { &fnv_test_str[175], (Fnv32_t) 0x06adc8fdUL }, + { &fnv_test_str[176], (Fnv32_t) 0x60e0d4b9UL }, + { &fnv_test_str[177], (Fnv32_t) 0x5ddc79d3UL }, + { &fnv_test_str[178], (Fnv32_t) 0x1e6d0b46UL }, + { &fnv_test_str[179], (Fnv32_t) 0x1d1514d8UL }, + { &fnv_test_str[180], (Fnv32_t) 0xb1903a4eUL }, + { &fnv_test_str[181], (Fnv32_t) 0x8200c318UL }, + { &fnv_test_str[182], (Fnv32_t) 0x15e22888UL }, + { &fnv_test_str[183], (Fnv32_t) 0x57591760UL }, + { &fnv_test_str[184], (Fnv32_t) 0x02462efcUL }, + { &fnv_test_str[185], (Fnv32_t) 0x7651ec44UL }, + { &fnv_test_str[186], (Fnv32_t) 0x7c24e9d4UL }, + { &fnv_test_str[187], (Fnv32_t) 0x1952a034UL }, + { &fnv_test_str[188], (Fnv32_t) 0xd4c46864UL }, + { &fnv_test_str[189], (Fnv32_t) 0xcb57cde0UL }, + { &fnv_test_str[190], (Fnv32_t) 0x71136a70UL }, + { &fnv_test_str[191], (Fnv32_t) 0x0618fb40UL }, + { &fnv_test_str[192], (Fnv32_t) 0x69a24fc0UL }, + { &fnv_test_str[193], (Fnv32_t) 0x6a9be510UL }, + { &fnv_test_str[194], (Fnv32_t) 0xe0477040UL }, + { &fnv_test_str[195], (Fnv32_t) 0x85aa94b0UL }, + { &fnv_test_str[196], (Fnv32_t) 0xc6d76240UL }, + { &fnv_test_str[197], (Fnv32_t) 0xa9f09e40UL }, + { &fnv_test_str[198], (Fnv32_t) 0xa0291540UL }, + { &fnv_test_str[199], (Fnv32_t) 0x00000000UL }, + { &fnv_test_str[200], (Fnv32_t) 0x2e672aa4UL }, + { &fnv_test_str[201], (Fnv32_t) 0x84b1aa48UL }, + { &fnv_test_str[202], (Fnv32_t) 0xfc24ba24UL }, + { NULL, 0 } +}; + +/* FNV-1 32 bit test vectors */ +struct fnv1_32_test_vector fnv1_32_vector[] = { + { &fnv_test_str[0], (Fnv32_t) 0x811c9dc5UL }, + { &fnv_test_str[1], (Fnv32_t) 0x050c5d7eUL }, + { &fnv_test_str[2], (Fnv32_t) 0x050c5d7dUL }, + { &fnv_test_str[3], (Fnv32_t) 0x050c5d7cUL }, + { &fnv_test_str[4], (Fnv32_t) 0x050c5d7bUL }, + { &fnv_test_str[5], (Fnv32_t) 0x050c5d7aUL }, + { &fnv_test_str[6], (Fnv32_t) 0x050c5d79UL }, + { &fnv_test_str[7], (Fnv32_t) 0x6b772514UL }, + { &fnv_test_str[8], (Fnv32_t) 0x408f5e13UL }, + { &fnv_test_str[9], (Fnv32_t) 0xb4b1178bUL }, + { &fnv_test_str[10], (Fnv32_t) 0xfdc80fb0UL }, + { &fnv_test_str[11], (Fnv32_t) 0x31f0b262UL }, + { &fnv_test_str[12], (Fnv32_t) 0x050c5d1fUL }, + { &fnv_test_str[13], (Fnv32_t) 0x70772d5aUL }, + { &fnv_test_str[14], (Fnv32_t) 0x6f772bc7UL }, + { &fnv_test_str[15], (Fnv32_t) 0x6e772a34UL }, + { &fnv_test_str[16], (Fnv32_t) 0x6d7728a1UL }, + { &fnv_test_str[17], (Fnv32_t) 0x6c77270eUL }, + { &fnv_test_str[18], (Fnv32_t) 0x6b77257bUL }, + { &fnv_test_str[19], (Fnv32_t) 0x408f5e7cUL }, + { &fnv_test_str[20], (Fnv32_t) 0xb4b117e9UL }, + { &fnv_test_str[21], (Fnv32_t) 0xfdc80fd1UL }, + { &fnv_test_str[22], (Fnv32_t) 0x31f0b210UL }, + { &fnv_test_str[23], (Fnv32_t) 0xffe8d046UL }, + { &fnv_test_str[24], (Fnv32_t) 0x6e772a5cUL }, + { &fnv_test_str[25], (Fnv32_t) 0x4197aebbUL }, + { &fnv_test_str[26], (Fnv32_t) 0xfcc8100fUL }, + { &fnv_test_str[27], (Fnv32_t) 0xfdf147faUL }, + { &fnv_test_str[28], (Fnv32_t) 0xbcd44ee1UL }, + { &fnv_test_str[29], (Fnv32_t) 0x23382c13UL }, + { &fnv_test_str[30], (Fnv32_t) 0x846d619eUL }, + { &fnv_test_str[31], (Fnv32_t) 0x1630abdbUL }, + { &fnv_test_str[32], (Fnv32_t) 0xc99e89b2UL }, + { &fnv_test_str[33], (Fnv32_t) 0x1692c316UL }, + { &fnv_test_str[34], (Fnv32_t) 0x9f091bcaUL }, + { &fnv_test_str[35], (Fnv32_t) 0x2556be9bUL }, + { &fnv_test_str[36], (Fnv32_t) 0x628e0e73UL }, + { &fnv_test_str[37], (Fnv32_t) 0x98a0bf6cUL }, + { &fnv_test_str[38], (Fnv32_t) 0xb10d5725UL }, + { &fnv_test_str[39], (Fnv32_t) 0xdd002f35UL }, + { &fnv_test_str[40], (Fnv32_t) 0x4197aed4UL }, + { &fnv_test_str[41], (Fnv32_t) 0xfcc81061UL }, + { &fnv_test_str[42], (Fnv32_t) 0xfdf1479dUL }, + { &fnv_test_str[43], (Fnv32_t) 0xbcd44e8eUL }, + { &fnv_test_str[44], (Fnv32_t) 0x23382c33UL }, + { &fnv_test_str[45], (Fnv32_t) 0x846d61e9UL }, + { &fnv_test_str[46], (Fnv32_t) 0x1630abbaUL }, + { &fnv_test_str[47], (Fnv32_t) 0xc99e89c1UL }, + { &fnv_test_str[48], (Fnv32_t) 0x1692c336UL }, + { &fnv_test_str[49], (Fnv32_t) 0x9f091ba2UL }, + { &fnv_test_str[50], (Fnv32_t) 0x2556befeUL }, + { &fnv_test_str[51], (Fnv32_t) 0x628e0e01UL }, + { &fnv_test_str[52], (Fnv32_t) 0x98a0bf09UL }, + { &fnv_test_str[53], (Fnv32_t) 0xb10d5704UL }, + { &fnv_test_str[54], (Fnv32_t) 0xdd002f3fUL }, + { &fnv_test_str[55], (Fnv32_t) 0x1c4a506fUL }, + { &fnv_test_str[56], (Fnv32_t) 0x6e772a41UL }, + { &fnv_test_str[57], (Fnv32_t) 0x26978421UL }, + { &fnv_test_str[58], (Fnv32_t) 0xe184ff97UL }, + { &fnv_test_str[59], (Fnv32_t) 0x9b5e5ac6UL }, + { &fnv_test_str[60], (Fnv32_t) 0x5b88e592UL }, + { &fnv_test_str[61], (Fnv32_t) 0xaa8164b7UL }, + { &fnv_test_str[62], (Fnv32_t) 0x20b18c7bUL }, + { &fnv_test_str[63], (Fnv32_t) 0xf28025c5UL }, + { &fnv_test_str[64], (Fnv32_t) 0x84bb753fUL }, + { &fnv_test_str[65], (Fnv32_t) 0x3219925aUL }, + { &fnv_test_str[66], (Fnv32_t) 0x384163c6UL }, + { &fnv_test_str[67], (Fnv32_t) 0x54f010d7UL }, + { &fnv_test_str[68], (Fnv32_t) 0x8cea820cUL }, + { &fnv_test_str[69], (Fnv32_t) 0xe12ab8eeUL }, + { &fnv_test_str[70], (Fnv32_t) 0x26978453UL }, + { &fnv_test_str[71], (Fnv32_t) 0xe184fff3UL }, + { &fnv_test_str[72], (Fnv32_t) 0x9b5e5ab5UL }, + { &fnv_test_str[73], (Fnv32_t) 0x5b88e5b2UL }, + { &fnv_test_str[74], (Fnv32_t) 0xaa8164d6UL }, + { &fnv_test_str[75], (Fnv32_t) 0x20b18c15UL }, + { &fnv_test_str[76], (Fnv32_t) 0xf28025a1UL }, + { &fnv_test_str[77], (Fnv32_t) 0x84bb751fUL }, + { &fnv_test_str[78], (Fnv32_t) 0x3219922dUL }, + { &fnv_test_str[79], (Fnv32_t) 0x384163aeUL }, + { &fnv_test_str[80], (Fnv32_t) 0x54f010b2UL }, + { &fnv_test_str[81], (Fnv32_t) 0x8cea8275UL }, + { &fnv_test_str[82], (Fnv32_t) 0xe12ab8e4UL }, + { &fnv_test_str[83], (Fnv32_t) 0x64411eaaUL }, + { &fnv_test_str[84], (Fnv32_t) 0x6977223cUL }, + { &fnv_test_str[85], (Fnv32_t) 0x428ae474UL }, + { &fnv_test_str[86], (Fnv32_t) 0xb6fa7167UL }, + { &fnv_test_str[87], (Fnv32_t) 0x73408525UL }, + { &fnv_test_str[88], (Fnv32_t) 0xb78320a1UL }, + { &fnv_test_str[89], (Fnv32_t) 0x0caf4135UL }, + { &fnv_test_str[90], (Fnv32_t) 0xb78320a2UL }, + { &fnv_test_str[91], (Fnv32_t) 0xcdc88e80UL }, + { &fnv_test_str[92], (Fnv32_t) 0xb78320a3UL }, + { &fnv_test_str[93], (Fnv32_t) 0x8ee1dbcbUL }, + { &fnv_test_str[94], (Fnv32_t) 0xb78320a4UL }, + { &fnv_test_str[95], (Fnv32_t) 0x4ffb2716UL }, + { &fnv_test_str[96], (Fnv32_t) 0x860632aaUL }, + { &fnv_test_str[97], (Fnv32_t) 0xcc2c5c64UL }, + { &fnv_test_str[98], (Fnv32_t) 0x860632a4UL }, + { &fnv_test_str[99], (Fnv32_t) 0x2a7ec4a6UL }, + { &fnv_test_str[100], (Fnv32_t) 0x860632baUL }, + { &fnv_test_str[101], (Fnv32_t) 0xfefe8e14UL }, + { &fnv_test_str[102], (Fnv32_t) 0x0a3cffd8UL }, + { &fnv_test_str[103], (Fnv32_t) 0xf606c108UL }, + { &fnv_test_str[104], (Fnv32_t) 0x0a3cffdbUL }, + { &fnv_test_str[105], (Fnv32_t) 0xf906c5c1UL }, + { &fnv_test_str[106], (Fnv32_t) 0x0a3cffdaUL }, + { &fnv_test_str[107], (Fnv32_t) 0xf806c42eUL }, + { &fnv_test_str[108], (Fnv32_t) 0xc07167d7UL }, + { &fnv_test_str[109], (Fnv32_t) 0xc9867775UL }, + { &fnv_test_str[110], (Fnv32_t) 0xbf716668UL }, + { &fnv_test_str[111], (Fnv32_t) 0xc78435b8UL }, + { &fnv_test_str[112], (Fnv32_t) 0xc6717155UL }, + { &fnv_test_str[113], (Fnv32_t) 0xb99568cfUL }, + { &fnv_test_str[114], (Fnv32_t) 0x7662e0d6UL }, + { &fnv_test_str[115], (Fnv32_t) 0x33a7f0e2UL }, + { &fnv_test_str[116], (Fnv32_t) 0xc2732f95UL }, + { &fnv_test_str[117], (Fnv32_t) 0xb053e78fUL }, + { &fnv_test_str[118], (Fnv32_t) 0x3a19c02aUL }, + { &fnv_test_str[119], (Fnv32_t) 0xa089821eUL }, + { &fnv_test_str[120], (Fnv32_t) 0x31ae8f83UL }, + { &fnv_test_str[121], (Fnv32_t) 0x995fa9c4UL }, + { &fnv_test_str[122], (Fnv32_t) 0x35983f8cUL }, + { &fnv_test_str[123], (Fnv32_t) 0x5036a251UL }, + { &fnv_test_str[124], (Fnv32_t) 0x97018583UL }, + { &fnv_test_str[125], (Fnv32_t) 0xb4448d60UL }, + { &fnv_test_str[126], (Fnv32_t) 0x025dfe59UL }, + { &fnv_test_str[127], (Fnv32_t) 0xc5eab3afUL }, + { &fnv_test_str[128], (Fnv32_t) 0x7d21ba1eUL }, + { &fnv_test_str[129], (Fnv32_t) 0x7704cddbUL }, + { &fnv_test_str[130], (Fnv32_t) 0xd0071bfeUL }, + { &fnv_test_str[131], (Fnv32_t) 0x0ff3774cUL }, + { &fnv_test_str[132], (Fnv32_t) 0xb0fea0eaUL }, + { &fnv_test_str[133], (Fnv32_t) 0x58177303UL }, + { &fnv_test_str[134], (Fnv32_t) 0x4f599cdaUL }, + { &fnv_test_str[135], (Fnv32_t) 0x3e590a47UL }, + { &fnv_test_str[136], (Fnv32_t) 0x965595f8UL }, + { &fnv_test_str[137], (Fnv32_t) 0xc37f178dUL }, + { &fnv_test_str[138], (Fnv32_t) 0x9711dd26UL }, + { &fnv_test_str[139], (Fnv32_t) 0x23c99b7fUL }, + { &fnv_test_str[140], (Fnv32_t) 0x6e568b17UL }, + { &fnv_test_str[141], (Fnv32_t) 0x43f0245bUL }, + { &fnv_test_str[142], (Fnv32_t) 0xbcb7a001UL }, + { &fnv_test_str[143], (Fnv32_t) 0x12e6dffeUL }, + { &fnv_test_str[144], (Fnv32_t) 0x0792f2d6UL }, + { &fnv_test_str[145], (Fnv32_t) 0xb966936bUL }, + { &fnv_test_str[146], (Fnv32_t) 0x46439ac5UL }, + { &fnv_test_str[147], (Fnv32_t) 0x728d49afUL }, + { &fnv_test_str[148], (Fnv32_t) 0xd33745c9UL }, + { &fnv_test_str[149], (Fnv32_t) 0xbc382a57UL }, + { &fnv_test_str[150], (Fnv32_t) 0x4bda1d31UL }, + { &fnv_test_str[151], (Fnv32_t) 0xce35ccaeUL }, + { &fnv_test_str[152], (Fnv32_t) 0x3b6eed94UL }, + { &fnv_test_str[153], (Fnv32_t) 0x445c9c58UL }, + { &fnv_test_str[154], (Fnv32_t) 0x3db8bf9dUL }, + { &fnv_test_str[155], (Fnv32_t) 0x2dee116dUL }, + { &fnv_test_str[156], (Fnv32_t) 0xc18738daUL }, + { &fnv_test_str[157], (Fnv32_t) 0x5b156176UL }, + { &fnv_test_str[158], (Fnv32_t) 0x2aa7d593UL }, + { &fnv_test_str[159], (Fnv32_t) 0xb2409658UL }, + { &fnv_test_str[160], (Fnv32_t) 0xe1489528UL }, + { &fnv_test_str[161], (Fnv32_t) 0xfe1ee07eUL }, + { &fnv_test_str[162], (Fnv32_t) 0xe8842315UL }, + { &fnv_test_str[163], (Fnv32_t) 0x3a6a63a2UL }, + { &fnv_test_str[164], (Fnv32_t) 0x06d2c18cUL }, + { &fnv_test_str[165], (Fnv32_t) 0xf8ef7225UL }, + { &fnv_test_str[166], (Fnv32_t) 0x843d3300UL }, + { &fnv_test_str[167], (Fnv32_t) 0xbb24f7aeUL }, + { &fnv_test_str[168], (Fnv32_t) 0x878c0ec9UL }, + { &fnv_test_str[169], (Fnv32_t) 0xb557810fUL }, + { &fnv_test_str[170], (Fnv32_t) 0x57423246UL }, + { &fnv_test_str[171], (Fnv32_t) 0x87f7505eUL }, + { &fnv_test_str[172], (Fnv32_t) 0xbb809f20UL }, + { &fnv_test_str[173], (Fnv32_t) 0x8932abb5UL }, + { &fnv_test_str[174], (Fnv32_t) 0x0a9b3aa0UL }, + { &fnv_test_str[175], (Fnv32_t) 0xb8682a24UL }, + { &fnv_test_str[176], (Fnv32_t) 0xa7ac1c56UL }, + { &fnv_test_str[177], (Fnv32_t) 0x11409252UL }, + { &fnv_test_str[178], (Fnv32_t) 0xa987f517UL }, + { &fnv_test_str[179], (Fnv32_t) 0xf309e7edUL }, + { &fnv_test_str[180], (Fnv32_t) 0xc9e8f417UL }, + { &fnv_test_str[181], (Fnv32_t) 0x7f447bddUL }, + { &fnv_test_str[182], (Fnv32_t) 0xb929adc5UL }, + { &fnv_test_str[183], (Fnv32_t) 0x57022879UL }, + { &fnv_test_str[184], (Fnv32_t) 0xdcfd2c49UL }, + { &fnv_test_str[185], (Fnv32_t) 0x6edafff5UL }, + { &fnv_test_str[186], (Fnv32_t) 0xf04fb1f1UL }, + { &fnv_test_str[187], (Fnv32_t) 0xfb7de8b9UL }, + { &fnv_test_str[188], (Fnv32_t) 0xc5f1d7e9UL }, + { &fnv_test_str[189], (Fnv32_t) 0x32c1f439UL }, + { &fnv_test_str[190], (Fnv32_t) 0x7fd3eb7dUL }, + { &fnv_test_str[191], (Fnv32_t) 0x81597da5UL }, + { &fnv_test_str[192], (Fnv32_t) 0x05eb7a25UL }, + { &fnv_test_str[193], (Fnv32_t) 0x9c0fa1b5UL }, + { &fnv_test_str[194], (Fnv32_t) 0x53ccb1c5UL }, + { &fnv_test_str[195], (Fnv32_t) 0xfabece15UL }, + { &fnv_test_str[196], (Fnv32_t) 0x4ad745a5UL }, + { &fnv_test_str[197], (Fnv32_t) 0xe5bdc495UL }, + { &fnv_test_str[198], (Fnv32_t) 0x23b3c0a5UL }, + { &fnv_test_str[199], (Fnv32_t) 0xfa823dd5UL }, + { &fnv_test_str[200], (Fnv32_t) 0x0c6c58b9UL }, + { &fnv_test_str[201], (Fnv32_t) 0xe2dbccd5UL }, + { &fnv_test_str[202], (Fnv32_t) 0xdb7f50f9UL }, + { NULL, 0 } +}; + +/* FNV-1a 32 bit test vectors */ +struct fnv1a_32_test_vector fnv1a_32_vector[] = { + { &fnv_test_str[0], (Fnv32_t) 0x811c9dc5UL }, + { &fnv_test_str[1], (Fnv32_t) 0xe40c292cUL }, + { &fnv_test_str[2], (Fnv32_t) 0xe70c2de5UL }, + { &fnv_test_str[3], (Fnv32_t) 0xe60c2c52UL }, + { &fnv_test_str[4], (Fnv32_t) 0xe10c2473UL }, + { &fnv_test_str[5], (Fnv32_t) 0xe00c22e0UL }, + { &fnv_test_str[6], (Fnv32_t) 0xe30c2799UL }, + { &fnv_test_str[7], (Fnv32_t) 0x6222e842UL }, + { &fnv_test_str[8], (Fnv32_t) 0xa9f37ed7UL }, + { &fnv_test_str[9], (Fnv32_t) 0x3f5076efUL }, + { &fnv_test_str[10], (Fnv32_t) 0x39aaa18aUL }, + { &fnv_test_str[11], (Fnv32_t) 0xbf9cf968UL }, + { &fnv_test_str[12], (Fnv32_t) 0x050c5d1fUL }, + { &fnv_test_str[13], (Fnv32_t) 0x2b24d044UL }, + { &fnv_test_str[14], (Fnv32_t) 0x9d2c3f7fUL }, + { &fnv_test_str[15], (Fnv32_t) 0x7729c516UL }, + { &fnv_test_str[16], (Fnv32_t) 0xb91d6109UL }, + { &fnv_test_str[17], (Fnv32_t) 0x931ae6a0UL }, + { &fnv_test_str[18], (Fnv32_t) 0x052255dbUL }, + { &fnv_test_str[19], (Fnv32_t) 0xbef39fe6UL }, + { &fnv_test_str[20], (Fnv32_t) 0x6150ac75UL }, + { &fnv_test_str[21], (Fnv32_t) 0x9aab3a3dUL }, + { &fnv_test_str[22], (Fnv32_t) 0x519c4c3eUL }, + { &fnv_test_str[23], (Fnv32_t) 0x0c1c9eb8UL }, + { &fnv_test_str[24], (Fnv32_t) 0x5f299f4eUL }, + { &fnv_test_str[25], (Fnv32_t) 0xef8580f3UL }, + { &fnv_test_str[26], (Fnv32_t) 0xac297727UL }, + { &fnv_test_str[27], (Fnv32_t) 0x4546b9c0UL }, + { &fnv_test_str[28], (Fnv32_t) 0xbd564e7dUL }, + { &fnv_test_str[29], (Fnv32_t) 0x6bdd5c67UL }, + { &fnv_test_str[30], (Fnv32_t) 0xdd77ed30UL }, + { &fnv_test_str[31], (Fnv32_t) 0xf4ca9683UL }, + { &fnv_test_str[32], (Fnv32_t) 0x4aeb9bd0UL }, + { &fnv_test_str[33], (Fnv32_t) 0xe0e67ad0UL }, + { &fnv_test_str[34], (Fnv32_t) 0xc2d32fa8UL }, + { &fnv_test_str[35], (Fnv32_t) 0x7f743fb7UL }, + { &fnv_test_str[36], (Fnv32_t) 0x6900631fUL }, + { &fnv_test_str[37], (Fnv32_t) 0xc59c990eUL }, + { &fnv_test_str[38], (Fnv32_t) 0x448524fdUL }, + { &fnv_test_str[39], (Fnv32_t) 0xd49930d5UL }, + { &fnv_test_str[40], (Fnv32_t) 0x1c85c7caUL }, + { &fnv_test_str[41], (Fnv32_t) 0x0229fe89UL }, + { &fnv_test_str[42], (Fnv32_t) 0x2c469265UL }, + { &fnv_test_str[43], (Fnv32_t) 0xce566940UL }, + { &fnv_test_str[44], (Fnv32_t) 0x8bdd8ec7UL }, + { &fnv_test_str[45], (Fnv32_t) 0x34787625UL }, + { &fnv_test_str[46], (Fnv32_t) 0xd3ca6290UL }, + { &fnv_test_str[47], (Fnv32_t) 0xddeaf039UL }, + { &fnv_test_str[48], (Fnv32_t) 0xc0e64870UL }, + { &fnv_test_str[49], (Fnv32_t) 0xdad35570UL }, + { &fnv_test_str[50], (Fnv32_t) 0x5a740578UL }, + { &fnv_test_str[51], (Fnv32_t) 0x5b004d15UL }, + { &fnv_test_str[52], (Fnv32_t) 0x6a9c09cdUL }, + { &fnv_test_str[53], (Fnv32_t) 0x2384f10aUL }, + { &fnv_test_str[54], (Fnv32_t) 0xda993a47UL }, + { &fnv_test_str[55], (Fnv32_t) 0x8227df4fUL }, + { &fnv_test_str[56], (Fnv32_t) 0x4c298165UL }, + { &fnv_test_str[57], (Fnv32_t) 0xfc563735UL }, + { &fnv_test_str[58], (Fnv32_t) 0x8cb91483UL }, + { &fnv_test_str[59], (Fnv32_t) 0x775bf5d0UL }, + { &fnv_test_str[60], (Fnv32_t) 0xd5c428d0UL }, + { &fnv_test_str[61], (Fnv32_t) 0x34cc0ea3UL }, + { &fnv_test_str[62], (Fnv32_t) 0xea3b4cb7UL }, + { &fnv_test_str[63], (Fnv32_t) 0x8e59f029UL }, + { &fnv_test_str[64], (Fnv32_t) 0x2094de2bUL }, + { &fnv_test_str[65], (Fnv32_t) 0xa65a0ad4UL }, + { &fnv_test_str[66], (Fnv32_t) 0x9bbee5f4UL }, + { &fnv_test_str[67], (Fnv32_t) 0xbe836343UL }, + { &fnv_test_str[68], (Fnv32_t) 0x22d5344eUL }, + { &fnv_test_str[69], (Fnv32_t) 0x19a1470cUL }, + { &fnv_test_str[70], (Fnv32_t) 0x4a56b1ffUL }, + { &fnv_test_str[71], (Fnv32_t) 0x70b8e86fUL }, + { &fnv_test_str[72], (Fnv32_t) 0x0a5b4a39UL }, + { &fnv_test_str[73], (Fnv32_t) 0xb5c3f670UL }, + { &fnv_test_str[74], (Fnv32_t) 0x53cc3f70UL }, + { &fnv_test_str[75], (Fnv32_t) 0xc03b0a99UL }, + { &fnv_test_str[76], (Fnv32_t) 0x7259c415UL }, + { &fnv_test_str[77], (Fnv32_t) 0x4095108bUL }, + { &fnv_test_str[78], (Fnv32_t) 0x7559bdb1UL }, + { &fnv_test_str[79], (Fnv32_t) 0xb3bf0bbcUL }, + { &fnv_test_str[80], (Fnv32_t) 0x2183ff1cUL }, + { &fnv_test_str[81], (Fnv32_t) 0x2bd54279UL }, + { &fnv_test_str[82], (Fnv32_t) 0x23a156caUL }, + { &fnv_test_str[83], (Fnv32_t) 0x64e2d7e4UL }, + { &fnv_test_str[84], (Fnv32_t) 0x683af69aUL }, + { &fnv_test_str[85], (Fnv32_t) 0xaed2346eUL }, + { &fnv_test_str[86], (Fnv32_t) 0x4f9f2cabUL }, + { &fnv_test_str[87], (Fnv32_t) 0x02935131UL }, + { &fnv_test_str[88], (Fnv32_t) 0xc48fb86dUL }, + { &fnv_test_str[89], (Fnv32_t) 0x2269f369UL }, + { &fnv_test_str[90], (Fnv32_t) 0xc18fb3b4UL }, + { &fnv_test_str[91], (Fnv32_t) 0x50ef1236UL }, + { &fnv_test_str[92], (Fnv32_t) 0xc28fb547UL }, + { &fnv_test_str[93], (Fnv32_t) 0x96c3bf47UL }, + { &fnv_test_str[94], (Fnv32_t) 0xbf8fb08eUL }, + { &fnv_test_str[95], (Fnv32_t) 0xf3e4d49cUL }, + { &fnv_test_str[96], (Fnv32_t) 0x32179058UL }, + { &fnv_test_str[97], (Fnv32_t) 0x280bfee6UL }, + { &fnv_test_str[98], (Fnv32_t) 0x30178d32UL }, + { &fnv_test_str[99], (Fnv32_t) 0x21addaf8UL }, + { &fnv_test_str[100], (Fnv32_t) 0x4217a988UL }, + { &fnv_test_str[101], (Fnv32_t) 0x772633d6UL }, + { &fnv_test_str[102], (Fnv32_t) 0x08a3d11eUL }, + { &fnv_test_str[103], (Fnv32_t) 0xb7e2323aUL }, + { &fnv_test_str[104], (Fnv32_t) 0x07a3cf8bUL }, + { &fnv_test_str[105], (Fnv32_t) 0x91dfb7d1UL }, + { &fnv_test_str[106], (Fnv32_t) 0x06a3cdf8UL }, + { &fnv_test_str[107], (Fnv32_t) 0x6bdd3d68UL }, + { &fnv_test_str[108], (Fnv32_t) 0x1d5636a7UL }, + { &fnv_test_str[109], (Fnv32_t) 0xd5b808e5UL }, + { &fnv_test_str[110], (Fnv32_t) 0x1353e852UL }, + { &fnv_test_str[111], (Fnv32_t) 0xbf16b916UL }, + { &fnv_test_str[112], (Fnv32_t) 0xa55b89edUL }, + { &fnv_test_str[113], (Fnv32_t) 0x3c1a2017UL }, + { &fnv_test_str[114], (Fnv32_t) 0x0588b13cUL }, + { &fnv_test_str[115], (Fnv32_t) 0xf22f0174UL }, + { &fnv_test_str[116], (Fnv32_t) 0xe83641e1UL }, + { &fnv_test_str[117], (Fnv32_t) 0x6e69b533UL }, + { &fnv_test_str[118], (Fnv32_t) 0xf1760448UL }, + { &fnv_test_str[119], (Fnv32_t) 0x64c8bd58UL }, + { &fnv_test_str[120], (Fnv32_t) 0x97b4ea23UL }, + { &fnv_test_str[121], (Fnv32_t) 0x9a4e92e6UL }, + { &fnv_test_str[122], (Fnv32_t) 0xcfb14012UL }, + { &fnv_test_str[123], (Fnv32_t) 0xf01b2511UL }, + { &fnv_test_str[124], (Fnv32_t) 0x0bbb59c3UL }, + { &fnv_test_str[125], (Fnv32_t) 0xce524afaUL }, + { &fnv_test_str[126], (Fnv32_t) 0xdd16ef45UL }, + { &fnv_test_str[127], (Fnv32_t) 0x60648bb3UL }, + { &fnv_test_str[128], (Fnv32_t) 0x7fa4bcfcUL }, + { &fnv_test_str[129], (Fnv32_t) 0x5053ae17UL }, + { &fnv_test_str[130], (Fnv32_t) 0xc9302890UL }, + { &fnv_test_str[131], (Fnv32_t) 0x956ded32UL }, + { &fnv_test_str[132], (Fnv32_t) 0x9136db84UL }, + { &fnv_test_str[133], (Fnv32_t) 0xdf9d3323UL }, + { &fnv_test_str[134], (Fnv32_t) 0x32bb6cd0UL }, + { &fnv_test_str[135], (Fnv32_t) 0xc8f8385bUL }, + { &fnv_test_str[136], (Fnv32_t) 0xeb08bfbaUL }, + { &fnv_test_str[137], (Fnv32_t) 0x62cc8e3dUL }, + { &fnv_test_str[138], (Fnv32_t) 0xc3e20f5cUL }, + { &fnv_test_str[139], (Fnv32_t) 0x39e97f17UL }, + { &fnv_test_str[140], (Fnv32_t) 0x7837b203UL }, + { &fnv_test_str[141], (Fnv32_t) 0x319e877bUL }, + { &fnv_test_str[142], (Fnv32_t) 0xd3e63f89UL }, + { &fnv_test_str[143], (Fnv32_t) 0x29b50b38UL }, + { &fnv_test_str[144], (Fnv32_t) 0x5ed678b8UL }, + { &fnv_test_str[145], (Fnv32_t) 0xb0d5b793UL }, + { &fnv_test_str[146], (Fnv32_t) 0x52450be5UL }, + { &fnv_test_str[147], (Fnv32_t) 0xfa72d767UL }, + { &fnv_test_str[148], (Fnv32_t) 0x95066709UL }, + { &fnv_test_str[149], (Fnv32_t) 0x7f52e123UL }, + { &fnv_test_str[150], (Fnv32_t) 0x76966481UL }, + { &fnv_test_str[151], (Fnv32_t) 0x063258b0UL }, + { &fnv_test_str[152], (Fnv32_t) 0x2ded6e8aUL }, + { &fnv_test_str[153], (Fnv32_t) 0xb07d7c52UL }, + { &fnv_test_str[154], (Fnv32_t) 0xd0c71b71UL }, + { &fnv_test_str[155], (Fnv32_t) 0xf684f1bdUL }, + { &fnv_test_str[156], (Fnv32_t) 0x868ecfa8UL }, + { &fnv_test_str[157], (Fnv32_t) 0xf794f684UL }, + { &fnv_test_str[158], (Fnv32_t) 0xd19701c3UL }, + { &fnv_test_str[159], (Fnv32_t) 0x346e171eUL }, + { &fnv_test_str[160], (Fnv32_t) 0x91f8f676UL }, + { &fnv_test_str[161], (Fnv32_t) 0x0bf58848UL }, + { &fnv_test_str[162], (Fnv32_t) 0x6317b6d1UL }, + { &fnv_test_str[163], (Fnv32_t) 0xafad4c54UL }, + { &fnv_test_str[164], (Fnv32_t) 0x0f25681eUL }, + { &fnv_test_str[165], (Fnv32_t) 0x91b18d49UL }, + { &fnv_test_str[166], (Fnv32_t) 0x7d61c12eUL }, + { &fnv_test_str[167], (Fnv32_t) 0x5147d25cUL }, + { &fnv_test_str[168], (Fnv32_t) 0x9a8b6805UL }, + { &fnv_test_str[169], (Fnv32_t) 0x4cd2a447UL }, + { &fnv_test_str[170], (Fnv32_t) 0x1e549b14UL }, + { &fnv_test_str[171], (Fnv32_t) 0x2fe1b574UL }, + { &fnv_test_str[172], (Fnv32_t) 0xcf0cd31eUL }, + { &fnv_test_str[173], (Fnv32_t) 0x6c471669UL }, + { &fnv_test_str[174], (Fnv32_t) 0x0e5eef1eUL }, + { &fnv_test_str[175], (Fnv32_t) 0x2bed3602UL }, + { &fnv_test_str[176], (Fnv32_t) 0xb26249e0UL }, + { &fnv_test_str[177], (Fnv32_t) 0x2c9b86a4UL }, + { &fnv_test_str[178], (Fnv32_t) 0xe415e2bbUL }, + { &fnv_test_str[179], (Fnv32_t) 0x18a98d1dUL }, + { &fnv_test_str[180], (Fnv32_t) 0xb7df8b7bUL }, + { &fnv_test_str[181], (Fnv32_t) 0x241e9075UL }, + { &fnv_test_str[182], (Fnv32_t) 0x063f70ddUL }, + { &fnv_test_str[183], (Fnv32_t) 0x0295aed9UL }, + { &fnv_test_str[184], (Fnv32_t) 0x56a7f781UL }, + { &fnv_test_str[185], (Fnv32_t) 0x253bc645UL }, + { &fnv_test_str[186], (Fnv32_t) 0x46610921UL }, + { &fnv_test_str[187], (Fnv32_t) 0x7c1577f9UL }, + { &fnv_test_str[188], (Fnv32_t) 0x512b2851UL }, + { &fnv_test_str[189], (Fnv32_t) 0x76823999UL }, + { &fnv_test_str[190], (Fnv32_t) 0xc0586935UL }, + { &fnv_test_str[191], (Fnv32_t) 0xf3415c85UL }, + { &fnv_test_str[192], (Fnv32_t) 0x0ae4ff65UL }, + { &fnv_test_str[193], (Fnv32_t) 0x58b79725UL }, + { &fnv_test_str[194], (Fnv32_t) 0xdea43aa5UL }, + { &fnv_test_str[195], (Fnv32_t) 0x2bb3be35UL }, + { &fnv_test_str[196], (Fnv32_t) 0xea777a45UL }, + { &fnv_test_str[197], (Fnv32_t) 0x8f21c305UL }, + { &fnv_test_str[198], (Fnv32_t) 0x5c9d0865UL }, + { &fnv_test_str[199], (Fnv32_t) 0xfa823dd5UL }, + { &fnv_test_str[200], (Fnv32_t) 0x21a27271UL }, + { &fnv_test_str[201], (Fnv32_t) 0x83c5c6d5UL }, + { &fnv_test_str[202], (Fnv32_t) 0x813b0881UL }, + { NULL, 0 } +}; + +/* FNV-0 64 bit test vectors */ +#if defined(HAVE_64BIT_LONG_LONG) +struct fnv0_64_test_vector fnv0_64_vector[] = { + { &fnv_test_str[0], (Fnv64_t) 0x0000000000000000ULL }, + { &fnv_test_str[1], (Fnv64_t) 0x0000000000000061ULL }, + { &fnv_test_str[2], (Fnv64_t) 0x0000000000000062ULL }, + { &fnv_test_str[3], (Fnv64_t) 0x0000000000000063ULL }, + { &fnv_test_str[4], (Fnv64_t) 0x0000000000000064ULL }, + { &fnv_test_str[5], (Fnv64_t) 0x0000000000000065ULL }, + { &fnv_test_str[6], (Fnv64_t) 0x0000000000000066ULL }, + { &fnv_test_str[7], (Fnv64_t) 0x000066000000ad3dULL }, + { &fnv_test_str[8], (Fnv64_t) 0x015a8f0001265ec8ULL }, + { &fnv_test_str[9], (Fnv64_t) 0x733fc501f4330dbaULL }, + { &fnv_test_str[10], (Fnv64_t) 0x08697c51f2c0536fULL }, + { &fnv_test_str[11], (Fnv64_t) 0x0b91ae3f7ccdc5efULL }, + { &fnv_test_str[12], (Fnv64_t) 0x0000000000000000ULL }, + { &fnv_test_str[13], (Fnv64_t) 0x000061000000a4d3ULL }, + { &fnv_test_str[14], (Fnv64_t) 0x000062000000a686ULL }, + { &fnv_test_str[15], (Fnv64_t) 0x000063000000a839ULL }, + { &fnv_test_str[16], (Fnv64_t) 0x000064000000a9ecULL }, + { &fnv_test_str[17], (Fnv64_t) 0x000065000000ab9fULL }, + { &fnv_test_str[18], (Fnv64_t) 0x000066000000ad52ULL }, + { &fnv_test_str[19], (Fnv64_t) 0x015a8f0001265ea7ULL }, + { &fnv_test_str[20], (Fnv64_t) 0x733fc501f4330dd8ULL }, + { &fnv_test_str[21], (Fnv64_t) 0x08697c51f2c0530eULL }, + { &fnv_test_str[22], (Fnv64_t) 0x0b91ae3f7ccdc59dULL }, + { &fnv_test_str[23], (Fnv64_t) 0x765104e111a7551dULL }, + { &fnv_test_str[24], (Fnv64_t) 0x000063000000a851ULL }, + { &fnv_test_str[25], (Fnv64_t) 0x01508a00011e01ccULL }, + { &fnv_test_str[26], (Fnv64_t) 0x59dc4a01e5fd0dcaULL }, + { &fnv_test_str[27], (Fnv64_t) 0xae5f8b39ccfe6e59ULL }, + { &fnv_test_str[28], (Fnv64_t) 0x4ac7ec3754558154ULL }, + { &fnv_test_str[29], (Fnv64_t) 0x6737b6044d4ac19cULL }, + { &fnv_test_str[30], (Fnv64_t) 0xae6be54f5606fc63ULL }, + { &fnv_test_str[31], (Fnv64_t) 0x685308cf2ddedc58ULL }, + { &fnv_test_str[32], (Fnv64_t) 0x23f4500af1b069fbULL }, + { &fnv_test_str[33], (Fnv64_t) 0xc88dfd98aec415a1ULL }, + { &fnv_test_str[34], (Fnv64_t) 0x8d5b8b70f730c0fbULL }, + { &fnv_test_str[35], (Fnv64_t) 0x634eebf407d7eae4ULL }, + { &fnv_test_str[36], (Fnv64_t) 0x9705d3a953e4211eULL }, + { &fnv_test_str[37], (Fnv64_t) 0x8307c6b98ca4459fULL }, + { &fnv_test_str[38], (Fnv64_t) 0x4a7c4c49fb224d0cULL }, + { &fnv_test_str[39], (Fnv64_t) 0xb382adb5bb48eb6eULL }, + { &fnv_test_str[40], (Fnv64_t) 0x01508a00011e01a3ULL }, + { &fnv_test_str[41], (Fnv64_t) 0x59dc4a01e5fd0da4ULL }, + { &fnv_test_str[42], (Fnv64_t) 0xae5f8b39ccfe6e3eULL }, + { &fnv_test_str[43], (Fnv64_t) 0x4ac7ec375455813bULL }, + { &fnv_test_str[44], (Fnv64_t) 0x6737b6044d4ac1bcULL }, + { &fnv_test_str[45], (Fnv64_t) 0xae6be54f5606fc14ULL }, + { &fnv_test_str[46], (Fnv64_t) 0x685308cf2ddedc39ULL }, + { &fnv_test_str[47], (Fnv64_t) 0x23f4500af1b06988ULL }, + { &fnv_test_str[48], (Fnv64_t) 0xc88dfd98aec41581ULL }, + { &fnv_test_str[49], (Fnv64_t) 0x8d5b8b70f730c093ULL }, + { &fnv_test_str[50], (Fnv64_t) 0x634eebf407d7ea81ULL }, + { &fnv_test_str[51], (Fnv64_t) 0x9705d3a953e4216cULL }, + { &fnv_test_str[52], (Fnv64_t) 0x8307c6b98ca445faULL }, + { &fnv_test_str[53], (Fnv64_t) 0x4a7c4c49fb224d2dULL }, + { &fnv_test_str[54], (Fnv64_t) 0xb382adb5bb48eb64ULL }, + { &fnv_test_str[55], (Fnv64_t) 0x4ff899cd3ce80beaULL }, + { &fnv_test_str[56], (Fnv64_t) 0x000063000000a84cULL }, + { &fnv_test_str[57], (Fnv64_t) 0x01508500011df956ULL }, + { &fnv_test_str[58], (Fnv64_t) 0x59cb5501e5eead46ULL }, + { &fnv_test_str[59], (Fnv64_t) 0x832eb839b4906d81ULL }, + { &fnv_test_str[60], (Fnv64_t) 0x78d08b0dd16a1213ULL }, + { &fnv_test_str[61], (Fnv64_t) 0xb46e5b7ad73cb628ULL }, + { &fnv_test_str[62], (Fnv64_t) 0xd43b99bbbc298596ULL }, + { &fnv_test_str[63], (Fnv64_t) 0xcacbd000ba8dfd86ULL }, + { &fnv_test_str[64], (Fnv64_t) 0x264ff73cff45ca92ULL }, + { &fnv_test_str[65], (Fnv64_t) 0x5fabaea5c3973661ULL }, + { &fnv_test_str[66], (Fnv64_t) 0x27f024ab59f166bbULL }, + { &fnv_test_str[67], (Fnv64_t) 0xce750a29d5318fa4ULL }, + { &fnv_test_str[68], (Fnv64_t) 0x026fe915433713d5ULL }, + { &fnv_test_str[69], (Fnv64_t) 0x5b3ce4213696b2e5ULL }, + { &fnv_test_str[70], (Fnv64_t) 0x01508500011df924ULL }, + { &fnv_test_str[71], (Fnv64_t) 0x59cb5501e5eead22ULL }, + { &fnv_test_str[72], (Fnv64_t) 0x832eb839b4906df2ULL }, + { &fnv_test_str[73], (Fnv64_t) 0x78d08b0dd16a1233ULL }, + { &fnv_test_str[74], (Fnv64_t) 0xb46e5b7ad73cb649ULL }, + { &fnv_test_str[75], (Fnv64_t) 0xd43b99bbbc2985f8ULL }, + { &fnv_test_str[76], (Fnv64_t) 0xcacbd000ba8dfde2ULL }, + { &fnv_test_str[77], (Fnv64_t) 0x264ff73cff45cab2ULL }, + { &fnv_test_str[78], (Fnv64_t) 0x5fabaea5c3973616ULL }, + { &fnv_test_str[79], (Fnv64_t) 0x27f024ab59f166d3ULL }, + { &fnv_test_str[80], (Fnv64_t) 0xce750a29d5318fc1ULL }, + { &fnv_test_str[81], (Fnv64_t) 0x026fe915433713acULL }, + { &fnv_test_str[82], (Fnv64_t) 0x5b3ce4213696b2efULL }, + { &fnv_test_str[83], (Fnv64_t) 0x9f2a896fc211fb1fULL }, + { &fnv_test_str[84], (Fnv64_t) 0x000068000000b0d1ULL }, + { &fnv_test_str[85], (Fnv64_t) 0x01618900012c7323ULL }, + { &fnv_test_str[86], (Fnv64_t) 0x3fa86e63bc7d03c8ULL }, + { &fnv_test_str[87], (Fnv64_t) 0xa8375b79486d6cd8ULL }, + { &fnv_test_str[88], (Fnv64_t) 0xa0d18504e316ac54ULL }, + { &fnv_test_str[89], (Fnv64_t) 0x08a97b0004e7fe54ULL }, + { &fnv_test_str[90], (Fnv64_t) 0xa0d18504e316ac57ULL }, + { &fnv_test_str[91], (Fnv64_t) 0x1152f60009cffda9ULL }, + { &fnv_test_str[92], (Fnv64_t) 0xa0d18504e316ac56ULL }, + { &fnv_test_str[93], (Fnv64_t) 0x19fc71000eb7fcfeULL }, + { &fnv_test_str[94], (Fnv64_t) 0xa0d18504e316ac51ULL }, + { &fnv_test_str[95], (Fnv64_t) 0x22a5ec00139ffa53ULL }, + { &fnv_test_str[96], (Fnv64_t) 0x29bed00139779a33ULL }, + { &fnv_test_str[97], (Fnv64_t) 0x4dbc81014e3c19f5ULL }, + { &fnv_test_str[98], (Fnv64_t) 0x29bed00139779a3dULL }, + { &fnv_test_str[99], (Fnv64_t) 0x81a72b016b9f7573ULL }, + { &fnv_test_str[100], (Fnv64_t) 0x29bed00139779a23ULL }, + { &fnv_test_str[101], (Fnv64_t) 0xd85411019cbbce45ULL }, + { &fnv_test_str[102], (Fnv64_t) 0xf548616b8621d657ULL }, + { &fnv_test_str[103], (Fnv64_t) 0xebd3e0b4eb7f35d5ULL }, + { &fnv_test_str[104], (Fnv64_t) 0xf548616b8621d654ULL }, + { &fnv_test_str[105], (Fnv64_t) 0xebd3ddb4eb7f30bcULL }, + { &fnv_test_str[106], (Fnv64_t) 0xf548616b8621d655ULL }, + { &fnv_test_str[107], (Fnv64_t) 0xebd3deb4eb7f326fULL }, + { &fnv_test_str[108], (Fnv64_t) 0x581cb60340ab0968ULL }, + { &fnv_test_str[109], (Fnv64_t) 0x63d2af86e2a0fbb8ULL }, + { &fnv_test_str[110], (Fnv64_t) 0x581cb70340ab0b37ULL }, + { &fnv_test_str[111], (Fnv64_t) 0x63d63186e2a40e75ULL }, + { &fnv_test_str[112], (Fnv64_t) 0x581cc40340ab212eULL }, + { &fnv_test_str[113], (Fnv64_t) 0x64023f86e2c9612aULL }, + { &fnv_test_str[114], (Fnv64_t) 0xdbda6a26c33c909fULL }, + { &fnv_test_str[115], (Fnv64_t) 0xd0b2feddbfe9be2dULL }, + { &fnv_test_str[116], (Fnv64_t) 0x9c9eae3f5d037decULL }, + { &fnv_test_str[117], (Fnv64_t) 0x252001ab0ceef804ULL }, + { &fnv_test_str[118], (Fnv64_t) 0x4456a56f9e05cfefULL }, + { &fnv_test_str[119], (Fnv64_t) 0x250b0ba983e0531dULL }, + { &fnv_test_str[120], (Fnv64_t) 0x52b007213b27b33eULL }, + { &fnv_test_str[121], (Fnv64_t) 0xcbf29ce484222325ULL }, + { &fnv_test_str[122], (Fnv64_t) 0xaf63bd4c8601b7dfULL }, + { &fnv_test_str[123], (Fnv64_t) 0x128599ccddae09f8ULL }, + { &fnv_test_str[124], (Fnv64_t) 0x270e4f1caebaf068ULL }, + { &fnv_test_str[125], (Fnv64_t) 0x01517d497446a395ULL }, + { &fnv_test_str[126], (Fnv64_t) 0x9af5a29a89450b40ULL }, + { &fnv_test_str[127], (Fnv64_t) 0xb502f6c063ba72e8ULL }, + { &fnv_test_str[128], (Fnv64_t) 0xacf41561498ca7dfULL }, + { &fnv_test_str[129], (Fnv64_t) 0x6be8c2423a351542ULL }, + { &fnv_test_str[130], (Fnv64_t) 0xd04f1f6da96ce4a3ULL }, + { &fnv_test_str[131], (Fnv64_t) 0x69eb9a8f282c7235ULL }, + { &fnv_test_str[132], (Fnv64_t) 0x6a7e5a418f77cfc5ULL }, + { &fnv_test_str[133], (Fnv64_t) 0xbcaf568ddc2ecba0ULL }, + { &fnv_test_str[134], (Fnv64_t) 0xb03b5cc4c38f8b1fULL }, + { &fnv_test_str[135], (Fnv64_t) 0xf89a9f51432db828ULL }, + { &fnv_test_str[136], (Fnv64_t) 0x549e856be6103429ULL }, + { &fnv_test_str[137], (Fnv64_t) 0x3cf50d224d29377aULL }, + { &fnv_test_str[138], (Fnv64_t) 0xdb762df418c10c37ULL }, + { &fnv_test_str[139], (Fnv64_t) 0xfeeb4226b0e9a6baULL }, + { &fnv_test_str[140], (Fnv64_t) 0x7004a4cd9310c052ULL }, + { &fnv_test_str[141], (Fnv64_t) 0xd1c727d7f5329276ULL }, + { &fnv_test_str[142], (Fnv64_t) 0xbe313796596ce908ULL }, + { &fnv_test_str[143], (Fnv64_t) 0x768f67ede090fcc5ULL }, + { &fnv_test_str[144], (Fnv64_t) 0xa81563cc9db9bfc3ULL }, + { &fnv_test_str[145], (Fnv64_t) 0x47194043c55197a8ULL }, + { &fnv_test_str[146], (Fnv64_t) 0xc99d81864aebab02ULL }, + { &fnv_test_str[147], (Fnv64_t) 0xcc1f161b235ea4a2ULL }, + { &fnv_test_str[148], (Fnv64_t) 0xaadab0c420ecd434ULL }, + { &fnv_test_str[149], (Fnv64_t) 0x6b3c034d6f44d740ULL }, + { &fnv_test_str[150], (Fnv64_t) 0x73a45e850602cbc6ULL }, + { &fnv_test_str[151], (Fnv64_t) 0x72360f04f0cd227bULL }, + { &fnv_test_str[152], (Fnv64_t) 0xa9ca80be384a778fULL }, + { &fnv_test_str[153], (Fnv64_t) 0xd4085e66906889e3ULL }, + { &fnv_test_str[154], (Fnv64_t) 0x93aa8b2748efdbc8ULL }, + { &fnv_test_str[155], (Fnv64_t) 0x6f8cd678407436a2ULL }, + { &fnv_test_str[156], (Fnv64_t) 0xf39a43d4dc8be4c7ULL }, + { &fnv_test_str[157], (Fnv64_t) 0xd7f5cec91125d245ULL }, + { &fnv_test_str[158], (Fnv64_t) 0x691d7b73be18adc4ULL }, + { &fnv_test_str[159], (Fnv64_t) 0xf4361e01caf6b691ULL }, + { &fnv_test_str[160], (Fnv64_t) 0xde7d8264f64be089ULL }, + { &fnv_test_str[161], (Fnv64_t) 0xa34ff43e5545c06fULL }, + { &fnv_test_str[162], (Fnv64_t) 0x181f0b8e908a2bdeULL }, + { &fnv_test_str[163], (Fnv64_t) 0x28a965b78ddbc071ULL }, + { &fnv_test_str[164], (Fnv64_t) 0xead9cea0e3cc6ae5ULL }, + { &fnv_test_str[165], (Fnv64_t) 0x0b6743153b43ebbaULL }, + { &fnv_test_str[166], (Fnv64_t) 0xa7aa3f012c74528dULL }, + { &fnv_test_str[167], (Fnv64_t) 0x2d5d8ad7f9dffeb7ULL }, + { &fnv_test_str[168], (Fnv64_t) 0x00750fb6e19624eaULL }, + { &fnv_test_str[169], (Fnv64_t) 0x01c125a4e6c76c82ULL }, + { &fnv_test_str[170], (Fnv64_t) 0x3fde3afac0722f1fULL }, + { &fnv_test_str[171], (Fnv64_t) 0xd7c3eaf4abaa379dULL }, + { &fnv_test_str[172], (Fnv64_t) 0xd2217e1c923c9f3fULL }, + { &fnv_test_str[173], (Fnv64_t) 0x82d0a2e3b725caf6ULL }, + { &fnv_test_str[174], (Fnv64_t) 0x0a10bee8eeb72e4fULL }, + { &fnv_test_str[175], (Fnv64_t) 0xc530e8723e72c6fdULL }, + { &fnv_test_str[176], (Fnv64_t) 0xd8d34dcd2e7bad99ULL }, + { &fnv_test_str[177], (Fnv64_t) 0xecf77466e9a2baf3ULL }, + { &fnv_test_str[178], (Fnv64_t) 0xde3d2ddb043b9666ULL }, + { &fnv_test_str[179], (Fnv64_t) 0xd1cc824e1a8157d8ULL }, + { &fnv_test_str[180], (Fnv64_t) 0x7d5c68ecbc90512eULL }, + { &fnv_test_str[181], (Fnv64_t) 0x2f7c691b1d7c76d8ULL }, + { &fnv_test_str[182], (Fnv64_t) 0x5d88c2bad3a46bc8ULL }, + { &fnv_test_str[183], (Fnv64_t) 0xdf107320276647a0ULL }, + { &fnv_test_str[184], (Fnv64_t) 0x0f78f22e7e70e9bcULL }, + { &fnv_test_str[185], (Fnv64_t) 0x8c67be5c80f67d04ULL }, + { &fnv_test_str[186], (Fnv64_t) 0x07c1adfa4d019194ULL }, + { &fnv_test_str[187], (Fnv64_t) 0xce1312420c5b1af4ULL }, + { &fnv_test_str[188], (Fnv64_t) 0x043a41b2dc53ab24ULL }, + { &fnv_test_str[189], (Fnv64_t) 0x0b038eebf7340860ULL }, + { &fnv_test_str[190], (Fnv64_t) 0x1bcd837353fb69b0ULL }, + { &fnv_test_str[191], (Fnv64_t) 0x46f992fc59eff180ULL }, + { &fnv_test_str[192], (Fnv64_t) 0x497678ee29ae79c0ULL }, + { &fnv_test_str[193], (Fnv64_t) 0xb10a62280ddd4450ULL }, + { &fnv_test_str[194], (Fnv64_t) 0x35eb228db4d68140ULL }, + { &fnv_test_str[195], (Fnv64_t) 0x8b350e86d9470870ULL }, + { &fnv_test_str[196], (Fnv64_t) 0x4e1fbdb2812e9540ULL }, + { &fnv_test_str[197], (Fnv64_t) 0x051e080df69a0600ULL }, + { &fnv_test_str[198], (Fnv64_t) 0x45e1e8ae54dadb40ULL }, + { &fnv_test_str[199], (Fnv64_t) 0x0000000000000000ULL }, + { &fnv_test_str[200], (Fnv64_t) 0xcd73806290557064ULL }, + { &fnv_test_str[201], (Fnv64_t) 0x2613a37bbe0317c8ULL }, + { &fnv_test_str[202], (Fnv64_t) 0x1480e21fcf2ae5e4ULL }, + { NULL, (Fnv64_t) 0 } +}; +#else /* HAVE_64BIT_LONG_LONG */ +struct fnv0_64_test_vector fnv0_64_vector[] = { + { &fnv_test_str[0], (Fnv64_t) {0x00000000UL, 0x00000000UL} }, + { &fnv_test_str[1], (Fnv64_t) {0x00000061UL, 0x00000000UL} }, + { &fnv_test_str[2], (Fnv64_t) {0x00000062UL, 0x00000000UL} }, + { &fnv_test_str[3], (Fnv64_t) {0x00000063UL, 0x00000000UL} }, + { &fnv_test_str[4], (Fnv64_t) {0x00000064UL, 0x00000000UL} }, + { &fnv_test_str[5], (Fnv64_t) {0x00000065UL, 0x00000000UL} }, + { &fnv_test_str[6], (Fnv64_t) {0x00000066UL, 0x00000000UL} }, + { &fnv_test_str[7], (Fnv64_t) {0x0000ad3dUL, 0x00006600UL} }, + { &fnv_test_str[8], (Fnv64_t) {0x01265ec8UL, 0x015a8f00UL} }, + { &fnv_test_str[9], (Fnv64_t) {0xf4330dbaUL, 0x733fc501UL} }, + { &fnv_test_str[10], (Fnv64_t) {0xf2c0536fUL, 0x08697c51UL} }, + { &fnv_test_str[11], (Fnv64_t) {0x7ccdc5efUL, 0x0b91ae3fUL} }, + { &fnv_test_str[12], (Fnv64_t) {0x00000000UL, 0x00000000UL} }, + { &fnv_test_str[13], (Fnv64_t) {0x0000a4d3UL, 0x00006100UL} }, + { &fnv_test_str[14], (Fnv64_t) {0x0000a686UL, 0x00006200UL} }, + { &fnv_test_str[15], (Fnv64_t) {0x0000a839UL, 0x00006300UL} }, + { &fnv_test_str[16], (Fnv64_t) {0x0000a9ecUL, 0x00006400UL} }, + { &fnv_test_str[17], (Fnv64_t) {0x0000ab9fUL, 0x00006500UL} }, + { &fnv_test_str[18], (Fnv64_t) {0x0000ad52UL, 0x00006600UL} }, + { &fnv_test_str[19], (Fnv64_t) {0x01265ea7UL, 0x015a8f00UL} }, + { &fnv_test_str[20], (Fnv64_t) {0xf4330dd8UL, 0x733fc501UL} }, + { &fnv_test_str[21], (Fnv64_t) {0xf2c0530eUL, 0x08697c51UL} }, + { &fnv_test_str[22], (Fnv64_t) {0x7ccdc59dUL, 0x0b91ae3fUL} }, + { &fnv_test_str[23], (Fnv64_t) {0x11a7551dUL, 0x765104e1UL} }, + { &fnv_test_str[24], (Fnv64_t) {0x0000a851UL, 0x00006300UL} }, + { &fnv_test_str[25], (Fnv64_t) {0x011e01ccUL, 0x01508a00UL} }, + { &fnv_test_str[26], (Fnv64_t) {0xe5fd0dcaUL, 0x59dc4a01UL} }, + { &fnv_test_str[27], (Fnv64_t) {0xccfe6e59UL, 0xae5f8b39UL} }, + { &fnv_test_str[28], (Fnv64_t) {0x54558154UL, 0x4ac7ec37UL} }, + { &fnv_test_str[29], (Fnv64_t) {0x4d4ac19cUL, 0x6737b604UL} }, + { &fnv_test_str[30], (Fnv64_t) {0x5606fc63UL, 0xae6be54fUL} }, + { &fnv_test_str[31], (Fnv64_t) {0x2ddedc58UL, 0x685308cfUL} }, + { &fnv_test_str[32], (Fnv64_t) {0xf1b069fbUL, 0x23f4500aUL} }, + { &fnv_test_str[33], (Fnv64_t) {0xaec415a1UL, 0xc88dfd98UL} }, + { &fnv_test_str[34], (Fnv64_t) {0xf730c0fbUL, 0x8d5b8b70UL} }, + { &fnv_test_str[35], (Fnv64_t) {0x07d7eae4UL, 0x634eebf4UL} }, + { &fnv_test_str[36], (Fnv64_t) {0x53e4211eUL, 0x9705d3a9UL} }, + { &fnv_test_str[37], (Fnv64_t) {0x8ca4459fUL, 0x8307c6b9UL} }, + { &fnv_test_str[38], (Fnv64_t) {0xfb224d0cUL, 0x4a7c4c49UL} }, + { &fnv_test_str[39], (Fnv64_t) {0xbb48eb6eUL, 0xb382adb5UL} }, + { &fnv_test_str[40], (Fnv64_t) {0x011e01a3UL, 0x01508a00UL} }, + { &fnv_test_str[41], (Fnv64_t) {0xe5fd0da4UL, 0x59dc4a01UL} }, + { &fnv_test_str[42], (Fnv64_t) {0xccfe6e3eUL, 0xae5f8b39UL} }, + { &fnv_test_str[43], (Fnv64_t) {0x5455813bUL, 0x4ac7ec37UL} }, + { &fnv_test_str[44], (Fnv64_t) {0x4d4ac1bcUL, 0x6737b604UL} }, + { &fnv_test_str[45], (Fnv64_t) {0x5606fc14UL, 0xae6be54fUL} }, + { &fnv_test_str[46], (Fnv64_t) {0x2ddedc39UL, 0x685308cfUL} }, + { &fnv_test_str[47], (Fnv64_t) {0xf1b06988UL, 0x23f4500aUL} }, + { &fnv_test_str[48], (Fnv64_t) {0xaec41581UL, 0xc88dfd98UL} }, + { &fnv_test_str[49], (Fnv64_t) {0xf730c093UL, 0x8d5b8b70UL} }, + { &fnv_test_str[50], (Fnv64_t) {0x07d7ea81UL, 0x634eebf4UL} }, + { &fnv_test_str[51], (Fnv64_t) {0x53e4216cUL, 0x9705d3a9UL} }, + { &fnv_test_str[52], (Fnv64_t) {0x8ca445faUL, 0x8307c6b9UL} }, + { &fnv_test_str[53], (Fnv64_t) {0xfb224d2dUL, 0x4a7c4c49UL} }, + { &fnv_test_str[54], (Fnv64_t) {0xbb48eb64UL, 0xb382adb5UL} }, + { &fnv_test_str[55], (Fnv64_t) {0x3ce80beaUL, 0x4ff899cdUL} }, + { &fnv_test_str[56], (Fnv64_t) {0x0000a84cUL, 0x00006300UL} }, + { &fnv_test_str[57], (Fnv64_t) {0x011df956UL, 0x01508500UL} }, + { &fnv_test_str[58], (Fnv64_t) {0xe5eead46UL, 0x59cb5501UL} }, + { &fnv_test_str[59], (Fnv64_t) {0xb4906d81UL, 0x832eb839UL} }, + { &fnv_test_str[60], (Fnv64_t) {0xd16a1213UL, 0x78d08b0dUL} }, + { &fnv_test_str[61], (Fnv64_t) {0xd73cb628UL, 0xb46e5b7aUL} }, + { &fnv_test_str[62], (Fnv64_t) {0xbc298596UL, 0xd43b99bbUL} }, + { &fnv_test_str[63], (Fnv64_t) {0xba8dfd86UL, 0xcacbd000UL} }, + { &fnv_test_str[64], (Fnv64_t) {0xff45ca92UL, 0x264ff73cUL} }, + { &fnv_test_str[65], (Fnv64_t) {0xc3973661UL, 0x5fabaea5UL} }, + { &fnv_test_str[66], (Fnv64_t) {0x59f166bbUL, 0x27f024abUL} }, + { &fnv_test_str[67], (Fnv64_t) {0xd5318fa4UL, 0xce750a29UL} }, + { &fnv_test_str[68], (Fnv64_t) {0x433713d5UL, 0x026fe915UL} }, + { &fnv_test_str[69], (Fnv64_t) {0x3696b2e5UL, 0x5b3ce421UL} }, + { &fnv_test_str[70], (Fnv64_t) {0x011df924UL, 0x01508500UL} }, + { &fnv_test_str[71], (Fnv64_t) {0xe5eead22UL, 0x59cb5501UL} }, + { &fnv_test_str[72], (Fnv64_t) {0xb4906df2UL, 0x832eb839UL} }, + { &fnv_test_str[73], (Fnv64_t) {0xd16a1233UL, 0x78d08b0dUL} }, + { &fnv_test_str[74], (Fnv64_t) {0xd73cb649UL, 0xb46e5b7aUL} }, + { &fnv_test_str[75], (Fnv64_t) {0xbc2985f8UL, 0xd43b99bbUL} }, + { &fnv_test_str[76], (Fnv64_t) {0xba8dfde2UL, 0xcacbd000UL} }, + { &fnv_test_str[77], (Fnv64_t) {0xff45cab2UL, 0x264ff73cUL} }, + { &fnv_test_str[78], (Fnv64_t) {0xc3973616UL, 0x5fabaea5UL} }, + { &fnv_test_str[79], (Fnv64_t) {0x59f166d3UL, 0x27f024abUL} }, + { &fnv_test_str[80], (Fnv64_t) {0xd5318fc1UL, 0xce750a29UL} }, + { &fnv_test_str[81], (Fnv64_t) {0x433713acUL, 0x026fe915UL} }, + { &fnv_test_str[82], (Fnv64_t) {0x3696b2efUL, 0x5b3ce421UL} }, + { &fnv_test_str[83], (Fnv64_t) {0xc211fb1fUL, 0x9f2a896fUL} }, + { &fnv_test_str[84], (Fnv64_t) {0x0000b0d1UL, 0x00006800UL} }, + { &fnv_test_str[85], (Fnv64_t) {0x012c7323UL, 0x01618900UL} }, + { &fnv_test_str[86], (Fnv64_t) {0xbc7d03c8UL, 0x3fa86e63UL} }, + { &fnv_test_str[87], (Fnv64_t) {0x486d6cd8UL, 0xa8375b79UL} }, + { &fnv_test_str[88], (Fnv64_t) {0xe316ac54UL, 0xa0d18504UL} }, + { &fnv_test_str[89], (Fnv64_t) {0x04e7fe54UL, 0x08a97b00UL} }, + { &fnv_test_str[90], (Fnv64_t) {0xe316ac57UL, 0xa0d18504UL} }, + { &fnv_test_str[91], (Fnv64_t) {0x09cffda9UL, 0x1152f600UL} }, + { &fnv_test_str[92], (Fnv64_t) {0xe316ac56UL, 0xa0d18504UL} }, + { &fnv_test_str[93], (Fnv64_t) {0x0eb7fcfeUL, 0x19fc7100UL} }, + { &fnv_test_str[94], (Fnv64_t) {0xe316ac51UL, 0xa0d18504UL} }, + { &fnv_test_str[95], (Fnv64_t) {0x139ffa53UL, 0x22a5ec00UL} }, + { &fnv_test_str[96], (Fnv64_t) {0x39779a33UL, 0x29bed001UL} }, + { &fnv_test_str[97], (Fnv64_t) {0x4e3c19f5UL, 0x4dbc8101UL} }, + { &fnv_test_str[98], (Fnv64_t) {0x39779a3dUL, 0x29bed001UL} }, + { &fnv_test_str[99], (Fnv64_t) {0x6b9f7573UL, 0x81a72b01UL} }, + { &fnv_test_str[100], (Fnv64_t) {0x39779a23UL, 0x29bed001UL} }, + { &fnv_test_str[101], (Fnv64_t) {0x9cbbce45UL, 0xd8541101UL} }, + { &fnv_test_str[102], (Fnv64_t) {0x8621d657UL, 0xf548616bUL} }, + { &fnv_test_str[103], (Fnv64_t) {0xeb7f35d5UL, 0xebd3e0b4UL} }, + { &fnv_test_str[104], (Fnv64_t) {0x8621d654UL, 0xf548616bUL} }, + { &fnv_test_str[105], (Fnv64_t) {0xeb7f30bcUL, 0xebd3ddb4UL} }, + { &fnv_test_str[106], (Fnv64_t) {0x8621d655UL, 0xf548616bUL} }, + { &fnv_test_str[107], (Fnv64_t) {0xeb7f326fUL, 0xebd3deb4UL} }, + { &fnv_test_str[108], (Fnv64_t) {0x40ab0968UL, 0x581cb603UL} }, + { &fnv_test_str[109], (Fnv64_t) {0xe2a0fbb8UL, 0x63d2af86UL} }, + { &fnv_test_str[110], (Fnv64_t) {0x40ab0b37UL, 0x581cb703UL} }, + { &fnv_test_str[111], (Fnv64_t) {0xe2a40e75UL, 0x63d63186UL} }, + { &fnv_test_str[112], (Fnv64_t) {0x40ab212eUL, 0x581cc403UL} }, + { &fnv_test_str[113], (Fnv64_t) {0xe2c9612aUL, 0x64023f86UL} }, + { &fnv_test_str[114], (Fnv64_t) {0xc33c909fUL, 0xdbda6a26UL} }, + { &fnv_test_str[115], (Fnv64_t) {0xbfe9be2dUL, 0xd0b2feddUL} }, + { &fnv_test_str[116], (Fnv64_t) {0x5d037decUL, 0x9c9eae3fUL} }, + { &fnv_test_str[117], (Fnv64_t) {0x0ceef804UL, 0x252001abUL} }, + { &fnv_test_str[118], (Fnv64_t) {0x9e05cfefUL, 0x4456a56fUL} }, + { &fnv_test_str[119], (Fnv64_t) {0x83e0531dUL, 0x250b0ba9UL} }, + { &fnv_test_str[120], (Fnv64_t) {0x3b27b33eUL, 0x52b00721UL} }, + { &fnv_test_str[121], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} }, + { &fnv_test_str[122], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} }, + { &fnv_test_str[123], (Fnv64_t) {0xddae09f8UL, 0x128599ccUL} }, + { &fnv_test_str[124], (Fnv64_t) {0xaebaf068UL, 0x270e4f1cUL} }, + { &fnv_test_str[125], (Fnv64_t) {0x7446a395UL, 0x01517d49UL} }, + { &fnv_test_str[126], (Fnv64_t) {0x89450b40UL, 0x9af5a29aUL} }, + { &fnv_test_str[127], (Fnv64_t) {0x63ba72e8UL, 0xb502f6c0UL} }, + { &fnv_test_str[128], (Fnv64_t) {0x498ca7dfUL, 0xacf41561UL} }, + { &fnv_test_str[129], (Fnv64_t) {0x3a351542UL, 0x6be8c242UL} }, + { &fnv_test_str[130], (Fnv64_t) {0xa96ce4a3UL, 0xd04f1f6dUL} }, + { &fnv_test_str[131], (Fnv64_t) {0x282c7235UL, 0x69eb9a8fUL} }, + { &fnv_test_str[132], (Fnv64_t) {0x8f77cfc5UL, 0x6a7e5a41UL} }, + { &fnv_test_str[133], (Fnv64_t) {0xdc2ecba0UL, 0xbcaf568dUL} }, + { &fnv_test_str[134], (Fnv64_t) {0xc38f8b1fUL, 0xb03b5cc4UL} }, + { &fnv_test_str[135], (Fnv64_t) {0x432db828UL, 0xf89a9f51UL} }, + { &fnv_test_str[136], (Fnv64_t) {0xe6103429UL, 0x549e856bUL} }, + { &fnv_test_str[137], (Fnv64_t) {0x4d29377aUL, 0x3cf50d22UL} }, + { &fnv_test_str[138], (Fnv64_t) {0x18c10c37UL, 0xdb762df4UL} }, + { &fnv_test_str[139], (Fnv64_t) {0xb0e9a6baUL, 0xfeeb4226UL} }, + { &fnv_test_str[140], (Fnv64_t) {0x9310c052UL, 0x7004a4cdUL} }, + { &fnv_test_str[141], (Fnv64_t) {0xf5329276UL, 0xd1c727d7UL} }, + { &fnv_test_str[142], (Fnv64_t) {0x596ce908UL, 0xbe313796UL} }, + { &fnv_test_str[143], (Fnv64_t) {0xe090fcc5UL, 0x768f67edUL} }, + { &fnv_test_str[144], (Fnv64_t) {0x9db9bfc3UL, 0xa81563ccUL} }, + { &fnv_test_str[145], (Fnv64_t) {0xc55197a8UL, 0x47194043UL} }, + { &fnv_test_str[146], (Fnv64_t) {0x4aebab02UL, 0xc99d8186UL} }, + { &fnv_test_str[147], (Fnv64_t) {0x235ea4a2UL, 0xcc1f161bUL} }, + { &fnv_test_str[148], (Fnv64_t) {0x20ecd434UL, 0xaadab0c4UL} }, + { &fnv_test_str[149], (Fnv64_t) {0x6f44d740UL, 0x6b3c034dUL} }, + { &fnv_test_str[150], (Fnv64_t) {0x0602cbc6UL, 0x73a45e85UL} }, + { &fnv_test_str[151], (Fnv64_t) {0xf0cd227bUL, 0x72360f04UL} }, + { &fnv_test_str[152], (Fnv64_t) {0x384a778fUL, 0xa9ca80beUL} }, + { &fnv_test_str[153], (Fnv64_t) {0x906889e3UL, 0xd4085e66UL} }, + { &fnv_test_str[154], (Fnv64_t) {0x48efdbc8UL, 0x93aa8b27UL} }, + { &fnv_test_str[155], (Fnv64_t) {0x407436a2UL, 0x6f8cd678UL} }, + { &fnv_test_str[156], (Fnv64_t) {0xdc8be4c7UL, 0xf39a43d4UL} }, + { &fnv_test_str[157], (Fnv64_t) {0x1125d245UL, 0xd7f5cec9UL} }, + { &fnv_test_str[158], (Fnv64_t) {0xbe18adc4UL, 0x691d7b73UL} }, + { &fnv_test_str[159], (Fnv64_t) {0xcaf6b691UL, 0xf4361e01UL} }, + { &fnv_test_str[160], (Fnv64_t) {0xf64be089UL, 0xde7d8264UL} }, + { &fnv_test_str[161], (Fnv64_t) {0x5545c06fUL, 0xa34ff43eUL} }, + { &fnv_test_str[162], (Fnv64_t) {0x908a2bdeUL, 0x181f0b8eUL} }, + { &fnv_test_str[163], (Fnv64_t) {0x8ddbc071UL, 0x28a965b7UL} }, + { &fnv_test_str[164], (Fnv64_t) {0xe3cc6ae5UL, 0xead9cea0UL} }, + { &fnv_test_str[165], (Fnv64_t) {0x3b43ebbaUL, 0x0b674315UL} }, + { &fnv_test_str[166], (Fnv64_t) {0x2c74528dUL, 0xa7aa3f01UL} }, + { &fnv_test_str[167], (Fnv64_t) {0xf9dffeb7UL, 0x2d5d8ad7UL} }, + { &fnv_test_str[168], (Fnv64_t) {0xe19624eaUL, 0x00750fb6UL} }, + { &fnv_test_str[169], (Fnv64_t) {0xe6c76c82UL, 0x01c125a4UL} }, + { &fnv_test_str[170], (Fnv64_t) {0xc0722f1fUL, 0x3fde3afaUL} }, + { &fnv_test_str[171], (Fnv64_t) {0xabaa379dUL, 0xd7c3eaf4UL} }, + { &fnv_test_str[172], (Fnv64_t) {0x923c9f3fUL, 0xd2217e1cUL} }, + { &fnv_test_str[173], (Fnv64_t) {0xb725caf6UL, 0x82d0a2e3UL} }, + { &fnv_test_str[174], (Fnv64_t) {0xeeb72e4fUL, 0x0a10bee8UL} }, + { &fnv_test_str[175], (Fnv64_t) {0x3e72c6fdUL, 0xc530e872UL} }, + { &fnv_test_str[176], (Fnv64_t) {0x2e7bad99UL, 0xd8d34dcdUL} }, + { &fnv_test_str[177], (Fnv64_t) {0xe9a2baf3UL, 0xecf77466UL} }, + { &fnv_test_str[178], (Fnv64_t) {0x043b9666UL, 0xde3d2ddbUL} }, + { &fnv_test_str[179], (Fnv64_t) {0x1a8157d8UL, 0xd1cc824eUL} }, + { &fnv_test_str[180], (Fnv64_t) {0xbc90512eUL, 0x7d5c68ecUL} }, + { &fnv_test_str[181], (Fnv64_t) {0x1d7c76d8UL, 0x2f7c691bUL} }, + { &fnv_test_str[182], (Fnv64_t) {0xd3a46bc8UL, 0x5d88c2baUL} }, + { &fnv_test_str[183], (Fnv64_t) {0x276647a0UL, 0xdf107320UL} }, + { &fnv_test_str[184], (Fnv64_t) {0x7e70e9bcUL, 0x0f78f22eUL} }, + { &fnv_test_str[185], (Fnv64_t) {0x80f67d04UL, 0x8c67be5cUL} }, + { &fnv_test_str[186], (Fnv64_t) {0x4d019194UL, 0x07c1adfaUL} }, + { &fnv_test_str[187], (Fnv64_t) {0x0c5b1af4UL, 0xce131242UL} }, + { &fnv_test_str[188], (Fnv64_t) {0xdc53ab24UL, 0x043a41b2UL} }, + { &fnv_test_str[189], (Fnv64_t) {0xf7340860UL, 0x0b038eebUL} }, + { &fnv_test_str[190], (Fnv64_t) {0x53fb69b0UL, 0x1bcd8373UL} }, + { &fnv_test_str[191], (Fnv64_t) {0x59eff180UL, 0x46f992fcUL} }, + { &fnv_test_str[192], (Fnv64_t) {0x29ae79c0UL, 0x497678eeUL} }, + { &fnv_test_str[193], (Fnv64_t) {0x0ddd4450UL, 0xb10a6228UL} }, + { &fnv_test_str[194], (Fnv64_t) {0xb4d68140UL, 0x35eb228dUL} }, + { &fnv_test_str[195], (Fnv64_t) {0xd9470870UL, 0x8b350e86UL} }, + { &fnv_test_str[196], (Fnv64_t) {0x812e9540UL, 0x4e1fbdb2UL} }, + { &fnv_test_str[197], (Fnv64_t) {0xf69a0600UL, 0x051e080dUL} }, + { &fnv_test_str[198], (Fnv64_t) {0x54dadb40UL, 0x45e1e8aeUL} }, + { &fnv_test_str[199], (Fnv64_t) {0x00000000UL, 0x00000000UL} }, + { &fnv_test_str[200], (Fnv64_t) {0x90557064UL, 0xcd738062UL} }, + { &fnv_test_str[201], (Fnv64_t) {0xbe0317c8UL, 0x2613a37bUL} }, + { &fnv_test_str[202], (Fnv64_t) {0xcf2ae5e4UL, 0x1480e21fUL} }, + { NULL, (Fnv64_t) {0,0} } +}; +#endif /* HAVE_64BIT_LONG_LONG */ + +/* FNV-1 64 bit test vectors */ +#if defined(HAVE_64BIT_LONG_LONG) +struct fnv1_64_test_vector fnv1_64_vector[] = { + { &fnv_test_str[0], (Fnv64_t) 0xcbf29ce484222325ULL }, + { &fnv_test_str[1], (Fnv64_t) 0xaf63bd4c8601b7beULL }, + { &fnv_test_str[2], (Fnv64_t) 0xaf63bd4c8601b7bdULL }, + { &fnv_test_str[3], (Fnv64_t) 0xaf63bd4c8601b7bcULL }, + { &fnv_test_str[4], (Fnv64_t) 0xaf63bd4c8601b7bbULL }, + { &fnv_test_str[5], (Fnv64_t) 0xaf63bd4c8601b7baULL }, + { &fnv_test_str[6], (Fnv64_t) 0xaf63bd4c8601b7b9ULL }, + { &fnv_test_str[7], (Fnv64_t) 0x08326207b4eb2f34ULL }, + { &fnv_test_str[8], (Fnv64_t) 0xd8cbc7186ba13533ULL }, + { &fnv_test_str[9], (Fnv64_t) 0x0378817ee2ed65cbULL }, + { &fnv_test_str[10], (Fnv64_t) 0xd329d59b9963f790ULL }, + { &fnv_test_str[11], (Fnv64_t) 0x340d8765a4dda9c2ULL }, + { &fnv_test_str[12], (Fnv64_t) 0xaf63bd4c8601b7dfULL }, + { &fnv_test_str[13], (Fnv64_t) 0x08326707b4eb37daULL }, + { &fnv_test_str[14], (Fnv64_t) 0x08326607b4eb3627ULL }, + { &fnv_test_str[15], (Fnv64_t) 0x08326507b4eb3474ULL }, + { &fnv_test_str[16], (Fnv64_t) 0x08326407b4eb32c1ULL }, + { &fnv_test_str[17], (Fnv64_t) 0x08326307b4eb310eULL }, + { &fnv_test_str[18], (Fnv64_t) 0x08326207b4eb2f5bULL }, + { &fnv_test_str[19], (Fnv64_t) 0xd8cbc7186ba1355cULL }, + { &fnv_test_str[20], (Fnv64_t) 0x0378817ee2ed65a9ULL }, + { &fnv_test_str[21], (Fnv64_t) 0xd329d59b9963f7f1ULL }, + { &fnv_test_str[22], (Fnv64_t) 0x340d8765a4dda9b0ULL }, + { &fnv_test_str[23], (Fnv64_t) 0x50a6d3b724a774a6ULL }, + { &fnv_test_str[24], (Fnv64_t) 0x08326507b4eb341cULL }, + { &fnv_test_str[25], (Fnv64_t) 0xd8d5c8186ba98bfbULL }, + { &fnv_test_str[26], (Fnv64_t) 0x1ccefc7ef118dbefULL }, + { &fnv_test_str[27], (Fnv64_t) 0x0c92fab3ad3db77aULL }, + { &fnv_test_str[28], (Fnv64_t) 0x9b77794f5fdec421ULL }, + { &fnv_test_str[29], (Fnv64_t) 0x0ac742dfe7874433ULL }, + { &fnv_test_str[30], (Fnv64_t) 0xd7dad5766ad8e2deULL }, + { &fnv_test_str[31], (Fnv64_t) 0xa1bb96378e897f5bULL }, + { &fnv_test_str[32], (Fnv64_t) 0x5b3f9b6733a367d2ULL }, + { &fnv_test_str[33], (Fnv64_t) 0xb07ce25cbea969f6ULL }, + { &fnv_test_str[34], (Fnv64_t) 0x8d9e9997f9df0d6aULL }, + { &fnv_test_str[35], (Fnv64_t) 0x838c673d9603cb7bULL }, + { &fnv_test_str[36], (Fnv64_t) 0x8b5ee8a5e872c273ULL }, + { &fnv_test_str[37], (Fnv64_t) 0x4507c4e9fb00690cULL }, + { &fnv_test_str[38], (Fnv64_t) 0x4c9ca59581b27f45ULL }, + { &fnv_test_str[39], (Fnv64_t) 0xe0aca20b624e4235ULL }, + { &fnv_test_str[40], (Fnv64_t) 0xd8d5c8186ba98b94ULL }, + { &fnv_test_str[41], (Fnv64_t) 0x1ccefc7ef118db81ULL }, + { &fnv_test_str[42], (Fnv64_t) 0x0c92fab3ad3db71dULL }, + { &fnv_test_str[43], (Fnv64_t) 0x9b77794f5fdec44eULL }, + { &fnv_test_str[44], (Fnv64_t) 0x0ac742dfe7874413ULL }, + { &fnv_test_str[45], (Fnv64_t) 0xd7dad5766ad8e2a9ULL }, + { &fnv_test_str[46], (Fnv64_t) 0xa1bb96378e897f3aULL }, + { &fnv_test_str[47], (Fnv64_t) 0x5b3f9b6733a367a1ULL }, + { &fnv_test_str[48], (Fnv64_t) 0xb07ce25cbea969d6ULL }, + { &fnv_test_str[49], (Fnv64_t) 0x8d9e9997f9df0d02ULL }, + { &fnv_test_str[50], (Fnv64_t) 0x838c673d9603cb1eULL }, + { &fnv_test_str[51], (Fnv64_t) 0x8b5ee8a5e872c201ULL }, + { &fnv_test_str[52], (Fnv64_t) 0x4507c4e9fb006969ULL }, + { &fnv_test_str[53], (Fnv64_t) 0x4c9ca59581b27f64ULL }, + { &fnv_test_str[54], (Fnv64_t) 0xe0aca20b624e423fULL }, + { &fnv_test_str[55], (Fnv64_t) 0x13998e580afa800fULL }, + { &fnv_test_str[56], (Fnv64_t) 0x08326507b4eb3401ULL }, + { &fnv_test_str[57], (Fnv64_t) 0xd8d5ad186ba95dc1ULL }, + { &fnv_test_str[58], (Fnv64_t) 0x1c72e17ef0ca4e97ULL }, + { &fnv_test_str[59], (Fnv64_t) 0x2183c1b327c38ae6ULL }, + { &fnv_test_str[60], (Fnv64_t) 0xb66d096c914504f2ULL }, + { &fnv_test_str[61], (Fnv64_t) 0x404bf57ad8476757ULL }, + { &fnv_test_str[62], (Fnv64_t) 0x887976bd815498bbULL }, + { &fnv_test_str[63], (Fnv64_t) 0x3afd7f02c2bf85a5ULL }, + { &fnv_test_str[64], (Fnv64_t) 0xfc4476b0eb70177fULL }, + { &fnv_test_str[65], (Fnv64_t) 0x186d2da00f77ecbaULL }, + { &fnv_test_str[66], (Fnv64_t) 0xf97140fa48c74066ULL }, + { &fnv_test_str[67], (Fnv64_t) 0xa2b1cf49aa926d37ULL }, + { &fnv_test_str[68], (Fnv64_t) 0x0690712cd6cf940cULL }, + { &fnv_test_str[69], (Fnv64_t) 0xf7045b3102b8906eULL }, + { &fnv_test_str[70], (Fnv64_t) 0xd8d5ad186ba95db3ULL }, + { &fnv_test_str[71], (Fnv64_t) 0x1c72e17ef0ca4ef3ULL }, + { &fnv_test_str[72], (Fnv64_t) 0x2183c1b327c38a95ULL }, + { &fnv_test_str[73], (Fnv64_t) 0xb66d096c914504d2ULL }, + { &fnv_test_str[74], (Fnv64_t) 0x404bf57ad8476736ULL }, + { &fnv_test_str[75], (Fnv64_t) 0x887976bd815498d5ULL }, + { &fnv_test_str[76], (Fnv64_t) 0x3afd7f02c2bf85c1ULL }, + { &fnv_test_str[77], (Fnv64_t) 0xfc4476b0eb70175fULL }, + { &fnv_test_str[78], (Fnv64_t) 0x186d2da00f77eccdULL }, + { &fnv_test_str[79], (Fnv64_t) 0xf97140fa48c7400eULL }, + { &fnv_test_str[80], (Fnv64_t) 0xa2b1cf49aa926d52ULL }, + { &fnv_test_str[81], (Fnv64_t) 0x0690712cd6cf9475ULL }, + { &fnv_test_str[82], (Fnv64_t) 0xf7045b3102b89064ULL }, + { &fnv_test_str[83], (Fnv64_t) 0x74f762479f9d6aeaULL }, + { &fnv_test_str[84], (Fnv64_t) 0x08326007b4eb2b9cULL }, + { &fnv_test_str[85], (Fnv64_t) 0xd8c4c9186b9b1a14ULL }, + { &fnv_test_str[86], (Fnv64_t) 0x7b495389bdbdd4c7ULL }, + { &fnv_test_str[87], (Fnv64_t) 0x3b6dba0d69908e25ULL }, + { &fnv_test_str[88], (Fnv64_t) 0xd6b2b17bf4b71261ULL }, + { &fnv_test_str[89], (Fnv64_t) 0x447bfb7f98e615b5ULL }, + { &fnv_test_str[90], (Fnv64_t) 0xd6b2b17bf4b71262ULL }, + { &fnv_test_str[91], (Fnv64_t) 0x3bd2807f93fe1660ULL }, + { &fnv_test_str[92], (Fnv64_t) 0xd6b2b17bf4b71263ULL }, + { &fnv_test_str[93], (Fnv64_t) 0x3329057f8f16170bULL }, + { &fnv_test_str[94], (Fnv64_t) 0xd6b2b17bf4b71264ULL }, + { &fnv_test_str[95], (Fnv64_t) 0x2a7f8a7f8a2e19b6ULL }, + { &fnv_test_str[96], (Fnv64_t) 0x23d3767e64b2f98aULL }, + { &fnv_test_str[97], (Fnv64_t) 0xff768d7e4f9d86a4ULL }, + { &fnv_test_str[98], (Fnv64_t) 0x23d3767e64b2f984ULL }, + { &fnv_test_str[99], (Fnv64_t) 0xccd1837e334e4aa6ULL }, + { &fnv_test_str[100], (Fnv64_t) 0x23d3767e64b2f99aULL }, + { &fnv_test_str[101], (Fnv64_t) 0x7691fd7e028f6754ULL }, + { &fnv_test_str[102], (Fnv64_t) 0x34ad3b1041204318ULL }, + { &fnv_test_str[103], (Fnv64_t) 0xa29e749ea9d201c8ULL }, + { &fnv_test_str[104], (Fnv64_t) 0x34ad3b104120431bULL }, + { &fnv_test_str[105], (Fnv64_t) 0xa29e779ea9d206e1ULL }, + { &fnv_test_str[106], (Fnv64_t) 0x34ad3b104120431aULL }, + { &fnv_test_str[107], (Fnv64_t) 0xa29e769ea9d2052eULL }, + { &fnv_test_str[108], (Fnv64_t) 0x02a17ebca4aa3497ULL }, + { &fnv_test_str[109], (Fnv64_t) 0x229ef18bcd375c95ULL }, + { &fnv_test_str[110], (Fnv64_t) 0x02a17dbca4aa32c8ULL }, + { &fnv_test_str[111], (Fnv64_t) 0x229b6f8bcd3449d8ULL }, + { &fnv_test_str[112], (Fnv64_t) 0x02a184bca4aa3ed5ULL }, + { &fnv_test_str[113], (Fnv64_t) 0x22b3618bcd48c3efULL }, + { &fnv_test_str[114], (Fnv64_t) 0x5c2c346706186f36ULL }, + { &fnv_test_str[115], (Fnv64_t) 0xb78c410f5b84f8c2ULL }, + { &fnv_test_str[116], (Fnv64_t) 0xed9478212b267395ULL }, + { &fnv_test_str[117], (Fnv64_t) 0xd9bbb55c5256662fULL }, + { &fnv_test_str[118], (Fnv64_t) 0x8c54f0203249438aULL }, + { &fnv_test_str[119], (Fnv64_t) 0xbd9790b5727dc37eULL }, + { &fnv_test_str[120], (Fnv64_t) 0xa64e5f36c9e2b0e3ULL }, + { &fnv_test_str[121], (Fnv64_t) 0x8fd0680da3088a04ULL }, + { &fnv_test_str[122], (Fnv64_t) 0x67aad32c078284ccULL }, + { &fnv_test_str[123], (Fnv64_t) 0xb37d55d81c57b331ULL }, + { &fnv_test_str[124], (Fnv64_t) 0x55ac0f3829057c43ULL }, + { &fnv_test_str[125], (Fnv64_t) 0xcb27f4b8e1b6cc20ULL }, + { &fnv_test_str[126], (Fnv64_t) 0x26caf88bcbef2d19ULL }, + { &fnv_test_str[127], (Fnv64_t) 0x8e6e063b97e61b8fULL }, + { &fnv_test_str[128], (Fnv64_t) 0xb42750f7f3b7c37eULL }, + { &fnv_test_str[129], (Fnv64_t) 0xf3c6ba64cf7ca99bULL }, + { &fnv_test_str[130], (Fnv64_t) 0xebfb69b427ea80feULL }, + { &fnv_test_str[131], (Fnv64_t) 0x39b50c3ed970f46cULL }, + { &fnv_test_str[132], (Fnv64_t) 0x5b9b177aa3eb3e8aULL }, + { &fnv_test_str[133], (Fnv64_t) 0x6510063ecf4ec903ULL }, + { &fnv_test_str[134], (Fnv64_t) 0x2b3bbd2c00797c7aULL }, + { &fnv_test_str[135], (Fnv64_t) 0xf1d6204ff5cb4aa7ULL }, + { &fnv_test_str[136], (Fnv64_t) 0x4836e27ccf099f38ULL }, + { &fnv_test_str[137], (Fnv64_t) 0x82efbb0dd073b44dULL }, + { &fnv_test_str[138], (Fnv64_t) 0x4a80c282ffd7d4c6ULL }, + { &fnv_test_str[139], (Fnv64_t) 0x305d1a9c9ee43bdfULL }, + { &fnv_test_str[140], (Fnv64_t) 0x15c366948ffc6997ULL }, + { &fnv_test_str[141], (Fnv64_t) 0x80153ae218916e7bULL }, + { &fnv_test_str[142], (Fnv64_t) 0xfa23e2bdf9e2a9e1ULL }, + { &fnv_test_str[143], (Fnv64_t) 0xd47e8d8a2333c6deULL }, + { &fnv_test_str[144], (Fnv64_t) 0x7e128095f688b056ULL }, + { &fnv_test_str[145], (Fnv64_t) 0x2f5356890efcedabULL }, + { &fnv_test_str[146], (Fnv64_t) 0x95c2b383014f55c5ULL }, + { &fnv_test_str[147], (Fnv64_t) 0x4727a5339ce6070fULL }, + { &fnv_test_str[148], (Fnv64_t) 0xb0555ecd575108e9ULL }, + { &fnv_test_str[149], (Fnv64_t) 0x48d785770bb4af37ULL }, + { &fnv_test_str[150], (Fnv64_t) 0x09d4701c12af02b1ULL }, + { &fnv_test_str[151], (Fnv64_t) 0x79f031e78f3cf62eULL }, + { &fnv_test_str[152], (Fnv64_t) 0x52a1ee85db1b5a94ULL }, + { &fnv_test_str[153], (Fnv64_t) 0x6bd95b2eb37fa6b8ULL }, + { &fnv_test_str[154], (Fnv64_t) 0x74971b7077aef85dULL }, + { &fnv_test_str[155], (Fnv64_t) 0xb4e4fae2ffcc1aadULL }, + { &fnv_test_str[156], (Fnv64_t) 0x2bd48bd898b8f63aULL }, + { &fnv_test_str[157], (Fnv64_t) 0xe9966ac1556257f6ULL }, + { &fnv_test_str[158], (Fnv64_t) 0x92a3d1cd078ba293ULL }, + { &fnv_test_str[159], (Fnv64_t) 0xf81175a482e20ab8ULL }, + { &fnv_test_str[160], (Fnv64_t) 0x5bbb3de722e73048ULL }, + { &fnv_test_str[161], (Fnv64_t) 0x6b4f363492b9f2beULL }, + { &fnv_test_str[162], (Fnv64_t) 0xc2d559df73d59875ULL }, + { &fnv_test_str[163], (Fnv64_t) 0xf75f62284bc7a8c2ULL }, + { &fnv_test_str[164], (Fnv64_t) 0xda8dd8e116a9f1ccULL }, + { &fnv_test_str[165], (Fnv64_t) 0xbdc1e6ab76057885ULL }, + { &fnv_test_str[166], (Fnv64_t) 0xfec6a4238a1224a0ULL }, + { &fnv_test_str[167], (Fnv64_t) 0xc03f40f3223e290eULL }, + { &fnv_test_str[168], (Fnv64_t) 0x1ed21673466ffda9ULL }, + { &fnv_test_str[169], (Fnv64_t) 0xdf70f906bb0dd2afULL }, + { &fnv_test_str[170], (Fnv64_t) 0xf3dcda369f2af666ULL }, + { &fnv_test_str[171], (Fnv64_t) 0x9ebb11573cdcebdeULL }, + { &fnv_test_str[172], (Fnv64_t) 0x81c72d9077fedca0ULL }, + { &fnv_test_str[173], (Fnv64_t) 0x0ec074a31be5fb15ULL }, + { &fnv_test_str[174], (Fnv64_t) 0x2a8b3280b6c48f20ULL }, + { &fnv_test_str[175], (Fnv64_t) 0xfd31777513309344ULL }, + { &fnv_test_str[176], (Fnv64_t) 0x194534a86ad006b6ULL }, + { &fnv_test_str[177], (Fnv64_t) 0x3be6fdf46e0cfe12ULL }, + { &fnv_test_str[178], (Fnv64_t) 0x017cc137a07eb057ULL }, + { &fnv_test_str[179], (Fnv64_t) 0x9428fc6e7d26b54dULL }, + { &fnv_test_str[180], (Fnv64_t) 0x9aaa2e3603ef8ad7ULL }, + { &fnv_test_str[181], (Fnv64_t) 0x82c6d3f3a0ccdf7dULL }, + { &fnv_test_str[182], (Fnv64_t) 0xc86eeea00cf09b65ULL }, + { &fnv_test_str[183], (Fnv64_t) 0x705f8189dbb58299ULL }, + { &fnv_test_str[184], (Fnv64_t) 0x415a7f554391ca69ULL }, + { &fnv_test_str[185], (Fnv64_t) 0xcfe3d49fa2bdc555ULL }, + { &fnv_test_str[186], (Fnv64_t) 0xf0f9c56039b25191ULL }, + { &fnv_test_str[187], (Fnv64_t) 0x7075cb6abd1d32d9ULL }, + { &fnv_test_str[188], (Fnv64_t) 0x43c94e2c8b277509ULL }, + { &fnv_test_str[189], (Fnv64_t) 0x3cbfd4e4ea670359ULL }, + { &fnv_test_str[190], (Fnv64_t) 0xc05887810f4d019dULL }, + { &fnv_test_str[191], (Fnv64_t) 0x14468ff93ac22dc5ULL }, + { &fnv_test_str[192], (Fnv64_t) 0xebed699589d99c05ULL }, + { &fnv_test_str[193], (Fnv64_t) 0x6d99f6df321ca5d5ULL }, + { &fnv_test_str[194], (Fnv64_t) 0x0cd410d08c36d625ULL }, + { &fnv_test_str[195], (Fnv64_t) 0xef1b2a2c86831d35ULL }, + { &fnv_test_str[196], (Fnv64_t) 0x3b349c4d69ee5f05ULL }, + { &fnv_test_str[197], (Fnv64_t) 0x55248ce88f45f035ULL }, + { &fnv_test_str[198], (Fnv64_t) 0xaa69ca6a18a4c885ULL }, + { &fnv_test_str[199], (Fnv64_t) 0x1fe3fce62bd816b5ULL }, + { &fnv_test_str[200], (Fnv64_t) 0x0289a488a8df69d9ULL }, + { &fnv_test_str[201], (Fnv64_t) 0x15e96e1613df98b5ULL }, + { &fnv_test_str[202], (Fnv64_t) 0xe6be57375ad89b99ULL }, + { NULL, (Fnv64_t) 0 } +}; +#else /* HAVE_64BIT_LONG_LONG */ +struct fnv1_64_test_vector fnv1_64_vector[] = { + { &fnv_test_str[0], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} }, + { &fnv_test_str[1], (Fnv64_t) {0x8601b7beUL, 0xaf63bd4cUL} }, + { &fnv_test_str[2], (Fnv64_t) {0x8601b7bdUL, 0xaf63bd4cUL} }, + { &fnv_test_str[3], (Fnv64_t) {0x8601b7bcUL, 0xaf63bd4cUL} }, + { &fnv_test_str[4], (Fnv64_t) {0x8601b7bbUL, 0xaf63bd4cUL} }, + { &fnv_test_str[5], (Fnv64_t) {0x8601b7baUL, 0xaf63bd4cUL} }, + { &fnv_test_str[6], (Fnv64_t) {0x8601b7b9UL, 0xaf63bd4cUL} }, + { &fnv_test_str[7], (Fnv64_t) {0xb4eb2f34UL, 0x08326207UL} }, + { &fnv_test_str[8], (Fnv64_t) {0x6ba13533UL, 0xd8cbc718UL} }, + { &fnv_test_str[9], (Fnv64_t) {0xe2ed65cbUL, 0x0378817eUL} }, + { &fnv_test_str[10], (Fnv64_t) {0x9963f790UL, 0xd329d59bUL} }, + { &fnv_test_str[11], (Fnv64_t) {0xa4dda9c2UL, 0x340d8765UL} }, + { &fnv_test_str[12], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} }, + { &fnv_test_str[13], (Fnv64_t) {0xb4eb37daUL, 0x08326707UL} }, + { &fnv_test_str[14], (Fnv64_t) {0xb4eb3627UL, 0x08326607UL} }, + { &fnv_test_str[15], (Fnv64_t) {0xb4eb3474UL, 0x08326507UL} }, + { &fnv_test_str[16], (Fnv64_t) {0xb4eb32c1UL, 0x08326407UL} }, + { &fnv_test_str[17], (Fnv64_t) {0xb4eb310eUL, 0x08326307UL} }, + { &fnv_test_str[18], (Fnv64_t) {0xb4eb2f5bUL, 0x08326207UL} }, + { &fnv_test_str[19], (Fnv64_t) {0x6ba1355cUL, 0xd8cbc718UL} }, + { &fnv_test_str[20], (Fnv64_t) {0xe2ed65a9UL, 0x0378817eUL} }, + { &fnv_test_str[21], (Fnv64_t) {0x9963f7f1UL, 0xd329d59bUL} }, + { &fnv_test_str[22], (Fnv64_t) {0xa4dda9b0UL, 0x340d8765UL} }, + { &fnv_test_str[23], (Fnv64_t) {0x24a774a6UL, 0x50a6d3b7UL} }, + { &fnv_test_str[24], (Fnv64_t) {0xb4eb341cUL, 0x08326507UL} }, + { &fnv_test_str[25], (Fnv64_t) {0x6ba98bfbUL, 0xd8d5c818UL} }, + { &fnv_test_str[26], (Fnv64_t) {0xf118dbefUL, 0x1ccefc7eUL} }, + { &fnv_test_str[27], (Fnv64_t) {0xad3db77aUL, 0x0c92fab3UL} }, + { &fnv_test_str[28], (Fnv64_t) {0x5fdec421UL, 0x9b77794fUL} }, + { &fnv_test_str[29], (Fnv64_t) {0xe7874433UL, 0x0ac742dfUL} }, + { &fnv_test_str[30], (Fnv64_t) {0x6ad8e2deUL, 0xd7dad576UL} }, + { &fnv_test_str[31], (Fnv64_t) {0x8e897f5bUL, 0xa1bb9637UL} }, + { &fnv_test_str[32], (Fnv64_t) {0x33a367d2UL, 0x5b3f9b67UL} }, + { &fnv_test_str[33], (Fnv64_t) {0xbea969f6UL, 0xb07ce25cUL} }, + { &fnv_test_str[34], (Fnv64_t) {0xf9df0d6aUL, 0x8d9e9997UL} }, + { &fnv_test_str[35], (Fnv64_t) {0x9603cb7bUL, 0x838c673dUL} }, + { &fnv_test_str[36], (Fnv64_t) {0xe872c273UL, 0x8b5ee8a5UL} }, + { &fnv_test_str[37], (Fnv64_t) {0xfb00690cUL, 0x4507c4e9UL} }, + { &fnv_test_str[38], (Fnv64_t) {0x81b27f45UL, 0x4c9ca595UL} }, + { &fnv_test_str[39], (Fnv64_t) {0x624e4235UL, 0xe0aca20bUL} }, + { &fnv_test_str[40], (Fnv64_t) {0x6ba98b94UL, 0xd8d5c818UL} }, + { &fnv_test_str[41], (Fnv64_t) {0xf118db81UL, 0x1ccefc7eUL} }, + { &fnv_test_str[42], (Fnv64_t) {0xad3db71dUL, 0x0c92fab3UL} }, + { &fnv_test_str[43], (Fnv64_t) {0x5fdec44eUL, 0x9b77794fUL} }, + { &fnv_test_str[44], (Fnv64_t) {0xe7874413UL, 0x0ac742dfUL} }, + { &fnv_test_str[45], (Fnv64_t) {0x6ad8e2a9UL, 0xd7dad576UL} }, + { &fnv_test_str[46], (Fnv64_t) {0x8e897f3aUL, 0xa1bb9637UL} }, + { &fnv_test_str[47], (Fnv64_t) {0x33a367a1UL, 0x5b3f9b67UL} }, + { &fnv_test_str[48], (Fnv64_t) {0xbea969d6UL, 0xb07ce25cUL} }, + { &fnv_test_str[49], (Fnv64_t) {0xf9df0d02UL, 0x8d9e9997UL} }, + { &fnv_test_str[50], (Fnv64_t) {0x9603cb1eUL, 0x838c673dUL} }, + { &fnv_test_str[51], (Fnv64_t) {0xe872c201UL, 0x8b5ee8a5UL} }, + { &fnv_test_str[52], (Fnv64_t) {0xfb006969UL, 0x4507c4e9UL} }, + { &fnv_test_str[53], (Fnv64_t) {0x81b27f64UL, 0x4c9ca595UL} }, + { &fnv_test_str[54], (Fnv64_t) {0x624e423fUL, 0xe0aca20bUL} }, + { &fnv_test_str[55], (Fnv64_t) {0x0afa800fUL, 0x13998e58UL} }, + { &fnv_test_str[56], (Fnv64_t) {0xb4eb3401UL, 0x08326507UL} }, + { &fnv_test_str[57], (Fnv64_t) {0x6ba95dc1UL, 0xd8d5ad18UL} }, + { &fnv_test_str[58], (Fnv64_t) {0xf0ca4e97UL, 0x1c72e17eUL} }, + { &fnv_test_str[59], (Fnv64_t) {0x27c38ae6UL, 0x2183c1b3UL} }, + { &fnv_test_str[60], (Fnv64_t) {0x914504f2UL, 0xb66d096cUL} }, + { &fnv_test_str[61], (Fnv64_t) {0xd8476757UL, 0x404bf57aUL} }, + { &fnv_test_str[62], (Fnv64_t) {0x815498bbUL, 0x887976bdUL} }, + { &fnv_test_str[63], (Fnv64_t) {0xc2bf85a5UL, 0x3afd7f02UL} }, + { &fnv_test_str[64], (Fnv64_t) {0xeb70177fUL, 0xfc4476b0UL} }, + { &fnv_test_str[65], (Fnv64_t) {0x0f77ecbaUL, 0x186d2da0UL} }, + { &fnv_test_str[66], (Fnv64_t) {0x48c74066UL, 0xf97140faUL} }, + { &fnv_test_str[67], (Fnv64_t) {0xaa926d37UL, 0xa2b1cf49UL} }, + { &fnv_test_str[68], (Fnv64_t) {0xd6cf940cUL, 0x0690712cUL} }, + { &fnv_test_str[69], (Fnv64_t) {0x02b8906eUL, 0xf7045b31UL} }, + { &fnv_test_str[70], (Fnv64_t) {0x6ba95db3UL, 0xd8d5ad18UL} }, + { &fnv_test_str[71], (Fnv64_t) {0xf0ca4ef3UL, 0x1c72e17eUL} }, + { &fnv_test_str[72], (Fnv64_t) {0x27c38a95UL, 0x2183c1b3UL} }, + { &fnv_test_str[73], (Fnv64_t) {0x914504d2UL, 0xb66d096cUL} }, + { &fnv_test_str[74], (Fnv64_t) {0xd8476736UL, 0x404bf57aUL} }, + { &fnv_test_str[75], (Fnv64_t) {0x815498d5UL, 0x887976bdUL} }, + { &fnv_test_str[76], (Fnv64_t) {0xc2bf85c1UL, 0x3afd7f02UL} }, + { &fnv_test_str[77], (Fnv64_t) {0xeb70175fUL, 0xfc4476b0UL} }, + { &fnv_test_str[78], (Fnv64_t) {0x0f77eccdUL, 0x186d2da0UL} }, + { &fnv_test_str[79], (Fnv64_t) {0x48c7400eUL, 0xf97140faUL} }, + { &fnv_test_str[80], (Fnv64_t) {0xaa926d52UL, 0xa2b1cf49UL} }, + { &fnv_test_str[81], (Fnv64_t) {0xd6cf9475UL, 0x0690712cUL} }, + { &fnv_test_str[82], (Fnv64_t) {0x02b89064UL, 0xf7045b31UL} }, + { &fnv_test_str[83], (Fnv64_t) {0x9f9d6aeaUL, 0x74f76247UL} }, + { &fnv_test_str[84], (Fnv64_t) {0xb4eb2b9cUL, 0x08326007UL} }, + { &fnv_test_str[85], (Fnv64_t) {0x6b9b1a14UL, 0xd8c4c918UL} }, + { &fnv_test_str[86], (Fnv64_t) {0xbdbdd4c7UL, 0x7b495389UL} }, + { &fnv_test_str[87], (Fnv64_t) {0x69908e25UL, 0x3b6dba0dUL} }, + { &fnv_test_str[88], (Fnv64_t) {0xf4b71261UL, 0xd6b2b17bUL} }, + { &fnv_test_str[89], (Fnv64_t) {0x98e615b5UL, 0x447bfb7fUL} }, + { &fnv_test_str[90], (Fnv64_t) {0xf4b71262UL, 0xd6b2b17bUL} }, + { &fnv_test_str[91], (Fnv64_t) {0x93fe1660UL, 0x3bd2807fUL} }, + { &fnv_test_str[92], (Fnv64_t) {0xf4b71263UL, 0xd6b2b17bUL} }, + { &fnv_test_str[93], (Fnv64_t) {0x8f16170bUL, 0x3329057fUL} }, + { &fnv_test_str[94], (Fnv64_t) {0xf4b71264UL, 0xd6b2b17bUL} }, + { &fnv_test_str[95], (Fnv64_t) {0x8a2e19b6UL, 0x2a7f8a7fUL} }, + { &fnv_test_str[96], (Fnv64_t) {0x64b2f98aUL, 0x23d3767eUL} }, + { &fnv_test_str[97], (Fnv64_t) {0x4f9d86a4UL, 0xff768d7eUL} }, + { &fnv_test_str[98], (Fnv64_t) {0x64b2f984UL, 0x23d3767eUL} }, + { &fnv_test_str[99], (Fnv64_t) {0x334e4aa6UL, 0xccd1837eUL} }, + { &fnv_test_str[100], (Fnv64_t) {0x64b2f99aUL, 0x23d3767eUL} }, + { &fnv_test_str[101], (Fnv64_t) {0x028f6754UL, 0x7691fd7eUL} }, + { &fnv_test_str[102], (Fnv64_t) {0x41204318UL, 0x34ad3b10UL} }, + { &fnv_test_str[103], (Fnv64_t) {0xa9d201c8UL, 0xa29e749eUL} }, + { &fnv_test_str[104], (Fnv64_t) {0x4120431bUL, 0x34ad3b10UL} }, + { &fnv_test_str[105], (Fnv64_t) {0xa9d206e1UL, 0xa29e779eUL} }, + { &fnv_test_str[106], (Fnv64_t) {0x4120431aUL, 0x34ad3b10UL} }, + { &fnv_test_str[107], (Fnv64_t) {0xa9d2052eUL, 0xa29e769eUL} }, + { &fnv_test_str[108], (Fnv64_t) {0xa4aa3497UL, 0x02a17ebcUL} }, + { &fnv_test_str[109], (Fnv64_t) {0xcd375c95UL, 0x229ef18bUL} }, + { &fnv_test_str[110], (Fnv64_t) {0xa4aa32c8UL, 0x02a17dbcUL} }, + { &fnv_test_str[111], (Fnv64_t) {0xcd3449d8UL, 0x229b6f8bUL} }, + { &fnv_test_str[112], (Fnv64_t) {0xa4aa3ed5UL, 0x02a184bcUL} }, + { &fnv_test_str[113], (Fnv64_t) {0xcd48c3efUL, 0x22b3618bUL} }, + { &fnv_test_str[114], (Fnv64_t) {0x06186f36UL, 0x5c2c3467UL} }, + { &fnv_test_str[115], (Fnv64_t) {0x5b84f8c2UL, 0xb78c410fUL} }, + { &fnv_test_str[116], (Fnv64_t) {0x2b267395UL, 0xed947821UL} }, + { &fnv_test_str[117], (Fnv64_t) {0x5256662fUL, 0xd9bbb55cUL} }, + { &fnv_test_str[118], (Fnv64_t) {0x3249438aUL, 0x8c54f020UL} }, + { &fnv_test_str[119], (Fnv64_t) {0x727dc37eUL, 0xbd9790b5UL} }, + { &fnv_test_str[120], (Fnv64_t) {0xc9e2b0e3UL, 0xa64e5f36UL} }, + { &fnv_test_str[121], (Fnv64_t) {0xa3088a04UL, 0x8fd0680dUL} }, + { &fnv_test_str[122], (Fnv64_t) {0x078284ccUL, 0x67aad32cUL} }, + { &fnv_test_str[123], (Fnv64_t) {0x1c57b331UL, 0xb37d55d8UL} }, + { &fnv_test_str[124], (Fnv64_t) {0x29057c43UL, 0x55ac0f38UL} }, + { &fnv_test_str[125], (Fnv64_t) {0xe1b6cc20UL, 0xcb27f4b8UL} }, + { &fnv_test_str[126], (Fnv64_t) {0xcbef2d19UL, 0x26caf88bUL} }, + { &fnv_test_str[127], (Fnv64_t) {0x97e61b8fUL, 0x8e6e063bUL} }, + { &fnv_test_str[128], (Fnv64_t) {0xf3b7c37eUL, 0xb42750f7UL} }, + { &fnv_test_str[129], (Fnv64_t) {0xcf7ca99bUL, 0xf3c6ba64UL} }, + { &fnv_test_str[130], (Fnv64_t) {0x27ea80feUL, 0xebfb69b4UL} }, + { &fnv_test_str[131], (Fnv64_t) {0xd970f46cUL, 0x39b50c3eUL} }, + { &fnv_test_str[132], (Fnv64_t) {0xa3eb3e8aUL, 0x5b9b177aUL} }, + { &fnv_test_str[133], (Fnv64_t) {0xcf4ec903UL, 0x6510063eUL} }, + { &fnv_test_str[134], (Fnv64_t) {0x00797c7aUL, 0x2b3bbd2cUL} }, + { &fnv_test_str[135], (Fnv64_t) {0xf5cb4aa7UL, 0xf1d6204fUL} }, + { &fnv_test_str[136], (Fnv64_t) {0xcf099f38UL, 0x4836e27cUL} }, + { &fnv_test_str[137], (Fnv64_t) {0xd073b44dUL, 0x82efbb0dUL} }, + { &fnv_test_str[138], (Fnv64_t) {0xffd7d4c6UL, 0x4a80c282UL} }, + { &fnv_test_str[139], (Fnv64_t) {0x9ee43bdfUL, 0x305d1a9cUL} }, + { &fnv_test_str[140], (Fnv64_t) {0x8ffc6997UL, 0x15c36694UL} }, + { &fnv_test_str[141], (Fnv64_t) {0x18916e7bUL, 0x80153ae2UL} }, + { &fnv_test_str[142], (Fnv64_t) {0xf9e2a9e1UL, 0xfa23e2bdUL} }, + { &fnv_test_str[143], (Fnv64_t) {0x2333c6deUL, 0xd47e8d8aUL} }, + { &fnv_test_str[144], (Fnv64_t) {0xf688b056UL, 0x7e128095UL} }, + { &fnv_test_str[145], (Fnv64_t) {0x0efcedabUL, 0x2f535689UL} }, + { &fnv_test_str[146], (Fnv64_t) {0x014f55c5UL, 0x95c2b383UL} }, + { &fnv_test_str[147], (Fnv64_t) {0x9ce6070fUL, 0x4727a533UL} }, + { &fnv_test_str[148], (Fnv64_t) {0x575108e9UL, 0xb0555ecdUL} }, + { &fnv_test_str[149], (Fnv64_t) {0x0bb4af37UL, 0x48d78577UL} }, + { &fnv_test_str[150], (Fnv64_t) {0x12af02b1UL, 0x09d4701cUL} }, + { &fnv_test_str[151], (Fnv64_t) {0x8f3cf62eUL, 0x79f031e7UL} }, + { &fnv_test_str[152], (Fnv64_t) {0xdb1b5a94UL, 0x52a1ee85UL} }, + { &fnv_test_str[153], (Fnv64_t) {0xb37fa6b8UL, 0x6bd95b2eUL} }, + { &fnv_test_str[154], (Fnv64_t) {0x77aef85dUL, 0x74971b70UL} }, + { &fnv_test_str[155], (Fnv64_t) {0xffcc1aadUL, 0xb4e4fae2UL} }, + { &fnv_test_str[156], (Fnv64_t) {0x98b8f63aUL, 0x2bd48bd8UL} }, + { &fnv_test_str[157], (Fnv64_t) {0x556257f6UL, 0xe9966ac1UL} }, + { &fnv_test_str[158], (Fnv64_t) {0x078ba293UL, 0x92a3d1cdUL} }, + { &fnv_test_str[159], (Fnv64_t) {0x82e20ab8UL, 0xf81175a4UL} }, + { &fnv_test_str[160], (Fnv64_t) {0x22e73048UL, 0x5bbb3de7UL} }, + { &fnv_test_str[161], (Fnv64_t) {0x92b9f2beUL, 0x6b4f3634UL} }, + { &fnv_test_str[162], (Fnv64_t) {0x73d59875UL, 0xc2d559dfUL} }, + { &fnv_test_str[163], (Fnv64_t) {0x4bc7a8c2UL, 0xf75f6228UL} }, + { &fnv_test_str[164], (Fnv64_t) {0x16a9f1ccUL, 0xda8dd8e1UL} }, + { &fnv_test_str[165], (Fnv64_t) {0x76057885UL, 0xbdc1e6abUL} }, + { &fnv_test_str[166], (Fnv64_t) {0x8a1224a0UL, 0xfec6a423UL} }, + { &fnv_test_str[167], (Fnv64_t) {0x223e290eUL, 0xc03f40f3UL} }, + { &fnv_test_str[168], (Fnv64_t) {0x466ffda9UL, 0x1ed21673UL} }, + { &fnv_test_str[169], (Fnv64_t) {0xbb0dd2afUL, 0xdf70f906UL} }, + { &fnv_test_str[170], (Fnv64_t) {0x9f2af666UL, 0xf3dcda36UL} }, + { &fnv_test_str[171], (Fnv64_t) {0x3cdcebdeUL, 0x9ebb1157UL} }, + { &fnv_test_str[172], (Fnv64_t) {0x77fedca0UL, 0x81c72d90UL} }, + { &fnv_test_str[173], (Fnv64_t) {0x1be5fb15UL, 0x0ec074a3UL} }, + { &fnv_test_str[174], (Fnv64_t) {0xb6c48f20UL, 0x2a8b3280UL} }, + { &fnv_test_str[175], (Fnv64_t) {0x13309344UL, 0xfd317775UL} }, + { &fnv_test_str[176], (Fnv64_t) {0x6ad006b6UL, 0x194534a8UL} }, + { &fnv_test_str[177], (Fnv64_t) {0x6e0cfe12UL, 0x3be6fdf4UL} }, + { &fnv_test_str[178], (Fnv64_t) {0xa07eb057UL, 0x017cc137UL} }, + { &fnv_test_str[179], (Fnv64_t) {0x7d26b54dUL, 0x9428fc6eUL} }, + { &fnv_test_str[180], (Fnv64_t) {0x03ef8ad7UL, 0x9aaa2e36UL} }, + { &fnv_test_str[181], (Fnv64_t) {0xa0ccdf7dUL, 0x82c6d3f3UL} }, + { &fnv_test_str[182], (Fnv64_t) {0x0cf09b65UL, 0xc86eeea0UL} }, + { &fnv_test_str[183], (Fnv64_t) {0xdbb58299UL, 0x705f8189UL} }, + { &fnv_test_str[184], (Fnv64_t) {0x4391ca69UL, 0x415a7f55UL} }, + { &fnv_test_str[185], (Fnv64_t) {0xa2bdc555UL, 0xcfe3d49fUL} }, + { &fnv_test_str[186], (Fnv64_t) {0x39b25191UL, 0xf0f9c560UL} }, + { &fnv_test_str[187], (Fnv64_t) {0xbd1d32d9UL, 0x7075cb6aUL} }, + { &fnv_test_str[188], (Fnv64_t) {0x8b277509UL, 0x43c94e2cUL} }, + { &fnv_test_str[189], (Fnv64_t) {0xea670359UL, 0x3cbfd4e4UL} }, + { &fnv_test_str[190], (Fnv64_t) {0x0f4d019dUL, 0xc0588781UL} }, + { &fnv_test_str[191], (Fnv64_t) {0x3ac22dc5UL, 0x14468ff9UL} }, + { &fnv_test_str[192], (Fnv64_t) {0x89d99c05UL, 0xebed6995UL} }, + { &fnv_test_str[193], (Fnv64_t) {0x321ca5d5UL, 0x6d99f6dfUL} }, + { &fnv_test_str[194], (Fnv64_t) {0x8c36d625UL, 0x0cd410d0UL} }, + { &fnv_test_str[195], (Fnv64_t) {0x86831d35UL, 0xef1b2a2cUL} }, + { &fnv_test_str[196], (Fnv64_t) {0x69ee5f05UL, 0x3b349c4dUL} }, + { &fnv_test_str[197], (Fnv64_t) {0x8f45f035UL, 0x55248ce8UL} }, + { &fnv_test_str[198], (Fnv64_t) {0x18a4c885UL, 0xaa69ca6aUL} }, + { &fnv_test_str[199], (Fnv64_t) {0x2bd816b5UL, 0x1fe3fce6UL} }, + { &fnv_test_str[200], (Fnv64_t) {0xa8df69d9UL, 0x0289a488UL} }, + { &fnv_test_str[201], (Fnv64_t) {0x13df98b5UL, 0x15e96e16UL} }, + { &fnv_test_str[202], (Fnv64_t) {0x5ad89b99UL, 0xe6be5737UL} }, + { NULL, (Fnv64_t) {0,0} } +}; +#endif /* HAVE_64BIT_LONG_LONG */ + +/* FNV-1a 64 bit test vectors */ +#if defined(HAVE_64BIT_LONG_LONG) +struct fnv1a_64_test_vector fnv1a_64_vector[] = { + { &fnv_test_str[0], (Fnv64_t) 0xcbf29ce484222325ULL }, + { &fnv_test_str[1], (Fnv64_t) 0xaf63dc4c8601ec8cULL }, + { &fnv_test_str[2], (Fnv64_t) 0xaf63df4c8601f1a5ULL }, + { &fnv_test_str[3], (Fnv64_t) 0xaf63de4c8601eff2ULL }, + { &fnv_test_str[4], (Fnv64_t) 0xaf63d94c8601e773ULL }, + { &fnv_test_str[5], (Fnv64_t) 0xaf63d84c8601e5c0ULL }, + { &fnv_test_str[6], (Fnv64_t) 0xaf63db4c8601ead9ULL }, + { &fnv_test_str[7], (Fnv64_t) 0x08985907b541d342ULL }, + { &fnv_test_str[8], (Fnv64_t) 0xdcb27518fed9d577ULL }, + { &fnv_test_str[9], (Fnv64_t) 0xdd120e790c2512afULL }, + { &fnv_test_str[10], (Fnv64_t) 0xcac165afa2fef40aULL }, + { &fnv_test_str[11], (Fnv64_t) 0x85944171f73967e8ULL }, + { &fnv_test_str[12], (Fnv64_t) 0xaf63bd4c8601b7dfULL }, + { &fnv_test_str[13], (Fnv64_t) 0x089be207b544f1e4ULL }, + { &fnv_test_str[14], (Fnv64_t) 0x08a61407b54d9b5fULL }, + { &fnv_test_str[15], (Fnv64_t) 0x08a2ae07b54ab836ULL }, + { &fnv_test_str[16], (Fnv64_t) 0x0891b007b53c4869ULL }, + { &fnv_test_str[17], (Fnv64_t) 0x088e4a07b5396540ULL }, + { &fnv_test_str[18], (Fnv64_t) 0x08987c07b5420ebbULL }, + { &fnv_test_str[19], (Fnv64_t) 0xdcb28a18fed9f926ULL }, + { &fnv_test_str[20], (Fnv64_t) 0xdd1270790c25b935ULL }, + { &fnv_test_str[21], (Fnv64_t) 0xcac146afa2febf5dULL }, + { &fnv_test_str[22], (Fnv64_t) 0x8593d371f738acfeULL }, + { &fnv_test_str[23], (Fnv64_t) 0x34531ca7168b8f38ULL }, + { &fnv_test_str[24], (Fnv64_t) 0x08a25607b54a22aeULL }, + { &fnv_test_str[25], (Fnv64_t) 0xf5faf0190cf90df3ULL }, + { &fnv_test_str[26], (Fnv64_t) 0xf27397910b3221c7ULL }, + { &fnv_test_str[27], (Fnv64_t) 0x2c8c2b76062f22e0ULL }, + { &fnv_test_str[28], (Fnv64_t) 0xe150688c8217b8fdULL }, + { &fnv_test_str[29], (Fnv64_t) 0xf35a83c10e4f1f87ULL }, + { &fnv_test_str[30], (Fnv64_t) 0xd1edd10b507344d0ULL }, + { &fnv_test_str[31], (Fnv64_t) 0x2a5ee739b3ddb8c3ULL }, + { &fnv_test_str[32], (Fnv64_t) 0xdcfb970ca1c0d310ULL }, + { &fnv_test_str[33], (Fnv64_t) 0x4054da76daa6da90ULL }, + { &fnv_test_str[34], (Fnv64_t) 0xf70a2ff589861368ULL }, + { &fnv_test_str[35], (Fnv64_t) 0x4c628b38aed25f17ULL }, + { &fnv_test_str[36], (Fnv64_t) 0x9dd1f6510f78189fULL }, + { &fnv_test_str[37], (Fnv64_t) 0xa3de85bd491270ceULL }, + { &fnv_test_str[38], (Fnv64_t) 0x858e2fa32a55e61dULL }, + { &fnv_test_str[39], (Fnv64_t) 0x46810940eff5f915ULL }, + { &fnv_test_str[40], (Fnv64_t) 0xf5fadd190cf8edaaULL }, + { &fnv_test_str[41], (Fnv64_t) 0xf273ed910b32b3e9ULL }, + { &fnv_test_str[42], (Fnv64_t) 0x2c8c5276062f6525ULL }, + { &fnv_test_str[43], (Fnv64_t) 0xe150b98c821842a0ULL }, + { &fnv_test_str[44], (Fnv64_t) 0xf35aa3c10e4f55e7ULL }, + { &fnv_test_str[45], (Fnv64_t) 0xd1ed680b50729265ULL }, + { &fnv_test_str[46], (Fnv64_t) 0x2a5f0639b3dded70ULL }, + { &fnv_test_str[47], (Fnv64_t) 0xdcfbaa0ca1c0f359ULL }, + { &fnv_test_str[48], (Fnv64_t) 0x4054ba76daa6a430ULL }, + { &fnv_test_str[49], (Fnv64_t) 0xf709c7f5898562b0ULL }, + { &fnv_test_str[50], (Fnv64_t) 0x4c62e638aed2f9b8ULL }, + { &fnv_test_str[51], (Fnv64_t) 0x9dd1a8510f779415ULL }, + { &fnv_test_str[52], (Fnv64_t) 0xa3de2abd4911d62dULL }, + { &fnv_test_str[53], (Fnv64_t) 0x858e0ea32a55ae0aULL }, + { &fnv_test_str[54], (Fnv64_t) 0x46810f40eff60347ULL }, + { &fnv_test_str[55], (Fnv64_t) 0xc33bce57bef63eafULL }, + { &fnv_test_str[56], (Fnv64_t) 0x08a24307b54a0265ULL }, + { &fnv_test_str[57], (Fnv64_t) 0xf5b9fd190cc18d15ULL }, + { &fnv_test_str[58], (Fnv64_t) 0x4c968290ace35703ULL }, + { &fnv_test_str[59], (Fnv64_t) 0x07174bd5c64d9350ULL }, + { &fnv_test_str[60], (Fnv64_t) 0x5a294c3ff5d18750ULL }, + { &fnv_test_str[61], (Fnv64_t) 0x05b3c1aeb308b843ULL }, + { &fnv_test_str[62], (Fnv64_t) 0xb92a48da37d0f477ULL }, + { &fnv_test_str[63], (Fnv64_t) 0x73cdddccd80ebc49ULL }, + { &fnv_test_str[64], (Fnv64_t) 0xd58c4c13210a266bULL }, + { &fnv_test_str[65], (Fnv64_t) 0xe78b6081243ec194ULL }, + { &fnv_test_str[66], (Fnv64_t) 0xb096f77096a39f34ULL }, + { &fnv_test_str[67], (Fnv64_t) 0xb425c54ff807b6a3ULL }, + { &fnv_test_str[68], (Fnv64_t) 0x23e520e2751bb46eULL }, + { &fnv_test_str[69], (Fnv64_t) 0x1a0b44ccfe1385ecULL }, + { &fnv_test_str[70], (Fnv64_t) 0xf5ba4b190cc2119fULL }, + { &fnv_test_str[71], (Fnv64_t) 0x4c962690ace2baafULL }, + { &fnv_test_str[72], (Fnv64_t) 0x0716ded5c64cda19ULL }, + { &fnv_test_str[73], (Fnv64_t) 0x5a292c3ff5d150f0ULL }, + { &fnv_test_str[74], (Fnv64_t) 0x05b3e0aeb308ecf0ULL }, + { &fnv_test_str[75], (Fnv64_t) 0xb92a5eda37d119d9ULL }, + { &fnv_test_str[76], (Fnv64_t) 0x73ce41ccd80f6635ULL }, + { &fnv_test_str[77], (Fnv64_t) 0xd58c2c132109f00bULL }, + { &fnv_test_str[78], (Fnv64_t) 0xe78baf81243f47d1ULL }, + { &fnv_test_str[79], (Fnv64_t) 0xb0968f7096a2ee7cULL }, + { &fnv_test_str[80], (Fnv64_t) 0xb425a84ff807855cULL }, + { &fnv_test_str[81], (Fnv64_t) 0x23e4e9e2751b56f9ULL }, + { &fnv_test_str[82], (Fnv64_t) 0x1a0b4eccfe1396eaULL }, + { &fnv_test_str[83], (Fnv64_t) 0x54abd453bb2c9004ULL }, + { &fnv_test_str[84], (Fnv64_t) 0x08ba5f07b55ec3daULL }, + { &fnv_test_str[85], (Fnv64_t) 0x337354193006cb6eULL }, + { &fnv_test_str[86], (Fnv64_t) 0xa430d84680aabd0bULL }, + { &fnv_test_str[87], (Fnv64_t) 0xa9bc8acca21f39b1ULL }, + { &fnv_test_str[88], (Fnv64_t) 0x6961196491cc682dULL }, + { &fnv_test_str[89], (Fnv64_t) 0xad2bb1774799dfe9ULL }, + { &fnv_test_str[90], (Fnv64_t) 0x6961166491cc6314ULL }, + { &fnv_test_str[91], (Fnv64_t) 0x8d1bb3904a3b1236ULL }, + { &fnv_test_str[92], (Fnv64_t) 0x6961176491cc64c7ULL }, + { &fnv_test_str[93], (Fnv64_t) 0xed205d87f40434c7ULL }, + { &fnv_test_str[94], (Fnv64_t) 0x6961146491cc5faeULL }, + { &fnv_test_str[95], (Fnv64_t) 0xcd3baf5e44f8ad9cULL }, + { &fnv_test_str[96], (Fnv64_t) 0xe3b36596127cd6d8ULL }, + { &fnv_test_str[97], (Fnv64_t) 0xf77f1072c8e8a646ULL }, + { &fnv_test_str[98], (Fnv64_t) 0xe3b36396127cd372ULL }, + { &fnv_test_str[99], (Fnv64_t) 0x6067dce9932ad458ULL }, + { &fnv_test_str[100], (Fnv64_t) 0xe3b37596127cf208ULL }, + { &fnv_test_str[101], (Fnv64_t) 0x4b7b10fa9fe83936ULL }, + { &fnv_test_str[102], (Fnv64_t) 0xaabafe7104d914beULL }, + { &fnv_test_str[103], (Fnv64_t) 0xf4d3180b3cde3edaULL }, + { &fnv_test_str[104], (Fnv64_t) 0xaabafd7104d9130bULL }, + { &fnv_test_str[105], (Fnv64_t) 0xf4cfb20b3cdb5bb1ULL }, + { &fnv_test_str[106], (Fnv64_t) 0xaabafc7104d91158ULL }, + { &fnv_test_str[107], (Fnv64_t) 0xf4cc4c0b3cd87888ULL }, + { &fnv_test_str[108], (Fnv64_t) 0xe729bac5d2a8d3a7ULL }, + { &fnv_test_str[109], (Fnv64_t) 0x74bc0524f4dfa4c5ULL }, + { &fnv_test_str[110], (Fnv64_t) 0xe72630c5d2a5b352ULL }, + { &fnv_test_str[111], (Fnv64_t) 0x6b983224ef8fb456ULL }, + { &fnv_test_str[112], (Fnv64_t) 0xe73042c5d2ae266dULL }, + { &fnv_test_str[113], (Fnv64_t) 0x8527e324fdeb4b37ULL }, + { &fnv_test_str[114], (Fnv64_t) 0x0a83c86fee952abcULL }, + { &fnv_test_str[115], (Fnv64_t) 0x7318523267779d74ULL }, + { &fnv_test_str[116], (Fnv64_t) 0x3e66d3d56b8caca1ULL }, + { &fnv_test_str[117], (Fnv64_t) 0x956694a5c0095593ULL }, + { &fnv_test_str[118], (Fnv64_t) 0xcac54572bb1a6fc8ULL }, + { &fnv_test_str[119], (Fnv64_t) 0xa7a4c9f3edebf0d8ULL }, + { &fnv_test_str[120], (Fnv64_t) 0x7829851fac17b143ULL }, + { &fnv_test_str[121], (Fnv64_t) 0x2c8f4c9af81bcf06ULL }, + { &fnv_test_str[122], (Fnv64_t) 0xd34e31539740c732ULL }, + { &fnv_test_str[123], (Fnv64_t) 0x3605a2ac253d2db1ULL }, + { &fnv_test_str[124], (Fnv64_t) 0x08c11b8346f4a3c3ULL }, + { &fnv_test_str[125], (Fnv64_t) 0x6be396289ce8a6daULL }, + { &fnv_test_str[126], (Fnv64_t) 0xd9b957fb7fe794c5ULL }, + { &fnv_test_str[127], (Fnv64_t) 0x05be33da04560a93ULL }, + { &fnv_test_str[128], (Fnv64_t) 0x0957f1577ba9747cULL }, + { &fnv_test_str[129], (Fnv64_t) 0xda2cc3acc24fba57ULL }, + { &fnv_test_str[130], (Fnv64_t) 0x74136f185b29e7f0ULL }, + { &fnv_test_str[131], (Fnv64_t) 0xb2f2b4590edb93b2ULL }, + { &fnv_test_str[132], (Fnv64_t) 0xb3608fce8b86ae04ULL }, + { &fnv_test_str[133], (Fnv64_t) 0x4a3a865079359063ULL }, + { &fnv_test_str[134], (Fnv64_t) 0x5b3a7ef496880a50ULL }, + { &fnv_test_str[135], (Fnv64_t) 0x48fae3163854c23bULL }, + { &fnv_test_str[136], (Fnv64_t) 0x07aaa640476e0b9aULL }, + { &fnv_test_str[137], (Fnv64_t) 0x2f653656383a687dULL }, + { &fnv_test_str[138], (Fnv64_t) 0xa1031f8e7599d79cULL }, + { &fnv_test_str[139], (Fnv64_t) 0xa31908178ff92477ULL }, + { &fnv_test_str[140], (Fnv64_t) 0x097edf3c14c3fb83ULL }, + { &fnv_test_str[141], (Fnv64_t) 0xb51ca83feaa0971bULL }, + { &fnv_test_str[142], (Fnv64_t) 0xdd3c0d96d784f2e9ULL }, + { &fnv_test_str[143], (Fnv64_t) 0x86cd26a9ea767d78ULL }, + { &fnv_test_str[144], (Fnv64_t) 0xe6b215ff54a30c18ULL }, + { &fnv_test_str[145], (Fnv64_t) 0xec5b06a1c5531093ULL }, + { &fnv_test_str[146], (Fnv64_t) 0x45665a929f9ec5e5ULL }, + { &fnv_test_str[147], (Fnv64_t) 0x8c7609b4a9f10907ULL }, + { &fnv_test_str[148], (Fnv64_t) 0x89aac3a491f0d729ULL }, + { &fnv_test_str[149], (Fnv64_t) 0x32ce6b26e0f4a403ULL }, + { &fnv_test_str[150], (Fnv64_t) 0x614ab44e02b53e01ULL }, + { &fnv_test_str[151], (Fnv64_t) 0xfa6472eb6eef3290ULL }, + { &fnv_test_str[152], (Fnv64_t) 0x9e5d75eb1948eb6aULL }, + { &fnv_test_str[153], (Fnv64_t) 0xb6d12ad4a8671852ULL }, + { &fnv_test_str[154], (Fnv64_t) 0x88826f56eba07af1ULL }, + { &fnv_test_str[155], (Fnv64_t) 0x44535bf2645bc0fdULL }, + { &fnv_test_str[156], (Fnv64_t) 0x169388ffc21e3728ULL }, + { &fnv_test_str[157], (Fnv64_t) 0xf68aac9e396d8224ULL }, + { &fnv_test_str[158], (Fnv64_t) 0x8e87d7e7472b3883ULL }, + { &fnv_test_str[159], (Fnv64_t) 0x295c26caa8b423deULL }, + { &fnv_test_str[160], (Fnv64_t) 0x322c814292e72176ULL }, + { &fnv_test_str[161], (Fnv64_t) 0x8a06550eb8af7268ULL }, + { &fnv_test_str[162], (Fnv64_t) 0xef86d60e661bcf71ULL }, + { &fnv_test_str[163], (Fnv64_t) 0x9e5426c87f30ee54ULL }, + { &fnv_test_str[164], (Fnv64_t) 0xf1ea8aa826fd047eULL }, + { &fnv_test_str[165], (Fnv64_t) 0x0babaf9a642cb769ULL }, + { &fnv_test_str[166], (Fnv64_t) 0x4b3341d4068d012eULL }, + { &fnv_test_str[167], (Fnv64_t) 0xd15605cbc30a335cULL }, + { &fnv_test_str[168], (Fnv64_t) 0x5b21060aed8412e5ULL }, + { &fnv_test_str[169], (Fnv64_t) 0x45e2cda1ce6f4227ULL }, + { &fnv_test_str[170], (Fnv64_t) 0x50ae3745033ad7d4ULL }, + { &fnv_test_str[171], (Fnv64_t) 0xaa4588ced46bf414ULL }, + { &fnv_test_str[172], (Fnv64_t) 0xc1b0056c4a95467eULL }, + { &fnv_test_str[173], (Fnv64_t) 0x56576a71de8b4089ULL }, + { &fnv_test_str[174], (Fnv64_t) 0xbf20965fa6dc927eULL }, + { &fnv_test_str[175], (Fnv64_t) 0x569f8383c2040882ULL }, + { &fnv_test_str[176], (Fnv64_t) 0xe1e772fba08feca0ULL }, + { &fnv_test_str[177], (Fnv64_t) 0x4ced94af97138ac4ULL }, + { &fnv_test_str[178], (Fnv64_t) 0xc4112ffb337a82fbULL }, + { &fnv_test_str[179], (Fnv64_t) 0xd64a4fd41de38b7dULL }, + { &fnv_test_str[180], (Fnv64_t) 0x4cfc32329edebcbbULL }, + { &fnv_test_str[181], (Fnv64_t) 0x0803564445050395ULL }, + { &fnv_test_str[182], (Fnv64_t) 0xaa1574ecf4642ffdULL }, + { &fnv_test_str[183], (Fnv64_t) 0x694bc4e54cc315f9ULL }, + { &fnv_test_str[184], (Fnv64_t) 0xa3d7cb273b011721ULL }, + { &fnv_test_str[185], (Fnv64_t) 0x577c2f8b6115bfa5ULL }, + { &fnv_test_str[186], (Fnv64_t) 0xb7ec8c1a769fb4c1ULL }, + { &fnv_test_str[187], (Fnv64_t) 0x5d5cfce63359ab19ULL }, + { &fnv_test_str[188], (Fnv64_t) 0x33b96c3cd65b5f71ULL }, + { &fnv_test_str[189], (Fnv64_t) 0xd845097780602bb9ULL }, + { &fnv_test_str[190], (Fnv64_t) 0x84d47645d02da3d5ULL }, + { &fnv_test_str[191], (Fnv64_t) 0x83544f33b58773a5ULL }, + { &fnv_test_str[192], (Fnv64_t) 0x9175cbb2160836c5ULL }, + { &fnv_test_str[193], (Fnv64_t) 0xc71b3bc175e72bc5ULL }, + { &fnv_test_str[194], (Fnv64_t) 0x636806ac222ec985ULL }, + { &fnv_test_str[195], (Fnv64_t) 0xb6ef0e6950f52ed5ULL }, + { &fnv_test_str[196], (Fnv64_t) 0xead3d8a0f3dfdaa5ULL }, + { &fnv_test_str[197], (Fnv64_t) 0x922908fe9a861ba5ULL }, + { &fnv_test_str[198], (Fnv64_t) 0x6d4821de275fd5c5ULL }, + { &fnv_test_str[199], (Fnv64_t) 0x1fe3fce62bd816b5ULL }, + { &fnv_test_str[200], (Fnv64_t) 0xc23e9fccd6f70591ULL }, + { &fnv_test_str[201], (Fnv64_t) 0xc1af12bdfe16b5b5ULL }, + { &fnv_test_str[202], (Fnv64_t) 0x39e9f18f2f85e221ULL }, + { NULL, (Fnv64_t) 0 } +}; +#else /* HAVE_64BIT_LONG_LONG */ +struct fnv1a_64_test_vector fnv1a_64_vector[] = { + { &fnv_test_str[0], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} }, + { &fnv_test_str[1], (Fnv64_t) {0x8601ec8cUL, 0xaf63dc4cUL} }, + { &fnv_test_str[2], (Fnv64_t) {0x8601f1a5UL, 0xaf63df4cUL} }, + { &fnv_test_str[3], (Fnv64_t) {0x8601eff2UL, 0xaf63de4cUL} }, + { &fnv_test_str[4], (Fnv64_t) {0x8601e773UL, 0xaf63d94cUL} }, + { &fnv_test_str[5], (Fnv64_t) {0x8601e5c0UL, 0xaf63d84cUL} }, + { &fnv_test_str[6], (Fnv64_t) {0x8601ead9UL, 0xaf63db4cUL} }, + { &fnv_test_str[7], (Fnv64_t) {0xb541d342UL, 0x08985907UL} }, + { &fnv_test_str[8], (Fnv64_t) {0xfed9d577UL, 0xdcb27518UL} }, + { &fnv_test_str[9], (Fnv64_t) {0x0c2512afUL, 0xdd120e79UL} }, + { &fnv_test_str[10], (Fnv64_t) {0xa2fef40aUL, 0xcac165afUL} }, + { &fnv_test_str[11], (Fnv64_t) {0xf73967e8UL, 0x85944171UL} }, + { &fnv_test_str[12], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} }, + { &fnv_test_str[13], (Fnv64_t) {0xb544f1e4UL, 0x089be207UL} }, + { &fnv_test_str[14], (Fnv64_t) {0xb54d9b5fUL, 0x08a61407UL} }, + { &fnv_test_str[15], (Fnv64_t) {0xb54ab836UL, 0x08a2ae07UL} }, + { &fnv_test_str[16], (Fnv64_t) {0xb53c4869UL, 0x0891b007UL} }, + { &fnv_test_str[17], (Fnv64_t) {0xb5396540UL, 0x088e4a07UL} }, + { &fnv_test_str[18], (Fnv64_t) {0xb5420ebbUL, 0x08987c07UL} }, + { &fnv_test_str[19], (Fnv64_t) {0xfed9f926UL, 0xdcb28a18UL} }, + { &fnv_test_str[20], (Fnv64_t) {0x0c25b935UL, 0xdd127079UL} }, + { &fnv_test_str[21], (Fnv64_t) {0xa2febf5dUL, 0xcac146afUL} }, + { &fnv_test_str[22], (Fnv64_t) {0xf738acfeUL, 0x8593d371UL} }, + { &fnv_test_str[23], (Fnv64_t) {0x168b8f38UL, 0x34531ca7UL} }, + { &fnv_test_str[24], (Fnv64_t) {0xb54a22aeUL, 0x08a25607UL} }, + { &fnv_test_str[25], (Fnv64_t) {0x0cf90df3UL, 0xf5faf019UL} }, + { &fnv_test_str[26], (Fnv64_t) {0x0b3221c7UL, 0xf2739791UL} }, + { &fnv_test_str[27], (Fnv64_t) {0x062f22e0UL, 0x2c8c2b76UL} }, + { &fnv_test_str[28], (Fnv64_t) {0x8217b8fdUL, 0xe150688cUL} }, + { &fnv_test_str[29], (Fnv64_t) {0x0e4f1f87UL, 0xf35a83c1UL} }, + { &fnv_test_str[30], (Fnv64_t) {0x507344d0UL, 0xd1edd10bUL} }, + { &fnv_test_str[31], (Fnv64_t) {0xb3ddb8c3UL, 0x2a5ee739UL} }, + { &fnv_test_str[32], (Fnv64_t) {0xa1c0d310UL, 0xdcfb970cUL} }, + { &fnv_test_str[33], (Fnv64_t) {0xdaa6da90UL, 0x4054da76UL} }, + { &fnv_test_str[34], (Fnv64_t) {0x89861368UL, 0xf70a2ff5UL} }, + { &fnv_test_str[35], (Fnv64_t) {0xaed25f17UL, 0x4c628b38UL} }, + { &fnv_test_str[36], (Fnv64_t) {0x0f78189fUL, 0x9dd1f651UL} }, + { &fnv_test_str[37], (Fnv64_t) {0x491270ceUL, 0xa3de85bdUL} }, + { &fnv_test_str[38], (Fnv64_t) {0x2a55e61dUL, 0x858e2fa3UL} }, + { &fnv_test_str[39], (Fnv64_t) {0xeff5f915UL, 0x46810940UL} }, + { &fnv_test_str[40], (Fnv64_t) {0x0cf8edaaUL, 0xf5fadd19UL} }, + { &fnv_test_str[41], (Fnv64_t) {0x0b32b3e9UL, 0xf273ed91UL} }, + { &fnv_test_str[42], (Fnv64_t) {0x062f6525UL, 0x2c8c5276UL} }, + { &fnv_test_str[43], (Fnv64_t) {0x821842a0UL, 0xe150b98cUL} }, + { &fnv_test_str[44], (Fnv64_t) {0x0e4f55e7UL, 0xf35aa3c1UL} }, + { &fnv_test_str[45], (Fnv64_t) {0x50729265UL, 0xd1ed680bUL} }, + { &fnv_test_str[46], (Fnv64_t) {0xb3dded70UL, 0x2a5f0639UL} }, + { &fnv_test_str[47], (Fnv64_t) {0xa1c0f359UL, 0xdcfbaa0cUL} }, + { &fnv_test_str[48], (Fnv64_t) {0xdaa6a430UL, 0x4054ba76UL} }, + { &fnv_test_str[49], (Fnv64_t) {0x898562b0UL, 0xf709c7f5UL} }, + { &fnv_test_str[50], (Fnv64_t) {0xaed2f9b8UL, 0x4c62e638UL} }, + { &fnv_test_str[51], (Fnv64_t) {0x0f779415UL, 0x9dd1a851UL} }, + { &fnv_test_str[52], (Fnv64_t) {0x4911d62dUL, 0xa3de2abdUL} }, + { &fnv_test_str[53], (Fnv64_t) {0x2a55ae0aUL, 0x858e0ea3UL} }, + { &fnv_test_str[54], (Fnv64_t) {0xeff60347UL, 0x46810f40UL} }, + { &fnv_test_str[55], (Fnv64_t) {0xbef63eafUL, 0xc33bce57UL} }, + { &fnv_test_str[56], (Fnv64_t) {0xb54a0265UL, 0x08a24307UL} }, + { &fnv_test_str[57], (Fnv64_t) {0x0cc18d15UL, 0xf5b9fd19UL} }, + { &fnv_test_str[58], (Fnv64_t) {0xace35703UL, 0x4c968290UL} }, + { &fnv_test_str[59], (Fnv64_t) {0xc64d9350UL, 0x07174bd5UL} }, + { &fnv_test_str[60], (Fnv64_t) {0xf5d18750UL, 0x5a294c3fUL} }, + { &fnv_test_str[61], (Fnv64_t) {0xb308b843UL, 0x05b3c1aeUL} }, + { &fnv_test_str[62], (Fnv64_t) {0x37d0f477UL, 0xb92a48daUL} }, + { &fnv_test_str[63], (Fnv64_t) {0xd80ebc49UL, 0x73cdddccUL} }, + { &fnv_test_str[64], (Fnv64_t) {0x210a266bUL, 0xd58c4c13UL} }, + { &fnv_test_str[65], (Fnv64_t) {0x243ec194UL, 0xe78b6081UL} }, + { &fnv_test_str[66], (Fnv64_t) {0x96a39f34UL, 0xb096f770UL} }, + { &fnv_test_str[67], (Fnv64_t) {0xf807b6a3UL, 0xb425c54fUL} }, + { &fnv_test_str[68], (Fnv64_t) {0x751bb46eUL, 0x23e520e2UL} }, + { &fnv_test_str[69], (Fnv64_t) {0xfe1385ecUL, 0x1a0b44ccUL} }, + { &fnv_test_str[70], (Fnv64_t) {0x0cc2119fUL, 0xf5ba4b19UL} }, + { &fnv_test_str[71], (Fnv64_t) {0xace2baafUL, 0x4c962690UL} }, + { &fnv_test_str[72], (Fnv64_t) {0xc64cda19UL, 0x0716ded5UL} }, + { &fnv_test_str[73], (Fnv64_t) {0xf5d150f0UL, 0x5a292c3fUL} }, + { &fnv_test_str[74], (Fnv64_t) {0xb308ecf0UL, 0x05b3e0aeUL} }, + { &fnv_test_str[75], (Fnv64_t) {0x37d119d9UL, 0xb92a5edaUL} }, + { &fnv_test_str[76], (Fnv64_t) {0xd80f6635UL, 0x73ce41ccUL} }, + { &fnv_test_str[77], (Fnv64_t) {0x2109f00bUL, 0xd58c2c13UL} }, + { &fnv_test_str[78], (Fnv64_t) {0x243f47d1UL, 0xe78baf81UL} }, + { &fnv_test_str[79], (Fnv64_t) {0x96a2ee7cUL, 0xb0968f70UL} }, + { &fnv_test_str[80], (Fnv64_t) {0xf807855cUL, 0xb425a84fUL} }, + { &fnv_test_str[81], (Fnv64_t) {0x751b56f9UL, 0x23e4e9e2UL} }, + { &fnv_test_str[82], (Fnv64_t) {0xfe1396eaUL, 0x1a0b4eccUL} }, + { &fnv_test_str[83], (Fnv64_t) {0xbb2c9004UL, 0x54abd453UL} }, + { &fnv_test_str[84], (Fnv64_t) {0xb55ec3daUL, 0x08ba5f07UL} }, + { &fnv_test_str[85], (Fnv64_t) {0x3006cb6eUL, 0x33735419UL} }, + { &fnv_test_str[86], (Fnv64_t) {0x80aabd0bUL, 0xa430d846UL} }, + { &fnv_test_str[87], (Fnv64_t) {0xa21f39b1UL, 0xa9bc8accUL} }, + { &fnv_test_str[88], (Fnv64_t) {0x91cc682dUL, 0x69611964UL} }, + { &fnv_test_str[89], (Fnv64_t) {0x4799dfe9UL, 0xad2bb177UL} }, + { &fnv_test_str[90], (Fnv64_t) {0x91cc6314UL, 0x69611664UL} }, + { &fnv_test_str[91], (Fnv64_t) {0x4a3b1236UL, 0x8d1bb390UL} }, + { &fnv_test_str[92], (Fnv64_t) {0x91cc64c7UL, 0x69611764UL} }, + { &fnv_test_str[93], (Fnv64_t) {0xf40434c7UL, 0xed205d87UL} }, + { &fnv_test_str[94], (Fnv64_t) {0x91cc5faeUL, 0x69611464UL} }, + { &fnv_test_str[95], (Fnv64_t) {0x44f8ad9cUL, 0xcd3baf5eUL} }, + { &fnv_test_str[96], (Fnv64_t) {0x127cd6d8UL, 0xe3b36596UL} }, + { &fnv_test_str[97], (Fnv64_t) {0xc8e8a646UL, 0xf77f1072UL} }, + { &fnv_test_str[98], (Fnv64_t) {0x127cd372UL, 0xe3b36396UL} }, + { &fnv_test_str[99], (Fnv64_t) {0x932ad458UL, 0x6067dce9UL} }, + { &fnv_test_str[100], (Fnv64_t) {0x127cf208UL, 0xe3b37596UL} }, + { &fnv_test_str[101], (Fnv64_t) {0x9fe83936UL, 0x4b7b10faUL} }, + { &fnv_test_str[102], (Fnv64_t) {0x04d914beUL, 0xaabafe71UL} }, + { &fnv_test_str[103], (Fnv64_t) {0x3cde3edaUL, 0xf4d3180bUL} }, + { &fnv_test_str[104], (Fnv64_t) {0x04d9130bUL, 0xaabafd71UL} }, + { &fnv_test_str[105], (Fnv64_t) {0x3cdb5bb1UL, 0xf4cfb20bUL} }, + { &fnv_test_str[106], (Fnv64_t) {0x04d91158UL, 0xaabafc71UL} }, + { &fnv_test_str[107], (Fnv64_t) {0x3cd87888UL, 0xf4cc4c0bUL} }, + { &fnv_test_str[108], (Fnv64_t) {0xd2a8d3a7UL, 0xe729bac5UL} }, + { &fnv_test_str[109], (Fnv64_t) {0xf4dfa4c5UL, 0x74bc0524UL} }, + { &fnv_test_str[110], (Fnv64_t) {0xd2a5b352UL, 0xe72630c5UL} }, + { &fnv_test_str[111], (Fnv64_t) {0xef8fb456UL, 0x6b983224UL} }, + { &fnv_test_str[112], (Fnv64_t) {0xd2ae266dUL, 0xe73042c5UL} }, + { &fnv_test_str[113], (Fnv64_t) {0xfdeb4b37UL, 0x8527e324UL} }, + { &fnv_test_str[114], (Fnv64_t) {0xee952abcUL, 0x0a83c86fUL} }, + { &fnv_test_str[115], (Fnv64_t) {0x67779d74UL, 0x73185232UL} }, + { &fnv_test_str[116], (Fnv64_t) {0x6b8caca1UL, 0x3e66d3d5UL} }, + { &fnv_test_str[117], (Fnv64_t) {0xc0095593UL, 0x956694a5UL} }, + { &fnv_test_str[118], (Fnv64_t) {0xbb1a6fc8UL, 0xcac54572UL} }, + { &fnv_test_str[119], (Fnv64_t) {0xedebf0d8UL, 0xa7a4c9f3UL} }, + { &fnv_test_str[120], (Fnv64_t) {0xac17b143UL, 0x7829851fUL} }, + { &fnv_test_str[121], (Fnv64_t) {0xf81bcf06UL, 0x2c8f4c9aUL} }, + { &fnv_test_str[122], (Fnv64_t) {0x9740c732UL, 0xd34e3153UL} }, + { &fnv_test_str[123], (Fnv64_t) {0x253d2db1UL, 0x3605a2acUL} }, + { &fnv_test_str[124], (Fnv64_t) {0x46f4a3c3UL, 0x08c11b83UL} }, + { &fnv_test_str[125], (Fnv64_t) {0x9ce8a6daUL, 0x6be39628UL} }, + { &fnv_test_str[126], (Fnv64_t) {0x7fe794c5UL, 0xd9b957fbUL} }, + { &fnv_test_str[127], (Fnv64_t) {0x04560a93UL, 0x05be33daUL} }, + { &fnv_test_str[128], (Fnv64_t) {0x7ba9747cUL, 0x0957f157UL} }, + { &fnv_test_str[129], (Fnv64_t) {0xc24fba57UL, 0xda2cc3acUL} }, + { &fnv_test_str[130], (Fnv64_t) {0x5b29e7f0UL, 0x74136f18UL} }, + { &fnv_test_str[131], (Fnv64_t) {0x0edb93b2UL, 0xb2f2b459UL} }, + { &fnv_test_str[132], (Fnv64_t) {0x8b86ae04UL, 0xb3608fceUL} }, + { &fnv_test_str[133], (Fnv64_t) {0x79359063UL, 0x4a3a8650UL} }, + { &fnv_test_str[134], (Fnv64_t) {0x96880a50UL, 0x5b3a7ef4UL} }, + { &fnv_test_str[135], (Fnv64_t) {0x3854c23bUL, 0x48fae316UL} }, + { &fnv_test_str[136], (Fnv64_t) {0x476e0b9aUL, 0x07aaa640UL} }, + { &fnv_test_str[137], (Fnv64_t) {0x383a687dUL, 0x2f653656UL} }, + { &fnv_test_str[138], (Fnv64_t) {0x7599d79cUL, 0xa1031f8eUL} }, + { &fnv_test_str[139], (Fnv64_t) {0x8ff92477UL, 0xa3190817UL} }, + { &fnv_test_str[140], (Fnv64_t) {0x14c3fb83UL, 0x097edf3cUL} }, + { &fnv_test_str[141], (Fnv64_t) {0xeaa0971bUL, 0xb51ca83fUL} }, + { &fnv_test_str[142], (Fnv64_t) {0xd784f2e9UL, 0xdd3c0d96UL} }, + { &fnv_test_str[143], (Fnv64_t) {0xea767d78UL, 0x86cd26a9UL} }, + { &fnv_test_str[144], (Fnv64_t) {0x54a30c18UL, 0xe6b215ffUL} }, + { &fnv_test_str[145], (Fnv64_t) {0xc5531093UL, 0xec5b06a1UL} }, + { &fnv_test_str[146], (Fnv64_t) {0x9f9ec5e5UL, 0x45665a92UL} }, + { &fnv_test_str[147], (Fnv64_t) {0xa9f10907UL, 0x8c7609b4UL} }, + { &fnv_test_str[148], (Fnv64_t) {0x91f0d729UL, 0x89aac3a4UL} }, + { &fnv_test_str[149], (Fnv64_t) {0xe0f4a403UL, 0x32ce6b26UL} }, + { &fnv_test_str[150], (Fnv64_t) {0x02b53e01UL, 0x614ab44eUL} }, + { &fnv_test_str[151], (Fnv64_t) {0x6eef3290UL, 0xfa6472ebUL} }, + { &fnv_test_str[152], (Fnv64_t) {0x1948eb6aUL, 0x9e5d75ebUL} }, + { &fnv_test_str[153], (Fnv64_t) {0xa8671852UL, 0xb6d12ad4UL} }, + { &fnv_test_str[154], (Fnv64_t) {0xeba07af1UL, 0x88826f56UL} }, + { &fnv_test_str[155], (Fnv64_t) {0x645bc0fdUL, 0x44535bf2UL} }, + { &fnv_test_str[156], (Fnv64_t) {0xc21e3728UL, 0x169388ffUL} }, + { &fnv_test_str[157], (Fnv64_t) {0x396d8224UL, 0xf68aac9eUL} }, + { &fnv_test_str[158], (Fnv64_t) {0x472b3883UL, 0x8e87d7e7UL} }, + { &fnv_test_str[159], (Fnv64_t) {0xa8b423deUL, 0x295c26caUL} }, + { &fnv_test_str[160], (Fnv64_t) {0x92e72176UL, 0x322c8142UL} }, + { &fnv_test_str[161], (Fnv64_t) {0xb8af7268UL, 0x8a06550eUL} }, + { &fnv_test_str[162], (Fnv64_t) {0x661bcf71UL, 0xef86d60eUL} }, + { &fnv_test_str[163], (Fnv64_t) {0x7f30ee54UL, 0x9e5426c8UL} }, + { &fnv_test_str[164], (Fnv64_t) {0x26fd047eUL, 0xf1ea8aa8UL} }, + { &fnv_test_str[165], (Fnv64_t) {0x642cb769UL, 0x0babaf9aUL} }, + { &fnv_test_str[166], (Fnv64_t) {0x068d012eUL, 0x4b3341d4UL} }, + { &fnv_test_str[167], (Fnv64_t) {0xc30a335cUL, 0xd15605cbUL} }, + { &fnv_test_str[168], (Fnv64_t) {0xed8412e5UL, 0x5b21060aUL} }, + { &fnv_test_str[169], (Fnv64_t) {0xce6f4227UL, 0x45e2cda1UL} }, + { &fnv_test_str[170], (Fnv64_t) {0x033ad7d4UL, 0x50ae3745UL} }, + { &fnv_test_str[171], (Fnv64_t) {0xd46bf414UL, 0xaa4588ceUL} }, + { &fnv_test_str[172], (Fnv64_t) {0x4a95467eUL, 0xc1b0056cUL} }, + { &fnv_test_str[173], (Fnv64_t) {0xde8b4089UL, 0x56576a71UL} }, + { &fnv_test_str[174], (Fnv64_t) {0xa6dc927eUL, 0xbf20965fUL} }, + { &fnv_test_str[175], (Fnv64_t) {0xc2040882UL, 0x569f8383UL} }, + { &fnv_test_str[176], (Fnv64_t) {0xa08feca0UL, 0xe1e772fbUL} }, + { &fnv_test_str[177], (Fnv64_t) {0x97138ac4UL, 0x4ced94afUL} }, + { &fnv_test_str[178], (Fnv64_t) {0x337a82fbUL, 0xc4112ffbUL} }, + { &fnv_test_str[179], (Fnv64_t) {0x1de38b7dUL, 0xd64a4fd4UL} }, + { &fnv_test_str[180], (Fnv64_t) {0x9edebcbbUL, 0x4cfc3232UL} }, + { &fnv_test_str[181], (Fnv64_t) {0x45050395UL, 0x08035644UL} }, + { &fnv_test_str[182], (Fnv64_t) {0xf4642ffdUL, 0xaa1574ecUL} }, + { &fnv_test_str[183], (Fnv64_t) {0x4cc315f9UL, 0x694bc4e5UL} }, + { &fnv_test_str[184], (Fnv64_t) {0x3b011721UL, 0xa3d7cb27UL} }, + { &fnv_test_str[185], (Fnv64_t) {0x6115bfa5UL, 0x577c2f8bUL} }, + { &fnv_test_str[186], (Fnv64_t) {0x769fb4c1UL, 0xb7ec8c1aUL} }, + { &fnv_test_str[187], (Fnv64_t) {0x3359ab19UL, 0x5d5cfce6UL} }, + { &fnv_test_str[188], (Fnv64_t) {0xd65b5f71UL, 0x33b96c3cUL} }, + { &fnv_test_str[189], (Fnv64_t) {0x80602bb9UL, 0xd8450977UL} }, + { &fnv_test_str[190], (Fnv64_t) {0xd02da3d5UL, 0x84d47645UL} }, + { &fnv_test_str[191], (Fnv64_t) {0xb58773a5UL, 0x83544f33UL} }, + { &fnv_test_str[192], (Fnv64_t) {0x160836c5UL, 0x9175cbb2UL} }, + { &fnv_test_str[193], (Fnv64_t) {0x75e72bc5UL, 0xc71b3bc1UL} }, + { &fnv_test_str[194], (Fnv64_t) {0x222ec985UL, 0x636806acUL} }, + { &fnv_test_str[195], (Fnv64_t) {0x50f52ed5UL, 0xb6ef0e69UL} }, + { &fnv_test_str[196], (Fnv64_t) {0xf3dfdaa5UL, 0xead3d8a0UL} }, + { &fnv_test_str[197], (Fnv64_t) {0x9a861ba5UL, 0x922908feUL} }, + { &fnv_test_str[198], (Fnv64_t) {0x275fd5c5UL, 0x6d4821deUL} }, + { &fnv_test_str[199], (Fnv64_t) {0x2bd816b5UL, 0x1fe3fce6UL} }, + { &fnv_test_str[200], (Fnv64_t) {0xd6f70591UL, 0xc23e9fccUL} }, + { &fnv_test_str[201], (Fnv64_t) {0xfe16b5b5UL, 0xc1af12bdUL} }, + { &fnv_test_str[202], (Fnv64_t) {0x2f85e221UL, 0x39e9f18fUL} }, + { NULL, (Fnv64_t) {0,0} } +}; +#endif /* HAVE_64BIT_LONG_LONG */ + +/* end of output generated by make vector.c */ +/* + * insert the contents of vector.c above + */ + + +/* + * unknown_hash_type - report an unknown hash type error + * + * NOTE: Does not return. + */ +void +unknown_hash_type(char *prog, enum fnv_type type, int code) +{ + fprintf(stderr, "%s: unknown or unexpexted hash type: %d\n", prog, type); + exit(code); +} + + +/* + * print_fnv32 - print an FNV hash + * + * given: + * hval the hash value to print + * mask lower bit mask + * verbose 1 => print arg with hash + * arg string or filename arg + */ +void +print_fnv32(Fnv32_t hval, Fnv32_t mask, int verbose, char *arg) +{ + if (verbose) { + printf("0x%08lx %s\n", hval & mask, arg); + } else { + printf("0x%08lx\n", hval & mask); + } +} + + +/* + * print_fnv64 - print an FNV hash + * + * given: + * hval the hash value to print + * mask lower bit mask + * verbose 1 => print arg with hash + * arg string or filename arg + */ +void +print_fnv64(Fnv64_t hval, Fnv64_t mask, int verbose, char *arg) +{ +#if defined(HAVE_64BIT_LONG_LONG) + if (verbose) { + printf("0x%016llx %s\n", hval & mask, arg); + } else { + printf("0x%016llx\n", hval & mask); + } +#else + if (verbose) { + printf("0x%08lx%08lx %s\n", + hval.w32[1] & mask.w32[1], + hval.w32[0] & mask.w32[0], + arg); + } else { + printf("0x%08lx%08lx\n", + hval.w32[1] & mask.w32[1], + hval.w32[0] & mask.w32[0]); + } +#endif +} diff --git a/lib/lufa b/lib/lufa -Subproject 913c56a6d422685f540b49afa7c61458fb9272a +Subproject 549b97320d515bfca2f95c145a67bd13be968fa diff --git a/lib/pico-sdk b/lib/pico-sdk new file mode 160000 +Subproject 07edde8e49890d2172bbc272aacc119f999df06 diff --git a/lib/printf b/lib/printf -Subproject d3b984684bb8a8bdc48cc7a1abecb93ce59bbe3 +Subproject c2e3b4e10d281e7f0f694d3ecbd9f320977288c diff --git a/lib/python/qmk/c_parse.py b/lib/python/qmk/c_parse.py index 359aaccbbc..c14eb490fa 100644 --- a/lib/python/qmk/c_parse.py +++ b/lib/python/qmk/c_parse.py @@ -24,6 +24,14 @@ def _get_chunks(it, size): return iter(lambda: tuple(islice(it, size)), ()) +def _preprocess_c_file(file): + """Load file and strip comments + """ + file_contents = file.read_text(encoding='utf-8') + file_contents = comment_remover(file_contents) + return file_contents.replace('\\\n', '') + + def strip_line_comment(string): """Removes comments from a single line string. """ @@ -58,9 +66,7 @@ def find_layouts(file): parsed_layouts = {} # Search the file for LAYOUT macros and aliases - file_contents = file.read_text(encoding='utf-8') - file_contents = comment_remover(file_contents) - file_contents = file_contents.replace('\\\n', '') + file_contents = _preprocess_c_file(file) for line in file_contents.split('\n'): if layout_macro_define_regex.match(line.lstrip()) and '(' in line and 'LAYOUT' in line: @@ -205,13 +211,23 @@ def _coerce_led_token(_type, value): return value_map[value] +def _validate_led_config(matrix, matrix_rows, matrix_indexes, position, position_raw, flags): + # TODO: Improve crude parsing/validation + if len(matrix) != matrix_rows and len(matrix) != (matrix_rows / 2): + raise ValueError("Unable to parse g_led_config matrix data") + if len(position) != len(flags): + raise ValueError("Unable to parse g_led_config position data") + if len(matrix_indexes) and (max(matrix_indexes) >= len(flags)): + raise ValueError("OOB within g_led_config matrix data") + if not all(isinstance(n, int) for n in matrix_indexes): + raise ValueError("matrix indexes are not all ints") + if (len(position_raw) % 2) != 0: + raise ValueError("Malformed g_led_config position data") + + def _parse_led_config(file, matrix_cols, matrix_rows): """Return any 'raw' led/rgb matrix config """ - file_contents = file.read_text(encoding='utf-8') - file_contents = comment_remover(file_contents) - file_contents = file_contents.replace('\\\n', '') - matrix_raw = [] position_raw = [] flags = [] @@ -219,7 +235,7 @@ def _parse_led_config(file, matrix_cols, matrix_rows): found_led_config = False bracket_count = 0 section = 0 - for _type, value in lex(file_contents, CLexer()): + for _type, value in lex(_preprocess_c_file(file), CLexer()): # Assume g_led_config..stuff..; if value == 'g_led_config': found_led_config = True @@ -242,23 +258,21 @@ def _parse_led_config(file, matrix_cols, matrix_rows): position_raw.append(_coerce_led_token(_type, value)) if section == 3 and bracket_count == 2: flags.append(_coerce_led_token(_type, value)) + elif _type in [Token.Comment.Preproc]: + # TODO: Promote to error + return None # Slightly better intrim format matrix = list(_get_chunks(matrix_raw, matrix_cols)) position = list(_get_chunks(position_raw, 2)) matrix_indexes = list(filter(lambda x: x is not None, matrix_raw)) - # If we have not found anything - bail + # If we have not found anything - bail with no error if not section: return None - # TODO: Improve crude parsing/validation - if len(matrix) != matrix_rows and len(matrix) != (matrix_rows / 2): - raise ValueError("Unable to parse g_led_config matrix data") - if len(position) != len(flags): - raise ValueError("Unable to parse g_led_config position data") - if len(matrix_indexes) and (max(matrix_indexes) >= len(flags)): - raise ValueError("OOB within g_led_config matrix data") + # Throw any validation errors + _validate_led_config(matrix, matrix_rows, matrix_indexes, position, position_raw, flags) return (matrix, position, flags) diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py index d7192631a3..98e212c47b 100644 --- a/lib/python/qmk/cli/__init__.py +++ b/lib/python/qmk/cli/__init__.py @@ -15,6 +15,7 @@ from milc.questions import yesno import_names = { # A mapping of package name to importable name 'pep8-naming': 'pep8ext_naming', + 'pyserial': 'serial', 'pyusb': 'usb.core', 'qmk-dotty-dict': 'dotty_dict', 'pillow': 'PIL' @@ -59,6 +60,9 @@ subcommands = [ 'qmk.cli.generate.rules_mk', 'qmk.cli.generate.version_h', 'qmk.cli.hello', + 'qmk.cli.import.kbfirmware', + 'qmk.cli.import.keyboard', + 'qmk.cli.import.keymap', 'qmk.cli.info', 'qmk.cli.json2c', 'qmk.cli.lint', @@ -91,7 +95,7 @@ def _install_deps(requirements): elif not os.access(sys.prefix, os.W_OK): # We can't write to sys.prefix, attempt to install locally - command.append('--local') + command.append('--user') return _run_cmd(*command, '-r', requirements) @@ -156,6 +160,18 @@ def _broken_module_imports(requirements): return False +def _yesno(*args): + """Wrapper to only prompt if interactive + """ + return sys.stdout.isatty() and yesno(*args) + + +def _eprint(errmsg): + """Wrapper to print to stderr + """ + print(errmsg, file=sys.stderr) + + # Make sure our python is new enough # # Supported version information @@ -177,7 +193,7 @@ def _broken_module_imports(requirements): # void: 3.9 if sys.version_info[0] != 3 or sys.version_info[1] < 7: - print('Error: Your Python is too old! Please upgrade to Python 3.7 or later.') + _eprint('Error: Your Python is too old! Please upgrade to Python 3.7 or later.') exit(127) milc_version = __VERSION__.split('.') @@ -185,7 +201,7 @@ milc_version = __VERSION__.split('.') if int(milc_version[0]) < 2 and int(milc_version[1]) < 4: requirements = Path('requirements.txt').resolve() - print(f'Your MILC library is too old! Please upgrade: python3 -m pip install -U -r {str(requirements)}') + _eprint(f'Your MILC library is too old! Please upgrade: python3 -m pip install -U -r {str(requirements)}') exit(127) # Make sure we can run binaries in the same directory as our Python interpreter @@ -195,7 +211,7 @@ if python_dir not in os.environ['PATH'].split(':'): os.environ['PATH'] = ":".join((python_dir, os.environ['PATH'])) # Check to make sure we have all our dependencies -msg_install = f'Please run `{sys.executable} -m pip install -r %s` to install required python dependencies.' +msg_install = f'\nPlease run `{sys.executable} -m pip install -r %s` to install required python dependencies.' args = sys.argv[1:] while args and args[0][0] == '-': del args[0] @@ -204,24 +220,20 @@ safe_command = args and args[0] in safe_commands if not safe_command: if _broken_module_imports('requirements.txt'): - if yesno('Would you like to install the required Python modules?'): + if _yesno('Would you like to install the required Python modules?'): _install_deps('requirements.txt') else: - print() - print(msg_install % (str(Path('requirements.txt').resolve()),)) - print() + _eprint(msg_install % (str(Path('requirements.txt').resolve()),)) exit(1) if cli.config.user.developer and _broken_module_imports('requirements-dev.txt'): - if yesno('Would you like to install the required developer Python modules?'): + if _yesno('Would you like to install the required developer Python modules?'): _install_deps('requirements-dev.txt') - elif yesno('Would you like to disable developer mode?'): + elif _yesno('Would you like to disable developer mode?'): _run_cmd(sys.argv[0], 'config', 'user.developer=None') else: - print() - print(msg_install % (str(Path('requirements-dev.txt').resolve()),)) - print('You can also turn off developer mode: qmk config user.developer=None') - print() + _eprint(msg_install % (str(Path('requirements-dev.txt').resolve()),)) + _eprint('You can also turn off developer mode: qmk config user.developer=None') exit(1) # Import our subcommands @@ -231,6 +243,6 @@ for subcommand in subcommands: except (ImportError, ModuleNotFoundError) as e: if safe_command: - print(f'Warning: Could not import {subcommand}: {e.__class__.__name__}, {e}') + _eprint(f'Warning: Could not import {subcommand}: {e.__class__.__name__}, {e}') else: raise diff --git a/lib/python/qmk/cli/compile.py b/lib/python/qmk/cli/compile.py index acbd778649..95118e6687 100755 --- a/lib/python/qmk/cli/compile.py +++ b/lib/python/qmk/cli/compile.py @@ -32,8 +32,9 @@ def compile(cli): If a keyboard and keymap are provided this command will build a firmware based on that. """ if cli.args.clean and not cli.args.filename and not cli.args.dry_run: - command = create_make_command(cli.config.compile.keyboard, cli.config.compile.keymap, 'clean') - cli.run(command, capture_output=False, stdin=DEVNULL) + if cli.config.compile.keyboard and cli.config.compile.keymap: + command = create_make_command(cli.config.compile.keyboard, cli.config.compile.keymap, 'clean') + cli.run(command, capture_output=False, stdin=DEVNULL) # Build the environment vars envs = {} diff --git a/lib/python/qmk/cli/doctor/linux.py b/lib/python/qmk/cli/doctor/linux.py index 94683d3307..a803305c0d 100644 --- a/lib/python/qmk/cli/doctor/linux.py +++ b/lib/python/qmk/cli/doctor/linux.py @@ -6,7 +6,7 @@ from pathlib import Path from milc import cli -from qmk.constants import QMK_FIRMWARE +from qmk.constants import QMK_FIRMWARE, BOOTLOADER_VIDS_PIDS from .check import CheckStatus @@ -26,6 +26,18 @@ def _udev_rule(vid, pid=None, *args): return rule +def _generate_desired_rules(bootloader_vids_pids): + rules = dict() + for bl in bootloader_vids_pids.keys(): + rules[bl] = set() + for vid_pid in bootloader_vids_pids[bl]: + if bl == 'caterina' or bl == 'md-boot': + rules[bl].add(_udev_rule(vid_pid[0], vid_pid[1], 'ENV{ID_MM_DEVICE_IGNORE}="1"')) + else: + rules[bl].add(_udev_rule(vid_pid[0], vid_pid[1])) + return rules + + def _deprecated_udev_rule(vid, pid=None): """ Helper function that return udev rules @@ -47,47 +59,8 @@ def check_udev_rules(): Path("/run/udev/rules.d/"), Path("/etc/udev/rules.d/"), ] - desired_rules = { - 'atmel-dfu': { - _udev_rule("03eb", "2fef"), # ATmega16U2 - _udev_rule("03eb", "2ff0"), # ATmega32U2 - _udev_rule("03eb", "2ff3"), # ATmega16U4 - _udev_rule("03eb", "2ff4"), # ATmega32U4 - _udev_rule("03eb", "2ff9"), # AT90USB64 - _udev_rule("03eb", "2ffa"), # AT90USB162 - _udev_rule("03eb", "2ffb") # AT90USB128 - }, - 'kiibohd': {_udev_rule("1c11", "b007")}, - 'stm32': { - _udev_rule("1eaf", "0003"), # STM32duino - _udev_rule("0483", "df11") # STM32 DFU - }, - 'bootloadhid': {_udev_rule("16c0", "05df")}, - 'usbasploader': {_udev_rule("16c0", "05dc")}, - 'massdrop': {_udev_rule("03eb", "6124", 'ENV{ID_MM_DEVICE_IGNORE}="1"')}, - 'caterina': { - # Spark Fun Electronics - _udev_rule("1b4f", "9203", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # Pro Micro 3V3/8MHz - _udev_rule("1b4f", "9205", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # Pro Micro 5V/16MHz - _udev_rule("1b4f", "9207", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # LilyPad 3V3/8MHz (and some Pro Micro clones) - # Pololu Electronics - _udev_rule("1ffb", "0101", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # A-Star 32U4 - # Arduino SA - _udev_rule("2341", "0036", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # Leonardo - _udev_rule("2341", "0037", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # Micro - # Adafruit Industries LLC - _udev_rule("239a", "000c", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # Feather 32U4 - _udev_rule("239a", "000d", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # ItsyBitsy 32U4 3V3/8MHz - _udev_rule("239a", "000e", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # ItsyBitsy 32U4 5V/16MHz - # dog hunter AG - _udev_rule("2a03", "0036", 'ENV{ID_MM_DEVICE_IGNORE}="1"'), # Leonardo - _udev_rule("2a03", "0037", 'ENV{ID_MM_DEVICE_IGNORE}="1"') # Micro - }, - 'hid-bootloader': { - _udev_rule("03eb", "2067"), # QMK HID - _udev_rule("16c0", "0478") # PJRC halfkay - } - } + + desired_rules = _generate_desired_rules(BOOTLOADER_VIDS_PIDS) # These rules are no longer recommended, only use them to check for their presence. deprecated_rules = { diff --git a/lib/python/qmk/cli/doctor/macos.py b/lib/python/qmk/cli/doctor/macos.py index 00fb272858..5d088c9492 100644 --- a/lib/python/qmk/cli/doctor/macos.py +++ b/lib/python/qmk/cli/doctor/macos.py @@ -8,6 +8,6 @@ from .check import CheckStatus def os_test_macos(): """Run the Mac specific tests. """ - cli.log.info("Detected {fg_cyan}macOS %s{fg_reset}.", platform.mac_ver()[0]) + cli.log.info("Detected {fg_cyan}macOS %s (%s){fg_reset}.", platform.mac_ver()[0], 'Apple Silicon' if platform.processor() == 'arm' else 'Intel') return CheckStatus.OK diff --git a/lib/python/qmk/cli/doctor/main.py b/lib/python/qmk/cli/doctor/main.py index 2898a9894c..1600ab8dd4 100755 --- a/lib/python/qmk/cli/doctor/main.py +++ b/lib/python/qmk/cli/doctor/main.py @@ -11,7 +11,7 @@ from milc.questions import yesno from qmk import submodules from qmk.constants import QMK_FIRMWARE, QMK_FIRMWARE_UPSTREAM from .check import CheckStatus, check_binaries, check_binary_versions, check_submodules -from qmk.git import git_check_repo, git_get_branch, git_get_tag, git_is_dirty, git_get_remotes, git_check_deviation +from qmk.git import git_check_repo, git_get_branch, git_get_tag, git_get_last_log_entry, git_get_common_ancestor, git_is_dirty, git_get_remotes, git_check_deviation from qmk.commands import in_virtualenv @@ -66,10 +66,32 @@ def git_tests(): if git_branch in ['master', 'develop'] and git_deviation: cli.log.warning('{fg_yellow}The local "%s" branch contains commits not found in the upstream branch.', git_branch) status = CheckStatus.WARNING + for branch in [git_branch, 'upstream/master', 'upstream/develop']: + cli.log.info('- Latest %s: %s', branch, git_get_last_log_entry(branch)) + for branch in ['upstream/master', 'upstream/develop']: + cli.log.info('- Common ancestor with %s: %s', branch, git_get_common_ancestor(branch, 'HEAD')) return status +def output_submodule_status(): + """Prints out information related to the submodule status. + """ + cli.log.info('Submodule status:') + sub_status = submodules.status() + for s in sub_status.keys(): + sub_info = sub_status[s] + if 'name' in sub_info: + sub_name = sub_info['name'] + sub_shorthash = sub_info['shorthash'] if 'shorthash' in sub_info else '' + sub_describe = sub_info['describe'] if 'describe' in sub_info else '' + sub_last_log_timestamp = sub_info['last_log_timestamp'] if 'last_log_timestamp' in sub_info else '' + if sub_last_log_timestamp != '': + cli.log.info(f'- {sub_name}: {sub_last_log_timestamp} -- {sub_describe} ({sub_shorthash})') + else: + cli.log.error(f'- {sub_name}: <<< missing or unknown >>>') + + @cli.argument('-y', '--yes', action='store_true', arg_only=True, help='Answer yes to all questions.') @cli.argument('-n', '--no', action='store_true', arg_only=True, help='Answer no to all questions.') @cli.subcommand('Basic QMK environment checks') @@ -129,6 +151,8 @@ def doctor(cli): elif sub_ok == CheckStatus.WARNING and status == CheckStatus.OK: status = CheckStatus.WARNING + output_submodule_status() + # Report a summary of our findings to the user if status == CheckStatus.OK: cli.log.info('{fg_green}QMK is ready to go') diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py index 28e48a4101..c39f4b36d4 100644 --- a/lib/python/qmk/cli/flash.py +++ b/lib/python/qmk/cli/flash.py @@ -4,6 +4,7 @@ You can compile a keymap already in the repo or using a QMK Configurator export. A bootloader must be specified. """ from subprocess import DEVNULL +import sys from argcomplete.completers import FilesCompleter from milc import cli @@ -12,6 +13,7 @@ import qmk.path from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.commands import compile_configurator_json, create_make_command, parse_configurator_json from qmk.keyboard import keyboard_completer, keyboard_folder +from qmk.flashers import flasher def print_bootloader_help(): @@ -33,12 +35,15 @@ def print_bootloader_help(): cli.echo('\tdfu-split-right') cli.echo('\tdfu-util-split-left') cli.echo('\tdfu-util-split-right') + cli.echo('\tuf2-split-left') + cli.echo('\tuf2-split-right') cli.echo('For more info, visit https://docs.qmk.fm/#/flashing') -@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), completer=FilesCompleter('.json'), help='The configurator export JSON to compile.') +@cli.argument('filename', nargs='?', arg_only=True, type=qmk.path.FileType('r'), completer=FilesCompleter('.json'), help='A configurator export JSON to be compiled and flashed or a pre-compiled binary firmware file (bin/hex) to be flashed.') @cli.argument('-b', '--bootloaders', action='store_true', help='List the available bootloaders.') @cli.argument('-bl', '--bootloader', default='flash', help='The flash command, corresponding to qmk\'s make options of bootloaders.') +@cli.argument('-m', '--mcu', help='The MCU name. Required for HalfKay, HID, USBAspLoader and ISP flashing.') @cli.argument('-km', '--keymap', help='The keymap to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.') @cli.argument('-kb', '--keyboard', type=keyboard_folder, completer=keyboard_completer, help='The keyboard to build a firmware for. Use this if you dont have a configurator file. Ignored when a configurator file is supplied.') @cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't actually build, just show the make command to be run.") @@ -51,6 +56,8 @@ def print_bootloader_help(): def flash(cli): """Compile and or flash QMK Firmware or keyboard/layout + If a binary firmware is supplied, try to flash that. + If a Configurator JSON export is supplied this command will create a new keymap. Keymap and Keyboard arguments will be ignored. @@ -58,55 +65,69 @@ def flash(cli): If bootloader is omitted the make system will use the configured bootloader for that keyboard. """ - if cli.args.clean and not cli.args.filename and not cli.args.dry_run: - command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, 'clean') - cli.run(command, capture_output=False, stdin=DEVNULL) - - # Build the environment vars - envs = {} - for env in cli.args.env: - if '=' in env: - key, value = env.split('=', 1) - envs[key] = value - else: - cli.log.warning('Invalid environment variable: %s', env) - - # Determine the compile command - command = '' - - if cli.args.bootloaders: - # Provide usage and list bootloaders - cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]') - print_bootloader_help() - return False - - if cli.args.filename: - # Handle compiling a configurator JSON - user_keymap = parse_configurator_json(cli.args.filename) - keymap_path = qmk.path.keymap(user_keymap['keyboard']) - command = compile_configurator_json(user_keymap, cli.args.bootloader, parallel=cli.config.flash.parallel, **envs) - - cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap']) + if cli.args.filename and cli.args.filename.suffix in ['.bin', '.hex']: + # Try to flash binary firmware + cli.echo('Flashing binary firmware...\nPlease reset your keyboard into bootloader mode now!\nPress Ctrl-C to exit.\n') + try: + err, msg = flasher(cli.args.mcu, cli.args.filename) + if err: + cli.log.error(msg) + return False + except KeyboardInterrupt: + cli.log.info('Ctrl-C was pressed, exiting...') + sys.exit(0) else: - if cli.config.flash.keyboard and cli.config.flash.keymap: - # Generate the make command for a specific keyboard/keymap. - command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, cli.args.bootloader, parallel=cli.config.flash.parallel, **envs) - - elif not cli.config.flash.keyboard: - cli.log.error('Could not determine keyboard!') - elif not cli.config.flash.keymap: - cli.log.error('Could not determine keymap!') - - # Compile the firmware, if we're able to - if command: - cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(command)) - if not cli.args.dry_run: - cli.echo('\n') - compile = cli.run(command, capture_output=False, stdin=DEVNULL) - return compile.returncode + if cli.args.clean and not cli.args.filename and not cli.args.dry_run: + if cli.config.flash.keyboard and cli.config.flash.keymap: + command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, 'clean') + cli.run(command, capture_output=False, stdin=DEVNULL) + + # Build the environment vars + envs = {} + for env in cli.args.env: + if '=' in env: + key, value = env.split('=', 1) + envs[key] = value + else: + cli.log.warning('Invalid environment variable: %s', env) + + # Determine the compile command + command = '' + + if cli.args.bootloaders: + # Provide usage and list bootloaders + cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]') + print_bootloader_help() + return False + + if cli.args.filename: + # Handle compiling a configurator JSON + user_keymap = parse_configurator_json(cli.args.filename) + keymap_path = qmk.path.keymap(user_keymap['keyboard']) + command = compile_configurator_json(user_keymap, cli.args.bootloader, parallel=cli.config.flash.parallel, **envs) + + cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap']) - else: - cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.') - cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]') - return False + else: + if cli.config.flash.keyboard and cli.config.flash.keymap: + # Generate the make command for a specific keyboard/keymap. + command = create_make_command(cli.config.flash.keyboard, cli.config.flash.keymap, cli.args.bootloader, parallel=cli.config.flash.parallel, **envs) + + elif not cli.config.flash.keyboard: + cli.log.error('Could not determine keyboard!') + elif not cli.config.flash.keymap: + cli.log.error('Could not determine keymap!') + + # Compile the firmware, if we're able to + if command: + cli.log.info('Compiling keymap with {fg_cyan}%s', ' '.join(command)) + if not cli.args.dry_run: + cli.echo('\n') + compile = cli.run(command, capture_output=False, stdin=DEVNULL) + return compile.returncode + + else: + cli.log.error('You must supply a configurator export, both `--keyboard` and `--keymap`, or be in a directory for a keyboard or keymap.') + cli.echo('usage: qmk flash [-h] [-b] [-n] [-kb KEYBOARD] [-km KEYMAP] [-bl BOOTLOADER] [filename]') + return False diff --git a/lib/python/qmk/cli/generate/api.py b/lib/python/qmk/cli/generate/api.py index 0596b3f22b..8d8ca3cd41 100755 --- a/lib/python/qmk/cli/generate/api.py +++ b/lib/python/qmk/cli/generate/api.py @@ -12,21 +12,30 @@ from qmk.json_encoders import InfoJSONEncoder from qmk.json_schema import json_load from qmk.keyboard import find_readme, list_keyboards -TEMPLATE_PATH = Path('data/templates/api/') +DATA_PATH = Path('data') +TEMPLATE_PATH = DATA_PATH / 'templates/api/' BUILD_API_PATH = Path('.build/api_data/') +def _filtered_keyboard_list(): + """Perform basic filtering of list_keyboards + """ + keyboard_list = list_keyboards() + if cli.args.filter: + kb_list = [] + for keyboard_name in keyboard_list: + if any(i in keyboard_name for i in cli.args.filter): + kb_list.append(keyboard_name) + keyboard_list = kb_list + return keyboard_list + + @cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't write the data to disk.") @cli.argument('-f', '--filter', arg_only=True, action='append', default=[], help="Filter the list of keyboards based on partial name matches the supplied value. May be passed multiple times.") -@cli.subcommand('Creates a new keymap for the keyboard of your choosing', hidden=False if cli.config.user.developer else True) +@cli.subcommand('Generate QMK API data', hidden=False if cli.config.user.developer else True) def generate_api(cli): """Generates the QMK API data. """ - if BUILD_API_PATH.exists(): - shutil.rmtree(BUILD_API_PATH) - - shutil.copytree(TEMPLATE_PATH, BUILD_API_PATH) - v1_dir = BUILD_API_PATH / 'v1' keyboard_all_file = v1_dir / 'keyboards.json' # A massive JSON containing everything keyboard_list_file = v1_dir / 'keyboard_list.json' # A simple list of keyboard targets @@ -34,14 +43,14 @@ def generate_api(cli): keyboard_metadata_file = v1_dir / 'keyboard_metadata.json' # All the data configurator/via needs for initialization usb_file = v1_dir / 'usb.json' # A mapping of USB VID/PID -> keyboard target + if BUILD_API_PATH.exists(): + shutil.rmtree(BUILD_API_PATH) + + shutil.copytree(TEMPLATE_PATH, BUILD_API_PATH) + shutil.copytree(DATA_PATH, v1_dir) + # Filter down when required - keyboard_list = list_keyboards() - if cli.args.filter: - kb_list = [] - for keyboard_name in keyboard_list: - if any(i in keyboard_name for i in cli.args.filter): - kb_list.append(keyboard_name) - keyboard_list = kb_list + keyboard_list = _filtered_keyboard_list() kb_all = {} usb_list = {} diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py index 893892c479..a26dcdf7d7 100755 --- a/lib/python/qmk/cli/generate/config_h.py +++ b/lib/python/qmk/cli/generate/config_h.py @@ -134,6 +134,36 @@ def generate_config_items(kb_info_json, config_h_lines): config_h_lines.append(f'#endif // {config_key}') +def generate_encoder_config(encoder_json, config_h_lines, postfix=''): + """Generate the config.h lines for encoders.""" + a_pads = [] + b_pads = [] + resolutions = [] + for encoder in encoder_json.get("rotary", []): + a_pads.append(encoder["pin_a"]) + b_pads.append(encoder["pin_b"]) + resolutions.append(encoder.get("resolution", None)) + + config_h_lines.append(f'#ifndef ENCODERS_PAD_A{postfix}') + config_h_lines.append(f'# define ENCODERS_PAD_A{postfix} {{ { ", ".join(a_pads) } }}') + config_h_lines.append(f'#endif // ENCODERS_PAD_A{postfix}') + + config_h_lines.append(f'#ifndef ENCODERS_PAD_B{postfix}') + config_h_lines.append(f'# define ENCODERS_PAD_B{postfix} {{ { ", ".join(b_pads) } }}') + config_h_lines.append(f'#endif // ENCODERS_PAD_B{postfix}') + + if None in resolutions: + cli.log.debug("Unable to generate ENCODER_RESOLUTION configuration") + elif len(set(resolutions)) == 1: + config_h_lines.append(f'#ifndef ENCODER_RESOLUTION{postfix}') + config_h_lines.append(f'# define ENCODER_RESOLUTION{postfix} { resolutions[0] }') + config_h_lines.append(f'#endif // ENCODER_RESOLUTION{postfix}') + else: + config_h_lines.append(f'#ifndef ENCODER_RESOLUTIONS{postfix}') + config_h_lines.append(f'# define ENCODER_RESOLUTIONS{postfix} {{ { ", ".join(map(str,resolutions)) } }}') + config_h_lines.append(f'#endif // ENCODER_RESOLUTIONS{postfix}') + + def generate_split_config(kb_info_json, config_h_lines): """Generate the config.h lines for split boards.""" if 'primary' in kb_info_json['split']: @@ -173,6 +203,9 @@ def generate_split_config(kb_info_json, config_h_lines): if 'right' in kb_info_json['split'].get('matrix_pins', {}): config_h_lines.append(matrix_pins(kb_info_json['split']['matrix_pins']['right'], '_RIGHT')) + if 'right' in kb_info_json['split'].get('encoder', {}): + generate_encoder_config(kb_info_json['split']['encoder']['right'], config_h_lines, '_RIGHT') + @cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to') @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") @@ -198,6 +231,9 @@ def generate_config_h(cli): if 'matrix_pins' in kb_info_json: config_h_lines.append(matrix_pins(kb_info_json['matrix_pins'])) + if 'encoder' in kb_info_json: + generate_encoder_config(kb_info_json['encoder'], config_h_lines) + if 'split' in kb_info_json: generate_split_config(kb_info_json, config_h_lines) diff --git a/lib/python/qmk/cli/generate/dfu_header.py b/lib/python/qmk/cli/generate/dfu_header.py index e873117387..aa0252ca86 100644 --- a/lib/python/qmk/cli/generate/dfu_header.py +++ b/lib/python/qmk/cli/generate/dfu_header.py @@ -33,8 +33,8 @@ def generate_dfu_header(cli): kb_info_json = dotty(info_json(cli.config.generate_dfu_header.keyboard)) keyboard_h_lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once'] - keyboard_h_lines.append(f'#define MANUFACTURER {kb_info_json["manufacturer"]}') - keyboard_h_lines.append(f'#define PRODUCT {kb_info_json["keyboard_name"]} Bootloader') + keyboard_h_lines.append(f'#define MANUFACTURER "{kb_info_json["manufacturer"]}"') + keyboard_h_lines.append(f'#define PRODUCT "{kb_info_json["keyboard_name"]} Bootloader"') # Optional if 'qmk_lufa_bootloader.esc_output' in kb_info_json: diff --git a/lib/python/qmk/cli/generate/info_json.py b/lib/python/qmk/cli/generate/info_json.py index 284d1a8510..0dc80f10cc 100755 --- a/lib/python/qmk/cli/generate/info_json.py +++ b/lib/python/qmk/cli/generate/info_json.py @@ -5,7 +5,7 @@ Compile an info.json for a particular keyboard and pretty-print it. import json from argcomplete.completers import FilesCompleter -from jsonschema import Draft7Validator, RefResolver, validators +from jsonschema import Draft202012Validator, RefResolver, validators from milc import cli from pathlib import Path @@ -18,7 +18,7 @@ from qmk.path import is_keyboard, normpath def pruning_validator(validator_class): - """Extends Draft7Validator to remove properties that aren't specified in the schema. + """Extends Draft202012Validator to remove properties that aren't specified in the schema. """ validate_properties = validator_class.VALIDATORS["properties"] @@ -37,10 +37,10 @@ def strip_info_json(kb_info_json): """Remove the API-only properties from the info.json. """ schema_store = compile_schema_store() - pruning_draft_7_validator = pruning_validator(Draft7Validator) + pruning_draft_validator = pruning_validator(Draft202012Validator) schema = schema_store['qmk.keyboard.v1'] resolver = RefResolver.from_schema(schema_store['qmk.keyboard.v1'], store=schema_store) - validator = pruning_draft_7_validator(schema, resolver=resolver).validate + validator = pruning_draft_validator(schema, resolver=resolver).validate return validator(kb_info_json) diff --git a/lib/python/qmk/cli/generate/keyboard_h.py b/lib/python/qmk/cli/generate/keyboard_h.py index 2058865cbf..54ddb4cffd 100755 --- a/lib/python/qmk/cli/generate/keyboard_h.py +++ b/lib/python/qmk/cli/generate/keyboard_h.py @@ -41,7 +41,7 @@ def generate_keyboard_h(cli): keyboard_h_lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '#include "quantum.h"'] if not has_layout_h: - keyboard_h_lines.append('#pragma error("<keyboard>.h is only optional for data driven keyboards - kb.h == bad times")') + keyboard_h_lines.append('#error("<keyboard>.h is only optional for data driven keyboards - kb.h == bad times")') # Show the results dump_lines(cli.args.output, keyboard_h_lines, cli.args.quiet) diff --git a/lib/python/qmk/cli/import/__init__.py b/lib/python/qmk/cli/import/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/python/qmk/cli/import/__init__.py diff --git a/lib/python/qmk/cli/import/kbfirmware.py b/lib/python/qmk/cli/import/kbfirmware.py new file mode 100644 index 0000000000..9c03737378 --- /dev/null +++ b/lib/python/qmk/cli/import/kbfirmware.py @@ -0,0 +1,25 @@ +from milc import cli + +from qmk.importers import import_kbfirmware as _import_kbfirmware +from qmk.path import FileType +from qmk.json_schema import json_load + + +@cli.argument('filename', type=FileType('r'), nargs='+', arg_only=True, help='file') +@cli.subcommand('Import kbfirmware json export') +def import_kbfirmware(cli): + filename = cli.args.filename[0] + + data = json_load(filename) + + cli.log.info(f'{{style_bright}}Importing {filename.name}.{{style_normal}}') + cli.echo('') + + cli.log.warn("Support here is basic - Consider using 'qmk new-keyboard' instead") + + kb_name = _import_kbfirmware(data) + + cli.log.info(f'{{fg_green}}Imported a new keyboard named {{fg_cyan}}{kb_name}{{fg_green}}.{{fg_reset}}') + cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}keyboards/{kb_name}{{fg_reset}},') + cli.log.info('or open the directory in your preferred text editor.') + cli.log.info(f"And build with {{fg_yellow}}qmk compile -kb {kb_name} -km default{{fg_reset}}.") diff --git a/lib/python/qmk/cli/import/keyboard.py b/lib/python/qmk/cli/import/keyboard.py new file mode 100644 index 0000000000..3a5ed37dee --- /dev/null +++ b/lib/python/qmk/cli/import/keyboard.py @@ -0,0 +1,23 @@ +from milc import cli + +from qmk.importers import import_keyboard as _import_keyboard +from qmk.path import FileType +from qmk.json_schema import json_load + + +@cli.argument('filename', type=FileType('r'), nargs='+', arg_only=True, help='file') +@cli.subcommand('Import data-driven keyboard') +def import_keyboard(cli): + filename = cli.args.filename[0] + + data = json_load(filename) + + cli.log.info(f'{{style_bright}}Importing {filename.name}.{{style_normal}}') + cli.echo('') + + kb_name = _import_keyboard(data) + + cli.log.info(f'{{fg_green}}Imported a new keyboard named {{fg_cyan}}{kb_name}{{fg_green}}.{{fg_reset}}') + cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}keyboards/{kb_name}{{fg_reset}},') + cli.log.info('or open the directory in your preferred text editor.') + cli.log.info(f"And build with {{fg_yellow}}qmk compile -kb {kb_name} -km default{{fg_reset}}.") diff --git a/lib/python/qmk/cli/import/keymap.py b/lib/python/qmk/cli/import/keymap.py new file mode 100644 index 0000000000..a499c93480 --- /dev/null +++ b/lib/python/qmk/cli/import/keymap.py @@ -0,0 +1,23 @@ +from milc import cli + +from qmk.importers import import_keymap as _import_keymap +from qmk.path import FileType +from qmk.json_schema import json_load + + +@cli.argument('filename', type=FileType('r'), nargs='+', arg_only=True, help='file') +@cli.subcommand('Import data-driven keymap') +def import_keymap(cli): + filename = cli.args.filename[0] + + data = json_load(filename) + + cli.log.info(f'{{style_bright}}Importing {filename.name}.{{style_normal}}') + cli.echo('') + + kb_name, km_name = _import_keymap(data) + + cli.log.info(f'{{fg_green}}Imported a new keymap named {{fg_cyan}}{km_name}{{fg_green}}.{{fg_reset}}') + cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}keyboards/{kb_name}/keymaps/{km_name}{{fg_reset}},') + cli.log.info('or open the directory in your preferred text editor.') + cli.log.info(f"And build with {{fg_yellow}}qmk compile -kb {kb_name} -km {km_name}{{fg_reset}}.") diff --git a/lib/python/qmk/cli/lint.py b/lib/python/qmk/cli/lint.py index af057b4110..6b077c250f 100644 --- a/lib/python/qmk/cli/lint.py +++ b/lib/python/qmk/cli/lint.py @@ -7,26 +7,43 @@ from milc import cli from qmk.decorators import automagic_keyboard, automagic_keymap from qmk.info import info_json from qmk.keyboard import keyboard_completer, list_keyboards -from qmk.keymap import locate_keymap +from qmk.keymap import locate_keymap, list_keymaps from qmk.path import is_keyboard, keyboard +from qmk.git import git_get_ignored_files -def keymap_check(kb, km): - """Perform the keymap level checks. +def _list_defaultish_keymaps(kb): + """Return default like keymaps for a given keyboard """ - ok = True - keymap_path = locate_keymap(kb, km) + defaultish = ['ansi', 'iso', 'via'] - if not keymap_path: + keymaps = set() + for x in list_keymaps(kb): + if x in defaultish or x.startswith('default'): + keymaps.add(x) + + return keymaps + + +def _handle_json_errors(kb, info): + """Convert any json errors into lint errors + """ + ok = True + # Check for errors in the json + if info['parse_errors']: ok = False - cli.log.error("%s: Can't find %s keymap.", kb, km) + cli.log.error(f'{kb}: Errors found when generating info.json.') + if cli.config.lint.strict and info['parse_warnings']: + ok = False + cli.log.error(f'{kb}: Warnings found when generating info.json (Strict mode enabled.)') return ok -def rules_mk_assignment_only(keyboard_path): +def _rules_mk_assignment_only(kb): """Check the keyboard-level rules.mk to ensure it only has assignments. """ + keyboard_path = keyboard(kb) current_path = Path() errors = [] @@ -58,10 +75,58 @@ def rules_mk_assignment_only(keyboard_path): return errors +def keymap_check(kb, km): + """Perform the keymap level checks. + """ + ok = True + keymap_path = locate_keymap(kb, km) + + if not keymap_path: + ok = False + cli.log.error("%s: Can't find %s keymap.", kb, km) + return ok + + # Additional checks + invalid_files = git_get_ignored_files(keymap_path.parent.as_posix()) + for file in invalid_files: + cli.log.error(f'{kb}/{km}: The file "{file}" should not exist!') + ok = False + + return ok + + +def keyboard_check(kb): + """Perform the keyboard level checks. + """ + ok = True + kb_info = info_json(kb) + + if not _handle_json_errors(kb, kb_info): + ok = False + + # Additional checks + rules_mk_assignment_errors = _rules_mk_assignment_only(kb) + if rules_mk_assignment_errors: + ok = False + cli.log.error('%s: Non-assignment code found in rules.mk. Move it to post_rules.mk instead.', kb) + for assignment_error in rules_mk_assignment_errors: + cli.log.error(assignment_error) + + invalid_files = git_get_ignored_files(f'keyboards/{kb}/') + for file in invalid_files: + if 'keymap' in file: + continue + cli.log.error(f'{kb}: The file "{file}" should not exist!') + ok = False + + return ok + + @cli.argument('--strict', action='store_true', help='Treat warnings as errors') @cli.argument('-kb', '--keyboard', completer=keyboard_completer, help='Comma separated list of keyboards to check') @cli.argument('-km', '--keymap', help='The keymap to check') @cli.argument('--all-kb', action='store_true', arg_only=True, help='Check all keyboards') +@cli.argument('--all-km', action='store_true', arg_only=True, help='Check all keymaps') @cli.subcommand('Check keyboard and keymap for common mistakes.') @automagic_keyboard @automagic_keymap @@ -73,7 +138,7 @@ def lint(cli): # Determine our keyboard list if cli.args.all_kb: if cli.args.keyboard: - cli.log.warning('Both --all-kb and --keyboard passed, --all-kb takes presidence.') + cli.log.warning('Both --all-kb and --keyboard passed, --all-kb takes precedence.') keyboard_list = list_keyboards() elif not cli.config.lint.keyboard: @@ -89,38 +154,25 @@ def lint(cli): cli.log.error('No such keyboard: %s', kb) continue - # Gather data about the keyboard. - ok = True - keyboard_path = keyboard(kb) - keyboard_info = info_json(kb) + # Determine keymaps to also check + if cli.args.all_km: + keymaps = list_keymaps(kb) + elif cli.config.lint.keymap: + keymaps = {cli.config.lint.keymap} + else: + keymaps = _list_defaultish_keymaps(kb) + # Ensure that at least a 'default' keymap always exists + keymaps.add('default') - # Check for errors in the info.json - if keyboard_info['parse_errors']: - ok = False - cli.log.error('%s: Errors found when generating info.json.', kb) - - if cli.config.lint.strict and keyboard_info['parse_warnings']: - ok = False - cli.log.error('%s: Warnings found when generating info.json (Strict mode enabled.)', kb) + ok = True - # Check the rules.mk file(s) - rules_mk_assignment_errors = rules_mk_assignment_only(keyboard_path) - if rules_mk_assignment_errors: + # keyboard level checks + if not keyboard_check(kb): ok = False - cli.log.error('%s: Non-assignment code found in rules.mk. Move it to post_rules.mk instead.', kb) - for assignment_error in rules_mk_assignment_errors: - cli.log.error(assignment_error) # Keymap specific checks - if cli.config.lint.keymap: - if not keymap_check(kb, cli.config.lint.keymap): - ok = False - - # Check if all non-data driven macros exist in <keyboard.h> - for layout, data in keyboard_info['layouts'].items(): - # Matrix data should be a list with exactly two integers: [0, 1] - if not data['c_macro'] and not all('matrix' in key_data.keys() or len(key_data) == 2 or all(isinstance(n, int) for n in key_data) for key_data in data['layout']): - cli.log.error(f'{kb}: "{layout}" has no "matrix" definition in either "info.json" or "<keyboard>.h"!') + for keymap in keymaps: + if not keymap_check(kb, keymap): ok = False # Report status diff --git a/lib/python/qmk/cli/multibuild.py b/lib/python/qmk/cli/multibuild.py index dff8c88422..5e0f0b5188 100755 --- a/lib/python/qmk/cli/multibuild.py +++ b/lib/python/qmk/cli/multibuild.py @@ -28,6 +28,7 @@ def _is_split(keyboard_name): return True if 'SPLIT_KEYBOARD' in rules_mk and rules_mk['SPLIT_KEYBOARD'].lower() == 'yes' else False +@cli.argument('-t', '--no-temp', arg_only=True, action='store_true', help="Remove temporary files during build.") @cli.argument('-j', '--parallel', type=int, default=1, help="Set the number of parallel make jobs; 0 means unlimited.") @cli.argument('-c', '--clean', arg_only=True, action='store_true', help="Remove object files before compiling.") @cli.argument('-f', '--filter', arg_only=True, action='append', default=[], help="Filter the list of keyboards based on the supplied value in rules.mk. Supported format is 'SPLIT_KEYBOARD=yes'. May be passed multiple times.") @@ -69,6 +70,7 @@ def multibuild(cli): all: {keyboard_safe}_binary {keyboard_safe}_binary: @rm -f "{QMK_FIRMWARE}/.build/failed.log.{keyboard_safe}" || true + @echo "Compiling QMK Firmware for target: '{keyboard_name}:{cli.args.keymap}'..." >>"{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" +@$(MAKE) -C "{QMK_FIRMWARE}" -f "{QMK_FIRMWARE}/builddefs/build_keyboard.mk" KEYBOARD="{keyboard_name}" KEYMAP="{cli.args.keymap}" REQUIRE_PLATFORM_KEY= COLOR=true SILENT=false {' '.join(cli.args.env)} \\ >>"{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" 2>&1 \\ || cp "{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" "{QMK_FIRMWARE}/.build/failed.log.{os.getpid()}.{keyboard_safe}" @@ -76,11 +78,26 @@ all: {keyboard_safe}_binary || {{ grep '\[WARNINGS\]' "{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" >/dev/null 2>&1 && printf "Build %-64s \e[1;33m[WARNINGS]\e[0m\\n" "{keyboard_name}:{cli.args.keymap}" ; }} \\ || printf "Build %-64s \e[1;32m[OK]\e[0m\\n" "{keyboard_name}:{cli.args.keymap}" @rm -f "{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}" || true - """# noqa ) # yapf: enable + if cli.args.no_temp: + # yapf: disable + f.write( + f"""\ + @rm -rf "{QMK_FIRMWARE}/.build/{keyboard_safe}_{cli.args.keymap}.elf" 2>/dev/null || true + @rm -rf "{QMK_FIRMWARE}/.build/{keyboard_safe}_{cli.args.keymap}.map" 2>/dev/null || true + @rm -rf "{QMK_FIRMWARE}/.build/{keyboard_safe}_{cli.args.keymap}.hex" 2>/dev/null || true + @rm -rf "{QMK_FIRMWARE}/.build/{keyboard_safe}_{cli.args.keymap}.bin" 2>/dev/null || true + @rm -rf "{QMK_FIRMWARE}/.build/{keyboard_safe}_{cli.args.keymap}.uf2" 2>/dev/null || true + @rm -rf "{QMK_FIRMWARE}/.build/obj_{keyboard_safe}" || true + @rm -rf "{QMK_FIRMWARE}/.build/obj_{keyboard_safe}_{cli.args.keymap}" || true +"""# noqa + ) + # yapf: enable + f.write('\n') + cli.run([make_cmd, *get_make_parallel_args(cli.args.parallel), '-f', makefile.as_posix(), 'all'], capture_output=False, stdin=DEVNULL) # Check for failures diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py index a54d9058bc..8a13029a8a 100644 --- a/lib/python/qmk/constants.py +++ b/lib/python/qmk/constants.py @@ -14,12 +14,13 @@ QMK_FIRMWARE_UPSTREAM = 'qmk/qmk_firmware' MAX_KEYBOARD_SUBFOLDERS = 5 # Supported processor types -CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95' +CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK64FX512', 'MK66FX1M0', 'RP2040', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95' LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85' # Bootloaders of the supported processors MCU2BOOTLOADER = { + "RP2040": "rp2040", "MKL26Z64": "halfkay", "MK20DX128": "halfkay", "MK20DX256": "halfkay", @@ -58,6 +59,59 @@ MCU2BOOTLOADER = { "atmega328": "usbasploader", } +# Map of legacy keycodes that can be automatically updated +LEGACY_KEYCODES = { # Comment here is to force multiline formatting + 'RESET': 'QK_BOOT' +} + +# Map VID:PID values to bootloaders +BOOTLOADER_VIDS_PIDS = { + 'atmel-dfu': { + ("03eb", "2fef"), # ATmega16U2 + ("03eb", "2ff0"), # ATmega32U2 + ("03eb", "2ff3"), # ATmega16U4 + ("03eb", "2ff4"), # ATmega32U4 + ("03eb", "2ff9"), # AT90USB64 + ("03eb", "2ffa"), # AT90USB162 + ("03eb", "2ffb") # AT90USB128 + }, + 'kiibohd': {("1c11", "b007")}, + 'stm32-dfu': { + ("1eaf", "0003"), # STM32duino + ("0483", "df11") # STM32 DFU + }, + 'apm32-dfu': {("314b", "0106")}, + 'gd32v-dfu': {("28e9", "0189")}, + 'bootloadhid': {("16c0", "05df")}, + 'usbasploader': {("16c0", "05dc")}, + 'usbtinyisp': {("1782", "0c9f")}, + 'md-boot': {("03eb", "6124")}, + 'caterina': { + # pid.codes shared PID + ("1209", "2302"), # Keyboardio Atreus 2 Bootloader + # Spark Fun Electronics + ("1b4f", "9203"), # Pro Micro 3V3/8MHz + ("1b4f", "9205"), # Pro Micro 5V/16MHz + ("1b4f", "9207"), # LilyPad 3V3/8MHz (and some Pro Micro clones) + # Pololu Electronics + ("1ffb", "0101"), # A-Star 32U4 + # Arduino SA + ("2341", "0036"), # Leonardo + ("2341", "0037"), # Micro + # Adafruit Industries LLC + ("239a", "000c"), # Feather 32U4 + ("239a", "000d"), # ItsyBitsy 32U4 3V3/8MHz + ("239a", "000e"), # ItsyBitsy 32U4 5V/16MHz + # dog hunter AG + ("2a03", "0036"), # Leonardo + ("2a03", "0037") # Micro + }, + 'hid-bootloader': { + ("03eb", "2067"), # QMK HID + ("16c0", "0478") # PJRC halfkay + } +} + # Common format strings DATE_FORMAT = '%Y-%m-%d' DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S %Z' @@ -67,13 +121,6 @@ TIME_FORMAT = '%H:%M:%S' COL_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijilmnopqrstuvwxyz' ROW_LETTERS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop' -# Mapping between info.json and config.h keys -LED_INDICATORS = { - 'caps_lock': 'LED_CAPS_LOCK_PIN', - 'num_lock': 'LED_NUM_LOCK_PIN', - 'scroll_lock': 'LED_SCROLL_LOCK_PIN', -} - # Constants that should match their counterparts in make BUILD_DIR = environ.get('BUILD_DIR', '.build') KEYBOARD_OUTPUT_PREFIX = f'{BUILD_DIR}/obj_' diff --git a/lib/python/qmk/flashers.py b/lib/python/qmk/flashers.py new file mode 100644 index 0000000000..a9cf726b44 --- /dev/null +++ b/lib/python/qmk/flashers.py @@ -0,0 +1,203 @@ +import shutil +import time +import os +import signal + +import usb.core + +from qmk.constants import BOOTLOADER_VIDS_PIDS +from milc import cli + +# yapf: disable +_PID_TO_MCU = { + '2fef': 'atmega16u2', + '2ff0': 'atmega32u2', + '2ff3': 'atmega16u4', + '2ff4': 'atmega32u4', + '2ff9': 'at90usb64', + '2ffa': 'at90usb162', + '2ffb': 'at90usb128' +} + +AVRDUDE_MCU = { + 'atmega32a': 'm32', + 'atmega328p': 'm328p', + 'atmega328': 'm328', +} +# yapf: enable + + +class DelayedKeyboardInterrupt: + # Custom interrupt handler to delay the processing of Ctrl-C + # https://stackoverflow.com/a/21919644 + def __enter__(self): + self.signal_received = False + self.old_handler = signal.signal(signal.SIGINT, self.handler) + + def handler(self, sig, frame): + self.signal_received = (sig, frame) + + def __exit__(self, type, value, traceback): + signal.signal(signal.SIGINT, self.old_handler) + if self.signal_received: + self.old_handler(*self.signal_received) + + +# TODO: Make this more generic, so cli/doctor/check.py and flashers.py can share the code +def _check_dfu_programmer_version(): + # Return True if version is higher than 0.7.0: supports '--force' + check = cli.run(['dfu-programmer', '--version'], combined_output=True, timeout=5) + first_line = check.stdout.split('\n')[0] + version_number = first_line.split()[1] + maj, min_, bug = version_number.split('.') + if int(maj) >= 0 and int(min_) >= 7: + return True + else: + return False + + +def _find_bootloader(): + # To avoid running forever in the background, only look for bootloaders for 10min + start_time = time.time() + while time.time() - start_time < 600: + for bl in BOOTLOADER_VIDS_PIDS: + for vid, pid in BOOTLOADER_VIDS_PIDS[bl]: + vid_hex = int(f'0x{vid}', 0) + pid_hex = int(f'0x{pid}', 0) + with DelayedKeyboardInterrupt(): + # PyUSB does not like to be interrupted by Ctrl-C + # therefore we catch the interrupt with a custom handler + # and only process it once pyusb finished + dev = usb.core.find(idVendor=vid_hex, idProduct=pid_hex) + if dev: + if bl == 'atmel-dfu': + details = _PID_TO_MCU[pid] + elif bl == 'caterina': + details = (vid_hex, pid_hex) + elif bl == 'hid-bootloader': + if vid == '16c0' and pid == '0478': + details = 'halfkay' + else: + details = 'qmk-hid' + elif bl == 'stm32-dfu' or bl == 'apm32-dfu' or bl == 'gd32v-dfu' or bl == 'kiibohd': + details = (vid, pid) + else: + details = None + return (bl, details) + time.sleep(0.1) + return (None, None) + + +def _find_serial_port(vid, pid): + if 'windows' in cli.platform.lower(): + from serial.tools.list_ports_windows import comports + platform = 'windows' + else: + from serial.tools.list_ports_posix import comports + platform = 'posix' + + start_time = time.time() + # Caterina times out after 8 seconds + while time.time() - start_time < 8: + for port in comports(): + port, desc, hwid = port + if f'{vid:04x}:{pid:04x}' in hwid.casefold(): + if platform == 'windows': + time.sleep(1) + return port + else: + start_time = time.time() + # Wait until the port becomes writable before returning + while time.time() - start_time < 8: + if os.access(port, os.W_OK): + return port + else: + time.sleep(0.5) + return None + return None + + +def _flash_caterina(details, file): + port = _find_serial_port(details[0], details[1]) + if port: + cli.run(['avrdude', '-p', 'atmega32u4', '-c', 'avr109', '-U', f'flash:w:{file}:i', '-P', port], capture_output=False) + return False + else: + return True + + +def _flash_atmel_dfu(mcu, file): + force = '--force' if _check_dfu_programmer_version() else '' + cli.run(['dfu-programmer', mcu, 'erase', force], capture_output=False) + cli.run(['dfu-programmer', mcu, 'flash', force, file], capture_output=False) + cli.run(['dfu-programmer', mcu, 'reset'], capture_output=False) + + +def _flash_hid_bootloader(mcu, details, file): + if details == 'halfkay': + if shutil.which('teensy-loader-cli'): + cmd = 'teensy-loader-cli' + elif shutil.which('teensy_loader_cli'): + cmd = 'teensy_loader_cli' + + # Use 'hid_bootloader_cli' for QMK HID and as a fallback for HalfKay + if not cmd: + if shutil.which('hid_bootloader_cli'): + cmd = 'hid_bootloader_cli' + else: + return True + + cli.run([cmd, f'-mmcu={mcu}', '-w', '-v', file], capture_output=False) + + +def _flash_dfu_util(details, file): + # STM32duino + if details[0] == '1eaf' and details[1] == '0003': + cli.run(['dfu-util', '-a', '2', '-d', f'{details[0]}:{details[1]}', '-R', '-D', file], capture_output=False) + # kiibohd + elif details[0] == '1c11' and details[1] == 'b007': + cli.run(['dfu-util', '-a', '0', '-d', f'{details[0]}:{details[1]}', '-D', file], capture_output=False) + # STM32, APM32, or GD32V DFU + else: + cli.run(['dfu-util', '-a', '0', '-d', f'{details[0]}:{details[1]}', '-s', '0x08000000:leave', '-D', file], capture_output=False) + + +def _flash_isp(mcu, programmer, file): + programmer = 'usbasp' if programmer == 'usbasploader' else 'usbtiny' + # Check if the provide mcu has an avrdude-specific name, otherwise pass on what the user provided + mcu = AVRDUDE_MCU.get(mcu, mcu) + cli.run(['avrdude', '-p', mcu, '-c', programmer, '-U', f'flash:w:{file}:i'], capture_output=False) + + +def _flash_mdloader(file): + cli.run(['mdloader', '--first', '--download', file, '--restart'], capture_output=False) + + +def flasher(mcu, file): + bl, details = _find_bootloader() + # Add a small sleep to avoid race conditions + time.sleep(1) + if bl == 'atmel-dfu': + _flash_atmel_dfu(details, file.name) + elif bl == 'caterina': + if _flash_caterina(details, file.name): + return (True, "The Caterina bootloader was found but is not writable. Check 'qmk doctor' output for advice.") + elif bl == 'hid-bootloader': + if mcu: + if _flash_hid_bootloader(mcu, details, file.name): + return (True, "Please make sure 'teensy_loader_cli' or 'hid_bootloader_cli' is available on your system.") + else: + return (True, "Specifying the MCU with '-m' is necessary for HalfKay/HID bootloaders!") + elif bl == 'stm32-dfu' or bl == 'apm32-dfu' or bl == 'gd32v-dfu' or bl == 'kiibohd': + _flash_dfu_util(details, file.name) + elif bl == 'usbasploader' or bl == 'usbtinyisp': + if mcu: + _flash_isp(mcu, bl, file.name) + else: + return (True, "Specifying the MCU with '-m' is necessary for ISP flashing!") + elif bl == 'md-boot': + _flash_mdloader(file.name) + else: + return (True, "Known bootloader found but flashing not currently supported!") + + return (False, None) diff --git a/lib/python/qmk/git.py b/lib/python/qmk/git.py index beeb689144..7fa0306f5c 100644 --- a/lib/python/qmk/git.py +++ b/lib/python/qmk/git.py @@ -62,6 +62,25 @@ def git_get_tag(): return git_tag.stdout.strip() +def git_get_last_log_entry(branch_name): + """Retrieves the last log entry for the branch being worked on. + """ + git_lastlog = cli.run(['git', '--no-pager', 'log', '--pretty=format:%ad (%h) -- %s', '--date=iso', '-n1', branch_name]) + + if git_lastlog.returncode == 0 and git_lastlog.stdout: + return git_lastlog.stdout.strip() + + +def git_get_common_ancestor(branch_a, branch_b): + """Retrieves the common ancestor between for the two supplied branches. + """ + git_merge_base = cli.run(['git', 'merge-base', branch_a, branch_b]) + git_branchpoint_log = cli.run(['git', '--no-pager', 'log', '--pretty=format:%ad (%h) -- %s', '--date=iso', '-n1', git_merge_base.stdout.strip()]) + + if git_branchpoint_log.returncode == 0 and git_branchpoint_log.stdout: + return git_branchpoint_log.stdout.strip() + + def git_get_remotes(): """Returns the current remotes for a repo. """ @@ -108,3 +127,12 @@ def git_check_deviation(active_branch): cli.run(['git', 'fetch', 'upstream', active_branch]) deviations = cli.run(['git', '--no-pager', 'log', f'upstream/{active_branch}...{active_branch}']) return bool(deviations.returncode) + + +def git_get_ignored_files(check_dir='.'): + """Return a list of files that would be captured by the current .gitignore + """ + invalid = cli.run(['git', 'ls-files', '-c', '-o', '-i', '--exclude-from=.gitignore', check_dir]) + if invalid.returncode != 0: + return [] + return invalid.stdout.strip().splitlines() diff --git a/lib/python/qmk/importers.py b/lib/python/qmk/importers.py new file mode 100644 index 0000000000..307c66ee3c --- /dev/null +++ b/lib/python/qmk/importers.py @@ -0,0 +1,193 @@ +from dotty_dict import dotty +from datetime import date +from pathlib import Path +import json + +from qmk.git import git_get_username +from qmk.json_schema import validate +from qmk.path import keyboard, keymap +from qmk.constants import MCU2BOOTLOADER, LEGACY_KEYCODES +from qmk.json_encoders import InfoJSONEncoder, KeymapJSONEncoder +from qmk.json_schema import deep_update, json_load + +TEMPLATE = Path('data/templates/keyboard/') + + +def replace_placeholders(src, dest, tokens): + """Replaces the given placeholders in each template file. + """ + content = src.read_text() + for key, value in tokens.items(): + content = content.replace(f'%{key}%', value) + + dest.write_text(content) + + +def _gen_dummy_keymap(name, info_data): + # Pick the first layout macro and just dump in KC_NOs or something? + (layout_name, layout_data), *_ = info_data["layouts"].items() + layout_length = len(layout_data["layout"]) + + keymap_data = { + "keyboard": name, + "layout": layout_name, + "layers": [["KC_NO" for _ in range(0, layout_length)]], + } + + return keymap_data + + +def _extract_kbfirmware_layout(kbf_data): + layout = [] + for key in kbf_data['keyboard.keys']: + item = { + 'matrix': [key['row'], key['col']], + 'x': key['state']['x'], + 'y': key['state']['y'], + } + if key['state']['w'] != 1: + item['w'] = key['state']['w'] + if key['state']['h'] != 1: + item['h'] = key['state']['h'] + layout.append(item) + + return layout + + +def _extract_kbfirmware_keymap(kbf_data): + keymap_data = { + 'keyboard': kbf_data['keyboard.settings.name'].lower(), + 'layout': 'LAYOUT', + 'layers': [], + } + + for i in range(15): + layer = [] + for key in kbf_data['keyboard.keys']: + keycode = key['keycodes'][i]['id'] + keycode = LEGACY_KEYCODES.get(keycode, keycode) + if '()' in keycode: + fields = key['keycodes'][i]['fields'] + keycode = f'{keycode.split(")")[0]}{",".join(map(str, fields))})' + layer.append(keycode) + if set(layer) == {'KC_TRNS'}: + break + keymap_data['layers'].append(layer) + + return keymap_data + + +def import_keymap(keymap_data): + # Validate to ensure we don't have to deal with bad data - handles stdin/file + validate(keymap_data, 'qmk.keymap.v1') + + kb_name = keymap_data['keyboard'] + km_name = keymap_data['keymap'] + + km_folder = keymap(kb_name) / km_name + keyboard_keymap = km_folder / 'keymap.json' + + # This is the deepest folder in the expected tree + keyboard_keymap.parent.mkdir(parents=True, exist_ok=True) + + # Dump out all those lovely files + keyboard_keymap.write_text(json.dumps(keymap_data, cls=KeymapJSONEncoder)) + + return (kb_name, km_name) + + +def import_keyboard(info_data, keymap_data=None): + # Validate to ensure we don't have to deal with bad data - handles stdin/file + validate(info_data, 'qmk.api.keyboard.v1') + + # And validate some more as everything is optional + if not all(key in info_data for key in ['keyboard_name', 'layouts']): + raise ValueError('invalid info.json') + + kb_name = info_data['keyboard_name'] + + # bail + kb_folder = keyboard(kb_name) + if kb_folder.exists(): + raise ValueError(f'Keyboard {{fg_cyan}}{kb_name}{{fg_reset}} already exists! Please choose a different name.') + + if not keymap_data: + # TODO: if supports community then grab that instead + keymap_data = _gen_dummy_keymap(kb_name, info_data) + + keyboard_info = kb_folder / 'info.json' + keyboard_keymap = kb_folder / 'keymaps' / 'default' / 'keymap.json' + + # begin with making the deepest folder in the tree + keyboard_keymap.parent.mkdir(parents=True, exist_ok=True) + + user_name = git_get_username() + if not user_name: + user_name = 'TODO' + + tokens = { # Comment here is to force multiline formatting + 'YEAR': str(date.today().year), + 'KEYBOARD': kb_name, + 'USER_NAME': user_name, + 'REAL_NAME': user_name, + } + + # Dump out all those lovely files + for file in list(TEMPLATE.iterdir()): + replace_placeholders(file, kb_folder / file.name, tokens) + + temp = json_load(keyboard_info) + deep_update(temp, info_data) + + keyboard_info.write_text(json.dumps(temp, cls=InfoJSONEncoder)) + keyboard_keymap.write_text(json.dumps(keymap_data, cls=KeymapJSONEncoder)) + + return kb_name + + +def import_kbfirmware(kbfirmware_data): + kbf_data = dotty(kbfirmware_data) + + diode_direction = ["COL2ROW", "ROW2COL"][kbf_data['keyboard.settings.diodeDirection']] + mcu = ["atmega32u2", "atmega32u4", "at90usb1286"][kbf_data['keyboard.controller']] + bootloader = MCU2BOOTLOADER.get(mcu, "custom") + + layout = _extract_kbfirmware_layout(kbf_data) + keymap_data = _extract_kbfirmware_keymap(kbf_data) + + # convert to d/d info.json + info_data = dotty({ + "keyboard_name": kbf_data['keyboard.settings.name'].lower(), + "processor": mcu, + "bootloader": bootloader, + "diode_direction": diode_direction, + "matrix_pins": { + "cols": kbf_data['keyboard.pins.col'], + "rows": kbf_data['keyboard.pins.row'], + }, + "layouts": { + "LAYOUT": { + "layout": layout, + } + } + }) + + if kbf_data['keyboard.pins.num'] or kbf_data['keyboard.pins.caps'] or kbf_data['keyboard.pins.scroll']: + if kbf_data['keyboard.pins.num']: + info_data['indicators.num_lock'] = kbf_data['keyboard.pins.num'] + if kbf_data['keyboard.pins.caps']: + info_data['indicators.caps_lock'] = kbf_data['keyboard.pins.caps'] + if kbf_data['keyboard.pins.scroll']: + info_data['indicators.scroll_lock'] = kbf_data['keyboard.pins.scroll'] + + if kbf_data['keyboard.pins.rgb']: + info_data['rgblight.animations.all'] = True + info_data['rgblight.led_count'] = kbf_data['keyboard.settings.rgbNum'] + info_data['rgblight.pin'] = kbf_data['keyboard.pins.rgb'] + + if kbf_data['keyboard.pins.led']: + info_data['backlight.levels'] = kbf_data['keyboard.settings.backlightLevels'] + info_data['backlight.pin'] = kbf_data['keyboard.pins.led'] + + # delegate as if it were a regular keyboard import + return import_keyboard(info_data.to_dict(), keymap_data) diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 0763433b3d..7460d84ad3 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -26,13 +26,6 @@ def _valid_community_layout(layout): return (Path('layouts/default') / layout).exists() -def _remove_newlines_from_labels(layouts): - for layout_name, layout_json in layouts.items(): - for key in layout_json['layout']: - if '\n' in key['label']: - key['label'] = key['label'].split('\n')[0] - - def info_json(keyboard): """Generate the info.json data for a specific keyboard. """ @@ -111,23 +104,13 @@ def info_json(keyboard): # Check that the reported matrix size is consistent with the actual matrix size _check_matrix(info_data) - # Remove newline characters from layout labels - _remove_newlines_from_labels(layouts) - return info_data def _extract_features(info_data, rules): """Find all the features enabled in rules.mk. """ - # Special handling for bootmagic which also supports a "lite" mode. - if rules.get('BOOTMAGIC_ENABLE') == 'lite': - rules['BOOTMAGIC_LITE_ENABLE'] = 'on' - del rules['BOOTMAGIC_ENABLE'] - if rules.get('BOOTMAGIC_ENABLE') == 'full': - rules['BOOTMAGIC_ENABLE'] = 'on' - - # Process the rest of the rules as booleans + # Process booleans rules for key, value in rules.items(): if key.endswith('_ENABLE'): key = '_'.join(key.split('_')[:-1]).lower() @@ -228,6 +211,66 @@ def _extract_audio(info_data, config_c): info_data['audio'] = {'pins': audio_pins} +def _extract_encoders_values(config_c, postfix=''): + """Common encoder extraction logic + """ + a_pad = config_c.get(f'ENCODERS_PAD_A{postfix}', '').replace(' ', '')[1:-1] + b_pad = config_c.get(f'ENCODERS_PAD_B{postfix}', '').replace(' ', '')[1:-1] + resolutions = config_c.get(f'ENCODER_RESOLUTIONS{postfix}', '').replace(' ', '')[1:-1] + + default_resolution = config_c.get('ENCODER_RESOLUTION', None) + + if a_pad and b_pad: + a_pad = list(filter(None, a_pad.split(','))) + b_pad = list(filter(None, b_pad.split(','))) + resolutions = list(filter(None, resolutions.split(','))) + if default_resolution: + resolutions += [default_resolution] * (len(a_pad) - len(resolutions)) + + encoders = [] + for index in range(len(a_pad)): + encoder = {'pin_a': a_pad[index], 'pin_b': b_pad[index]} + if index < len(resolutions): + encoder['resolution'] = int(resolutions[index]) + encoders.append(encoder) + + return encoders + + +def _extract_encoders(info_data, config_c): + """Populate data about encoder pins + """ + encoders = _extract_encoders_values(config_c) + if encoders: + if 'encoder' not in info_data: + info_data['encoder'] = {} + + if 'rotary' in info_data['encoder']: + _log_warning(info_data, 'Encoder config is specified in both config.h and info.json (encoder.rotary) (Value: %s), the config.h value wins.' % info_data['encoder']['rotary']) + + info_data['encoder']['rotary'] = encoders + + +def _extract_split_encoders(info_data, config_c): + """Populate data about split encoder pins + """ + encoders = _extract_encoders_values(config_c, '_RIGHT') + if encoders: + if 'split' not in info_data: + info_data['split'] = {} + + if 'encoder' not in info_data['split']: + info_data['split']['encoder'] = {} + + if 'right' not in info_data['split']['encoder']: + info_data['split']['encoder']['right'] = {} + + if 'rotary' in info_data['split']['encoder']['right']: + _log_warning(info_data, 'Encoder config is specified in both config.h and info.json (encoder.rotary) (Value: %s), the config.h value wins.' % info_data['split']['encoder']['right']['rotary']) + + info_data['split']['encoder']['right']['rotary'] = encoders + + def _extract_secure_unlock(info_data, config_c): """Populate data about the secure unlock sequence """ @@ -324,12 +367,10 @@ def _extract_split_right_pins(info_data, config_c): # Figure out the right half matrix pins row_pins = config_c.get('MATRIX_ROW_PINS_RIGHT', '').replace('{', '').replace('}', '').strip() col_pins = config_c.get('MATRIX_COL_PINS_RIGHT', '').replace('{', '').replace('}', '').strip() - unused_pin_text = config_c.get('UNUSED_PINS_RIGHT') - unused_pins = unused_pin_text.replace('{', '').replace('}', '').strip() if isinstance(unused_pin_text, str) else None direct_pins = config_c.get('DIRECT_PINS_RIGHT', '').replace(' ', '')[1:-1] - if row_pins and col_pins: - if info_data.get('split', {}).get('matrix_pins', {}).get('right') in info_data: + if row_pins or col_pins or direct_pins: + if info_data.get('split', {}).get('matrix_pins', {}).get('right', None): _log_warning(info_data, 'Right hand matrix data is specified in both info.json and config.h, the config.h values win.') if 'split' not in info_data: @@ -341,37 +382,14 @@ def _extract_split_right_pins(info_data, config_c): if 'right' not in info_data['split']['matrix_pins']: info_data['split']['matrix_pins']['right'] = {} - info_data['split']['matrix_pins']['right'] = { - 'cols': _extract_pins(col_pins), - 'rows': _extract_pins(row_pins), - } + if col_pins: + info_data['split']['matrix_pins']['right']['cols'] = _extract_pins(col_pins) - if direct_pins: - if info_data.get('split', {}).get('matrix_pins', {}).get('right', {}): - _log_warning(info_data, 'Right hand matrix data is specified in both info.json and config.h, the config.h values win.') + if row_pins: + info_data['split']['matrix_pins']['right']['rows'] = _extract_pins(row_pins) - if 'split' not in info_data: - info_data['split'] = {} - - if 'matrix_pins' not in info_data['split']: - info_data['split']['matrix_pins'] = {} - - if 'right' not in info_data['split']['matrix_pins']: - info_data['split']['matrix_pins']['right'] = {} - - info_data['split']['matrix_pins']['right']['direct'] = _extract_direct_matrix(direct_pins) - - if unused_pins: - if 'split' not in info_data: - info_data['split'] = {} - - if 'matrix_pins' not in info_data['split']: - info_data['split']['matrix_pins'] = {} - - if 'right' not in info_data['split']['matrix_pins']: - info_data['split']['matrix_pins']['right'] = {} - - info_data['split']['matrix_pins']['right']['unused'] = _extract_pins(unused_pins) + if direct_pins: + info_data['split']['matrix_pins']['right']['direct'] = _extract_direct_matrix(direct_pins) def _extract_matrix_info(info_data, config_c): @@ -379,8 +397,6 @@ def _extract_matrix_info(info_data, config_c): """ row_pins = config_c.get('MATRIX_ROW_PINS', '').replace('{', '').replace('}', '').strip() col_pins = config_c.get('MATRIX_COL_PINS', '').replace('{', '').replace('}', '').strip() - unused_pin_text = config_c.get('UNUSED_PINS') - unused_pins = unused_pin_text.replace('{', '').replace('}', '').strip() if isinstance(unused_pin_text, str) else None direct_pins = config_c.get('DIRECT_PINS', '').replace(' ', '')[1:-1] info_snippet = {} @@ -406,12 +422,6 @@ def _extract_matrix_info(info_data, config_c): info_snippet['direct'] = _extract_direct_matrix(direct_pins) - if unused_pins: - if 'matrix_pins' not in info_data: - info_data['matrix_pins'] = {} - - info_snippet['unused'] = _extract_pins(unused_pins) - if config_c.get('CUSTOM_MATRIX', 'no') != 'no': if 'matrix_pins' in info_data and 'custom' in info_data['matrix_pins']: _log_warning(info_data, 'Custom Matrix is specified in both info.json and config.h, the config.h values win.') @@ -440,6 +450,47 @@ def _extract_device_version(info_data): info_data['usb']['device_version'] = f'{major}.{minor}.{revision}' +def _config_to_json(key_type, config_value): + """Convert config value using spec + """ + if key_type.startswith('array'): + if '.' in key_type: + key_type, array_type = key_type.split('.', 1) + else: + array_type = None + + config_value = config_value.replace('{', '').replace('}', '').strip() + + if array_type == 'int': + return list(map(int, config_value.split(','))) + else: + return config_value.split(',') + + elif key_type == 'bool': + return config_value in true_values + + elif key_type == 'hex': + return '0x' + config_value[2:].upper() + + elif key_type == 'list': + return config_value.split() + + elif key_type == 'int': + return int(config_value) + + elif key_type == 'str': + return config_value.strip('"') + + elif key_type == 'bcd_version': + major = int(config_value[2:4]) + minor = int(config_value[4]) + revision = int(config_value[5]) + + return f'{major}.{minor}.{revision}' + + return config_value + + def _extract_config_h(info_data, config_c): """Pull some keyboard information from existing config.h files """ @@ -452,47 +503,23 @@ def _extract_config_h(info_data, config_c): key_type = info_dict.get('value_type', 'raw') try: + replace_with = info_dict.get('replace_with') + if config_key in config_c and info_dict.get('invalid', False): + if replace_with: + _log_error(info_data, '%s in config.h is no longer a valid option and should be replaced with %s' % (config_key, replace_with)) + else: + _log_error(info_data, '%s in config.h is no longer a valid option and should be removed' % config_key) + elif config_key in config_c and info_dict.get('deprecated', False): + if replace_with: + _log_warning(info_data, '%s in config.h is deprecated in favor of %s and will be removed at a later date' % (config_key, replace_with)) + else: + _log_warning(info_data, '%s in config.h is deprecated and will be removed at a later date' % config_key) + if config_key in config_c and info_dict.get('to_json', True): if dotty_info.get(info_key) and info_dict.get('warn_duplicate', True): _log_warning(info_data, '%s in config.h is overwriting %s in info.json' % (config_key, info_key)) - if key_type.startswith('array'): - if '.' in key_type: - key_type, array_type = key_type.split('.', 1) - else: - array_type = None - - config_value = config_c[config_key].replace('{', '').replace('}', '').strip() - - if array_type == 'int': - dotty_info[info_key] = list(map(int, config_value.split(','))) - else: - dotty_info[info_key] = config_value.split(',') - - elif key_type == 'bool': - dotty_info[info_key] = config_c[config_key] in true_values - - elif key_type == 'hex': - dotty_info[info_key] = '0x' + config_c[config_key][2:].upper() - - elif key_type == 'list': - dotty_info[info_key] = config_c[config_key].split() - - elif key_type == 'int': - dotty_info[info_key] = int(config_c[config_key]) - - elif key_type == 'str': - dotty_info[info_key] = config_c[config_key].strip('"') - - elif key_type == 'bcd_version': - major = int(config_c[config_key][2:4]) - minor = int(config_c[config_key][4]) - revision = int(config_c[config_key][5]) - - dotty_info[info_key] = f'{major}.{minor}.{revision}' - - else: - dotty_info[info_key] = config_c[config_key] + dotty_info[info_key] = _config_to_json(key_type, config_c[config_key]) except Exception as e: _log_warning(info_data, f'{config_key}->{info_key}: {e}') @@ -506,6 +533,8 @@ def _extract_config_h(info_data, config_c): _extract_split_main(info_data, config_c) _extract_split_transport(info_data, config_c) _extract_split_right_pins(info_data, config_c) + _extract_encoders(info_data, config_c) + _extract_split_encoders(info_data, config_c) _extract_device_version(info_data) return info_data @@ -547,40 +576,23 @@ def _extract_rules_mk(info_data, rules): key_type = info_dict.get('value_type', 'raw') try: + replace_with = info_dict.get('replace_with') + if rules_key in rules and info_dict.get('invalid', False): + if replace_with: + _log_error(info_data, '%s in rules.mk is no longer a valid option and should be replaced with %s' % (rules_key, replace_with)) + else: + _log_error(info_data, '%s in rules.mk is no longer a valid option and should be removed' % rules_key) + elif rules_key in rules and info_dict.get('deprecated', False): + if replace_with: + _log_warning(info_data, '%s in rules.mk is deprecated in favor of %s and will be removed at a later date' % (rules_key, replace_with)) + else: + _log_warning(info_data, '%s in rules.mk is deprecated and will be removed at a later date' % rules_key) + if rules_key in rules and info_dict.get('to_json', True): if dotty_info.get(info_key) and info_dict.get('warn_duplicate', True): _log_warning(info_data, '%s in rules.mk is overwriting %s in info.json' % (rules_key, info_key)) - if key_type.startswith('array'): - if '.' in key_type: - key_type, array_type = key_type.split('.', 1) - else: - array_type = None - - rules_value = rules[rules_key].replace('{', '').replace('}', '').strip() - - if array_type == 'int': - dotty_info[info_key] = list(map(int, rules_value.split(','))) - else: - dotty_info[info_key] = rules_value.split(',') - - elif key_type == 'list': - dotty_info[info_key] = rules[rules_key].split() - - elif key_type == 'bool': - dotty_info[info_key] = rules[rules_key] in true_values - - elif key_type == 'hex': - dotty_info[info_key] = '0x' + rules[rules_key][2:].upper() - - elif key_type == 'int': - dotty_info[info_key] = int(rules[rules_key]) - - elif key_type == 'str': - dotty_info[info_key] = rules[rules_key].strip('"') - - else: - dotty_info[info_key] = rules[rules_key] + dotty_info[info_key] = _config_to_json(key_type, rules[rules_key]) except Exception as e: _log_warning(info_data, f'{rules_key}->{info_key}: {e}') @@ -821,8 +833,11 @@ def merge_info_jsons(keyboard, info_data): for new_key, existing_key in zip(layout['layout'], info_data['layouts'][layout_name]['layout']): existing_key.update(new_key) else: - layout['c_macro'] = False - info_data['layouts'][layout_name] = layout + if not all('matrix' in key_data.keys() for key_data in layout['layout']): + _log_error(info_data, f'Layout "{layout_name}" has no "matrix" definition in either "info.json" or "<keyboard>.h"!') + else: + layout['c_macro'] = False + info_data['layouts'][layout_name] = layout # Update info_data with the new data if 'layouts' in new_info_data: diff --git a/lib/python/qmk/json_schema.py b/lib/python/qmk/json_schema.py index 682346113e..01175146b5 100644 --- a/lib/python/qmk/json_schema.py +++ b/lib/python/qmk/json_schema.py @@ -68,11 +68,7 @@ def create_validator(schema): schema_store = compile_schema_store() resolver = jsonschema.RefResolver.from_schema(schema_store[schema], store=schema_store) - # TODO: Remove this after the jsonschema>=4 requirement had time to reach users - try: - return jsonschema.Draft202012Validator(schema_store[schema], resolver=resolver).validate - except AttributeError: - return jsonschema.Draft7Validator(schema_store[schema], resolver=resolver).validate + return jsonschema.Draft202012Validator(schema_store[schema], resolver=resolver).validate def validate(data, schema): diff --git a/lib/python/qmk/keyboard.py b/lib/python/qmk/keyboard.py index e69f63aebe..686d4fc403 100644 --- a/lib/python/qmk/keyboard.py +++ b/lib/python/qmk/keyboard.py @@ -103,7 +103,7 @@ def list_keyboards(): """ # We avoid pathlib here because this is performance critical code. kb_wildcard = os.path.join(base_path, "**", "rules.mk") - paths = [path for path in glob(kb_wildcard, recursive=True) if 'keymaps' not in path] + paths = [path for path in glob(kb_wildcard, recursive=True) if os.path.sep + 'keymaps' + os.path.sep not in path] return sorted(set(map(resolve_keyboard, map(_find_name, paths)))) diff --git a/lib/python/qmk/keymap.py b/lib/python/qmk/keymap.py index ca5be0959b..f317f4d11e 100644 --- a/lib/python/qmk/keymap.py +++ b/lib/python/qmk/keymap.py @@ -12,7 +12,7 @@ from pygments.token import Token from pygments import lex import qmk.path -from qmk.keyboard import find_keyboard_from_dir, rules_mk +from qmk.keyboard import find_keyboard_from_dir, rules_mk, keyboard_folder from qmk.errors import CppError # The `keymap.c` template to use when a keyboard doesn't have its own @@ -357,7 +357,7 @@ def locate_keymap(keyboard, keymap): checked_dirs = '' keymap_path = '' - for dir in keyboard.split('/'): + for dir in keyboard_folder(keyboard).split('/'): if checked_dirs: checked_dirs = '/'.join((checked_dirs, dir)) else: diff --git a/lib/python/qmk/submodules.py b/lib/python/qmk/submodules.py index 6a272dae50..52efa602a0 100644 --- a/lib/python/qmk/submodules.py +++ b/lib/python/qmk/submodules.py @@ -11,7 +11,11 @@ def status(): { 'name': 'submodule_name', 'status': None/False/True, - 'githash': '<sha-1 hash for the submodule> + 'githash': '<sha-1 hash for the submodule>' + 'shorthash': '<short hash for the submodule>' + 'describe': '<output of `git describe --tags`>' + 'last_log_message': 'log message' + 'last_log_timestamp': 'timestamp' } status is None when the submodule doesn't exist, False when it's out of date, and True when it's current @@ -36,6 +40,26 @@ def status(): else: raise ValueError('Unknown `git submodule status` sha-1 prefix character: "%s"' % status) + submodule_logs = cli.run(['git', 'submodule', '-q', 'foreach', 'git --no-pager log --pretty=format:"$sm_path%x01%h%x01%ad%x01%s%x0A" --date=iso -n1']) + for log_line in submodule_logs.stdout.split('\n'): + if not log_line: + continue + + r = log_line.split('\x01') + submodule = r[0] + submodules[submodule]['shorthash'] = r[1] if len(r) > 1 else '' + submodules[submodule]['last_log_timestamp'] = r[2] if len(r) > 2 else '' + submodules[submodule]['last_log_message'] = r[3] if len(r) > 3 else '' + + submodule_tags = cli.run(['git', 'submodule', '-q', 'foreach', '\'echo $sm_path `git describe --tags`\'']) + for log_line in submodule_tags.stdout.split('\n'): + if not log_line: + continue + + r = log_line.split() + submodule = r[0] + submodules[submodule]['describe'] = r[1] if len(r) > 1 else '' + return submodules diff --git a/lib/python/qmk/tests/test_cli_commands.py b/lib/python/qmk/tests/test_cli_commands.py index 71830ce194..2f3d09723f 100644 --- a/lib/python/qmk/tests/test_cli_commands.py +++ b/lib/python/qmk/tests/test_cli_commands.py @@ -97,13 +97,15 @@ def test_list_keyboards(): def test_list_keymaps(): result = check_subcommand('list-keymaps', '-kb', 'handwired/pytest/basic') check_returncode(result) - assert 'default' and 'default_json' in result.stdout + assert 'default' in result.stdout + assert 'default_json' in result.stdout def test_list_keymaps_long(): result = check_subcommand('list-keymaps', '--keyboard', 'handwired/pytest/basic') check_returncode(result) - assert 'default' and 'default_json' in result.stdout + assert 'default' in result.stdout + assert 'default_json' in result.stdout def test_list_keymaps_community(): @@ -113,25 +115,24 @@ def test_list_keymaps_community(): def test_list_keymaps_kb_only(): -<<<<<<< HEAD result = check_subcommand('list-keymaps', '-kb', 'moonlander') -======= - result = check_subcommand('list-keymaps', '-kb', 'contra') ->>>>>>> qmk/master check_returncode(result) - assert 'default' and 'oyrx' and 'webusb' in result.stdout + assert 'default' in result.stdout + assert 'oryx' in result.stdout def test_list_keymaps_vendor_kb(): result = check_subcommand('list-keymaps', '-kb', 'planck/ez') check_returncode(result) - assert 'default' and 'oryx' and 'webusb' in result.stdout + assert 'default' in result.stdout + assert 'oryx' in result.stdout -# def test_list_keymaps_vendor_kb_rev(): -# result = check_subcommand('list-keymaps', '-kb', 'kbdfans/kbd67/mkiirgb/v2') -# check_returncode(result) -# assert 'default' and 'via' in result.stdout +def test_list_keymaps_vendor_kb_rev(): + result = check_subcommand('list-keymaps', '-kb', 'kbdfans/kbd67/mkiirgb/v2') + check_returncode(result) + assert 'default' in result.stdout + assert 'oryx' in result.stdout def test_list_keymaps_no_keyboard_found(): @@ -263,7 +264,6 @@ def test_generate_config_h(): result = check_subcommand('generate-config-h', '-kb', 'handwired/pytest/basic') check_returncode(result) assert '# define DEVICE_VER 0x0001' in result.stdout - assert '# define DESCRIPTION "handwired/pytest/basic"' in result.stdout assert '# define DIODE_DIRECTION COL2ROW' in result.stdout assert '# define MANUFACTURER none' in result.stdout assert '# define PRODUCT pytest' in result.stdout diff --git a/lib/vusb b/lib/vusb -Subproject bdb53e4c043d089279d9891b68bea77614cb97e +Subproject 819dbc1e5d5926b17e27e00ca6d3d2988adae04 |