blob: 53a0e9da1339fe46b1f85dbd24cbf71b6aec8156 [file] [log] [blame]
Guido van Rossum81daa321993-05-20 14:24:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum81daa321993-05-20 14:24: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 Rossum81daa321993-05-20 14:24: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 Rossum81daa321993-05-20 14:24: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 Rossum81daa321993-05-20 14:24: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 Rossum81daa321993-05-20 14:24:46 +000029
30******************************************************************/
31
Guido van Rossum0dfcf751996-08-12 22:00:53 +000032#ifdef SUPPORT_OBSOLETE_ACCESS /* This object type is no longer supported */
33
Guido van Rossum81daa321993-05-20 14:24:46 +000034/* Access object implementation */
35
Guido van Rossum234f9421993-06-17 12:35:49 +000036/* XXX TO DO LIST
Guido van Rossum234f9421993-06-17 12:35:49 +000037 - __init__ and __del__ (and all other similar methods)
Guido van Rossumb6775db1994-08-01 11:34:53 +000038 should be usable even when private, not ignored
Guido van Rossum234f9421993-06-17 12:35:49 +000039*/
40
Guido van Rossum81daa321993-05-20 14:24:46 +000041#include "allobjects.h"
Guido van Rossumed18fdc1993-07-11 19:55:34 +000042#include "ceval.h"
Guido van Rossum81daa321993-05-20 14:24:46 +000043#include "structmember.h"
44#include "modsupport.h" /* For getargs() etc. */
45
46typedef struct {
47 OB_HEAD
48 object *ac_value;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +000049 object *ac_owner;
Guido van Rossum81daa321993-05-20 14:24:46 +000050 typeobject *ac_type;
51 int ac_mode;
52} accessobject;
53
54/* Forward */
55static int typecheck PROTO((object *, typeobject *));
Guido van Rossumeb6b33a1993-05-25 09:38:27 +000056static int ownercheck PROTO((object *, object *, int, int));
Guido van Rossum81daa321993-05-20 14:24:46 +000057
58object *
Guido van Rossumeb6b33a1993-05-25 09:38:27 +000059newaccessobject(value, owner, type, mode)
Guido van Rossum81daa321993-05-20 14:24:46 +000060 object *value;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +000061 object *owner;
Guido van Rossum81daa321993-05-20 14:24:46 +000062 typeobject *type;
63 int mode;
64{
65 accessobject *ap;
Guido van Rossum81daa321993-05-20 14:24:46 +000066 if (!typecheck(value, type)) {
67 err_setstr(AccessError,
68 "access: initial value has inappropriate type");
69 return NULL;
70 }
71 ap = NEWOBJ(accessobject, &Accesstype);
72 if (ap == NULL)
73 return NULL;
74 XINCREF(value);
75 ap->ac_value = value;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +000076 XINCREF(owner);
77 ap->ac_owner = owner;
Guido van Rossum81daa321993-05-20 14:24:46 +000078 XINCREF(type);
79 ap->ac_type = (typeobject *)type;
80 ap->ac_mode = mode;
81 return (object *)ap;
82}
83
84object *
85cloneaccessobject(op)
86 object *op;
87{
88 register accessobject *ap;
89 if (!is_accessobject(op)) {
90 err_badcall();
91 return NULL;
92 }
93 ap = (accessobject *)op;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +000094 return newaccessobject(ap->ac_value, ap->ac_owner,
Guido van Rossum81daa321993-05-20 14:24:46 +000095 ap->ac_type, ap->ac_mode);
96}
97
98void
Guido van Rossumeb6b33a1993-05-25 09:38:27 +000099setaccessowner(op, owner)
Guido van Rossum81daa321993-05-20 14:24:46 +0000100 object *op;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000101 object *owner;
Guido van Rossum81daa321993-05-20 14:24:46 +0000102{
103 register accessobject *ap;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000104 if (!is_accessobject(op))
Guido van Rossum81daa321993-05-20 14:24:46 +0000105 return; /* XXX no error */
106 ap = (accessobject *)op;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000107 XDECREF(ap->ac_owner);
108 XINCREF(owner);
109 ap->ac_owner = owner;
Guido van Rossum81daa321993-05-20 14:24:46 +0000110}
111
Guido van Rossumb3f72581993-05-21 19:56:10 +0000112int
113hasaccessvalue(op)
114 object *op;
115{
116 if (!is_accessobject(op))
117 return 0;
118 return ((accessobject *)op)->ac_value != NULL;
119}
120
Guido van Rossum81daa321993-05-20 14:24:46 +0000121object *
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000122getaccessvalue(op, caller)
Guido van Rossum81daa321993-05-20 14:24:46 +0000123 object *op;
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000124 object *caller;
Guido van Rossum81daa321993-05-20 14:24:46 +0000125{
126 register accessobject *ap;
127 if (!is_accessobject(op)) {
128 err_badcall();
129 return NULL;
130 }
131 ap = (accessobject *)op;
132
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000133 if (!ownercheck(caller, ap->ac_owner, AC_R, ap->ac_mode)) {
Guido van Rossum81daa321993-05-20 14:24:46 +0000134 err_setstr(AccessError, "read access denied");
135 return NULL;
136 }
137
138 if (ap->ac_value == NULL) {
139 err_setstr(AccessError, "no current value");
140 return NULL;
141 }
142 INCREF(ap->ac_value);
143 return ap->ac_value;
144}
145
146int
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000147setaccessvalue(op, caller, value)
Guido van Rossum81daa321993-05-20 14:24:46 +0000148 object *op;
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000149 object *caller;
Guido van Rossum81daa321993-05-20 14:24:46 +0000150 object *value;
151{
152 register accessobject *ap;
153 if (!is_accessobject(op)) {
154 err_badcall();
155 return -1;
156 }
157 ap = (accessobject *)op;
158
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000159 if (!ownercheck(caller, ap->ac_owner, AC_W, ap->ac_mode)) {
Guido van Rossum81daa321993-05-20 14:24:46 +0000160 err_setstr(AccessError, "write access denied");
161 return -1;
162 }
163
164 if (!typecheck(value, ap->ac_type)) {
165 err_setstr(AccessError, "assign value of inappropriate type");
166 return -1;
167 }
168
169 if (value == NULL) { /* Delete it */
170 if (ap->ac_value == NULL) {
171 err_setstr(AccessError, "no current value");
172 return -1;
173 }
174 DECREF(ap->ac_value);
175 ap->ac_value = NULL;
176 return 0;
177 }
178 XDECREF(ap->ac_value);
179 INCREF(value);
180 ap->ac_value = value;
181 return 0;
182}
183
184static int
185typecheck(value, type)
186 object *value;
187 typeobject *type;
188{
189 object *x;
190 if (value == NULL || type == NULL)
191 return 1; /* No check */
192 if (value->ob_type == type)
193 return 1; /* Exact match */
194 if (type == &Anynumbertype) {
195 if (value->ob_type->tp_as_number == NULL)
196 return 0;
197 if (!is_instanceobject(value))
198 return 1;
199 /* For instances, make sure it really looks like a number */
200 x = getattr(value, "__sub__");
201 if (x == NULL) {
202 err_clear();
203 return 0;
204 }
205 DECREF(x);
206 return 1;
207 }
208 if (type == &Anysequencetype) {
209 if (value->ob_type->tp_as_sequence == NULL)
210 return 0;
211 if (!is_instanceobject(value))
212 return 1;
213 /* For instances, make sure it really looks like a sequence */
214 x = getattr(value, "__getslice__");
215 if (x == NULL) {
216 err_clear();
217 return 0;
218 }
219 DECREF(x);
220 return 1;
221 }
222 if (type == &Anymappingtype) {
223 if (value->ob_type->tp_as_mapping == NULL)
224 return 0;
225 if (!is_instanceobject(value))
226 return 1;
227 /* For instances, make sure it really looks like a mapping */
228 x = getattr(value, "__getitem__");
229 if (x == NULL) {
230 err_clear();
231 return 0;
232 }
233 DECREF(x);
234 return 1;
235 }
236 return 0;
237}
238
239static int
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000240isprivileged(caller)
241 object *caller;
242{
243 object *g;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000244 static char privileged[] = "__privileged__";
245 if (caller != NULL && hasattr(caller, privileged))
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000246 return 1;
247 g = getglobals();
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000248 if (g != NULL && dictlookup(g, privileged))
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000249 return 1;
250 return 0;
251}
252
253static int
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000254ownercheck(caller, owner, access, mode)
Guido van Rossum81daa321993-05-20 14:24:46 +0000255 object *caller;
256 object *owner;
257 int access;
258 int mode;
259{
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000260 int mask = AC_PUBLIC;
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000261 if (caller == owner || isprivileged(caller))
262 mask |= AC_PRIVATE | AC_PROTECTED;
263 else if (caller != NULL && owner != NULL &&
264 is_classobject(owner) && is_classobject(caller) &&
265 (issubclass(caller, owner) ||
266 issubclass(owner, caller)))
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000267 mask |= AC_PROTECTED;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000268 return access & mode & mask;
Guido van Rossum81daa321993-05-20 14:24:46 +0000269}
270
271/* Access methods */
272
273static void
274access_dealloc(ap)
275 accessobject *ap;
276{
277 XDECREF(ap->ac_value);
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000278 XDECREF(ap->ac_owner);
Guido van Rossum81daa321993-05-20 14:24:46 +0000279 XDECREF(ap->ac_type);
280 DEL(ap);
281}
282
283#define OFF(x) offsetof(accessobject, x)
284
285static struct memberlist access_memberlist[] = {
286 {"ac_value", T_OBJECT, OFF(ac_value)},
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000287 {"ac_owner", T_OBJECT, OFF(ac_owner)},
Guido van Rossum81daa321993-05-20 14:24:46 +0000288 {"ac_type", T_OBJECT, OFF(ac_type)},
289 {"ac_mode", T_INT, OFF(ac_mode)},
290 {NULL} /* Sentinel */
291};
292
293static object *
294access_getattr(ap, name)
295 accessobject *ap;
296 char *name;
297{
298 return getmember((char *)ap, access_memberlist, name);
299}
300
301static object *
302access_repr(ap)
303 accessobject *ap;
304{
305 char buf[300];
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000306 char buf2[20];
307 char *ownername;
Guido van Rossum81daa321993-05-20 14:24:46 +0000308 typeobject *type = ap->ac_type;
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000309 if (is_classobject(ap->ac_owner)) {
310 ownername =
311 getstringvalue(((classobject *)ap->ac_owner)->cl_name);
312 }
313 else {
314 sprintf(buf2, "0x%lx", (long)ap->ac_owner);
315 ownername = buf2;
316 }
Guido van Rossumb3f72581993-05-21 19:56:10 +0000317 sprintf(buf,
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000318 "<access object, value 0x%lx, owner %.100s, type %.100s, mode %04o>",
Guido van Rossumb3f72581993-05-21 19:56:10 +0000319 (long)(ap->ac_value),
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000320 ownername,
Guido van Rossum81daa321993-05-20 14:24:46 +0000321 type ? type->tp_name : "-",
322 ap->ac_mode);
323 return newstringobject(buf);
324}
325
326typeobject Accesstype = {
327 OB_HEAD_INIT(&Typetype)
328 0, /*ob_size*/
329 "access", /*tp_name*/
330 sizeof(accessobject), /*tp_size*/
331 0, /*tp_itemsize*/
332 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000333 (destructor)access_dealloc, /*tp_dealloc*/
Guido van Rossum81daa321993-05-20 14:24:46 +0000334 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000335 (getattrfunc)access_getattr, /*tp_getattr*/
Guido van Rossum81daa321993-05-20 14:24:46 +0000336 0, /*tp_setattr*/
337 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000338 (reprfunc)access_repr, /*tp_repr*/
Guido van Rossum81daa321993-05-20 14:24:46 +0000339 0, /*tp_as_number*/
340 0, /*tp_as_sequence*/
341 0, /*tp_as_mapping*/
342 0, /*tp_hash*/
343};
344
Guido van Rossumeb6b33a1993-05-25 09:38:27 +0000345
346/* Pseudo type objects to indicate collections of types */
Guido van Rossum81daa321993-05-20 14:24:46 +0000347
348/* XXX This should be replaced by a more general "subclassing"
349 XXX mechanism for type objects... */
350
351typeobject Anynumbertype = {
352 OB_HEAD_INIT(&Typetype)
353 0, /*ob_size*/
354 "*number*", /*tp_name*/
355};
356
357/* XXX Should really distinguish mutable and immutable sequences as well */
358
359typeobject Anysequencetype = {
360 OB_HEAD_INIT(&Typetype)
361 0, /*ob_size*/
362 "*sequence*", /*tp_name*/
363};
364
365typeobject Anymappingtype = {
366 OB_HEAD_INIT(&Typetype)
367 0, /*ob_size*/
368 "*mapping*", /*tp_name*/
369};
Guido van Rossum0dfcf751996-08-12 22:00:53 +0000370
371#endif /* SUPPORT_OBSOLETE_ACCESS */