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;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 |