/*
 * 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: mapc.c,v 1.12 2006/05/27 05:22:45 ca Exp $")

#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/heap.h"
#include "sm/cstr.h"
#include "sm/map-str.h"
#include "sm/mapc.h"
#include "sm/maps.h"

#if SM_MAP_CHECK
# define sm_mapc_setmagic(mapc)	(mapc)->sm_magic = SM_MAPC_MAGIC
#else /* SM_MAP_CHECK */
# define sm_mapc_setmagic(mapc)
#endif /* SM_MAP_CHECK */

#define SM_MAPC_DEF(type, flags, create, open, close, reopen, destroy, add, rm, alloc, free, lookup, locate, first, next, setopt, getopt) \
	do							\
	{							\
		mapc = (sm_mapc_P) sm_zalloc(sizeof(*mapc));	\
		if (mapc == NULL)				\
			break;					\
		mapc->sm_mapc_type = SM_CSTR_DUP(type);		\
		mapc->sm_mapc_flags = (flags);			\
		mapc->sm_mapc_createf = (create);		\
		mapc->sm_mapc_openf = (open);			\
		mapc->sm_mapc_closef = (close);			\
		mapc->sm_mapc_reopenf = (reopen);		\
		mapc->sm_mapc_destroyf = (destroy);		\
		mapc->sm_mapc_addf = (add);			\
		mapc->sm_mapc_rmf = (rm);			\
		mapc->sm_mapc_allocf = (alloc);			\
		mapc->sm_mapc_freef = (free);			\
		mapc->sm_mapc_lookupf = (lookup);		\
		mapc->sm_mapc_locatef = (locate);		\
		mapc->sm_mapc_firstf = (first);			\
		mapc->sm_mapc_nextf = (next);			\
		mapc->sm_mapc_setoptf = (setopt);		\
		mapc->sm_mapc_getoptf = (getopt);		\
		sm_mapc_setmagic(mapc);				\
	} while (0)

/*
**  MAPC_CREATE -- create/enter map class
**
**	Parameters:
**		maps -- map system context
**		... -- entries for mapc creation
**		pmapc -- (pointer to) map class context (output)
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_mapc_create(sm_maps_P maps,
	sm_cstr_P	 mapc_type,
	uint32_t	 mapc_flags,
	sm_map_create_F	 mapc_createf,
	sm_map_open_F	 mapc_openf,
	sm_map_close_F	 mapc_closef,
	sm_map_reopen_F	 mapc_reopenf,
	sm_map_destroy_F mapc_destroyf,
	sm_map_add_F	 mapc_addf,
	sm_map_rm_F	 mapc_rmf,
	sm_map_alloc_F	 mapc_allocf,
	sm_map_free_F	 mapc_freef,
	sm_map_lookup_F	 mapc_lookupf,
	sm_map_locate_F	 mapc_locatef,
	sm_map_first_F	 mapc_firstf,
	sm_map_next_F	 mapc_nextf,
	sm_map_setopt_F	 map_setoptf,
	sm_map_getopt_F	 map_getoptf,
	sm_mapc_P	 *pmapc)
{
	sm_ret_T ret;
	sm_mapc_P mapc;

	SM_IS_MAPS(maps);
	SM_REQUIRE(pmapc != NULL);
	ret = SM_SUCCESS;

	/* XXX add some requirements, e.g., open()/lookup() must exist? */
	SM_MAPC_DEF(mapc_type, mapc_flags, mapc_createf, mapc_openf
		, mapc_closef, mapc_reopenf, mapc_destroyf
		, mapc_addf, mapc_rmf
		, mapc_allocf, mapc_freef, mapc_lookupf, mapc_locatef
		, mapc_firstf, mapc_nextf, map_setoptf, map_getoptf);

	if (mapc == NULL)
		goto error;
	if (mapc_addf != NULL)
		mapc->sm_mapc_flags |= SMMAPC_FL_ADD;
	if (mapc_rmf != NULL)
		mapc->sm_mapc_flags |= SMMAPC_FL_RM;
	if (mapc_lookupf != NULL)
		mapc->sm_mapc_flags |= SMMAPC_FL_LOOKUP;
	ret = sm_maps_add(maps, mapc);
	if (sm_is_err(ret))
		goto error;
	mapc->sm_mapc_maps = maps;
	*pmapc = mapc;
	return ret;

  error:
	if (ret == SM_SUCCESS)
		ret = sm_error_temp(SM_EM_MAP, ENOMEM);
	/* cleanup mapc? */
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1