Exemple #1
0
/* Reads and applies the command-line options. Returns only if the
 * syntax is valid, with the names of the input and output files
 * initialized.
 */
static void parsecmdline(int argc, char *argv[])
{
    static char const *optstring = "Eei:mo:qs:v:w:X";
    static struct option options[] = {
	{ "force-end", no_argument, NULL, 'e' },
	{ "exclude-end", no_argument, NULL, 'E' },
	{ "force-hex", no_argument, NULL, 'X' },
	{ "allow-misaligned", no_argument, NULL, 'm' },
	{ "quiet", no_argument, NULL, 'q' },
	{ "indent", required_argument, NULL, 'i' },
	{ "width", required_argument, NULL, 'w' },
	{ "output", required_argument, NULL, 'o' },
	{ "structname", required_argument, NULL, 's' },
	{ "varname", required_argument, NULL, 'v' },
	{ "help", no_argument, NULL, 'H' },
	{ "version", no_argument, NULL, 'V' },
	{ 0, 0, 0, 0 }
    };

    char const *structname = NULL;
    char const *varname = NULL;
    char const *width = NULL;
    char const *indent = NULL;
    int n;

    setprogramname(argv[0]);
    while ((n = getopt_long(argc, argv, optstring, options, NULL)) != EOF) {
	switch (n) {
	  case 'e':	include_end(TRUE);		break;
	  case 'E':	include_end(FALSE);		break;
	  case 'X':	forcehexbytes();		break;
	  case 'm':	permitmisalignment();		break;
	  case 'q':	enablewarnings(FALSE);		break;
	  case 'i':	indent = optarg;		break;
	  case 'w':	width = optarg;			break;
	  case 'o':	outputfilename = optarg;	break;
	  case 's':	structname = optarg;		break;
	  case 'v':	varname = optarg;		break;
	  case 'H':	fputs(yowzitch, stdout);	exit(EXIT_SUCCESS);
	  case 'V':	fputs(vourzhon, stdout);	exit(EXIT_SUCCESS);
	  default:
	    fprintf(stderr, "%s", helpsuffix);
	    exit(EXIT_FAILURE);
	}
    }

    if (optind == argc)
	fail("no input file.\n%s", helpsuffix);
    if (optind + 1 < argc)
	fail("unrecognized extra argments.\n%s", helpsuffix);
    inputfilename = argv[optind];

    if (width) {
	if (sscanf(width, "%d", &n) != 1 || n < 4)
	    fail("invalid width parameter: %s.", width);
	setoutputwidth(n);
    }
    if (indent) {
	if (sscanf(indent, "%d", &n) != 1 || n < 0)
	    fail("invalid indent parameter: %s.", indent);
	setoutputindent(n);
    }
    if (varname) {
	if (!isvalididentifier(varname))
	    fail("invalid variable name: \"%s\".", varname);
	setvarname(varname);
    }
    if (structname) {
	if (!isvalididentifier(structname))
	    fail("invalid structure name: \"%s\".", structname);
	setstructname(structname);
    }
}
Exemple #2
0
int main(int argc, char **argv) {
	xpc_t *xpc;
	char *inrom = NULL;
	char *outrom = NULL;
	char *xpcfile = NULL;
	FILE *fi, *fo;
	unsigned char buffer[8192];
	int apply = ASKNONE;
	int i, j, k;

	setprogramname(argv[0]);
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-o")) {
			if (i < argc-1) outrom = argv[++i]; else goto help;
		} else if (!strcmp(argv[i], "-ask")) {
			apply = ASKSOME;
		} else if (!strcmp(argv[i], "-askall")) {
			apply = ASKALL;
		} else if (!inrom) {
			inrom = argv[i];
		} else if (!xpcfile) {
			xpcfile = argv[i];
		} else goto help;
	}
	if (!inrom || argc > 6 || argc < 2 || (argc == 2 && !strcmp(argv[1], "--help"))) {
help:		fprintf(stderr, "xpctools - xpcapply\n"
				"(c) 2004 A&L Software\n"
				"This program may be freely copied, modified and distributed\n"
				"under the terms of GNU GPL license version 2 or later.\n\n"
				"usage: xpcapply romfile [xpcfile] [-o modifiedromfile] [-ask|-askall]\n"
				"if xpcfile is ommited or \"-\", it will be read from stdin\n"
				"if output ROM file is ommited, original ROM file itself will be modified\n");
		exit(1);
	}
	if (!xpcfile) {
		if (apply != ASKNONE) {
			fprintf(stderr, "%s: can't use interactive mode when reading patchfile from stdin\n", programname);
			exit(1);
		}
		xpcfile = "-";
	}
	if (outrom) {
		if (!(fi = fopen(inrom, "rb"))) {
			fprintf(stderr, "%s: can't open %s\n", programname, inrom);
			exit(1);
		}
		if (!(fo = fopen(outrom, "wb"))) {
			fprintf(stderr, "%s: can't create %s\n", programname, outrom);
			exit(1);
		}
		while (!feof(fi)) {
			i = fread(buffer, 1, 8192, fi);
			if (fwrite(buffer, 1, i, fo) != i) {
				fprintf(stderr, "%s: can't write %s\n", programname, outrom);
				exit(1);
			}
		}
		fclose(fi);
		fclose(fo);
		inrom = outrom;
	}
	xpc = readxpc(xpcfile);
	if (!(fi = fopen(inrom, "r+b"))) {
		fprintf(stderr, "%s: can't open %s\n", programname, inrom);
		exit(1);
	}
	fseek(fi, 0L, SEEK_END);
	if ((ftell(fi) & 0x1fff) != 0) {
		fprintf(stderr, "%s: file %s doesn't have size multiple of 8192 bytes\n", programname, inrom);
		exit(1);
	}
	fseek(fi, 0L, SEEK_SET);
	for (i = 0; i < xpc->numblocks; i++) {
		if ((apply == ASKSOME && !xpc->xpcblock[i]->essential) || apply == ASKALL) {
			printf("%s? (Y/N) ", xpc->xpcblock[i]->description);
			fflush(stdout);
			fflush(stdin);
			fgets(buffer, 8191, stdin);
			if (*buffer == 'N' || *buffer == 'n') continue;
		}
		for (j = 0; j < xpc->xpcblock[i]->numpatches; j++) {
			fseek(fi, xpc->xpcblock[i]->patches[j]->page*8192+xpc->xpcblock[i]->patches[j]->address, SEEK_SET);
			for (k = 0; k < xpc->xpcblock[i]->patches[j]->size; k++) {
				if (fputc(xpc->xpcblock[i]->patches[j]->data[k], fi) != xpc->xpcblock[i]->patches[j]->data[k]) {
					fprintf(stderr, "%s: error writing %s\n", programname, inrom);
					exit(1);
				}
			}
		}
	}
	fclose(fi);
	return 0;
}