00001
00002
00003
00004
00005
00006
00007 #include "Python.h"
00008 #include <string.h>
00009 #include <ctype.h>
00010 #include <stdio.h>
00011
00012
00013 #if defined(_WIN32) || defined(__WIN32__)
00014 #include <float.h>
00015 #define NaN_Check(x) _isnan(x)
00016 #define Inf_Check(x) (_finite(x) && !_isnan(x))
00017 #else
00018 #include <math.h>
00019 #define NaN_Check(x) isnan(x)
00020 #define Inf_Check(x) isinf(x)
00021 #endif
00022
00023 #define Boolean_Check(v) ((v)->ob_type == &PyBoolean_Type)
00024 #define Boolean_Value(v) (((PyBooleanObject *)(v))->value)
00025
00026 typedef struct {
00027 PyObject_HEAD
00028 int value;
00029 } PyBooleanObject;
00030
00031 static PyBooleanObject *g_true;
00032 static PyBooleanObject *g_false;
00033
00034 static PyObject *g_true_string;
00035 static PyObject *g_false_string;
00036
00037 static PyTypeObject PyBoolean_Type;
00038
00039
00040 static PyObject *
00041 BooleanValue(PyObject *self, PyObject *args) {
00042 PyObject *obj;
00043 PyObject *str_func;
00044 PyBooleanObject *result = NULL;
00045
00046 if (!PyArg_ParseTuple(args, "O|O:BooleanValue", &obj, &str_func))
00047 return NULL;
00048
00049 if (Boolean_Check(obj)){
00050 result = (PyBooleanObject *)obj;
00051 }
00052 else if (PyFloat_Check(obj)) {
00053 if (NaN_Check(PyFloat_AS_DOUBLE(obj))) {
00054 result = g_false;
00055 }
00056 else {
00057 result = PyObject_IsTrue(obj) ? g_true : g_false;
00058 }
00059 }
00060 else if (PyNumber_Check(obj) || PySequence_Check(obj)){
00061 result = PyObject_IsTrue(obj) ? g_true : g_false;
00062 }
00063 else if (str_func) {
00064 obj = PyObject_CallFunction(str_func, "(O)", obj);
00065 if (!obj)
00066 return NULL;
00067 result = PyObject_IsTrue(obj) ? g_true : g_false;
00068 Py_DECREF(obj);
00069 }
00070 else {
00071 result = g_false;
00072 }
00073 Py_INCREF(result);
00074 return (PyObject *)result;
00075 }
00076
00077 static int
00078 pyobj_as_boolean_int(PyObject *obj) {
00079 if (Boolean_Check(obj))
00080 return Boolean_Value((PyBooleanObject *)obj);
00081 else if (PyNumber_Check(obj) || PySequence_Check(obj))
00082 return PyObject_IsTrue(obj) ? 1 : 0;
00083 else
00084 return 0;
00085 }
00086
00087 static PyObject *
00088 IsBooleanType(PyObject *self, PyObject *args) {
00089 PyObject *obj;
00090 PyObject *result = NULL;
00091
00092 if (!PyArg_ParseTuple(args, "O:IsBooleanType", &obj))
00093 return NULL;
00094
00095 if (Boolean_Check(obj))
00096 result = Py_True;
00097 else
00098 result = Py_False;
00099 Py_INCREF(result);
00100 return result;
00101 }
00102
00103 static PyBooleanObject *
00104 boolean_NEW(int initval)
00105 {
00106 PyBooleanObject *object = PyObject_NEW(PyBooleanObject, &PyBoolean_Type);
00107 object->value = initval;
00108 return object;
00109 }
00110
00111 static void
00112 boolean_dealloc(PyObject *self)
00113 {
00114 PyMem_DEL(self);
00115 }
00116
00117 static int
00118 boolean_cmp(PyObject *o1, PyObject *o2){
00119 int result = -1;
00120 PyBooleanObject *b1;
00121 PyBooleanObject *b2;
00122
00123 if (Boolean_Check(o1) && Boolean_Check(o2)) {
00124 b1 = (PyBooleanObject *)o1;
00125 b2 = (PyBooleanObject *)o2;
00126 result = !(Boolean_Value(o1) == Boolean_Value(o2));
00127 }
00128 else if (Boolean_Check(o1)) {
00129 b1 = (PyBooleanObject *)o1;
00130 result = !(Boolean_Value(o1) == pyobj_as_boolean_int(o2));
00131 }
00132 else if (Boolean_Check(o2)) {
00133 b2 = (PyBooleanObject *)o2;
00134 result = !(Boolean_Value(o2) == pyobj_as_boolean_int(o1));
00135 }
00136 return result;
00137 }
00138
00139 static PyObject *
00140 boolean_repr(PyObject *self)
00141 {
00142 PyObject *result;
00143
00144 if (Boolean_Value((PyBooleanObject *)self))
00145 result = g_true_string;
00146 else
00147 result = g_false_string;
00148 Py_INCREF(result);
00149 return result;
00150 }
00151
00152 static int
00153 boolean_coerce(PyObject **v, PyObject **w)
00154 {
00155 PyObject *newv, *neww;
00156
00157 if ((*v)->ob_type == (*w)->ob_type){
00158 Py_INCREF(*v);
00159 Py_INCREF(*w);
00160 return 0;
00161 }
00162 newv = PyNumber_Int(*v);
00163 neww = PyNumber_Int(*w);
00164 if (newv && neww){
00165 *v = newv;
00166 *w = neww;
00167 return 0;
00168 }
00169 Py_XDECREF(newv);
00170 Py_XDECREF(neww);
00171 return -1;
00172 }
00173
00174 static PyObject *
00175 boolean_and(PyObject *o1, PyObject *o2)
00176 {
00177
00178
00179 int lhs = pyobj_as_boolean_int(o1), rhs = pyobj_as_boolean_int(o2);
00180 PyObject *result = NULL;
00181
00182 result = PyInt_FromLong((long)(lhs && rhs));
00183 Py_INCREF(result);
00184 return result;
00185 }
00186
00187 static PyObject *
00188 boolean_or(PyObject *o1, PyObject *o2)
00189 {
00190
00191
00192 int lhs = pyobj_as_boolean_int(o1), rhs = pyobj_as_boolean_int(o2);
00193
00194 return PyInt_FromLong((long)(lhs || rhs));
00195 }
00196
00197 static PyObject *
00198 boolean_xor(PyObject *o1, PyObject *o2)
00199 {
00200
00201
00202 int lhs = pyobj_as_boolean_int(o1), rhs = pyobj_as_boolean_int(o2);
00203
00204 return PyInt_FromLong((long)(lhs ^ rhs));
00205 }
00206
00207 static int
00208 boolean_nonzero(PyObject *o)
00209 {
00210 return Boolean_Value((PyBooleanObject *)o);
00211 }
00212
00213 static PyObject *
00214 boolean_int(PyObject *o)
00215 {
00216 PyBooleanObject *obj = (PyBooleanObject *)o;
00217
00218 return PyInt_FromLong((long)Boolean_Value(obj));
00219 }
00220
00221 static PyObject *
00222 boolean_long(PyObject *o)
00223 {
00224 PyBooleanObject *obj = (PyBooleanObject *)o;
00225
00226 return PyLong_FromLong((long)Boolean_Value(obj));
00227 }
00228
00229 static PyObject *
00230 boolean_float(PyObject *o)
00231 {
00232 PyBooleanObject *obj = (PyBooleanObject *)o;
00233
00234 return PyFloat_FromDouble((double)Boolean_Value(obj));
00235 }
00236
00237 static PyNumberMethods boolean_as_number = {
00238 0,
00239 0,
00240 0,
00241 0,
00242 0,
00243 0,
00244 0,
00245 0,
00246 0,
00247 0,
00248 boolean_nonzero,
00249 0,
00250 0,
00251 0,
00252 boolean_and,
00253 boolean_xor,
00254 boolean_or,
00255 boolean_coerce,
00256 boolean_int,
00257 boolean_long,
00258 boolean_float,
00259 0,
00260 0,
00261 };
00262
00263 static PyTypeObject PyBoolean_Type = {
00264 PyObject_HEAD_INIT(0)
00265 0,
00266 "boolean",
00267 sizeof(PyBooleanObject),
00268 0,
00269 boolean_dealloc,
00270 0,
00271 0,
00272 0,
00273 (cmpfunc)boolean_cmp,
00274 boolean_repr,
00275 &boolean_as_number,
00276 0,
00277 0,
00278 0,
00279 0,
00280 0,
00281 0,
00282 0,
00283 };
00284
00285 static PyMethodDef booleanMethods[] = {
00286 { "BooleanValue", BooleanValue, METH_VARARGS },
00287 { "IsBooleanType", IsBooleanType, METH_VARARGS },
00288 { NULL, NULL }
00289 };
00290
00291 DL_EXPORT(void)
00292 initboolean(void) {
00293 PyObject *m;
00294
00295 m = Py_InitModule("boolean", booleanMethods);
00296
00297 PyBoolean_Type.ob_type = &PyType_Type;
00298 Py_INCREF(&PyBoolean_Type);
00299 PyModule_AddObject(m, "BooleanType", (PyObject *)&PyBoolean_Type);
00300
00301 if (g_true_string == NULL)
00302 g_true_string = PyString_FromString("true");
00303 if (g_false_string == NULL)
00304 g_false_string = PyString_FromString("false");
00305
00306 if (g_true == NULL)
00307 g_true = boolean_NEW(1);
00308 if (g_false == NULL)
00309 g_false = boolean_NEW(0);
00310
00311 Py_INCREF(g_true);
00312 PyModule_AddObject(m, "true", (PyObject *)g_true);
00313 Py_INCREF(g_false);
00314 PyModule_AddObject(m, "false", (PyObject *)g_false);
00315
00316 return;
00317 }