Allow strip escape sequence characters from log file

The log without escape key stripped is like:

^M[12:47:17] ACRN:\>
^M[12:47:17] ACRN:\>lasdfjklsdjf
^M
^M[12:47:18] Error: Invalid command.
^M[12:47:19] ACRN:\>
^M[12:47:26] ACRN:\>
^M[12:47:26] ACRN:\>sdafkljsdkaljfklsadjflksdjafjsda^H ^H^H...
^M
^M[12:47:31] Error: Invalid command.

After strip escape key, the log is like:

[12:49:18] ACRN:\>
[12:49:19] ACRN:\>
[12:49:19] ACRN:\>ls

[12:49:19] Error: Invalid command.
[12:49:19] ACRN:\>
[12:49:19] ACRN:\>dfaslhj

[12:49:24] Error: Invalid command.

Beside escape key, it also handle backspace key as well.
This commit is contained in:
Yin Fengwei 2021-01-21 10:35:33 +08:00
parent 1079991608
commit c0c21b1814
5 changed files with 101 additions and 18 deletions

View file

@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "tio/options.h"
#include "tio/print.h"
#include "tio/error.h"
@ -40,7 +41,7 @@ void log_open(const char *filename)
log_error = true;
exit(EXIT_FAILURE);
}
setvbuf(fp, NULL, _IONBF, 0);
setvbuf(fp, NULL, _IOLBF, 0);
}
void log_write(char c)
@ -49,6 +50,75 @@ void log_write(char c)
fputc(c, fp);
}
#define IS_ESC_INTERMEDIATE_CHAR(c) ((c <= 0x2F) && (c >= 0x20))
#define IS_ESC_END_CHAR(c) ((c <= 0x7E) && (c >= 0x30))
#define IS_CSI_END_CHAR(c) ((c <= 0x7E) && (c >= 0x40))
static void scan_ctrl_char(char *buf, int length)
{
int i, j;
size_t len = strnlen(buf, length);
char c;
i = j = 0;
while (i < len) {
c = buf[i++];
if (iscntrl(c)) {
switch (c)
{
case 8: /* backspace */
j--;
break;
case 13: /* \r */
break;
case 27: /* ESC */
c = buf[i++];
if (c == 0x5B) { /* CSI */
c = buf[i++];
while (!IS_CSI_END_CHAR(c)) {
c = buf[i++];
}
} else {
while (!IS_ESC_END_CHAR(c)) {
c = buf[i++];
}
}
break;
default:
buf[j++] = c;
break;
}
} else {
buf[j++] = c;
}
}
buf[j] = '\0';
}
void log_writeline(char *l, int max_line_size, bool esc_strip)
{
char *buf = NULL;
if (fp == NULL)
return;
if (esc_strip) {
buf = strdup(l);
scan_ctrl_char(buf, max_line_size);
fputs(buf, fp);
free(buf);
} else {
buf = l;
fputs(buf, fp);
}
fflush(fp);
}
void log_close(void)
{
if (fp != NULL)