/* Boolean type, a subtype of int */

#include "Python.h"

/* We need to define bool_print to override int_print */

static int
bool_print(PyBoolObject *self, FILE *fp, int flags)
{
	fputs(self->ob_ival == 0 ? "False" : "True", fp);
	return 0;
}

/* We define bool_repr to return "False" or "True" */

static PyObject *false_str = NULL;
static PyObject *true_str = NULL;

static PyObject *
bool_repr(PyBoolObject *self)
{
	PyObject *s;

	if (self->ob_ival)
		s = true_str ? true_str :
			(true_str = PyString_InternFromString("True"));
	else
		s = false_str ? false_str :
			(false_str = PyString_InternFromString("False"));
	Py_XINCREF(s);
	return s;
}

/* Function to return a bool from a C long */

PyObject *PyBool_FromLong(long ok)
{
	PyObject *result;

	if (ok)
		result = Py_True;
	else
		result = Py_False;
	Py_INCREF(result);
	return result;
}

/* We define bool_new to always return either Py_True or Py_False */

static PyObject *
bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	static char *kwlist[] = {"x", 0};
	PyObject *x = Py_False;
	long ok;

	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", kwlist, &x))
		return NULL;
	ok = PyObject_IsTrue(x);
	if (ok < 0)
		return NULL;
	return PyBool_FromLong(ok);
}

/* Arithmetic operations redefined to return bool if both args are bool. */

static PyObject *
bool_and(PyObject *a, PyObject *b)
{
	if (!PyBool_Check(a) || !PyBool_Check(b))
		return PyInt_Type.tp_as_number->nb_and(a, b);
	return PyBool_FromLong(
		((PyBoolObject *)a)->ob_ival & ((PyBoolObject *)b)->ob_ival);
}

static PyObject *
bool_or(PyObject *a, PyObject *b)
{
	if (!PyBool_Check(a) || !PyBool_Check(b))
		return PyInt_Type.tp_as_number->nb_or(a, b);
	return PyBool_FromLong(
		((PyBoolObject *)a)->ob_ival | ((PyBoolObject *)b)->ob_ival);
}

static PyObject *
bool_xor(PyObject *a, PyObject *b)
{
	if (!PyBool_Check(a) || !PyBool_Check(b))
		return PyInt_Type.tp_as_number->nb_xor(a, b);
	return PyBool_FromLong(
		((PyBoolObject *)a)->ob_ival ^ ((PyBoolObject *)b)->ob_ival);
}

/* Doc string */

PyDoc_STRVAR(bool_doc,
"bool(x) -> bool\n\
\n\
Returns True when the argument x is true, False otherwise.\n\
The builtins True and False are the only two instances of the class bool.\n\
The class bool is a subclass of the class int, and cannot be subclassed.");

/* Arithmetic methods -- only so we can override &, |, ^. */

static PyNumberMethods bool_as_number = {
	0,			/* nb_add */
	0,			/* nb_subtract */
	0,			/* nb_multiply */
	0,			/* nb_remainder */
	0,			/* nb_divmod */
	0,			/* nb_power */
	0,			/* nb_negative */
	0,			/* nb_positive */
	0,			/* nb_absolute */
	0,			/* nb_bool */
	0,			/* nb_invert */
	0,			/* nb_lshift */
	0,			/* nb_rshift */
	bool_and,		/* nb_and */
	bool_xor,		/* nb_xor */
	bool_or,		/* nb_or */
	0,			/* nb_coerce */
	0,			/* nb_int */
	0,			/* nb_long */
	0,			/* nb_float */
	0,			/* nb_oct */
	0,		 	/* nb_hex */
	0,			/* nb_inplace_add */
	0,			/* nb_inplace_subtract */
	0,			/* nb_inplace_multiply */
	0,			/* nb_inplace_remainder */
	0,			/* nb_inplace_power */
	0,			/* nb_inplace_lshift */
	0,			/* nb_inplace_rshift */
	0,			/* nb_inplace_and */
	0,			/* nb_inplace_xor */
	0,			/* nb_inplace_or */
	0,			/* nb_floor_divide */
	0,			/* nb_true_divide */
	0,			/* nb_inplace_floor_divide */
	0,			/* nb_inplace_true_divide */
};

/* The type object for bool.  Note that this cannot be subclassed! */

PyTypeObject PyBool_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,
	"bool",
	sizeof(PyIntObject),
	0,
	0,					/* tp_dealloc */
	(printfunc)bool_print,			/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	(reprfunc)bool_repr,			/* tp_repr */
	&bool_as_number,			/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
        0,					/* tp_call */
        (reprfunc)bool_repr,			/* tp_str */
	0,					/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
	bool_doc,				/* tp_doc */
	0,					/* tp_traverse */
	0,					/* tp_clear */
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	0,					/* tp_methods */
	0,					/* tp_members */
	0,					/* tp_getset */
	&PyInt_Type,				/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	0,					/* tp_init */
	0,					/* tp_alloc */
	bool_new,				/* tp_new */
};

/* The objects representing bool values False and True */

/* Named Zero for link-level compatibility */
PyIntObject _Py_ZeroStruct = {
	PyObject_HEAD_INIT(&PyBool_Type)
	0
};

PyIntObject _Py_TrueStruct = {
	PyObject_HEAD_INIT(&PyBool_Type)
	1
};
