
/* @(#)UserFunc.c	2.1.2.1 95/05/11 */

#define	numfuncs	5
#include "WZTools.h"

extern void	InitFunc(), Factorial(), MultOrCat(),
	AddCat3(), MyIncr(), AddCat5(), ExitFunc();

/* set up structure */
void (*initfunc)() = InitFunc;

ROUT	rout = {
	numfuncs, ExitFunc,
	{
		{ Factorial, "\004Fact", 1 },
		{ MultOrCat, "\011MultOrCat", 2 },
		{ AddCat3, "\007AddCat3", 3 },
		{ MyIncr, "\006MyIncr", 1 },
		{ AddCat5, "\007AddCat5", 5 },
	}
};

void
InitFunc(pret, parg)
PVAL	pret, parg;
{
}

void
Factorial(pret, parg)
PVAL	pret, parg;
{
	int	ii;

	if (parg[0].flag == NUMERIC && parg[0].val.numeric >= 0) {
		pret->flag = NUMERIC;
		for (pret->val.numeric = 1, ii = parg[0].val.numeric; ii; --ii) {
			pret->val.numeric *= ii;
		}
		return;
	} else {
		pret->flag = ERR;
		pret->val.err = 12;
		return;
	}
}


void
MultOrCat(pret, parg)
PVAL	pret, parg;
{
	int	ii = 0,		/* Index Variable */
		n;		/* String Length */

	char	CStrng[256],	/* 'C' String */
		Result[257];

	if (parg[0].flag == STRING && parg[1].flag == STRING) {
		pret->flag = STRING;
		Result[1] = '\0';
		for (ii = 0; ii < rout.relts[1].narg; ++ii) {
                	n = parg[ii].val.string[0]; 
	       		strncpy (CStrng, &parg[ii].val.string[1], n);
       			CStrng[n] = '\0';
			strcat (&Result[1], CStrng);
		}
		Result[0] = strlen (&Result[1]);
                pret->val.string = Result;
		return;

	} else if (parg[0].flag == NUMERIC && parg[1].flag == NUMERIC) {
		pret->flag = NUMERIC;
		pret->val.numeric = parg[0].val.numeric * parg[1].val.numeric;
		return;

	} else {	/* Bad Arguments */
		pret->flag  = ERR;
		pret->val.err = 12;

	}
}

void
AddCat3(pret, parg)
PVAL	pret, parg;
{
	int	ii = 0,
		n;		/* String Length */

	char	CStrng[256],	/* 'C' String */
		Result[257];

	if (parg[0].flag == STRING) {
		if (parg[1].flag != STRING ||
				parg[2].flag != STRING) {
			pret->flag  = ERR;
			pret->val.err = 12;	/* bad argument */
			return;

		}
	} else if (parg[0].flag == NUMERIC) {
		if (parg[1].flag != NUMERIC ||
			parg[2].flag != NUMERIC) {
				pret->flag  = ERR;
				pret->val.err = 12;	/* bad argument */
			return;

		}
	}

	if (parg[0].flag == STRING) {
		pret->flag = STRING;
		Result[1] = '\0';
		for (ii = 0; ii < rout.relts[2].narg; ++ii) {
                	n = parg[ii].val.string[0]; 
	       		strncpy (CStrng, &parg[ii].val.string[1], n);
       			CStrng[n] = '\0';
			strcat (&Result[1], CStrng);
		}
		Result[0] = strlen (&Result[1]);
		pret->val.string = Result;
		return;
	} else {
		pret->flag = NUMERIC;
		pret->val.numeric = 0;
		for (ii = 0; ii < rout.relts[2].narg; ++ii) {
			pret->val.numeric += parg[ii].val.numeric;
		}
		return;
	}
}


void
MyIncr(pret, parg)
PVAL	pret, parg;
{
	if (parg[0].flag == NUMERIC) {
		pret->flag = NUMERIC;
		pret->val.numeric = parg[0].val.numeric + 1;
		return;
	} else {
		pret->flag = ERR;
		pret->val.err = 12;
		return;
	}
}


void
AddCat5(pret, parg)
PVAL	pret, parg;
{
	int	ii = 0,
		n;		/* String Length */

	char	CStrng[256],	/* 'C' String */
		Result[257];

	if (parg[0].flag == STRING) {
		if (parg[1].flag != STRING ||
				parg[2].flag != STRING ||
				parg[3].flag != STRING ||
				parg[4].flag != STRING) {
			pret->flag  = ERR;
			pret->val.err = 12;							/* bad argument */
			return;
		}
	} else if (parg[0].flag == NUMERIC) {
		if (parg[1].flag != NUMERIC ||
				parg[2].flag != NUMERIC ||
				parg[3].flag != NUMERIC ||
				parg[4].flag != NUMERIC) {
			pret->flag  = ERR;
			pret->val.err = 12;							/* bad argument */
			return;
		}
	}

	if (parg[0].flag == STRING) {
		pret->flag = STRING;
		Result[1] = '\0';
		for (ii = 0; ii < rout.relts[4].narg; ++ii) {
                	n = parg[ii].val.string[0]; 
	       		strncpy (CStrng, &parg[ii].val.string[1], n);
       			CStrng[n] = '\0';
			strcat (&Result[1], CStrng);
		}
		Result[0] = strlen (&Result[1]);
		pret->val.string = Result;
		return;
	} else {
		pret->flag = NUMERIC;
		pret->val.numeric = 0;
		for (ii = 0; ii < rout.relts[4].narg; ++ii) {
			pret->val.numeric += parg[ii].val.numeric;
		}
		return;
	}
}

void
ExitFunc(pret, parg)
PVAL	pret, parg;
{
}
