Main Page | Class List | Directories | File List | Class Members | File Members

boolean.c

Go to the documentation of this file.
00001 /*
00002  Boolean extension, by Uche Ogbuji
00003  Copyright (c) 2001 Fourthought, Inc. USA.   All Rights Reserved.
00004  See  http://4suite.org/COPYRIGHT  for license and copyright information
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;  /* couldn't do it */
00172 }
00173 
00174 static PyObject *
00175 boolean_and(PyObject *o1, PyObject *o2)
00176 {
00177     /* FIXME: Check whether we need to conver the 1st arg.
00178        The Python/C docs don't help */
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     /* FIXME: Check whether we need to conver the 1st arg.
00191        The Python/C docs don't help */
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     /* FIXME: Check whether we need to conver the 1st arg.
00201        The Python/C docs don't help */
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,                 /* binaryfunc nb_add;       __add__ */
00239     0,                 /* binaryfunc nb_subtract;  __sub__ */
00240     0,                 /* binaryfunc nb_multiply;  __mul__ */
00241     0,                 /* binaryfunc nb_divide;    __div__ */
00242     0,                 /* binaryfunc nb_remainder; __mod__ */
00243     0,                 /* binaryfunc nb_divmod;    __divmod__ */
00244     0,                 /* ternaryfunc nb_power;    __pow__ */
00245     0,                 /* unaryfunc nb_negative;   __neg__ */
00246     0,                 /* unaryfunc nb_positive;   __pos__ */
00247     0,                 /* unaryfunc nb_absolute;   __abs__ */
00248     boolean_nonzero,   /* inquiry nb_nonzero;      __nonzero__ */
00249     0,                 /* unaryfunc nb_invert;     __invert__ */
00250     0,                 /* binaryfunc nb_lshift;    __lshift__ */
00251     0,                 /* binaryfunc nb_rshift;    __rshift__ */
00252     boolean_and,       /* binaryfunc nb_and;       __and__ */
00253     boolean_xor,       /* binaryfunc nb_xor;       __xor__ */
00254     boolean_or,        /* binaryfunc nb_or;        __or__ */
00255     boolean_coerce,    /* coercion nb_coerce;      __coerce__ */
00256     boolean_int,       /* unaryfunc nb_int;        __int__ */
00257     boolean_long,      /* unaryfunc nb_long;       __long__ */
00258     boolean_float,     /* unaryfunc nb_float;      __float__ */
00259     0,                 /* unaryfunc nb_oct;        __oct__ */
00260     0,                 /* unaryfunc nb_hex;        __hex__ */
00261 };
00262 
00263 static PyTypeObject PyBoolean_Type = {
00264     PyObject_HEAD_INIT(0)
00265     0,
00266     "boolean",
00267     sizeof(PyBooleanObject),
00268     0,
00269     boolean_dealloc,      /* tp_dealloc */
00270     0,                    /* tp_print */
00271     0,                    /* tp_getattr */
00272     0,                    /* tp_setattr */
00273     (cmpfunc)boolean_cmp, /* tp_compare */
00274     boolean_repr,         /* tp_repr */
00275     &boolean_as_number,   /* tp_as_number */
00276     0,                    /* tp_as_sequence */
00277     0,                    /* tp_as_mapping */
00278     0,                    /* tp_hash */
00279     0,                    /* tp_call */
00280     0,                    /* tp_str */
00281     0,                    /* tp_getattro */
00282     0,                    /* tp_setattro */
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 }

© sourcejam.com 2005-2008