Files
kitty-mirror/kitty/parse-dnd-command.h
2026-03-21 08:41:47 +05:30

222 lines
6.3 KiB
C

// This file is generated by apc_parsers.py do not edit!
#pragma once
#include "base64.h"
static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
const size_t parser_buf_pos) {
unsigned int pos = 0;
size_t payload_start = 0;
enum PARSER_STATES { KEY, EQUAL, UINT, INT, FLAG, AFTER_VALUE, PAYLOAD };
enum PARSER_STATES state = KEY, value_state = FLAG;
DnDCommand g = {0};
unsigned int i, code;
uint64_t lcode;
int64_t accumulator;
bool is_negative;
(void)is_negative;
size_t sz;
enum KEYS {
type = 't',
more = 'm',
client_id = 'i',
operation = 'o',
cell_x = 'x',
cell_y = 'y',
pixel_x = 'X',
pixel_y = 'Y'
};
enum KEYS key = 'a';
if (parser_buf[pos] == ';')
state = AFTER_VALUE;
while (pos < parser_buf_pos) {
switch (state) {
case KEY:
key = parser_buf[pos++];
state = EQUAL;
switch (key) {
case type:
value_state = FLAG;
break;
case more:
value_state = UINT;
break;
case client_id:
value_state = UINT;
break;
case operation:
value_state = UINT;
break;
case cell_x:
value_state = INT;
break;
case cell_y:
value_state = INT;
break;
case pixel_x:
value_state = INT;
break;
case pixel_y:
value_state = INT;
break;
default:
REPORT_ERROR(
"Malformed DnDCommand control block, invalid key character: 0x%x",
key);
return;
}
break;
case EQUAL:
if (parser_buf[pos++] != '=') {
REPORT_ERROR("Malformed DnDCommand control block, no = after key, "
"found: 0x%x instead",
parser_buf[pos - 1]);
return;
}
state = value_state;
break;
case FLAG:
switch (key) {
case type: {
g.type = parser_buf[pos++];
if (g.type != 'A' && g.type != 'M' && g.type != 'R' && g.type != 'a' &&
g.type != 'm' && g.type != 'r') {
REPORT_ERROR("Malformed DnDCommand control block, unknown flag value "
"for type: 0x%x",
g.type);
return;
};
} break;
default:
break;
}
state = AFTER_VALUE;
break;
case INT:
#define READ_UINT \
for (i = pos, accumulator = 0; i < MIN(parser_buf_pos, pos + 10); i++) { \
int64_t n = parser_buf[i] - '0'; \
if (n < 0 || n > 9) \
break; \
accumulator += n * digit_multipliers[i - pos]; \
} \
if (i == pos) { \
REPORT_ERROR("Malformed DnDCommand control block, expecting an integer " \
"value for key: %c", \
key & 0xFF); \
return; \
} \
lcode = accumulator / digit_multipliers[i - pos - 1]; \
pos = i; \
if (lcode > UINT32_MAX) { \
REPORT_ERROR("Malformed DnDCommand control block, number is too large"); \
return; \
} \
code = lcode;
is_negative = false;
if (parser_buf[pos] == '-') {
is_negative = true;
pos++;
}
#define I(x) \
case x: \
g.x = is_negative ? 0 - (int32_t)code : (int32_t)code; \
break
READ_UINT;
switch (key) {
I(cell_x);
I(cell_y);
I(pixel_x);
I(pixel_y);
default:
break;
}
state = AFTER_VALUE;
break;
#undef I
case UINT:
READ_UINT;
#define U(x) \
case x: \
g.x = code; \
break
switch (key) {
U(more);
U(client_id);
U(operation);
default:
break;
}
state = AFTER_VALUE;
break;
#undef U
#undef READ_UINT
case AFTER_VALUE:
switch (parser_buf[pos++]) {
default:
REPORT_ERROR("Malformed DnDCommand control block, expecting a : or "
"semi-colon after a value, found: 0x%x",
parser_buf[pos - 1]);
return;
case ':':
state = KEY;
break;
case ';':
state = PAYLOAD;
break;
}
break;
case PAYLOAD: {
sz = parser_buf_pos - pos;
payload_start = pos;
g.payload_sz = sz;
pos = parser_buf_pos;
} break;
} // end switch
} // end while
switch (state) {
case EQUAL:
REPORT_ERROR("Malformed DnDCommand control block, no = after key");
return;
case INT:
case UINT:
REPORT_ERROR(
"Malformed DnDCommand control block, expecting an integer value");
return;
case FLAG:
REPORT_ERROR("Malformed DnDCommand control block, expecting a flag value");
return;
default:
break;
}
REPORT_VA_COMMAND(
"K s {sc sI sI sI si si si si ss#}", self->window_id, "dnd_command",
"type", g.type,
"more", (unsigned int)g.more, "client_id", (unsigned int)g.client_id,
"operation", (unsigned int)g.operation,
"cell_x", (int)g.cell_x, "cell_y", (int)g.cell_y, "pixel_x",
(int)g.pixel_x, "pixel_y", (int)g.pixel_y,
"", (char *)parser_buf + payload_start, g.payload_sz);
screen_handle_dnd_command(self->screen, &g, parser_buf + payload_start);
}