Dont use a macro for as_text_generic
This commit is contained in:
parent
b7d12de0a7
commit
af8fdf1dbe
5 changed files with 74 additions and 56 deletions
|
|
@ -379,12 +379,23 @@ end:
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Line line;
|
||||
HistoryBuf *self;
|
||||
} GetLineWrapper;
|
||||
|
||||
static Line*
|
||||
get_line_wrapper(void *x, int y) {
|
||||
GetLineWrapper *glw = x;
|
||||
get_line(glw->self, y, &glw->line);
|
||||
return &glw->line;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
as_text(HistoryBuf *self, PyObject *args) {
|
||||
Line l = {.xnum=self->xnum};
|
||||
#define gl(self, y) get_line(self, y, &l);
|
||||
as_text_generic(args, self, gl, self->count, self->xnum);
|
||||
#undef gl
|
||||
GetLineWrapper glw = {.self=self};
|
||||
glw.line.xnum = self->xnum;
|
||||
return as_text_generic(args, &glw, get_line_wrapper, self->count, self->xnum);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -421,14 +421,15 @@ as_ansi(LineBuf *self, PyObject *callback) {
|
|||
}
|
||||
|
||||
static inline Line*
|
||||
get_line(LineBuf *self, index_type y) {
|
||||
linebuf_init_line(self, y);
|
||||
get_line(void *x, int y) {
|
||||
LineBuf *self = (LineBuf*)x;
|
||||
linebuf_init_line(self, MAX(0, y));
|
||||
return self->line;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
as_text(LineBuf *self, PyObject *args) {
|
||||
as_text_generic(args, self, get_line, self->ynum, self->xnum);
|
||||
return as_text_generic(args, self, get_line, self->ynum, self->xnum);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
45
kitty/line.c
45
kitty/line.c
|
|
@ -737,6 +737,51 @@ mark_text_in_line(PyObject *marker, Line *line) {
|
|||
Py_DECREF(text);
|
||||
}
|
||||
|
||||
PyObject*
|
||||
as_text_generic(PyObject *args, void *container, get_line_func get_line, index_type lines, index_type columns) {
|
||||
PyObject *callback;
|
||||
int as_ansi = 0, insert_wrap_markers = 0;
|
||||
if (!PyArg_ParseTuple(args, "O|pp", &callback, &as_ansi, &insert_wrap_markers)) return NULL;
|
||||
PyObject *ret = NULL, *t = NULL;
|
||||
Py_UCS4 *buf = NULL;
|
||||
PyObject *nl = PyUnicode_FromString("\n");
|
||||
PyObject *cr = PyUnicode_FromString("\r");
|
||||
const GPUCell *prev_cell = NULL;
|
||||
if (nl == NULL || cr == NULL) goto end;
|
||||
if (as_ansi) {
|
||||
buf = malloc(sizeof(Py_UCS4) * columns * 100);
|
||||
if (buf == NULL) { PyErr_NoMemory(); goto end; }
|
||||
}
|
||||
for (index_type y = 0; y < lines; y++) {
|
||||
Line *line = get_line(container, y);
|
||||
if (!line->continued && y > 0) {
|
||||
ret = PyObject_CallFunctionObjArgs(callback, nl, NULL);
|
||||
if (ret == NULL) goto end;
|
||||
Py_CLEAR(ret);
|
||||
}
|
||||
if (as_ansi) {
|
||||
bool truncated;
|
||||
index_type num = line_as_ansi(line, buf, columns * 100 - 2, &truncated, &prev_cell);
|
||||
t = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buf, num);
|
||||
} else {
|
||||
t = line_as_unicode(line);
|
||||
}
|
||||
if (t == NULL) goto end;
|
||||
ret = PyObject_CallFunctionObjArgs(callback, t, NULL);
|
||||
Py_DECREF(t); if (ret == NULL) goto end; Py_DECREF(ret);
|
||||
if (insert_wrap_markers) {
|
||||
ret = PyObject_CallFunctionObjArgs(callback, cr, NULL);
|
||||
if (ret == NULL) goto end;
|
||||
Py_CLEAR(ret);
|
||||
}
|
||||
}
|
||||
end:
|
||||
Py_CLEAR(nl); Py_CLEAR(cr); free(buf);
|
||||
if (PyErr_Occurred()) return NULL;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
// Boilerplate {{{
|
||||
static PyObject*
|
||||
copy_char(Line* self, PyObject *args);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ line_reset_cells(Line *line, index_type start, index_type num, GPUCell *gpu_cell
|
|||
memcpy(line->cpu_cells + start, cpu_cells + start, sizeof(CPUCell) * num);
|
||||
}
|
||||
|
||||
typedef Line*(get_line_func)(void *, int);
|
||||
void line_clear_text(Line *self, unsigned int at, unsigned int num, char_type ch);
|
||||
void line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, bool clear_char);
|
||||
void line_set_char(Line *, unsigned int , uint32_t , unsigned int , Cursor *, bool);
|
||||
|
|
@ -92,47 +93,4 @@ void historybuf_refresh_sprite_positions(HistoryBuf *self);
|
|||
void historybuf_clear(HistoryBuf *self);
|
||||
void mark_text_in_line(PyObject *marker, Line *line);
|
||||
bool line_has_mark(Line *, attrs_type mark);
|
||||
|
||||
|
||||
#define as_text_generic(args, container, get_line, lines, columns) { \
|
||||
PyObject *callback; \
|
||||
int as_ansi = 0, insert_wrap_markers = 0; \
|
||||
if (!PyArg_ParseTuple(args, "O|pp", &callback, &as_ansi, &insert_wrap_markers)) return NULL; \
|
||||
PyObject *ret = NULL, *t = NULL; \
|
||||
Py_UCS4 *buf = NULL; \
|
||||
PyObject *nl = PyUnicode_FromString("\n"); \
|
||||
PyObject *cr = PyUnicode_FromString("\r"); \
|
||||
const GPUCell *prev_cell = NULL; \
|
||||
if (nl == NULL || cr == NULL) goto end; \
|
||||
if (as_ansi) { \
|
||||
buf = malloc(sizeof(Py_UCS4) * columns * 100); \
|
||||
if (buf == NULL) { PyErr_NoMemory(); goto end; } \
|
||||
} \
|
||||
for (index_type y = 0; y < lines; y++) { \
|
||||
Line *line = get_line(container, y); \
|
||||
if (!line->continued && y > 0) { \
|
||||
ret = PyObject_CallFunctionObjArgs(callback, nl, NULL); \
|
||||
if (ret == NULL) goto end; \
|
||||
Py_CLEAR(ret); \
|
||||
} \
|
||||
if (as_ansi) { \
|
||||
bool truncated; \
|
||||
index_type num = line_as_ansi(line, buf, columns * 100 - 2, &truncated, &prev_cell); \
|
||||
t = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buf, num); \
|
||||
} else { \
|
||||
t = line_as_unicode(line); \
|
||||
} \
|
||||
if (t == NULL) goto end; \
|
||||
ret = PyObject_CallFunctionObjArgs(callback, t, NULL); \
|
||||
Py_DECREF(t); if (ret == NULL) goto end; Py_DECREF(ret); \
|
||||
if (insert_wrap_markers) { \
|
||||
ret = PyObject_CallFunctionObjArgs(callback, cr, NULL); \
|
||||
if (ret == NULL) goto end; \
|
||||
Py_CLEAR(ret); \
|
||||
}\
|
||||
} \
|
||||
end: \
|
||||
Py_CLEAR(nl); Py_CLEAR(cr); free(buf); \
|
||||
if (PyErr_Occurred()) return NULL; \
|
||||
Py_RETURN_NONE; \
|
||||
}
|
||||
PyObject* as_text_generic(PyObject *args, void *container, get_line_func get_line, index_type lines, index_type columns);
|
||||
|
|
|
|||
|
|
@ -1749,26 +1749,29 @@ set_pending_timeout(Screen *self, PyObject *val) {
|
|||
return ans;
|
||||
}
|
||||
|
||||
static Line* get_visual_line(void *x, int y) { return visual_line_(x, y); }
|
||||
static Line* get_range_line(void *x, int y) { return range_line_(x, y); }
|
||||
|
||||
static PyObject*
|
||||
as_text(Screen *self, PyObject *args) {
|
||||
as_text_generic(args, self, visual_line_, self->lines, self->columns);
|
||||
return as_text_generic(args, self, get_visual_line, self->lines, self->columns);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
as_text_non_visual(Screen *self, PyObject *args) {
|
||||
as_text_generic(args, self, range_line_, self->lines, self->columns);
|
||||
return as_text_generic(args, self, get_range_line, self->lines, self->columns);
|
||||
}
|
||||
|
||||
static inline PyObject*
|
||||
as_text_generic_wrapper(Screen *self, PyObject *args, Line*(get_line)(Screen *, int)) {
|
||||
as_text_generic(args, self, get_line, self->lines, self->columns);
|
||||
as_text_generic_wrapper(Screen *self, PyObject *args, get_line_func get_line) {
|
||||
return as_text_generic(args, self, get_line, self->lines, self->columns);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
as_text_alternate(Screen *self, PyObject *args) {
|
||||
LineBuf *original = self->linebuf;
|
||||
self->linebuf = original == self->main_linebuf ? self->alt_linebuf : self->main_linebuf;
|
||||
PyObject *ans = as_text_generic_wrapper(self, args, range_line_);
|
||||
PyObject *ans = as_text_generic_wrapper(self, args, get_range_line);
|
||||
self->linebuf = original;
|
||||
return ans;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue