/* In text block */ %s I /* Outside of text block */ %s O /* Waiting for Width argument */ %s W /* Waiting for OpCode arguments */ %s Op int num_blocks = 0; int num_lines = 0; int cur_num_lines = 0; int cur_num_block = 0; int line_width = 0; int max_line_width = 0; int block_lines = 0; int block_width = 0; int errstate = 0; void yputc(int c, int a); %% ""\n { int i; char zeros[4] = {0, 0, 0, 0}; num_blocks = atoi(yytext + 8); fprintf(stderr, "Number of blocks: %i\n", num_blocks); num_lines = 2; BEGIN(O); } .* { fprintf(stderr, "Invalid file, must begin with \n"); errstate = 1; num_lines = 2; num_blocks = 9999; } "= num_blocks) { fprintf(stderr, "Error: too much blocks at line %i\n", num_lines); errstate = 1; } block_lines = atoi(yytext + 18); BEGIN(W); } "width:"\ *[[:digit:]]+">\n" { block_width = atoi(yytext + 6); fprintf(stderr, "Begin of block %i at line %i -- lines = %i, width = %i\n", cur_num_block, num_lines, block_lines, block_width); num_lines++; line_width = 0; max_line_width = 0; cur_num_lines = 1; BEGIN(I); } .* { fprintf(stderr, "Error: invalid arguments to command Text_block at line %i: '%s'\n", num_lines, yytext); errstate = 1; BEGIN(O); } \n { if (line_width > block_width) { fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width); } if (line_width > max_line_width) max_line_width = line_width; line_width = 0; num_lines++; cur_num_lines++; if (cur_num_lines > block_lines) { fprintf(stderr, "Warning: too much lines for text block %i at line %i (%i > %i)\n", cur_num_block, num_lines, cur_num_lines, block_lines); } putc('\n', yyout); } "\n" { if (line_width > block_width) { fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width); } if (line_width > max_line_width) max_line_width = line_width; line_width = 0; num_lines++; cur_num_lines = 1; putc('\n', yyout); } "\n" { if (line_width > block_width) { fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width); } if (line_width > max_line_width) max_line_width = line_width; line_width = 0; num_lines++; cur_num_lines = 1; putc('\n', yyout); } "" { cur_num_lines = 1; } "" { int d = atoi(yytext + 7); if (d > 255) { fprintf(stderr, "Error: delay too important: %i\n", d); errstate = 1; } } "" { int d = atoi(yytext + 5); if (d > 255) { fprintf(stderr, "Error: gear number too important: %i\n", d); errstate = 1; } else { putc(0xf, yyout); putc(5, yyout); putc(d, yyout); line_width += 16; } } "" { BEGIN(Op); } [[:digit:]]+\ +[[:digit:]]+">" { int o1, o2; o1 = atoi(yytext); o2 = atoi(yytext + (o1 < 10 ? 2 : o1 < 100 ? 3 : 4)); BEGIN(I); } [^<]*">" { yytext[strlen(yytext - 1)] = 0; fprintf(stderr, "Error: invalid OpCode '%s'\n", yytext); errstate = 1; BEGIN(I); } "<"[[:digit:]]">" unput(*(yytext + 1)); "<".">" unput(*(yytext + 1)); "<..>" unput('.'); unput('.'); "<...>" unput('.'); unput('.'); unput('.'); "" { int d = atoi(yytext + 7); if (d > 255) { fprintf(stderr, "Error: Extra1 number too important: %i\n", d); errstate = 1; } else { putc(0xfe, yyout); putc(d, yyout); } } "" { int d = atoi(yytext + 7); if (d > 255) { fprintf(stderr, "Error: Extra2 number too important: %i\n", d); errstate = 1; } else { putc(0xff, yyout); putc(d, yyout); } } "" { char str[5] = {'0', 'x', 0, 0, 0}; int d; for (yytext += 6; *yytext == ' '; yytext++); str[2] = *(yytext++); str[3] = *(yytext++); sscanf(str, "%i", &d); if (d > 255) { fprintf(stderr, "Error: Bare number too important: %i\n", d); errstate = 1; } else { putc(d, yyout); } } "" unput('e'); unput('o'); "" unput('e'); unput('a'); "\n" { if (line_width > max_line_width) max_line_width = line_width; if (max_line_width < block_width) fprintf(stderr, "Warning: block %i too large (%i < %i)\n", cur_num_block, max_line_width, block_width); num_lines++; cur_num_block++; putc('\n', yyout); putc('\n', yyout); BEGIN(O); } "<"[^\>\n]*">" { yytext[strlen(yytext) - 1] = 0; fprintf(stderr, "Error: Invalid command at line %i: '%s'\n", num_lines, yytext + 1); errstate = 1; } \n num_lines++; . /* Eat up comments */ . { putc(*yytext, yyout); } . { fprintf(stderr, "Hu uh, something's wrong at line %i...\n", num_lines); } %% int yywrap(void) { if (cur_num_block < num_blocks) { fprintf(stderr, "Warning: Too few blocks at end of file.\n"); } exit(errstate ? -1 : 0); } int main(int argc, char ** argv) { if ((argc < 2) || (argc > 3)) { fprintf(stderr, "Usage: %s [input]\n", argv[0]); exit(-1); } if (!(yyout = fopen(argv[1], "wb"))) { fprintf(stderr, "Error: can't open file %s\n", argv[1]); exit(-1); } if (argc == 3) { if (!(yyin = fopen(argv[2], "rb"))) { fprintf(stderr, "Error: can't open file %s\n", argv[2]); exit(-1); } } fprintf(stderr, "Creating file %s\n", argv[1]); yylex(); exit(errstate ? -1 : 0); } void yputc(int c, int a) { line_width += a; putc(c, yyout); }