Use stdbool

This commit is contained in:
Kovid Goyal 2016-11-08 11:03:47 +05:30
parent 0a69f00ab4
commit d9daca8e36
3 changed files with 57 additions and 13 deletions

View file

@ -62,6 +62,11 @@ copy(Cursor *self, PyObject *args);
// Boilerplate {{{
BOOL_GETSET(Cursor, bold)
BOOL_GETSET(Cursor, italic)
BOOL_GETSET(Cursor, reverse)
BOOL_GETSET(Cursor, strikethrough)
static PyMemberDef members[] = {
{"x", T_OBJECT_EX, offsetof(Cursor, x), 0, "x"},
{"y", T_OBJECT_EX, offsetof(Cursor, y), 0, "y"},
@ -70,10 +75,6 @@ static PyMemberDef members[] = {
{"color", T_OBJECT_EX, offsetof(Cursor, color), 0, "color"},
{"hidden", T_OBJECT_EX, offsetof(Cursor, hidden), 0, "hidden"},
{"bold", T_UBYTE, offsetof(Cursor, bold), 0, "bold"},
{"italic", T_UBYTE, offsetof(Cursor, italic), 0, "italic"},
{"strikethrough", T_UBYTE, offsetof(Cursor, strikethrough), 0, "strikethrough"},
{"reverse", T_UBYTE, offsetof(Cursor, reverse), 0, "reverse"},
{"decoration", T_UBYTE, offsetof(Cursor, decoration), 0, "decoration"},
{"fg", T_UINT, offsetof(Cursor, fg), 0, "fg"},
{"bg", T_UINT, offsetof(Cursor, bg), 0, "bg"},
@ -81,6 +82,14 @@ static PyMemberDef members[] = {
{NULL} /* Sentinel */
};
static PyGetSetDef getseters[] = {
GETSET(bold)
GETSET(italic)
GETSET(reverse)
GETSET(strikethrough)
{NULL} /* Sentinel */
};
static PyMethodDef methods[] = {
METHOD(copy, METH_NOARGS)
{NULL} /* Sentinel */
@ -101,6 +110,7 @@ PyTypeObject Cursor_Type = {
.tp_richcompare = richcmp,
.tp_methods = methods,
.tp_members = members,
.tp_getset = getseters,
.tp_new = new,
};

View file

@ -9,6 +9,7 @@
#include <stdint.h>
#include <stdbool.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#define UNUSED __attribute__ ((unused))
@ -68,6 +69,13 @@ typedef unsigned int index_type;
#define METHOD(name, arg_type) {#name, (PyCFunction)name, arg_type, name##_doc},
#define BOOL_GETSET(type, x) \
static PyObject* x##_get(type *self, void UNUSED *closure) { PyObject *ans = self->x ? Py_True : Py_False; Py_INCREF(ans); return ans; } \
static int x##_set(type *self, PyObject *value, void UNUSED *closure) { if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete attribute"); return -1; } self->x = PyObject_IsTrue(value) ? true : false; return 0; }
#define GETSET(x) \
{#x, (getter) x##_get, (setter) x##_set, #x, NULL},
#define INIT_TYPE(type) \
int init_##type(PyObject *module) {\
if (PyType_Ready(&type##_Type) < 0) return 0; \
@ -100,18 +108,18 @@ typedef struct {
decoration_type *decoration_fg;
combining_type *combining_chars;
index_type xnum, ynum;
uint8_t continued;
uint8_t needs_free;
bool continued;
bool needs_free;
} Line;
typedef struct {
PyObject_HEAD
uint8_t *buf;
bool *buf;
index_type xnum, ynum, *line_map, *scratch;
index_type block_size;
uint8_t *continued_map;
bool *continued_map;
Line *line;
// Pointers into buf
@ -126,7 +134,8 @@ typedef struct {
PyObject_HEAD
PyObject *x, *y, *shape, *blink, *hidden, *color;
uint8_t bold, italic, reverse, strikethrough, decoration;
bool bold, italic, reverse, strikethrough;
uint8_t decoration;
uint32_t fg, bg, decoration_fg;
} Cursor;

View file

@ -52,7 +52,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
self->buf = PyMem_Calloc(xnum * ynum, CELL_SIZE);
self->line_map = PyMem_Calloc(ynum, sizeof(index_type));
self->scratch = PyMem_Calloc(ynum, sizeof(index_type));
self->continued_map = PyMem_Calloc(ynum, sizeof(uint8_t));
self->continued_map = PyMem_Calloc(ynum, sizeof(bool));
self->line = alloc_line();
if (self->buf == NULL || self->line_map == NULL || self->scratch == NULL || self->continued_map == NULL || self->line == NULL) {
PyErr_NoMemory();
@ -128,7 +128,7 @@ set_continued(LineBuf *self, PyObject *args) {
}
static inline int
allocate_line_storage(Line *line, uint8_t initialize) {
allocate_line_storage(Line *line, bool initialize) {
if (initialize) {
line->chars = PyMem_Calloc(line->xnum, sizeof(char_type));
line->colors = PyMem_Calloc(line->xnum, sizeof(color_type));
@ -209,7 +209,7 @@ index(LineBuf *self, PyObject *args) {
if (!PyArg_ParseTuple(args, "II", &top, &bottom)) return NULL;
if (top >= self->ynum - 1 || bottom >= self->ynum || bottom <= top) { PyErr_SetString(PyExc_ValueError, "Out of bounds"); return NULL; }
index_type old_top = self->line_map[top];
uint8_t old_cont = self->continued_map[top];
bool old_cont = self->continued_map[top];
for (index_type i = top; i < bottom; i++) {
self->line_map[i] = self->line_map[i + 1];
self->continued_map[i] = self->continued_map[i + 1];
@ -226,7 +226,7 @@ reverse_index(LineBuf *self, PyObject *args) {
if (!PyArg_ParseTuple(args, "II", &top, &bottom)) return NULL;
if (top >= self->ynum - 1 || bottom >= self->ynum || bottom <= top) { PyErr_SetString(PyExc_ValueError, "Out of bounds"); return NULL; }
index_type old_bottom = self->line_map[bottom];
uint8_t old_cont = self->continued_map[bottom];
bool old_cont = self->continued_map[bottom];
for (index_type i = bottom; i > top; i--) {
self->line_map[i] = self->line_map[i - 1];
self->continued_map[i] = self->continued_map[i - 1];
@ -308,17 +308,23 @@ delete_lines(LineBuf *self, PyObject *args) {
Py_RETURN_NONE;
}
// Boilerplate {{{
static PyObject*
copy_old(LineBuf *self, PyObject *y);
#define copy_old_doc "Copy the contents of the specified LineBuf to this LineBuf. Both must have the same number of columns, but the number of lines can be different, in which case the bottom lines are copied."
static PyObject*
rewrap(LineBuf *self, PyObject *val);
#define rewrap_doc "rewrap(new_screen) -> Fill up new screen (which can have different size to this screen) with as much of the contents of this screen as will fit. Return lines that overflow."
static PyMethodDef methods[] = {
METHOD(line, METH_O)
METHOD(clear_line, METH_O)
METHOD(copy_old, METH_O)
METHOD(copy_line_to, METH_VARARGS)
METHOD(create_line_copy, METH_O)
METHOD(rewrap, METH_O)
METHOD(clear, METH_NOARGS)
METHOD(set_attribute, METH_VARARGS)
METHOD(set_continued, METH_VARARGS)
@ -369,3 +375,22 @@ copy_old(LineBuf *self, PyObject *y) {
Py_RETURN_NONE;
}
static PyObject*
rewrap(LineBuf *self, PyObject *val) {
LineBuf* other;
if (!PyObject_TypeCheck(val, &LineBuf_Type)) { PyErr_SetString(PyExc_TypeError, "Not a LineBuf object"); return NULL; }
other = (LineBuf*) val;
PyObject *ret = PyList_New(0);
if (ret == NULL) return PyErr_NoMemory();
// Fast path
if (other->xnum == self->xnum && other->ynum == self->ynum) {
memcpy(other->line_map, self->line_map, sizeof(index_type) * self->ynum);
memcpy(other->continued_map, self->continued_map, sizeof(bool) * self->ynum);
memcpy(other->buf, self->buf, self->xnum * self->ynum * CELL_SIZE);
return ret;
}
return ret;
}