/* * Copyright 2007 Michael Buckley * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the license or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the Gnu Public License for more * details. * * You should have received a copy of the GNU General Public License along * with this program; if not, If not, see . */ #include #include #ifndef __mac_os #undef FALSE #undef TRUE typedef enum { FALSE, TRUE } bool; #endif #define COOKIE "MegaHALv8" #define BYTE1 unsigned char #define BYTE2 unsigned short #define BYTE4 unsigned long static void convert_brain(FILE* in, FILE* out, bool native); static bool convert_tree(FILE* in, FILE* out, bool native); static bool convert_dictionary(FILE* in, FILE* out, bool native); static BYTE2 swap2(BYTE2 val); static BYTE4 swap4(BYTE4 val); int main(int argc, char* argv[]) { /* This code is outdated. It's worth a look if you want to understand the * workings of the megahal brain. However, a lot of it is similar to the * load methods from the MegaHAL source. Furthermore, it requires the user * to specify whether to convert it to or from the native format. The newer * version uses a different method which does not parse the data structures * as MegaHAL does. If you really want to see this program in action, * comment out the next three lines. */ fprintf(stdout, "DO NOT USE THIS PROGRAM, IT IS OUTDATED.\n"); fprintf(stdout, "You can get a new version from http://angrymen.org/\n\n"); return 0; if(argc < 3 || argc > 4){ fprintf(stdout, "Incorrect arguments.\n"); fprintf(stdout, "Usage: %s in out [tonative|fromnative]\n", argv[0]); return 0; } FILE* in = fopen(argv[1], "r"); if(in == NULL){ printf("Could not open the file %s for reading", argv[1]); return 0; } FILE* out = fopen(argv[2], "w"); if(in == NULL){ printf("Could not open the file %s for writing", argv[2]); return 0; } bool native; if(argc == 3){ native = FALSE; }else{ native = strcmp(argv[3], "tonative") != 0; } convert_brain(in, out, native); return 0; } void convert_brain(FILE* in, FILE* out, bool native) { char cookie[10]; memset(cookie, 0, 10); if(fread(cookie, sizeof(char), strlen(COOKIE), in) < strlen(COOKIE)){ fprintf(stderr, "Error: Reached file end before magic number.\n"); } if(strcmp(cookie, COOKIE)!=0){ fprintf(stderr, "This is not a Megahal Brain.\n"); return; } fwrite(cookie, 1, strlen(COOKIE), out); BYTE1 order = fgetc(in); if(feof(in) != 0){ fprintf(stderr, "Error: reached file end before model order.\n"); return; } fputc(order, out); if(convert_tree(in, out, native) == TRUE){ if(convert_tree(in, out, native) == FALSE){ return; } }else{ return; } if(convert_dictionary(in, out, native) == FALSE){ return; } fprintf(stdout, "Conversion successful.\n"); } bool convert_tree(FILE* in, FILE* out, bool native) { BYTE2 symbol; if(fread(&symbol, sizeof(BYTE2), 1, in) < 1){ fprintf(stderr, "Error: reached file end before tree symbol.\n"); return FALSE; } symbol = swap2(symbol); fwrite(&symbol, sizeof(BYTE2), 1, out); BYTE4 usage; if(fread(&usage, sizeof(BYTE4), 1, in) < 1){ fprintf(stderr, "Error: reached file end before tree usage.\n"); return FALSE; } usage = swap4(usage); fwrite(&usage, sizeof(BYTE4), 1, out); BYTE2 count; if(fread(&count, sizeof(BYTE2), 1, in) < 1){ fprintf(stderr, "Error: reached file end before tree count.\n"); return FALSE; } count = swap2(count); fwrite(&count, sizeof(BYTE2), 1, out); BYTE2 branch; if(fread(&branch, sizeof(BYTE2), 1, in) < 1){ fprintf(stderr, "Error: reached file end before tree branch.\n"); return FALSE; } int loopval = branch; branch = swap2(branch); if(native == FALSE){ loopval = branch; } fwrite(&branch, sizeof(BYTE2), 1, out); register unsigned int i; for(i = 0; i < loopval; ++i){ if(convert_tree(in, out, native) == FALSE){ return FALSE; } } return TRUE; } bool convert_dictionary(FILE* in, FILE* out, bool native) { BYTE4 size; if(fread(&size, sizeof(BYTE4), 1, in) < 1){ fprintf(stderr, "Error: reached file end before dictionary size.\n"); return FALSE; } size = swap4(size); fwrite(&size, sizeof(BYTE4), 1, out); char c = fgetc(in); while(c != EOF){ fputc(c, out); c = fgetc(in); } return TRUE; } BYTE2 swap2(BYTE2 val) { return (((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8)); } BYTE4 swap4(BYTE4 val) { return (((val & 0xFF000000) >> 24) | ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8) | ((val & 0x000000FF) << 24)); }