/* *  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 <http://www.gnu.org/licenses/>. */#include <stdio.h>#include <string.h>#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));}
