// Copyright © 2017 Project Golan, all rights reserved. // See COPYING for more information. #include "m_tokbuf.h" #include "m_binio.h" #include #include #include #include // Static Objects ------------------------------------------------------------| static jmp_buf ejmp; // Static Functions ----------------------------------------------------------| // // Expect // static M_token *Expect(M_tkbuf *tb, M_tokty t) { M_token *tok = M_TokBuf_Get(tb); if(tok->type != t) { fprintf(stderr, "unexpected token\n"); longjmp(ejmp, 1); } return tok; } // // WriteNum // static void WriteNum(FILE *fp, M_tkbuf *tb) { M_IO_WriteLE4k(fp, strtof(Expect(tb, tok_number)->textV, NULL)); } // Extern Functions ----------------------------------------------------------| // // main // int main(int argc, char **argv) { if(argc < 2) { fprintf(stderr, "not enough arguments\n"); return 1; } M_tkbuf tb = {.fp = fopen(argv[1], "r"), .bbeg = 1, .bend = 8}; if(!tb.fp) { fprintf(stderr, "couldn't open input file\n"); return 1; } FILE *out = fopen(argv[2], "wb"); if(!out) { fclose(tb.fp); fprintf(stderr, "couldn't open output file\n"); return 1; } M_TokBuf_Ctor(&tb); if(setjmp(ejmp) == 1) goto done; fwrite("Gmf0\r\n\xF7\0", 1, 8, out); for(M_token *tok; (tok = M_TokBuf_Get(&tb))->type != tok_eof;) { if(tok->type == tok_braceo) { M_IO_WriteLE4u(out, strtoul(Expect(&tb, tok_number)->textV, NULL, 0)); tok = Expect(&tb, tok_identi); // Write length and content of name. fputc(tok->textC - 1, out); fwrite(tok->textV, 1, tok->textC - 1, out); // Write content size and content. if(strcmp(tok->textV, "Sector") == 0) { M_IO_WriteLE2u(out, 4 * 6); for(int i = 0; i < 6; i++) WriteNum(out, &tb); } else { M_IO_WriteLE2u(out, 4 * 3); for(int i = 0; i < 3; i++) WriteNum(out, &tb); } Expect(&tb, tok_bracec); } } M_IO_WriteLE4u(out, 0); fputc(0, out); M_IO_WriteLE2u(out, 0); done: fclose(out); M_TokBuf_Dtor(&tb); fclose(tb.fp); return 0; } // EOF