示例#1
0
static int
DddmpCuddDdArrayStorePrefixBody (
  DdManager *ddMgr      /* IN: Manager */,
  int n                 /* IN: Number of output nodes to be dumped */,
  DdNode **f            /* IN: Array of output nodes to be dumped */,
  char **inputNames     /* IN: Array of input names (or NULL) */,
  char **outputNames    /* IN: Array of output names (or NULL) */,
  FILE *fp              /* IN: Pointer to the dump file */
  )
{
  st_table *visited = NULL;
  int retValue;
  int i;

  /* Initialize symbol table for visited nodes. */
  visited = st_init_table(st_ptrcmp, st_ptrhash);
  Dddmp_CheckAndGotoLabel (visited==NULL,
    "Error if function st_init_table.", failure);

  /* Call the function that really gets the job done. */
  for (i = 0; i < n; i++) {
    retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr, Cudd_Regular(f[i]),
      fp, visited, inputNames);
    Dddmp_CheckAndGotoLabel (retValue==0,
      "Error if function DddmpCuddDdArrayStorePrefixStep.", failure);
  }

  /* To account for the possible complement on the root,
   ** we put either a buffer or an inverter at the output of
   ** the multiplexer representing the top node.
   */
  for (i=0; i<n; i++) {
    if (outputNames == NULL) {
      retValue = fprintf (fp,  "(BUF outNode%d ", i);
    } else {
      retValue = fprintf (fp,  "(BUF %s ", outputNames[i]);
    }
    Dddmp_CheckAndGotoLabel (retValue==EOF,
      "Error during file store.", failure);

    if (Cudd_IsComplement(f[i])) {
      retValue = fprintf (fp, "(NOT node%" PRIxPTR "))\n",
        (ptruint) f[i] / sizeof(DdNode));
    } else {
      retValue = fprintf (fp, "node%" PRIxPTR ")\n",
        (ptruint) f[i] / sizeof(DdNode));
    }
    Dddmp_CheckAndGotoLabel (retValue==EOF,
      "Error during file store.", failure);
  }

  st_free_table (visited);

  return(1);

failure:
    if (visited != NULL) st_free_table(visited);
    return(0);

}
static void dealloc(xmlDocPtr doc)
{
  st_table *node_hash;

  NOKOGIRI_DEBUG_START(doc);

  node_hash  = DOC_UNLINKED_NODE_HASH(doc);

  st_foreach(node_hash, dealloc_node_i, (st_data_t)doc);
  st_free_table(node_hash);

  free(doc->_private);

  /* When both Nokogiri and libxml-ruby are loaded, make sure that all nodes
   * have their _private pointers cleared. This is to avoid libxml-ruby's
   * xmlDeregisterNode callback from accessing VALUE pointers from ruby's GC
   * free context, which can result in segfaults.
   */
  if (xmlDeregisterNodeDefaultValue)
    remove_private((xmlNodePtr)doc);

  xmlFreeDoc(doc);

  NOKOGIRI_DEBUG_END(doc);
}
示例#3
0
文件: vm.c 项目: qnighy/ruby-1.9.2p0
int
ruby_vm_destruct(void *ptr)
{
    RUBY_FREE_ENTER("vm");
    if (ptr) {
	rb_vm_t *vm = ptr;
	rb_thread_t *th = vm->main_thread;
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
	struct rb_objspace *objspace = vm->objspace;
#endif
	rb_gc_force_recycle(vm->self);
	vm->main_thread = 0;
	if (th) {
	    thread_free(th);
	}
	if (vm->living_threads) {
	    st_free_table(vm->living_threads);
	    vm->living_threads = 0;
	}
	rb_thread_lock_unlock(&vm->global_vm_lock);
	rb_thread_lock_destroy(&vm->global_vm_lock);
	ruby_xfree(vm);
	ruby_current_vm = 0;
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
	if (objspace) {
	    rb_objspace_free(objspace);
	}
#endif
    }
    RUBY_FREE_LEAVE("vm");
    return 0;
}
示例#4
0
文件: schema.c 项目: AlexChen12/avro
avro_schema_t avro_schema_union(void)
{
	struct avro_union_schema_t *schema =
	    (struct avro_union_schema_t *) avro_new(struct avro_union_schema_t);
	if (!schema) {
		avro_set_error("Cannot allocate new union schema");
		return NULL;
	}
	schema->branches = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
	if (!schema->branches) {
		avro_set_error("Cannot allocate new union schema");
		avro_freet(struct avro_union_schema_t, schema);
		return NULL;
	}
	schema->branches_byname =
	    st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
	if (!schema->branches_byname) {
		avro_set_error("Cannot allocate new union schema");
		st_free_table(schema->branches);
		avro_freet(struct avro_union_schema_t, schema);
		return NULL;
	}

	avro_schema_init(&schema->obj, AVRO_UNION);
	return &schema->obj;
}
示例#5
0
void rabbit_object_free( VALUE value )
{
	assert( value );

	if( !IS_PTR_VALUE(value) ) {
		rabbit_bug("(object_free)ポインタ型では無いオブジェクトが送られてきました(type %d)", VALUE_TYPE(value) );
	}

	switch(VALUE_TYPE(value)) {
	case TYPE_STRING:
		free( R_STRING(value)->ptr );
		break;

	case TYPE_ARRAY:
		free( R_ARRAY(value)->ptr );
		break;

	case TYPE_CLASS:
		break;

	case TYPE_OBJECT:
		st_free_table( R_OBJECT(value)->ival_tbl );
		R_OBJECT(value)->ival_tbl = 0;
		break;

	case TYPE_METHOD:
		break;

	default:
		rabbit_bug("(object_free)未対応型のオブジェクトが送られてきました(type %d)", VALUE_TYPE(value) );
	}

	free( (void*)(value) );
}
示例#6
0
static VALUE
stackprof_results(VALUE self)
{
    VALUE results, frames;

    if (!_stackprof.frames || _stackprof.running)
	return Qnil;

    results = rb_hash_new();
    rb_hash_aset(results, sym_version, DBL2NUM(1.1));
    rb_hash_aset(results, sym_mode, _stackprof.mode);
    rb_hash_aset(results, sym_interval, _stackprof.interval);
    rb_hash_aset(results, sym_samples, SIZET2NUM(_stackprof.overall_samples));
    rb_hash_aset(results, sym_gc_samples, SIZET2NUM(_stackprof.during_gc));
    rb_hash_aset(results, sym_missed_samples, SIZET2NUM(_stackprof.overall_signals - _stackprof.overall_samples));

    frames = rb_hash_new();
    rb_hash_aset(results, sym_frames, frames);
    st_foreach(_stackprof.frames, frame_i, (st_data_t)frames);

    st_free_table(_stackprof.frames);
    _stackprof.frames = NULL;

    return results;
}
示例#7
0
VALUE
rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
{
    VALUE recur, ary, klass, origin;
    st_table *list, *mtbl;

    if (argc == 0) {
	recur = Qtrue;
    }
    else {
	rb_scan_args(argc, argv, "01", &recur);
    }
    klass = CLASS_OF(obj);
    origin = RCLASS_ORIGIN(klass);
    list = st_init_numtable();
    if (klass && FL_TEST(klass, FL_SINGLETON)) {
	if ((mtbl = RCLASS_M_TBL(origin)) != 0)
	    st_foreach(mtbl, method_entry_i, (st_data_t)list);
	klass = RCLASS_SUPER(klass);
    }
    if (RTEST(recur)) {
	while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
	    if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0)
		st_foreach(mtbl, method_entry_i, (st_data_t)list);
	    klass = RCLASS_SUPER(klass);
	}
    }
    ary = rb_ary_new();
    st_foreach(list, ins_methods_i, ary);
    st_free_table(list);

    return ary;
}
示例#8
0
int
ruby_vm_destruct(rb_vm_t *vm)
{
    RUBY_FREE_ENTER("vm");
    if (vm) {
	rb_thread_t *th = vm->main_thread;
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
	struct rb_objspace *objspace = vm->objspace;
#endif
	rb_gc_force_recycle(vm->self);
	vm->main_thread = 0;
	if (th) {
	    thread_free(th);
	}
	if (vm->living_threads) {
	    st_free_table(vm->living_threads);
	    vm->living_threads = 0;
	}
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
	if (objspace) {
	    rb_objspace_free(objspace);
	}
#endif
	ruby_vm_run_at_exit_hooks(vm);
	rb_vm_gvl_destroy(vm);
	ruby_xfree(vm);
	ruby_current_vm = 0;
    }
    RUBY_FREE_LEAVE("vm");
    return 0;
}
示例#9
0
PerlFMM *
PerlFMM_clone(PerlFMM *self)
{
    PerlFMM *state;
    fmmagic *d, *s;

    state = PerlFMM_create(NULL);
    st_free_table(state->ext);
    state->ext = st_copy( self->ext );

    s = self->magic;
    Newxz(d, 1, fmmagic);
    memcpy(d, s, sizeof(fmmagic));
    state->magic = d;
    while (s->next != NULL) {
        Newxz(d->next, 1, fmmagic);
        memcpy(d->next, s->next, sizeof(struct _fmmagic));
        d = d->next;
        s = s->next;
    }
    state->last = d;
    state->last->next = NULL;

    return state;
}
示例#10
0
文件: map.c 项目: 1ack/Impala
void avro_raw_map_done(avro_raw_map_t *map)
{
	avro_raw_map_free_keys(map);
	avro_raw_array_done(&map->elements);
	st_free_table((st_table *) map->indices_by_key);
	memset(map, 0, sizeof(avro_raw_map_t));
}
示例#11
0
文件: map.c 项目: 1ack/Impala
void avro_raw_map_clear(avro_raw_map_t *map)
{
	avro_raw_map_free_keys(map);
	avro_raw_array_clear(&map->elements);
	st_free_table((st_table *) map->indices_by_key);
	map->indices_by_key = st_init_strtable();
}
示例#12
0
文件: init.c 项目: mtmiron/toi
void
toi_init(int argc, char **argv)
{
	gv_tbl = st_init_numtable();

	Init_thread();
	THREAD(cur_thr)->recv = main_thread();
	if (THREAD(main_thread())->env_tbl)
		st_free_table(THREAD(main_thread())->env_tbl);
	THREAD(main_thread())->env_tbl = gv_tbl;

	Init_symbol();
	Init_class();

	/* have to call Init_thread() again */
	Init_thread();

	Init_kernel();
	cself = cKernel;
	Init_numeric();
	Init_float();
	Init_integer();
	Init_array();
	Init_hash();
	Init_string();
	Init_iostream();
	Init_exception();

	toi_set_argv(argc, argv);

	Init_gc();

	signal(SIGINT, handle_sigint);
}
示例#13
0
文件: class.c 项目: technohippy/oruby
static VALUE
class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, long, VALUE))
{
    VALUE ary;
    int recur;
    st_table *list;

    if (argc == 0) {
	recur = TRUE;
    }
    else {
	VALUE r;
	rb_scan_args(argc, argv, "01", &r);
	recur = RTEST(r);
    }

    list = st_init_numtable();
    for (; mod; mod = RCLASS_SUPER(mod)) {
	st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
	if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
	if (FL_TEST(mod, FL_SINGLETON)) continue;
	if (!recur) break;
    }
    ary = rb_ary_new();
    st_foreach(list, func, ary);
    st_free_table(list);

    return ary;
}
示例#14
0
文件: hash.c 项目: mtmiron/toi
void
hash_reap(VALUE hash)
{
	check_type(hash, T_HASH);

	st_free_table(HASH(hash)->ptr);
}
示例#15
0
文件: class.c 项目: technohippy/oruby
VALUE
rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
{
    VALUE recur, ary, klass;
    st_table *list;

    if (argc == 0) {
	recur = Qtrue;
    }
    else {
	rb_scan_args(argc, argv, "01", &recur);
    }
    klass = CLASS_OF(obj);
    list = st_init_numtable();
    if (klass && FL_TEST(klass, FL_SINGLETON)) {
	st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
	klass = RCLASS_SUPER(klass);
    }
    if (RTEST(recur)) {
	while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
	    st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
	    klass = RCLASS_SUPER(klass);
	}
    }
    ary = rb_ary_new();
    st_foreach(list, ins_methods_i, ary);
    st_free_table(list);

    return ary;
}
示例#16
0
static VALUE
class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
{
    VALUE ary;
    int recur, prepended = 0;
    st_table *list;

    if (argc == 0) {
	recur = TRUE;
    }
    else {
	VALUE r;
	rb_scan_args(argc, argv, "01", &r);
	recur = RTEST(r);
    }

    if (!recur && RCLASS_ORIGIN(mod) != mod) {
	mod = RCLASS_ORIGIN(mod);
	prepended = 1;
    }

    list = st_init_numtable();
    for (; mod; mod = RCLASS_SUPER(mod)) {
	if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list);
	if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
	if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
	if (!recur) break;
    }
    ary = rb_ary_new();
    st_foreach(list, func, ary);
    st_free_table(list);

    return ary;
}
示例#17
0
void
avro_memoize_done(avro_memoize_t *mem)
{
	st_foreach(mem->cache, avro_memoize_free_key, 0);
	st_free_table(mem->cache);
	memset(mem, 0, sizeof(avro_memoize_t));
}
示例#18
0
/* does the inet_diag stuff with netlink(), this is called w/o GVL */
static VALUE diag(void *ptr)
{
	struct nogvl_args *args = ptr;
	struct sockaddr_nl nladdr;
	struct rtattr rta;
	struct diag_req req;
	struct msghdr msg;
	const char *err = NULL;
	unsigned seq = ++g_seq;

	prep_diag_args(args, &nladdr, &rta, &req, &msg);
	req.nlh.nlmsg_seq = seq;

	if (sendmsg(args->fd, &msg, 0) < 0) {
		err = err_sendmsg;
		goto out;
	}

	prep_recvmsg_buf(args);

	while (1) {
		ssize_t readed;
		size_t r;
		struct nlmsghdr *h = (struct nlmsghdr *)args->iov[0].iov_base;

		prep_msghdr(&msg, args, &nladdr, 1);
		readed = recvmsg(args->fd, &msg, 0);
		if (readed < 0) {
			if (errno == EINTR)
				continue;
			err = err_recvmsg;
			goto out;
		}
		if (readed == 0)
			goto out;
		r = (size_t)readed;
		for ( ; NLMSG_OK(h, r); h = NLMSG_NEXT(h, r)) {
			if (h->nlmsg_seq != seq)
				continue;
			if (h->nlmsg_type == NLMSG_DONE)
				goto out;
			if (h->nlmsg_type == NLMSG_ERROR) {
				err = err_nlmsg;
				goto out;
			}
			r_acc(args, NLMSG_DATA(h));
		}
	}
out:
	{
		int save_errno = errno;
		if (err && args->table) {
			st_foreach(args->table, st_free_data, 0);
			st_free_table(args->table);
		}
		errno = save_errno;
	}
	return (VALUE)err;
}
示例#19
0
VALUE st_spec_st_insert(VALUE self) {
  st_index_t entries;
  st_table *tbl = st_init_numtable_with_size(128);
  st_insert(tbl, 1, 1);
  entries = tbl->num_entries;
  st_free_table(tbl);
  return ST2NUM(entries);
}
示例#20
0
static void
t_tbl_free(void *data)
{
  threads_table_t *t_tbl = (threads_table_t *) data;

  st_free_table(t_tbl->tbl);
  xfree(t_tbl);
}
示例#21
0
static int
frame_i(st_data_t key, st_data_t val, st_data_t arg)
{
    VALUE frame = (VALUE)key;
    frame_data_t *frame_data = (frame_data_t *)val;
    VALUE results = (VALUE)arg;
    VALUE details = rb_hash_new();
    VALUE name, file, edges, lines;
    VALUE line;

    rb_hash_aset(results, rb_obj_id(frame), details);

    name = rb_profile_frame_full_label(frame);
    rb_hash_aset(details, sym_name, name);

    file = rb_profile_frame_absolute_path(frame);
    if (NIL_P(file))
	file = rb_profile_frame_path(frame);
    rb_hash_aset(details, sym_file, file);

    if ((line = rb_profile_frame_first_lineno(frame)) != INT2FIX(0))
	rb_hash_aset(details, sym_line, line);

    rb_hash_aset(details, sym_total_samples, SIZET2NUM(frame_data->total_samples));
    rb_hash_aset(details, sym_samples, SIZET2NUM(frame_data->caller_samples));

    if (frame_data->edges) {
        edges = rb_hash_new();
        rb_hash_aset(details, sym_edges, edges);
        st_foreach(frame_data->edges, frame_edges_i, (st_data_t)edges);
        st_free_table(frame_data->edges);
        frame_data->edges = NULL;
    }

    if (frame_data->lines) {
	lines = rb_hash_new();
	rb_hash_aset(details, sym_lines, lines);
	st_foreach(frame_data->lines, frame_lines_i, (st_data_t)lines);
	st_free_table(frame_data->lines);
	frame_data->lines = NULL;
    }

    xfree(frame_data);
    return ST_DELETE;
}
示例#22
0
static void
struct_layout_free(StructLayout *layout)
{
    xfree(layout->ffiTypes);
    xfree(layout->base.ffiType);
    xfree(layout->fields);
    st_free_table(layout->fieldSymbolTable);
    xfree(layout);
}
示例#23
0
VALUE st_spec_st_foreach(VALUE self) {
  int total = 0;
  st_table *tbl = st_init_numtable_with_size(128);
  st_insert(tbl, 1, 3);
  st_insert(tbl, 2, 4);
  st_foreach(tbl, sum, (st_data_t)&total);
  st_free_table(tbl);
  return INT2FIX(total);
}
示例#24
0
/**Function*************************************************************

  Synopsis    [Stops AIG recording.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Cudd2_Quit( void * pCudd )
{
    assert( s_pCuddMan != NULL );
    Aig_ManDumpBlif( s_pCuddMan->pAig, "aig_temp.blif" );
    Aig_ManStop( s_pCuddMan->pAig );
    st_free_table( s_pCuddMan->pTable );
    free( s_pCuddMan );
    s_pCuddMan = NULL;
}
示例#25
0
static void rsFini(void * _rpmSyck)
{
    rpmSyck rs = (rpmSyck) _rpmSyck;
    if(rs->syms)
	st_foreach(rs->syms, (enum st_retval (*)(const char *, const void *, void *))rpmSyckFreeNode, 0);

    st_free_table(rs->syms);
    rs->syms = NULL;
    rs->firstNode = NULL;
}
示例#26
0
/**Function********************************************************************

  Synopsis    [Convert a BDD from a manager to another one.]

  Description [Convert a BDD from a manager to another one. Returns a
  pointer to the BDD in the destination manager if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Extra_TransferPermute]

******************************************************************************/
DdNode * extraTransferPermuteTime( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute, int TimeOut )
{
    DdNode *res;
    st_table *table = NULL;
    st_generator *gen = NULL;
    DdNode *key, *value;

    table = st_init_table( st_ptrcmp, st_ptrhash );
    if ( table == NULL )
        goto failure;
    res = extraTransferPermuteRecurTime( ddS, ddD, f, table, Permute, TimeOut );
    if ( res != NULL )
        cuddRef( res );

    /* Dereference all elements in the table and dispose of the table.
       ** This must be done also if res is NULL to avoid leaks in case of
       ** reordering. */
    gen = st_init_gen( table );
    if ( gen == NULL )
        goto failure;
    while ( st_gen( gen, ( const char ** ) &key, ( char ** ) &value ) )
    {
        Cudd_RecursiveDeref( ddD, value );
    }
    st_free_gen( gen );
    gen = NULL;
    st_free_table( table );
    table = NULL;

    if ( res != NULL )
        cuddDeref( res );
    return ( res );

  failure:
    if ( table != NULL )
        st_free_table( table );
    if ( gen != NULL )
        st_free_gen( gen );
    return ( NULL );

} /* end of extraTransferPermuteTime */
示例#27
0
/**Function********************************************************************

  Synopsis    [Convert a BDD from a manager to another one.]

  Description [Convert a BDD from a manager to another one. Returns a
  pointer to the BDD in the destination manager if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddTransfer]

******************************************************************************/
DdNode *
cuddBddTransfer(
  DdManager * ddS,
  DdManager * ddD,
  DdNode * f)
{
    DdNode *res;
    st_table *table = NULL;
    st_generator *gen = NULL;
    DdNode *key, *value;

    /* NuSMV: begin add */
    abort(); /* NOT USED BY NUSMV */
    /* NuSMV: begin end */

    table = st_init_table(st_ptrcmp,st_ptrhash);
    if (table == NULL) goto failure;
    res = cuddBddTransferRecur(ddS, ddD, f, table);
    if (res != NULL) cuddRef(res);

    /* Dereference all elements in the table and dispose of the table.
    ** This must be done also if res is NULL to avoid leaks in case of
    ** reordering. */
    gen = st_init_gen(table);
    if (gen == NULL) goto failure;
    while (st_gen(gen, &key, &value)) {
	Cudd_RecursiveDeref(ddD, value);
    }
    st_free_gen(gen); gen = NULL;
    st_free_table(table); table = NULL;

    if (res != NULL) cuddDeref(res);
    return(res);

failure:
    if (table != NULL) st_free_table(table);
    if (gen != NULL) st_free_gen(gen);
    return(NULL);

} /* end of cuddBddTransfer */
示例#28
0
VALUE st_spec_st_lookup(VALUE self) {
  st_data_t result = (st_data_t)0;
  st_table *tbl = st_init_numtable_with_size(128);
  st_insert(tbl, 7, 42);
  st_insert(tbl, 2, 4);
  st_lookup(tbl, (st_data_t)7, &result);
  st_free_table(tbl);
#if SIZEOF_LONG == SIZEOF_VOIDP
  return ULONG2NUM(result);
#else
  return ULL2NUM(result);
#endif
}
示例#29
0
void osm_db_domain_destroy(IN osm_db_domain_t * const p_db_domain)
{
	osm_db_domain_imp_t *p_domain_imp;
	p_domain_imp = (osm_db_domain_imp_t *) p_db_domain->p_domain_imp;

	osm_db_clear(p_db_domain);

	cl_spinlock_destroy(&p_domain_imp->lock);

	st_free_table(p_domain_imp->p_hash);
	free(p_domain_imp->file_name);
	free(p_domain_imp);
}
示例#30
0
文件: st.c 项目: jixc2008/rhodes
st_table*
st_copy(st_table *old_table)
{
    st_table *new_table;
    st_table_entry *ptr, *entry, *prev, **tail;
    int num_bins = old_table->num_bins;
    unsigned int hash_val;

    new_table = alloc(st_table);
    if (new_table == 0) {
	return 0;
    }

    *new_table = *old_table;
    new_table->bins = (st_table_entry**)
	Calloc((unsigned)num_bins, sizeof(st_table_entry*));

    if (new_table->bins == 0) {
	free(new_table);
	return 0;
    }

    if (old_table->entries_packed) {
        memcpy(new_table->bins, old_table->bins, sizeof(struct st_table_entry *) * old_table->num_bins);
        return new_table;
    }

    if ((ptr = old_table->head) != 0) {
	prev = 0;
	tail = &new_table->head;
	do {
	    entry = alloc(st_table_entry);
	    if (entry == 0) {
		st_free_table(new_table);
		return 0;
	    }
	    *entry = *ptr;
	    hash_val = entry->hash % num_bins;
	    entry->next = new_table->bins[hash_val];
	    new_table->bins[hash_val] = entry;
	    entry->back = prev;
	    *tail = prev = entry;
	    tail = &entry->fore;
	} while ((ptr = ptr->fore) != old_table->head);
	entry = new_table->head;
	entry->back = prev;
	*tail = entry;
    }

    return new_table;
}