more commands and glitches fixed, better debug messages, discard bad unicode
This commit is contained in:
+341
-249
@@ -11,26 +11,27 @@ static const char _ansi_actions[] = {
|
||||
0, 1, 0, 1, 1, 1, 2, 1,
|
||||
3, 1, 4, 1, 5, 1, 6, 1,
|
||||
7, 1, 8, 1, 9, 1, 10, 1,
|
||||
11, 1, 12, 1, 13, 1, 14, 2,
|
||||
2, 5, 2, 10, 11, 2, 10, 12
|
||||
|
||||
11, 1, 12, 1, 13, 1, 14, 1,
|
||||
15, 1, 16, 1, 17, 2, 2, 5,
|
||||
2, 10, 11, 2, 10, 12
|
||||
};
|
||||
|
||||
static const char _ansi_eof_actions[] = {
|
||||
0, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 0, 0, 0, 0,
|
||||
0, 0, 0, 0
|
||||
13, 13, 13, 13, 13, 13, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const int ansi_start = 1;
|
||||
static const int ansi_first_final = 28;
|
||||
static const int ansi_first_final = 30;
|
||||
static const int ansi_error = 0;
|
||||
|
||||
static const int ansi_en_CSI_body = 4;
|
||||
static const int ansi_en_OSC_body = 6;
|
||||
static const int ansi_en_TITLE_body = 26;
|
||||
static const int ansi_en_CSI_body = 5;
|
||||
static const int ansi_en_OSC_body = 7;
|
||||
static const int ansi_en_TITLE_body = 27;
|
||||
static const int ansi_en_charsetcmd_body = 29;
|
||||
static const int ansi_en_main = 1;
|
||||
|
||||
|
||||
@@ -45,10 +46,39 @@ static void ICACHE_FLASH_ATTR
|
||||
resetParserCb(void *arg) {
|
||||
if (cs != ansi_start) {
|
||||
cs = ansi_start;
|
||||
warn("Parser timeout, state reset");
|
||||
apars_reset_utf8buffer();
|
||||
ansi_warn("Parser timeout, state reset");
|
||||
}
|
||||
}
|
||||
|
||||
#define HISTORY_LEN 16
|
||||
|
||||
#if DEBUG_ANSI
|
||||
static char history[HISTORY_LEN + 1];
|
||||
#endif
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_handle_badseq(void)
|
||||
{
|
||||
#if DEBUG_ANSI
|
||||
char buf1[HISTORY_LEN*3+2];
|
||||
char buf2[HISTORY_LEN*3+2];
|
||||
char *b1 = buf1;
|
||||
char *b2 = buf2;
|
||||
char c;
|
||||
|
||||
for(int i=0;i<HISTORY_LEN;i++) {
|
||||
c = history[i];
|
||||
b1 += sprintf(b1, "%2X ", c);
|
||||
if (c < 32 || c > 127) c = '.';
|
||||
b2 += sprintf(b2, "%c ", c);
|
||||
}
|
||||
|
||||
ansi_dbg("Context: %s", buf2);
|
||||
ansi_dbg(" %s", buf1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Linear ANSI chars stream parser
|
||||
*
|
||||
@@ -68,6 +98,7 @@ ansi_parser(const char *newdata, size_t len)
|
||||
// The CSI code is built here
|
||||
static char csi_leading; //!< Leading char, 0 if none
|
||||
static int csi_ni; //!< Number of the active digit
|
||||
static int csi_cnt; //!< Digit count
|
||||
static int csi_n[CSI_N_MAX]; //!< Param digits
|
||||
static char csi_char; //!< CSI action char (end)
|
||||
static char osc_buffer[OSC_CHAR_MAX];
|
||||
@@ -83,24 +114,35 @@ ansi_parser(const char *newdata, size_t len)
|
||||
// Init Ragel on the first run
|
||||
if (cs == -1) {
|
||||
|
||||
/* #line 87 "user/ansi_parser.c" */
|
||||
/* #line 118 "user/ansi_parser.c" */
|
||||
{
|
||||
cs = ansi_start;
|
||||
}
|
||||
|
||||
/* #line 57 "user/ansi_parser.rl" */
|
||||
/* #line 87 "user/ansi_parser.rl" */
|
||||
|
||||
#if DEBUG_ANSI
|
||||
memset(history, 0, sizeof(history));
|
||||
#endif
|
||||
}
|
||||
|
||||
// schedule state reset
|
||||
// schedule state reset after idle timeout
|
||||
if (termconf->parser_tout_ms > 0) {
|
||||
os_timer_disarm(&resetTim);
|
||||
os_timer_setfn(&resetTim, resetParserCb, NULL);
|
||||
os_timer_arm(&resetTim, termconf->parser_tout_ms, 0);
|
||||
}
|
||||
|
||||
#if DEBUG_ANSI
|
||||
for(int i=len; i<HISTORY_LEN; i++) {
|
||||
history[i-len] = history[i];
|
||||
}
|
||||
strcpy(&history[HISTORY_LEN-len], newdata);
|
||||
#endif
|
||||
|
||||
// The parser
|
||||
|
||||
/* #line 104 "user/ansi_parser.c" */
|
||||
/* #line 146 "user/ansi_parser.c" */
|
||||
{
|
||||
const char *_acts;
|
||||
unsigned int _nacts;
|
||||
@@ -117,201 +159,216 @@ case 1:
|
||||
goto tr0;
|
||||
case 2:
|
||||
switch( (*p) ) {
|
||||
case 35: goto tr3;
|
||||
case 91: goto tr5;
|
||||
case 93: goto tr6;
|
||||
case 107: goto tr7;
|
||||
}
|
||||
if ( (*p) < 65 ) {
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr4;
|
||||
} else if ( (*p) > 90 ) {
|
||||
if ( 97 <= (*p) && (*p) <= 122 )
|
||||
goto tr4;
|
||||
} else
|
||||
goto tr4;
|
||||
goto tr2;
|
||||
case 0:
|
||||
goto _out;
|
||||
case 3:
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr8;
|
||||
goto tr2;
|
||||
case 28:
|
||||
if ( (*p) == 27 )
|
||||
goto tr1;
|
||||
goto tr0;
|
||||
case 4:
|
||||
switch( (*p) ) {
|
||||
case 59: goto tr11;
|
||||
case 64: goto tr12;
|
||||
case 32: goto tr3;
|
||||
case 35: goto tr4;
|
||||
case 91: goto tr7;
|
||||
case 93: goto tr8;
|
||||
case 107: goto tr9;
|
||||
}
|
||||
if ( (*p) < 60 ) {
|
||||
if ( (*p) > 47 ) {
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr10;
|
||||
goto tr6;
|
||||
} else if ( (*p) >= 40 )
|
||||
goto tr5;
|
||||
} else if ( (*p) > 62 ) {
|
||||
if ( (*p) > 90 ) {
|
||||
if ( 97 <= (*p) && (*p) <= 122 )
|
||||
goto tr6;
|
||||
} else if ( (*p) >= 65 )
|
||||
goto tr6;
|
||||
} else
|
||||
goto tr6;
|
||||
goto tr2;
|
||||
case 0:
|
||||
goto _out;
|
||||
case 3:
|
||||
if ( 70 <= (*p) && (*p) <= 71 )
|
||||
goto tr10;
|
||||
goto tr2;
|
||||
case 30:
|
||||
if ( (*p) == 27 )
|
||||
goto tr1;
|
||||
goto tr0;
|
||||
case 4:
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr11;
|
||||
goto tr2;
|
||||
case 5:
|
||||
switch( (*p) ) {
|
||||
case 59: goto tr14;
|
||||
case 64: goto tr15;
|
||||
}
|
||||
if ( (*p) < 60 ) {
|
||||
if ( (*p) > 47 ) {
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr13;
|
||||
} else if ( (*p) >= 32 )
|
||||
goto tr9;
|
||||
goto tr12;
|
||||
} else if ( (*p) > 63 ) {
|
||||
if ( (*p) > 90 ) {
|
||||
if ( 96 <= (*p) && (*p) <= 122 )
|
||||
goto tr13;
|
||||
goto tr16;
|
||||
} else if ( (*p) >= 65 )
|
||||
goto tr13;
|
||||
goto tr16;
|
||||
} else
|
||||
goto tr9;
|
||||
goto tr2;
|
||||
case 5:
|
||||
if ( (*p) == 59 )
|
||||
goto tr11;
|
||||
if ( (*p) < 64 ) {
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr10;
|
||||
} else if ( (*p) > 90 ) {
|
||||
if ( 96 <= (*p) && (*p) <= 122 )
|
||||
goto tr13;
|
||||
} else
|
||||
goto tr13;
|
||||
goto tr2;
|
||||
case 29:
|
||||
goto tr2;
|
||||
case 30:
|
||||
if ( (*p) == 59 )
|
||||
goto tr11;
|
||||
if ( (*p) < 64 ) {
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr10;
|
||||
} else if ( (*p) > 90 ) {
|
||||
if ( 96 <= (*p) && (*p) <= 122 )
|
||||
goto tr13;
|
||||
} else
|
||||
goto tr13;
|
||||
goto tr12;
|
||||
goto tr2;
|
||||
case 6:
|
||||
switch( (*p) ) {
|
||||
case 48: goto tr14;
|
||||
case 66: goto tr15;
|
||||
case 84: goto tr16;
|
||||
case 87: goto tr17;
|
||||
}
|
||||
goto tr2;
|
||||
case 7:
|
||||
if ( (*p) == 59 )
|
||||
goto tr18;
|
||||
goto tr14;
|
||||
if ( (*p) < 64 ) {
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr13;
|
||||
} else if ( (*p) > 90 ) {
|
||||
if ( 96 <= (*p) && (*p) <= 122 )
|
||||
goto tr16;
|
||||
} else
|
||||
goto tr16;
|
||||
goto tr2;
|
||||
case 8:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr20;
|
||||
case 27: goto tr21;
|
||||
}
|
||||
goto tr19;
|
||||
case 31:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr20;
|
||||
case 27: goto tr21;
|
||||
}
|
||||
goto tr19;
|
||||
case 9:
|
||||
if ( (*p) == 92 )
|
||||
goto tr22;
|
||||
goto tr2;
|
||||
case 32:
|
||||
if ( (*p) == 59 )
|
||||
goto tr14;
|
||||
if ( (*p) < 64 ) {
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr13;
|
||||
} else if ( (*p) > 90 ) {
|
||||
if ( 96 <= (*p) && (*p) <= 122 )
|
||||
goto tr16;
|
||||
} else
|
||||
goto tr16;
|
||||
goto tr2;
|
||||
case 10:
|
||||
if ( (*p) == 84 )
|
||||
goto tr23;
|
||||
goto tr2;
|
||||
case 11:
|
||||
if ( (*p) == 78 )
|
||||
goto tr24;
|
||||
goto tr2;
|
||||
case 12:
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr25;
|
||||
goto tr2;
|
||||
case 13:
|
||||
if ( (*p) == 61 )
|
||||
goto tr26;
|
||||
goto tr2;
|
||||
case 14:
|
||||
case 7:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr28;
|
||||
case 27: goto tr29;
|
||||
case 48: goto tr17;
|
||||
case 66: goto tr18;
|
||||
case 84: goto tr19;
|
||||
case 87: goto tr20;
|
||||
}
|
||||
goto tr27;
|
||||
goto tr2;
|
||||
case 8:
|
||||
if ( (*p) == 59 )
|
||||
goto tr21;
|
||||
goto tr2;
|
||||
case 9:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr23;
|
||||
case 27: goto tr24;
|
||||
}
|
||||
goto tr22;
|
||||
case 33:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr28;
|
||||
case 27: goto tr29;
|
||||
case 7: goto tr23;
|
||||
case 27: goto tr24;
|
||||
}
|
||||
goto tr27;
|
||||
case 15:
|
||||
goto tr22;
|
||||
case 10:
|
||||
if ( (*p) == 92 )
|
||||
goto tr30;
|
||||
goto tr25;
|
||||
goto tr2;
|
||||
case 16:
|
||||
if ( (*p) == 73 )
|
||||
goto tr31;
|
||||
case 34:
|
||||
goto tr2;
|
||||
case 17:
|
||||
case 11:
|
||||
if ( (*p) == 84 )
|
||||
goto tr32;
|
||||
goto tr26;
|
||||
goto tr2;
|
||||
case 18:
|
||||
if ( (*p) == 76 )
|
||||
case 12:
|
||||
if ( (*p) == 78 )
|
||||
goto tr27;
|
||||
goto tr2;
|
||||
case 13:
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr28;
|
||||
goto tr2;
|
||||
case 14:
|
||||
if ( (*p) == 61 )
|
||||
goto tr29;
|
||||
goto tr2;
|
||||
case 15:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr31;
|
||||
case 27: goto tr32;
|
||||
}
|
||||
goto tr30;
|
||||
case 35:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr31;
|
||||
case 27: goto tr32;
|
||||
}
|
||||
goto tr30;
|
||||
case 16:
|
||||
if ( (*p) == 92 )
|
||||
goto tr33;
|
||||
goto tr2;
|
||||
case 19:
|
||||
if ( (*p) == 69 )
|
||||
case 17:
|
||||
if ( (*p) == 73 )
|
||||
goto tr34;
|
||||
goto tr2;
|
||||
case 20:
|
||||
if ( (*p) == 61 )
|
||||
case 18:
|
||||
if ( (*p) == 84 )
|
||||
goto tr35;
|
||||
goto tr2;
|
||||
case 21:
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
case 19:
|
||||
if ( (*p) == 76 )
|
||||
goto tr36;
|
||||
goto tr2;
|
||||
case 20:
|
||||
if ( (*p) == 69 )
|
||||
goto tr37;
|
||||
goto tr2;
|
||||
case 21:
|
||||
if ( (*p) == 61 )
|
||||
goto tr38;
|
||||
goto tr2;
|
||||
case 22:
|
||||
if ( (*p) == 59 )
|
||||
goto tr37;
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr36;
|
||||
goto tr2;
|
||||
case 23:
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr38;
|
||||
goto tr2;
|
||||
case 24:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr39;
|
||||
case 27: goto tr40;
|
||||
}
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr38;
|
||||
goto tr2;
|
||||
case 25:
|
||||
if ( (*p) == 92 )
|
||||
goto tr39;
|
||||
goto tr2;
|
||||
case 26:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr42;
|
||||
case 27: goto tr43;
|
||||
}
|
||||
goto tr41;
|
||||
case 34:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr42;
|
||||
case 27: goto tr43;
|
||||
}
|
||||
goto tr41;
|
||||
case 27:
|
||||
if ( (*p) == 92 )
|
||||
goto tr44;
|
||||
case 23:
|
||||
if ( (*p) == 59 )
|
||||
goto tr40;
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr39;
|
||||
goto tr2;
|
||||
case 35:
|
||||
case 24:
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr41;
|
||||
goto tr2;
|
||||
case 25:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr42;
|
||||
case 27: goto tr43;
|
||||
}
|
||||
if ( 48 <= (*p) && (*p) <= 57 )
|
||||
goto tr41;
|
||||
goto tr2;
|
||||
case 26:
|
||||
if ( (*p) == 92 )
|
||||
goto tr42;
|
||||
goto tr2;
|
||||
case 27:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr45;
|
||||
case 27: goto tr46;
|
||||
}
|
||||
goto tr44;
|
||||
case 36:
|
||||
switch( (*p) ) {
|
||||
case 7: goto tr45;
|
||||
case 27: goto tr46;
|
||||
}
|
||||
goto tr44;
|
||||
case 28:
|
||||
if ( (*p) == 92 )
|
||||
goto tr47;
|
||||
goto tr2;
|
||||
case 37:
|
||||
goto tr2;
|
||||
case 29:
|
||||
goto tr48;
|
||||
case 38:
|
||||
goto tr2;
|
||||
}
|
||||
|
||||
@@ -319,101 +376,112 @@ case 35:
|
||||
tr0: cs = 1; goto f1;
|
||||
tr1: cs = 2; goto _again;
|
||||
tr3: cs = 3; goto _again;
|
||||
tr9: cs = 5; goto f7;
|
||||
tr10: cs = 5; goto f8;
|
||||
tr11: cs = 5; goto f9;
|
||||
tr14: cs = 7; goto _again;
|
||||
tr18: cs = 8; goto _again;
|
||||
tr19: cs = 8; goto f12;
|
||||
tr4: cs = 4; goto _again;
|
||||
tr12: cs = 6; goto f9;
|
||||
tr13: cs = 6; goto f10;
|
||||
tr14: cs = 6; goto f11;
|
||||
tr17: cs = 8; goto _again;
|
||||
tr21: cs = 9; goto _again;
|
||||
tr15: cs = 10; goto _again;
|
||||
tr23: cs = 11; goto _again;
|
||||
tr24: cs = 12; goto _again;
|
||||
tr25: cs = 13; goto f8;
|
||||
tr26: cs = 14; goto _again;
|
||||
tr27: cs = 14; goto f12;
|
||||
tr22: cs = 9; goto f14;
|
||||
tr24: cs = 10; goto _again;
|
||||
tr18: cs = 11; goto _again;
|
||||
tr26: cs = 12; goto _again;
|
||||
tr27: cs = 13; goto _again;
|
||||
tr28: cs = 14; goto f10;
|
||||
tr29: cs = 15; goto _again;
|
||||
tr16: cs = 16; goto _again;
|
||||
tr31: cs = 17; goto _again;
|
||||
tr32: cs = 18; goto _again;
|
||||
tr33: cs = 19; goto _again;
|
||||
tr34: cs = 20; goto _again;
|
||||
tr17: cs = 21; goto _again;
|
||||
tr36: cs = 22; goto f8;
|
||||
tr37: cs = 23; goto f9;
|
||||
tr38: cs = 24; goto f8;
|
||||
tr40: cs = 25; goto _again;
|
||||
tr41: cs = 26; goto f12;
|
||||
tr43: cs = 27; goto _again;
|
||||
tr4: cs = 28; goto f2;
|
||||
tr5: cs = 28; goto f3;
|
||||
tr6: cs = 28; goto f4;
|
||||
tr7: cs = 28; goto f5;
|
||||
tr8: cs = 28; goto f6;
|
||||
tr13: cs = 29; goto f11;
|
||||
tr12: cs = 30; goto f10;
|
||||
tr20: cs = 31; goto f13;
|
||||
tr35: cs = 32; goto f5;
|
||||
tr22: cs = 32; goto f14;
|
||||
tr30: cs = 32; goto f16;
|
||||
tr39: cs = 32; goto f17;
|
||||
tr28: cs = 33; goto f15;
|
||||
tr42: cs = 34; goto f13;
|
||||
tr44: cs = 35; goto f14;
|
||||
tr30: cs = 15; goto f14;
|
||||
tr32: cs = 16; goto _again;
|
||||
tr19: cs = 17; goto _again;
|
||||
tr34: cs = 18; goto _again;
|
||||
tr35: cs = 19; goto _again;
|
||||
tr36: cs = 20; goto _again;
|
||||
tr37: cs = 21; goto _again;
|
||||
tr20: cs = 22; goto _again;
|
||||
tr39: cs = 23; goto f10;
|
||||
tr40: cs = 24; goto f11;
|
||||
tr41: cs = 25; goto f10;
|
||||
tr43: cs = 26; goto _again;
|
||||
tr44: cs = 27; goto f14;
|
||||
tr46: cs = 28; goto _again;
|
||||
tr5: cs = 30; goto f2;
|
||||
tr6: cs = 30; goto f3;
|
||||
tr7: cs = 30; goto f4;
|
||||
tr8: cs = 30; goto f5;
|
||||
tr9: cs = 30; goto f6;
|
||||
tr10: cs = 30; goto f7;
|
||||
tr11: cs = 30; goto f8;
|
||||
tr16: cs = 31; goto f13;
|
||||
tr15: cs = 32; goto f12;
|
||||
tr23: cs = 33; goto f15;
|
||||
tr38: cs = 34; goto f6;
|
||||
tr25: cs = 34; goto f16;
|
||||
tr33: cs = 34; goto f18;
|
||||
tr42: cs = 34; goto f19;
|
||||
tr31: cs = 35; goto f17;
|
||||
tr45: cs = 36; goto f15;
|
||||
tr47: cs = 37; goto f16;
|
||||
tr48: cs = 38; goto f20;
|
||||
|
||||
f1: _acts = _ansi_actions + 1; goto execFuncs;
|
||||
f3: _acts = _ansi_actions + 3; goto execFuncs;
|
||||
f7: _acts = _ansi_actions + 5; goto execFuncs;
|
||||
f8: _acts = _ansi_actions + 7; goto execFuncs;
|
||||
f9: _acts = _ansi_actions + 9; goto execFuncs;
|
||||
f11: _acts = _ansi_actions + 11; goto execFuncs;
|
||||
f4: _acts = _ansi_actions + 3; goto execFuncs;
|
||||
f9: _acts = _ansi_actions + 5; goto execFuncs;
|
||||
f10: _acts = _ansi_actions + 7; goto execFuncs;
|
||||
f11: _acts = _ansi_actions + 9; goto execFuncs;
|
||||
f13: _acts = _ansi_actions + 11; goto execFuncs;
|
||||
f0: _acts = _ansi_actions + 13; goto execFuncs;
|
||||
f4: _acts = _ansi_actions + 15; goto execFuncs;
|
||||
f5: _acts = _ansi_actions + 17; goto execFuncs;
|
||||
f17: _acts = _ansi_actions + 19; goto execFuncs;
|
||||
f12: _acts = _ansi_actions + 21; goto execFuncs;
|
||||
f14: _acts = _ansi_actions + 23; goto execFuncs;
|
||||
f16: _acts = _ansi_actions + 25; goto execFuncs;
|
||||
f6: _acts = _ansi_actions + 27; goto execFuncs;
|
||||
f2: _acts = _ansi_actions + 29; goto execFuncs;
|
||||
f10: _acts = _ansi_actions + 31; goto execFuncs;
|
||||
f13: _acts = _ansi_actions + 34; goto execFuncs;
|
||||
f15: _acts = _ansi_actions + 37; goto execFuncs;
|
||||
f5: _acts = _ansi_actions + 15; goto execFuncs;
|
||||
f6: _acts = _ansi_actions + 17; goto execFuncs;
|
||||
f19: _acts = _ansi_actions + 19; goto execFuncs;
|
||||
f14: _acts = _ansi_actions + 21; goto execFuncs;
|
||||
f16: _acts = _ansi_actions + 23; goto execFuncs;
|
||||
f18: _acts = _ansi_actions + 25; goto execFuncs;
|
||||
f8: _acts = _ansi_actions + 27; goto execFuncs;
|
||||
f3: _acts = _ansi_actions + 29; goto execFuncs;
|
||||
f7: _acts = _ansi_actions + 31; goto execFuncs;
|
||||
f2: _acts = _ansi_actions + 33; goto execFuncs;
|
||||
f20: _acts = _ansi_actions + 35; goto execFuncs;
|
||||
f12: _acts = _ansi_actions + 37; goto execFuncs;
|
||||
f15: _acts = _ansi_actions + 40; goto execFuncs;
|
||||
f17: _acts = _ansi_actions + 43; goto execFuncs;
|
||||
|
||||
execFuncs:
|
||||
_nacts = *_acts++;
|
||||
while ( _nacts-- > 0 ) {
|
||||
switch ( *_acts++ ) {
|
||||
case 0:
|
||||
/* #line 76 "user/ansi_parser.rl" */
|
||||
/* #line 117 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_plainchar((*p));
|
||||
if ((*p) != 0) {
|
||||
apars_handle_plainchar((*p));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* #line 83 "user/ansi_parser.rl" */
|
||||
/* #line 126 "user/ansi_parser.rl" */
|
||||
{
|
||||
// Reset the CSI builder
|
||||
csi_leading = csi_char = 0;
|
||||
csi_ni = 0;
|
||||
csi_cnt = 0;
|
||||
|
||||
// Zero out digits
|
||||
for(int i = 0; i < CSI_N_MAX; i++) {
|
||||
csi_n[i] = 0;
|
||||
}
|
||||
|
||||
{cs = 4;goto _again;}
|
||||
{cs = 5;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* #line 96 "user/ansi_parser.rl" */
|
||||
/* #line 140 "user/ansi_parser.rl" */
|
||||
{
|
||||
csi_leading = (*p);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* #line 100 "user/ansi_parser.rl" */
|
||||
/* #line 144 "user/ansi_parser.rl" */
|
||||
{
|
||||
if (csi_cnt == 0) csi_cnt = 1;
|
||||
// x10 + digit
|
||||
if (csi_ni < CSI_N_MAX) {
|
||||
csi_n[csi_ni] = csi_n[csi_ni]*10 + ((*p) - '0');
|
||||
@@ -421,30 +489,31 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
/* #line 107 "user/ansi_parser.rl" */
|
||||
/* #line 152 "user/ansi_parser.rl" */
|
||||
{
|
||||
if (csi_cnt == 0) csi_cnt = 1; // handle case when first arg is empty
|
||||
csi_cnt++;
|
||||
csi_ni++;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
/* #line 111 "user/ansi_parser.rl" */
|
||||
/* #line 158 "user/ansi_parser.rl" */
|
||||
{
|
||||
csi_char = (*p);
|
||||
|
||||
apars_handle_CSI(csi_leading, csi_n, csi_char);
|
||||
|
||||
apars_handle_CSI(csi_leading, csi_n, csi_cnt, csi_char);
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
/* #line 119 "user/ansi_parser.rl" */
|
||||
/* #line 164 "user/ansi_parser.rl" */
|
||||
{
|
||||
ansi_warn("Invalid escape sequence discarded.");
|
||||
apars_handle_badseq();
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
/* #line 136 "user/ansi_parser.rl" */
|
||||
/* #line 182 "user/ansi_parser.rl" */
|
||||
{
|
||||
csi_ni = 0;
|
||||
|
||||
@@ -456,32 +525,32 @@ execFuncs:
|
||||
osc_bi = 0;
|
||||
osc_buffer[0] = '\0';
|
||||
|
||||
{cs = 6;goto _again;}
|
||||
{cs = 7;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
/* #line 151 "user/ansi_parser.rl" */
|
||||
/* #line 197 "user/ansi_parser.rl" */
|
||||
{
|
||||
osc_bi = 0;
|
||||
osc_buffer[0] = '\0';
|
||||
{cs = 26;goto _again;}
|
||||
{cs = 27;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
/* #line 157 "user/ansi_parser.rl" */
|
||||
/* #line 203 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_OSC_SetScreenSize(csi_n[0], csi_n[1]);
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
/* #line 162 "user/ansi_parser.rl" */
|
||||
/* #line 208 "user/ansi_parser.rl" */
|
||||
{
|
||||
osc_buffer[osc_bi++] = (*p);
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
/* #line 166 "user/ansi_parser.rl" */
|
||||
/* #line 212 "user/ansi_parser.rl" */
|
||||
{
|
||||
osc_buffer[osc_bi++] = '\0';
|
||||
apars_handle_OSC_SetTitle(osc_buffer);
|
||||
@@ -489,7 +558,7 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
/* #line 172 "user/ansi_parser.rl" */
|
||||
/* #line 218 "user/ansi_parser.rl" */
|
||||
{
|
||||
osc_buffer[osc_bi++] = '\0';
|
||||
apars_handle_OSC_SetButton(csi_n[0], osc_buffer);
|
||||
@@ -497,20 +566,42 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
/* #line 204 "user/ansi_parser.rl" */
|
||||
/* #line 250 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_hashCode((*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
/* #line 209 "user/ansi_parser.rl" */
|
||||
/* #line 255 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_shortCode((*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
/* #line 514 "user/ansi_parser.c" */
|
||||
case 15:
|
||||
/* #line 260 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_setXCtrls((*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
/* #line 265 "user/ansi_parser.rl" */
|
||||
{
|
||||
// abuse the buffer for storing the leading char
|
||||
osc_buffer[0] = (*p);
|
||||
{cs = 29;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
/* #line 271 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_characterSet(osc_buffer[0], (*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
/* #line 605 "user/ansi_parser.c" */
|
||||
}
|
||||
}
|
||||
goto _again;
|
||||
@@ -528,15 +619,16 @@ _again:
|
||||
while ( __nacts-- > 0 ) {
|
||||
switch ( *__acts++ ) {
|
||||
case 6:
|
||||
/* #line 119 "user/ansi_parser.rl" */
|
||||
/* #line 164 "user/ansi_parser.rl" */
|
||||
{
|
||||
ansi_warn("Invalid escape sequence discarded.");
|
||||
apars_handle_badseq();
|
||||
{cs = 1; if ( p == pe )
|
||||
goto _test_eof;
|
||||
goto _again;}
|
||||
}
|
||||
break;
|
||||
/* #line 540 "user/ansi_parser.c" */
|
||||
/* #line 632 "user/ansi_parser.c" */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -544,7 +636,7 @@ goto _again;}
|
||||
_out: {}
|
||||
}
|
||||
|
||||
/* #line 229 "user/ansi_parser.rl" */
|
||||
/* #line 295 "user/ansi_parser.rl" */
|
||||
|
||||
}
|
||||
|
||||
|
||||
+17
-2
@@ -8,14 +8,26 @@
|
||||
#define CSI_N_MAX 3
|
||||
#define OSC_CHAR_MAX TERM_TITLE_LEN
|
||||
|
||||
extern void apars_handle_badseq(void);
|
||||
extern void apars_handle_plainchar(char c);
|
||||
extern void apars_handle_CSI(char leadchar, int *params, char keychar);
|
||||
extern void apars_handle_CSI(char leadchar, int *params, int count, char keychar);
|
||||
extern void apars_handle_OSC_SetScreenSize(int rows, int cols);
|
||||
extern void apars_handle_OSC_SetButton(int num, const char *buffer);
|
||||
extern void apars_handle_OSC_SetTitle(const char *buffer);
|
||||
extern void apars_handle_shortCode(char c);
|
||||
extern void apars_handle_hashCode(char c);
|
||||
extern void apars_handle_characterSet(char leadchar, char c);
|
||||
extern void apars_handle_setXCtrls(char c);
|
||||
extern void apars_reset_utf8buffer(void);
|
||||
|
||||
// defined in the makefile
|
||||
#if DEBUG_ANSI
|
||||
#define ansi_warn warn
|
||||
#define ansi_dbg warn
|
||||
#else
|
||||
#define ansi_warn(...)
|
||||
#define ansi_dbg(...)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Linear ANSI chars stream parser
|
||||
@@ -32,4 +44,7 @@ extern void apars_handle_hashCode(char c);
|
||||
*/
|
||||
void ansi_parser(const char *newdata, size_t len);
|
||||
|
||||
/** This shows a short error message and prints the history (if any) */
|
||||
void apars_handle_badseq(void);
|
||||
|
||||
#endif // ANSI_PARSER_H
|
||||
|
||||
+73
-7
@@ -16,10 +16,39 @@ static void ICACHE_FLASH_ATTR
|
||||
resetParserCb(void *arg) {
|
||||
if (cs != ansi_start) {
|
||||
cs = ansi_start;
|
||||
warn("Parser timeout, state reset");
|
||||
apars_reset_utf8buffer();
|
||||
ansi_warn("Parser timeout, state reset");
|
||||
}
|
||||
}
|
||||
|
||||
#define HISTORY_LEN 16
|
||||
|
||||
#if DEBUG_ANSI
|
||||
static char history[HISTORY_LEN + 1];
|
||||
#endif
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_handle_badseq(void)
|
||||
{
|
||||
#if DEBUG_ANSI
|
||||
char buf1[HISTORY_LEN*3+2];
|
||||
char buf2[HISTORY_LEN*3+2];
|
||||
char *b1 = buf1;
|
||||
char *b2 = buf2;
|
||||
char c;
|
||||
|
||||
for(int i=0;i<HISTORY_LEN;i++) {
|
||||
c = history[i];
|
||||
b1 += sprintf(b1, "%2X ", c);
|
||||
if (c < 32 || c > 127) c = '.';
|
||||
b2 += sprintf(b2, "%c ", c);
|
||||
}
|
||||
|
||||
ansi_dbg("Context: %s", buf2);
|
||||
ansi_dbg(" %s", buf1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Linear ANSI chars stream parser
|
||||
*
|
||||
@@ -39,6 +68,7 @@ ansi_parser(const char *newdata, size_t len)
|
||||
// The CSI code is built here
|
||||
static char csi_leading; //!< Leading char, 0 if none
|
||||
static int csi_ni; //!< Number of the active digit
|
||||
static int csi_cnt; //!< Digit count
|
||||
static int csi_n[CSI_N_MAX]; //!< Param digits
|
||||
static char csi_char; //!< CSI action char (end)
|
||||
static char osc_buffer[OSC_CHAR_MAX];
|
||||
@@ -54,15 +84,26 @@ ansi_parser(const char *newdata, size_t len)
|
||||
// Init Ragel on the first run
|
||||
if (cs == -1) {
|
||||
%% write init;
|
||||
|
||||
#if DEBUG_ANSI
|
||||
memset(history, 0, sizeof(history));
|
||||
#endif
|
||||
}
|
||||
|
||||
// schedule state reset
|
||||
// schedule state reset after idle timeout
|
||||
if (termconf->parser_tout_ms > 0) {
|
||||
os_timer_disarm(&resetTim);
|
||||
os_timer_setfn(&resetTim, resetParserCb, NULL);
|
||||
os_timer_arm(&resetTim, termconf->parser_tout_ms, 0);
|
||||
}
|
||||
|
||||
#if DEBUG_ANSI
|
||||
for(int i=len; i<HISTORY_LEN; i++) {
|
||||
history[i-len] = history[i];
|
||||
}
|
||||
strcpy(&history[HISTORY_LEN-len], newdata);
|
||||
#endif
|
||||
|
||||
// The parser
|
||||
%%{
|
||||
#/*
|
||||
@@ -74,7 +115,9 @@ ansi_parser(const char *newdata, size_t len)
|
||||
# --- Regular characters to be printed ---
|
||||
|
||||
action plain_char {
|
||||
apars_handle_plainchar(fc);
|
||||
if (fc != 0) {
|
||||
apars_handle_plainchar(fc);
|
||||
}
|
||||
}
|
||||
|
||||
# --- CSI CSI commands (Select Graphic Rendition) ---
|
||||
@@ -84,6 +127,7 @@ ansi_parser(const char *newdata, size_t len)
|
||||
// Reset the CSI builder
|
||||
csi_leading = csi_char = 0;
|
||||
csi_ni = 0;
|
||||
csi_cnt = 0;
|
||||
|
||||
// Zero out digits
|
||||
for(int i = 0; i < CSI_N_MAX; i++) {
|
||||
@@ -98,6 +142,7 @@ ansi_parser(const char *newdata, size_t len)
|
||||
}
|
||||
|
||||
action CSI_digit {
|
||||
if (csi_cnt == 0) csi_cnt = 1;
|
||||
// x10 + digit
|
||||
if (csi_ni < CSI_N_MAX) {
|
||||
csi_n[csi_ni] = csi_n[csi_ni]*10 + (fc - '0');
|
||||
@@ -105,18 +150,19 @@ ansi_parser(const char *newdata, size_t len)
|
||||
}
|
||||
|
||||
action CSI_semi {
|
||||
if (csi_cnt == 0) csi_cnt = 1; // handle case when first arg is empty
|
||||
csi_cnt++;
|
||||
csi_ni++;
|
||||
}
|
||||
|
||||
action CSI_end {
|
||||
csi_char = fc;
|
||||
|
||||
apars_handle_CSI(csi_leading, csi_n, csi_char);
|
||||
|
||||
apars_handle_CSI(csi_leading, csi_n, csi_cnt, csi_char);
|
||||
fgoto main;
|
||||
}
|
||||
|
||||
action errBadSeq {
|
||||
ansi_warn("Invalid escape sequence discarded.");
|
||||
apars_handle_badseq();
|
||||
fgoto main;
|
||||
}
|
||||
@@ -211,6 +257,24 @@ ansi_parser(const char *newdata, size_t len)
|
||||
fgoto main;
|
||||
}
|
||||
|
||||
action SetXCtrls {
|
||||
apars_handle_setXCtrls(fc);
|
||||
fgoto main;
|
||||
}
|
||||
|
||||
action CharsetCmd_start {
|
||||
// abuse the buffer for storing the leading char
|
||||
osc_buffer[0] = fc;
|
||||
fgoto charsetcmd_body;
|
||||
}
|
||||
|
||||
action CharsetCmd_end {
|
||||
apars_handle_characterSet(osc_buffer[0], fc);
|
||||
fgoto main;
|
||||
}
|
||||
|
||||
charsetcmd_body := (any @CharsetCmd_end) $!errBadSeq;
|
||||
|
||||
# --- Main parser loop ---
|
||||
|
||||
main :=
|
||||
@@ -220,7 +284,9 @@ ansi_parser(const char *newdata, size_t len)
|
||||
(']' @OSC_start) |
|
||||
('#' digit @HASH_code) |
|
||||
('k' @SetTitle_start) |
|
||||
([a-jl-zA-Z0-9] @SHORT_code)
|
||||
([a-jl-zA-Z0-9=<>] @SHORT_code) |
|
||||
([()*+-./] @CharsetCmd_start) |
|
||||
(' ' [FG] @SetXCtrls)
|
||||
)
|
||||
)+ $!errBadSeq;
|
||||
|
||||
|
||||
+132
-23
@@ -39,28 +39,53 @@ apars_handle_plainchar(char c)
|
||||
utf_j = 1;
|
||||
}
|
||||
else {
|
||||
utf_collect[utf_j++] = c;
|
||||
if (utf_j >= utf_i) {
|
||||
screen_putchar(utf_collect);
|
||||
utf_i = 0;
|
||||
utf_j = 0;
|
||||
memset(utf_collect, 0, 4);
|
||||
if ((c & 0xC0) != 0x80) {
|
||||
// bad UTF
|
||||
ansi_warn("Bad UTF-8");
|
||||
apars_reset_utf8buffer();
|
||||
}
|
||||
else {
|
||||
utf_collect[utf_j++] = c;
|
||||
if (utf_j >= utf_i) {
|
||||
screen_putchar(utf_collect);
|
||||
apars_reset_utf8buffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c == 14 || c == 15) { // pushIn, pushOut
|
||||
//ansi_warn("char %d ignored", c);
|
||||
// TODO implement for charset switching
|
||||
return;
|
||||
}
|
||||
|
||||
utf_collect[0] = c;
|
||||
utf_collect[1] = 0; // just to make sure it's closed...
|
||||
screen_putchar(utf_collect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bad sequence received, show warning
|
||||
*/
|
||||
void apars_handle_badseq(void)
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_reset_utf8buffer(void)
|
||||
{
|
||||
warn("Invalid escape sequence discarded.");
|
||||
utf_i = 0;
|
||||
utf_j = 0;
|
||||
memset(utf_collect, 0, 4);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_handle_characterSet(char leadchar, char c)
|
||||
{
|
||||
// TODO implement for charset switching
|
||||
// ansi_warn("NOIMPL charset cmd %c%c", leadchar, c);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_handle_setXCtrls(char c)
|
||||
{
|
||||
// this does not seem to do anything, sent by some unix programs
|
||||
// ansi_warn("NOIMPL Select %cbit ctrls", c=='F'? '7':'8');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +95,7 @@ void apars_handle_badseq(void)
|
||||
* \param keychar - the char terminating the sequence
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_handle_CSI(char leadchar, int *params, char keychar)
|
||||
apars_handle_CSI(char leadchar, int *params, int count, char keychar)
|
||||
{
|
||||
/*
|
||||
Implemented codes (from Wikipedia)
|
||||
@@ -216,38 +241,66 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
|
||||
// Query device status - reply "Device is OK"
|
||||
UART_WriteString(UART0, "\033[0n", UART_TIMEOUT_US);
|
||||
}
|
||||
else {
|
||||
ansi_warn("NOIMPL query %d", n1);
|
||||
}
|
||||
break;
|
||||
|
||||
// DECTCEM feature enable / disable
|
||||
|
||||
case 'h': // feature enable
|
||||
if (leadchar == '?') {
|
||||
if (n1 == 25) {
|
||||
screen_cursor_enable(1);
|
||||
} else if (n1 == 7) {
|
||||
screen_wrap_enable(1);
|
||||
if (n1 == 25) screen_cursor_enable(1);
|
||||
else if (n1 == 7) screen_wrap_enable(1);
|
||||
else if (n1 == 1) {
|
||||
// TODO something with arrow keys??
|
||||
}
|
||||
else {
|
||||
ansi_warn("NOIMPL DEC opt %d", n1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (n1 == 4) {
|
||||
// TODO insert mode, i think this is to suppress user input
|
||||
}
|
||||
else {
|
||||
ansi_warn("NOIMPL flag %d", n1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l': // feature disable
|
||||
if (leadchar == '?') {
|
||||
if (n1 == 25) {
|
||||
screen_cursor_enable(0);
|
||||
} else if (n1 == 7) {
|
||||
screen_wrap_enable(0);
|
||||
if (n1 == 25) screen_cursor_enable(0);
|
||||
else if (n1 == 7) screen_wrap_enable(0);
|
||||
else if (n1 == 1) {
|
||||
// TODO see above
|
||||
}
|
||||
else {
|
||||
ansi_warn("NOIMPL DEC opt %d", n1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (n1 == 4) {
|
||||
// TODO see above
|
||||
}
|
||||
else {
|
||||
ansi_warn("NOIMPL flag %d", n1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm': // SGR - graphics rendition aka attributes
|
||||
if (count == 0) {
|
||||
count = 1; // this makes it work as 0 (reset)
|
||||
}
|
||||
|
||||
// iterate arguments
|
||||
for (int i = 0; i < CSI_N_MAX; i++) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
int n = params[i];
|
||||
|
||||
if (i == 0 && n == 0) { // reset SGR
|
||||
if (n == 0) { // reset SGR
|
||||
screen_reset_cursor(); // resets colors, inverse and bold.
|
||||
break; // cannot combine reset with others - discard
|
||||
}
|
||||
else if (n >= 30 && n <= 37) screen_set_fg((Color) (n - 30)); // ANSI normal fg
|
||||
else if (n >= 40 && n <= 47) screen_set_bg((Color) (n - 40)); // ANSI normal bg
|
||||
@@ -259,6 +312,9 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
|
||||
else if (n == 21 || n == 22) screen_set_bold(false); // bold off
|
||||
else if (n >= 90 && n <= 97) screen_set_fg((Color) (n - 90 + 8)); // AIX bright fg
|
||||
else if (n >= 100 && n <= 107) screen_set_bg((Color) (n - 100 + 8)); // AIX bright bg
|
||||
else {
|
||||
ansi_warn("NOIMPL SGR attr %d", n);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -281,6 +337,30 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
|
||||
case 'P':
|
||||
screen_delete_characters(n1);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
// TODO scrolling region
|
||||
ansi_warn("NOIMPL scrolling region");
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
// TODO clear tab
|
||||
ansi_warn("NOIMPL clear tab");
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
// TODO back tab
|
||||
ansi_warn("NOIMPL cursor back tab");
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
// TODO setmode (??)
|
||||
ansi_warn("NOIMPL CSI setmode %d", n1);
|
||||
break;
|
||||
|
||||
default:
|
||||
ansi_warn("Unknown CSI: %c", keychar);
|
||||
apars_handle_badseq();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,6 +371,9 @@ void ICACHE_FLASH_ATTR apars_handle_hashCode(char c)
|
||||
case '8':
|
||||
screen_fill_with_E();
|
||||
break;
|
||||
|
||||
default:
|
||||
ansi_warn("Unknown # sequence: %c", c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,22 +384,48 @@ void ICACHE_FLASH_ATTR apars_handle_shortCode(char c)
|
||||
case 'c': // screen reset
|
||||
screen_reset();
|
||||
break;
|
||||
|
||||
case '7': // save cursor + attrs
|
||||
screen_cursor_save(true);
|
||||
break;
|
||||
|
||||
case '8': // restore cursor + attrs
|
||||
screen_cursor_restore(true);
|
||||
break;
|
||||
|
||||
case 'E': // same as CR LF
|
||||
screen_cursor_move(1, 0, false);
|
||||
screen_cursor_set_x(0);
|
||||
break;
|
||||
|
||||
case 'D': // move cursor down, scroll screen up if needed
|
||||
screen_cursor_move(1, 0, true);
|
||||
break;
|
||||
|
||||
case 'M': // move cursor up, scroll screen down if needed
|
||||
screen_cursor_move(-1, 0, true);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
// TODO set tab
|
||||
// ansi_warn("NOIMPL set tab");
|
||||
break;
|
||||
|
||||
// TODO those don't seem to do anything
|
||||
case '>':
|
||||
// ansi_warn("NOIMPL NUMKP");
|
||||
break;
|
||||
|
||||
case '<':
|
||||
// ansi_warn("NOIMPL SETANSI");
|
||||
break;
|
||||
|
||||
case '=':
|
||||
// ansi_warn("NOIMPL ALTKP");
|
||||
break;
|
||||
|
||||
default:
|
||||
ansi_warn("Unknown 1-char seq %c", c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#ifndef ANSI_PARSER_CALLBACKS_H
|
||||
#define ANSI_PARSER_CALLBACKS_H
|
||||
|
||||
void apars_handle_badseq(void);
|
||||
void apars_handle_plainchar(char c);
|
||||
void apars_handle_CSI(char leadchar, int *params, char keychar);
|
||||
void apars_handle_CSI(char leadchar, int *params, int count, char keychar);
|
||||
void apars_handle_OSC_SetScreenSize(int rows, int cols);
|
||||
void apars_handle_OSC_SetButton(int num, const char *buffer);
|
||||
void apars_handle_OSC_SetTitle(const char *buffer);
|
||||
void apars_handle_shortCode(char c);
|
||||
void apars_handle_hashCode(char c);
|
||||
void apars_handle_characterSet(char leadchar, char c);
|
||||
void apars_handle_setXCtrls(char c);
|
||||
void apars_reset_utf8buffer(void);
|
||||
|
||||
#endif //ESP_VT100_FIRMWARE_ANSI_PARSER_CALLBACKS_H
|
||||
|
||||
+5
-5
@@ -98,7 +98,7 @@ void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
|
||||
|
||||
// TODO re-implement those, use single byte markers and B2 encoding
|
||||
|
||||
dbg("Sock RX str: %s, len %d", data, len);
|
||||
ws_dbg("Sock RX str: %s, len %d", data, len);
|
||||
|
||||
if (strstarts(data, "STR:")) {
|
||||
// pass string verbatim
|
||||
@@ -134,24 +134,24 @@ void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
|
||||
}
|
||||
|
||||
if (!screen_isCoordValid(y, x)) {
|
||||
warn("Mouse input at invalid coordinates");
|
||||
ws_warn("Mouse input at invalid coordinates");
|
||||
return;
|
||||
}
|
||||
|
||||
dbg("Screen clicked at row %d, col %d", y+1, x+1);
|
||||
ws_dbg("Screen clicked at row %d, col %d", y+1, x+1);
|
||||
|
||||
// Send as 1-based to user
|
||||
sprintf(buf, "\033[%d;%dM", y+1, x+1);
|
||||
UART_WriteString(UART0, buf, UART_TIMEOUT_US);
|
||||
}
|
||||
else {
|
||||
warn("Bad command.");
|
||||
ws_warn("Bad command.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Socket connected for updates */
|
||||
void ICACHE_FLASH_ATTR updateSockConnect(Websock *ws)
|
||||
{
|
||||
info("Socket connected to "URL_WS_UPDATE);
|
||||
ws_info("Socket connected to "URL_WS_UPDATE);
|
||||
ws->recvCb = updateSockRx;
|
||||
}
|
||||
|
||||
@@ -9,4 +9,15 @@
|
||||
void updateSockConnect(Websock *ws);
|
||||
void screen_notifyChange(ScreenNotifyChangeTopic topic);
|
||||
|
||||
// defined in the makefile
|
||||
#if DEBUG_INPUT
|
||||
#define ws_warn warn
|
||||
#define ws_dbg dbg
|
||||
#define ws_info info
|
||||
#else
|
||||
#define ws_warn(...)
|
||||
#define ws_dbg(...)
|
||||
#define ws_info(...)
|
||||
#endif
|
||||
|
||||
#endif //CGI_SOCKETS_H
|
||||
|
||||
+1
-3
@@ -186,12 +186,10 @@ screen_reset(void)
|
||||
void ICACHE_FLASH_ATTR
|
||||
screen_reset_cursor(void)
|
||||
{
|
||||
NOTIFY_LOCK();
|
||||
cursor.fg = termconf_scratch.default_fg;
|
||||
cursor.bg = termconf_scratch.default_bg;
|
||||
cursor.inverse = 0;
|
||||
cursor.bold = 0;
|
||||
NOTIFY_DONE();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -712,7 +710,7 @@ screen_putchar(const char *ch)
|
||||
default:
|
||||
if (ch[0] < ' ') {
|
||||
// Discard
|
||||
warn("Ignoring control char %d", (int)ch);
|
||||
warn("Ignoring control char %d", (int)ch[0]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user