Framework for testing graphics command parsing

This commit is contained in:
Kovid Goyal 2017-09-25 20:54:36 +05:30
parent 967e65e150
commit 8e64895c23
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 56 additions and 2 deletions

View File

@ -136,6 +136,7 @@ extern bool init_glfw(PyObject *m);
extern bool init_sprites(PyObject *module);
extern bool init_state(PyObject *module);
extern bool init_keys(PyObject *module);
extern bool init_graphics(PyObject *module);
extern bool init_shaders(PyObject *module);
extern bool init_shaders_debug(PyObject *module);
#ifdef __APPLE__
@ -166,6 +167,7 @@ PyInit_fast_data_types(void) {
if (!init_sprites(m)) return NULL;
if (!init_state(m)) return NULL;
if (!init_keys(m)) return NULL;
if (!init_graphics(m)) return NULL;
if (PySys_GetObject("debug_gl") == Py_True) {
if (!init_shaders_debug(m)) return NULL;
} else {

15
kitty/graphics.c Normal file
View File

@ -0,0 +1,15 @@
/*
* graphics.c
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "graphics.h"
#include "state.h"
bool
init_graphics(PyObject UNUSED *m) {
return true;
}

View File

@ -5,6 +5,8 @@
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
typedef struct {
unsigned char action, transmission_type;

View File

@ -87,6 +87,7 @@ _report_params(PyObject *dump_callback, const char *name, unsigned int *params,
#define GET_MACRO(_1,_2,_3,NAME,...) NAME
#define REPORT_COMMAND(...) GET_MACRO(__VA_ARGS__, REPORT_COMMAND3, REPORT_COMMAND2, REPORT_COMMAND1, SENTINEL)(__VA_ARGS__)
#define REPORT_VA_COMMAND(...) Py_XDECREF(PyObject_CallFunction(dump_callback, __VA_ARGS__)); PyErr_Clear();
#define REPORT_DRAW(ch) \
Py_XDECREF(PyObject_CallFunction(dump_callback, "sC", "draw", ch)); PyErr_Clear();
@ -109,6 +110,7 @@ _report_params(PyObject *dump_callback, const char *name, unsigned int *params,
#define REPORT_ERROR(...) fprintf(stderr, "%s ", ERROR_PREFIX); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n");
#define REPORT_COMMAND(...)
#define REPORT_VA_COMMAND(...)
#define REPORT_DRAW(ch)
#define REPORT_PARAMS(...)
#define FLUSH_DRAW
@ -603,7 +605,7 @@ parse_graphics_code(Screen *screen, PyObject UNUSED *dump_callback) {
if (screen->parser_buf[i] < '0' || screen->parser_buf[i] > '9') break; \
} \
if (i == pos) { REPORT_ERROR("Malformed graphics control block, expecting an integer value"); return; } \
code = utoi(screen->parser_buf + pos, i - pos);
code = utoi(screen->parser_buf + pos, i - pos); pos = i;
case INT:
is_negative = false;
@ -638,7 +640,7 @@ parse_graphics_code(Screen *screen, PyObject UNUSED *dump_callback) {
state = PAYLOAD;
break;
default:
REPORT_ERROR("Malformed graphics control block, expecting a comma or semi-colon after a value");
REPORT_ERROR("Malformed graphics control block, expecting a comma or semi-colon after a value, found: 0x%x", screen->parser_buf[screen->parser_buf_pos - 1]);
return;
}
break;
@ -651,6 +653,18 @@ parse_graphics_code(Screen *screen, PyObject UNUSED *dump_callback) {
break;
}
}
#define A(x) #x, g.x
#define U(x) #x, (unsigned int)(g.x)
#define I(x) #x, (int)(g.x)
REPORT_VA_COMMAND("s {sc sc sI sI sI sI sI sI sI sI sI sI sI sI si}", "graphics_command",
A(action), A(transmission_type),
U(format), U(more), U(id),
U(width), U(height), U(x_offset), U(y_offset), U(data_height), U(data_width), U(num_cells), U(num_lines),
U(payload_sz), I(z_index)
);
#undef U
#undef A
#undef I
}
static inline void

View File

@ -68,6 +68,7 @@ def filled_history_buf(ynum=5, xnum=5, cursor=Cursor()):
class BaseTest(TestCase):
ae = TestCase.assertEqual
maxDiff = 2000
def create_screen(self, cols=5, lines=5, scrollback=5):
c = Callbacks()

View File

@ -191,3 +191,23 @@ def test_oth_codes(self):
for prefix in '\033^', '\u009e':
for suffix in '\u009c', '\033\\':
pb('a{}+\\++{}bcde'.format(prefix, suffix), ('draw', 'a'), ('Unrecognized PM code: 0x2b',), ('draw', 'bcde'))
def test_graphics_command(self):
from base64 import standard_b64encode
def e(x):
return standard_b64encode(x.encode('utf-8') if isinstance(x, str) else x).decode('ascii')
def c(**k):
for p, v in tuple(k.items()):
if isinstance(v, str):
k[p] = v.encode('ascii')
for f in 'action transmission_type'.split():
k.setdefault(f, b'\0')
for f in 'format more id width height x_offset y_offset data_height data_width num_cells num_lines z_index payload_sz'.split():
k.setdefault(f, 0)
return ('graphics_command', k)
s = self.create_screen()
pb = partial(self.parse_bytes_dump, s)
pb('\033_Ga=t,t=f,s=100,v=99;{}\033\\'.format(e('a')), c(action='t', transmission_type='f', data_width=100, data_height=99, payload_sz=1))