special cases and other things in wxPython, and since I plan on making several more, I've decided to put the SWIG sources in wxPython's CVS instead of relying on maintaining patches. This effectivly becomes a fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still doesn't have some things I rely on in 1.1, not to mention that my custom patches would all have to be redone, I felt that this is the easier road to take. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15307 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			360 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			360 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*******************************************************************************
 | 
						|
 * Simplified Wrapper and Interface Generator  (SWIG)
 | 
						|
 * 
 | 
						|
 * Author : David Beazley
 | 
						|
 *
 | 
						|
 * Department of Computer Science        
 | 
						|
 * University of Chicago
 | 
						|
 * 1100 E 58th Street
 | 
						|
 * Chicago, IL  60637
 | 
						|
 * beazley@cs.uchicago.edu
 | 
						|
 *
 | 
						|
 * Please read the file LICENSE for the copyright and terms by which SWIG
 | 
						|
 * can be used and distributed.
 | 
						|
 *******************************************************************************/
 | 
						|
 | 
						|
#include "internal.h"
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 * $Header$
 | 
						|
 *
 | 
						|
 * File : hash.cxx
 | 
						|
 *
 | 
						|
 * A very simple Hash table class.  Could probably make it more elegant with
 | 
						|
 * templates, but templates are pure evil...
 | 
						|
 *******************************************************************************/
 | 
						|
 | 
						|
#define INIT_SIZE   119
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// Hash::Hash()
 | 
						|
//
 | 
						|
// Constructor.  Creates a new hash table. 
 | 
						|
// 
 | 
						|
// Inputs : None
 | 
						|
//
 | 
						|
// Output : New Hash object.
 | 
						|
//
 | 
						|
// Side Effects : None
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
Hash::Hash() {
 | 
						|
  int i;
 | 
						|
  hashsize = INIT_SIZE;
 | 
						|
  hashtable = new Node *[hashsize];
 | 
						|
  for (i = 0; i < hashsize; i++) {
 | 
						|
    hashtable[i] = 0;
 | 
						|
  }
 | 
						|
  index = -1;
 | 
						|
  current = 0;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// Hash::~Hash()
 | 
						|
//
 | 
						|
// Destructor.
 | 
						|
// 
 | 
						|
// Inputs : None
 | 
						|
//
 | 
						|
// Output : None
 | 
						|
//
 | 
						|
// Side Effects : Total destruction.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
Hash::~Hash() {
 | 
						|
  int   i;
 | 
						|
  Node *n,*next;
 | 
						|
 | 
						|
  for (i = 0; i < hashsize; i++) {
 | 
						|
    if (hashtable[i]) {
 | 
						|
      n = hashtable[i];
 | 
						|
      while (n) {
 | 
						|
	next = n->next;
 | 
						|
	delete n;
 | 
						|
	n = next;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  delete [] hashtable;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int Hash::h1(const char *key)
 | 
						|
// 
 | 
						|
// Hashing function.
 | 
						|
//
 | 
						|
// Inputs : ASCII character string.
 | 
						|
//
 | 
						|
// Output : Hash table index.
 | 
						|
//
 | 
						|
// Side Effects : None
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int Hash::h1(const char *key) {
 | 
						|
  int h = 0;
 | 
						|
  const char *c;
 | 
						|
 | 
						|
  c = key;
 | 
						|
  while (*c) {
 | 
						|
    h = (128*h + *c) % hashsize;
 | 
						|
    c++;
 | 
						|
  }
 | 
						|
  return h;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int Hash::add(const char *k, void *obj)
 | 
						|
// 
 | 
						|
// Adds a new object to the hash table.
 | 
						|
//
 | 
						|
// Inputs : 
 | 
						|
//          k     = Hash key
 | 
						|
//          obj   = Pointer to an object
 | 
						|
//
 | 
						|
// Output : 0 on success, -1 if item is already in hash table.
 | 
						|
//
 | 
						|
// Side Effects : 
 | 
						|
//          Makes a new hash table entry.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int Hash::add(const char *k, void *obj) {
 | 
						|
 | 
						|
  int  hv;
 | 
						|
  Node *n,*prev;
 | 
						|
 | 
						|
  hv = h1(k);                                  // Get hash value
 | 
						|
  n = hashtable[hv];
 | 
						|
  prev = n;
 | 
						|
  while (n) {
 | 
						|
    if (strcmp(n->key,k) == 0) return -1;      // Already in hash table
 | 
						|
    prev = n;
 | 
						|
    n = n->next;
 | 
						|
  }
 | 
						|
 | 
						|
  // Safe to add this to the table
 | 
						|
 | 
						|
  n = new Node(k,obj,0);
 | 
						|
  if (prev) prev->next = n;
 | 
						|
  else hashtable[hv] = n;
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// int Hash::add(const char *k, void *obj, void (*d)(void *))
 | 
						|
// 
 | 
						|
// Adds a new object to the hash table.  Allows additional specification of
 | 
						|
// a callback function for object deletion.
 | 
						|
//
 | 
						|
// Inputs :
 | 
						|
//          k       = Hash key
 | 
						|
//          obj     = Object pointer
 | 
						|
//          d       = Deletion function
 | 
						|
//
 | 
						|
// Output : 0 on success, -1 if item is already in hash table.
 | 
						|
//
 | 
						|
// Side Effects :
 | 
						|
//          Adds an entry to the hash table
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
int Hash::add(const char *k, void *obj, void (*d)(void *)) {
 | 
						|
 | 
						|
  int  hv;
 | 
						|
  Node *n,*prev;
 | 
						|
 | 
						|
  hv = h1(k);                                  // Get hash value
 | 
						|
  n = hashtable[hv];
 | 
						|
  prev = n;
 | 
						|
  while (n) {
 | 
						|
    if (strcmp(n->key,k) == 0) return -1;      // Already in hash table
 | 
						|
    prev = n;
 | 
						|
    n = n->next;
 | 
						|
  }
 | 
						|
 | 
						|
  // Safe to add this to the table
 | 
						|
 | 
						|
  n = new Node(k,obj,d);
 | 
						|
  if (prev) prev->next = n;
 | 
						|
  else hashtable[hv] = n;
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void *Hash::lookup(const char *k)
 | 
						|
// 
 | 
						|
// Looks up a value in the hash table.  Returns a pointer to the object if found.
 | 
						|
//
 | 
						|
// Inputs : k   = key value
 | 
						|
//
 | 
						|
// Output : Pointer to object or NULL if not found.
 | 
						|
//
 | 
						|
// Side Effects : None
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void *Hash::lookup(const char *k) {
 | 
						|
  int hv;
 | 
						|
  Node *n;
 | 
						|
 | 
						|
  hv = h1(k);                                // Get hash value
 | 
						|
  n = hashtable[hv];
 | 
						|
 | 
						|
  while (n) {
 | 
						|
    if (strcmp(n->key,k) == 0) return n->object;
 | 
						|
    n = n->next;
 | 
						|
  }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void Hash::remove(const char *k)
 | 
						|
//
 | 
						|
// Removes an item from the hash table.  Does nothing if item isn't in the
 | 
						|
// hash table to begin with.
 | 
						|
// 
 | 
						|
// Inputs : k = Key value
 | 
						|
//
 | 
						|
// Output : None
 | 
						|
//
 | 
						|
// Side Effects : Deletes item from hash table.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void Hash::remove(const char *k) {
 | 
						|
 | 
						|
  int  hv;
 | 
						|
  Node *n,*prev;
 | 
						|
 | 
						|
  hv = h1(k);                                  // Get hash value
 | 
						|
  n = hashtable[hv];
 | 
						|
  prev = 0;
 | 
						|
  while (n) {
 | 
						|
    if (strcmp(n->key,k) == 0) {
 | 
						|
      // Found it, kill the thing
 | 
						|
      if (prev) {
 | 
						|
	prev->next = n->next;
 | 
						|
      } else {
 | 
						|
	hashtable[hv] = n->next;
 | 
						|
      }
 | 
						|
      delete n;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    prev = n;
 | 
						|
    n = n->next;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void *Hash::first()
 | 
						|
//
 | 
						|
// Gets the first item from the hash table or NULL if empty.
 | 
						|
// 
 | 
						|
// Inputs : None
 | 
						|
//
 | 
						|
// Output : First object in hash table or NULL if hash table is empty.
 | 
						|
//
 | 
						|
// Side Effects : Resets an internal iterator variable on the hash table.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void *Hash::first() {
 | 
						|
  index = 0;
 | 
						|
  current = 0;
 | 
						|
 | 
						|
  while (!hashtable[index] && (index < hashsize))
 | 
						|
    index++;
 | 
						|
 | 
						|
  if (index >= hashsize) return 0;
 | 
						|
  current = hashtable[index];
 | 
						|
  return current->object;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// char *Hash::firstkey()
 | 
						|
//
 | 
						|
// Gets the first key from the hash table or NULL if empty.
 | 
						|
// 
 | 
						|
// Inputs : None
 | 
						|
//
 | 
						|
// Output : First key in hash table or NULL if hash table is empty.
 | 
						|
//
 | 
						|
// Side Effects : Resets an internal iterator variable on the hash table.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
char *Hash::firstkey() {
 | 
						|
  index = 0;
 | 
						|
  current = 0;
 | 
						|
 | 
						|
  while ((index < hashsize) && (!hashtable[index]))
 | 
						|
    index++;
 | 
						|
 | 
						|
  if (index >= hashsize) return 0;
 | 
						|
  current = hashtable[index];
 | 
						|
  return current->key;
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// void *Hash::next()
 | 
						|
// 
 | 
						|
// Returns the next item in the hash table or NULL if there are no more entries.
 | 
						|
// A call to first() should generally be made before using this function.
 | 
						|
//
 | 
						|
// Inputs : None
 | 
						|
//
 | 
						|
// Output : Pointer to next object or NULL if there are no more objects.
 | 
						|
//
 | 
						|
// Side Effects : Updates an iterator variable private to the hash table.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
void *Hash::next() {
 | 
						|
  if (index < 0) return first();
 | 
						|
  
 | 
						|
  // Try to move to the next entry
 | 
						|
 | 
						|
  current = current->next;
 | 
						|
 | 
						|
  if (current) {
 | 
						|
    return current->object;
 | 
						|
  } else {
 | 
						|
    index++;
 | 
						|
    while ((index < hashsize) && (!hashtable[index]))
 | 
						|
      index++;
 | 
						|
    if (index >= hashsize) return 0;
 | 
						|
    current = hashtable[index];
 | 
						|
    return current->object;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// char *Hash::nextkey()
 | 
						|
// 
 | 
						|
// Returns the next key in the hash table or NULL if there are no more entries.
 | 
						|
// A call to firstkey() should generally be made before using this function.
 | 
						|
//
 | 
						|
// Inputs : None
 | 
						|
//
 | 
						|
// Output : Pointer to next key or NULL if there are no more objects.
 | 
						|
//
 | 
						|
// Side Effects : Updates an iterator variable private to the hash table.
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
char *Hash::nextkey() {
 | 
						|
  if (index < 0) return firstkey();
 | 
						|
  
 | 
						|
  // Try to move to the next entry
 | 
						|
 | 
						|
  current = current->next;
 | 
						|
 | 
						|
  if (current) {
 | 
						|
    return current->key;
 | 
						|
  } else {
 | 
						|
    index++;
 | 
						|
    while (!hashtable[index] && (index < hashsize))
 | 
						|
      index++;
 | 
						|
    if (index >= hashsize) return 0;
 | 
						|
    current = hashtable[index];
 | 
						|
    return current->key;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 |