kv_double_from_string(const char *string,
		      const char *pair_separator,
		      const char *kv_separator,
		      struct key_value_double **result_out)

{
	char **pairs;
	char **pair;
	struct key_value_double *result = NULL;
	ssize_t npairs = 0;
	unsigned int idx = 0;

	if (!pair_separator || pair_separator[0] == '\0' ||
	    !kv_separator || kv_separator[0] == '\0')
		return -1;

	pairs = strv_from_string(string, pair_separator);
	if (!pairs)
		return -1;

	for (pair = pairs; *pair; pair++)
		npairs++;

	if (npairs == 0)
		goto error;

	result = zalloc(npairs * sizeof *result);

	for (pair = pairs; *pair; pair++) {
		char **kv = strv_from_string(*pair, kv_separator);
		double k, v;

		if (!kv || !kv[0] || !kv[1] || kv[2] ||
		    !safe_atod(kv[0], &k) ||
		    !safe_atod(kv[1], &v)) {
			strv_free(kv);
			goto error;
		}

		result[idx].key = k;
		result[idx].value = v;
		idx++;

		strv_free(kv);
	}

	strv_free(pairs);

	*result_out = result;

	return npairs;

error:
	strv_free(pairs);
	free(result);
	return -1;
}
kv_double_from_string(const char *string,
		      const char *pair_separator,
		      const char *kv_separator,
		      struct key_value_double **result_out)

{
	char **pairs;
	char **pair;
	struct key_value_double *result = NULL;
	ssize_t npairs = 0;
	unsigned int idx = 0;

	if (!pair_separator || pair_separator[0] == '\0' ||
	    !kv_separator || kv_separator[0] == '\0')
		return -1;

	pairs = strv_from_string(string, pair_separator);
	if (!pairs)
		return -1;

	for (pair = pairs; *pair; pair++)
		npairs++;

	if (npairs == 0)
		goto error;

	result = zalloc(npairs * sizeof *result);

	for (pair = pairs; *pair; pair++) {
		char **kv = strv_from_string(*pair, kv_separator);
		double k, v;

		if (!kv || !kv[0] || !kv[1] || kv[2] ||
		    !safe_atod(kv[0], &k) ||
		    !safe_atod(kv[1], &v)) {
			strv_free(kv);
			goto error;
		}

		result[idx].key = k;
		result[idx].value = v;
		idx++;

		strv_free(kv);
	}

	strv_free(pairs);

	*result_out = result;

	return npairs;

error:
	strv_free(pairs);
	free(result);
	return -1;
}