| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | /***********************************************************
 | 
					
						
							| 
									
										
										
										
											1995-01-04 19:07:38 +00:00
										 |  |  | Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, | 
					
						
							|  |  |  | The Netherlands. | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         All Rights Reserved | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | Permission to use, copy, modify, and distribute this software and its | 
					
						
							|  |  |  | documentation for any purpose and without fee is hereby granted, | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | provided that the above copyright notice appear in all copies and that | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | both that copyright notice and this permission notice appear in | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | supporting documentation, and that the names of Stichting Mathematisch | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | Centrum or CWI or Corporation for National Research Initiatives or | 
					
						
							|  |  |  | CNRI not be used in advertising or publicity pertaining to | 
					
						
							|  |  |  | distribution of the software without specific, written prior | 
					
						
							|  |  |  | permission. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | While CWI is the initial source for this software, a modified version | 
					
						
							|  |  |  | is made available by the Corporation for National Research Initiatives | 
					
						
							|  |  |  | (CNRI) at the Internet address ftp://ftp.python.org.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH | 
					
						
							|  |  |  | REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF | 
					
						
							|  |  |  | MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH | 
					
						
							|  |  |  | CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | 
					
						
							|  |  |  | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | 
					
						
							|  |  |  | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | 
					
						
							|  |  |  | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | 
					
						
							|  |  |  | PERFORMANCE OF THIS SOFTWARE. | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ******************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-24 19:06:42 +00:00
										 |  |  | /* Dictionary object implementation using a hash table */ | 
					
						
							| 
									
										
										
										
											1993-03-29 10:43:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  |  * MINSIZE is the minimum size of a dictionary. | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MINSIZE 4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | Table of irreducible polynomials to efficiently cycle through | 
					
						
							|  |  |  | GF(2^n)-{0}, 2<=n<=30. | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | static long polys[] = { | 
					
						
							| 
									
										
										
										
											1997-01-29 04:45:16 +00:00
										 |  |  | 	4 + 3, | 
					
						
							|  |  |  | 	8 + 3, | 
					
						
							|  |  |  | 	16 + 3, | 
					
						
							|  |  |  | 	32 + 5, | 
					
						
							|  |  |  | 	64 + 3, | 
					
						
							|  |  |  | 	128 + 3, | 
					
						
							|  |  |  | 	256 + 29, | 
					
						
							|  |  |  | 	512 + 17, | 
					
						
							|  |  |  | 	1024 + 9, | 
					
						
							|  |  |  | 	2048 + 5, | 
					
						
							|  |  |  | 	4096 + 83, | 
					
						
							|  |  |  | 	8192 + 27, | 
					
						
							|  |  |  | 	16384 + 43, | 
					
						
							|  |  |  | 	32768 + 3, | 
					
						
							|  |  |  | 	65536 + 45, | 
					
						
							|  |  |  | 	131072 + 9, | 
					
						
							|  |  |  | 	262144 + 39, | 
					
						
							|  |  |  | 	524288 + 39, | 
					
						
							|  |  |  | 	1048576 + 9, | 
					
						
							|  |  |  | 	2097152 + 5, | 
					
						
							|  |  |  | 	4194304 + 3, | 
					
						
							|  |  |  | 	8388608 + 33, | 
					
						
							|  |  |  | 	16777216 + 27, | 
					
						
							|  |  |  | 	33554432 + 9, | 
					
						
							|  |  |  | 	67108864 + 71, | 
					
						
							|  |  |  | 	134217728 + 39, | 
					
						
							|  |  |  | 	268435456 + 9, | 
					
						
							|  |  |  | 	536870912 + 5, | 
					
						
							|  |  |  | 	1073741824 + 83, | 
					
						
							|  |  |  | 	0 | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Object used as dummy key to fill deleted entries */ | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | static PyObject *dummy; /* Initialized by first call to newdictobject() */ | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											1999-03-24 19:06:42 +00:00
										 |  |  | Invariant for entries: when in use, me_value is not NULL and me_key is | 
					
						
							|  |  |  | not NULL and not dummy; when not in use, me_value is NULL and me_key | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | is either NULL or dummy.  A dummy key value cannot be replaced by | 
					
						
							|  |  |  | NULL, since otherwise other keys may be lost. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	long me_hash; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *me_key; | 
					
						
							|  |  |  | 	PyObject *me_value; | 
					
						
							| 
									
										
										
										
											1997-04-11 19:14:07 +00:00
										 |  |  | #ifdef USE_CACHE_ALIGNED
 | 
					
						
							|  |  |  | 	long	aligner; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | } dictentry; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | To ensure the lookup algorithm terminates, the table size must be a | 
					
						
							|  |  |  | prime number and there must be at least one NULL key in the table. | 
					
						
							|  |  |  | The value ma_fill is the number of non-NULL keys; ma_used is the number | 
					
						
							|  |  |  | of non-NULL, non-dummy keys. | 
					
						
							|  |  |  | To avoid slowing down lookups on a near-full table, we resize the table | 
					
						
							|  |  |  | when it is more than half filled. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject_HEAD | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	int ma_fill; | 
					
						
							|  |  |  | 	int ma_used; | 
					
						
							|  |  |  | 	int ma_size; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	int ma_poly; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	dictentry *ma_table; | 
					
						
							|  |  |  | } dictobject; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyDict_New() | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (dummy == NULL) { /* Auto-initialize dummy */ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		dummy = PyString_FromString("<dummy key>"); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		if (dummy == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	mp = PyObject_NEW(dictobject, &PyDict_Type); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (mp == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 	mp->ma_size = 0; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	mp->ma_poly = 0; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 	mp->ma_table = NULL; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	mp->ma_fill = 0; | 
					
						
							|  |  |  | 	mp->ma_used = 0; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	return (PyObject *)mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | The basic lookup function used by all operations. | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4. | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | Open addressing is preferred over chaining since the link overhead for | 
					
						
							|  |  |  | chaining would be substantial (100% with typical malloc overhead). | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | However, instead of going through the table at constant steps, we cycle | 
					
						
							|  |  |  | through the values of GF(2^n)-{0}. This avoids modulo computations, being | 
					
						
							|  |  |  | much cheaper on RISC machines, without leading to clustering. | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-24 19:06:42 +00:00
										 |  |  | The initial probe index is computed as hash mod the table size. | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | Subsequent probe indices use the values of x^i in GF(2^n) as an offset, | 
					
						
							| 
									
										
										
										
											1999-03-24 19:06:42 +00:00
										 |  |  | where x is a root. The initial value is derived from hash, too. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | All arithmetic on hash should ignore overflow. | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | (This version is due to Reimer Behrends, some ideas are also due to | 
					
						
							| 
									
										
										
										
											1997-08-18 21:52:47 +00:00
										 |  |  | Jyrki Alakuijala and Vladimir Marangozov.) | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | static dictentry *lookdict Py_PROTO((dictobject *, PyObject *, long)); | 
					
						
							|  |  |  | static dictentry * | 
					
						
							|  |  |  | lookdict(mp, key, hash) | 
					
						
							|  |  |  | 	dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *key; | 
					
						
							| 
									
										
										
										
											1997-08-18 21:52:47 +00:00
										 |  |  | 	register long hash; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	register int i; | 
					
						
							|  |  |  | 	register unsigned incr; | 
					
						
							| 
									
										
										
										
											1997-08-18 21:52:47 +00:00
										 |  |  | 	register dictentry *freeslot; | 
					
						
							| 
									
										
										
										
											1997-04-09 19:41:24 +00:00
										 |  |  | 	register unsigned int mask = mp->ma_size-1; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	dictentry *ep0 = mp->ma_table; | 
					
						
							|  |  |  | 	register dictentry *ep; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	/* We must come up with (i, incr) such that 0 <= i < ma_size
 | 
					
						
							|  |  |  | 	   and 0 < incr < ma_size and both are a function of hash */ | 
					
						
							| 
									
										
										
										
											1997-08-18 21:52:47 +00:00
										 |  |  | 	i = (~hash) & mask; | 
					
						
							|  |  |  | 	/* We use ~hash instead of hash, as degenerate hash functions, such
 | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	   as for ints <sigh>, can have lots of leading zeros. It's not | 
					
						
							|  |  |  | 	   really a performance risk, but better safe than sorry. */ | 
					
						
							| 
									
										
										
										
											1997-01-29 15:53:56 +00:00
										 |  |  | 	ep = &ep0[i]; | 
					
						
							| 
									
										
										
										
											1998-10-06 16:01:14 +00:00
										 |  |  | 	if (ep->me_key == NULL || ep->me_key == key) | 
					
						
							| 
									
										
										
										
											1997-01-16 21:06:45 +00:00
										 |  |  | 		return ep; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	if (ep->me_key == dummy) | 
					
						
							| 
									
										
										
										
											1997-01-16 21:06:45 +00:00
										 |  |  | 		freeslot = ep; | 
					
						
							| 
									
										
										
										
											1997-08-18 21:52:47 +00:00
										 |  |  | 	else { | 
					
						
							| 
									
										
										
										
											1998-10-06 16:01:14 +00:00
										 |  |  | 		if (ep->me_hash == hash && | 
					
						
							|  |  |  | 		    PyObject_Compare(ep->me_key, key) == 0) | 
					
						
							| 
									
										
										
										
											1997-08-18 21:52:47 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			return ep; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		freeslot = NULL; | 
					
						
							| 
									
										
										
										
											1997-01-18 07:55:05 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-23 00:01:41 +00:00
										 |  |  | 	/* XXX What if PyObject_Compare returned an exception? */ | 
					
						
							| 
									
										
										
										
											1999-03-24 19:06:42 +00:00
										 |  |  | 	/* Derive incr from hash, just to make it more arbitrary. Note that
 | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	   incr must not be 0, or we will get into an infinite loop.*/ | 
					
						
							| 
									
										
										
										
											1997-08-18 21:52:47 +00:00
										 |  |  | 	incr = (hash ^ ((unsigned long)hash >> 3)) & mask; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	if (!incr) | 
					
						
							|  |  |  | 		incr = mask; | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											1997-01-29 15:53:56 +00:00
										 |  |  | 		ep = &ep0[(i+incr)&mask]; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 		if (ep->me_key == NULL) { | 
					
						
							|  |  |  | 			if (freeslot != NULL) | 
					
						
							|  |  |  | 				return freeslot; | 
					
						
							|  |  |  | 			else | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 				return ep; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (ep->me_key == dummy) { | 
					
						
							|  |  |  | 			if (freeslot == NULL) | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 				freeslot = ep; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 		else if (ep->me_key == key || | 
					
						
							|  |  |  | 			 (ep->me_hash == hash && | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			  PyObject_Compare(ep->me_key, key) == 0)) { | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 			return ep; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-05-23 00:01:41 +00:00
										 |  |  | 		/* XXX What if PyObject_Compare returned an exception? */ | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 		/* Cycle through GF(2^n)-{0} */ | 
					
						
							|  |  |  | 		incr = incr << 1; | 
					
						
							|  |  |  | 		if (incr > mask) | 
					
						
							| 
									
										
										
										
											1998-11-16 22:46:30 +00:00
										 |  |  | 			incr ^= mp->ma_poly; /* This will implicitely clear
 | 
					
						
							|  |  |  | 						the highest bit */ | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | Internal routine to insert a new item into the table. | 
					
						
							|  |  |  | Used both by the internal resize routine and by the public insert routine. | 
					
						
							|  |  |  | Eats a reference to key and one to value. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | static void insertdict | 
					
						
							|  |  |  | 	Py_PROTO((dictobject *, PyObject *, long, PyObject *)); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | insertdict(mp, key, hash, value) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *key; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	long hash; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *value; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *old_value; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictentry *ep; | 
					
						
							|  |  |  | 	ep = lookdict(mp, key, hash); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (ep->me_value != NULL) { | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 		old_value = ep->me_value; | 
					
						
							|  |  |  | 		ep->me_value = value; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		Py_DECREF(old_value); /* which **CAN** re-enter */ | 
					
						
							|  |  |  | 		Py_DECREF(key); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		if (ep->me_key == NULL) | 
					
						
							|  |  |  | 			mp->ma_fill++; | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			Py_DECREF(ep->me_key); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		ep->me_key = key; | 
					
						
							|  |  |  | 		ep->me_hash = hash; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 		ep->me_value = value; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		mp->ma_used++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | Restructure the table by allocating a new table and reinserting all | 
					
						
							|  |  |  | items again.  When entries have been deleted, the new table may | 
					
						
							|  |  |  | actually be smaller than the old one. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  | static int dictresize Py_PROTO((dictobject *, int)); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  | dictresize(mp, minused) | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  | 	int minused; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	register int oldsize = mp->ma_size; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	register int newsize, newpoly; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictentry *oldtable = mp->ma_table; | 
					
						
							|  |  |  | 	register dictentry *newtable; | 
					
						
							|  |  |  | 	register dictentry *ep; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	register int i; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	for (i = 0, newsize = MINSIZE; ; i++, newsize <<= 1) { | 
					
						
							|  |  |  | 		if (i > sizeof(polys)/sizeof(polys[0])) { | 
					
						
							|  |  |  | 			/* Ran out of polynomials */ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			PyErr_NoMemory(); | 
					
						
							| 
									
										
										
										
											1994-08-30 08:27:36 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  | 		if (newsize > minused) { | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 			newpoly = polys[i]; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1998-07-16 15:06:13 +00:00
										 |  |  | 	newtable = (dictentry *) malloc(sizeof(dictentry) * newsize); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (newtable == NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		PyErr_NoMemory(); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1998-07-16 15:06:13 +00:00
										 |  |  | 	memset(newtable, '\0', sizeof(dictentry) * newsize); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	mp->ma_size = newsize; | 
					
						
							| 
									
										
										
										
											1997-01-28 00:00:11 +00:00
										 |  |  | 	mp->ma_poly = newpoly; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	mp->ma_table = newtable; | 
					
						
							|  |  |  | 	mp->ma_fill = 0; | 
					
						
							|  |  |  | 	mp->ma_used = 0; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Make two passes, so we can avoid decrefs
 | 
					
						
							|  |  |  | 	   (and possible side effects) till the table is copied */ | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	for (i = 0, ep = oldtable; i < oldsize; i++, ep++) { | 
					
						
							|  |  |  | 		if (ep->me_value != NULL) | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 			insertdict(mp,ep->me_key,ep->me_hash,ep->me_value); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for (i = 0, ep = oldtable; i < oldsize; i++, ep++) { | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 		if (ep->me_value == NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			Py_XDECREF(ep->me_key); | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyMem_XDEL(oldtable); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyDict_GetItem(op, key) | 
					
						
							|  |  |  | 	PyObject *op; | 
					
						
							|  |  |  | 	PyObject *key; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	long hash; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyDict_Check(op)) { | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	if (((dictobject *)op)->ma_table == NULL) | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #ifdef CACHE_HASH
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyString_Check(key) || | 
					
						
							|  |  |  | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		hash = PyObject_Hash(key); | 
					
						
							| 
									
										
										
										
											1998-05-14 01:00:51 +00:00
										 |  |  | 		if (hash == -1) { | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											1998-05-14 01:00:51 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	return lookdict((dictobject *)op, key, hash) -> me_value; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyDict_SetItem(op, key, value) | 
					
						
							|  |  |  | 	register PyObject *op; | 
					
						
							|  |  |  | 	PyObject *key; | 
					
						
							|  |  |  | 	PyObject *value; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	register long hash; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyDict_Check(op)) { | 
					
						
							|  |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	mp = (dictobject *)op; | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #ifdef CACHE_HASH
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (PyString_Check(key)) { | 
					
						
							| 
									
										
										
										
											1997-01-18 07:55:05 +00:00
										 |  |  | #ifdef INTERN_STRINGS
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		if (((PyStringObject *)key)->ob_sinterned != NULL) { | 
					
						
							|  |  |  | 			key = ((PyStringObject *)key)->ob_sinterned; | 
					
						
							|  |  |  | 			hash = ((PyStringObject *)key)->ob_shash; | 
					
						
							| 
									
										
										
										
											1997-01-18 07:55:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1997-01-18 07:55:05 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			hash = ((PyStringObject *)key)->ob_shash; | 
					
						
							| 
									
										
										
										
											1997-01-18 07:55:05 +00:00
										 |  |  | 			if (hash == -1) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 				hash = PyObject_Hash(key); | 
					
						
							| 
									
										
										
										
											1997-01-18 07:55:05 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		hash = PyObject_Hash(key); | 
					
						
							| 
									
										
										
										
											1997-01-18 07:55:05 +00:00
										 |  |  | 		if (hash == -1) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  | 	/* if fill >= 2/3 size, double in size */ | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (mp->ma_fill*3 >= mp->ma_size*2) { | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  | 		if (dictresize(mp, mp->ma_used*2) != 0) { | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 			if (mp->ma_fill+1 > mp->ma_size) | 
					
						
							|  |  |  | 				return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	Py_INCREF(value); | 
					
						
							|  |  |  | 	Py_INCREF(key); | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	insertdict(mp, key, hash, value); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyDict_DelItem(op, key) | 
					
						
							|  |  |  | 	PyObject *op; | 
					
						
							|  |  |  | 	PyObject *key; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	register long hash; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictentry *ep; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *old_value, *old_key; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyDict_Check(op)) { | 
					
						
							|  |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #ifdef CACHE_HASH
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyString_Check(key) || | 
					
						
							|  |  |  | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		hash = PyObject_Hash(key); | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 		if (hash == -1) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	mp = (dictobject *)op; | 
					
						
							|  |  |  | 	if (((dictobject *)op)->ma_table == NULL) | 
					
						
							| 
									
										
										
										
											1995-01-02 19:42:39 +00:00
										 |  |  | 		goto empty; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	ep = lookdict(mp, key, hash); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (ep->me_value == NULL) { | 
					
						
							| 
									
										
										
										
											1995-01-02 19:42:39 +00:00
										 |  |  | 	empty: | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		PyErr_SetObject(PyExc_KeyError, key); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 	old_key = ep->me_key; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	Py_INCREF(dummy); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	ep->me_key = dummy; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 	old_value = ep->me_value; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	ep->me_value = NULL; | 
					
						
							|  |  |  | 	mp->ma_used--; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	Py_DECREF(old_value);  | 
					
						
							|  |  |  | 	Py_DECREF(old_key);  | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyDict_Clear(op) | 
					
						
							|  |  |  | 	PyObject *op; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 	int i, n; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictentry *table; | 
					
						
							|  |  |  | 	dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyDict_Check(op)) | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	mp = (dictobject *)op; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 	table = mp->ma_table; | 
					
						
							|  |  |  | 	if (table == NULL) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	n = mp->ma_size; | 
					
						
							|  |  |  | 	mp->ma_size = mp->ma_used = mp->ma_fill = 0; | 
					
						
							|  |  |  | 	mp->ma_table = NULL; | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		Py_XDECREF(table[i].me_key); | 
					
						
							|  |  |  | 		Py_XDECREF(table[i].me_value); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyMem_DEL(table); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyDict_Next(op, ppos, pkey, pvalue) | 
					
						
							|  |  |  | 	PyObject *op; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 	int *ppos; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject **pkey; | 
					
						
							|  |  |  | 	PyObject **pvalue; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyDict_Check(op)) | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	mp = (dictobject *)op; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 	i = *ppos; | 
					
						
							|  |  |  | 	if (i < 0) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	while (i < mp->ma_size && mp->ma_table[i].me_value == NULL) | 
					
						
							|  |  |  | 		i++; | 
					
						
							|  |  |  | 	*ppos = i+1; | 
					
						
							|  |  |  | 	if (i >= mp->ma_size) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	if (pkey) | 
					
						
							|  |  |  | 		*pkey = mp->ma_table[i].me_key; | 
					
						
							|  |  |  | 	if (pvalue) | 
					
						
							|  |  |  | 		*pvalue = mp->ma_table[i].me_value; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Methods */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_dealloc(mp) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	register int i; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictentry *ep; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 		if (ep->me_key != NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			Py_DECREF(ep->me_key); | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (ep->me_value != NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			Py_DECREF(ep->me_value); | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyMem_XDEL(mp->ma_table); | 
					
						
							|  |  |  | 	PyMem_DEL(mp); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_print(mp, fp, flags) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	register FILE *fp; | 
					
						
							|  |  |  | 	register int flags; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	register int i; | 
					
						
							|  |  |  | 	register int any; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictentry *ep; | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	i = Py_ReprEnter((PyObject*)mp); | 
					
						
							|  |  |  | 	if (i != 0) { | 
					
						
							|  |  |  | 		if (i < 0) | 
					
						
							|  |  |  | 			return i; | 
					
						
							|  |  |  | 		fprintf(fp, "{...}"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	fprintf(fp, "{"); | 
					
						
							|  |  |  | 	any = 0; | 
					
						
							|  |  |  | 	for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { | 
					
						
							|  |  |  | 		if (ep->me_value != NULL) { | 
					
						
							|  |  |  | 			if (any++ > 0) | 
					
						
							|  |  |  | 				fprintf(fp, ", "); | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 			if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) { | 
					
						
							|  |  |  | 				Py_ReprLeave((PyObject*)mp); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 				return -1; | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 			fprintf(fp, ": "); | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 			if (PyObject_Print(ep->me_value, fp, 0) != 0) { | 
					
						
							|  |  |  | 				Py_ReprLeave((PyObject*)mp); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 				return -1; | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fprintf(fp, "}"); | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 	Py_ReprLeave((PyObject*)mp); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_repr(mp) | 
					
						
							|  |  |  | 	dictobject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	auto PyObject *v; | 
					
						
							|  |  |  | 	PyObject *sepa, *colon; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	register int i; | 
					
						
							|  |  |  | 	register int any; | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	register dictentry *ep; | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	i = Py_ReprEnter((PyObject*)mp); | 
					
						
							|  |  |  | 	if (i != 0) { | 
					
						
							|  |  |  | 		if (i > 0) | 
					
						
							|  |  |  | 			return PyString_FromString("{...}"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	v = PyString_FromString("{"); | 
					
						
							|  |  |  | 	sepa = PyString_FromString(", "); | 
					
						
							|  |  |  | 	colon = PyString_FromString(": "); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	any = 0; | 
					
						
							| 
									
										
										
										
											1994-08-30 08:27:36 +00:00
										 |  |  | 	for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) { | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		if (ep->me_value != NULL) { | 
					
						
							|  |  |  | 			if (any++) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 				PyString_Concat(&v, sepa); | 
					
						
							|  |  |  | 			PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key)); | 
					
						
							|  |  |  | 			PyString_Concat(&v, colon); | 
					
						
							|  |  |  | 			PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_value)); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyString_ConcatAndDel(&v, PyString_FromString("}")); | 
					
						
							| 
									
										
										
										
											1998-04-10 22:47:14 +00:00
										 |  |  | 	Py_ReprLeave((PyObject*)mp); | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	Py_XDECREF(sepa); | 
					
						
							|  |  |  | 	Py_XDECREF(colon); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_length(mp) | 
					
						
							|  |  |  | 	dictobject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return mp->ma_used; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_subscript(mp, key) | 
					
						
							|  |  |  | 	dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	register PyObject *key; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *v; | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | 	long hash; | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 	if (mp->ma_table == NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		PyErr_SetObject(PyExc_KeyError, key); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:07:15 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #ifdef CACHE_HASH
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyString_Check(key) || | 
					
						
							|  |  |  | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		hash = PyObject_Hash(key); | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 		if (hash == -1) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	v = lookdict(mp, key, hash) -> me_value; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (v == NULL) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		PyErr_SetObject(PyExc_KeyError, key); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		Py_INCREF(v); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_ass_sub(mp, v, w) | 
					
						
							|  |  |  | 	dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *v, *w; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (w == NULL) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		return PyDict_DelItem((PyObject *)mp, v); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		return PyDict_SetItem((PyObject *)mp, v, w); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | static PyMappingMethods dict_as_mapping = { | 
					
						
							|  |  |  | 	(inquiry)dict_length, /*mp_length*/ | 
					
						
							|  |  |  | 	(binaryfunc)dict_subscript, /*mp_subscript*/ | 
					
						
							|  |  |  | 	(objobjargproc)dict_ass_sub, /*mp_ass_subscript*/ | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_keys(mp, args) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *args; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	register PyObject *v; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	register int i, j; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyArg_NoArgs(args)) | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	v = PyList_New(mp->ma_used); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	for (i = 0, j = 0; i < mp->ma_size; i++) { | 
					
						
							|  |  |  | 		if (mp->ma_table[i].me_value != NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			PyObject *key = mp->ma_table[i].me_key; | 
					
						
							|  |  |  | 			Py_INCREF(key); | 
					
						
							|  |  |  | 			PyList_SetItem(v, j, key); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 			j++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_values(mp, args) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *args; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	register PyObject *v; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 	register int i, j; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyArg_NoArgs(args)) | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	v = PyList_New(mp->ma_used); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	for (i = 0, j = 0; i < mp->ma_size; i++) { | 
					
						
							|  |  |  | 		if (mp->ma_table[i].me_value != NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			PyObject *value = mp->ma_table[i].me_value; | 
					
						
							|  |  |  | 			Py_INCREF(value); | 
					
						
							|  |  |  | 			PyList_SetItem(v, j, value); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 			j++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_items(mp, args) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *args; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	register PyObject *v; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 	register int i, j; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyArg_NoArgs(args)) | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	v = PyList_New(mp->ma_used); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	for (i = 0, j = 0; i < mp->ma_size; i++) { | 
					
						
							|  |  |  | 		if (mp->ma_table[i].me_value != NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			PyObject *key = mp->ma_table[i].me_key; | 
					
						
							|  |  |  | 			PyObject *value = mp->ma_table[i].me_value; | 
					
						
							|  |  |  | 			PyObject *item = PyTuple_New(2); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 			if (item == NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 				Py_DECREF(v); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			Py_INCREF(key); | 
					
						
							|  |  |  | 			PyTuple_SetItem(item, 0, key); | 
					
						
							|  |  |  | 			Py_INCREF(value); | 
					
						
							|  |  |  | 			PyTuple_SetItem(item, 1, value); | 
					
						
							|  |  |  | 			PyList_SetItem(v, j, item); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 			j++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-06-02 17:13:37 +00:00
										 |  |  | dict_update(mp, args) | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  |       register dictobject *mp; | 
					
						
							|  |  |  |       PyObject *args; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	register int i; | 
					
						
							|  |  |  | 	dictobject *other; | 
					
						
							|  |  |  |         dictentry *entry; | 
					
						
							|  |  |  | 	if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if (other == mp) | 
					
						
							| 
									
										
										
										
											1997-06-02 17:13:37 +00:00
										 |  |  | 		goto done; /* a.update(a); nothing to do */ | 
					
						
							| 
									
										
										
										
											1997-05-28 19:15:28 +00:00
										 |  |  | 	/* Do one big resize at the start, rather than incrementally
 | 
					
						
							|  |  |  | 	   resizing as we insert new items.  Expect that there will be | 
					
						
							|  |  |  | 	   no (or few) overlapping keys. */ | 
					
						
							|  |  |  | 	if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) { | 
					
						
							|  |  |  | 		if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (i = 0; i < other->ma_size; i++) { | 
					
						
							|  |  |  | 		entry = &other->ma_table[i]; | 
					
						
							|  |  |  | 		if (entry->me_value != NULL) { | 
					
						
							|  |  |  | 			Py_INCREF(entry->me_key); | 
					
						
							|  |  |  | 			Py_INCREF(entry->me_value); | 
					
						
							|  |  |  | 			insertdict(mp, entry->me_key, entry->me_hash, | 
					
						
							|  |  |  | 				   entry->me_value); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |   done: | 
					
						
							|  |  |  | 	Py_INCREF(Py_None); | 
					
						
							|  |  |  | 	return Py_None; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | dict_copy(mp, args) | 
					
						
							|  |  |  |       register dictobject *mp; | 
					
						
							|  |  |  |       PyObject *args; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	register int i; | 
					
						
							|  |  |  | 	dictobject *copy; | 
					
						
							|  |  |  |         dictentry *entry; | 
					
						
							|  |  |  | 	if (!PyArg_Parse(args, "")) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	copy = (dictobject *)PyDict_New(); | 
					
						
							|  |  |  | 	if (copy == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if (mp->ma_used > 0) { | 
					
						
							|  |  |  | 		if (dictresize(copy, mp->ma_used*3/2) != 0) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		for (i = 0; i < mp->ma_size; i++) { | 
					
						
							|  |  |  | 			entry = &mp->ma_table[i]; | 
					
						
							|  |  |  | 			if (entry->me_value != NULL) { | 
					
						
							|  |  |  | 				Py_INCREF(entry->me_key); | 
					
						
							|  |  |  | 				Py_INCREF(entry->me_value); | 
					
						
							|  |  |  | 				insertdict(copy, entry->me_key, entry->me_hash, | 
					
						
							|  |  |  | 					   entry->me_value); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return (PyObject *)copy; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-11-05 10:18:44 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyDict_Size(mp) | 
					
						
							|  |  |  | 	PyObject *mp; | 
					
						
							| 
									
										
										
										
											1993-11-05 10:18:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (mp == NULL || !PyDict_Check(mp)) { | 
					
						
							|  |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											1993-11-23 17:53:17 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											1993-11-05 10:18:44 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	return ((dictobject *)mp)->ma_used; | 
					
						
							| 
									
										
										
										
											1993-11-05 10:18:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyDict_Keys(mp) | 
					
						
							|  |  |  | 	PyObject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (mp == NULL || !PyDict_Check(mp)) { | 
					
						
							|  |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	return dict_keys((dictobject *)mp, (PyObject *)NULL); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyDict_Values(mp) | 
					
						
							|  |  |  | 	PyObject *mp; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (mp == NULL || !PyDict_Check(mp)) { | 
					
						
							|  |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	return dict_values((dictobject *)mp, (PyObject *)NULL); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyDict_Items(mp) | 
					
						
							|  |  |  | 	PyObject *mp; | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (mp == NULL || !PyDict_Check(mp)) { | 
					
						
							|  |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	return dict_items((dictobject *)mp, (PyObject *)NULL); | 
					
						
							| 
									
										
										
										
											1993-05-19 14:50:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | #define NEWCMP
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef NEWCMP
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Subroutine which returns the smallest key in a for which b's value
 | 
					
						
							|  |  |  |    is different or absent.  The value is returned too, through the | 
					
						
							|  |  |  |    pval argument.  No reference counts are incremented. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | characterize(a, b, pval) | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	dictobject *a; | 
					
						
							|  |  |  | 	dictobject *b; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject **pval; | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *diff = NULL; | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*pval = NULL; | 
					
						
							|  |  |  | 	for (i = 0; i < a->ma_size; i++) { | 
					
						
							|  |  |  | 		if (a->ma_table[i].me_value != NULL) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			PyObject *key = a->ma_table[i].me_key; | 
					
						
							|  |  |  | 			PyObject *aval, *bval; | 
					
						
							| 
									
										
										
										
											1997-05-23 00:01:41 +00:00
										 |  |  | 			/* XXX What if PyObject_Compare raises an exception? */ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			if (diff != NULL && PyObject_Compare(key, diff) > 0) | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | 				continue; | 
					
						
							|  |  |  | 			aval = a->ma_table[i].me_value; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			bval = PyDict_GetItem((PyObject *)b, key); | 
					
						
							| 
									
										
										
										
											1997-05-23 00:01:41 +00:00
										 |  |  | 			/* XXX What if PyObject_Compare raises an exception? */ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			if (bval == NULL || PyObject_Compare(aval, bval) != 0) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | 				diff = key; | 
					
						
							|  |  |  | 				*pval = aval; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return diff; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_compare(a, b) | 
					
						
							|  |  |  | 	dictobject *a, *b; | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *adiff, *bdiff, *aval, *bval; | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | 	int res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Compare lengths first */ | 
					
						
							|  |  |  | 	if (a->ma_used < b->ma_used) | 
					
						
							|  |  |  | 		return -1;	/* a is shorter */ | 
					
						
							|  |  |  | 	else if (a->ma_used > b->ma_used) | 
					
						
							|  |  |  | 		return 1;	/* b is shorter */ | 
					
						
							|  |  |  | 	/* Same length -- check all keys */ | 
					
						
							|  |  |  | 	adiff = characterize(a, b, &aval); | 
					
						
							| 
									
										
										
										
											1997-05-23 00:01:41 +00:00
										 |  |  | 	if (PyErr_Occurred()) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | 	if (adiff == NULL) | 
					
						
							|  |  |  | 		return 0;	/* a is a subset with the same length */ | 
					
						
							|  |  |  | 	bdiff = characterize(b, a, &bval); | 
					
						
							| 
									
										
										
										
											1997-05-23 00:01:41 +00:00
										 |  |  | 	if (PyErr_Occurred()) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | 	/* bdiff == NULL would be impossible now */ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	res = PyObject_Compare(adiff, bdiff); | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | 	if (res == 0) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		res = PyObject_Compare(aval, bval); | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /* !NEWCMP */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_compare(a, b) | 
					
						
							|  |  |  | 	dictobject *a, *b; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *akeys, *bkeys; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	int i, n, res; | 
					
						
							|  |  |  | 	if (a == b) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	if (a->ma_used == 0) { | 
					
						
							|  |  |  | 		if (b->ma_used != 0) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		if (b->ma_used == 0) | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	akeys = dict_keys(a, (PyObject *)NULL); | 
					
						
							|  |  |  | 	bkeys = dict_keys(b, (PyObject *)NULL); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	if (akeys == NULL || bkeys == NULL) { | 
					
						
							|  |  |  | 		/* Oops, out of memory -- what to do? */ | 
					
						
							|  |  |  | 		/* For now, sort on address! */ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		Py_XDECREF(akeys); | 
					
						
							|  |  |  | 		Py_XDECREF(bkeys); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		if (a < b) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyList_Sort(akeys); | 
					
						
							|  |  |  | 	PyList_Sort(bkeys); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	n = a->ma_used < b->ma_used ? a->ma_used : b->ma_used; /* smallest */ | 
					
						
							|  |  |  | 	res = 0; | 
					
						
							|  |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		PyObject *akey, *bkey, *aval, *bval; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		long ahash, bhash; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		akey = PyList_GetItem(akeys, i); | 
					
						
							|  |  |  | 		bkey = PyList_GetItem(bkeys, i); | 
					
						
							|  |  |  | 		res = PyObject_Compare(akey, bkey); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		if (res != 0) | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #ifdef CACHE_HASH
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		if (!PyString_Check(akey) || | 
					
						
							|  |  |  | 		    (ahash = ((PyStringObject *) akey)->ob_shash) == -1) | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			ahash = PyObject_Hash(akey); | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 			if (ahash == -1) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 				PyErr_Clear(); /* Don't want errors here */ | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #ifdef CACHE_HASH
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		if (!PyString_Check(bkey) || | 
					
						
							|  |  |  | 		    (bhash = ((PyStringObject *) bkey)->ob_shash) == -1) | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 			bhash = PyObject_Hash(bkey); | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 			if (bhash == -1) | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 				PyErr_Clear(); /* Don't want errors here */ | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 		aval = lookdict(a, akey, ahash) -> me_value; | 
					
						
							|  |  |  | 		bval = lookdict(b, bkey, bhash) -> me_value; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		res = PyObject_Compare(aval, bval); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		if (res != 0) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (res == 0) { | 
					
						
							|  |  |  | 		if (a->ma_used < b->ma_used) | 
					
						
							|  |  |  | 			res = -1; | 
					
						
							|  |  |  | 		else if (a->ma_used > b->ma_used) | 
					
						
							|  |  |  | 			res = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	Py_DECREF(akeys); | 
					
						
							|  |  |  | 	Py_DECREF(bkeys); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-05 21:55:55 +00:00
										 |  |  | #endif /* !NEWCMP */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_has_key(mp, args) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *args; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *key; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	long hash; | 
					
						
							|  |  |  | 	register long ok; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyArg_Parse(args, "O", &key)) | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #ifdef CACHE_HASH
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyString_Check(key) || | 
					
						
							|  |  |  | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
					
						
							| 
									
										
										
										
											1993-10-22 12:04:32 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 		hash = PyObject_Hash(key); | 
					
						
							| 
									
										
										
										
											1997-01-23 19:39:29 +00:00
										 |  |  | 		if (hash == -1) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	ok = mp->ma_size != 0 && lookdict(mp, key, hash)->me_value != NULL; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	return PyInt_FromLong(ok); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-10-06 17:49:20 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | dict_get(mp, args) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							|  |  |  | 	PyObject *args; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *key; | 
					
						
							| 
									
										
										
										
											1997-10-20 17:26:25 +00:00
										 |  |  | 	PyObject *failobj = Py_None; | 
					
						
							| 
									
										
										
										
											1997-10-06 17:49:20 +00:00
										 |  |  | 	PyObject *val = NULL; | 
					
						
							|  |  |  | 	long hash; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTuple(args, "O|O", &key, &failobj)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1997-10-20 20:10:00 +00:00
										 |  |  | 	if (mp->ma_table == NULL) | 
					
						
							|  |  |  | 		goto finally; | 
					
						
							| 
									
										
										
										
											1997-10-06 17:49:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef CACHE_HASH
 | 
					
						
							|  |  |  | 	if (!PyString_Check(key) || | 
					
						
							|  |  |  | 	    (hash = ((PyStringObject *) key)->ob_shash) == -1) | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		hash = PyObject_Hash(key); | 
					
						
							|  |  |  | 		if (hash == -1) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	val = lookdict(mp, key, hash)->me_value; | 
					
						
							| 
									
										
										
										
											1997-10-20 17:26:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-10-20 20:10:00 +00:00
										 |  |  |   finally: | 
					
						
							| 
									
										
										
										
											1997-10-06 17:49:20 +00:00
										 |  |  | 	if (val == NULL) | 
					
						
							|  |  |  | 		val = failobj; | 
					
						
							|  |  |  | 	Py_INCREF(val); | 
					
						
							|  |  |  | 	return val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_clear(mp, args) | 
					
						
							|  |  |  | 	register dictobject *mp; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *args; | 
					
						
							| 
									
										
										
										
											1997-03-21 21:55:12 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	if (!PyArg_NoArgs(args)) | 
					
						
							| 
									
										
										
										
											1997-03-21 21:55:12 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyDict_Clear((PyObject *)mp); | 
					
						
							|  |  |  | 	Py_INCREF(Py_None); | 
					
						
							|  |  |  | 	return Py_None; | 
					
						
							| 
									
										
										
										
											1997-03-21 21:55:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyMethodDef mapp_methods[] = { | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	{"has_key",	(PyCFunction)dict_has_key}, | 
					
						
							|  |  |  | 	{"keys",	(PyCFunction)dict_keys}, | 
					
						
							| 
									
										
										
										
											1997-07-13 03:58:01 +00:00
										 |  |  | 	{"items",	(PyCFunction)dict_items}, | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	{"values",	(PyCFunction)dict_values}, | 
					
						
							| 
									
										
										
										
											1997-07-13 03:58:01 +00:00
										 |  |  | 	{"update",	(PyCFunction)dict_update}, | 
					
						
							|  |  |  | 	{"clear",	(PyCFunction)dict_clear}, | 
					
						
							|  |  |  | 	{"copy",	(PyCFunction)dict_copy}, | 
					
						
							| 
									
										
										
										
											1997-10-06 17:49:20 +00:00
										 |  |  | 	{"get",         (PyCFunction)dict_get, 1}, | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	{NULL,		NULL}		/* sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | dict_getattr(mp, name) | 
					
						
							|  |  |  | 	dictobject *mp; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	char *name; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	return Py_FindMethod(mapp_methods, (PyObject *)mp, name); | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyTypeObject PyDict_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(&PyType_Type) | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	0, | 
					
						
							| 
									
										
										
										
											1993-03-29 10:43:31 +00:00
										 |  |  | 	"dictionary", | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	sizeof(dictobject), | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	0, | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	(destructor)dict_dealloc, /*tp_dealloc*/ | 
					
						
							|  |  |  | 	(printfunc)dict_print, /*tp_print*/ | 
					
						
							|  |  |  | 	(getattrfunc)dict_getattr, /*tp_getattr*/ | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	0,			/*tp_setattr*/ | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	(cmpfunc)dict_compare, /*tp_compare*/ | 
					
						
							|  |  |  | 	(reprfunc)dict_repr, /*tp_repr*/ | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	0,			/*tp_as_number*/ | 
					
						
							|  |  |  | 	0,			/*tp_as_sequence*/ | 
					
						
							| 
									
										
										
										
											1997-05-13 21:02:11 +00:00
										 |  |  | 	&dict_as_mapping,	/*tp_as_mapping*/ | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-16 14:23:33 +00:00
										 |  |  | /* For backward compatibility with old dictionary interface */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PyDict_GetItemString(v, key) | 
					
						
							|  |  |  | 	PyObject *v; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	char *key; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-16 14:23:33 +00:00
										 |  |  | 	PyObject *kv, *rv; | 
					
						
							|  |  |  | 	kv = PyString_FromString(key); | 
					
						
							|  |  |  | 	if (kv == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	rv = PyDict_GetItem(v, kv); | 
					
						
							|  |  |  | 	Py_DECREF(kv); | 
					
						
							|  |  |  | 	return rv; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyDict_SetItemString(v, key, item) | 
					
						
							|  |  |  | 	PyObject *v; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	char *key; | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | 	PyObject *item; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-16 14:23:33 +00:00
										 |  |  | 	PyObject *kv; | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 	kv = PyString_FromString(key); | 
					
						
							|  |  |  | 	if (kv == NULL) | 
					
						
							| 
									
										
										
										
											1997-05-20 18:35:19 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											1997-09-29 23:31:11 +00:00
										 |  |  | 	PyString_InternInPlace(&kv); /* XXX Should we really? */ | 
					
						
							| 
									
										
										
										
											1997-05-16 14:23:33 +00:00
										 |  |  | 	err = PyDict_SetItem(v, kv, item); | 
					
						
							|  |  |  | 	Py_DECREF(kv); | 
					
						
							|  |  |  | 	return err; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											1997-05-02 03:12:38 +00:00
										 |  |  | PyDict_DelItemString(v, key) | 
					
						
							|  |  |  | 	PyObject *v; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | 	char *key; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-16 14:23:33 +00:00
										 |  |  | 	PyObject *kv; | 
					
						
							|  |  |  | 	int err; | 
					
						
							|  |  |  | 	kv = PyString_FromString(key); | 
					
						
							|  |  |  | 	if (kv == NULL) | 
					
						
							| 
									
										
										
										
											1997-05-20 18:35:19 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											1997-05-16 14:23:33 +00:00
										 |  |  | 	err = PyDict_DelItem(v, kv); | 
					
						
							|  |  |  | 	Py_DECREF(kv); | 
					
						
							|  |  |  | 	return err; | 
					
						
							| 
									
										
										
										
											1993-03-27 18:11:32 +00:00
										 |  |  | } |