2000-01-04 23:41:21 -05:00
|
|
|
/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */
|
1998-01-16 07:13:05 -05:00
|
|
|
|
|
|
|
/* @(#) st.h 5.1 89/12/14 */
|
|
|
|
|
2007-06-09 23:06:15 -04:00
|
|
|
#ifndef RUBY_ST_H
|
|
|
|
#define RUBY_ST_H 1
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2007-06-09 23:06:15 -04:00
|
|
|
#if defined(__cplusplus)
|
|
|
|
extern "C" {
|
|
|
|
#if 0
|
|
|
|
} /* satisfy cc-mode */
|
|
|
|
#endif
|
|
|
|
#endif
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2008-12-23 00:19:27 -05:00
|
|
|
#include "ruby/defines.h"
|
2008-12-10 21:11:09 -05:00
|
|
|
|
2013-04-05 06:29:38 -04:00
|
|
|
RUBY_SYMBOL_EXPORT_BEGIN
|
2010-07-21 17:38:25 -04:00
|
|
|
|
2006-07-09 21:08:15 -04:00
|
|
|
#if SIZEOF_LONG == SIZEOF_VOIDP
|
2003-07-27 13:20:29 -04:00
|
|
|
typedef unsigned long st_data_t;
|
2006-07-09 21:08:15 -04:00
|
|
|
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
|
|
|
|
typedef unsigned LONG_LONG st_data_t;
|
|
|
|
#else
|
2011-12-28 11:56:16 -05:00
|
|
|
# error ---->> st.c requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
|
2006-07-09 21:08:15 -04:00
|
|
|
#endif
|
2003-05-20 02:48:04 -04:00
|
|
|
#define ST_DATA_T_DEFINED
|
* st.h, st.c: Introduce new conventional typedef's, st_data_t,
st_compare_func_t, st_hash_func_t and st_each_func_t.
* st.h, st.c: Do explicit function declarations and do not rely on
implicit declarations. On such platforms as IA64, int argument
values are NOT automatically promoted to long (64bit) values, so
explicit declarations are mandatory for those functions that
take long values or pointers. This fixes miniruby's coredump on
FreeBSD/IA64.
* class.c, eval.c, gc.c, hash.c, marshal.c, parse.y, variable.c:
Add proper casts to avoid warnings.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3303 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-01-06 10:55:43 -05:00
|
|
|
|
2007-08-31 22:14:40 -04:00
|
|
|
#ifndef CHAR_BIT
|
|
|
|
# ifdef HAVE_LIMITS_H
|
|
|
|
# include <limits.h>
|
|
|
|
# else
|
|
|
|
# define CHAR_BIT 8
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
#ifndef _
|
|
|
|
# define _(args) args
|
|
|
|
#endif
|
|
|
|
#ifndef ANYARGS
|
|
|
|
# ifdef __cplusplus
|
|
|
|
# define ANYARGS ...
|
|
|
|
# else
|
|
|
|
# define ANYARGS
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
1998-01-16 07:13:05 -05:00
|
|
|
typedef struct st_table st_table;
|
|
|
|
|
2009-09-08 09:10:04 -04:00
|
|
|
typedef st_data_t st_index_t;
|
2007-08-31 22:14:40 -04:00
|
|
|
typedef int st_compare_func(st_data_t, st_data_t);
|
2009-09-08 09:10:04 -04:00
|
|
|
typedef st_index_t st_hash_func(st_data_t);
|
2007-08-31 22:14:40 -04:00
|
|
|
|
2009-11-04 02:06:13 -05:00
|
|
|
typedef char st_check_for_sizeof_st_index_t[SIZEOF_VOIDP == (int)sizeof(st_index_t) ? 1 : -1];
|
|
|
|
#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP
|
|
|
|
|
1998-01-16 07:13:05 -05:00
|
|
|
struct st_hash_type {
|
2007-08-31 22:14:40 -04:00
|
|
|
int (*compare)(ANYARGS /*st_data_t, st_data_t*/); /* st_compare_func* */
|
2009-09-08 09:10:04 -04:00
|
|
|
st_index_t (*hash)(ANYARGS /*st_data_t*/); /* st_hash_func* */
|
1998-01-16 07:13:05 -05:00
|
|
|
};
|
|
|
|
|
2007-09-01 01:24:25 -04:00
|
|
|
#define ST_INDEX_BITS (sizeof(st_index_t) * CHAR_BIT)
|
2007-08-31 22:14:40 -04:00
|
|
|
|
2013-11-27 11:07:10 -05:00
|
|
|
#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR) && defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
|
|
|
|
# define ST_DATA_COMPATIBLE_P(type) \
|
|
|
|
__builtin_choose_expr(__builtin_types_compatible_p(type, st_data_t), 1, 0)
|
|
|
|
#else
|
|
|
|
# define ST_DATA_COMPATIBLE_P(type) 0
|
|
|
|
#endif
|
|
|
|
|
1998-01-16 07:13:05 -05:00
|
|
|
struct st_table {
|
2007-07-04 21:06:49 -04:00
|
|
|
const struct st_hash_type *type;
|
2007-09-02 10:40:47 -04:00
|
|
|
st_index_t num_bins;
|
2007-08-28 22:36:54 -04:00
|
|
|
unsigned int entries_packed : 1;
|
2008-07-01 03:59:21 -04:00
|
|
|
#ifdef __GNUC__
|
2011-02-01 10:32:08 -05:00
|
|
|
/*
|
|
|
|
* C spec says,
|
|
|
|
* A bit-field shall have a type that is a qualified or unqualified
|
|
|
|
* version of _Bool, signed int, unsigned int, or some other
|
|
|
|
* implementation-defined type. It is implementation-defined whether
|
|
|
|
* atomic types are permitted.
|
|
|
|
* In short, long and long long bit-field are implementation-defined
|
|
|
|
* feature. Therefore we want to supress a warning explicitly.
|
|
|
|
*/
|
2008-07-01 03:59:21 -04:00
|
|
|
__extension__
|
|
|
|
#endif
|
2007-09-02 10:40:47 -04:00
|
|
|
st_index_t num_entries : ST_INDEX_BITS - 1;
|
2012-03-04 22:44:05 -05:00
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
struct st_table_entry **bins;
|
|
|
|
struct st_table_entry *head, *tail;
|
|
|
|
} big;
|
2012-03-10 09:52:06 -05:00
|
|
|
struct {
|
|
|
|
struct st_packed_entry *entries;
|
|
|
|
st_index_t real_entries;
|
|
|
|
} packed;
|
2012-03-04 22:44:05 -05:00
|
|
|
} as;
|
1998-01-16 07:13:05 -05:00
|
|
|
};
|
|
|
|
|
2011-04-12 07:54:28 -04:00
|
|
|
#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2004-09-22 00:48:52 -04:00
|
|
|
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
|
|
|
|
|
2007-07-04 21:06:49 -04:00
|
|
|
st_table *st_init_table(const struct st_hash_type *);
|
2009-09-08 09:18:13 -04:00
|
|
|
st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t);
|
* bignum.c: changed `foo _((boo))' to `foo(boo)`. [ruby-dev:27056]
* defines.h, dir.c, dln.h, enumerator.c, env.h, error.c, eval.c, file.c,
gc.c, hash.c, inits.c, intern.h, io.c, lex.c, marshal.c, missing.h,
node.h, numeric.c, pack.c, process.c, re.h, ruby.c, ruby.h, rubyio.h,
rubysig.h, signal.c, sprintf.c, st.h, string.c, struct.c, time.c,
util.c, util.h, variable.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-14 02:32:32 -04:00
|
|
|
st_table *st_init_numtable(void);
|
2009-09-08 09:18:13 -04:00
|
|
|
st_table *st_init_numtable_with_size(st_index_t);
|
* bignum.c: changed `foo _((boo))' to `foo(boo)`. [ruby-dev:27056]
* defines.h, dir.c, dln.h, enumerator.c, env.h, error.c, eval.c, file.c,
gc.c, hash.c, inits.c, intern.h, io.c, lex.c, marshal.c, missing.h,
node.h, numeric.c, pack.c, process.c, re.h, ruby.c, ruby.h, rubyio.h,
rubysig.h, signal.c, sprintf.c, st.h, string.c, struct.c, time.c,
util.c, util.h, variable.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-14 02:32:32 -04:00
|
|
|
st_table *st_init_strtable(void);
|
2009-09-08 09:18:13 -04:00
|
|
|
st_table *st_init_strtable_with_size(st_index_t);
|
2007-09-28 15:27:10 -04:00
|
|
|
st_table *st_init_strcasetable(void);
|
2009-09-08 09:18:13 -04:00
|
|
|
st_table *st_init_strcasetable_with_size(st_index_t);
|
2008-08-07 05:06:04 -04:00
|
|
|
int st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
|
* bignum.c: changed `foo _((boo))' to `foo(boo)`. [ruby-dev:27056]
* defines.h, dir.c, dln.h, enumerator.c, env.h, error.c, eval.c, file.c,
gc.c, hash.c, inits.c, intern.h, io.c, lex.c, marshal.c, missing.h,
node.h, numeric.c, pack.c, process.c, re.h, ruby.c, ruby.h, rubyio.h,
rubysig.h, signal.c, sprintf.c, st.h, string.c, struct.c, time.c,
util.c, util.h, variable.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-14 02:32:32 -04:00
|
|
|
int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
|
2013-04-25 01:03:30 -04:00
|
|
|
int st_shift(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
|
* bignum.c: changed `foo _((boo))' to `foo(boo)`. [ruby-dev:27056]
* defines.h, dir.c, dln.h, enumerator.c, env.h, error.c, eval.c, file.c,
gc.c, hash.c, inits.c, intern.h, io.c, lex.c, marshal.c, missing.h,
node.h, numeric.c, pack.c, process.c, re.h, ruby.c, ruby.h, rubyio.h,
rubysig.h, signal.c, sprintf.c, st.h, string.c, struct.c, time.c,
util.c, util.h, variable.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-14 02:32:32 -04:00
|
|
|
int st_insert(st_table *, st_data_t, st_data_t);
|
2009-05-27 11:56:14 -04:00
|
|
|
int st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
|
* bignum.c: changed `foo _((boo))' to `foo(boo)`. [ruby-dev:27056]
* defines.h, dir.c, dln.h, enumerator.c, env.h, error.c, eval.c, file.c,
gc.c, hash.c, inits.c, intern.h, io.c, lex.c, marshal.c, missing.h,
node.h, numeric.c, pack.c, process.c, re.h, ruby.c, ruby.h, rubyio.h,
rubysig.h, signal.c, sprintf.c, st.h, string.c, struct.c, time.c,
util.c, util.h, variable.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-14 02:32:32 -04:00
|
|
|
int st_lookup(st_table *, st_data_t, st_data_t *);
|
2007-12-24 03:06:16 -05:00
|
|
|
int st_get_key(st_table *, st_data_t, st_data_t *);
|
2012-03-29 10:50:20 -04:00
|
|
|
typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing);
|
2014-07-06 11:11:53 -04:00
|
|
|
/* *key may be altered, but must equal to the old key, i.e., the
|
|
|
|
* results of hash() are same and compare() returns 0, otherwise the
|
|
|
|
* behavior is undefined */
|
2012-03-29 03:36:12 -04:00
|
|
|
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
|
* bignum.c: changed `foo _((boo))' to `foo(boo)`. [ruby-dev:27056]
* defines.h, dir.c, dln.h, enumerator.c, env.h, error.c, eval.c, file.c,
gc.c, hash.c, inits.c, intern.h, io.c, lex.c, marshal.c, missing.h,
node.h, numeric.c, pack.c, process.c, re.h, ruby.c, ruby.h, rubyio.h,
rubysig.h, signal.c, sprintf.c, st.h, string.c, struct.c, time.c,
util.c, util.h, variable.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-14 02:32:32 -04:00
|
|
|
int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
|
2012-03-10 09:52:19 -05:00
|
|
|
int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t, st_data_t);
|
2007-08-21 00:43:51 -04:00
|
|
|
int st_reverse_foreach(st_table *, int (*)(ANYARGS), st_data_t);
|
2013-11-27 11:07:10 -05:00
|
|
|
st_index_t st_keys(st_table *table, st_data_t *keys, st_index_t size);
|
2013-11-28 03:15:26 -05:00
|
|
|
st_index_t st_keys_check(st_table *table, st_data_t *keys, st_index_t size, st_data_t never);
|
2013-11-28 03:39:16 -05:00
|
|
|
st_index_t st_values(st_table *table, st_data_t *values, st_index_t size);
|
|
|
|
st_index_t st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t never);
|
* bignum.c: changed `foo _((boo))' to `foo(boo)`. [ruby-dev:27056]
* defines.h, dir.c, dln.h, enumerator.c, env.h, error.c, eval.c, file.c,
gc.c, hash.c, inits.c, intern.h, io.c, lex.c, marshal.c, missing.h,
node.h, numeric.c, pack.c, process.c, re.h, ruby.c, ruby.h, rubyio.h,
rubysig.h, signal.c, sprintf.c, st.h, string.c, struct.c, time.c,
util.c, util.h, variable.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-14 02:32:32 -04:00
|
|
|
void st_add_direct(st_table *, st_data_t, st_data_t);
|
|
|
|
void st_free_table(st_table *);
|
|
|
|
void st_cleanup_safe(st_table *, st_data_t);
|
2007-08-21 00:43:51 -04:00
|
|
|
void st_clear(st_table *);
|
* bignum.c: changed `foo _((boo))' to `foo(boo)`. [ruby-dev:27056]
* defines.h, dir.c, dln.h, enumerator.c, env.h, error.c, eval.c, file.c,
gc.c, hash.c, inits.c, intern.h, io.c, lex.c, marshal.c, missing.h,
node.h, numeric.c, pack.c, process.c, re.h, ruby.c, ruby.h, rubyio.h,
rubysig.h, signal.c, sprintf.c, st.h, string.c, struct.c, time.c,
util.c, util.h, variable.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-14 02:32:32 -04:00
|
|
|
st_table *st_copy(st_table *);
|
2007-08-31 22:14:40 -04:00
|
|
|
int st_numcmp(st_data_t, st_data_t);
|
2009-09-08 09:10:04 -04:00
|
|
|
st_index_t st_numhash(st_data_t);
|
2013-07-16 19:15:41 -04:00
|
|
|
int st_locale_insensitive_strcasecmp(const char *s1, const char *s2);
|
|
|
|
int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);
|
2013-07-16 23:31:44 -04:00
|
|
|
#define st_strcasecmp st_locale_insensitive_strcasecmp
|
|
|
|
#define st_strncasecmp st_locale_insensitive_strncasecmp
|
2009-09-09 02:27:35 -04:00
|
|
|
size_t st_memsize(const st_table *);
|
2009-09-26 10:29:13 -04:00
|
|
|
st_index_t st_hash(const void *ptr, size_t len, st_index_t h);
|
2009-09-28 06:08:46 -04:00
|
|
|
st_index_t st_hash_uint32(st_index_t h, uint32_t i);
|
2009-09-26 10:29:13 -04:00
|
|
|
st_index_t st_hash_uint(st_index_t h, st_index_t i);
|
|
|
|
st_index_t st_hash_end(st_index_t h);
|
|
|
|
st_index_t st_hash_start(st_index_t h);
|
|
|
|
#define st_hash_start(h) ((st_index_t)(h))
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2013-04-05 06:29:38 -04:00
|
|
|
RUBY_SYMBOL_EXPORT_END
|
2010-07-21 17:38:25 -04:00
|
|
|
|
2007-06-09 23:06:15 -04:00
|
|
|
#if defined(__cplusplus)
|
|
|
|
#if 0
|
|
|
|
{ /* satisfy cc-mode */
|
|
|
|
#endif
|
|
|
|
} /* extern "C" { */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* RUBY_ST_H */
|