#include uint8_t vga_colors[8] = { [0] = 0, [1] = 4, [2] = 2, [3] = 6, [4] = 1, [5] = 5, [6] = 3, [7] = 7 }; void ansi_step(void (*putcf)(int), int c, struct AttrState* s) { switch(s->state) { case NORMAL: if(c != 27) putcf(c | (s->cattrs << 8)); 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)) | vga_colors[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; } }