/*
  cces.c -- UTF-8 checker

  usage:
     % cces < file

 */
#include <stdio.h>

struct tagTrans {
    int m, v;
    int trans[15];
} trans[7] = {
    {0x80, 0x00,{ 0,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1}},
    {0xc0, 0x80,{-1, 0, 3,  0, 5, 6,  0, 8, 9, 10, 0,12, 13,15, 0}},
    {0xe0, 0xc0,{ 1,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1}},
    {0xf0, 0xe0,{ 2,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1}},
    {0xf8, 0xf0,{ 4,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1}},
    {0xfc, 0xf8,{ 7,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1}},
    {0xfe, 0xfc,{11,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1, -1,-1,-1}}
};

void
invalid(int line, int ch)
{
    printf("Line %d: Invalid byte(%02x)\n", line, ch);
}

int
main(int argc, char* argv[])
{
    int i, c, s = 0, l = 1;
    struct tagTrans *p;
    
    while ((c = getchar()) != EOF) {
	if (c == '\n')
	    l++;
	for (i = 0, p = trans; i < 7; i++, p++)
	    if ((c & p->m) == p->v) {
		if ((s = p->trans[s]) < 0) {
		    invalid(l, c);
		    s = 0;
		}
		break;
	    }
	if (i == 7) {
	    invalid(l, c);
	    s = 0;
	}
    }
    if (s)
	printf("Line %d: Unexpected EOF\n", l);
}

/* end of cces.c */
