Implement very bad state machine to match a subset of ANSI escape codes.
This commit is contained in:
parent
dd3281aba0
commit
f00ab71fb5
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user