mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-20 01:33:03 +00:00
* lib/hash.c, lib/hash.h: Replace with Fileutils 4.1's version.
* configure.in: Check for the declarations of free and malloc. * src/muscle_tab.c: Adjust.
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
2002-02-05 Akim Demaille <akim@epita.fr>
|
||||||
|
|
||||||
|
* lib/hash.c, lib/hash.h: Replace with Fileutils 4.1's version.
|
||||||
|
* configure.in: Check for the declarations of free and malloc.
|
||||||
|
* src/muscle_tab.c: Adjust.
|
||||||
|
|
||||||
|
|
||||||
2002-02-05 Akim Demaille <akim@epita.fr>
|
2002-02-05 Akim Demaille <akim@epita.fr>
|
||||||
|
|
||||||
* src/muscle_tab.c (muscle_init): Don't default to NULL muscle
|
* src/muscle_tab.c (muscle_init): Don't default to NULL muscle
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ AC_FUNC_OBSTACK
|
|||||||
AC_FUNC_ERROR_AT_LINE
|
AC_FUNC_ERROR_AT_LINE
|
||||||
AC_FUNC_STRNLEN
|
AC_FUNC_STRNLEN
|
||||||
AC_CHECK_FUNCS(mkstemp setlocale)
|
AC_CHECK_FUNCS(mkstemp setlocale)
|
||||||
AC_CHECK_DECLS([stpcpy, strchr, strspn, strnlen, memchr, memrchr])
|
AC_CHECK_DECLS([free, stpcpy, strchr, strspn, strnlen, malloc, memchr, memrchr])
|
||||||
AC_REPLACE_FUNCS(stpcpy strchr strspn memchr memrchr)
|
AC_REPLACE_FUNCS(stpcpy strchr strspn memchr memrchr)
|
||||||
jm_FUNC_MALLOC
|
jm_FUNC_MALLOC
|
||||||
jm_FUNC_REALLOC
|
jm_FUNC_REALLOC
|
||||||
|
|||||||
1196
lib/hash.c
1196
lib/hash.c
File diff suppressed because it is too large
Load Diff
207
lib/hash.h
207
lib/hash.h
@@ -1,6 +1,6 @@
|
|||||||
/* hash.h -- decls for hash table
|
/* hash - hashing table processing.
|
||||||
Copyright 1995, 2001 Free Software Foundation, Inc.
|
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||||
Written by Greg McGary <gkm@gnu.ai.mit.edu>
|
Written by Jim Meyering <meyering@ascend.com>, 1998.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -13,141 +13,108 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#ifndef _hash_h_
|
/* A generic hash table package. */
|
||||||
#define _hash_h_
|
|
||||||
|
|
||||||
#include <stdio.h>
|
/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use
|
||||||
|
obstacks instead of malloc, and recompile `hash.c' with same setting. */
|
||||||
|
|
||||||
#ifndef PARAMS
|
#ifndef PARAMS
|
||||||
# if defined PROTOTYPES || defined __STDC__
|
# if PROTOTYPES || __STDC__
|
||||||
# define PARAMS(Args) Args
|
# define PARAMS(Args) Args
|
||||||
# else
|
# else
|
||||||
# define PARAMS(Args) ()
|
# define PARAMS(Args) ()
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef unsigned long (*hash_func_t) PARAMS((void const *key));
|
typedef unsigned (*Hash_hasher) PARAMS ((const void *, unsigned));
|
||||||
typedef int (*hash_cmp_func_t) PARAMS((void const *x, void const *y));
|
typedef bool (*Hash_comparator) PARAMS ((const void *, const void *));
|
||||||
typedef void (*hash_map_func_t) PARAMS((void const *item));
|
typedef void (*Hash_data_freer) PARAMS ((void *));
|
||||||
|
typedef bool (*Hash_processor) PARAMS ((void *, void *));
|
||||||
|
|
||||||
|
struct hash_entry
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
struct hash_entry *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hash_tuning
|
||||||
|
{
|
||||||
|
/* This structure is mainly used for `hash_initialize', see the block
|
||||||
|
documentation of `hash_reset_tuning' for more complete comments. */
|
||||||
|
|
||||||
|
float shrink_threshold; /* ratio of used buckets to trigger a shrink */
|
||||||
|
float shrink_factor; /* ratio of new smaller size to original size */
|
||||||
|
float growth_threshold; /* ratio of used buckets to trigger a growth */
|
||||||
|
float growth_factor; /* ratio of new bigger size to original size */
|
||||||
|
bool is_n_buckets; /* if CANDIDATE really means table size */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct hash_tuning Hash_tuning;
|
||||||
|
|
||||||
struct hash_table
|
struct hash_table
|
||||||
{
|
{
|
||||||
void **ht_vec;
|
/* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1,
|
||||||
unsigned long ht_size; /* total number of slots (power of 2) */
|
for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets
|
||||||
unsigned long ht_capacity; /* usable slots, limited by loading-factor */
|
are not empty, there are N_ENTRIES active entries in the table. */
|
||||||
unsigned long ht_fill; /* items in table */
|
struct hash_entry *bucket;
|
||||||
unsigned long ht_collisions; /* # of failed calls to comparison function */
|
struct hash_entry *bucket_limit;
|
||||||
unsigned long ht_lookups; /* # of queries */
|
unsigned n_buckets;
|
||||||
unsigned int ht_rehashes; /* # of times we've expanded table */
|
unsigned n_buckets_used;
|
||||||
hash_func_t ht_hash_1; /* primary hash function */
|
unsigned n_entries;
|
||||||
hash_func_t ht_hash_2; /* secondary hash function */
|
|
||||||
hash_cmp_func_t ht_compare; /* comparison function */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int (*qsort_cmp_t) PARAMS((void const *, void const *));
|
/* Tuning arguments, kept in a physicaly separate structure. */
|
||||||
|
const Hash_tuning *tuning;
|
||||||
|
|
||||||
void hash_init PARAMS((struct hash_table *ht, unsigned long size,
|
/* Three functions are given to `hash_initialize', see the documentation
|
||||||
hash_func_t hash_1, hash_func_t hash_2, hash_cmp_func_t hash_cmp));
|
block for this function. In a word, HASHER randomizes a user entry
|
||||||
void hash_load PARAMS((struct hash_table *ht, void *item_table,
|
into a number up from 0 up to some maximum minus 1; COMPARATOR returns
|
||||||
unsigned long cardinality, unsigned long size));
|
true if two user entries compare equally; and DATA_FREER is the cleanup
|
||||||
void **hash_find_slot PARAMS((struct hash_table *ht, void const *key));
|
function for a user entry. */
|
||||||
void *hash_find_item PARAMS((struct hash_table *ht, void const *key));
|
Hash_hasher hasher;
|
||||||
const void *hash_insert PARAMS((struct hash_table *ht, void *item));
|
Hash_comparator comparator;
|
||||||
const void *hash_insert_at PARAMS((struct hash_table *ht, void *item, void const *slot));
|
Hash_data_freer data_freer;
|
||||||
const void *hash_delete PARAMS((struct hash_table *ht, void const *item));
|
|
||||||
const void *hash_delete_at PARAMS((struct hash_table *ht, void const *slot));
|
|
||||||
void hash_delete_items PARAMS((struct hash_table *ht));
|
|
||||||
void hash_free_items PARAMS((struct hash_table *ht));
|
|
||||||
void hash_free PARAMS((struct hash_table *ht, int free_items));
|
|
||||||
void hash_map PARAMS((struct hash_table *ht, hash_map_func_t map));
|
|
||||||
void hash_print_stats PARAMS((struct hash_table *ht, FILE *out_FILE));
|
|
||||||
void **hash_dump PARAMS((struct hash_table *ht, void **vector_0, qsort_cmp_t compare));
|
|
||||||
|
|
||||||
extern void *hash_deleted_item;
|
/* A linked list of freed struct hash_entry structs. */
|
||||||
#define HASH_VACANT(item) \
|
struct hash_entry *free_entry_list;
|
||||||
((item) == 0 || (const void *) (item) == hash_deleted_item)
|
|
||||||
|
|
||||||
|
#if USE_OBSTACK
|
||||||
/* hash and comparison macros for string keys. */
|
/* Whenever obstacks are used, it is possible to allocate all overflowed
|
||||||
|
entries into a single stack, so they all can be freed in a single
|
||||||
|
operation. It is not clear if the speedup is worth the trouble. */
|
||||||
|
struct obstack entry_stack;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#define STRING_HASH_1(_key_, _result_) { \
|
typedef struct hash_table Hash_table;
|
||||||
unsigned char const *kk = (unsigned char const *) (_key_) - 1; \
|
|
||||||
while (*++kk) \
|
|
||||||
(_result_) += (*kk << (kk[1] & 0xf)); \
|
|
||||||
} while (0)
|
|
||||||
#define return_STRING_HASH_1(_key_) do { \
|
|
||||||
unsigned long result = 0; \
|
|
||||||
STRING_HASH_1 ((_key_), result); \
|
|
||||||
return result; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define STRING_HASH_2(_key_, _result_) do { \
|
/* Information and lookup. */
|
||||||
unsigned char const *kk = (unsigned char const *) (_key_) - 1; \
|
unsigned hash_get_n_buckets PARAMS ((const Hash_table *));
|
||||||
while (*++kk) \
|
unsigned hash_get_n_buckets_used PARAMS ((const Hash_table *));
|
||||||
(_result_) += (*kk << (kk[1] & 0x7)); \
|
unsigned hash_get_n_entries PARAMS ((const Hash_table *));
|
||||||
} while (0)
|
unsigned hash_get_max_bucket_length PARAMS ((const Hash_table *));
|
||||||
#define return_STRING_HASH_2(_key_) do { \
|
bool hash_table_ok PARAMS ((const Hash_table *));
|
||||||
unsigned long result = 0; \
|
void hash_print_statistics PARAMS ((const Hash_table *, FILE *));
|
||||||
STRING_HASH_2 ((_key_), result); \
|
void *hash_lookup PARAMS ((const Hash_table *, const void *));
|
||||||
return result; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define STRING_COMPARE(_x_, _y_, _result_) do { \
|
/* Walking. */
|
||||||
unsigned char const *xx = (unsigned char const *) (_x_) - 1; \
|
void *hash_get_first PARAMS ((const Hash_table *));
|
||||||
unsigned char const *yy = (unsigned char const *) (_y_) - 1; \
|
void *hash_get_next PARAMS ((const Hash_table *, const void *));
|
||||||
do { \
|
unsigned hash_get_entries PARAMS ((const Hash_table *, void **, unsigned));
|
||||||
if (*++xx == '\0') { \
|
unsigned hash_do_for_each PARAMS ((const Hash_table *, Hash_processor, void *));
|
||||||
yy++; \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
} while (*xx == *++yy); \
|
|
||||||
(_result_) = *xx - *yy; \
|
|
||||||
} while (0)
|
|
||||||
#define return_STRING_COMPARE(_x_, _y_) do { \
|
|
||||||
int result; \
|
|
||||||
STRING_COMPARE (_x_, _y_, result); \
|
|
||||||
return result; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* hash and comparison macros for integer keys. */
|
/* Allocation and clean-up. */
|
||||||
|
unsigned hash_string PARAMS ((const char *, unsigned));
|
||||||
|
void hash_reset_tuning PARAMS ((Hash_tuning *));
|
||||||
|
Hash_table *hash_initialize PARAMS ((unsigned, const Hash_tuning *,
|
||||||
|
Hash_hasher, Hash_comparator,
|
||||||
|
Hash_data_freer));
|
||||||
|
void hash_clear PARAMS ((Hash_table *));
|
||||||
|
void hash_free PARAMS ((Hash_table *));
|
||||||
|
|
||||||
#define INTEGER_HASH_1(_key_, _result_) do { \
|
/* Insertion and deletion. */
|
||||||
(_result_) += ((unsigned long)(_key_)); \
|
bool hash_rehash PARAMS ((Hash_table *, unsigned));
|
||||||
} while (0)
|
void *hash_insert PARAMS ((Hash_table *, const void *));
|
||||||
#define return_INTEGER_HASH_1(_key_) do { \
|
void *hash_delete PARAMS ((Hash_table *, const void *));
|
||||||
unsigned long result = 0; \
|
|
||||||
INTEGER_HASH_1 ((_key_), result); \
|
|
||||||
return result; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define INTEGER_HASH_2(_key_, _result_) do { \
|
|
||||||
(_result_) += ~((unsigned long)(_key_)); \
|
|
||||||
} while (0)
|
|
||||||
#define return_INTEGER_HASH_2(_key_) do { \
|
|
||||||
unsigned long result = 0; \
|
|
||||||
INTEGER_HASH_2 ((_key_), result); \
|
|
||||||
return result; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define INTEGER_COMPARE(_x_, _y_, _result_) do { \
|
|
||||||
(_result_) = _x_ - _y_; \
|
|
||||||
} while (0)
|
|
||||||
#define return_INTEGER_COMPARE(_x_, _y_) do { \
|
|
||||||
int result; \
|
|
||||||
INTEGER_COMPARE (_x_, _y_, result); \
|
|
||||||
return result; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* hash and comparison macros for address keys. */
|
|
||||||
|
|
||||||
#define ADDRESS_HASH_1(_key_, _result_) INTEGER_HASH_1 (((unsigned long)(_key_)) >> 3, (_result_))
|
|
||||||
#define ADDRESS_HASH_2(_key_, _result_) INTEGER_HASH_2 (((unsigned long)(_key_)) >> 3, (_result_))
|
|
||||||
#define ADDRESS_COMPARE(_x_, _y_, _result_) INTEGER_COMPARE ((_x_), (_y_), (_result_))
|
|
||||||
#define return_ADDRESS_HASH_1(_key_) return_INTEGER_HASH_1 (((unsigned long)(_key_)) >> 3)
|
|
||||||
#define return_ADDRESS_HASH_2(_key_) return_INTEGER_HASH_2 (((unsigned long)(_key_)) >> 3)
|
|
||||||
#define return_ADDRESS_COMPARE(_x_, _y_) return_INTEGER_COMPARE ((_x_), (_y_))
|
|
||||||
|
|
||||||
#endif /* not _hash_h_ */
|
|
||||||
|
|||||||
@@ -195,9 +195,6 @@ closure (short *core, int n)
|
|||||||
/* Index over CORE. */
|
/* Index over CORE. */
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
/* Index over RULESET. */
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* A bit index over RULESET. */
|
/* A bit index over RULESET. */
|
||||||
int ruleno;
|
int ruleno;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Macro table manager for Bison,
|
/* Macro table manager for Bison,
|
||||||
Copyright 2001 Free Software Foundation, Inc.
|
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of Bison, the GNU Compiler Compiler.
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
@@ -24,31 +24,31 @@
|
|||||||
#include "muscle_tab.h"
|
#include "muscle_tab.h"
|
||||||
#include "getargs.h"
|
#include "getargs.h"
|
||||||
|
|
||||||
struct hash_table muscle_table;
|
/* Initial capacity of muscles hash table. */
|
||||||
|
#define HT_INITIAL_CAPACITY 257
|
||||||
|
|
||||||
static unsigned long
|
struct hash_table *muscle_table = NULL;
|
||||||
mhash1 (const void *item)
|
|
||||||
|
static bool
|
||||||
|
hash_compare_muscles (void const *x, void const *y)
|
||||||
{
|
{
|
||||||
return_STRING_HASH_1 (((const muscle_entry_t *) item)->key);
|
const muscle_entry_t *m1 = x;
|
||||||
|
const muscle_entry_t *m2 = y;
|
||||||
|
return strcmp (m1->key, m2->key) ? FALSE : TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long
|
static unsigned int
|
||||||
mhash2 (const void *item)
|
hash_muscle (const void *x, unsigned int tablesize)
|
||||||
{
|
{
|
||||||
return_STRING_HASH_2 (((const muscle_entry_t *) item)->key);
|
const muscle_entry_t *m = x;
|
||||||
}
|
return hash_string (m->key, tablesize);
|
||||||
|
|
||||||
static int
|
|
||||||
mcmp (const void *x, const void *y)
|
|
||||||
{
|
|
||||||
return strcmp (((const muscle_entry_t*) x)->key,
|
|
||||||
((const muscle_entry_t *) y)->key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
muscle_init (void)
|
muscle_init (void)
|
||||||
{
|
{
|
||||||
hash_init (&muscle_table, MTABSIZE, &mhash1, &mhash2, &mcmp);
|
muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
|
||||||
|
hash_compare_muscles, NULL);
|
||||||
|
|
||||||
/* Version and input file. */
|
/* Version and input file. */
|
||||||
muscle_insert ("version", VERSION);
|
muscle_insert ("version", VERSION);
|
||||||
@@ -72,16 +72,23 @@ muscle_init (void)
|
|||||||
void
|
void
|
||||||
muscle_insert (const char *key, const char *value)
|
muscle_insert (const char *key, const char *value)
|
||||||
{
|
{
|
||||||
muscle_entry_t *pair = XMALLOC (muscle_entry_t, 1);
|
muscle_entry_t pair = { key, NULL };
|
||||||
pair->key = key;
|
muscle_entry_t *entry = hash_lookup (muscle_table, &pair);
|
||||||
pair->value = value;
|
|
||||||
hash_insert (&muscle_table, pair);
|
if (!entry)
|
||||||
|
{
|
||||||
|
/* First insertion in the hash. */
|
||||||
|
entry = XMALLOC (muscle_entry_t, 1);
|
||||||
|
entry->key = key;
|
||||||
|
hash_insert (muscle_table, entry);
|
||||||
|
}
|
||||||
|
entry->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
muscle_find (const char *key)
|
muscle_find (const char *key)
|
||||||
{
|
{
|
||||||
muscle_entry_t pair = { key, 0 };
|
muscle_entry_t pair = { key, NULL };
|
||||||
muscle_entry_t *result = hash_find_item (&muscle_table, &pair);
|
muscle_entry_t *result = hash_lookup (muscle_table, &pair);
|
||||||
return result ? result->value : 0;
|
return result ? result->value : NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user