110 lines
2.2 KiB
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_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
|