/*
 *	cook - file construction tool
 *	Copyright (C) 1997, 1998 Peter Miller;
 *	All rights reserved.
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 *
 * MANIFEST: Canned Cookbook Functions
 *
 * This file presents users with some useful functions, defined in terms
 * of the built-in functions.  While useful, they also serve as examples
 * of how to write your own functions.
 *
 * See the ``Functions'' section of the Cook User Guide for more
 * information.  ([arg] and [@1] to [@9] are local variables.)
 */


/*
 * NAME
 *	capitalize
 *
 * SYNOPSIS
 *	[capitalize <word>...]
 *
 * DESCRIPTION
 *	The capitalize function maps all of its arguments into lower
 *	case, and then the first letter of each argument is mapped to
 *	upper case.  Zero, one or more arguments may be given.
 */

function capitalize =
{
	@1 = ;
	@2 = [downcase [arg]];
	loop
	{
		if [not [count [@2]]] then
			loopstop;
		@3 = [head [@2]];
		@2 = [tail [@2]];
		@1 = [@1] [upcase [substr 1 1 [@3]]][substr 2 9999 [@3]];
	}
	return [@1];
}


/*
 * NAME
 *	defined-or-null
 *
 * SYNOPSIS
 *	[defined-or-null <name> ]
 *
 * DESCRIPTION
 *	The defined-or-null function may be used to determine if a
 *	variable has been set (on the command line, for example) and
 *	return its value if so, otherwise return the empty list.
 *
 * ARGUMENTS
 *	This function should only be given one argument - the name of
 *	the variable to look for.  Additional arguments will be ignored.
 *	Too few arguments will produce a complaint about the "" variable
 *	being undefined.
 *
 * RETURNS
 *	The value of the named variable, or the empty list if the
 *	variable is not defined.
 */

function defined-or-null =
{
	if [defined [@1]] then
		return [[@1]];
	return;
}


/*
 * NAME
 *	defined-or-default
 *
 * SYNOPSIS
 *	[defined-or-default <name> <default-value>... ]
 *
 * DESCRIPTION
 *	The defined-or-default function may be used to determine if a
 *	variable has been set (on the command line, for example) and
 *	return its value if so, otherwise return the given default value.
 *
 * ARGUMENTS
 *	The first argument is the name of the variable to look for.
 *
 *	The second and later arguments (if present) are the default
 *	value to be used if the named variable is not defined.  Optional.
 *
 * RETURNS
 *	The value of the named variable, or the default list if the
 *	variable is not defined.
 */

function defined-or-default =
{
	if [defined [@1]] then
		return [[@1]];
	return [tail [arg]];
}


/*
 * NAME
 *	repeat
 *
 * SYNOPSIS
 *	[repeat <unary-function> <arguments>... ]
 *
 * DESCRIPTION
 *	The repeat function is used to repeatedly call another function,
 *	once for each of the specified arguments.  The can be useful
 *	when dealing with functions which do not automaticly accept
 *	argument lists in the form you require.
 *
 *	There are many instances where the repeat function call be used
 *	to elegantly avoid used to the ``loop { loopstop }'' construct.
 *
 * ARGUMENTS
 *	The first argument is the name of the function you want called.
 *	This function must accept a single argument.
 *
 *	The second and subsequent arguments are argument values to be
 *	passed to the named function, one at a time.
 *
 * RETURNS
 *	The results of the invocations of the function are accumulated
 *	in the order in which they were calculated.  The accumulated
 *	results are returned.
 */

function repeat =
{
	@2 = ;
	@3 = [tail [arg]];
	loop
	{
		if [not [count [@3]]] then
			loopstop;
		@4 = [head [@3]];
		@3 = [tail [@3]];
		/* run the named function on this argument */
		@2 = [@2] [[@1] [@4]];
	}
	return [@2];
}
