
#include "strutils.h"
#include "fdiskP.h"

/**
 * SECTION: ask
 * @title: Ask
 * @short_description: interface for dialog driven partitioning, warning and info messages
 *
 */

static void fdisk_ask_menu_reset_items(struct fdisk_ask *ask);


/**
 * fdisk_set_ask:
 * @cxt: context
 * @ask_cb: callback
 * @data: callback data
 *
 * Set callback for dialog driven partitioning and library warnings/errors.
 *
 * Returns: 0 on success, < 0 on error.
 */
int fdisk_set_ask(struct fdisk_context *cxt,
		int (*ask_cb)(struct fdisk_context *, struct fdisk_ask *, void *),
		void *data)
{
	assert(cxt);

	cxt->ask_cb = ask_cb;
	cxt->ask_data = data;
	return 0;
}

struct fdisk_ask *fdisk_new_ask(void)
{
	struct fdisk_ask *ask = calloc(1, sizeof(struct fdisk_ask));
	DBG(ASK, ul_debugobj(ask, "alloc"));
	ask->refcount = 1;
	return ask;
}

void fdisk_reset_ask(struct fdisk_ask *ask)
{
	int refcount;

	assert(ask);
	free(ask->query);

	DBG(ASK, ul_debugobj(ask, "reset"));
	refcount = ask->refcount;

	if (fdisk_is_ask(ask, MENU))
		fdisk_ask_menu_reset_items(ask);

	memset(ask, 0, sizeof(*ask));
	ask->refcount = refcount;
}

/**
 * fdisk_ref_ask:
 * @ask: ask instance
 *
 * Incremparts reference counter.
 */
void fdisk_ref_ask(struct fdisk_ask *ask)
{
	if (ask)
		ask->refcount++;
}


/**
 * fdisk_unref_ask:
 * @ask: ask instance
 *
 * De-incremparts reference counter, on zero the @ask is automatically
 * deallocated.
 */
void fdisk_unref_ask(struct fdisk_ask *ask)
{
	if (!ask)
		return;
	ask->refcount--;

	if (ask->refcount <= 0) {
		fdisk_reset_ask(ask);
		DBG(ASK, ul_debugobj(ask, "free"));
		free(ask);
	}
}

/**
 * fdisk_ask_get_query:
 * @ask: ask instance
 *
 * Returns: pointer to dialog string.
 */
const char *fdisk_ask_get_query(struct fdisk_ask *ask)
{
	assert(ask);
	return ask->query;
}

int fdisk_ask_set_query(struct fdisk_ask *ask, const char *str)
{
	assert(ask);
	return !strdup_to_struct_member(ask, query, str) ? -ENOMEM : 0;
}

/**
 * fdisk_ask_get_type:
 * @ask: ask instance
 *
 * Returns: FDISK_ASKTYPE_*
 */
int fdisk_ask_get_type(struct fdisk_ask *ask)
{
	assert(ask);
	return ask->type;
}

int fdisk_ask_set_type(struct fdisk_ask *ask, int type)
{
	assert(ask);
	ask->type = type;
	return 0;
}

int fdisk_do_ask(struct fdisk_context *cxt, struct fdisk_ask *ask)
{
	int rc;

	assert(ask);
	assert(cxt);

	DBG(ASK, ul_debugobj(ask, "do_ask for '%s'",
				ask->query ? ask->query :
				ask->type == FDISK_ASKTYPE_INFO  ? "info" :
				ask->type == FDISK_ASKTYPE_WARNX ? "warnx" :
				ask->type == FDISK_ASKTYPE_WARN  ? "warn" :
				"?nothing?"));

	if (!cxt->ask_cb) {
		DBG(ASK, ul_debugobj(ask, "no ask callback specified!"));
		return -EINVAL;
	}

	rc = cxt->ask_cb(cxt, ask, cxt->ask_data);

	DBG(ASK, ul_debugobj(ask, "do_ask done [rc=%d]", rc));
	return rc;
}

#define is_number_ask(a)  (fdisk_is_ask(a, NUMBER) || fdisk_is_ask(a, OFFSET))

/**
 * fdisk_ask_number_get_range:
 * @ask: ask instance
 *
 * Returns: string with range (e.g. "1,3,5-10")
 */
const char *fdisk_ask_number_get_range(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.range;
}

int fdisk_ask_number_set_range(struct fdisk_ask *ask, const char *range)
{
	assert(ask);
	assert(is_number_ask(ask));
	ask->data.num.range = range;
	return 0;
}

/**
 * fdisk_ask_number_get_default:
 * @ask: ask instance
 *
 * Returns: default number
 *
 */
uint64_t fdisk_ask_number_get_default(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.dfl;
}

int fdisk_ask_number_set_default(struct fdisk_ask *ask, uint64_t dflt)
{
	assert(ask);
	ask->data.num.dfl = dflt;
	return 0;
}

/**
 * fdisk_ask_number_get_low:
 * @ask: ask instance
 *
 * Returns: minimal possible number when ask for numbers in range
 */
uint64_t fdisk_ask_number_get_low(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.low;
}

int fdisk_ask_number_set_low(struct fdisk_ask *ask, uint64_t low)
{
	assert(ask);
	ask->data.num.low = low;
	return 0;
}

/**
 * fdisk_ask_number_get_high:
 * @ask: ask instance
 *
 * Returns: maximal possible number when ask for numbers in range
 */
uint64_t fdisk_ask_number_get_high(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.hig;
}

int fdisk_ask_number_set_high(struct fdisk_ask *ask, uint64_t high)
{
	assert(ask);
	ask->data.num.hig = high;
	return 0;
}

/**
 * fdisk_ask_number_get_result:
 * @ask: ask instance
 *
 * Returns: result
 */
uint64_t fdisk_ask_number_get_result(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.result;
}

/**
 * fdisk_ask_number_set_result:
 * @ask: ask instance
 * @result: dialog result
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_ask_number_set_result(struct fdisk_ask *ask, uint64_t result)
{
	assert(ask);
	ask->data.num.result = result;
	return 0;
}

/**
 * fdisk_ask_number_get_base:
 * @ask: ask instance
 *
 * Returns: base when user specify number in relative notation (+size)
 */
uint64_t fdisk_ask_number_get_base(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.base;
}

int fdisk_ask_number_set_base(struct fdisk_ask *ask, uint64_t base)
{
	assert(ask);
	ask->data.num.base = base;
	return 0;
}

/**
 * fdisk_ask_number_get_unit:
 * @ask: ask instance
 *
 * Returns: number of bytes per the unit
 */
uint64_t fdisk_ask_number_get_unit(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.unit;
}

int fdisk_ask_number_set_unit(struct fdisk_ask *ask, uint64_t unit)
{
	assert(ask);
	ask->data.num.unit = unit;
	return 0;
}

int fdisk_ask_number_is_relative(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.relative;
}

/**
 * fdisk_ask_number_set_relative
 * @ask: ask instance
 * @relative: 0 or 1
 *
 * Inform libfdisk that user specified number in relative notation rather than
 * by explicit number. This info allows to fdisk do some optimization (e.g.
 * align end of partiton, etc.)
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_ask_number_set_relative(struct fdisk_ask *ask, int relative)
{
	assert(ask);
	ask->data.num.relative = relative ? 1 : 0;
	return 0;
}

/**
 * fdisk_ask_number_inchars:
 * @ask: ask instance
 *
 * For example for BSD is normal to address partition by chars rather than by
 * number (first partition is 'a').
 *
 * Returns: 1 if number should be presented as chars
 *
 */
int fdisk_ask_number_inchars(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_number_ask(ask));
	return ask->data.num.inchars;
}

/*
 * Generates string with list ranges (e.g. 1,2,5-8) for the 'cur'
 */
#define tochar(num)	((int) ('a' + num - 1))
static char *mk_string_list(char *ptr, size_t *len, size_t *begin,
			    size_t *run, ssize_t cur, int inchar)
{
	int rlen;

	if (cur != -1) {
		if (!*begin) {			/* begin of the list */
			*begin = cur + 1;
			return ptr;
		}

		if (*begin + *run == cur) {	/* no gap, continue */
			(*run)++;
			return ptr;
		}
	} else if (!*begin) {
		*ptr = '\0';
		return ptr;		/* end of empty list */
	}

					/* add to the list */
	if (!*run)
		rlen = inchar ? snprintf(ptr, *len, "%c,", tochar(*begin)) :
				snprintf(ptr, *len, "%zu,", *begin);
	else if (*run == 1)
		rlen = inchar ?
			snprintf(ptr, *len, "%c,%c,", tochar(*begin), tochar(*begin + 1)) :
			snprintf(ptr, *len, "%zu,%zu,", *begin, *begin + 1);
	else
		rlen = inchar ?
			snprintf(ptr, *len, "%c-%c,", tochar(*begin), tochar(*begin + *run)) :
			snprintf(ptr, *len, "%zu-%zu,", *begin, *begin + *run);

	if (rlen < 0 || (size_t) rlen + 1 > *len)
		return NULL;

	ptr += rlen;

	if (rlen > 0 && *len > (size_t) rlen)
		*len -= rlen;
	else
		*len = 0;

	if (cur == -1 && *begin) {
		/* end of the list */
		*(ptr - 1) = '\0';	/* remove tailing ',' from the list */
		return ptr;
	}

	*begin = cur + 1;
	*run = 0;

	return ptr;
}

/**
 * fdisk_ask_partnum:
 * @cxt: context
 * @partnum: returns partition number
 * @wantnew: 0|1
 *
 * High-level API to ask for used or unused partition number.
 *
 * Returns: 0 on success, < 0 on error, 1 if no free/used partition
 */
int fdisk_ask_partnum(struct fdisk_context *cxt, size_t *partnum, int wantnew)
{
	int rc = 0, inchar = 0;
	char range[BUFSIZ], *ptr = range;
	size_t i, len = sizeof(range), begin = 0, run = 0;
	struct fdisk_ask *ask = NULL;
	__typeof__(ask->data.num) *num;

	assert(cxt);
	assert(cxt->label);
	assert(partnum);

	if (cxt->label && cxt->label->flags & FDISK_LABEL_FL_INCHARS_PARTNO)
		inchar = 1;

	DBG(ASK, ul_debug("%s: asking for %s partition number "
			  "(max: %zu, inchar: %s)",
			cxt->label->name,
			wantnew ? "new" : "used",
			cxt->label->nparts_max,
			inchar ? "yes" : "not"));

	ask = fdisk_new_ask();
	if (!ask)
		return -ENOMEM;

	fdisk_ask_set_type(ask, FDISK_ASKTYPE_NUMBER);
	num = &ask->data.num;

	ask->data.num.inchars = inchar ? 1 : 0;

	for (i = 0; i < cxt->label->nparts_max; i++) {
		int used = fdisk_is_partition_used(cxt, i);

		if (wantnew && !used) {
			ptr = mk_string_list(ptr, &len, &begin, &run, i, inchar);
			if (!ptr) {
				rc = -EINVAL;
				break;
			}
			if (!num->low)
				num->dfl = num->low = i + 1;
			num->hig = i + 1;
		} else if (!wantnew && used) {
			ptr = mk_string_list(ptr, &len, &begin, &run, i, inchar);
			if (!num->low)
				num->low = i + 1;
			num->dfl = num->hig = i + 1;
		}
	}

	DBG(ASK, ul_debugobj(ask, "ask limits: low: %ju, high: %ju, default: %ju",
				num->low, num->hig, num->dfl));

	if (!rc && !wantnew && num->low == num->hig) {
		if (num->low > 0) {
			/* only one existing partiton, don't ask, return the number */
			fdisk_ask_number_set_result(ask, num->low);
			fdisk_info(cxt, _("Selected partition %ju"), num->low);

		} else if (num->low == 0) {
			fdisk_warnx(cxt, _("No partition is defined yet!"));
			rc = 1;
		}
		goto dont_ask;
	}
	if (!rc && wantnew && num->low == num->hig) {
		if (num->low > 0) {
			/* only one free partition, don't ask, return the number */
			fdisk_ask_number_set_result(ask, num->low);
			fdisk_info(cxt, _("Selected partition %ju"), num->low);
		}
		if (num->low == 0) {
			fdisk_warnx(cxt, _("No free partition available!"));
			rc = 1;
		}
		goto dont_ask;
	}
	if (!rc) {
		mk_string_list(ptr, &len, &begin, &run, -1, inchar);	/* terminate the list */
		rc = fdisk_ask_number_set_range(ask, range);
	}
	if (!rc)
		rc = fdisk_ask_set_query(ask, _("Partition number"));
	if (!rc)
		rc = fdisk_do_ask(cxt, ask);

dont_ask:
	if (!rc) {
		*partnum = fdisk_ask_number_get_result(ask);
		if (*partnum)
			*partnum -= 1;
	}
	DBG(ASK, ul_debugobj(ask, "result: %ju [rc=%d]\n", fdisk_ask_number_get_result(ask), rc));
	fdisk_unref_ask(ask);
	return rc;
}

/**
 * fdisk_ask_number:
 * @cxt: context
 * @low: minimal possible number
 * @dflt: default suggestion
 * @high: maximal possible number
 * @query: question string
 * @result: returns result
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_ask_number(struct fdisk_context *cxt,
		     uintmax_t low,
		     uintmax_t dflt,
		     uintmax_t high,
		     const char *query,
		     uintmax_t *result)
{
	struct fdisk_ask *ask;
	int rc;

	assert(cxt);

	ask = fdisk_new_ask();
	if (!ask)
		return -ENOMEM;

	rc = fdisk_ask_set_type(ask, FDISK_ASKTYPE_NUMBER);
	if (!rc)
		fdisk_ask_number_set_low(ask, low);
	if (!rc)
		fdisk_ask_number_set_default(ask, dflt);
	if (!rc)
		fdisk_ask_number_set_high(ask, high);
	if (!rc)
		fdisk_ask_set_query(ask, query);
	if (!rc)
		rc = fdisk_do_ask(cxt, ask);
	if (!rc)
		*result = fdisk_ask_number_get_result(ask);

	DBG(ASK, ul_debugobj(ask, "result: %ju [rc=%d]\n", *result, rc));
	fdisk_unref_ask(ask);
	return rc;
}

/**
 * fdisk_ask_string_get_result:
 * @ask: ask instance
 *
 * Returns: pointer to dialog result
 */
char *fdisk_ask_string_get_result(struct fdisk_ask *ask)
{
	assert(ask);
	assert(fdisk_is_ask(ask, STRING));
	return ask->data.str.result;
}

/**
 * fdisk_ask_string_set_result:
 * @ask: ask instance
 * @result: pointer to allocated buffer with string
 *
 * You don't have to care about the @result deallocation, libfdisk is going to
 * deallocate the result when destroy @ask instance.
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_ask_string_set_result(struct fdisk_ask *ask, char *result)
{
	assert(ask);
	ask->data.str.result = result;
	return 0;
}

/**
 * fdisk_ask_string:
 * @cxt: context:
 * @query: question string
 * @result: returns allocated buffer
 *
 * High-level API to ask for strings. Don't forget to deallocate the @result.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_ask_string(struct fdisk_context *cxt,
		     const char *query,
		     char **result)
{
	struct fdisk_ask *ask;
	int rc;

	assert(cxt);

	ask = fdisk_new_ask();
	if (!ask)
		return -ENOMEM;

	rc = fdisk_ask_set_type(ask, FDISK_ASKTYPE_STRING);
	if (!rc)
		fdisk_ask_set_query(ask, query);
	if (!rc)
		rc = fdisk_do_ask(cxt, ask);
	if (!rc)
		*result = fdisk_ask_string_get_result(ask);

	DBG(ASK, ul_debugobj(ask, "result: %s [rc=%d]\n", *result, rc));
	fdisk_unref_ask(ask);
	return rc;
}

/**
 * fdisk_ask_yesno:
 * @cxt: context
 * @query: question string
 * @result: returns 0 (no) or 1 (yes)
 *
 * Hight-level API to ask Yes/No questions
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_ask_yesno(struct fdisk_context *cxt,
		     const char *query,
		     int *result)
{
	struct fdisk_ask *ask;
	int rc;

	assert(cxt);

	ask = fdisk_new_ask();
	if (!ask)
		return -ENOMEM;

	rc = fdisk_ask_set_type(ask, FDISK_ASKTYPE_YESNO);
	if (!rc)
		fdisk_ask_set_query(ask, query);
	if (!rc)
		rc = fdisk_do_ask(cxt, ask);
	if (!rc)
		*result = fdisk_ask_yesno_get_result(ask) == 1 ? 1 : 0;

	DBG(ASK, ul_debugobj(ask, "result: %d [rc=%d]\n", *result, rc));
	fdisk_unref_ask(ask);
	return rc;
}

/**
 * fdisk_ask_yesno_get_result:
 * @ask: ask instance
 *
 * Returns: 0 or 1
 */
int fdisk_ask_yesno_get_result(struct fdisk_ask *ask)
{
	assert(ask);
	assert(fdisk_is_ask(ask, YESNO));
	return ask->data.yesno.result;
}

/**
 * fdisk_ask_yesno_set_result:
 * @ask: ask instance
 * @result: 1 or 0
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_ask_yesno_set_result(struct fdisk_ask *ask, int result)
{
	assert(ask);
	ask->data.yesno.result = result;
	return 0;
}

/*
 * menu
 */
int fdisk_ask_menu_set_default(struct fdisk_ask *ask, int dfl)
{
	assert(ask);
	assert(fdisk_is_ask(ask, MENU));
	ask->data.menu.dfl = dfl;
	return 0;
}

/**
 * fdisk_ask_menu_get_default:
 * @ask: ask instance
 *
 * Returns: default menu item key
 */
int fdisk_ask_menu_get_default(struct fdisk_ask *ask)
{
	assert(ask);
	assert(fdisk_is_ask(ask, MENU));
	return ask->data.menu.dfl;
}

/**
 * fdisk_ask_menu_set_result:
 * @ask: ask instance
 * @key: result
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_ask_menu_set_result(struct fdisk_ask *ask, int key)
{
	assert(ask);
	assert(fdisk_is_ask(ask, MENU));
	ask->data.menu.result = key;
	DBG(ASK, ul_debugobj(ask, "menu result: %c\n", key));
	return 0;

}

/**
 * fdisk_ask_menu_get_result:
 * @ask: ask instance
 * @key: returns selected menu item key
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_ask_menu_get_result(struct fdisk_ask *ask, int *key)
{
	assert(ask);
	assert(fdisk_is_ask(ask, MENU));
	if (key)
		*key =  ask->data.menu.result;
	return 0;
}

/**
 * fdisk_ask_menu_get_item:
 * @ask: ask menu instance
 * @idx: wanted menu item index
 * @key: returns key of the menu item
 * @name: returns name of the menu item
 * @desc: returns description of the menu item
 *
 * Returns: 0 on success, <0 on error, >0 if idx out-of-range
 */
int fdisk_ask_menu_get_item(struct fdisk_ask *ask, size_t idx, int *key,
			    const char **name, const char **desc)
{
	size_t i;
	struct ask_menuitem *mi;

	assert(ask);
	assert(fdisk_is_ask(ask, MENU));

	for (i = 0, mi = ask->data.menu.first; mi; mi = mi->next, i++) {
		if (i == idx)
			break;
	}

	if (!mi)
		return 1;	/* no more items */
	if (key)
		*key = mi->key;
	if (name)
		*name = mi->name;
	if (desc)
		*desc = mi->desc;
	return 0;
}

static void fdisk_ask_menu_reset_items(struct fdisk_ask *ask)
{
	struct ask_menuitem *mi;

	assert(ask);
	assert(fdisk_is_ask(ask, MENU));

	for (mi = ask->data.menu.first; mi; ) {
		struct ask_menuitem *next = mi->next;
		free(mi);
		mi = next;
	}
}

/**
 * fdisk_ask_menu_get_nitems:
 * @ask: ask instance
 *
 * Returns: number of menu items
 */
size_t fdisk_ask_menu_get_nitems(struct fdisk_ask *ask)
{
	struct ask_menuitem *mi;
	size_t n;

	assert(ask);
	assert(fdisk_is_ask(ask, MENU));

	for (n = 0, mi = ask->data.menu.first; mi; mi = mi->next, n++);

	return n;
}

int fdisk_ask_menu_add_item(struct fdisk_ask *ask, int key,
			const char *name, const char *desc)
{
	struct ask_menuitem *mi;

	assert(ask);
	assert(fdisk_is_ask(ask, MENU));

	mi = calloc(1, sizeof(*mi));
	if (!mi)
		return -ENOMEM;
	mi->key = key;
	mi->name = name;
	mi->desc = desc;

	if (!ask->data.menu.first)
		ask->data.menu.first = mi;
	else {
	        struct ask_menuitem *last = ask->data.menu.first;

		while (last->next)
			last = last->next;
		last->next = mi;
	}

	DBG(ASK, ul_debugobj(ask, "new menu item: %c, \"%s\" (%s)\n", mi->key, mi->name, mi->desc));
	return 0;
}


/*
 * print-like
 */

#define is_print_ask(a) (fdisk_is_ask(a, WARN) || fdisk_is_ask(a, WARNX) || fdisk_is_ask(a, INFO))

/**
 * fdisk_ask_print_get_errno:
 * @ask: ask instance
 *
 * Returns: error number for warning/error messages
 */
int fdisk_ask_print_get_errno(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_print_ask(ask));
	return ask->data.print.errnum;
}

int fdisk_ask_print_set_errno(struct fdisk_ask *ask, int errnum)
{
	assert(ask);
	ask->data.print.errnum = errnum;
	return 0;
}

/**
 * fdisk_ask_print_get_mesg:
 * @ask: ask instance
 *
 * Returns: pointer to message
 */
const char *fdisk_ask_print_get_mesg(struct fdisk_ask *ask)
{
	assert(ask);
	assert(is_print_ask(ask));
	return ask->data.print.mesg;
}

/* does not reallocate the message! */
int fdisk_ask_print_set_mesg(struct fdisk_ask *ask, const char *mesg)
{
	assert(ask);
	ask->data.print.mesg = mesg;
	return 0;
}

static int do_vprint(struct fdisk_context *cxt, int errnum, int type,
		     const char *fmt, va_list va)
{
	struct fdisk_ask *ask;
	int rc;
	char *mesg;

	assert(cxt);

	if (vasprintf(&mesg, fmt, va) < 0)
		return -ENOMEM;

	ask = fdisk_new_ask();
	if (!ask) {
		free(mesg);
		return -ENOMEM;
	}

	fdisk_ask_set_type(ask, type);
	fdisk_ask_print_set_mesg(ask, mesg);
	if (errnum >= 0)
		fdisk_ask_print_set_errno(ask, errnum);
	rc = fdisk_do_ask(cxt, ask);

	fdisk_unref_ask(ask);
	free(mesg);
	return rc;
}

/**
 * fdisk_info:
 * @cxt: context
 * @fmt: printf-like formatted string
 * @...: variable parametrs
 *
 * High-level API to print info messages,
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_info(struct fdisk_context *cxt, const char *fmt, ...)
{
	int rc;
	va_list ap;

	assert(cxt);
	va_start(ap, fmt);
	rc = do_vprint(cxt, -1, FDISK_ASKTYPE_INFO, fmt, ap);
	va_end(ap);
	return rc;
}

/**
 * fdisk_info:
 * @cxt: context
 * @fmt: printf-like formatted string
 * @...: variable parametrs
 *
 * High-level API to print warning message (errno expected)
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_warn(struct fdisk_context *cxt, const char *fmt, ...)
{
	int rc;
	va_list ap;

	assert(cxt);
	va_start(ap, fmt);
	rc = do_vprint(cxt, errno, FDISK_ASKTYPE_WARN, fmt, ap);
	va_end(ap);
	return rc;
}

/**
 * fdisk_warnx:
 * @cxt: context
 * @fmt: printf-like formatted string
 * @...: variable options
 *
 * High-level API to print warning message
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_warnx(struct fdisk_context *cxt, const char *fmt, ...)
{
	int rc;
	va_list ap;

	assert(cxt);
	va_start(ap, fmt);
	rc = do_vprint(cxt, -1, FDISK_ASKTYPE_WARNX, fmt, ap);
	va_end(ap);
	return rc;
}

int fdisk_info_new_partition(
			struct fdisk_context *cxt,
			int num, fdisk_sector_t start, fdisk_sector_t stop,
			struct fdisk_parttype *t)
{
	int rc;
	char *str = size_to_human_string(SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE,
				     (uint64_t)(stop - start + 1) * cxt->sector_size);

	rc = fdisk_info(cxt,
			_("Created a new partition %d of type '%s' and of size %s."),
			num, t ? t->name : _("Unknown"), str);
	free(str);
	return rc;
}

#ifdef TEST_PROGRAM
int test_ranges(struct fdisk_test *ts, int argc, char *argv[])
{
	/*                1  -  3,       6,    8, 9,   11    13 */
	size_t nums[] = { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1 };
	size_t numx[] = { 0, 0, 0 };
	char range[BUFSIZ], *ptr = range;
	size_t i, len = sizeof(range), begin = 0, run = 0;

	for (i = 0; i < ARRAY_SIZE(nums); i++) {
		if (!nums[i])
			continue;
		ptr = mk_string_list(ptr, &len, &begin, &run, i, 0);
	}
	mk_string_list(ptr, &len, &begin, &run, -1, 0);
	printf("list: '%s'\n", range);

	ptr = range;
	len = sizeof(range), begin = 0, run = 0;
	for (i = 0; i < ARRAY_SIZE(numx); i++) {
		if (!numx[i])
			continue;
		ptr = mk_string_list(ptr, &len, &begin, &run, i, 0);
	}
	mk_string_list(ptr, &len, &begin, &run, -1, 0);
	printf("empty list: '%s'\n", range);

	return 0;
}

int main(int argc, char *argv[])
{
	struct fdisk_test tss[] = {
	{ "--ranges",  test_ranges,    "generates ranges" },
	{ NULL }
	};

	return fdisk_run_test(tss, argc, argv);
}

#endif
