test(vterm): move test functions into vterm_test fixture

In order to run unittests with a release build, we need the test
functions to be accessible when NDEBUG is defined. Moving the functions
into the test fixture ensures they are available and only available for
use by the unit tests.
This commit is contained in:
James McCoy 2024-11-27 11:17:42 -05:00
parent 3d3a99e69c
commit 7a367c6967
No known key found for this signature in database
GPG Key ID: DFE691AE331BA3DB
5 changed files with 546 additions and 541 deletions

View File

@ -430,509 +430,3 @@ void vterm_check_version(int major, int minor)
// Happy
}
// For unit tests.
#ifndef NDEBUG
int parser_text(const char bytes[], size_t len, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "text ");
int i;
for(i = 0; i < len; i++) {
unsigned char b = bytes[i];
if(b < 0x20 || b == 0x7f || (b >= 0x80 && b < 0xa0)) {
break;
}
fprintf(f, i ? ",%x" : "%x", b);
}
fprintf(f, "\n");
fclose(f);
return i;
}
static void printchars(const char *s, size_t len, FILE *f)
{
while(len--) {
fprintf(f, "%c", (s++)[0]);
}
}
int parser_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "csi %02x", command);
if(leader && leader[0]) {
fprintf(f, " L=");
for(int i = 0; leader[i]; i++) {
fprintf(f, "%02x", leader[i]);
}
}
for(int i = 0; i < argcount; i++) {
char sep = i ? ',' : ' ';
if(args[i] == CSI_ARG_MISSING) {
fprintf(f, "%c*", sep);
} else {
fprintf(f, "%c%ld%s", sep, CSI_ARG(args[i]), CSI_ARG_HAS_MORE(args[i]) ? "+" : "");
}
}
if(intermed && intermed[0]) {
fprintf(f, " I=");
for(int i = 0; intermed[i]; i++) {
fprintf(f, "%02x", intermed[i]);
}
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_osc(int command, VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "osc ");
if(frag.initial) {
if(command == -1) {
fprintf(f, "[");
} else {
fprintf(f, "[%d;", command);
}
}
printchars(frag.str, frag.len, f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "dcs ");
if(frag.initial) {
fprintf(f, "[");
for(int i = 0; i < commandlen; i++) {
fprintf(f, "%c", command[i]);
}
}
printchars(frag.str, frag.len,f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_apc(VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "apc ");
if(frag.initial) {
fprintf(f, "[");
}
printchars(frag.str, frag.len, f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_pm(VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "pm ");
if(frag.initial) {
fprintf(f, "[");
}
printchars(frag.str, frag.len,f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_sos(VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "sos ");
if(frag.initial) {
fprintf(f, "[");
}
printchars(frag.str, frag.len,f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "selection-set mask=%04X ", mask);
if(frag.initial) {
fprintf(f, "[");
}
printchars(frag.str, frag.len, f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f,"\n");
fclose(f);
return 1;
}
int selection_query(VTermSelectionMask mask, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"selection-query mask=%04X\n", mask);
fclose(f);
return 1;
}
bool want_state_putglyph;
int state_putglyph(VTermGlyphInfo *info, VTermPos pos, void *user)
{
if(!want_state_putglyph) {
return 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "putglyph ");
for(int i = 0; i < VTERM_MAX_CHARS_PER_CELL && info->chars[i]; i++) {
fprintf(f, i ? ",%x" : "%x", info->chars[i]);
}
fprintf(f, " %d %d,%d", info->width, pos.row, pos.col);
if(info->protected_cell) {
fprintf(f, " prot");
}
if(info->dwl) {
fprintf(f, " dwl");
}
if(info->dhl) {
fprintf(f, " dhl-%s", info->dhl == 1 ? "top" : info->dhl == 2 ? "bottom" : "?" );
}
fprintf(f, "\n");
fclose(f);
return 1;
}
bool want_state_movecursor;
VTermPos state_pos;
int state_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
state_pos = pos;
if(want_state_movecursor) {
fprintf(f,"movecursor %d,%d\n", pos.row, pos.col);
}
fclose(f);
return 1;
}
bool want_state_scrollrect;
int state_scrollrect(VTermRect rect, int downward, int rightward, void *user)
{
if(!want_state_scrollrect) {
return 0;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"scrollrect %d..%d,%d..%d => %+d,%+d\n",
rect.start_row, rect.end_row, rect.start_col, rect.end_col,
downward, rightward);
fclose(f);
return 1;
}
bool want_state_moverect;
int state_moverect(VTermRect dest, VTermRect src, void *user)
{
if(!want_state_moverect) {
return 0;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"moverect %d..%d,%d..%d -> %d..%d,%d..%d\n",
src.start_row, src.end_row, src.start_col, src.end_col,
dest.start_row, dest.end_row, dest.start_col, dest.end_col);
fclose(f);
return 1;
}
void print_color(const VTermColor *col)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
if (VTERM_COLOR_IS_RGB(col)) {
fprintf(f,"rgb(%d,%d,%d", col->rgb.red, col->rgb.green, col->rgb.blue);
}
else if (VTERM_COLOR_IS_INDEXED(col)) {
fprintf(f,"idx(%d", col->indexed.idx);
}
else {
fprintf(f,"invalid(%d", col->type);
}
if (VTERM_COLOR_IS_DEFAULT_FG(col)) {
fprintf(f,",is_default_fg");
}
if (VTERM_COLOR_IS_DEFAULT_BG(col)) {
fprintf(f,",is_default_bg");
}
fprintf(f,")");
fclose(f);
}
bool want_state_settermprop;
int state_settermprop(VTermProp prop, VTermValue *val, void *user)
{
if(!want_state_settermprop) {
return 1;
}
int errcode = 0;
FILE *f = fopen(VTERM_TEST_FILE, "a");
VTermValueType type = vterm_get_prop_type(prop);
switch(type) {
case VTERM_VALUETYPE_BOOL:
fprintf(f,"settermprop %d %s\n", prop, val->boolean ? "true" : "false");
errcode = 1;
goto end;
case VTERM_VALUETYPE_INT:
fprintf(f,"settermprop %d %d\n", prop, val->number);
errcode = 1;
goto end;
case VTERM_VALUETYPE_STRING:
fprintf(f,"settermprop %d %s\"%.*s\"%s\n", prop,
val->string.initial ? "[" : "", (int)val->string.len, val->string.str, val->string.final ? "]" : "");
errcode=0;
goto end;
case VTERM_VALUETYPE_COLOR:
fprintf(f,"settermprop %d ", prop);
print_color(&val->color);
fprintf(f,"\n");
errcode=1;
goto end;
case VTERM_N_VALUETYPES:
goto end;
}
end:
fclose(f);
return errcode;
}
bool want_state_erase;
int state_erase(VTermRect rect, int selective, void *user)
{
if(!want_state_erase) {
return 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"erase %d..%d,%d..%d%s\n",
rect.start_row, rect.end_row, rect.start_col, rect.end_col,
selective ? " selective" : "");
fclose(f);
return 1;
}
struct {
int bold;
int underline;
int italic;
int blink;
int reverse;
int conceal;
int strike;
int font;
int small;
int baseline;
VTermColor foreground;
VTermColor background;
} state_pen;
int state_setpenattr(VTermAttr attr, VTermValue *val, void *user)
{
switch(attr) {
case VTERM_ATTR_BOLD:
state_pen.bold = val->boolean;
break;
case VTERM_ATTR_UNDERLINE:
state_pen.underline = val->number;
break;
case VTERM_ATTR_ITALIC:
state_pen.italic = val->boolean;
break;
case VTERM_ATTR_BLINK:
state_pen.blink = val->boolean;
break;
case VTERM_ATTR_REVERSE:
state_pen.reverse = val->boolean;
break;
case VTERM_ATTR_CONCEAL:
state_pen.conceal = val->boolean;
break;
case VTERM_ATTR_STRIKE:
state_pen.strike = val->boolean;
break;
case VTERM_ATTR_FONT:
state_pen.font = val->number;
break;
case VTERM_ATTR_SMALL:
state_pen.small = val->boolean;
break;
case VTERM_ATTR_BASELINE:
state_pen.baseline = val->number;
break;
case VTERM_ATTR_FOREGROUND:
state_pen.foreground = val->color;
break;
case VTERM_ATTR_BACKGROUND:
state_pen.background = val->color;
break;
case VTERM_N_ATTRS:
return 0;
default:
break;
}
return 1;
}
bool want_state_scrollback;
int state_sb_clear(void *user) {
if(!want_state_scrollback) {
return 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"sb_clear\n");
fclose(f);
return 0;
}
bool want_screen_scrollback;
int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user)
{
if(!want_screen_scrollback) {
return 1;
}
int eol = cols;
while(eol && !cells[eol-1].chars[0]) {
eol--;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "sb_pushline %d =", cols);
for(int c = 0; c < eol; c++) {
fprintf(f, " %02X", cells[c].chars[0]);
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int screen_sb_popline(int cols, VTermScreenCell *cells, void *user)
{
if(!want_screen_scrollback) {
return 0;
}
// All lines of scrollback contain "ABCDE"
for(int col = 0; col < cols; col++) {
if(col < 5) {
cells[col].chars[0] = 'A' + col;
} else {
cells[col].chars[0] = 0;
}
cells[col].width = 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"sb_popline %d\n", cols);
fclose(f);
return 1;
}
int screen_sb_clear(void *user)
{
if(!want_screen_scrollback) {
return 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "sb_clear\n");
fclose(f);
return 0;
}
void term_output(const char *s, size_t len, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "output ");
for(int i = 0; i < len; i++) {
fprintf(f, "%x%s", (unsigned char)s[i], i < len-1 ? "," : "\n");
}
fclose(f);
}
#endif

View File

@ -635,40 +635,6 @@ void vterm_copy_cells(VTermRect dest,
void (*copycell)(VTermPos dest, VTermPos src, void *user),
void *user);
#ifndef NDEBUG
int parser_text(const char bytes[], size_t len, void *user);
int parser_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user);
int parser_osc(int command, VTermStringFragment frag, void *user);
int parser_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user);
int parser_apc(VTermStringFragment frag, void *user);
int parser_pm(VTermStringFragment frag, void *user);
int parser_sos(VTermStringFragment frag, void *user);
int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user);
int selection_query(VTermSelectionMask mask, void *user);
int state_putglyph(VTermGlyphInfo *info, VTermPos pos, void *user);
int state_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user);
int state_scrollrect(VTermRect rect, int downward, int rightward, void *user);
int state_moverect(VTermRect dest, VTermRect src, void *user);
int state_settermprop(VTermProp prop, VTermValue *val, void *user);
int state_erase(VTermRect rect, int selective, void *user);
int state_setpenattr(VTermAttr attr, VTermValue *val, void *user);
int state_sb_clear(void *user);
void print_color(const VTermColor *col);
int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user);
int screen_sb_popline(int cols, VTermScreenCell *cells, void *user);
int screen_sb_clear(void *user);
void term_output(const char *s, size_t len, void *user);
EXTERN VTermPos state_pos;
EXTERN bool want_state_putglyph INIT (=false);
EXTERN bool want_state_movecursor INIT(= false);
EXTERN bool want_state_erase INIT(= false);
EXTERN bool want_state_scrollrect INIT(= false);
EXTERN bool want_state_moverect INIT(= false);
EXTERN bool want_state_settermprop INIT(= false);
EXTERN bool want_state_scrollback INIT(= false);
EXTERN bool want_screen_scrollback INIT(= false);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,504 @@
#include "vterm_test.h"
#include <stdio.h>
int parser_text(const char bytes[], size_t len, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "text ");
size_t i;
for(i = 0; i < len; i++) {
unsigned char b = (unsigned char)bytes[i];
if(b < 0x20 || b == 0x7f || (b >= 0x80 && b < 0xa0)) {
break;
}
fprintf(f, i ? ",%x" : "%x", b);
}
fprintf(f, "\n");
fclose(f);
return (int)i;
}
static void printchars(const char *s, size_t len, FILE *f)
{
while(len--) {
fprintf(f, "%c", (s++)[0]);
}
}
int parser_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "csi %02x", command);
if(leader && leader[0]) {
fprintf(f, " L=");
for(int i = 0; leader[i]; i++) {
fprintf(f, "%02x", leader[i]);
}
}
for(int i = 0; i < argcount; i++) {
char sep = i ? ',' : ' ';
if(args[i] == CSI_ARG_MISSING) {
fprintf(f, "%c*", sep);
} else {
fprintf(f, "%c%ld%s", sep, CSI_ARG(args[i]), CSI_ARG_HAS_MORE(args[i]) ? "+" : "");
}
}
if(intermed && intermed[0]) {
fprintf(f, " I=");
for(int i = 0; intermed[i]; i++) {
fprintf(f, "%02x", intermed[i]);
}
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_osc(int command, VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "osc ");
if(frag.initial) {
if(command == -1) {
fprintf(f, "[");
} else {
fprintf(f, "[%d;", command);
}
}
printchars(frag.str, frag.len, f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "dcs ");
if(frag.initial) {
fprintf(f, "[");
for(size_t i = 0; i < commandlen; i++) {
fprintf(f, "%c", command[i]);
}
}
printchars(frag.str, frag.len,f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_apc(VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "apc ");
if(frag.initial) {
fprintf(f, "[");
}
printchars(frag.str, frag.len, f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_pm(VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "pm ");
if(frag.initial) {
fprintf(f, "[");
}
printchars(frag.str, frag.len,f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int parser_sos(VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "sos ");
if(frag.initial) {
fprintf(f, "[");
}
printchars(frag.str, frag.len,f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "selection-set mask=%04X ", mask);
if(frag.initial) {
fprintf(f, "[");
}
printchars(frag.str, frag.len, f);
if(frag.final) {
fprintf(f, "]");
}
fprintf(f,"\n");
fclose(f);
return 1;
}
int selection_query(VTermSelectionMask mask, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"selection-query mask=%04X\n", mask);
fclose(f);
return 1;
}
bool want_state_putglyph;
int state_putglyph(VTermGlyphInfo *info, VTermPos pos, void *user)
{
if(!want_state_putglyph) {
return 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "putglyph ");
for(int i = 0; i < VTERM_MAX_CHARS_PER_CELL && info->chars[i]; i++) {
fprintf(f, i ? ",%x" : "%x", info->chars[i]);
}
fprintf(f, " %d %d,%d", info->width, pos.row, pos.col);
if(info->protected_cell) {
fprintf(f, " prot");
}
if(info->dwl) {
fprintf(f, " dwl");
}
if(info->dhl) {
fprintf(f, " dhl-%s", info->dhl == 1 ? "top" : info->dhl == 2 ? "bottom" : "?" );
}
fprintf(f, "\n");
fclose(f);
return 1;
}
bool want_state_movecursor;
VTermPos state_pos;
int state_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
state_pos = pos;
if(want_state_movecursor) {
fprintf(f,"movecursor %d,%d\n", pos.row, pos.col);
}
fclose(f);
return 1;
}
bool want_state_scrollrect;
int state_scrollrect(VTermRect rect, int downward, int rightward, void *user)
{
if(!want_state_scrollrect) {
return 0;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"scrollrect %d..%d,%d..%d => %+d,%+d\n",
rect.start_row, rect.end_row, rect.start_col, rect.end_col,
downward, rightward);
fclose(f);
return 1;
}
bool want_state_moverect;
int state_moverect(VTermRect dest, VTermRect src, void *user)
{
if(!want_state_moverect) {
return 0;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"moverect %d..%d,%d..%d -> %d..%d,%d..%d\n",
src.start_row, src.end_row, src.start_col, src.end_col,
dest.start_row, dest.end_row, dest.start_col, dest.end_col);
fclose(f);
return 1;
}
void print_color(const VTermColor *col)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
if (VTERM_COLOR_IS_RGB(col)) {
fprintf(f,"rgb(%d,%d,%d", col->rgb.red, col->rgb.green, col->rgb.blue);
}
else if (VTERM_COLOR_IS_INDEXED(col)) {
fprintf(f,"idx(%d", col->indexed.idx);
}
else {
fprintf(f,"invalid(%d", col->type);
}
if (VTERM_COLOR_IS_DEFAULT_FG(col)) {
fprintf(f,",is_default_fg");
}
if (VTERM_COLOR_IS_DEFAULT_BG(col)) {
fprintf(f,",is_default_bg");
}
fprintf(f,")");
fclose(f);
}
bool want_state_settermprop;
int state_settermprop(VTermProp prop, VTermValue *val, void *user)
{
if(!want_state_settermprop) {
return 1;
}
int errcode = 0;
FILE *f = fopen(VTERM_TEST_FILE, "a");
VTermValueType type = vterm_get_prop_type(prop);
switch(type) {
case VTERM_VALUETYPE_BOOL:
fprintf(f,"settermprop %d %s\n", prop, val->boolean ? "true" : "false");
errcode = 1;
goto end;
case VTERM_VALUETYPE_INT:
fprintf(f,"settermprop %d %d\n", prop, val->number);
errcode = 1;
goto end;
case VTERM_VALUETYPE_STRING:
fprintf(f,"settermprop %d %s\"%.*s\"%s\n", prop,
val->string.initial ? "[" : "", (int)val->string.len, val->string.str, val->string.final ? "]" : "");
errcode=0;
goto end;
case VTERM_VALUETYPE_COLOR:
fprintf(f,"settermprop %d ", prop);
print_color(&val->color);
fprintf(f,"\n");
errcode=1;
goto end;
case VTERM_N_VALUETYPES:
goto end;
}
end:
fclose(f);
return errcode;
}
bool want_state_erase;
int state_erase(VTermRect rect, int selective, void *user)
{
if(!want_state_erase) {
return 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"erase %d..%d,%d..%d%s\n",
rect.start_row, rect.end_row, rect.start_col, rect.end_col,
selective ? " selective" : "");
fclose(f);
return 1;
}
struct {
int bold;
int underline;
int italic;
int blink;
int reverse;
int conceal;
int strike;
int font;
int small;
int baseline;
VTermColor foreground;
VTermColor background;
} state_pen;
int state_setpenattr(VTermAttr attr, VTermValue *val, void *user)
{
switch(attr) {
case VTERM_ATTR_BOLD:
state_pen.bold = val->boolean;
break;
case VTERM_ATTR_UNDERLINE:
state_pen.underline = val->number;
break;
case VTERM_ATTR_ITALIC:
state_pen.italic = val->boolean;
break;
case VTERM_ATTR_BLINK:
state_pen.blink = val->boolean;
break;
case VTERM_ATTR_REVERSE:
state_pen.reverse = val->boolean;
break;
case VTERM_ATTR_CONCEAL:
state_pen.conceal = val->boolean;
break;
case VTERM_ATTR_STRIKE:
state_pen.strike = val->boolean;
break;
case VTERM_ATTR_FONT:
state_pen.font = val->number;
break;
case VTERM_ATTR_SMALL:
state_pen.small = val->boolean;
break;
case VTERM_ATTR_BASELINE:
state_pen.baseline = val->number;
break;
case VTERM_ATTR_FOREGROUND:
state_pen.foreground = val->color;
break;
case VTERM_ATTR_BACKGROUND:
state_pen.background = val->color;
break;
case VTERM_N_ATTRS:
return 0;
default:
break;
}
return 1;
}
bool want_state_scrollback;
int state_sb_clear(void *user) {
if(!want_state_scrollback) {
return 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"sb_clear\n");
fclose(f);
return 0;
}
bool want_screen_scrollback;
int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user)
{
if(!want_screen_scrollback) {
return 1;
}
int eol = cols;
while(eol && !cells[eol-1].chars[0]) {
eol--;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "sb_pushline %d =", cols);
for(int c = 0; c < eol; c++) {
fprintf(f, " %02X", cells[c].chars[0]);
}
fprintf(f, "\n");
fclose(f);
return 1;
}
int screen_sb_popline(int cols, VTermScreenCell *cells, void *user)
{
if(!want_screen_scrollback) {
return 0;
}
// All lines of scrollback contain "ABCDE"
for(int col = 0; col < cols; col++) {
if(col < 5) {
cells[col].chars[0] = (uint32_t)('A' + col);
} else {
cells[col].chars[0] = 0;
}
cells[col].width = 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f,"sb_popline %d\n", cols);
fclose(f);
return 1;
}
int screen_sb_clear(void *user)
{
if(!want_screen_scrollback) {
return 1;
}
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "sb_clear\n");
fclose(f);
return 0;
}
void term_output(const char *s, size_t len, void *user)
{
FILE *f = fopen(VTERM_TEST_FILE, "a");
fprintf(f, "output ");
for(size_t i = 0; i < len; i++) {
fprintf(f, "%x%s", (unsigned char)s[i], i < len-1 ? "," : "\n");
}
fclose(f);
}

View File

@ -0,0 +1,37 @@
#include <stdbool.h>
#include <stdint.h>
#include "nvim/macros_defs.h"
#include "vterm/vterm.h"
int parser_text(const char bytes[], size_t len, void *user);
int parser_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user);
int parser_osc(int command, VTermStringFragment frag, void *user);
int parser_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user);
int parser_apc(VTermStringFragment frag, void *user);
int parser_pm(VTermStringFragment frag, void *user);
int parser_sos(VTermStringFragment frag, void *user);
int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user);
int selection_query(VTermSelectionMask mask, void *user);
int state_putglyph(VTermGlyphInfo *info, VTermPos pos, void *user);
int state_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user);
int state_scrollrect(VTermRect rect, int downward, int rightward, void *user);
int state_moverect(VTermRect dest, VTermRect src, void *user);
int state_settermprop(VTermProp prop, VTermValue *val, void *user);
int state_erase(VTermRect rect, int selective, void *user);
int state_setpenattr(VTermAttr attr, VTermValue *val, void *user);
int state_sb_clear(void *user);
void print_color(const VTermColor *col);
int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user);
int screen_sb_popline(int cols, VTermScreenCell *cells, void *user);
int screen_sb_clear(void *user);
void term_output(const char *s, size_t len, void *user);
EXTERN VTermPos state_pos;
EXTERN bool want_state_putglyph INIT (=false);
EXTERN bool want_state_movecursor INIT(= false);
EXTERN bool want_state_erase INIT(= false);
EXTERN bool want_state_scrollrect INIT(= false);
EXTERN bool want_state_moverect INIT(= false);
EXTERN bool want_state_settermprop INIT(= false);
EXTERN bool want_state_scrollback INIT(= false);
EXTERN bool want_screen_scrollback INIT(= false);

View File

@ -79,7 +79,11 @@ local bit = require('bit')
--- @field vterm_state_set_callbacks function
--- @field vterm_state_set_selection_callbacks function
--- @field vterm_state_set_unrecognised_fallbacks function
local vterm = t.cimport('./src/vterm/vterm.h', './src/vterm/vterm_internal.h')
local vterm = t.cimport(
'./src/vterm/vterm.h',
'./src/vterm/vterm_internal.h',
'./test/unit/fixtures/vterm_test.h'
)
--- @return string
local function read_rm()