Fix up ansi handling in message reader

This commit is contained in:
Andrew Pamment 2017-09-09 22:18:23 +10:00
parent 07ea0e7ebb
commit 2dcb07ebbf

View File

@ -806,66 +806,139 @@ void unmangle_ansi(char *body, int len, char **body_out, int *body_len) {
struct character_t ***fake_screen; struct character_t ***fake_screen;
int ansi; int ansi;
line_at = 1;
char_at = 1;
for (i=0;i<len;i++) { for (i=0;i<len;i++) {
if (body[i] == '\r') {
line_count++; if (state == 0) {
line_at++; if (body[i] == 27) {
} else if (body[i] != 27){ state = 1;
char_at ++; continue;
if (char_at == 80) { } else {
char_at = 0; if (body[i] == '\r') {
line_at++; char_at = 1;
line_at++;
} else {
char_at++;
while (char_at > 80) {
line_at++;
char_at -= 80;
}
}
if (line_at > line_count) { if (line_at > line_count) {
line_count = line_at; line_count = line_at;
} }
} }
} else if (state == 1) {
if (body[i] == '[') {
state = 2;
continue;
}
} else if (state == 2) {
param_count = 0;
for (j=0;j<16;j++) {
params[j] = 0;
}
state = 3;
}
if (state == 3) {
if (body[i] == ';') {
if (param_count < 15) {
param_count++;
}
continue;
} else if (body[i] >= '0' && body[i] <= '9') {
if (!param_count) param_count = 1;
params[param_count-1] = params[param_count-1] * 10 + (body[i] - '0');
continue;
} else {
state = 4;
}
} }
if (body[i] == 27) { if (state == 4) {
ansi = i; switch(body[i]) {
while (strchr("ABCDEFGHIGJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", body[i]) == NULL) case 'H':
i++; case 'f':
if (body[i] == 'A') { if (params[0]) params[0]--;
if (i == ansi + 1) { if (params[1]) params[1]--;
line_at--; line_at = params[0] + 1;
} else { char_at = params[1] + 1;
line_at -= atoi(&body[ansi + 1]);
}
} else if (body[i] == 'B') {
if (i == ansi + 1) {
line_at++;
} else {
line_at += atoi(&body[ansi + 1]);
}
if (line_at > line_count) {
line_count = line_at;
}
} else if (body[i] == 'C') {
if (i == ansi + 1) {
char_at++;
} else {
char_at += atoi(&body[ansi + 1]);
}
while (char_at >= 80) {
line_count++;
char_at -= 80;
}
} else if (body[i] == 'D') { if (char_at > 80) {
if (i == ansi + 1) { char_at = 80;
char_at--; }
} else {
char_at -= atoi(&body[ansi + 1]);
}
while (char_at < 0) {
char_at = 0;
}
if (line_at > line_count) {
line_count = line_at;
}
state = 0;
break;
case 'A':
if (param_count > 0) {
line_at = line_at - params[0];
} else {
line_at--;
}
if (line_at < 1) {
line_at = 1;
}
state = 0;
break;
case 'B':
if (param_count > 0) {
line_at = line_at + params[0];
} else {
line_at++;
}
if (line_at > line_count) {
line_count = line_at;
}
state = 0;
break;
case 'C':
if (param_count > 0) {
char_at = char_at + params[0];
} else {
char_at ++;
}
if (char_at > 80) {
char_at = 80;
}
state = 0;
break;
case 'D':
if (param_count > 0) {
char_at = char_at - params[0];
} else {
char_at --;
}
if (char_at < 1) {
char_at = 1;
}
state = 0;
break;
case 's':
save_char_at = char_at;
save_line_at = line_at;
state = 0;
break;
case 'u':
char_at = save_char_at;
line_at = save_line_at;
state = 0;
break;
default:
state = 0;
break;
} }
} }
} }
fake_screen = (struct character_t ***)malloc(sizeof(struct character_t **) * line_count); fake_screen = (struct character_t ***)malloc(sizeof(struct character_t **) * line_count);
for (i=0;i<line_count;i++) { for (i=0;i<line_count;i++) {
fake_screen[i] = (struct character_t **)malloc(sizeof(struct character_t*) * 80); fake_screen[i] = (struct character_t **)malloc(sizeof(struct character_t*) * 80);
@ -891,6 +964,7 @@ void unmangle_ansi(char *body, int len, char **body_out, int *body_len) {
char_at = 1; char_at = 1;
line_at++; line_at++;
} else { } else {
if (line_at > line_count) line_at = line_count;
fake_screen[line_at -1][char_at - 1]->c = body[i]; fake_screen[line_at -1][char_at - 1]->c = body[i];
fake_screen[line_at -1][char_at - 1]->fg = fg; fake_screen[line_at -1][char_at - 1]->fg = fg;
fake_screen[line_at -1][char_at - 1]->bg = bg; fake_screen[line_at -1][char_at - 1]->bg = bg;
@ -955,6 +1029,9 @@ void unmangle_ansi(char *body, int len, char **body_out, int *body_len) {
} else { } else {
line_at++; line_at++;
} }
if (line_at > line_count) {
line_at = line_count;
}
state = 0; state = 0;
break; break;
case 'C': case 'C':