/*-
 * Copyright (c) 2001 Jordan DeLong
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#ifndef PLUGUTIL_H
#define PLUGUTIL_H

/* include golem headers */
#include "wm.h"

/*
 * some plugin helper macros, to promote cleaner plugin code,
 * particularly during loading of plugin params.
 */

/* warn a mesg to the user */
#define PWARN(frmt, args...) do {					\
	warnx("%s: " frmt, plugin_this->name , ## args);		\
} while (0)

/* warn a mesg and then return PLUGIN_UNLOAD */
#define PERR(frmt, args...) do {					\
	PWARN(frmt , ## args);						\
	return PLUGIN_UNLOAD;						\
} while (0)



/* debug trace for plugins */
#define PTRACE(frmt, args...) do {					\
	trace("%s " frmt, plugin_this->name , ## args);			\
} while (0)

/* load a requred param or die */
#define REQUIRED_PARAM(subparams, name, type, ret) do {			\
	if (plugin_##type##_param((subparams), (name), &(ret)) == -1)	\
		PERR("required parameter " name " wasn't provided");	\
} while (0)

/* load a required param or goto something (for freeage, see examples) */
#define REQUIRED_PARAMTO(subparams, name, type, ret, label) do {	\
	if (plugin_##type##_param((subparams), (name), &(ret)) == -1) {	\
		PWARN("required parameter " name " wasn't provided");	\
		goto label;						\
	}								\
} while (0)

/*
 * load an optional param, using defval as the default if the param
 * wasn't given by the user.  Users of this macro should be advised
 * that if they do a string param with a string defval, it wont need
 * to be freed, but if it was a val from the user it does need to be
 * freed.
 */
#define OPTIONAL_PARAM(subparams, name, type, ret, defval) do {		\
	if (plugin_##type##_param((subparams), (name), &(ret)) == -1)	\
		(ret) = (defval);					\
} while (0)

#if 1
#define SUBPARAMS_FOREACH( i, ret, subparams ) \
    (i) = -1; \
    if( (subparams)->count ) \
        while( (++(i) < (subparams)->count) \
               && ( ((ret) = (subparams)->params[(i)]) || (1) ) )
#else
/* loop through all of the params in a subparams */
#define SUBPARAMS_FOREACH(var, ret, subparams)				\
	if ((subparams)->count)						\
		for ((var) = 0, (ret) = (subparams)->params[0];		\
			(var) < (subparams)->count; (var)++,		\
			(ret) = (subparams)->params[(var)])
#endif

#endif
