blob: 7b47c3fb850143661c757310dcea1e12e32e0130 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Method object implementation */
33
Guido van Rossumc0b618a1997-05-02 03:12:38 +000034#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036#include "token.h"
37
38typedef struct {
Guido van Rossumc0b618a1997-05-02 03:12:38 +000039 PyObject_HEAD
40 PyMethodDef *m_ml;
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000041 PyObject *m_self;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000042} PyCFunctionObject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000044static PyCFunctionObject *free_list = NULL;
45
Guido van Rossumc0b618a1997-05-02 03:12:38 +000046PyObject *
47PyCFunction_New(ml, self)
48 PyMethodDef *ml;
49 PyObject *self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050{
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000051 PyCFunctionObject *op;
52 op = free_list;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053 if (op != NULL) {
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000054 free_list = (PyCFunctionObject *)(op->m_self);
55 op->ob_type = &PyCFunction_Type;
56 _Py_NewReference(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057 }
Guido van Rossum1f39c5c1997-08-05 02:11:41 +000058 else {
59 op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type);
60 if (op == NULL)
61 return NULL;
62 }
63 op->m_ml = ml;
64 Py_XINCREF(self);
65 op->m_self = self;
Guido van Rossumc0b618a1997-05-02 03:12:38 +000066 return (PyObject *)op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067}
68
Guido van Rossumc0b618a1997-05-02 03:12:38 +000069PyCFunction
70PyCFunction_GetFunction(op)
71 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000073 if (!PyCFunction_Check(op)) {
74 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 return NULL;
76 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000077 return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078}
79
Guido van Rossumc0b618a1997-05-02 03:12:38 +000080PyObject *
81PyCFunction_GetSelf(op)
82 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000084 if (!PyCFunction_Check(op)) {
85 PyErr_BadInternalCall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086 return NULL;
87 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000088 return ((PyCFunctionObject *)op) -> m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089}
90
Guido van Rossumc0602291991-12-16 13:07:24 +000091int
Guido van Rossumc0b618a1997-05-02 03:12:38 +000092PyCFunction_GetFlags(op)
93 PyObject *op;
Guido van Rossumc0602291991-12-16 13:07:24 +000094{
Guido van Rossumc0b618a1997-05-02 03:12:38 +000095 if (!PyCFunction_Check(op)) {
96 PyErr_BadInternalCall();
Guido van Rossumc0602291991-12-16 13:07:24 +000097 return -1;
98 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +000099 return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
Guido van Rossumc0602291991-12-16 13:07:24 +0000100}
101
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102/* Methods (the standard built-in methods, that is) */
103
104static void
105meth_dealloc(m)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000106 PyCFunctionObject *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000108 Py_XDECREF(m->m_self);
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000109 m->m_self = (PyObject *)free_list;
110 free_list = m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111}
112
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113static PyObject *
Guido van Rossumcab650d1995-01-07 12:34:58 +0000114meth_getattr(m, name)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115 PyCFunctionObject *m;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000116 char *name;
117{
118 if (strcmp(name, "__name__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000119 return PyString_FromString(m->m_ml->ml_name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000120 }
121 if (strcmp(name, "__doc__") == 0) {
122 char *doc = m->m_ml->ml_doc;
123 if (doc != NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124 return PyString_FromString(doc);
125 Py_INCREF(Py_None);
126 return Py_None;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000127 }
128 if (strcmp(name, "__self__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000129 PyObject *self;
130 if (PyEval_GetRestricted()) {
131 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum10393b11995-01-10 10:39:49 +0000132 "method.__self__ not accessible in restricted mode");
133 return NULL;
134 }
135 self = m->m_self;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000136 if (self == NULL)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000137 self = Py_None;
138 Py_INCREF(self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000139 return self;
140 }
141 if (strcmp(name, "__members__") == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000142 return Py_BuildValue("[sss]",
143 "__doc__", "__name__", "__self__");
Guido van Rossumcab650d1995-01-07 12:34:58 +0000144 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000145 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000146 return NULL;
147}
148
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000149static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150meth_repr(m)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000151 PyCFunctionObject *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152{
153 char buf[200];
154 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000155 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000157 sprintf(buf,
Guido van Rossumb3f72581993-05-21 19:56:10 +0000158 "<built-in method %.80s of %.80s object at %lx>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000159 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000160 (long)m->m_self);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000161 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162}
163
Guido van Rossum9bfef441993-03-29 10:43:31 +0000164static int
165meth_compare(a, b)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000166 PyCFunctionObject *a, *b;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000167{
168 if (a->m_self != b->m_self)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000169 return PyObject_Compare(a->m_self, b->m_self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000170 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000171 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000172 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000173 return -1;
174 else
175 return 1;
176}
177
178static long
179meth_hash(a)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000180 PyCFunctionObject *a;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000181{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000182 long x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000183 if (a->m_self == NULL)
184 x = 0;
185 else {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186 x = PyObject_Hash(a->m_self);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000187 if (x == -1)
188 return -1;
189 }
Guido van Rossumcab650d1995-01-07 12:34:58 +0000190 return x ^ (long) a->m_ml->ml_meth;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000191}
192
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000193PyTypeObject PyCFunction_Type = {
194 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000196 "builtin_function_or_method",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000197 sizeof(PyCFunctionObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000199 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000200 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000201 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000203 (cmpfunc)meth_compare, /*tp_compare*/
204 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205 0, /*tp_as_number*/
206 0, /*tp_as_sequence*/
207 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000208 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000210
Guido van Rossum69785031995-01-26 22:58:48 +0000211/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000212
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000213static PyObject *
Guido van Rossum69785031995-01-26 22:58:48 +0000214listmethodchain(chain)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215 PyMethodChain *chain;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000216{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000217 PyMethodChain *c;
218 PyMethodDef *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000219 int i, n;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000220 PyObject *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000221
222 n = 0;
223 for (c = chain; c != NULL; c = c->link) {
224 for (ml = c->methods; ml->ml_name != NULL; ml++)
225 n++;
226 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000227 v = PyList_New(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000228 if (v == NULL)
229 return NULL;
230 i = 0;
231 for (c = chain; c != NULL; c = c->link) {
232 for (ml = c->methods; ml->ml_name != NULL; ml++) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000233 PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
Guido van Rossum69785031995-01-26 22:58:48 +0000234 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000235 }
236 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 if (PyErr_Occurred()) {
238 Py_DECREF(v);
Guido van Rossum69785031995-01-26 22:58:48 +0000239 return NULL;
240 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000241 PyList_Sort(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000242 return v;
243}
244
Guido van Rossum69785031995-01-26 22:58:48 +0000245/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000246
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000247PyObject *
248Py_FindMethodInChain(chain, self, name)
249 PyMethodChain *chain;
250 PyObject *self;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000251 char *name;
252{
Guido van Rossume9c430f1991-10-20 20:21:15 +0000253 if (strcmp(name, "__methods__") == 0)
Guido van Rossum69785031995-01-26 22:58:48 +0000254 return listmethodchain(chain);
255 while (chain != NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000256 PyMethodDef *ml = chain->methods;
Guido van Rossum69785031995-01-26 22:58:48 +0000257 for (; ml->ml_name != NULL; ml++) {
258 if (name[0] == ml->ml_name[0] &&
259 strcmp(name+1, ml->ml_name+1) == 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000260 return PyCFunction_New(ml, self);
Guido van Rossum69785031995-01-26 22:58:48 +0000261 }
262 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000263 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000264 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000265 return NULL;
266}
Guido van Rossum69785031995-01-26 22:58:48 +0000267
268/* Find a method in a single method list */
269
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000270PyObject *
271Py_FindMethod(methods, self, name)
272 PyMethodDef *methods;
273 PyObject *self;
Guido van Rossum69785031995-01-26 22:58:48 +0000274 char *name;
275{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276 PyMethodChain chain;
Guido van Rossum69785031995-01-26 22:58:48 +0000277 chain.methods = methods;
278 chain.link = NULL;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000279 return Py_FindMethodInChain(&chain, self, name);
Guido van Rossum69785031995-01-26 22:58:48 +0000280}
Guido van Rossum1f39c5c1997-08-05 02:11:41 +0000281
282/* Clear out the free list */
283
284void
285PyCFunction_Fini()
286{
287 while (free_list) {
288 PyCFunctionObject *v = free_list;
289 free_list = (PyCFunctionObject *)(v->m_self);
290 PyMem_DEL(v);
291 }
292}