예제 #1
0
multicart_open_error multicart_open(emu_options &options, const char *filename, const char *gamedrv, multicart_load_flags load_flags, multicart_t **cart)
{
	multicart_open_error err;
	zip_error ziperr;
	object_pool *pool;
	multicart_load_state state = {0, };
	const zip_file_header *header;
	const char *pcb_type;
	char *layout_text = NULL;

	/* allocate an object pool */
	pool = pool_alloc_lib(NULL);
	if (pool == NULL)
	{
		err = MCERR_OUT_OF_MEMORY;
		goto done;
	}

	/* allocate the multicart */
	state.multicart = (multicart_t*)pool_malloc_lib(pool, sizeof(*state.multicart));
	if (state.multicart == NULL)
	{
		err = MCERR_OUT_OF_MEMORY;
		goto done;
	}
	memset(state.multicart, 0, sizeof(*state.multicart));

	/* allocate the multicart's private data */
	state.multicart->data = (multicart_private*)pool_malloc_lib(pool, sizeof(*state.multicart->data));
	if (state.multicart->data == NULL)
	{
		err = MCERR_OUT_OF_MEMORY;
		goto done;
	}
	memset(state.multicart->data, 0, sizeof(*state.multicart->data));
	state.multicart->data->pool = pool;
	pool = NULL;

	/* open the ZIP file */
	ziperr = zip_file_open(filename, &state.zip);
	if (ziperr != ZIPERR_NONE)
	{
		err = MCERR_NOT_MULTICART;
		goto done;
	}

	/* find the layout.xml file */
	header = find_file(state.zip, "layout.xml");
	if (header == NULL)
	{
		err = MCERR_MISSING_LAYOUT;
		goto done;
	}

	/* reserve space for the layout text */
	layout_text = (char*)malloc(header->uncompressed_length + 1);
	if (layout_text == NULL)
	{
		err = MCERR_OUT_OF_MEMORY;
		goto done;
	}

	/* uncompress the layout text */
	ziperr = zip_file_decompress(state.zip, layout_text, header->uncompressed_length);
	if (ziperr != ZIPERR_NONE)
	{
		err = MCERR_ZIP_ERROR;
		goto done;
	}
	layout_text[header->uncompressed_length] = '\0';

	/* parse the layout text */
	state.layout_xml = xml_string_read(layout_text, NULL);
	if (state.layout_xml == NULL)
	{
		err = MCERR_XML_ERROR;
		goto done;
	}

	/* locate the PCB node */
	if (!find_pcb_and_resource_nodes(state.layout_xml, &state.pcb_node, &state.resources_node))
	{
		err = MCERR_NO_PCB_OR_RESOURCES;
		goto done;
	}

	/* get the PCB resource_type */
	pcb_type = xml_get_attribute_string(state.pcb_node, "type", "");
	state.multicart->pcb_type = pool_strdup_lib(state.multicart->data->pool, pcb_type);
	if (state.multicart->pcb_type == NULL)
	{
		err = MCERR_OUT_OF_MEMORY;
		goto done;
	}

	state.multicart->gamedrv_name = pool_strdup_lib(state.multicart->data->pool, gamedrv);
	if (state.multicart->gamedrv_name == NULL)
	{
		err = MCERR_OUT_OF_MEMORY;
		goto done;
	}

	/* do we have to load resources? */
	if (load_flags & MULTICART_FLAGS_LOAD_RESOURCES)
	{
		err = load_all_resources(options, &state);
		if (err != MCERR_NONE)
			goto done;

		err = load_all_sockets(&state);
		if (err != MCERR_NONE)
			goto done;
	}

	err = MCERR_NONE;

done:
	if (pool != NULL)
		pool_free_lib(pool);
	if (state.zip != NULL)
		zip_file_close(state.zip);
	if (layout_text != NULL)
		free(layout_text);
	if (state.layout_xml != NULL)
		xml_file_free(state.layout_xml);

	if ((err != MCERR_NONE) && (state.multicart != NULL))
	{
		multicart_close(options, state.multicart);
		state.multicart = NULL;
	}
	*cart = state.multicart;
	return err;
}
예제 #2
0
int messtest(const struct messtest_options *opts, int *test_count, int *failure_count)
{
	char saved_directory[1024];
	FILE *file;
	int result = -1;
	char *script_directory;
	xml_parse_options parse_options;
	xml_parse_error parse_error;
	xml_data_node *root_node;
	xml_data_node *tests_node;
	mess_pile pile;
	const char *xml;
	size_t sz;
	char buf[256];

	*test_count = 0;
	*failure_count = 0;

	pile_init(&pile);

	/* open the script file */
	file = fopen(opts->script_filename, "r");
	if (!file)
	{
		fprintf(stderr, "%s: Cannot open file\n", opts->script_filename);
		goto done;
	}

	/* read the file */
	while(!feof(file))
	{
		sz = fread(buf, 1, sizeof(buf), file);
		pile_write(&pile, buf, sz);
	}
	pile_writebyte(&pile, '\0', 1);
	xml = (const char *) pile_getptr(&pile);

	/* save the current working directory, and change to the test directory */
	saved_directory[0] = '\0';
	if (!opts->preserve_directory)
	{
		script_directory = osd_dirname(opts->script_filename);
		if (script_directory)
		{
			osd_getcurdir(saved_directory, sizeof(saved_directory) / sizeof(saved_directory[0]));
			osd_setcurdir(script_directory);
			free(script_directory);
		}
	}

	/* set up parse options */
	memset(&parse_options, 0, sizeof(parse_options));
	parse_options.init_parser = parse_init;
	parse_options.flags = XML_PARSE_FLAG_WHITESPACE_SIGNIFICANT;
	parse_options.error = &parse_error;

	/* do the parse */
	root_node = xml_string_read(xml, &parse_options);
	if (!root_node)
	{
		fprintf(stderr, "%s:%d:%d: %s\n",
			opts->script_filename,
			parse_error.error_line,
			parse_error.error_column,
			parse_error.error_message);
		goto done;
	}

	/* find the tests node */
	tests_node = xml_get_sibling(root_node->child, "tests");
	if (!tests_node)
		goto done;

	node_tests(tests_node, test_count, failure_count);
	result = 0;

done:
	/* restore the directory */
	if (saved_directory[0])
		osd_setcurdir(saved_directory);
	pile_delete(&pile);
	return result;
}