예제 #1
0
파일: scenario.c 프로젝트: AmesianX/nvml
/*
 * clone_scenario -- alloc a new scenario and copy all data from src scenario
 */
struct scenario *
clone_scenario(struct scenario *src_scenario)
{
	assert(src_scenario != NULL);

	struct scenario *new_scenario = scenario_alloc(src_scenario->name,
						src_scenario->benchmark);
	assert(new_scenario != NULL);

	struct kv *src_kv;

	FOREACH_KV(src_kv, src_scenario) {
		struct kv *new_kv = kv_alloc(src_kv->key, src_kv->value);
		assert(new_kv != NULL);

		TAILQ_INSERT_TAIL(&new_scenario->head, new_kv, next);
	}

	return new_scenario;
}
예제 #2
0
/*
 * config_reader_get_scenarios -- return scenarios from config file
 *
 * This function reads the config file and returns a list of scenarios.
 * Each scenario contains a list of key/value arguments.
 * The scenario's arguments are merged with arguments from global section.
 */
int
config_reader_get_scenarios(struct config_reader *cr,
			    struct scenarios **scenarios)
{
	/*
	 * Read all groups.
	 * The config file must have at least one group, otherwise
	 * it is considered as invalid.
	 */
	gsize ngroups;
	gsize g;
	gchar **groups = g_key_file_get_groups(cr->key_file, &ngroups);
	assert(nullptr != groups);
	if (!groups)
		return -1;

	/*
	 * Check if global section is present and read keys from it.
	 */
	int ret = 0;
	int has_global =
		g_key_file_has_group(cr->key_file, SECTION_GLOBAL) == TRUE;
	gsize ngkeys;
	gchar **gkeys = nullptr;
	struct scenarios *s;
	if (has_global) {
		gkeys = g_key_file_get_keys(cr->key_file, SECTION_GLOBAL,
					    &ngkeys, nullptr);
		assert(nullptr != gkeys);
		if (!gkeys) {
			ret = -1;
			goto err_groups;
		}
	}

	s = scenarios_alloc();
	assert(nullptr != s);
	if (!s) {
		ret = -1;
		goto err_gkeys;
	}

	for (g = 0; g < ngroups; g++) {
		/*
		 * Check whether a group is a scenario
		 * or global section.
		 */
		if (!is_scenario(groups[g]))
			continue;

		/*
		 * Check for KEY_BENCHMARK which contains benchmark name.
		 * If not present the benchmark name is the same as the
		 * name of the section.
		 */
		struct scenario *scenario = nullptr;
		if (g_key_file_has_key(cr->key_file, groups[g], KEY_BENCHMARK,
				       nullptr) == FALSE) {
			scenario = scenario_alloc(groups[g], groups[g]);
			assert(scenario != nullptr);
		} else {
			gchar *benchmark =
				g_key_file_get_value(cr->key_file, groups[g],
						     KEY_BENCHMARK, nullptr);
			assert(benchmark != nullptr);
			if (!benchmark) {
				ret = -1;
				goto err_scenarios;
			}
			scenario = scenario_alloc(groups[g], benchmark);
			assert(scenario != nullptr);
			free(benchmark);
		}

		gsize k;
		if (has_global) {
			/*
			 * Merge key/values from global section.
			 */
			for (k = 0; k < ngkeys; k++) {
				if (g_key_file_has_key(cr->key_file, groups[g],
						       gkeys[k],
						       nullptr) == TRUE)
					continue;

				if (!is_argument(gkeys[k]))
					continue;

				char *value = g_key_file_get_value(
					cr->key_file, SECTION_GLOBAL, gkeys[k],
					nullptr);
				assert(nullptr != value);
				if (!value) {
					ret = -1;
					goto err_scenarios;
				}

				struct kv *kv = kv_alloc(gkeys[k], value);
				assert(nullptr != kv);

				free(value);
				if (!kv) {
					ret = -1;
					goto err_scenarios;
				}

				TAILQ_INSERT_TAIL(&scenario->head, kv, next);
			}
		}

		/* check for group name */
		if (g_key_file_has_key(cr->key_file, groups[g], KEY_GROUP,
				       nullptr) != FALSE) {
			gchar *group = g_key_file_get_value(
				cr->key_file, groups[g], KEY_GROUP, nullptr);
			assert(group != nullptr);
			scenario_set_group(scenario, group);
		} else if (g_key_file_has_key(cr->key_file, SECTION_GLOBAL,
					      KEY_GROUP, nullptr) != FALSE) {
			gchar *group = g_key_file_get_value(cr->key_file,
							    SECTION_GLOBAL,
							    KEY_GROUP, nullptr);
			scenario_set_group(scenario, group);
		}

		gsize nkeys;
		gchar **keys = g_key_file_get_keys(cr->key_file, groups[g],
						   &nkeys, nullptr);
		assert(nullptr != keys);
		if (!keys) {
			ret = -1;
			goto err_scenarios;
		}

		/*
		 * Read key/values from the scenario's section.
		 */
		for (k = 0; k < nkeys; k++) {
			if (!is_argument(keys[k]))
				continue;
			char *value = g_key_file_get_value(
				cr->key_file, groups[g], keys[k], nullptr);
			assert(nullptr != value);
			if (!value) {
				ret = -1;
				g_strfreev(keys);
				goto err_scenarios;
			}

			struct kv *kv = kv_alloc(keys[k], value);
			assert(nullptr != kv);

			free(value);
			if (!kv) {
				g_strfreev(keys);
				ret = -1;
				goto err_scenarios;
			}

			TAILQ_INSERT_TAIL(&scenario->head, kv, next);
		}

		g_strfreev(keys);

		TAILQ_INSERT_TAIL(&s->head, scenario, next);
	}

	g_strfreev(gkeys);
	g_strfreev(groups);

	*scenarios = s;
	return 0;
err_scenarios:
	scenarios_free(s);
err_gkeys:
	g_strfreev(gkeys);
err_groups:
	g_strfreev(groups);
	return ret;
}
예제 #3
0
/*
 * config_reader_get_scenarios -- return scenarios from config file
 *
 * This function reads the config file and returns a list of scenarios.
 * Each scenario contains a list of key/value arguments.
 * The scenario's arguments are merged with arguments from global section.
 */
int
config_reader_get_scenarios(struct config_reader *cr,
			    struct scenarios **scenarios)
{
	/*
	 * Read all groups.
	 * The config file must have at least one group, otherwise
	 * it is considered as invalid.
	 */
	int ret = 0;

	TCHAR *sections = (TCHAR *)malloc(sizeof(TCHAR) * SIZEOF_SECTION);
	if (!sections)
		return -1;

	GetPrivateProfileSectionNames(sections, SIZEOF_SECTION, cr->lpFileName);

	if (NULL_LIST_EMPTY(sections)) {
		ret = -1;
		goto err_sections;
	}

	/*
	 * Check if global section is present and read it.
	 */
	TCHAR *global = (TCHAR *)malloc(sizeof(TCHAR) * SIZEOF_SECTION);
	if (!global)
		return -1;

	GetPrivateProfileSection(SECTION_GLOBAL, global, SIZEOF_SECTION,
				 cr->lpFileName);
	KV_LIST global_kv = KV_LIST_INIT(global);

	int has_global = !KV_LIST_EMPTY(global_kv);

	struct scenarios *s = scenarios_alloc();
	assert(NULL != s);
	if (!s) {
		ret = -1;
		goto err_gkeys;
	}

	LPTSTR global_group = NULL;
	for (KV_LIST it = global_kv; !KV_LIST_EMPTY(it); KV_LIST_NEXT(it)) {
		if (_tcscmp(KV_LIST_KEY(it), KEY_GROUP) == 0) {
			global_group = KV_LIST_VALUE(it);
			break;
		}
	}
	TCHAR *section;
	for (LPTSTR group_name = sections; !NULL_LIST_EMPTY(group_name);
	     group_name = NULL_LIST_NEXT(group_name)) {
		/*
		 * Check whether a group is a scenario
		 * or global section.
		 */
		if (!is_scenario(group_name))
			continue;

		/*
		 * Check for KEY_BENCHMARK which contains benchmark name.
		 * If not present the benchmark name is the same as the
		 * name of the section.
		 */
		section = (TCHAR *)malloc(sizeof(TCHAR) * SIZEOF_SECTION);
		if (!section)
			ret = -1;
		GetPrivateProfileSection(group_name, section, SIZEOF_SECTION,
					 cr->lpFileName);

		KV_LIST section_kv = KV_LIST_INIT(section);
		struct scenario *scenario = NULL;
		LPTSTR name = NULL;
		LPTSTR group = NULL;
		for (KV_LIST it = section_kv; !KV_LIST_EMPTY(it);
		     KV_LIST_NEXT(it)) {
			if (_tcscmp(KV_LIST_KEY(it), KEY_BENCHMARK) == 0) {
				name = KV_LIST_VALUE(it);
			}
			if (_tcscmp(KV_LIST_KEY(it), KEY_GROUP) == 0) {
				group = KV_LIST_VALUE(it);
			}
		}
		if (name == NULL) {
			scenario = scenario_alloc((const char *)group_name,
						  (const char *)group_name);
		} else {
			scenario = scenario_alloc((const char *)group_name,
						  (const char *)name);
		}
		assert(scenario != NULL);

		if (has_global) {
			/*
			 * Merge key/values from global section.
			 */
			for (KV_LIST it = global_kv; !KV_LIST_EMPTY(it);
			     KV_LIST_NEXT(it)) {
				LPTSTR key = KV_LIST_KEY(it);
				if (!is_argument(key))
					continue;

				LPTSTR value = KV_LIST_VALUE(it);
				assert(NULL != value);
				if (!value) {
					ret = -1;
					goto err_scenarios;
				}

				struct kv *kv = kv_alloc((const char *)key,
							 (const char *)value);
				assert(NULL != kv);

				if (!kv) {
					ret = -1;
					goto err_scenarios;
				}

				TAILQ_INSERT_TAIL(&scenario->head, kv, next);
			}
		}

		/* check for group name */
		if (group) {
			scenario_set_group(scenario, (const char *)group);
		} else if (global_group) {
			scenario_set_group(scenario,
					   (const char *)global_group);
		}

		for (KV_LIST it = section_kv; !KV_LIST_EMPTY(it);
		     KV_LIST_NEXT(it)) {
			LPTSTR key = KV_LIST_KEY(it);
			if (!is_argument(key))
				continue;

			LPTSTR value = KV_LIST_VALUE(it);
			assert(NULL != value);
			if (!value) {
				ret = -1;
				goto err_scenarios;
			}

			struct kv *kv = kv_alloc((const char *)key,
						 (const char *)value);
			assert(NULL != kv);

			if (!kv) {
				ret = -1;
				goto err_scenarios;
			}

			TAILQ_INSERT_TAIL(&scenario->head, kv, next);
		}
		TAILQ_INSERT_TAIL(&s->head, scenario, next);

		free(section);
	}
	*scenarios = s;

	free(global);
	free(sections);
	return 0;

err_scenarios:
	free(section);
	scenarios_free(s);
err_gkeys:
	free(global);
err_sections:
	free(sections);
	return ret;
}