/*
 * Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: strexpdig.c,v 1.9 2005/06/06 16:26:06 ca Exp $")

#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/ctype.h"
#include "sm/str-int.h"
#include "sm/strexp.h"

/*
**  SM_STR_EXPDIG -- Expand %digit in string with argv[digit] (%=meta)
**	%[0-9] -> argv[0-9]
**	%x -> x for anything else
**
**	Parameters:
**		src -- str to expand (read)
**		dst -- str into which the expanded sequence is written (output)
**		meta -- meta character ('%')
**		argc -- number of valid elements in argv (0 - 10)
**		argv -- array of strings to use for expansion
**
**	Returns:
**		>=0: number of replacements
**		<0: usual sm_error code
*/

sm_ret_T
sm_str_expdig(const sm_str_P src, sm_str_P dst, uchar meta, uint argc, sm_str_P *argv)
{
	uint i, len, idx, n;
	uchar ch;
	sm_ret_T ret;

	SM_IS_BUF(dst);
	SM_IS_BUF(src);

	n = 0;
	if (meta == '\0')
		meta = '%';
	len = sm_str_getlen(src);
	for (i = 0; i < len; i++)
	{
		ch = sm_str_rd_elem(src, i);

		if (ch == meta && i + 1 < len)
		{
			++i;
			ch = sm_str_rd_elem(src, i);
			if (!ISDIGIT(ch))
			{
				ret = sm_str_put(dst, ch);
				if (sm_is_err(ret))
					goto error;
				continue;
			}

			idx = ch - '0';

			/*
			**  Is there an argv[] element for this?
			**  If no: %n will be replaced by an empty string!
			*/

			if (idx >= argc || argv[idx] == NULL)
				continue;
			ret = sm_str_cat(dst, argv[idx]);
			if (sm_is_err(ret))
				goto error;
			++n;
			continue;
		}

		ret = sm_str_put(dst, ch);
		if (sm_is_err(ret))
			goto error;
	}

	if (n > (uint)SM_RET_MAX)
		n = SM_RET_MAX;
	return (sm_ret_T) n;

  error:
	/* cleanup? */
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1