Initial revision
[blender.git] / source / blender / bpython / intern / BPY_constobject.c
1 /* 
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30 $Id$
31
32 This is code to emulate a readonly Dictionary/Class object 
33 for storage of Constants 
34
35 Inserting readonly values:
36
37 PyObject *constants = ConstObject_New();
38 insertConst(constants, "item", PyInt_FromInt(CONSTANT));
39 ...
40
41
42 Constant values are accessed in python by either:
43
44 c = module.Const.CONSTANT   
45
46    or
47
48 c = module.Const['CONSTANT']
49
50 */
51
52 #include "Python.h"
53 #include "BPY_macros.h"
54
55 #include "BPY_constobject.h"
56
57 #define Const_Check(v)       ((v)->ob_type == &Const_Type)
58
59
60 /* ----------------------------------------------------- */
61 /* Declarations for objects of type const */
62
63
64 PyTypeObject Const_Type;
65
66 /* PROTOS */
67
68
69
70 static constobject *
71 newconstobject()
72 {
73         constobject *self;
74         Const_Type.ob_type = &PyType_Type;
75         self = PyObject_NEW(constobject, &Const_Type);
76         if (self == NULL)
77                 return NULL;
78         self->dict = PyDict_New();      
79         return self;
80 }
81
82 char ConstObject_doc[] = "Readonly dictionary type\n\n\
83 This is used as a container for constants, which can be accessed by two ways:\n\
84 \n\
85     c = <ConstObject>.<attribute>\n\
86 \n\
87 or\n\
88     c = <ConstObject>['<attribute>']";
89
90 PyObject *ConstObject_New(void)
91 {
92         return (PyObject *) newconstobject();
93 }       
94
95 PyObject *const_repr(constobject *self) 
96 {
97         PyObject *repr;
98         repr = PyObject_Repr(self->dict);
99         return repr;
100 }
101
102 static void const_dealloc(PyObject *self) {
103         Py_DECREF(((constobject *)self)->dict);
104         PyMem_DEL(self);
105 }
106 static PyObject *
107 const_getattr(constobject *self, char *name)
108 {
109         PyObject *item;
110         if (STREQ(name, "__doc__")) {
111                 return PyString_FromString(ConstObject_doc);
112         }       
113         if (STREQ(name, "__members__")) {
114                 return PyDict_Keys(self->dict);
115         }       
116         item = PyDict_GetItemString(self->dict, name);  /* borrowed ref ! */
117         if (item)
118                 Py_INCREF(item);
119         if (!item) {
120                 PyErr_SetString(PyExc_AttributeError, name);
121         }
122         return item;
123 }
124
125 /* inserts a constant with name into the dictionary self */
126 void insertConst(PyObject *self, char *name, PyObject *cnst)
127 {
128         PyDict_SetItemString(((constobject *)self)->dict, name, cnst);
129 }
130
131
132 /* Code to access const objects as mappings */
133
134 static int
135 const_length(constobject *self)
136 {
137         return 0;
138 }
139
140 static PyObject *
141 const_subscript(constobject *self, PyObject *key)
142 {
143         PyObject *item;
144         item =  PyDict_GetItem(self->dict, key);        
145         if (item) 
146                 Py_INCREF(item);
147         return item;
148 }
149
150 static int
151 const_ass_sub(constobject *self, PyObject *v, PyObject *w)
152 {
153         /* no write access */
154         return 0;
155 }
156
157 static PyMappingMethods const_as_mapping = {
158         (inquiry)const_length,          /*mp_length*/
159         (binaryfunc)const_subscript,            /*mp_subscript*/
160         (objobjargproc)const_ass_sub,   /*mp_ass_subscript*/
161 };
162
163 /* -------------------------------------------------------- */
164
165 PyTypeObject Const_Type = {
166         PyObject_HEAD_INIT(NULL)
167         0,                              /*ob_size*/
168         "const",                        /*tp_name*/
169         sizeof(constobject),            /*tp_basicsize*/
170         0,                              /*tp_itemsize*/
171         /* methods */
172         (destructor)     const_dealloc, /*tp_dealloc*/
173         (printfunc)      0,   /*tp_print*/
174         (getattrfunc)    const_getattr, /*tp_getattr*/
175         (setattrfunc)    0,             /*tp_setattr*/
176         (cmpfunc)        0,             /*tp_compare*/
177         (reprfunc)       const_repr,             /*tp_repr*/
178                          0,             /*tp_as_number*/
179                          0,             /*tp_as_sequence*/
180                          &const_as_mapping,     /*tp_as_mapping*/
181                          0,                 /*tp_hash*/
182 };
183