Convert strip_ansi() from unsigned char to char

This required a few careful changes to ensure that the result does the same
thing.

Also included a few little cleanups in this function.
This commit is contained in:
Kevin Easton
2015-06-19 23:12:10 +10:00
parent 1b1734d7e1
commit 53f7c374cf
4 changed files with 129 additions and 137 deletions

View File

@@ -296,7 +296,7 @@ extern Function_ptr *global;
#define xterm_settitle (*(void (*)(void))global[XTERM_SETTITLE]) #define xterm_settitle (*(void (*)(void))global[XTERM_SETTITLE])
#define add_wait_prompt (*(void (*)(char *, void (*)(char *, char *), char *, int , int ))global[ADD_WAIT_PROMPT]) #define add_wait_prompt (*(void (*)(char *, void (*)(char *, char *), char *, int , int ))global[ADD_WAIT_PROMPT])
#define skip_ctl_c_seq (*(char *(*)(const char *, int *, int *, int ))global[SKIP_CTL_C_SEQ]) #define skip_ctl_c_seq (*(char *(*)(const char *, int *, int *, int ))global[SKIP_CTL_C_SEQ])
#define strip_ansi (*(unsigned char *(*)(const unsigned char *))global[STRIP_ANSI]) #define strip_ansi (*(char *(*)(const char *))global[STRIP_ANSI])
#define create_new_screen ((Screen * (*)(void))global[CREATE_NEW_SCREEN]) #define create_new_screen ((Screen * (*)(void))global[CREATE_NEW_SCREEN])
#define create_additional_screen ((Window * (*)(void))global[CREATE_ADDITIONAL_SCREEN]) #define create_additional_screen ((Window * (*)(void))global[CREATE_ADDITIONAL_SCREEN])

View File

@@ -59,7 +59,7 @@ Screen * BX_create_new_screen(void);
void refresh_window_screen(Window *); void refresh_window_screen(Window *);
#endif #endif
u_char *BX_strip_ansi (const u_char *); char *BX_strip_ansi(const char *);
char *normalize_color(int, int, int, int); char *normalize_color(int, int, int, int);
char *BX_skip_ctl_c_seq(const char *, int *, int *, int); char *BX_skip_ctl_c_seq(const char *, int *, int *, int);
char **BX_prepare_display(const char *, int, int *, int); char **BX_prepare_display(const char *, int, int *, int);

View File

@@ -243,7 +243,7 @@ extern void BX_update_input (int update)
term_echo(last_input_screen->promptlist->echo); term_echo(last_input_screen->promptlist->echo);
ptr_free = ptr; ptr_free = ptr;
ptr = (char *)strip_ansi(ptr); ptr = strip_ansi(ptr);
strcat(ptr, ALL_OFF_STR); /* Yes, we can do this */ strcat(ptr, ALL_OFF_STR); /* Yes, we can do this */
if (free_it) if (free_it)
new_free(&ptr_free); new_free(&ptr_free);

View File

@@ -2191,13 +2191,34 @@ char *BX_skip_ctl_c_seq(const char *start, int *lhs, int *rhs, int proper)
return (char *)after; return (char *)after;
} }
/*
* This started off as a general ansi parser, and it worked for stuff that
* was going out to the display, but it couldnt deal properly with ansi codes,
* and so when i tried to use it for the status bar, it just all fell to
* pieces. After working it over, i came up with this. What this does is,
* (believe it or not) walk through and strip oUt all the ansi codes in the
* target string. Any codes that we recognize as being safe (pretty much
* just ^[[<number-list>m), are converted back into their logical characters
* (eg, ^B, ^R, ^_, etc), and everything else is completely blown away.
*/
/*
* These macros help keep 8 bit chars from sneaking into the output stream
* where they might be stripped out.
*/
#define this_char() (eightbit ? *str : (*str) & 0x7f)
#define next_char() (eightbit ? *str++ : (*str++) & 0x7f)
#define put_back() (str--)
char *BX_strip_ansi(const char *str)
{
/* /*
* Used as a translation table when we cant display graphics characters * Used as a translation table when we cant display graphics characters
* or we have been told to do translation. A no-brainer, with little attempt * or we have been told to do translation. A no-brainer, with little attempt
* at being smart. * at being smart.
* (JKJ: perhaps we should allow a user to /set this?) * (JKJ: perhaps we should allow a user to /set this?)
*/ */
static u_char gcxlate[256] = { const static char gcxlate[256] = {
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
'#', '*', '#', '*', '*', '*', '*', '*', '#', '*', '#', '*', '*', '*', '*', '*',
'>', '<', '|', '!', '|', '$', '_', '|', '>', '<', '|', '!', '|', '$', '_', '|',
@@ -2241,7 +2262,7 @@ static u_char gcxlate[256] = {
* State 5 is "ROM character" (022) * State 5 is "ROM character" (022)
* State 6 is a character that should never be printed * State 6 is a character that should never be printed
*/ */
static u_char ansi_state[256] = { const static char ansi_state[256] = {
/* ^@ ^A ^B ^C ^D ^E ^F ^G */ /* ^@ ^A ^B ^C ^D ^E ^F ^G */
6, 6, 4, 3, 6, 4, 4, 4, /* 000 */ 6, 6, 4, 3, 6, 4, 4, 4, /* 000 */
/* ^H ^I ^J ^K ^D ^M ^N ^O */ /* ^H ^I ^J ^K ^D ^M ^N ^O */
@@ -2280,36 +2301,8 @@ static u_char ansi_state[256] = {
1, 1, 1, 1, 1, 1, 1, 1 /* 370 */ 1, 1, 1, 1, 1, 1, 1, 1 /* 370 */
}; };
/* char *output;
* This started off as a general ansi parser, and it worked for stuff that char chr;
* was going out to the display, but it couldnt deal properly with ansi codes,
* and so when i tried to use it for the status bar, it just all fell to
* pieces. After working it over, i came up with this. What this does is,
* (believe it or not) walk through and strip oUt all the ansi codes in the
* target string. Any codes that we recognize as being safe (pretty much
* just ^[[<number-list>m), are converted back into their logical characters
* (eg, ^B, ^R, ^_, etc), and everything else is completely blown away.
*/
/*
* These macros help keep 8 bit chars from sneaking into the output stream
* where they might be stripped out.
*/
#if 1
#define this_char() (eightbit ? *str : (*str) & 0x7f)
#define next_char() (eightbit ? *str++ : (*str++) & 0x7f)
#define put_back() (str--)
#else
#define this_char() (*str)
#define next_char() (*str++)
#define put_back() (str--)
#endif
unsigned char *BX_strip_ansi (const unsigned char *str)
{
u_char *output;
u_char chr, chr1;
int pos, maxpos; int pos, maxpos;
int args[10], nargs, i; int args[10], nargs, i;
@@ -2321,29 +2314,31 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
int fg_color = 0; int fg_color = 0;
int bg_color = 1; int bg_color = 1;
int ansi = get_int_var(DISPLAY_ANSI_VAR); const int ansi = get_int_var(DISPLAY_ANSI_VAR);
int gcmode = get_int_var(DISPLAY_PC_CHARACTERS_VAR); const int gcmode = get_int_var(DISPLAY_PC_CHARACTERS_VAR);
const int eightbit = term_eight_bit();
int n; int n;
int eightbit = term_eight_bit();
/* /*
* The output string has a few extra chars on the end just * The output string has a few extra chars on the end just
* in case you need to tack something else onto it. * in case you need to tack something else onto it.
*/ */
maxpos = strlen(str); maxpos = strlen(str);
output = (u_char *)new_malloc(maxpos + 64); output = new_malloc(maxpos + 64);
pos = 0; pos = 0;
while ((chr = next_char())) while ((chr = next_char()))
{ {
chr1 = *(str - 1); /* chr1 is the same as chr, but without the top bit masked. */
const char chr1 = *(str - 1);
if (pos > maxpos) if (pos > maxpos)
{ {
maxpos += 64; /* Extend 64 chars at a time */ maxpos += 64; /* Extend 64 chars at a time */
RESIZE(output, unsigned char, maxpos + 64); RESIZE(output, char, maxpos + 64);
} }
switch (ansi_state[chr1]) switch (ansi_state[(unsigned char)chr1])
{ {
/* /*
* State 0 is a normal, printable ascii character * State 0 is a normal, printable ascii character
@@ -2364,14 +2359,14 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
* This is a very paranoid check to make sure that * This is a very paranoid check to make sure that
* the 8-bit escape code doesnt elude us. * the 8-bit escape code doesnt elude us.
*/ */
if (chr == 27 + 128) if (chr == '\x9b')
{ {
output[pos++] = REV_TOG; output[pos++] = REV_TOG;
output[pos++] = '['; output[pos++] = '[';
output[pos++] = REV_TOG; output[pos++] = REV_TOG;
continue; continue;
} }
if (ansi_state[chr] == 6) if (ansi_state[(unsigned char)chr] == 6)
my_gcmode = 1; my_gcmode = 1;
if (strip_ansi_never_xlate) if (strip_ansi_never_xlate)
my_gcmode = 4; my_gcmode = 4;
@@ -2383,7 +2378,7 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
*/ */
case 5: case 5:
{ {
output[pos++] = gcxlate[chr]; output[pos++] = gcxlate[(unsigned char)chr];
break; break;
} }
@@ -2404,7 +2399,7 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
if (termfeatures & TERM_CAN_GCHAR) if (termfeatures & TERM_CAN_GCHAR)
output[pos++] = chr; output[pos++] = chr;
else else
output[pos++] = gcxlate[chr]; output[pos++] = gcxlate[(unsigned char)chr];
break; break;
} }
@@ -2418,7 +2413,7 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
else else
{ {
output[pos++] = REV_TOG; output[pos++] = REV_TOG;
output[pos++] = gcxlate[chr]; output[pos++] = gcxlate[(unsigned char)chr];
output[pos++] = REV_TOG; output[pos++] = REV_TOG;
} }
break; break;
@@ -2433,15 +2428,12 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
*/ */
case 1: case 1:
{ {
if (termfeatures & TERM_CAN_GCHAR) if ((termfeatures & TERM_CAN_GCHAR) || (chr & 0x80))
output[pos++] = chr;
else if ((chr & 0x80) && eightbit)
output[pos++] = chr; output[pos++] = chr;
else else
{ {
output[pos++] = REV_TOG; output[pos++] = REV_TOG;
output[pos++] = output[pos++] = chr | 0x40;
(chr | 0x40) & 0x7f;
output[pos++] = REV_TOG; output[pos++] = REV_TOG;
} }
break; break;
@@ -2599,7 +2591,7 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
{ {
n = 0; n = 0;
for (n = 0; for (n = 0;
isdigit(this_char()); isdigit((unsigned char)this_char());
next_char()) next_char())
{ {
n = n * 10 + (this_char() - '0'); n = n * 10 + (this_char() - '0');
@@ -2647,7 +2639,7 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
if (pos + args[0] > maxpos) if (pos + args[0] > maxpos)
{ {
maxpos += args[0]; maxpos += args[0];
RESIZE(output, u_char, maxpos + 64); RESIZE(output, char, maxpos + 64);
} }
while (args[0]-- > 0) while (args[0]-- > 0)
output[pos++] = ND_SPACE; output[pos++] = ND_SPACE;
@@ -2760,7 +2752,7 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
} }
else if (args[i] >= 30 && args[i] <= 37) else if (args[i] >= 30 && args[i] <= 37)
{ {
output[pos++] = 003; output[pos++] = COLOR_CHAR;
if (bold) if (bold)
output[pos++] = '5'; output[pos++] = '5';
else else
@@ -2776,7 +2768,7 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
} }
else if (args[i] >= 40 && args[i] <= 47) else if (args[i] >= 40 && args[i] <= 47)
{ {
output[pos++] = 003; output[pos++] = COLOR_CHAR;
output[pos++] = ','; output[pos++] = ',';
if (blink) if (blink)
output[pos++] = '5'; output[pos++] = '5';
@@ -2800,7 +2792,7 @@ unsigned char *BX_strip_ansi (const unsigned char *str)
*/ */
case 3: case 3:
{ {
const u_char *end; const char *end;
int lhs, rhs; int lhs, rhs;
put_back(); put_back();