blob: c33cea5cb52e36cac9d898566b033716a8b35764 [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) {
110 object *self = m->m_self;
111 if (self == NULL)
112 self = None;
113 INCREF(self);
114 return self;
115 }
116 if (strcmp(name, "__members__") == 0) {
117 return mkvalue("[sss]", "__doc__", "__name__", "__self__");
118 }
119 err_setstr(AttributeError, name);
120 return NULL;
121}
122
123static object *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124meth_repr(m)
125 methodobject *m;
126{
127 char buf[200];
128 if (m->m_self == NULL)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000129 sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 else
Guido van Rossum3f5da241990-12-20 15:06:42 +0000131 sprintf(buf,
Guido van Rossumb3f72581993-05-21 19:56:10 +0000132 "<built-in method %.80s of %.80s object at %lx>",
Guido van Rossumcab650d1995-01-07 12:34:58 +0000133 m->m_ml->ml_name, m->m_self->ob_type->tp_name,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000134 (long)m->m_self);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 return newstringobject(buf);
136}
137
Guido van Rossum9bfef441993-03-29 10:43:31 +0000138static int
139meth_compare(a, b)
140 methodobject *a, *b;
141{
142 if (a->m_self != b->m_self)
143 return cmpobject(a->m_self, b->m_self);
Guido van Rossumcab650d1995-01-07 12:34:58 +0000144 if (a->m_ml->ml_meth == b->m_ml->ml_meth)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000145 return 0;
Guido van Rossumcab650d1995-01-07 12:34:58 +0000146 if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000147 return -1;
148 else
149 return 1;
150}
151
152static long
153meth_hash(a)
154 methodobject *a;
155{
Guido van Rossumd7047b31995-01-02 19:07:15 +0000156 long x;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000157 if (a->m_self == NULL)
158 x = 0;
159 else {
160 x = hashobject(a->m_self);
161 if (x == -1)
162 return -1;
163 }
Guido van Rossumcab650d1995-01-07 12:34:58 +0000164 return x ^ (long) a->m_ml->ml_meth;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000165}
166
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167typeobject Methodtype = {
168 OB_HEAD_INIT(&Typetype)
169 0,
Guido van Rossum7066dd71992-09-17 17:54:56 +0000170 "builtin_function_or_method",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171 sizeof(methodobject),
172 0,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000173 (destructor)meth_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000174 0, /*tp_print*/
Guido van Rossumcab650d1995-01-07 12:34:58 +0000175 (getattrfunc)meth_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 0, /*tp_setattr*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000177 (cmpfunc)meth_compare, /*tp_compare*/
178 (reprfunc)meth_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179 0, /*tp_as_number*/
180 0, /*tp_as_sequence*/
181 0, /*tp_as_mapping*/
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000182 (hashfunc)meth_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183};
Guido van Rossum3f5da241990-12-20 15:06:42 +0000184
Guido van Rossumb73cc041993-11-01 16:28:59 +0000185static object *listmethods PROTO((struct methodlist *)); /* Forward */
Guido van Rossume9c430f1991-10-20 20:21:15 +0000186
187static object *
188listmethods(ml)
189 struct methodlist *ml;
190{
191 int i, n;
192 object *v;
193 for (n = 0; ml[n].ml_name != NULL; n++)
194 ;
195 v = newlistobject(n);
196 if (v != NULL) {
197 for (i = 0; i < n; i++)
198 setlistitem(v, i, newstringobject(ml[i].ml_name));
199 if (err_occurred()) {
200 DECREF(v);
201 v = NULL;
202 }
203 else {
204 sortlist(v);
205 }
206 }
207 return v;
208}
209
Guido van Rossum3f5da241990-12-20 15:06:42 +0000210/* Find a method in a module's method table.
211 Usually called from an object's getattr method. */
212
213object *
214findmethod(ml, op, name)
215 struct methodlist *ml;
216 object *op;
217 char *name;
218{
Guido van Rossume9c430f1991-10-20 20:21:15 +0000219 if (strcmp(name, "__methods__") == 0)
220 return listmethods(ml);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221 for (; ml->ml_name != NULL; ml++) {
222 if (strcmp(name, ml->ml_name) == 0)
Guido van Rossumcab650d1995-01-07 12:34:58 +0000223 return newmethodobject(ml, op);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000224 }
Guido van Rossumbd3a2e61991-12-10 13:58:49 +0000225 err_setstr(AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000226 return NULL;
227}