blob: cb09223884b30dfa6bdd21a2eedf75e314d20a05 [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 Rossum3f5da241990-12-20 15:06:42 +000034#include "allobjects.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 {
39 OB_HEAD
Guido van Rossumcab650d1995-01-07 12:34:58 +000040 struct methodlist *m_ml;
Guido van Rossumc0602291991-12-16 13:07:24 +000041 object *m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000042} methodobject;
43
44object *
Guido van Rossumcab650d1995-01-07 12:34:58 +000045newmethodobject(ml, self)
46 struct methodlist *ml;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047 object *self;
48{
49 methodobject *op = NEWOBJ(methodobject, &Methodtype);
50 if (op != NULL) {
Guido van Rossumcab650d1995-01-07 12:34:58 +000051 op->m_ml = ml;
52 XINCREF(self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053 op->m_self = self;
54 }
55 return (object *)op;
56}
57
58method
59getmethod(op)
60 object *op;
61{
62 if (!is_methodobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000063 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064 return NULL;
65 }
Guido van Rossumcab650d1995-01-07 12:34:58 +000066 return ((methodobject *)op) -> m_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067}
68
69object *
70getself(op)
71 object *op;
72{
73 if (!is_methodobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000074 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 return NULL;
76 }
77 return ((methodobject *)op) -> m_self;
78}
79
Guido van Rossumc0602291991-12-16 13:07:24 +000080int
Guido van Rossuma83f2701995-07-26 18:07:32 +000081getflags(op)
Guido van Rossumc0602291991-12-16 13:07:24 +000082 object *op;
83{
84 if (!is_methodobject(op)) {
85 err_badcall();
86 return -1;
87 }
Guido van Rossuma83f2701995-07-26 18:07:32 +000088 return ((methodobject *)op) -> m_ml -> ml_flags;
Guido van Rossumc0602291991-12-16 13:07:24 +000089}
90
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091/* Methods (the standard built-in methods, that is) */
92
93static void
94meth_dealloc(m)
95 methodobject *m;
96{
Guido van Rossumcab650d1995-01-07 12:34:58 +000097 XDECREF(m->m_self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098 free((char *)m);
99}
100
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101static object *
Guido van Rossumcab650d1995-01-07 12:34:58 +0000102meth_getattr(m, name)
103 methodobject *m;
104 char *name;
105{
106 if (strcmp(name, "__name__") == 0) {
107 return newstringobject(m->m_ml->ml_name);
108 }
109 if (strcmp(name, "__doc__") == 0) {
110 char *doc = m->m_ml->ml_doc;
111 if (doc != NULL)
112 return newstringobject(doc);
113 INCREF(None);
114 return None;
115 }
116 if (strcmp(name, "__self__") == 0) {
Guido van Rossum10393b11995-01-10 10:39:49 +0000117 object *self;
118 if (getrestricted()) {
119 err_setstr(RuntimeError,
120 "method.__self__ not accessible in restricted mode");
121 return NULL;
122 }
123 self = m->m_self;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000124 if (self == NULL)
125 self = None;
126 INCREF(self);
127 return self;
128 }
129 if (strcmp(name, "__members__") == 0) {
130 return mkvalue("[sss]", "__doc__", "__name__", "__self__");
131 }
132 err_setstr(AttributeError, name);
133 return NULL;
134}
135
136static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137meth_repr(m)
138 methodobject *m;
139{
140 char buf[200];
141 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000142 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000144 sprintf(buf,
Guido van Rossumb3f72581993-05-21 19:56:10 +0000145 "<built-in method %.80s of %.80s object at %lx>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000146 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000147 (long)m->m_self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 return newstringobject(buf);
149}
150
Guido van Rossum9bfef441993-03-29 10:43:31 +0000151static int
152meth_compare(a, b)
153 methodobject *a, *b;
154{
155 if (a->m_self != b->m_self)
156 return cmpobject(a->m_self, b->m_self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000157 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000158 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000159 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000160 return -1;
161 else
162 return 1;
163}
164
165static long
166meth_hash(a)
167 methodobject *a;
168{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000169 long x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000170 if (a->m_self == NULL)
171 x = 0;
172 else {
173 x = hashobject(a->m_self);
174 if (x == -1)
175 return -1;
176 }
Guido van Rossumcab650d1995-01-07 12:34:58 +0000177 return x ^ (long) a->m_ml->ml_meth;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000178}
179
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180typeobject Methodtype = {
181 OB_HEAD_INIT(&Typetype)
182 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000183 "builtin_function_or_method",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 sizeof(methodobject),
185 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000186 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000187 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000188 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000190 (cmpfunc)meth_compare, /*tp_compare*/
191 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 0, /*tp_as_number*/
193 0, /*tp_as_sequence*/
194 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000195 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000197
Guido van Rossum69785031995-01-26 22:58:48 +0000198/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000199
200static object *
Guido van Rossum69785031995-01-26 22:58:48 +0000201listmethodchain(chain)
202 struct methodchain *chain;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000203{
Guido van Rossum69785031995-01-26 22:58:48 +0000204 struct methodchain *c;
205 struct methodlist *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000206 int i, n;
207 object *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000208
209 n = 0;
210 for (c = chain; c != NULL; c = c->link) {
211 for (ml = c->methods; ml->ml_name != NULL; ml++)
212 n++;
213 }
Guido van Rossume9c430f1991-10-20 20:21:15 +0000214 v = newlistobject(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000215 if (v == NULL)
216 return NULL;
217 i = 0;
218 for (c = chain; c != NULL; c = c->link) {
219 for (ml = c->methods; ml->ml_name != NULL; ml++) {
220 setlistitem(v, i, newstringobject(ml->ml_name));
221 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000222 }
223 }
Guido van Rossum69785031995-01-26 22:58:48 +0000224 if (err_occurred()) {
225 DECREF(v);
226 return NULL;
227 }
228 sortlist(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000229 return v;
230}
231
Guido van Rossum69785031995-01-26 22:58:48 +0000232/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000233
234object *
Guido van Rossum69785031995-01-26 22:58:48 +0000235findmethodinchain(chain, self, name)
236 struct methodchain *chain;
237 object *self;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000238 char *name;
239{
Guido van Rossume9c430f1991-10-20 20:21:15 +0000240 if (strcmp(name, "__methods__") == 0)
Guido van Rossum69785031995-01-26 22:58:48 +0000241 return listmethodchain(chain);
242 while (chain != NULL) {
243 struct methodlist *ml = chain->methods;
244 for (; ml->ml_name != NULL; ml++) {
245 if (name[0] == ml->ml_name[0] &&
246 strcmp(name+1, ml->ml_name+1) == 0)
247 return newmethodobject(ml, self);
248 }
249 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250 }
Guido van Rossumbd3a2e61991-12-10 13:58:49 +0000251 err_setstr(AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000252 return NULL;
253}
Guido van Rossum69785031995-01-26 22:58:48 +0000254
255/* Find a method in a single method list */
256
257object *
258findmethod(methods, self, name)
259 struct methodlist *methods;
260 object *self;
261 char *name;
262{
263 struct methodchain chain;
264 chain.methods = methods;
265 chain.link = NULL;
266 return findmethodinchain(&chain, self, name);
267}