Implement very bad state machine to match a subset of ANSI escape codes.

This commit is contained in:
Danila Fedorin 2019-04-04 21:46:17 -07:00
parent dd3281aba0
commit f00ab71fb5
2 changed files with 62 additions and 1 deletions

View File

@ -38,6 +38,14 @@ i386_init(void)
// Test the stack backtrace function (lab 1 only) // Test the stack backtrace function (lab 1 only)
test_backtrace(5); test_backtrace(5);
// Test ANSI color escape codes
cprintf("\33[31m" "C"
"\33[33m" "o"
"\33[32m" "l"
"\33[36m" "o"
"\33[34m" "r"
"\33[0m" " Works!" "\n");
// Drop into the kernel monitor. // Drop into the kernel monitor.
while (1) while (1)
monitor(NULL); monitor(NULL);

View File

@ -79,6 +79,54 @@ getint(va_list *ap, int lflag)
// Main function to format and print a string. // Main function to format and print a string.
void printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...); void printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...);
struct AttrState {
uint8_t cattrs;
uint8_t attrs;
enum {
NORMAL,
ESC,
BRACKET,
COLOR_FG,
COLOR
} state;
};
void
putchw(void (*putch)(int, void*), int c, void* data, struct AttrState* s) {
switch(s->state) {
case NORMAL:
if(c != 27) putch(c | (s->cattrs << 8), data);
else s->state = ESC;
return;
case ESC:
s->state = (c == '[') ? BRACKET : NORMAL;
return;
case BRACKET:
if(c == '3') {
s->state = COLOR_FG;
} else if(c == '0') {
s->state = COLOR;
s->attrs = 0;
} else {
s->state = NORMAL;
}
return;
case COLOR_FG:
if(c >= '0' && c <= '9') {
s->attrs = (s->attrs & ~(0x07)) | (c - '0');
c |= ((c - '0') << 8);
s->state = COLOR;
} else {
s->state = NORMAL;
}
return;
case COLOR:
s->state = (c == ';') ? BRACKET : NORMAL;
if(c == 'm') s->cattrs = s->attrs;
return;
}
}
void void
vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
{ {
@ -87,12 +135,17 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
unsigned long long num; unsigned long long num;
int base, lflag, width, precision, altflag; int base, lflag, width, precision, altflag;
char padc; char padc;
struct AttrState attst;
attst.state = NORMAL;
attst.cattrs = 0;
attst.attrs = 0;
while (1) { while (1) {
while ((ch = *(unsigned char *) fmt++) != '%') { while ((ch = *(unsigned char *) fmt++) != '%') {
if (ch == '\0') if (ch == '\0')
return; return;
putch(ch, putdat); putchw(putch, ch, putdat, &attst);
} }
// Process a %-escape sequence // Process a %-escape sequence