示例#1
0
文件: receive-pack.c 项目: Sp1t/git
static void rp_warning(const char *err, ...)
{
	va_list params;
	va_start(params, err);
	report_message("warning: ", err, params);
	va_end(params);
}
示例#2
0
static void rp_error(const char *err, ...)
{
	va_list params;
	va_start(params, err);
	report_message("error: ", err, params);
	va_end(params);
}
示例#3
0
static void dump_screenshot(int write_file)
{
	mame_file *fp;
	char buf[128];
	mame_bitmap *bitmap;
	int x, y, is_blank;
	pen_t color;
	extern mame_bitmap *scrbitmap[8];

	bitmap = artwork_get_ui_bitmap();

	if (write_file)
	{
		/* dump a screenshot */
		snprintf(buf, sizeof(buf) / sizeof(buf[0]),
			(screenshot_num >= 0) ? "_%s_%d.png" : "_%s.png",
			current_testcase.name, screenshot_num);
		fp = mame_fopen(Machine->gamedrv->name, buf, FILETYPE_SCREENSHOT, 1);
		if (fp)
		{
			save_screen_snapshot_as(fp, bitmap);
			mame_fclose(fp);
			report_message(MSG_INFO, "Saved screenshot as %s", buf);
		}

		if (screenshot_num >= 0)
			screenshot_num++;
	}

	/* check to see if bitmap is blank */
	bitmap = scrbitmap[0];
	is_blank = 1;
	color = bitmap->read(bitmap, 0, 0);
	for (y = 0; is_blank && (y < bitmap->height); y++)
	{
		for (x = 0; is_blank && (x < bitmap->width); x++)
		{
			if (bitmap->read(bitmap, x, y) != color)
				is_blank = 0;
		}
	}
	if (is_blank)
	{
		had_failure = TRUE;
		report_message(MSG_FAILURE, "Screenshot is blank");
	}
}
示例#4
0
static void node_checkfreespace(struct imgtooltest_state *state, xml_data_node *node)
{
	imgtoolerr_t err;
	UINT64 current_freespace;
	INT64 leaked_space;
	const char *verb;

	if (!state->m_partition)
	{
		state->m_failed = 1;
		report_message(MSG_FAILURE, "Partition not loaded");
		return;
	}

	err = imgtool_partition_get_free_space(state->m_partition, &current_freespace);
	if (err)
	{
		state->m_failed = 1;
		report_imgtoolerr(err);
		return;
	}

	if (state->m_recorded_freespace != current_freespace)
	{
		leaked_space = state->m_recorded_freespace - current_freespace;
		if (leaked_space > 0)
		{
			verb = "Leaked";
		}
		else
		{
			leaked_space = -leaked_space;
			verb = "Reverse leaked";
		}

		state->m_failed = 1;
		report_message(MSG_FAILURE, "%s %u bytes of space", verb, (unsigned int) leaked_space);
	}
}
示例#5
0
static void node_recordfreespace(struct imgtooltest_state *state, xml_data_node *node)
{
	imgtoolerr_t err;

	if (!state->m_partition)
	{
		state->m_failed = 1;
		report_message(MSG_FAILURE, "Partition not loaded");
		return;
	}

	err = imgtool_partition_get_free_space(state->m_partition, &state->m_recorded_freespace);
	if (err)
	{
		state->m_failed = 1;
		report_imgtoolerr(err);
		return;
	}
}
示例#6
0
void CLIB_DECL osd_die(const char *text,...)
{
	va_list va;
	char buf[256];
	char *s;

	/* format the die message */
	va_start(va, text);
	vsnprintf(buf, sizeof(buf) / sizeof(buf[0]), text, va);
	va_end(va);

	/* strip out \n */
	s = strchr(buf, '\n');
	if (s)
		*s = '\0';

	/* report the failure */
	report_message(MSG_FAILURE, "Die: %s", buf);
	state = STATE_ABORTED;
	longjmp(die_jmpbuf, -1);
}
示例#7
0
static void command_input(void)
{
	/* post a set of characters to the emulation */
	if (state == STATE_READY)
	{
		if (!inputx_can_post())
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Natural keyboard input not supported for this driver");
			return;
		}

		/* input_chars can be NULL, so we should check for that */
		if (current_command->u.input_args.input_chars)
		{
			inputx_post_utf8_rate(current_command->u.input_args.input_chars,
				current_command->u.input_args.rate);
		}
	}
	state = inputx_is_posting() ? STATE_INCOMMAND : STATE_READY;
}
示例#8
0
static device_image_interface *find_device_by_identity(running_machine &machine, const messtest_device_identity *ident)
{
	device_image_interface *device = NULL;

	/* look up the image slot */
	if (ident->type == IO_UNKNOWN)
	{
		/* no device_type was specified; use the new preferred mechanism */
		device = dynamic_cast<device_image_interface *>(machine.device(ident->tag));
	}

	/* did the image slot lookup fail? */
	if (device == NULL)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Device '%s %i' does not exist",
			device_config_image_interface::device_typename(ident->type), ident->slot);
	}

	return device;
}
示例#9
0
static void node_checkattr(struct imgtooltest_state *state, xml_data_node *node)
{
	imgtoolerr_t err;
	xml_attribute_node *attr_node;
	UINT32 attribute;
	imgtool_attribute value;
	imgtool_attribute expected_value;

	memset(&value, 0, sizeof(value));
	memset(&expected_value, 0, sizeof(expected_value));

	attr_node = xml_get_attribute(node, "path");
	if (!attr_node)
	{
		state->m_failed = 1;
		error_missingattribute("path");
		return;
	}

	attribute = identify_attribute(state, node, &expected_value);
	if (!attribute)
		return;

	err = imgtool_partition_get_file_attribute(state->m_partition, attr_node->value, attribute, &value);
	if (err)
	{
		state->m_failed = 1;
		report_imgtoolerr(err);
		return;
	}

	if (memcmp(&value, &expected_value, sizeof(value)))
	{
		state->m_failed = 1;
		report_message(MSG_FAILURE, "Comparison failed");
		return;
	}
}
示例#10
0
int main(int argc, char **argv)
{
  int r;
  int broadcast = 1;

  if (argc < 2)
    barf("need a hostname");

  if (argc >= 3) {
    service = strdup(argv[2]);
  }

  ctx.sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (ctx.sockfd < 0)
    barf(strerror(errno));

  if (lookup(argv[1]) < 0)
    barf("bad lookup");

  /* request broadcast permissions if possible */
  setsockopt(ctx.sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
  
  /* trasmit query */
  r = sendto(ctx.sockfd, query, 4, 0, (struct sockaddr *)&ctx.saddr, sizeof(ctx.saddr));
  if (r<0)
    barf(strerror(errno));

  while (collect_response()) {
    message *m;
    m = decode_message(inmsg, inlen);
    report_message(m);
    printf ("\n");
  }

  return 0;
}
示例#11
0
static void dump_screenshot(int write_file)
{
	mame_file_error filerr;
	mame_file *fp;
	char buf[128];
	int is_blank = 0;
	int scrnum;
	UINT32 screenmask;

	if (write_file)
	{
		/* dump a screenshot */
		snprintf(buf, sizeof(buf) / sizeof(buf[0]),
			(screenshot_num >= 0) ? "_%s_%d.png" : "_%s.png",
			current_testcase.name, screenshot_num);
		filerr = mame_fopen(SEARCHPATH_SCREENSHOT, buf, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &fp);
		if (filerr == FILERR_NONE)
		{
			screenmask = render_get_live_screens_mask();

			if (screenmask != 0)
			{
				/* choose a screen */
				for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++)
				{
					if (screenmask & (1 << scrnum))
						break;
				}

				video_screen_save_snapshot(fp, scrnum);
				report_message(MSG_INFO, "Saved screenshot as %s", buf);
			}
			else
			{
				report_message(MSG_FAILURE, "Could not save screenshot; no live screen");
			}
			mame_fclose(fp);
		}
		else
		{
			/* report the error */
			report_message(MSG_FAILURE, "Could not save screenshot; error #%d", filerr);
		}

		if (screenshot_num >= 0)
			screenshot_num++;
	}

#if 0
	/* check to see if bitmap is blank */
	bitmap = scrbitmap[0];
	is_blank = 1;
	color = bitmap->read(bitmap, 0, 0);
	for (y = 0; is_blank && (y < bitmap->height); y++)
	{
		for (x = 0; is_blank && (x < bitmap->width); x++)
		{
			if (bitmap->read(bitmap, x, y) != color)
				is_blank = 0;
		}
	}
#endif
	if (is_blank)
	{
		had_failure = TRUE;
		report_message(MSG_FAILURE, "Screenshot is blank");
	}
}
示例#12
0
static messtest_result_t run_test(int flags, struct messtest_results *results)
{
	int driver_num;
	messtest_result_t rc;
	clock_t begin_time;
	double real_run_time;
	char *fullpath = NULL;

	/* lookup driver */
	for (driver_num = 0; drivers[driver_num]; driver_num++)
	{
		if (!mame_stricmp(current_testcase.driver, drivers[driver_num]->name))
			break;
	}

	/* cannot find driver? */
	if (!drivers[driver_num])
	{
		report_message(MSG_FAILURE, "Cannot find driver '%s'", current_testcase.driver);
		return MESSTEST_RESULT_STARTFAILURE;
	}

	/* prepare testing state */
	current_command = current_testcase.commands;
	state = STATE_READY;
	test_flags = flags;
	screenshot_num = 0;
	runtime_hash = 0;
	had_failure = FALSE;
	seen_first_update = FALSE;
	videoram = NULL;
	videoram_size = 0;
	dirtybuffer = NULL;

	/* set up options */
	memset(&options, 0, sizeof(options));
	options.skip_disclaimer = 1;
	options.skip_gameinfo = 1;
	options.skip_warnings = 1;
	options.disable_normal_ui = 1;
	options.ram = current_testcase.ram;
	options.samplerate = 44100;
	options.mame_debug = 1;
	options.brightness = 1.0;
	options.contrast = 1.0;
	options.gamma = 1.0;

	/* preload any needed images */
	while(current_command->command_type == MESSTEST_COMMAND_IMAGE_PRELOAD)
	{
		fullpath = assemble_software_path(drivers[driver_num], current_command->u.image_args.filename);
		options.image_files[options.image_count].name = fullpath;
		options.image_files[options.image_count].device_type = current_command->u.image_args.device_type;
		options.image_files[options.image_count].device_index = -1;
		options.image_count++;
		current_command++;
	}

	/* perform the test */
	report_message(MSG_INFO, "Beginning test (driver '%s')", current_testcase.driver);
	begin_time = clock();
	mame_set_output_channel(OUTPUT_CHANNEL_ERROR, messtest_output_error, NULL, NULL, NULL);
	mame_set_output_channel(OUTPUT_CHANNEL_WARNING, mame_null_output_callback, NULL, NULL, NULL);
	mame_set_output_channel(OUTPUT_CHANNEL_INFO, mame_null_output_callback, NULL, NULL, NULL);
	mame_set_output_channel(OUTPUT_CHANNEL_DEBUG, mame_null_output_callback, NULL, NULL, NULL);
	mame_set_output_channel(OUTPUT_CHANNEL_LOG, mame_null_output_callback, NULL, NULL, NULL);
	run_game(driver_num);
	real_run_time = ((double) (clock() - begin_time)) / CLOCKS_PER_SEC;

	/* what happened? */
	switch(state)
	{
		case STATE_ABORTED:
			report_message(MSG_FAILURE, "Test aborted");
			rc = MESSTEST_RESULT_RUNTIMEFAILURE;
			break;

		case STATE_DONE:
			if (had_failure)
			{
				report_message(MSG_FAILURE, "Test failed (real time %.2f; emu time %.2f [%i%%])",
					real_run_time, final_time, (int) ((final_time / real_run_time) * 100));
				rc = MESSTEST_RESULT_RUNTIMEFAILURE;
			}
			else
			{
				report_message(MSG_INFO, "Test succeeded (real time %.2f; emu time %.2f [%i%%])",
					real_run_time, final_time, (int) ((final_time / real_run_time) * 100));
				rc = MESSTEST_RESULT_SUCCESS;
			}
			break;

		default:
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Abnormal termination");
			rc = MESSTEST_RESULT_STARTFAILURE;
			break;
	}

	if (results)
	{
		results->rc = rc;
		results->runtime_hash = runtime_hash;
	}
	if (fullpath)
		free(fullpath);
	return rc;
}
示例#13
0
static messtest_result_t run_test(int flags, struct messtest_results *results)
{
	int driver_num;
	messtest_result_t rc;
	clock_t begin_time;
	double real_run_time;

	/* lookup driver */
	for (driver_num = 0; drivers[driver_num]; driver_num++)
	{
		if (!mame_stricmp(current_testcase.driver, drivers[driver_num]->name))
			break;
	}

	/* cannot find driver? */
	if (!drivers[driver_num])
	{
		report_message(MSG_FAILURE, "Cannot find driver '%s'", current_testcase.driver);
		return MESSTEST_RESULT_STARTFAILURE;
	}

	/* prepare testing state */
	current_command = current_testcase.commands;
	state = STATE_READY;
	test_flags = flags;
	screenshot_num = 0;
	runtime_hash = 0;
	had_failure = FALSE;
	seen_first_update = FALSE;

	/* set up options */
	memset(&options, 0, sizeof(options));
	options.skip_disclaimer = 1;
	options.skip_gameinfo = 1;
	options.skip_warnings = 1;
	options.disable_normal_ui = 1;
	options.ram = current_testcase.ram;
	options.vector_intensity = 1.5;
	options.use_artwork = 1;
	options.samplerate = 44100;
	options.mame_debug = 1;

	/* preload any needed images */
	while(current_command->command_type == MESSTEST_COMMAND_IMAGE_PRELOAD)
	{
		options.image_files[options.image_count].name = current_command->u.image_args.filename;
		options.image_files[options.image_count].type = current_command->u.image_args.device_type;
		options.image_count++;
		current_command++;
	}

	/* perform the test */
	report_message(MSG_INFO, "Beginning test (driver '%s')", current_testcase.driver);
	begin_time = clock();
	if (setjmp(die_jmpbuf) == 0)
		run_game(driver_num);
	real_run_time = ((double) (clock() - begin_time)) / CLOCKS_PER_SEC;

	/* what happened? */
	switch(state)
	{
		case STATE_ABORTED:
			report_message(MSG_FAILURE, "Test aborted");
			rc = MESSTEST_RESULT_RUNTIMEFAILURE;
			break;

		case STATE_DONE:
			if (had_failure)
			{
				report_message(MSG_FAILURE, "Test failed (real time %.2f; emu time %.2f [%i%%])",
					real_run_time, final_time, (int) ((final_time / real_run_time) * 100));
				rc = MESSTEST_RESULT_RUNTIMEFAILURE;
			}
			else
			{
				report_message(MSG_INFO, "Test succeeded (real time %.2f; emu time %.2f [%i%%])",
					real_run_time, final_time, (int) ((final_time / real_run_time) * 100));
				rc = MESSTEST_RESULT_SUCCESS;
			}
			break;

		default:
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Abnormal termination");
			rc = MESSTEST_RESULT_STARTFAILURE;
			break;
	}

	if (results)
	{
		results->rc = rc;
		results->runtime_hash = runtime_hash;
	}
	return rc;
}
示例#14
0
static void node_createimage(struct imgtooltest_state *state, xml_data_node *node)
{
	imgtoolerr_t err;
	xml_data_node *child_node;
	xml_attribute_node *attr_node;
	option_resolution *opts = NULL;
	const imgtool_module *module;
	const char *driver;
	const char *param_name;
	const char *param_value;

	attr_node = xml_get_attribute(node, "driver");
	if (!attr_node)
	{
		error_missingattribute("driver");
		return;
	}
	driver = attr_node->value;

	/* does image creation support options? */
	module = imgtool_find_module(attr_node->value);
	if (module && module->createimage_optguide && module->createimage_optspec)
		opts = option_resolution_create(module->createimage_optguide, module->createimage_optspec);

	report_message(MSG_INFO, "Creating image (module '%s')", driver);

	for (child_node = xml_get_sibling(node->child, "param"); child_node; child_node = xml_get_sibling(child_node->next, "param"))
	{
		if (!opts)
		{
			report_message(MSG_FAILURE, "Cannot specify creation options with this module");
			return;
		}

		attr_node = xml_get_attribute(child_node, "name");
		if (!attr_node)
		{
			error_missingattribute("name");
			return;
		}
		param_name = attr_node->value;

		attr_node = xml_get_attribute(child_node, "value");
		if (!attr_node)
		{
			error_missingattribute("value");
			return;
		}
		param_value = attr_node->value;

		option_resolution_add_param(opts, param_name, param_value);
	}

	err = imgtool_image_create_byname(driver, tempfile_name(), opts, &state->m_image);
	if (opts)
	{
		option_resolution_close(opts);
		opts = NULL;
	}
	if (err)
	{
		state->m_failed = 1;
		report_imgtoolerr(err);
		return;
	}

	err = imgtool_partition_open(state->m_image, 0, &state->m_partition);
	if (err)
	{
		state->m_failed = 1;
		report_imgtoolerr(err);
		return;
	}
}
示例#15
0
static void messtest_warn(const char *message)
{
	report_message(MSG_FAILURE, "%s", message);
}
示例#16
0
static void dump_screenshot(running_machine &machine, int write_file)
{
	file_error filerr;
	char buf[128];
	int is_blank = 0;

	if (write_file)
	{
		/* dump a screenshot */
		snprintf(buf, ARRAY_LENGTH(buf),
			(screenshot_num >= 0) ? "_%s_%d.png" : "_%s.png",
			current_testcase.name, screenshot_num);
		emu_file fp(machine.options(), SEARCHPATH_SCREENSHOT, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
		filerr = fp.open(buf);
		if (filerr == FILERR_NONE)
		{
			/* choose a screen */
			screen_device *screen = machine.first_screen();
			while((screen != NULL) && !machine.render().is_live(*screen))
			{
				screen = screen->next_screen();
			}

			/* did we find a live screen? */
			if (screen != NULL)
			{
				screen->machine().video().save_snapshot(screen, fp);
				report_message(MSG_INFO, "Saved screenshot as %s", buf);
			}
			else
			{
				report_message(MSG_FAILURE, "Could not save screenshot; no live screen");
			}
		}
		else
		{
			/* report the error */
			report_message(MSG_FAILURE, "Could not save screenshot; error #%d", filerr);
		}

		if (screenshot_num >= 0)
			screenshot_num++;
	}

#if 0
	/* check to see if bitmap is blank */
	bitmap = scrbitmap[0];
	is_blank = 1;
	color = bitmap->read(bitmap, 0, 0);
	for (y = 0; is_blank && (y < bitmap->height); y++)
	{
		for (x = 0; is_blank && (x < bitmap->width); x++)
		{
			if (bitmap->read(bitmap, x, y) != color)
				is_blank = 0;
		}
	}
#endif
	if (is_blank)
	{
		had_failure = TRUE;
		report_message(MSG_FAILURE, "Screenshot is blank");
	}
}
示例#17
0
static void command_image_loadcreate(void)
{
	mess_image *image;
	int device_type;
	int device_slot;
	const char *device_tag;
	int i, format_index = 0;
	const char *filename;
	const char *format;
	char buf[128];
	const struct IODevice *dev;
	const char *file_extensions;
	char *filepath;
	int success;
	const game_driver *gamedrv;

	device_slot = current_command->u.image_args.device_slot;
	device_type = current_command->u.image_args.device_type;
	device_tag = current_command->u.image_args.device_tag;

	/* look up the image slot */
	if (device_tag)
		image = image_from_devtag_and_index(device_tag, device_slot);
	else
		image = image_from_devtype_and_index(device_type, device_slot);
	if (!image)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Image slot '%s %i' does not exist",
			device_typename(device_type), device_slot);
		return;
	}
	dev = image_device(image);
	file_extensions = dev->file_extensions;

	/* is an image format specified? */
	format = current_command->u.image_args.format;
	if (format)
	{
		if (current_command->command_type != MESSTEST_COMMAND_IMAGE_CREATE)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Cannot specify format unless creating");
			return;
		}

		if (!dev->createimage_options)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Cannot specify format for device");
			return;
		}

		for (i = 0; dev->createimage_options[i].name; i++)
		{
			if (!strcmp(format, dev->createimage_options[i].name))
				break;
		}
		if (!dev->createimage_options[i].name)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Unknown device '%s'", format);
			return;
		}
		format_index = i;
		file_extensions = dev->createimage_options[i].extensions;
	}

	/* figure out the filename */
	filename = current_command->u.image_args.filename;
	if (!filename)
	{
		snprintf(buf, sizeof(buf) / sizeof(buf[0]),	"%s.%s",
			current_testcase.name, file_extensions);
		osd_get_temp_filename(buf, ARRAY_LENGTH(buf), buf);
		filename = buf;
	}

	success = FALSE;
	for (gamedrv = Machine->gamedrv; !success && gamedrv; gamedrv = mess_next_compatible_driver(gamedrv))
	{
		/* assemble the full path */
		filepath = assemble_software_path(gamedrv, filename);

		/* actually create or load the image */
		switch(current_command->command_type)
		{
			case MESSTEST_COMMAND_IMAGE_CREATE:
				success = (image_create(image, filepath, format_index, NULL) == INIT_PASS);
				break;
			
			case MESSTEST_COMMAND_IMAGE_LOAD:
				success = (image_load(image, filepath) == INIT_PASS);
				break;

			default:
				fatalerror("Unexpected error");
				break;
		}
		free(filepath);
	}
	if (!success)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Failed to load/create image '%s': %s", filename, image_error(image));
		return;
	}
}
示例#18
0
static void report_imgtoolerr(imgtoolerr_t err)
{
	const char *msg;
	msg = imgtool_error(err);
	report_message(MSG_FAILURE, "%s", msg);
}
示例#19
0
void osd_update(running_machine &machine, int skip_redraw)
{
	int i;
	attotime time_limit;
	attotime current_time;

	target->get_primitives();

	/* don't do anything if we are initializing! */
	switch(machine.phase())
	{
		case MACHINE_PHASE_PREINIT:
		case MACHINE_PHASE_INIT:
		case MACHINE_PHASE_RESET:
			return;
		default: break;
	}

	/* if we have already aborted or completed, our work is done */
	if ((state == STATE_ABORTED) || (state == STATE_DONE))
	{
		machine.schedule_exit();
		return;
	}

	/* have we hit the time limit? */
	current_time = machine.time();
	time_limit = (current_testcase.time_limit != attotime::zero) ? current_testcase.time_limit
		: attotime::from_seconds(600);
	if (current_time > time_limit)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Time limit of %s attoseconds exceeded", time_limit.as_string(9));
		return;
	}

	for (i = 0; i < ARRAY_LENGTH(commands); i++)
	{
		if (current_command->command_type == commands[i].command_type)
		{
			commands[i].proc(machine);
			break;
		}
	}

	/* if we are ready for the next command, advance to it */
	if (state == STATE_READY)
	{
		/* if we are at the end, and we are dumping screenshots, and we didn't
         * just dump a screenshot, dump one now
         */
		if ((test_flags & MESSTEST_ALWAYS_DUMP_SCREENSHOT) &&
			(current_command[0].command_type != MESSTEST_COMMAND_SCREENSHOT) &&
			(current_command[1].command_type == MESSTEST_COMMAND_END))
		{
			dump_screenshot(machine, TRUE);
		}

		current_command++;
	}
}
示例#20
0
void node_testmess(xml_data_node *node)
{
	xml_data_node *child_node;
	xml_attribute_node *attr_node;
	int result;

	pile_init(&command_pile);
	command_pool = pool_alloc_lib(NULL);

	memset(&new_command, 0, sizeof(new_command));
	command_count = 0;

	/* 'driver' attribute */
	attr_node = xml_get_attribute(node, "driver");
	if (!attr_node)
	{
		error_missingattribute("driver");
		return;
	}
	current_testcase.driver = attr_node->value;

	/* 'name' attribute */
	attr_node = xml_get_attribute(node, "name");
	current_testcase.name = attr_node ? attr_node->value : current_testcase.driver;

	/* 'bios' attribute */
	attr_node = xml_get_attribute(node, "bios");
	current_testcase.bios = attr_node ? attr_node->value : NULL;

	/* 'ramsize' attribute */
	attr_node = xml_get_attribute(node, "ramsize");
	current_testcase.ram = attr_node ? ram_parse_string(attr_node->value) : 0;

	/* 'wavwrite' attribute */
	attr_node = xml_get_attribute(node, "wavwrite");
	current_testcase.wavwrite = attr_node && (atoi(attr_node->value) != 0);

	/* 'enabled' attribute */
	attr_node = xml_get_attribute(node, "enabled");
	current_testcase.enabled = (!attr_node || atoi(attr_node->value)) ? TRUE : FALSE;

	/* report the beginning of the test case */
	report_testcase_begin(current_testcase.name);

	if (current_testcase.enabled)
	{
		current_testcase.commands = NULL;

		for (child_node = node->child; child_node; child_node = child_node->next)
		{
			if (!strcmp(child_node->name, "wait"))
				node_wait(child_node);
			else if (!strcmp(child_node->name, "input"))
				node_input(child_node);
			else if (!strcmp(child_node->name, "rawinput"))
				node_rawinput(child_node);
			else if (!strcmp(child_node->name, "switch"))
				node_switch(child_node);
			else if (!strcmp(child_node->name, "screenshot"))
				node_screenshot(child_node);
			else if (!strcmp(child_node->name, "checkblank"))
				node_checkblank(child_node);
			else if (!strcmp(child_node->name, "imagecreate"))
				node_imagecreate(child_node);
			else if (!strcmp(child_node->name, "imageload"))
				node_imageload(child_node);
			else if (!strcmp(child_node->name, "memverify"))
				node_memverify(child_node);
			else if (!strcmp(child_node->name, "imageverify"))
				node_imageverify(child_node);
			else if (!strcmp(child_node->name, "trace"))
				node_trace(child_node);
			else if (!strcmp(child_node->name, "reset"))
				node_soft_reset(child_node);
			else if (!strcmp(child_node->name, "hardreset"))
				node_hard_reset(child_node);
		}

		memset(&new_command, 0, sizeof(new_command));
		new_command.command_type = MESSTEST_COMMAND_END;
		if (!append_command())
		{
			error_outofmemory();
			return;
		}

		result = run_test(0, NULL);
	}
	else
	{
		/* report that the test case was skipped */
		report_message(MSG_INFO, "Test case skipped");
		result = 0;
	}

	report_testcase_ran(result);
	pile_delete(&command_pile);
	pool_free_lib(command_pool);
}
示例#21
0
static void node_checkdirectory(struct imgtooltest_state *state, xml_data_node *node)
{
	imgtoolerr_t err = IMGTOOLERR_SUCCESS;
	imgtool_directory *imageenum;
	imgtool_dirent ent;
	char expected_listing[1024];
	char actual_listing[1024];
	int i/*, actual_count*/;
	int mismatch;
	xml_attribute_node *attr_node;
	xml_data_node *child_node;
	const char *filename;
	expected_dirent *entry;
	expected_dirent entries[256];
	int entry_count;

	if (!state->m_partition)
	{
		state->m_failed = 1;
		report_message(MSG_FAILURE, "Partition not loaded");
		return;
	}

	attr_node = xml_get_attribute(node, "path");
	filename = attr_node ? attr_node->value : "";

	memset(&entries, 0, sizeof(entries));
	entry_count = 0;

	for (child_node = xml_get_sibling(node->child, "entry"); child_node; child_node = xml_get_sibling(child_node->next, "entry"))
	{
		if (entry_count >= ARRAY_LENGTH(entries))
		{
			report_message(MSG_FAILURE, "Too many directory entries");
			return;
		}

		entry = &entries[entry_count++];

		attr_node = xml_get_attribute(child_node, "name");
		entry->filename = attr_node ? attr_node->value : NULL;

		attr_node = xml_get_attribute(child_node, "size");
		entry->size = attr_node ? atoi(attr_node->value) : -1;
	}

	/* build expected listing string */
	expected_listing[0] = '\0';
	for (i = 0; i < entry_count; i++)
	{
		append_to_list(expected_listing,
			ARRAY_LENGTH(expected_listing),
			entries[i].filename);
	}

	/* now enumerate though listing */
	//actual_count = 0;
	actual_listing[0] = '\0';
	mismatch = FALSE;

	memset(&ent, 0, sizeof(ent));

	err = imgtool_directory_open(state->m_partition, filename, &imageenum);
	if (err)
		goto done;

	i = 0;
	do
	{
		err = imgtool_directory_get_next(imageenum, &ent);
		if (err)
			goto done;

		if (!ent.eof)
		{
			append_to_list(actual_listing,
				ARRAY_LENGTH(actual_listing),
				ent.filename);

			if (i < entry_count && (strcmp(ent.filename, entries[i].filename)))
				mismatch = TRUE;
			i++;
		}
	}
	while(!ent.eof);

	if (i != entry_count)
		mismatch = TRUE;

	if (mismatch)
	{
		state->m_failed = 1;
		report_message(MSG_FAILURE, "File listing mismatch: {%s} expected {%s}",
			actual_listing, expected_listing);
		goto done;
	}

done:
	if (imageenum)
		imgtool_directory_close(imageenum);
	if (err)
	{
		state->m_failed = 1;
		report_imgtoolerr(err);
	}
}
示例#22
0
static void command_verify_memory(void)
{
	int i = 0;
	offs_t offset, offset_start, offset_end;
	const UINT8 *verify_data;
	size_t verify_data_size;
	const UINT8 *target_data;
	size_t target_data_size;
	int region;

	offset_start = current_command->u.verify_args.start;
	offset_end = current_command->u.verify_args.end;
	verify_data = (const UINT8 *) current_command->u.verify_args.verify_data;
	verify_data_size = current_command->u.verify_args.verify_data_size;

	if (offset_end == 0)
		offset_end = offset_start + verify_data_size - 1;

	region = current_command->u.verify_args.mem_region;
	if (region)
	{
		target_data = memory_region(region);
		target_data_size = memory_region_length(region);
	}
	else
	{
		target_data = mess_ram;
		target_data_size = mess_ram_size;
	}

	/* sanity check the ranges */
	if (!verify_data || (verify_data_size <= 0))
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Invalid memory region during verify");
		return;
	}
	if (offset_start > offset_end)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Invalid verify offset range (0x%x-0x%x)", offset_start, offset_end);
		return;
	}
	if (offset_end >= target_data_size)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Verify memory range out of bounds");
		return;
	}

	for (offset = offset_start; offset <= offset_end; offset++)
	{
		if (verify_data[i] != target_data[offset])
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Failed verification step (REGION_%s; 0x%x-0x%x)",
				memory_region_to_string(region), offset_start, offset_end);
			break;
		}
		i = (i + 1) % verify_data_size;
	}
}
示例#23
0
static void command_verify_memory(running_machine &machine)
{
	int i = 0;
	offs_t offset, offset_start, offset_end;
	const UINT8 *verify_data;
	size_t verify_data_size;
	const UINT8 *target_data = NULL;
	size_t target_data_size = 0;
	const char *region;
	const char *cpu_name;

	offset_start = current_command->u.verify_args.start;
	offset_end = current_command->u.verify_args.end;
	verify_data = (const UINT8 *) current_command->u.verify_args.verify_data;
	verify_data_size = current_command->u.verify_args.verify_data_size;

	if (offset_end == 0)
		offset_end = offset_start + verify_data_size - 1;

	cpu_name = current_command->u.verify_args.cpu_name;

	/* what type of memory are we validating? */
	region = current_command->u.verify_args.mem_region;
	if (region)
	{
		/* we're validating a conventional memory region */
		target_data = machine.region(region)->base();
		target_data_size = machine.region(region)->bytes();
	}

	/* sanity check the ranges */
	if (!verify_data || (verify_data_size <= 0))
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Invalid memory region during verify");
		return;
	}
	if (offset_start > offset_end)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Invalid verify offset range (0x%x-0x%x)", offset_start, offset_end);
		return;
	}

	if (region) {
		if (offset_end >= target_data_size)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Verify memory range out of bounds");
			return;
		}
	} else {
		if (cpu_name==NULL) {
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "If region is not defined then cpu must be");
			return;
		}
	}

	/* loop through the memory, verifying it byte by byte */
	for (offset = offset_start; offset <= offset_end; offset++)
	{
		if (region) {
			if (verify_data[i] != target_data[offset])
			{
				state = STATE_ABORTED;
				report_message(MSG_FAILURE, "Failed verification step (region %s; 0x%x-0x%x)",
					region, offset_start, offset_end);
				break;
			}
		} else {
			address_space *space = machine.device(cpu_name)->memory().space(AS_PROGRAM);

			if (verify_data[i] != space->read_byte(offset))
			{
				state = STATE_ABORTED;
				report_message(MSG_FAILURE, "Failed verification step (0x%x-0x%x)",
					offset_start, offset_end);
				break;
			}
		}
		i = (i + 1) % verify_data_size;
	}
}
示例#24
0
static void command_image_loadcreate(running_machine &machine)
{
	device_image_interface *image;
	const char *filename;
	const char *format_name;
	char buf[128];
	const char *file_extensions;
	astring *filepath;
	int success;
	const game_driver *gamedrv;
	const image_device_format *format = NULL;

	/* look up the image slot */
	image = find_device_by_identity(machine, &current_command->u.image_args.device_ident);
	if (image == NULL)
		return;

	file_extensions = image->image_config().file_extensions();

	/* is an image format specified? */
	format_name = current_command->u.image_args.format;
	if (format_name != NULL)
	{
		if (current_command->command_type != MESSTEST_COMMAND_IMAGE_CREATE)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Cannot specify format unless creating");
			return;
		}

		/* look up the format name */
		format = image->device_get_named_creatable_format(format_name);
		if (format == NULL)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Unknown device format '%s'", format_name);
			return;
		}
	}

	/* figure out the filename */
	filename = current_command->u.image_args.filename;
	if (!filename)
	{
		snprintf(buf, ARRAY_LENGTH(buf),	"%s.%s",
			current_testcase.name, file_extensions);
		//osd_get_temp_filename(buf, ARRAY_LENGTH(buf), buf);
		filename = buf;
	}

	success = FALSE;
	for (gamedrv = machine.system(); !success && gamedrv; gamedrv = driver_get_compatible(gamedrv))
	{
		/* assemble the full path */
		filepath = assemble_software_path(astring_alloc(), gamedrv, filename);

		/* actually create or load the image */
		switch(current_command->command_type)
		{
			case MESSTEST_COMMAND_IMAGE_CREATE:
				success = (image->create(astring_c(filepath), format, NULL) == IMAGE_INIT_PASS);
				break;

			case MESSTEST_COMMAND_IMAGE_LOAD:
				success = (image->load(astring_c(filepath)) == IMAGE_INIT_PASS);
				break;

			default:
				fatalerror("Unexpected error");
				break;
		}
		astring_free(filepath);
	}
	if (!success)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Failed to load/create image '%s': %s", filename, image->error());
		return;
	}
}
示例#25
0
static void command_image_preload(void)
{
	state = STATE_ABORTED;
	report_message(MSG_FAILURE, "Image preloads must be at the beginning");
}
示例#26
0
int osd_update(mame_time emutime)
{
	int i;
	double time_limit;
	double current_time;
	int cpunum;

	render_target_get_primitives(target);

	/* is this the first update?  if so, eat it */
	if (!seen_first_update)
	{
		seen_first_update = TRUE;
		goto done;
	}

	/* if we have already aborted or completed, our work is done */
	if ((state == STATE_ABORTED) || (state == STATE_DONE))
	{
		mame_schedule_exit(Machine);
		goto done;
	}

	/* have we hit the time limit? */
	current_time = timer_get_time();
	time_limit = (current_testcase.time_limit != 0.0) ? current_testcase.time_limit
		: TIME_IN_SEC(600);
	if (current_time > time_limit)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Time limit of %.2f seconds exceeded", time_limit);
		goto done;
	}

	/* update the runtime hash */
	if (0)
	{
		for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		{
			runtime_hash *= 57;
			runtime_hash ^= cpunum_get_reg(cpunum, REG_PC);	/* TODO - Add more registers? */
		}
	}

	for (i = 0; i < sizeof(commands) / sizeof(commands[i]); i++)
	{
		if (current_command->command_type == commands[i].command_type)
		{
			commands[i].proc();
			break;
		}
	}

	/* if we are ready for the next command, advance to it */
	if (state == STATE_READY)
	{
		/* if we are at the end, and we are dumping screenshots, and we didn't
		 * just dump a screenshot, dump one now
		 */
		if ((test_flags & MESSTEST_ALWAYS_DUMP_SCREENSHOT) &&
			(current_command[0].command_type != MESSTEST_COMMAND_SCREENSHOT) &&
			(current_command[1].command_type == MESSTEST_COMMAND_END))
		{
			dump_screenshot(TRUE);
		}

		current_command++;
	}

done:
	return FALSE;
}
示例#27
0
static void command_image_loadcreate(void)
{
	mess_image *image;
	int device_type;
	int device_slot;
	const char *device_tag;
	int i, format_index = 0;
	const char *filename;
	const char *format;
	char buf[128];
	const struct IODevice *dev;
	const char *file_extensions;

	device_slot = current_command->u.image_args.device_slot;
	device_type = current_command->u.image_args.device_type;
	device_tag = current_command->u.image_args.device_tag;

	/* look up the image slot */
	if (device_tag)
		image = image_from_devtag_and_index(device_tag, device_slot);
	else
		image = image_from_devtype_and_index(device_type, device_slot);
	if (!image)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Image slot '%s %i' does not exist",
			device_typename(device_type), device_slot);
		return;
	}
	dev = image_device(image);
	file_extensions = dev->file_extensions;

	/* is an image format specified? */
	format = current_command->u.image_args.format;
	if (format)
	{
		if (current_command->command_type != MESSTEST_COMMAND_IMAGE_CREATE)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Cannot specify format unless creating");
			return;
		}

		if (!dev->createimage_options)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Cannot specify format for device");
			return;
		}

		for (i = 0; dev->createimage_options[i].name; i++)
		{
			if (!strcmp(format, dev->createimage_options[i].name))
				break;
		}
		if (!dev->createimage_options[i].name)
		{
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Unknown device '%s'", format);
			return;
		}
		format_index = i;
		file_extensions = dev->createimage_options[i].extensions;
	}

	/* figure out the filename */
	filename = current_command->u.image_args.filename;
	if (!filename)
	{
		snprintf(buf, sizeof(buf) / sizeof(buf[0]),	"%s.%s",
			current_testcase.name, file_extensions);
		make_filename_temporary(buf, sizeof(buf) / sizeof(buf[0]));
		filename = buf;
	}

	/* actually create or load the image */
	switch(current_command->command_type)
	{
		case MESSTEST_COMMAND_IMAGE_CREATE:
			if (image_create(image, filename, format_index, NULL))
			{
				state = STATE_ABORTED;
				report_message(MSG_FAILURE, "Failed to create image '%s': %s", filename, image_error(image));
				return;
			}
			break;
		
		case MESSTEST_COMMAND_IMAGE_LOAD:
			if (image_load(image, filename))
			{
				state = STATE_ABORTED;
				report_message(MSG_FAILURE, "Failed to load image '%s': %s", filename, image_error(image));
				return;
			}
			break;

		default:
			break;
	}
}
示例#28
0
static messtest_result_t run_test(int flags, messtest_results *results)
{
	const game_driver *driver;
	messtest_result_t rc;
	clock_t begin_time;
	double real_run_time;
	astring *fullpath = NULL;
	const char *device_opt;
	const char *fake_argv[2];
	core_options *opts;

	/* lookup driver */
	driver = driver_get_name(current_testcase.driver);

	/* cannot find driver? */
	if (driver == NULL)
	{
		report_message(MSG_FAILURE, "Cannot find driver '%s'", current_testcase.driver);
		return MESSTEST_RESULT_STARTFAILURE;
	}

	/* prepare testing state */
	current_command = current_testcase.commands;
	state = STATE_READY;
	test_flags = flags;
	screenshot_num = 0;
	runtime_hash = 0;
	had_failure = FALSE;
	//videoram = NULL;
	//videoram_size = 0;

	/* set up options */
	opts = mame_options_init(win_mess_opts);
	options_set_string(opts, OPTION_GAMENAME, driver->name, OPTION_PRIORITY_CMDLINE);
	if( current_testcase.bios )
		options_set_string(opts, OPTION_BIOS, current_testcase.bios, OPTION_PRIORITY_CMDLINE);
	options_set_bool(opts, OPTION_SKIP_GAMEINFO, TRUE, OPTION_PRIORITY_CMDLINE);
	options_set_bool(opts, OPTION_THROTTLE, FALSE, OPTION_PRIORITY_CMDLINE);
	options_set_bool(opts, OPTION_DEBUG, FALSE, OPTION_PRIORITY_CMDLINE);
	options_set_bool(opts, OPTION_DEBUG_INTERNAL, FALSE, OPTION_PRIORITY_CMDLINE);
	options_set_bool(opts, OPTION_WRITECONFIG, FALSE, OPTION_PRIORITY_CMDLINE);

	if (current_testcase.ram != 0)
	{
		options_set_int(opts, OPTION_RAMSIZE, current_testcase.ram, OPTION_PRIORITY_CMDLINE);
	}

	/* ugh... hideous ugly fake arguments */
	fake_argv[0] = "MESSTEST";
	fake_argv[1] = driver->name;
	options_parse_command_line(opts, ARRAY_LENGTH(fake_argv), (char **) fake_argv, OPTION_PRIORITY_CMDLINE,TRUE);

	/* preload any needed images */
	while(current_command->command_type == MESSTEST_COMMAND_IMAGE_PRELOAD)
	{
		/* get the path */
		fullpath = assemble_software_path(astring_alloc(), driver, current_command->u.image_args.filename);

		/* get the option name */
		device_opt = device_config_image_interface::device_typename(current_command->u.image_args.device_ident.type);

		/* set the option */
		options_set_string(opts, device_opt, astring_c(fullpath), OPTION_PRIORITY_CMDLINE);

		/* cleanup */
		astring_free(fullpath);
		fullpath = NULL;

		/* next command */
		current_command++;
	}

	/* perform the test */
	report_message(MSG_INFO, "Beginning test (driver '%s')", current_testcase.driver);
	begin_time = clock();
	mame_set_output_channel(OUTPUT_CHANNEL_ERROR, messtest_output_error, NULL, NULL, NULL);
	mame_set_output_channel(OUTPUT_CHANNEL_WARNING, mame_null_output_callback, NULL, NULL, NULL);
	mame_set_output_channel(OUTPUT_CHANNEL_INFO, mame_null_output_callback, NULL, NULL, NULL);
	mame_set_output_channel(OUTPUT_CHANNEL_DEBUG, mame_null_output_callback, NULL, NULL, NULL);
	mame_set_output_channel(OUTPUT_CHANNEL_LOG, mame_null_output_callback, NULL, NULL, NULL);
	test_osd_interface osd;
	mame_execute(osd, opts);
	real_run_time = ((double) (clock() - begin_time)) / CLOCKS_PER_SEC;

	/* what happened? */
	switch(state)
	{
		case STATE_ABORTED:
			report_message(MSG_FAILURE, "Test aborted");
			rc = MESSTEST_RESULT_RUNTIMEFAILURE;
			break;

		case STATE_DONE:
			if (had_failure)
			{
				report_message(MSG_FAILURE, "Test failed (real time %.2f; emu time %.2f [%i%%])",
					real_run_time, final_time.as_double(), (int) ((final_time.as_double() / real_run_time) * 100));
				rc = MESSTEST_RESULT_RUNTIMEFAILURE;
			}
			else
			{
				report_message(MSG_INFO, "Test succeeded (real time %.2f; emu time %.2f [%i%%])",
					real_run_time, final_time.as_double(), (int) ((final_time.as_double() / real_run_time) * 100));
				rc = MESSTEST_RESULT_SUCCESS;
			}
			break;

		default:
			state = STATE_ABORTED;
			report_message(MSG_FAILURE, "Abnormal termination");
			rc = MESSTEST_RESULT_STARTFAILURE;
			break;
	}

	if (results)
	{
		results->rc = rc;
		results->runtime_hash = runtime_hash;
	}

	options_free(opts);
	return rc;
}
示例#29
0
void osd_update_video_and_audio(mame_display *display)
{
	int i;
	double time_limit;
	double current_time;
	int cpunum;

	/* if the visible area has changed, update it */
	if (display->changed_flags & GAME_VISIBLE_AREA_CHANGED)
	{
		ui_set_visible_area(display->game_visible_area.min_x, display->game_visible_area.min_y,
			display->game_visible_area.max_x, display->game_visible_area.max_y);
	}

	/* is this the first update?  if so, eat it */
	if (!seen_first_update)
	{
		seen_first_update = TRUE;
		return;
	}

	/* if we have already aborted or completed, our work is done */
	if ((state == STATE_ABORTED) || (state == STATE_DONE))
		return;

	/* have we hit the time limit? */
	current_time = timer_get_time();
	time_limit = (current_testcase.time_limit != 0.0) ? current_testcase.time_limit
		: TIME_IN_SEC(600);
	if (current_time > time_limit)
	{
		state = STATE_ABORTED;
		report_message(MSG_FAILURE, "Time limit of %.2f seconds exceeded", time_limit);
		return;
	}

	/* update the runtime hash */
	if (0)
	{
		for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
		{
			runtime_hash *= 57;
			runtime_hash ^= cpunum_get_reg(cpunum, REG_PC);	/* TODO - Add more registers? */
		}
	}

	for (i = 0; i < sizeof(commands) / sizeof(commands[i]); i++)
	{
		if (current_command->command_type == commands[i].command_type)
		{
			commands[i].proc();
			break;
		}
	}

	/* if we are ready for the next command, advance to it */
	if (state == STATE_READY)
	{
		/* if we are at the end, and we are dumping screenshots, and we didn't
		 * just dump a screenshot, dump one now
		 */
		if ((test_flags & MESSTEST_ALWAYS_DUMP_SCREENSHOT) &&
			(current_command[0].command_type != MESSTEST_COMMAND_SCREENSHOT) &&
			(current_command[1].command_type == MESSTEST_COMMAND_END))
		{
			dump_screenshot(TRUE);
		}

		current_command++;
	}
}
示例#30
0
文件: testzpth.c 项目: kkalmaz/psmame
void node_testzippath(xml_data_node *node)
{
	xml_attribute_node *attr_node;
	xml_data_node *first_child_node;
	xml_data_node *child_node;
	const char *path;
	const char *plus;
	astring *apath = NULL;
	zippath_directory *directory = NULL;
	const osd_directory_entry *dirent;
	const char *type_string;
	file_error err;
	UINT64 size;
	mess_pile pile;
	core_file *file = NULL;

	pile_init(&pile);

	/* name the test case */
	report_testcase_begin("zippath");

	/* retrieve path */
	attr_node = xml_get_attribute(node, "path");
	path = (attr_node != NULL) ? attr_node->value : "";

	/* retrieve 'plus' - for testing zippath_combine */
	attr_node = xml_get_attribute(node, "plus");
	if (attr_node != NULL)
	{
		plus = attr_node->value;
		apath = zippath_combine(astring_alloc(), path, plus);
		report_message(MSG_INFO, "Testing ZIP Path '%s' + '%s' ==> '%s'", path, plus, astring_c(apath));
	}
	else
	{
		apath = astring_cpyc(astring_alloc(), path);
		report_message(MSG_INFO, "Testing ZIP Path '%s'", astring_c(apath));
	}

	/* try doing a file compare */
	messtest_get_data(node, &pile);
	if (pile_size(&pile) > 0)
	{
		err = zippath_fopen(astring_c(apath), OPEN_FLAG_READ, &file, NULL);
		if (err != FILERR_NONE)
		{
			report_message(MSG_FAILURE, "Error %d opening file", (int) err);
			goto done;
		}

		if (pile_size(&pile) != core_fsize(file))
		{
			report_message(MSG_FAILURE, "Expected file to be of length %d, instead got %d", (int) pile_size(&pile), (int) core_fsize(file));
			goto done;
		}

		if (memcmp(pile_getptr(&pile), core_fbuffer(file), pile_size(&pile)))
		{
			report_message(MSG_FAILURE, "File sizes match, but contents do not");
			goto done;
		}
	}

	/* try doing a directory listing */
	first_child_node = xml_get_sibling(node->child, "entry");
	if (first_child_node != NULL)
	{
		err = zippath_opendir(astring_c(apath), &directory);
		if (err != FILERR_NONE)
		{
			report_message(MSG_FAILURE, "Error %d opening directory", (int) err);
			goto done;
		}

		/* read each directory entry */
		while((dirent = zippath_readdir(directory)) != NULL)
		{
			/* find it in the list */
			for (child_node = first_child_node; child_node != NULL; child_node = xml_get_sibling(child_node->next, "entry"))
			{
				attr_node = xml_get_attribute(child_node, "name");
				if ((attr_node != NULL) && !strcmp(attr_node->value, dirent->name))
					break;
			}

			/* did we find the node? */
			if (child_node != NULL)
			{
				/* check dirent type */
				attr_node = xml_get_attribute(child_node, "type");
				if (attr_node != NULL)
				{
					type_string = dir_entry_type_string(dirent->type);
					if (mame_stricmp(attr_node->value, type_string))
						report_message(MSG_FAILURE, "Expected '%s' to be '%s', but instead got '%s'", dirent->name, attr_node->value, type_string);
				}

				/* check size */
				attr_node = xml_get_attribute(child_node, "size");
				if (attr_node != NULL)
				{
					size = atoi(attr_node->value);
					if (size != dirent->size)
						report_message(MSG_FAILURE, "Expected '%s' to be of size '%ld', but instead got '%ld'", dirent->name, (long) size, (long) dirent->size);
				}
			}
			else
			{
				report_message(MSG_FAILURE, "Unexpected directory entry '%s'", dirent->name);
			}
		}
	}

done:
	pile_delete(&pile);
	if (apath != NULL)
		astring_free(apath);
	if (file != NULL)
		core_fclose(file);
	if (directory != NULL)
		zippath_closedir(directory);
}