#include <parseargs.h>
#include <ctype.h>

#ifdef __STDC__
typedef void *pointer;
#else
typedef char *pointer;
#endif

extern pointer malloc();

#define ALL_AD		ad = argd; ad->ad_name != '\0'; ad++
#define ALL_DEFS	ad = _DefaultArgs; ad->ad_name != '\0'; ad++

extern char	*ProgName;

/* Argument list utility routines. After processing, parseargs calls
 * cleanup_lists to reverse all argument lists so they stay in order.
 */

/* Reverse a list */
struct arglist *reverselist(from)
struct arglist *from;
{
	struct arglist *to, *tmp;

	to = NULL;
	while(from) {
		tmp = from; /* remove top from old list */
		from = from->nl_next;
		tmp->nl_next = to; /* insert top in new list */
		to = tmp;
	}
	return to;
}

/* Reverse all arglists in argd */
cleanup_lists(argd)
ARGDESC *argd;
{
	ARGDESC *ad;

	for(ALL_AD) {
		if( (ad->ad_flags & ARGLIST) &&
		    *(struct arglist **)ad->ad_valp) {
			*(struct arglist **)ad->ad_valp =
				reverselist( *(struct arglist **)ad->ad_valp );
		}
	}
}

/*
**  ARGlist -- list argument translation routines.
**
**	Each of these converts a parameter value to the internal form,
**	including validity checking.  Their parameters and return values
**	all behave identically. These are the routines for dealing with
**	lists...
**
**	Parameters:
**		ad -- the argument descriptor for this parameter.
**		vp -- a pointer to the string input value.
**		copyf -- if TRUE, the value will be destroyed later,
**			and so should be copied if it will be retained
**			(as for a string).
**
**	Returns:
**		TRUE -- if the conversion was successful.  The actual
**			value should be added to the list stored in the
**			location indicated by ad->ad_valp.
**		FALSE -- if the conversion failed.  The reason for failure
**			should be diagnosed using usrerr().
**
**	Side Effects:
**		The value should be stored through ad->ad_valp.
*/

BOOL
listStr(ad, vp, copyf)
	register ARGDESC *ad;
	register char *vp;
	BOOL copyf;
{
	char *cp;
	struct arglist *nl;

	if (copyf)
	{
		register int i;

		i = strlen(vp) + 1;
		cp = (char *) malloc(i);
		if(!cp) {
			usrerr("out of memory saving string %s", ad->ad_prompt);
			return FALSE;
		}
		bcopy(vp, cp, i);
	}
	else
	{
		cp = vp;
	}

	nl = (struct arglist *) malloc(sizeof *nl);
	if(!nl) {
		usrerr("out of memory saving arg %s", ad->ad_prompt);
		if(copyf) free(cp);
		return FALSE;
	}

	nl->nl_next = *(struct arglist **) ad->ad_valp;
	nl->nl_val = (ARBPTR)cp;
	*(struct arglist **) ad->ad_valp = nl;
	return (TRUE);
}

