/*
 * 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: strsplit.c,v 1.4 2005/08/08 17:23:10 ca Exp $")

#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/memops.h"
#include "sm/rpool.h"
#include "sm/strrcb.h"
#include "sm/str-int.h"
#include "sm/str2rcb.h"

/*
**  SM_STR_SPLITIDX -- Split a string at a given position
**
**	Parameters:
**		str -- sm_str_P object to modify.
**		i -- index to use for splitting
**		excl -- exclude the character at i?
**		left -- left string
**		right -- right string
**
**	Returns:
**		0: usual error code (doesn't happen)
*/

sm_ret_T
sm_str_splitidx(sm_str_P str, uint i, bool excl, sm_str_P left, sm_str_P right)
{
	sm_ret_T ret;

	SM_IS_BUF(str);
	SM_REQUIRE(str->sm_str_base != NULL);
	if (left != NULL)
		SM_IS_BUF(left);
	if (right != NULL)
		SM_IS_BUF(right);

	ret = SM_SUCCESS;
	if (i < str->sm_str_len)
	{
		/* SM_ASSERT(str->sm_str_len > 0); */
		if (i > 0 && left != NULL)
		{
			ret = sm_str_catpart(left, (sm_rdstr_P) str, 0, i - 1);
			if (sm_is_err(ret))
				return ret;
		}
		if (right != NULL)
		{
			if (excl && i + 1 < str->sm_str_len)
			{
				ret = sm_str_catpart(right, (sm_rdstr_P) str,
						i + 1, str->sm_str_len - 1);
				if (sm_is_err(ret))
					return ret;
			}
			else if (!excl && i < str->sm_str_len)
			{
				ret = sm_str_catpart(right, (sm_rdstr_P) str, i,
						str->sm_str_len - 1);
				if (sm_is_err(ret))
					return ret;
			}
		}
	}
	return ret;
}

/*
**  SM_STR_SPLIT -- Split a string at a certain character
**
**	Parameters:
**		str -- sm_str_P object to modify.
**		delim -- character to use for splitting
**		excl -- exclude the character at i?
**		left -- left string
**		right -- right string
**
**	Returns:
**		0: nothing changed
**		>0: position of delimiter
**		<0: usual error code (doesn't happen)
*/

sm_ret_T
sm_str_split(sm_str_P str, uchar delim, bool excl, sm_str_P left, sm_str_P right)
{
	uint i;
	sm_ret_T ret;

	SM_IS_BUF(str);
	SM_REQUIRE(str->sm_str_base != NULL);
	if (left != NULL)
		SM_IS_BUF(left);
	if (right != NULL)
		SM_IS_BUF(right);

	ret = SM_SUCCESS;
	for (i = 0; i < str->sm_str_len; i++)
	{
		if (str->sm_str_base[i] == delim)
		{
			ret = sm_str_splitidx(str, i, excl, left, right);
			if (sm_is_err(ret))
				return ret;
			break;
		}
	}
	return i;
}


syntax highlighted by Code2HTML, v. 0.9.1