Skip to content
Snippets Groups Projects
Commit f26b296b authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Use an enum for ANSI output state

No functional change with regard to the ANSI output state, just making the code easier to read.

Removed the conversion of `[ and \xFA[ to \x1b[ in putmsg(). This unexplained output translation has been supported since at least v2.xx and I have no recollection of exactly why it was added. If I recall correctly, some BBS software at some point in time sent ANSI-encoded messages into message networks by translating the ESC (\x1b) character in the ANSI sequences to either ` or \xFA in the process. This "feature" seems like it would still work, but it's completely undocumented and I have no idea why it was added (and seriously doubt anyone relies on this behavior), so I'm removing it. If anyone misses this feature, I'll happily add it back, but I'm skeptical that'll happen.
parent 2edad526
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
......@@ -566,57 +566,46 @@ const char* sbbs_t::term_charset(long term)
/****************************************************************************/
int sbbs_t::outchar(char ch)
{
/*
* outchar_esc values:
* 0: No sequence
* 1: ESC
* 2: CSI
* 3: Final byte
* 4: APS, DCS, PM, or OSC
* 5: SOS
* 6: ESC inside of SOS
*/
if(console&CON_ECHO_OFF)
return 0;
if(ch==ESC && outchar_esc < 4)
outchar_esc=1;
else if(outchar_esc==1) {
if(ch == ESC && outchar_esc < ansiState_string)
outchar_esc = ansiState_esc;
else if(outchar_esc == ansiState_esc) {
if(ch == '[')
outchar_esc++;
outchar_esc = ansiState_csi;
else if(ch == '_' || ch == 'P' || ch == '^' || ch == ']')
outchar_esc=4;
outchar_esc = ansiState_string;
else if(ch=='X')
outchar_esc=5;
else if(ch >= 0x40 && ch <= 0x5f)
outchar_esc=3;
outchar_esc = ansiState_sos;
else if(ch >= '@' && ch <= '_')
outchar_esc = ansiState_final;
else
outchar_esc=0;
outchar_esc = ansiState_none;
}
else if(outchar_esc==2) {
else if(outchar_esc == ansiState_csi) {
if(ch >= '@' && ch <= '~')
outchar_esc++;
outchar_esc = ansiState_final;
}
else if(outchar_esc==4) { // APS, DCS, PM, or OSC
else if(outchar_esc == ansiState_string) { // APS, DCS, PM, or OSC
if (ch == ESC)
outchar_esc = 1;
if (!((ch >= 0x08 && ch <= 0x0d) || (ch >= 0x20 && ch <= 0x7e)))
outchar_esc = 0;
outchar_esc = ansiState_esc;
if (!((ch >= '\b' && ch <= '\r') || (ch >= ' ' && ch <= '~')))
outchar_esc = ansiState_none;
}
else if(outchar_esc==5) { // SOS
else if(outchar_esc == ansiState_sos) { // SOS
if (ch == ESC)
outchar_esc++;
outchar_esc = ansiState_sos_esc;
}
else if(outchar_esc==6) { // ESC inside SOS
else if(outchar_esc == ansiState_sos_esc) { // ESC inside SOS
if (ch == '\\')
outchar_esc = 1;
outchar_esc = ansiState_esc;
else if (ch == 'X')
outchar_esc = 0;
outchar_esc = ansiState_none;
else
outchar_esc = 5;
outchar_esc = ansiState_sos;
}
else
outchar_esc=0;
outchar_esc = ansiState_none;
long term = term_supports();
char utf8[UTF8_MAX_LEN + 1] = "";
if(!(term&PETSCII)) {
......@@ -642,7 +631,7 @@ int sbbs_t::outchar(char ch)
if(!(console&CON_R_ECHO))
return 0;
if((console&CON_R_ECHOX) && (uchar)ch>=' ' && !outchar_esc) {
if((console&CON_R_ECHOX) && (uchar)ch>=' ' && outchar_esc == ansiState_none) {
ch=text[YNQP][3];
if(text[YNQP][2]==0 || ch==0) ch='X';
}
......@@ -677,7 +666,7 @@ int sbbs_t::outchar(char ch)
outcom(ch);
}
}
if(!outchar_esc) {
if(outchar_esc == ansiState_none) {
/* Track cursor position locally */
switch(ch) {
case '\a': // 7
......@@ -718,8 +707,8 @@ int sbbs_t::outchar(char ch)
break;
}
}
if(outchar_esc==3)
outchar_esc=0;
if(outchar_esc == ansiState_final)
outchar_esc = ansiState_none;
if(lncntr==rows-1 && ((useron.misc&(UPAUSE^(console&CON_PAUSEOFF))) || sys_status&SS_PAUSEON)
&& !(sys_status&(SS_PAUSEOFF|SS_ABORT))) {
......
......@@ -3369,7 +3369,7 @@ sbbs_t::sbbs_t(ushort node_num, union xp_sockaddr *addr, size_t addr_len, const
pause_hotspot = NULL;
console = 0;
online = 0;
outchar_esc = 0;
outchar_esc = ansiState_none;
nodemsg_inside = 0; /* allows single nest */
hotkey_inside = 0; /* allows single nest */
event_time = 0;
......
......@@ -193,10 +193,6 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
l+=2;
}
}
else if((str[l]=='`' || str[l]=='') && str[l+1]=='[') {
outchar(ESC); /* Convert `[ and [ to ESC[ */
l++;
}
else if(!((*mode)&P_NOXATTRS)
&& (cfg.sys_misc&SM_PCBOARD) && str[l]=='@' && str[l+1]=='X'
&& isxdigit((unsigned char)str[l+2]) && isxdigit((unsigned char)str[l+3])) {
......@@ -348,7 +344,7 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
}
/* ansi escape sequence */
if(outchar_esc) {
if(outchar_esc >= ansiState_csi) {
if(str[l]=='A' || str[l]=='B' || str[l]=='H' || str[l]=='J'
|| str[l]=='f' || str[l]=='u') /* ANSI anim */
lncntr=0; /* so defeat pause */
......
......@@ -348,7 +348,15 @@ public:
scfg_t cfg;
int outchar_esc; // track ANSI escape seq output
enum ansiState {
ansiState_none // No sequence
,ansiState_esc // Escape
,ansiState_csi // CSI
,ansiState_final // Final byte
,ansiState_string // APS, DCS, PM, or OSC
,ansiState_sos // SOS
,ansiState_sos_esc // ESC inside SOS
} outchar_esc; // track ANSI escape seq output
int rioctl(ushort action); // remote i/o control
bool rio_abortable;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment