Migrate history.c

This commit is contained in:
Kovid Goyal 2017-08-28 14:54:32 +05:30
parent 052fd46ff9
commit 564010c7cd
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 45 additions and 44 deletions

View File

@ -155,10 +155,11 @@ PyTypeObject LineBuf_Type;
typedef struct {
PyObject_HEAD
uint32_t *buf;
Cell *buf;
index_type xnum, ynum;
Line *line;
index_type start_of_data, count;
bool *continued_map;
} HistoryBuf;
PyTypeObject HistoryBuf_Type;

View File

@ -6,15 +6,12 @@
*/
#include "data-types.h"
#include "lineops.h"
#include <structmember.h>
#define CELL_FIELD_COUNT_H (CELL_FIELD_COUNT + 1)
#define CELL_SIZE_H (CELL_FIELD_COUNT_H * 4)
static inline uint32_t*
start_of(HistoryBuf *self, index_type num) {
// Pointer to the start of the line with index (buffer position) num
return self->buf + CELL_FIELD_COUNT_H * num * self->xnum;
static inline Cell*
lineptr(HistoryBuf *linebuf, index_type y) {
return linebuf->buf + y * linebuf->xnum;
}
static PyObject *
@ -33,17 +30,17 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
if (self != NULL) {
self->xnum = xnum;
self->ynum = ynum;
self->buf = (uint32_t*)PyMem_Calloc(xnum * ynum, CELL_SIZE_H);
self->buf = PyMem_Calloc(xnum * ynum, sizeof(Cell));
self->continued_map = PyMem_Calloc(ynum, sizeof(bool));
self->line = alloc_line();
if (self->buf == NULL || self->line == NULL) {
if (self->buf == NULL || self->line == NULL || self->continued_map) {
PyErr_NoMemory();
PyMem_Free(self->buf); Py_CLEAR(self->line);
PyMem_Free(self->buf); Py_CLEAR(self->line); PyMem_Free(self->continued_map);
Py_CLEAR(self);
} else {
self->line->xnum = xnum;
for(index_type y = 0; y < self->ynum; y++) {
self->line->chars = start_of(self, y) + 1;
for (index_type i = 0; i < self->xnum; i++) self->line->chars[i] = (1 << ATTRS_SHIFT) | BLANK_CHAR;
clear_chars_in_line(lineptr(self, y), self->xnum, BLANK_CHAR);
}
}
}
@ -55,6 +52,7 @@ static void
dealloc(HistoryBuf* self) {
Py_CLEAR(self->line);
PyMem_Free(self->buf);
PyMem_Free(self->continued_map);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@ -70,13 +68,8 @@ index_of(HistoryBuf *self, index_type lnum) {
static inline void
init_line(HistoryBuf *self, index_type num, Line *l) {
// Initialize the line l, setting its pointer to the offsets for the line at index (buffer position) num
uint32_t *start_ptr = start_of(self, num);
l->continued = (bool)(*start_ptr);
l->chars = (char_type*)(start_ptr + 1);
l->fg_colors = (color_type*)(l->chars + self->xnum);
l->bg_colors = (color_type*)(l->fg_colors + self->xnum);
l->decoration_fg = (color_type*)(l->bg_colors + self->xnum);
l->combining_chars = (combining_type*)(l->decoration_fg + self->xnum);
l->cells = lineptr(self, num);
l->continued = self->continued_map[num];
}
void
@ -84,8 +77,8 @@ historybuf_init_line(HistoryBuf *self, index_type lnum, Line *l) {
init_line(self, index_of(self, lnum), l);
}
static inline
index_type historybuf_push(HistoryBuf *self) {
static inline index_type
historybuf_push(HistoryBuf *self) {
index_type idx = (self->start_of_data + self->count) % self->ynum;
init_line(self, idx, self->line);
if (self->count == self->ynum) self->start_of_data = (self->start_of_data + 1) % self->ynum;
@ -99,20 +92,21 @@ historybuf_resize(HistoryBuf *self, index_type lines) {
t.xnum=self->xnum;
t.ynum=lines;
if (t.ynum > 0 && t.ynum != self->ynum) {
t.buf = (uint32_t*)PyMem_Calloc(t.xnum * t.ynum, CELL_SIZE_H);
t.buf = PyMem_Calloc(t.xnum * t.ynum, sizeof(Cell));
if (t.buf == NULL) { PyErr_NoMemory(); return false; }
t.continued_map = PyMem_Calloc(t.ynum, sizeof(bool));
if (t.continued_map == NULL) { PyMem_Free(t.buf); PyErr_NoMemory(); return false; }
t.count = MIN(self->count, t.ynum);
if (t.count > 0) {
for (index_type s=0; s < t.count; s++) {
uint32_t *src = start_of(self, index_of(self, s)), *dest = start_of(&t, index_of(&t, s));
memcpy(dest, src, CELL_SIZE_H * t.xnum);
}
for (index_type s=0; s < t.count; s++) {
index_type si = index_of(self, s), ti = index_of(&t, s);
copy_cells(lineptr(self, si), lineptr(&t, ti), t.xnum);
t.continued_map[ti] = self->continued_map[si];
}
self->count = t.count;
self->start_of_data = t.start_of_data;
self->ynum = t.ynum;
PyMem_Free(self->buf);
self->buf = t.buf;
PyMem_Free(self->buf); PyMem_Free(self->continued_map);
self->buf = t.buf; self->continued_map = t.continued_map;
}
return true;
}
@ -120,8 +114,8 @@ historybuf_resize(HistoryBuf *self, index_type lines) {
void
historybuf_add_line(HistoryBuf *self, const Line *line) {
index_type idx = historybuf_push(self);
COPY_LINE(line, self->line);
*(start_of(self, idx)) = line->continued;
copy_line(line, self->line);
self->continued_map[idx] = line->continued;
}
static PyObject*
@ -159,7 +153,7 @@ as_ansi(HistoryBuf *self, PyObject *callback) {
for(unsigned int i = 0; i < self->count; i++) {
init_line(self, i, &l);
if (i < self->count - 1) {
l.continued = *start_of(self, index_of(self, i + 1));
l.continued = self->continued_map[index_of(self, i + 1)];
} else l.continued = false;
index_type num = line_as_ansi(&l, t, 5120);
if (!(l.continued) && num < 5119) t[num++] = 10; // 10 = \n
@ -218,9 +212,9 @@ HistoryBuf *alloc_historybuf(unsigned int lines, unsigned int columns) {
#define init_src_line(src_y) init_line(src, map_src_index(src_y), src->line);
#define is_src_line_continued(src_y) (map_src_index(src_y) < src->ynum - 1 ? (bool)(*(start_of(src, map_src_index(src_y + 1)))) : false)
#define is_src_line_continued(src_y) (map_src_index(src_y) < src->ynum - 1 ? src->continued_map[map_src_index(src_y + 1)] : false)
#define next_dest_line(cont) *start_of(dest, historybuf_push(dest)) = cont; dest->line->continued = cont;
#define next_dest_line(cont) dest->continued_map[historybuf_push(dest)] = cont; dest->line->continued = cont;
#define first_dest_line next_dest_line(false);
@ -230,7 +224,8 @@ void historybuf_rewrap(HistoryBuf *self, HistoryBuf *other) {
// Fast path
if (other->xnum == self->xnum && other->ynum == self->ynum) {
Py_BEGIN_ALLOW_THREADS;
memcpy(other->buf, self->buf, CELL_SIZE_H * self->xnum * self->ynum);
memcpy(other->buf, self->buf, sizeof(Cell) * self->xnum * self->ynum);
memcpy(other->continued_map, self->continued_map, sizeof(bool) * self->ynum);
other->count = self->count; other->start_of_data = self->start_of_data;
Py_END_ALLOW_THREADS;
return;

View File

@ -14,12 +14,6 @@ lineptr(LineBuf *linebuf, index_type y) {
return linebuf->buf + y * linebuf->xnum;
}
static inline void
clear_chars_in_line(Cell *cells, index_type xnum, char_type ch) {
char_type c = (1 << ATTRS_SHIFT) | ch;
for (index_type i = 0; i < xnum; i++) cells[i].ch = c;
}
static inline void
clear_chars_to(LineBuf* linebuf, index_type y, char_type ch) {
clear_chars_in_line(lineptr(linebuf, y), linebuf->xnum, ch);

View File

@ -17,6 +17,17 @@ set_attribute_on_line(Cell *cells, uint32_t shift, uint32_t val, index_type xnum
}
static inline void
copy_line(Line *src, Line *dest) {
memcpy(dest->cells, src->cells, sizeof(Cell) * (MIN(src->xnum, dest->xnum)));
copy_cells(const Cell *src, Cell *dest, index_type xnum) {
memcpy(dest, src, sizeof(Cell) * xnum);
}
static inline void
copy_line(const Line *src, Line *dest) {
copy_cells(src->cells, dest->cells, MIN(src->xnum, dest->xnum));
}
static inline void
clear_chars_in_line(Cell *cells, index_type xnum, char_type ch) {
char_type c = (1 << ATTRS_SHIFT) | ch;
for (index_type i = 0; i < xnum; i++) cells[i].ch = c;
}