omi-eikyo/src/golan5.c

110 lines
2.2 KiB
C

// Copyright © 2017 Project Golan, all rights reserved.
// See COPYING for more information.
#include "m_tokbuf.h"
#include "m_binio.h"
#include <setjmp.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
// Static Objects ------------------------------------------------------------|
static jmp_buf ejmp;
// Static Functions ----------------------------------------------------------|
//
// Expect
//
static M_token *Expect(M_tkbuf *tb, M_toktype 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