blob: d9daf2349d35ae50916eefc572c2e4b142ba4580 [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
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Method object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000029#include "token.h"
30
31typedef struct {
32 OB_HEAD
Guido van Rossumcab650d1995-01-07 12:34:58 +000033 struct methodlist *m_ml;
Guido van Rossumc0602291991-12-16 13:07:24 +000034 object *m_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035} methodobject;
36
37object *
Guido van Rossumcab650d1995-01-07 12:34:58 +000038newmethodobject(ml, self)
39 struct methodlist *ml;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000040 object *self;
41{
42 methodobject *op = NEWOBJ(methodobject, &Methodtype);
43 if (op != NULL) {
Guido van Rossumcab650d1995-01-07 12:34:58 +000044 op->m_ml = ml;
45 XINCREF(self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046 op->m_self = self;
47 }
48 return (object *)op;
49}
50
51method
52getmethod(op)
53 object *op;
54{
55 if (!is_methodobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000056 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057 return NULL;
58 }
Guido van Rossumcab650d1995-01-07 12:34:58 +000059 return ((methodobject *)op) -> m_ml -> ml_meth;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060}
61
62object *
63getself(op)
64 object *op;
65{
66 if (!is_methodobject(op)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +000067 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068 return NULL;
69 }
70 return ((methodobject *)op) -> m_self;
71}
72
Guido van Rossumc0602291991-12-16 13:07:24 +000073int
74getvarargs(op)
75 object *op;
76{
77 if (!is_methodobject(op)) {
78 err_badcall();
79 return -1;
80 }
Guido van Rossumcab650d1995-01-07 12:34:58 +000081 return ((methodobject *)op) -> m_ml -> ml_flags & METH_VARARGS;
Guido van Rossumc0602291991-12-16 13:07:24 +000082}
83
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084/* Methods (the standard built-in methods, that is) */
85
86static void
87meth_dealloc(m)
88 methodobject *m;
89{
Guido van Rossumcab650d1995-01-07 12:34:58 +000090 XDECREF(m->m_self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 free((char *)m);
92}
93
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094static object *
Guido van Rossumcab650d1995-01-07 12:34:58 +000095meth_getattr(m, name)
96 methodobject *m;
97 char *name;
98{
99 if (strcmp(name, "__name__") == 0) {
100 return newstringobject(m->m_ml->ml_name);
101 }
102 if (strcmp(name, "__doc__") == 0) {
103 char *doc = m->m_ml->ml_doc;
104 if (doc != NULL)
105 return newstringobject(doc);
106 INCREF(None);
107 return None;
108 }
109 if (strcmp(name, "__self__") == 0) {
Guido van Rossum10393b11995-01-10 10:39:49 +0000110 object *self;
111 if (getrestricted()) {
112 err_setstr(RuntimeError,
113 "method.__self__ not accessible in restricted mode");
114 return NULL;
115 }
116 self = m->m_self;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000117 if (self == NULL)
118 self = None;
119 INCREF(self);
120 return self;
121 }
122 if (strcmp(name, "__members__") == 0) {
123 return mkvalue("[sss]", "__doc__", "__name__", "__self__");
124 }
125 err_setstr(AttributeError, name);
126 return NULL;
127}
128
129static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130meth_repr(m)
131 methodobject *m;
132{
133 char buf[200];
134 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000135 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000137 sprintf(buf,
Guido van Rossumb3f72581993-05-21 19:56:10 +0000138 "<built-in method %.80s of %.80s object at %lx>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000139 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000140 (long)m->m_self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141 return newstringobject(buf);
142}
143
Guido van Rossum9bfef441993-03-29 10:43:31 +0000144static int
145meth_compare(a, b)
146 methodobject *a, *b;
147{
148 if (a->m_self != b->m_self)
149 return cmpobject(a->m_self, b->m_self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000150 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000151 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000152 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000153 return -1;
154 else
155 return 1;
156}
157
158static long
159meth_hash(a)
160 methodobject *a;
161{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000162 long x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000163 if (a->m_self == NULL)
164 x = 0;
165 else {
166 x = hashobject(a->m_self);
167 if (x == -1)
168 return -1;
169 }
Guido van Rossumcab650d1995-01-07 12:34:58 +0000170 return x ^ (long) a->m_ml->ml_meth;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000171}
172
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173typeobject Methodtype = {
174 OB_HEAD_INIT(&Typetype)
175 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000176 "builtin_function_or_method",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177 sizeof(methodobject),
178 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000179 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000180 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000181 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000183 (cmpfunc)meth_compare, /*tp_compare*/
184 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185 0, /*tp_as_number*/
186 0, /*tp_as_sequence*/
187 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000188 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000190
Guido van Rossum69785031995-01-26 22:58:48 +0000191/* List all methods in a chain -- helper for findmethodinchain */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000192
193static object *
Guido van Rossum69785031995-01-26 22:58:48 +0000194listmethodchain(chain)
195 struct methodchain *chain;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000196{
Guido van Rossum69785031995-01-26 22:58:48 +0000197 struct methodchain *c;
198 struct methodlist *ml;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000199 int i, n;
200 object *v;
Guido van Rossum69785031995-01-26 22:58:48 +0000201
202 n = 0;
203 for (c = chain; c != NULL; c = c->link) {
204 for (ml = c->methods; ml->ml_name != NULL; ml++)
205 n++;
206 }
Guido van Rossume9c430f1991-10-20 20:21:15 +0000207 v = newlistobject(n);
Guido van Rossum69785031995-01-26 22:58:48 +0000208 if (v == NULL)
209 return NULL;
210 i = 0;
211 for (c = chain; c != NULL; c = c->link) {
212 for (ml = c->methods; ml->ml_name != NULL; ml++) {
213 setlistitem(v, i, newstringobject(ml->ml_name));
214 i++;
Guido van Rossume9c430f1991-10-20 20:21:15 +0000215 }
216 }
Guido van Rossum69785031995-01-26 22:58:48 +0000217 if (err_occurred()) {
218 DECREF(v);
219 return NULL;
220 }
221 sortlist(v);
Guido van Rossume9c430f1991-10-20 20:21:15 +0000222 return v;
223}
224
Guido van Rossum69785031995-01-26 22:58:48 +0000225/* Find a method in a method chain */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000226
227object *
Guido van Rossum69785031995-01-26 22:58:48 +0000228findmethodinchain(chain, self, name)
229 struct methodchain *chain;
230 object *self;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000231 char *name;
232{
Guido van Rossume9c430f1991-10-20 20:21:15 +0000233 if (strcmp(name, "__methods__") == 0)
Guido van Rossum69785031995-01-26 22:58:48 +0000234 return listmethodchain(chain);
235 while (chain != NULL) {
236 struct methodlist *ml = chain->methods;
237 for (; ml->ml_name != NULL; ml++) {
238 if (name[0] == ml->ml_name[0] &&
239 strcmp(name+1, ml->ml_name+1) == 0)
240 return newmethodobject(ml, self);
241 }
242 chain = chain->link;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000243 }
Guido van Rossumbd3a2e61991-12-10 13:58:49 +0000244 err_setstr(AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000245 return NULL;
246}
Guido van Rossum69785031995-01-26 22:58:48 +0000247
248/* Find a method in a single method list */
249
250object *
251findmethod(methods, self, name)
252 struct methodlist *methods;
253 object *self;
254 char *name;
255{
256 struct methodchain chain;
257 chain.methods = methods;
258 chain.link = NULL;
259 return findmethodinchain(&chain, self, name);
260}