Index: /trunk/archive/pslib/src/Utils/hash.c
===================================================================
--- /trunk/archive/pslib/src/Utils/hash.c	(revision 172)
+++ /trunk/archive/pslib/src/Utils/hash.c	(revision 173)
@@ -31,7 +31,7 @@
  * Con/Destruct buckets
  */
-static HashBucket *hashBucketNew(const char *key,
-				 void *data,
-				 HashBucket *next)
+static HashBucket *hashBucketAlloc(const char *key,
+				   void *data,
+				   HashBucket *next)
 {
     HashBucket *bucket = psAlloc(sizeof(HashBucket));
@@ -44,7 +44,7 @@
 }
 
-static void hashBucketDel(
+static void hashBucketFree(
     HashBucket *bucket,			// bucket to free
-    void (*itemDel)(void *item))	// how to free hashed data;
+    void (*itemFree)(void *item))	// how to free hashed data;
 					// or NULL
 {
@@ -56,6 +56,6 @@
     psMemDecrRefCounter(bucket->data);
     
-    if (itemDel != NULL) {
-	itemDel(bucket->data);
+    if (itemFree != NULL) {
+	itemFree(bucket->data);
     }
     
@@ -67,5 +67,5 @@
  * Con/Destruct psHash tables
  */
-psHash *psHashNew(int nbucket)		// initial number of buckets
+psHash *psHashAlloc(int nbucket)	// initial number of buckets
 {
     psHash *table = psAlloc(sizeof(psHash));
@@ -82,6 +82,6 @@
 }
 
-void psHashDel(psHash *table,		// hash table to be freed
-	       void (*itemDel)(void *item)) // how to free hashed data; or NULL
+void psHashFree(psHash *table,		// hash table to be freed
+		void (*itemFree)(void *item)) // how to free hashed data; or NULL
 {
     if (table == NULL) {
@@ -96,5 +96,5 @@
 	    while (ptr != NULL) {
 		HashBucket *tmp = ptr->next;
-		hashBucketDel(ptr, itemDel);
+		hashBucketFree(ptr, itemFree);
 		ptr = tmp;
 	    }
@@ -108,7 +108,7 @@
 /*****************************************************************************/
 /*
- * Here's the routine to do the work of insertion/retrieval.
+ * Here's the routine to do the work of insertion/retrieval/removal
  *
- * We need itemDel if the key is already in use and we're inserting
+ * We need itemFree if the key is already in use and we're inserting
  *
  * N.b. this is NOT a good hash function! See Knuth for some better ones
@@ -118,6 +118,7 @@
     const char *key,			// key to use
     void *data,				// data to insert,
-					// or (if NULL) retrieve
-    void (*itemDel)(void *item))	// how to free hashed data
+					// or (if NULL) retrieve/remove
+    int remove,				// remove the item from the list?
+    void (*itemFree)(void *item))	// how to free hashed data
 					// or NULL
 {
@@ -134,11 +135,33 @@
      * We've found the correct hash bucket, now we need to know what to do
      */
-    if (data == NULL) {			// retrieve
-	while (ptr != NULL) {
-	    if (strcmp(key, ptr->key) == 0) { // found it!
-		return ptr->data;
-	    }
-
-	    ptr = ptr->next;
+    if (data == NULL) {			// retrieve/remove
+	if (remove) {
+	    HashBucket *optr = ptr;
+	    while (ptr != NULL) {
+		if (strcmp(key, ptr->key) == 0) { // found it!
+		    void *data = ptr->data;
+		    optr->next = ptr->next;
+
+		    if (ptr == table->buckets[hash]) {
+			table->buckets[hash] = ptr->next;
+		    }
+
+		    psFree(ptr->key);
+		    psFree(ptr);
+
+		    return psMemDecrRefCounter(data); // return data
+		}
+
+		optr = ptr;
+		ptr = ptr->next;
+	    }
+	} else {
+	    while (ptr != NULL) {
+		if (strcmp(key, ptr->key) == 0) { // found it!
+		    return ptr->data;
+		}
+		
+		ptr = ptr->next;
+	    }
 	}
 
@@ -147,5 +170,5 @@
 	while (ptr != NULL) {
 	    if (strcmp(key, ptr->key) == 0) { // found it!
-		if (itemDel == NULL) {
+		if (itemFree == NULL) {
 		    return NULL;	// can't insert
 		}			
@@ -154,5 +177,5 @@
 			key);
 
-		itemDel(psMemDecrRefCounter(ptr->data));
+		itemFree(psMemDecrRefCounter(ptr->data));
 		ptr->data = psMemIncrRefCounter(data);
 
@@ -163,5 +186,5 @@
 	 * Not found, so insert at the front of the list
 	 */
-	table->buckets[hash] = hashBucketNew(key, data, table->buckets[hash]);
+	table->buckets[hash] = hashBucketAlloc(key, data, table->buckets[hash]);
 
 	return data;
@@ -176,8 +199,8 @@
 		   const char *key,	// key to use
 		   void *data,		// data to insert
-		   void (*itemDel)(void *item))	// how to free hashed data;
+		   void (*itemFree)(void *item)) // how to free hashed data;
 					// or NULL
 {
-    return doHashWork(table, key, data, itemDel);
+    return doHashWork(table, key, data, 0, itemFree);
 }
 
@@ -189,5 +212,15 @@
 		   const char *key)	// key to lookup
 {
-    return doHashWork(table, key, NULL, NULL);
+    return doHashWork(table, key, NULL, 0, NULL);
+}
+
+/*****************************************************************************/
+/*
+ * Remove and return a value from a hash table
+ */
+void *psHashRemove(psHash *table,	// table to lookup key in
+		   const char *key)	// key to lookup
+{
+    return doHashWork(table, key, NULL, 1, NULL);
 }
 
@@ -196,5 +229,5 @@
 
 typedef struct { char *name; } ID;
-static ID *IdNew(const char *name)
+static ID *IdAlloc(const char *name)
 {
     ID *id = psAlloc(sizeof(ID));
@@ -204,5 +237,6 @@
 }
 
-static void IdDel(ID *id) {
+static void IdFree(ID *id)
+{
     if (psMemGetRefCounter(id) > 1) {
 	psMemDecrRefCounter(id);
@@ -219,10 +253,10 @@
     long memId0 = psMemGetId();
 
-    psHash *hash = psHashNew(16);
-
-    psHashInsert(hash, "Lynda", IdNew("Lee"), (void (*)(void *))IdDel);
-    psHashInsert(hash, "Lynda", IdNew("Lee"), (void (*)(void *))IdDel);
-    psHashInsert(hash, "Robert", IdNew("Lupton"), (void (*)(void *))IdDel);
-    psHashInsert(hash, "Robert", IdNew("the Good"), (void (*)(void *))IdDel);
+    psHash *hash = psHashAlloc(16);
+
+    psHashInsert(hash, "Lynda", IdAlloc("Lee"), (void (*)(void *))IdFree);
+    psHashInsert(hash, "Lynda", IdAlloc("Lee"), (void (*)(void *))IdFree);
+    psHashInsert(hash, "Robert", IdAlloc("Lupton"), (void (*)(void *))IdFree);
+    psHashInsert(hash, "Robert", IdAlloc("the Good"), (void (*)(void *))IdFree);
 
     char *names[] = {"Robert", "Lynda", "Rowan", NULL};
@@ -233,5 +267,5 @@
     }
 
-    psHashDel(hash, (void (*)(void *))IdDel);
+    psHashFree(hash, (void (*)(void *))IdFree);
     /*
      * Check for memory leaks
Index: /trunk/archive/pslib/src/Utils/psHash.h
===================================================================
--- /trunk/archive/pslib/src/Utils/psHash.h	(revision 172)
+++ /trunk/archive/pslib/src/Utils/psHash.h	(revision 173)
@@ -4,7 +4,7 @@
 typedef struct HashTable psHash;
 
-psHash *psHashNew(int nbucket);		// initial number of buckets
-void psHashDel(psHash *table,		// hash table to be freed
-	       void (*itemDel)(void *item)); // how to free hashed data;
+psHash *psHashAlloc(int nbucket);	// initial number of buckets
+void psHashFree(psHash *table,		// hash table to be freed
+		void (*itemFree)(void *item)); // how to free hashed data;
 					// or NULL
 
@@ -12,8 +12,10 @@
 		   const char *key,	// key to use
 		   void *data,		// data to insert
-		   void (*itemDel)(void *item)); // how to free hashed data;
+		   void (*itemFree)(void *item)); // how to free hashed data;
 					// or NULL
 void *psHashLookup(psHash *table,	// table to lookup key in
 		   const char *key);	// key to lookup
 
+void *psHashRemove(psHash *table,	// table to lookup key in
+		   const char *key);	// key to lookup
 #endif
