Parse DCS+q

This commit is contained in:
Kovid Goyal
2016-11-24 08:14:29 +05:30
parent 1e19dbde15
commit 2e3e6d331d
4 changed files with 56 additions and 27 deletions

View File

@@ -361,6 +361,7 @@ void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom);
void set_title(Screen *self, PyObject*);
void set_icon(Screen *self, PyObject*);
void set_dynamic_color(Screen *self, unsigned int code, PyObject*);
void screen_request_capabilities(Screen *, PyObject *);
void report_device_attributes(Screen *self, unsigned int UNUSED mode, bool UNUSED secondary);
void select_graphic_rendition(Screen *self, unsigned int *params, unsigned int count);
void report_device_status(Screen *self, unsigned int which, bool UNUSED);

View File

@@ -204,29 +204,31 @@ dispatch_osc(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
if (i < limit - 1 && screen->parser_buf[i] == ';') i++;
}
PyObject *string = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, screen->parser_buf + i, limit - i);
switch(code) {
case 0:
DISPATCH_OSC(set_title);
DISPATCH_OSC(set_icon);
break;
case 1:
DISPATCH_OSC(set_icon);
break;
case 2:
DISPATCH_OSC(set_title);
break;
case 10:
case 11:
case 110:
case 111:
REPORT_OSC(set_dynamic_color, string);
set_dynamic_color(screen, code, string);
break;
default:
REPORT_ERROR("Unknown OSC code: %u", code);
break;
if (string != NULL) {
switch(code) {
case 0:
DISPATCH_OSC(set_title);
DISPATCH_OSC(set_icon);
break;
case 1:
DISPATCH_OSC(set_icon);
break;
case 2:
DISPATCH_OSC(set_title);
break;
case 10:
case 11:
case 110:
case 111:
REPORT_OSC(set_dynamic_color, string);
set_dynamic_color(screen, code, string);
break;
default:
REPORT_ERROR("Unknown OSC code: %u", code);
break;
}
Py_CLEAR(string);
}
Py_CLEAR(string);
#undef DISPATCH_OSC
}
// }}}
@@ -376,8 +378,26 @@ dispatch_csi(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
// DCS mode {{{
static inline void
dispatch_dcs(Screen *screen) {
screen->parser_buf_pos++;
dispatch_dcs(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
PyObject *string = NULL;
if (screen->parser_buf_pos < 2) return;
switch(screen->parser_buf[0]) {
case '+':
if (screen->parser_buf[1] == 'q') {
string = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, screen->parser_buf + 2, screen->parser_buf_pos - 2);
if (string != NULL) {
REPORT_OSC(screen_request_capabilities, string);
screen_request_capabilities(screen, string);
Py_CLEAR(string);
}
} else {
REPORT_ERROR("Unrecognized DCS+ code: 0x%x", screen->parser_buf[1]);
}
break;
default:
REPORT_ERROR("Unrecognized DCS code: 0x%x", screen->parser_buf[0]);
break;
}
}
// }}}
@@ -521,7 +541,7 @@ _parse_bytes(Screen *screen, uint8_t *buf, Py_ssize_t len, PyObject DUMP_UNUSED
if (accumulate_osc(screen, codepoint, dump_callback)) { dispatch_osc(screen, dump_callback); SET_STATE(0); }
break;
case DCS:
if (accumulate_dcs(screen, codepoint, dump_callback)) { dispatch_dcs(screen); SET_STATE(0); }
if (accumulate_dcs(screen, codepoint, dump_callback)) { dispatch_dcs(screen, dump_callback); SET_STATE(0); }
if (screen->parser_state == ESC) { HANDLE(esc_mode_char); }
break;
default:

View File

@@ -810,6 +810,11 @@ void set_dynamic_color(Screen *self, unsigned int code, PyObject *color) {
if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
}
void screen_request_capabilities(Screen *self, PyObject *q) {
PyObject_CallMethod(self->callbacks, "request_capabilities", "O", q);
if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
}
// }}}
// Python interface {{{

View File

@@ -32,9 +32,12 @@ class Callbacks:
def set_dynamic_color(self, code, data):
self.colorbuf += data
def request_capabilities(self, q):
self.qbuf += q
def clear(self):
self.wtcbuf = b''
self.iconbuf = self.titlebuf = self.colorbuf = ''
self.iconbuf = self.titlebuf = self.colorbuf = self.qbuf = ''
class TestParser(BaseTest):
@@ -168,5 +171,5 @@ class TestParser(BaseTest):
def test_dcs_codes(self):
s = self.create_screen()
pb = partial(self.parse_bytes_dump, s)
pb('a\033P2;xyz\x9cbcde', 'abcde')
pb('a\033P+q436f\x9cbcde', 'a', ('screen_request_capabilities', '436f'), 'bcde')
self.ae(str(s.line(0)), 'abcde')