#define alloca(n) __ALLOCA(n)
#endif
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+/* # undef WORDS_BIGENDIAN */
+
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* # undef _ALL_SOURCE */
#endif
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+/* # undef WORDS_BIGENDIAN */
+
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
AC_AIX
AC_ISC_POSIX
AC_MINIX
+AC_C_BIGENDIAN
# Enable gettext, in "external" mode.
AM_GNU_GETTEXT_VERSION([0.19.4])
return n + 1;
}
+
+#define rol32(v, n) \
+ ((v) << (n) | ((v) >> (32 - (n))))
+
+/* jhash_mix -- mix 3 32-bit values reversibly. */
+#define jhash_mix(a, b, c) \
+{ \
+ a -= c; a ^= rol32(c, 4); c += b; \
+ b -= a; b ^= rol32(a, 6); a += c; \
+ c -= b; c ^= rol32(b, 8); b += a; \
+ a -= c; a ^= rol32(c, 16); c += b; \
+ b -= a; b ^= rol32(a, 19); a += c; \
+ c -= b; c ^= rol32(b, 4); b += a; \
+}
+
+/* jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
+#define jhash_final(a, b, c) \
+{ \
+ c ^= b; c -= rol32(b, 14); \
+ a ^= c; a -= rol32(c, 11); \
+ b ^= a; b -= rol32(a, 25); \
+ c ^= b; c -= rol32(b, 16); \
+ a ^= c; a -= rol32(c, 4); \
+ b ^= a; b -= rol32(a, 14); \
+ c ^= b; c -= rol32(b, 24); \
+}
+
+/* An arbitrary initial parameter */
+#define JHASH_INITVAL 0xdeadbeef
+
+#define sum_get_unaligned_32(r, p) \
+ do { \
+ unsigned int val; \
+ memcpy(&val, (p), 4); \
+ r += val; \
+ } while(0);
+
+unsigned jhash(unsigned const char *k, int length)
+{
+ unsigned int a, b, c;
+
+ /* Set up the internal state */
+ a = b = c = JHASH_INITVAL + length;
+
+ /* All but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12) {
+ sum_get_unaligned_32(a, k);
+ sum_get_unaligned_32(b, k + 4);
+ sum_get_unaligned_32(c, k + 8);
+ jhash_mix(a, b, c);
+ length -= 12;
+ k += 12;
+ }
+
+ if (!length)
+ return c;
+
+ if (length > 8)
+ {
+ sum_get_unaligned_32(a, k);
+ length -= 4;
+ k += 4;
+ }
+ if (length > 4)
+ {
+ sum_get_unaligned_32(b, k);
+ length -= 4;
+ k += 4;
+ }
+
+ if (length == 4)
+ c += (unsigned)k[3]<<24;
+ if (length >= 3)
+ c += (unsigned)k[2]<<16;
+ if (length >= 2)
+ c += (unsigned)k[1]<<8;
+ c += k[0];
+ jhash_final(a, b, c);
+ return c;
+}
+
+#ifdef WORDS_BIGENDIAN
+/* The ifs are ordered from the first byte in memory to the last. */
+#define sum_up_to_nul(r, p, flag) \
+ do { \
+ unsigned int val; \
+ memcpy(&val, (p), 4); \
+ if ((val & 0xFF000000) == 0) \
+ flag = 1; \
+ else if ((val & 0xFF0000) == 0) \
+ r += val & ~0xFFFF, flag = 1; \
+ else if ((val & 0xFF00) == 0) \
+ r += val & ~0xFF, flag = 1; \
+ else \
+ r += val, flag = (val & 0xFF) == 0; \
+ } while (0)
+#else
+/* First detect the presence of zeroes. If there is none, we can
+ sum the 4 bytes directly. Otherwise, the ifs are ordered as in the
+ big endian case, from the first byte in memory to the last. */
+#define sum_up_to_nul(r, p, flag) \
+ do { \
+ unsigned int val; \
+ unsigned int zeroes; \
+ memcpy(&val, (p), 4); \
+ zeroes = ((val - 0x01010101) & ~val); \
+ if (!(zeroes & 0x80808080)) \
+ r += val; \
+ else if ((val & 0xFF) == 0) \
+ flag = 1; \
+ else if ((val & 0xFF00) == 0) \
+ r += val & 0xFF, flag = 1; \
+ else if ((val & 0xFF0000) == 0) \
+ r += val & 0xFFFF, flag = 1; \
+ else \
+ r += val, flag = 1; \
+ } while (0)
+#endif
+
+unsigned jhash_string(unsigned const char *k)
+{
+ unsigned int a, b, c;
+ unsigned int have_nul = 0;
+ unsigned const char *start = k;
+
+ /* Set up the internal state */
+ a = b = c = JHASH_INITVAL;
+
+ /* All but the last block: affect some 32 bits of (a,b,c) */
+ for (;;) {
+ sum_up_to_nul(a, k, have_nul);
+ if (have_nul)
+ break;
+ k += 4;
+ sum_up_to_nul(b, k, have_nul);
+ if (have_nul)
+ break;
+ k += 4;
+ sum_up_to_nul(c, k, have_nul);
+ if (have_nul)
+ break;
+ k += 4;
+ jhash_mix(a, b, c);
+ }
+
+ jhash_final(a, b, c);
+ return c + (k - start);
+}
void hash_print_stats __P((struct hash_table *ht, FILE *out_FILE));
void **hash_dump __P((struct hash_table *ht, void **vector_0, qsort_cmp_t compare));
+extern unsigned jhash(unsigned char const *key, int n);
+extern unsigned jhash_string(unsigned char const *key);
+
extern void *hash_deleted_item;
#define HASH_VACANT(item) ((item) == 0 || (void *) (item) == hash_deleted_item)
be identical. Take advantage of that to short-circuit string compares. */
#define STRING_HASH_1(KEY, RESULT) do { \
- unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \
- while (*++_key_) \
- (RESULT) += (*_key_ << (_key_[1] & 0xf)); \
+ unsigned char const *_key_ = (unsigned char const *) (KEY); \
+ (RESULT) += jhash_string(_key_); \
} while (0)
#define return_STRING_HASH_1(KEY) do { \
unsigned long _result_ = 0; \
return _result_; \
} while (0)
+/* No need for a second hash because jhash already provides
+ pretty good results. However, do evaluate the arguments
+ to avoid warnings. */
#define STRING_HASH_2(KEY, RESULT) do { \
- unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \
- while (*++_key_) \
- (RESULT) += (*_key_ << (_key_[1] & 0x7)); \
+ (void)(KEY); \
} while (0)
#define return_STRING_HASH_2(KEY) do { \
unsigned long _result_ = 0; \
#define STRING_N_HASH_1(KEY, N, RESULT) do { \
- unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \
- int _n_ = (N); \
- if (_n_) \
- while (--_n_ && *++_key_) \
- (RESULT) += (*_key_ << (_key_[1] & 0xf)); \
- (RESULT) += *++_key_; \
+ unsigned char const *_key_ = (unsigned char const *) (KEY); \
+ (RESULT) += jhash(_key_, N); \
} while (0)
+
#define return_STRING_N_HASH_1(KEY, N) do { \
unsigned long _result_ = 0; \
STRING_N_HASH_1 ((KEY), (N), _result_); \
return _result_; \
} while (0)
+/* No need for a second hash because jhash already provides
+ pretty good results. However, do evaluate the arguments
+ to avoid warnings. */
#define STRING_N_HASH_2(KEY, N, RESULT) do { \
- unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \
- int _n_ = (N); \
- if (_n_) \
- while (--_n_ && *++_key_) \
- (RESULT) += (*_key_ << (_key_[1] & 0x7)); \
- (RESULT) += *++_key_; \
+ (void)(KEY); \
+ (void)(N); \
} while (0)
+
#define return_STRING_N_HASH_2(KEY, N) do { \
unsigned long _result_ = 0; \
STRING_N_HASH_2 ((KEY), (N), _result_); \
} while (0)
#define STRING_N_COMPARE(X, Y, N, RESULT) do { \
- RESULT = (X) == (Y) ? 0 : strncmp ((X), (Y), (N)); \
+ RESULT = (X) == (Y) ? 0 : memcmp ((X), (Y), (N)); \
} while (0)
#define return_STRING_N_COMPARE(X, Y, N) do { \
- return (X) == (Y) ? 0 : strncmp ((X), (Y), (N)); \
+ return (X) == (Y) ? 0 : memcmp ((X), (Y), (N)); \
} while (0)
#ifdef HAVE_CASE_INSENSITIVE_FS
# TEST #3
&run_make_with_options($makefile,'foo.c',&get_logfile);
-$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm bar.e foo.e\n";
+$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm foo.e bar.e\n";
&compare_output($answer, &get_logfile(1));
# TEST #4
&touch('foo.f');
&run_make_with_options($makefile,'foo.c',&get_logfile);
-$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm bar.e foo.e\n";
+$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm foo.e bar.e\n";
&compare_output($answer, &get_logfile(1));
# TEST #6 -- added for PR/1669: don't remove files mentioned on the cmd line.
final: intermediate
intermediate: source
-final intermediate source:
- echo $< > $@
+final intermediate source: ; echo $< > $@
EOF
close(MAKEFILE);
cp 1.b 1.c
cp 2.a 2.b
cp 2.b 2.c
-rm 1.b 2.b');
+rm 2.b 1.b');
unlink(qw(1.a 2.a 1.c 2.c));