From fa53e10a933b91ad94b24d5ae9f1069b0e3413ad Mon Sep 17 00:00:00 2001 From: Rob <rob@synchro.net> Date: Thu, 8 Oct 2020 20:05:14 -0700 Subject: [PATCH] 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. --- src/sbbs3/con_out.cpp | 69 ++++++++++++++++++------------------------- src/sbbs3/main.cpp | 2 +- src/sbbs3/putmsg.cpp | 6 +--- src/sbbs3/sbbs.h | 10 ++++++- 4 files changed, 40 insertions(+), 47 deletions(-) diff --git a/src/sbbs3/con_out.cpp b/src/sbbs3/con_out.cpp index 2cfaa77278..1c2ed232e8 100644 --- a/src/sbbs3/con_out.cpp +++ b/src/sbbs3/con_out.cpp @@ -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=='[') - outchar_esc++; - else if(ch=='_' || ch=='P' || ch == '^' || ch == ']') - outchar_esc=4; + if(ch == ESC && outchar_esc < ansiState_string) + outchar_esc = ansiState_esc; + else if(outchar_esc == ansiState_esc) { + if(ch == '[') + outchar_esc = ansiState_csi; + else if(ch == '_' || ch == 'P' || ch == '^' || ch == ']') + 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) { - if(ch>='@' && ch<='~') - outchar_esc++; + else if(outchar_esc == ansiState_csi) { + if(ch >= '@' && ch <= '~') + 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))) { diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index c0502bb5f0..499f6670ec 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -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; diff --git a/src/sbbs3/putmsg.cpp b/src/sbbs3/putmsg.cpp index ad8c67cb08..62fd6b3a57 100644 --- a/src/sbbs3/putmsg.cpp +++ b/src/sbbs3/putmsg.cpp @@ -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 */ diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 7f78bc34ad..2139e8b947 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -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; -- GitLab