/*
 * Copyright (c) 1995-2002 Silicon Graphics, Inc.  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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * fun.c
 *
 * These functions are generated from skeletons <file>.sk
 * by the shell-script './meta'.
 ***********************************************************************/

#include "pmapi.h"
#if defined(HAVE_SYS_WAIT_H)
#include <sys/wait.h>
#endif
#include "dstruct.h"
#include "pragmatics.h"
#include "fun.h"
#include "show.h"
#include "stomp.h"


/*
 * Copyright (c) 2015,2017 Red Hat.
 * 
 * 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.
 */

/***********************************************************************
 * skeleton: fetch.sk - fetch metric values
 ***********************************************************************/

/*
 *  operator: cndFetch
 */

static int
indom_changed(Metric *m)
{
    int		changed = 0;
    int		j;

    /* check for changes in the instance domain */
    if (m->vset == NULL || m->vset->numval <= 0) {
	if (m->m_idom > 0)
	    changed = 1;
    }
    else {
	if (m->vset->numval != m->m_idom)
	    changed = 1;
	else {
	    for (j = 0; j < m->m_idom; j++) {
		if (m->iids[j] != m->vset->vlist[j].inst) {
		    changed = 1;
		    break;
		}
	    }
	}
    }

    if (changed) {
	int		old;
	int		new;
	int		numval;
	char		**inames;
	int		*iids;
	int		sts;
	int		handle = -1;
	int		old_handle = -1;
	char		**get_inames;
	int		*get_iids;
	int		numinst = -1;

	if (m->vset == NULL || m->vset->numval <= 0)
	    numval = 0;
	else
	    numval = m->vset->numval;

	/* build new inames[] and iids[] */
	if (numval > 0) {
	    inames = (char **)alloc(numval * sizeof(char *));
	    iids = (int *)alloc(numval * sizeof(int));
	    if (numval > m->m_idom && m->desc.sem == PM_SEM_COUNTER) {
		/* more instances, so expand the val array */
		m->vals = (double *)ralloc(m->vals, numval * sizeof(double));
		for (j = m->m_idom; j < numval; j++)
		    m->vals[j] = 0;
	    }
	}
	else {
	    inames = NULL;
	    iids = NULL;
	}

	for (new = 0; new < numval; new++) {
	    for (old = 0; old < m->m_idom; old++) {
		if (m->iids[old] == m->vset->vlist[new].inst)
		    break;
	    }
	    if (old < m->m_idom) {
		/* in both lists */
		inames[new] = m->inames[old];
		m->inames[old] = NULL;
		iids[new] = m->iids[old];
		if (m->desc.sem == PM_SEM_COUNTER && new != old) {
		    /* swap vals[] */
		    double	d;
		    d = m->vals[new];
		    m->vals[new] = m->vals[old];
		    m->vals[old] = d;
		}
	    }
	    else {
		/* new one */
		inames[new] = NULL;
		iids[new] = m->vset->vlist[new].inst;
	    }
	}

	/*
	 * clean up old inames and iids, the install new ones
	 */
	if (m->m_idom > 0 && m->inames != NULL) {
	    for (old = 0; old < m->m_idom; old++) {
		if (m->inames[old] != NULL) free(m->inames[old]);
	    }
	}
	if (m->inames != NULL)
	    free(m->inames);
	if (m->iids != NULL)
	    free(m->iids);
	m->inames = inames;
	m->iids = iids;
	m->m_idom = numval;

	for (new = 0; new < m->m_idom; new++) {
	    if (m->inames[new] == NULL) {
		if (handle < 0) {
		    /* set up temporary context */
		    if (old_handle < 0)
			old_handle = pmWhichContext();
		    handle = newContext(&m->hname, symName(m->hconn), 0);
		}
		if (handle < 0) {
		    sts = -1;
		}
		else {
		    if (archives) {
			if ((sts = pmNameInDomArchive(m->desc.indom, m->iids[new], &m->inames[new])) < 0) {
			    pmNotifyErr(LOG_ERR, "metric %s from %s: instance domain not "
				"available in archive\npmNameInDomArchive failed: %s\n",
				symName(m->mname), findsource(symName(m->hname),symName(m->hconn)), pmErrStr(sts));
			}
		    }
		    else {
			if (numinst == -1) {
			    if ((sts = pmGetInDom(m->desc.indom, &get_iids, &get_inames)) < 0) {
				pmNotifyErr(LOG_ERR, "metric %s from %s: instance domain not (currently) available\n"
				    "pmGetInDom failed: %s\n",
				    symName(m->mname), findsource(symName(m->hname),symName(m->hconn)), pmErrStr(sts));
			    }
			    else
				numinst = sts;
			}
			sts = -1;
			for (j = 0; j < numinst; j++) {
			    if (m->iids[new] == get_iids[j]) {
				m->inames[new] = sdup(get_inames[j]);
				sts = 0;
				break;
			    }
			}
		    }
		}
		if (sts < 0) {
		    /* ugly, but not much choice */
		    m->inames[new] = sdup("inst#xxxxxxxxxxxx?");
		    pmsprintf(m->inames[new], 19, "inst#%d?", m->iids[new]);
		}

		if (m->desc.sem == PM_SEM_COUNTER)
		    m->vals[new] = 0;
	    }
	}
	if (handle >= 0) {
	    pmDestroyContext(handle);
	    if (old_handle >= 0)
		pmUseContext(old_handle);
	}
	if (numinst > 0) {
	    /* pmGetInDom returned some instances above */
	    free(get_iids);
	    free(get_inames);
	}
	if (pmDebugOptions.appl2) {
	    fprintf(stderr, "indom_changed: %s from %s\n",
		    symName(m->mname), symName(m->hname));
	    if (m->m_idom < 1) fprintf(stderr, "  %d instances!\n", m->m_idom);
	    for (j = 0; j < m->m_idom; j++) {
		fprintf(stderr, "  indom[%d] %d \"%s\"\n",
			j, m->iids[j], m->inames[j]);
	    }
	}
    }

    return changed;
}

/* null instance domain - so 1 instance only */
void
cndFetch_1(Expr *x)
{
    Metric	*m = x->metrics;
    double	*op;
    char	**op_s;
    RealTime	stamp = 0;
    pmAtomValue	a;
    double	t;
    int		i, j;
    int		dorate = 0;

    ROTATE(x)
    x->valid++;
    op = (double *)x->smpls[0].ptr;
    op_s = (char **)x->smpls[0].ptr;

    if (m->desc.sem == PM_SEM_COUNTER) {
	/* need rate conversion, unless some parent node is CND_INSTANT */
	Expr	*p = x->parent;
	dorate = 1;
	while (p != NULL) {
	    if (p->op == CND_INSTANT) {
		dorate = 0;
		break;
	    }
	    p = p->parent;
	}
    }

    for (i = 0; i < x->hdom; i++) {
	/* extract value */
	if (m->vset && m->vset->numval == 1) {
	    if (m->desc.type == PM_TYPE_STRING) {
		if (*op_s != NULL)
		    free(*op_s);
		*op_s = strdup(m->vset->vlist[0].value.pval->vbuf);
		if (pmDebugOptions.appl2) {
		    fprintf(stderr, "cndFetch_1(" PRINTF_P_PFX "%p): %s from %s = \"%s\" (" PRINTF_P_PFX "%p)\n",
			    x, symName(m->mname), symName(m->hname), *op_s, *op_s);
		}
		op_s++;
	    }
	    else {
		pmExtractValue(m->vset->valfmt, &m->vset->vlist[0], m->desc.type, &a, PM_TYPE_DOUBLE);
		*op = m->conv * a.d;
		if (pmDebugOptions.appl2) {
		    fprintf(stderr, "cndFetch_1(" PRINTF_P_PFX "%p): %s from %s = %g",
			    x, symName(m->mname), symName(m->hname), *op);
		    if (m->conv != 1) fprintf(stderr, " (unconv = %g)", a.d);
		    fputc('\n', stderr);
		}
		op++;
	    }
	}
	else {
	    /* no value */
	    x->valid = 0;
	    for (j = i; j < x->hdom; j++) {
		m->stomp = 0;
		m->vset = NULL;
		m++;
	    }
	    return;
	}
	m->vset = NULL;

	/*
	 * rate computation ... only relevant for numeric values, 
	 * so op was updated above and op_s was not used above
	 */
	if (dorate) {
	    op--;
	    if (m->m_idom > 0) {
		t = *op - m->vals[0];
		if (t < 0.0 && dowrap) {
		    switch (m->desc.type) {
			case PM_TYPE_32:
			case PM_TYPE_U32:
			    t += (double)UINT_MAX+1;
			    break;
			case PM_TYPE_64:
			case PM_TYPE_U64:
			    t += (double)ULONGLONG_MAX+1;
			    break;
		    }
		}
		t /= (m->stamp - m->stomp);
		m->vals[0] = *op;
		if (t < 0.0) x->valid = 0;
		else *op = t;
		op++;
	    }
	    if (m->stomp == 0) x->valid = 0;
	    m->stomp = m->stamp;
	}

	/* pick up most recent timestamp */
	if (m->stamp > stamp) stamp = m->stamp;

	m++;
    }
    x->smpls[0].stamp = stamp;
}

void
cndFetch_all(Expr *x)
{
    Metric	*m = x->metrics;
    double	*op;
    char	**op_s;
    RealTime	stamp = 0;
    pmAtomValue	a;
    double	t;
    int		fix_idom = 0;
    int		i, j;
    int		dorate = 0;

    ROTATE(x)

    /* preliminary scan through Metrics */
    for (i = 0; i < x->hdom; i++) {
	/* check for different instances */
	if (indom_changed(m)) {
	    fix_idom = 1;
	    m->stomp = 0;
	}
	m++;
    }

    if (fix_idom) {
	/*
	 * propagate indom changes up the expression tree
	 * and reshape the ring buffer if required
	 */
	instFetchExpr(x);
    }

    /*
     * even if ring buffer reshaped in instFetchExpr(), we're
     * about to populate it with another set of values, so bump
     * valid counter
     */
    x->valid++;

    m = x->metrics;

    if (m->desc.sem == PM_SEM_COUNTER) {
	/* need rate conversion, unless some parent node is CND_INSTANT */
	Expr	*p = x->parent;
	dorate = 1;
	while (p != NULL) {
	    if (p->op == CND_INSTANT) {
		dorate = 0;
		break;
	    }
	    p = p->parent;
	}
    }

    /* extract values */
    op = (double *)x->smpls[0].ptr;
    op_s = (char **)x->smpls[0].ptr;

    for (i = 0; i < x->hdom; i++) {

	/* extract values from m->vset */
	for (j = 0; j < m->m_idom; j++) {
	    if (m->desc.type == PM_TYPE_STRING) {
		if (*op_s != NULL)
		    free(*op_s);
		*op_s = strdup(m->vset->vlist[j].value.pval->vbuf);
		if (pmDebugOptions.appl2) {
		    fprintf(stderr, "cndFetch_all(" PRINTF_P_PFX "%p): %s[%s] from %s = \"%s\" (" PRINTF_P_PFX "%p)\n",
			    x, symName(m->mname), m->inames[j], symName(m->hname), *op_s, *op_s);
		}
		op_s++;
	    }
	    else {
		pmExtractValue(m->vset->valfmt, &m->vset->vlist[j], m->desc.type, &a, PM_TYPE_DOUBLE);
		*op = m->conv * a.d;
		if (pmDebugOptions.appl2) {
		    fprintf(stderr, "cndFetch_all(" PRINTF_P_PFX "%p): %s[%s] from %s = %g",
			    x, symName(m->mname), m->inames[j], symName(m->hname), *op);
		    if (m->conv != 1) fprintf(stderr, " (unconv = %g)", a.d);
		    fputc('\n', stderr);
		}
		op++;
	    }
	}
	m->vset = NULL;

	/*
	 * rate computation ... only relevant for numeric values, 
	 * so op was updated above and op_s was not used above
	 */
	if (dorate) {
	    op -= m->m_idom;
	    for (j = 0; j < m->m_idom; j++) {
		t = *op - m->vals[j];
		if (t < 0.0 && dowrap) {
		    switch (m->desc.type) {
			case PM_TYPE_32:
			case PM_TYPE_U32:
			    t += (double)UINT_MAX+1;
			    break;
			case PM_TYPE_64:
			case PM_TYPE_U64:
			    t += (double)ULONGLONG_MAX+1;
			    break;
		    }
		}
		t /= (m->stamp - m->stomp);
		m->vals[j] = *op;
		if (t < 0.0) x->valid = 0;
		else *op = t;
		op++;
	    }
	    if (m->stomp == 0) x->valid = 0;
	    m->stomp = m->stamp;
	}

	/* pick up most recent timestamp */
	if (m->stamp > stamp) stamp = m->stamp;

	m++;
    }
    x->smpls[0].stamp = stamp;
}

void
cndFetch_n(Expr *x)
{
    Metric	*m = x->metrics;
    double	*op;
    char	**op_s;
    RealTime	stamp = 0;
    pmAtomValue	a;
    double	t;
    int		i, j, k;
    int		dorate = 0;

    ROTATE(x)
    x->valid++;
    op = (double *)x->smpls[0].ptr;
    op_s = (char **)x->smpls[0].ptr;

    if (m->desc.sem == PM_SEM_COUNTER) {
	/* need rate conversion, unless some parent node is CND_INSTANT */
	Expr	*p = x->parent;
	dorate = 1;
	while (p != NULL) {
	    if (p->op == CND_INSTANT) {
		dorate = 0;
		break;
	    }
	    p = p->parent;
	}
    }

    for (i = 0; i < x->hdom; i++) {
	/* no values */
	if ((m->vset == NULL) || (m->vset->numval < 0)) {
	    x->valid = 0;
	    for (j = i; j < x->hdom; j++) {
		m->stomp = 0;
		m->vset = NULL;
		m++;
	    }
	    return;
	}

	/* extract values */
	for (j = 0; j < m->m_idom; j++) {
	    for (k = 0; k < m->vset->numval; k++) {
		if (m->iids[j] == m->vset->vlist[k].inst) {
		    if (m->desc.type == PM_TYPE_STRING) {
			if (*op_s != NULL)
			    free(*op_s);
			*op_s = strdup(m->vset->vlist[k].value.pval->vbuf);
			if (pmDebugOptions.appl2) {
			    fprintf(stderr, "cndFetch_n(" PRINTF_P_PFX "%p): %s[%s] from %s = \"%s\" (" PRINTF_P_PFX "%p)\n",
				    x, symName(m->mname), m->inames[j], symName(m->hname), *op_s, *op_s);
			}
			op_s++;
		    }
		    else {
			pmExtractValue(m->vset->valfmt, &m->vset->vlist[k], m->desc.type, &a, PM_TYPE_DOUBLE);
			*op = m->conv * a.d;
			if (pmDebugOptions.appl2) {
			    fprintf(stderr, "cndFetch_n(" PRINTF_P_PFX "%p): %s[%s] from %s = %g",
				    x, symName(m->mname), m->inames[j], symName(m->hname), *op);
			    if (m->conv != 1) fprintf(stderr, " (unconv = %g)", a.d);
			    fputc('\n', stderr);
			}
			op++;
		    }
		    break;
		}
	    }

	    /* missing value */
	    if (k == m->vset->numval) {
		x->valid = 0;
		m->stomp = 0;
		m->vset = NULL;
		return;
	    }
	}
	m->vset = NULL;

	/*
	 * rate computation ... only relevant for numeric values, 
	 * so op was updated above and op_s was not used above
	 */
	if (dorate) {
	    op -= m->m_idom;
	    for (j = 0; j < m->m_idom; j++) {
		t = *op - m->vals[j];
		if (t < 0.0 && dowrap) {
		    switch (m->desc.type) {
			case PM_TYPE_32:
			case PM_TYPE_U32:
			    t += (double)UINT_MAX+1;
			    break;
			case PM_TYPE_64:
			case PM_TYPE_U64:
			    t += (double)ULONGLONG_MAX+1;
			    break;
		    }
		}
		t /= (m->stamp - m->stomp);
		m->vals[j] = *op;
		if (t < 0.0) x->valid = 0;
		else *op = t;
		op++;
	    }
	    if (m->stomp == 0) x->valid = 0;
	    m->stomp = m->stamp;
	}

	/* pick up most recent timestamp */
	if (m->stamp > stamp) stamp = m->stamp;

	m++;
    }
    x->smpls[0].stamp = stamp;
}


/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: misc.sk
 ***********************************************************************/

#include <assert.h>

/*
 * operator RULE
 */

void
rule(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    int		sts;

    EVALARG(arg1)
    if ((x->valid = arg1->valid) > 0) {
	sts = (*(Boolean *)x->ring = *(Boolean *)arg1->ring);
	if (sts == B_FALSE)
	    perf->eval_false++;
	else if (sts == B_TRUE) {
	    perf->eval_true++;
	    EVALARG(arg2)
	}
	else
	    perf->eval_unknown++;
    }
    else
	perf->eval_unknown++;
}

/*
 * operator CND_RULESET
 */

void
ruleset(Expr *x)
{
    Expr 	*op;		/* operator nodes */
    Expr	*rp;		/* rule or action nodes */
    Expr	*save_curr;	/* save-restore curr when calling rule() */
    Expr	*other;		/* UNKNOWN/OTHERWISE clauses */
    int		all_unknown = 1;

    x->valid = 0;
    op = x->arg1;
    while (op != NULL) {
	if (op->op == RULE)
	    rp = op;
	else {
	    assert(op->op == CND_RULESET || op->op == CND_OR);
	    rp = op->arg1;
	}
	assert(rp->op == RULE);
	save_curr = curr;
	curr = rp;
	rule(rp);
	curr = save_curr;
	if (rp->arg1->valid) {
	    x->valid = rp->arg1->valid;
	    *(Boolean *)x->ring = *(Boolean *)rp->arg1->ring;
	    if (x->valid > 0 && *(Boolean *)x->ring == B_TRUE) {
		/* predicate is true, so stop evaluation */
		return;
	    }
	    if (x->valid > 0 && *(Boolean *)x->ring == B_FALSE) {
		/* predicate is false, so don't do UNKNOWN clause */
		all_unknown = 0;
	    }
	}
	if (op->op == RULE)
	    break;
	op = op->arg2;
    }

    if (x->arg2 == NULL)
	/* no OTHERWISE or UNKNOWN clauses */
	return;

    other = x->arg2;
    assert(other->op == CND_OTHER);

    if (all_unknown) {
	/*
	 * all predicates are B_UNKNOWN, so do the UNKNOWN action if any
	 */
	if (other->arg1->op != NOP) {
	    rp = other->arg1;
	    save_curr = curr;
	    curr = rp;
	    rule(rp);
	    curr = save_curr;
	    return;
	}
    }

    /*
     * no predicate is B_TRUE and either some predicate is B_FALSE
     * or they are all B_UNKNOWN and there is no UNKNOWN action ...
     * so do the OTHERWISE action, if any
     */
    if (other->arg2->op != NOP) {
	rp = other->arg2;
	save_curr = curr;
	curr = rp;
	rule(rp);
	save_curr = curr;
	x->valid = rp->arg1->valid;
	*(Boolean *)x->ring = *(Boolean *)rp->arg1->ring;
    }
}

/*
 *  operator: cndDelay
 */

void
cndDelay_n(Expr *x)
{
    Expr	*arg1 = x->arg1;
    int		n = arg1->tdom;
    Sample	*is = &arg1->smpls[n - 1];
    Sample	*os = &x->smpls[0];
    int         i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0) {
	if (arg1->metrics != NULL && arg1->metrics->desc.type == PM_TYPE_STRING) {
	    /* string values */
	    char	**iv = (char **)is->ptr;
	    char	**ov = (char **)os->ptr;
	    for (i = 0; i < x->tspan; i++) {
		if (*ov != NULL)
		    free(*ov);
		*ov++ = strdup(*iv++);
	    }
	}
	else {
	    /* numeric values */
	    double	*ip;
	    double	*op;
	    ip = (double *)is->ptr;
	    op = (double *)os->ptr;
	    for (i = 0; i < x->tspan; i++)
		*op++ = *ip++;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else x->valid = 0;
}

void
cndDelay_1(Expr *x)
{
    Expr	*arg1 = x->arg1;
    int		n = arg1->tdom;
    Sample	*is = &arg1->smpls[n - 1];
    Sample	*os = &x->smpls[0];

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n) {
	if (arg1->metrics != NULL && arg1->metrics->desc.type == PM_TYPE_STRING) {
	    /* string values */
	    char	**iv = (char **)is->ptr;
	    char	**ov = (char **)os->ptr;
	    if (*ov != NULL)
		free(*ov);
	    *ov = strdup(*iv);
	}
	else {
	    /* numeric values */
	    *(double *)os->ptr = *(double *)is->ptr;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else x->valid = 0;
}


/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: aggregate.sk - aggregation and quantification
 ***********************************************************************/

/***********************************************************************
 * operator: cndSum
 ***********************************************************************/

void
cndSum_host(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double      *ip;
    double      *op;
    double	a;
    int		n;
    int		i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && arg1->hdom > 0) {
	ip = (double *)is->ptr;
	op = (double *)os->ptr;
	n = arg1->hdom;
	a = *ip;
	for (i = 1; i < n; i++) {
	    ip++;
	    a += *ip;
	}
	*op++ = a;
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSum_host(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndSum_inst(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double      *ip;
    double      *op;
    double	a;
    Metric	*m;
    int		n;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->hdom != 0) {
	ip = (double *)is->ptr;
	op = (double *)os->ptr;
	if (abs(x->hdom) == 1) {
	    n = arg1->e_idom;
	    if (n < 1) {
		x->valid = 0;
		goto done;
	    }
	    a = *ip;
	    for (i = 1; i < n; i++) {
		ip++;
		a += *ip;
	    }
	    *op++ = a;
	}
	else {
	    m = x->metrics;
	    for (i = 0; i < x->hdom; i++) {
		n = m->m_idom;
		if (n < 1) {
		    x->valid = 0;
		    goto done;
		}
		a = *ip;
		for (j = 1; j < n; j++){
		    /* Note! no break allowed in this loop */
		    ip++;
		    a += *ip;
		}
		*op++ = a;
		m++;
	    }
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

done:
    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSum_inst(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndSum_time(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ring = (double *)arg1->ring;
    double      *ip;
    double      *op;
    double	a;
    int		n = arg1->tdom;
    int		tspan;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0 && arg1->tdom > 0) {
	op = (double *)os->ptr;
	tspan = x->tspan;
	for (i = 0; i < tspan; i++) {
	    ip = ring + i;
	    a = *ip;
	    for (j = 1; j < n; j++){
		ip += tspan;
		a += *ip;
	    }
	    *op++ = a;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSum_time(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: aggregate.sk - aggregation and quantification
 ***********************************************************************/

/***********************************************************************
 * operator: cndAvg
 ***********************************************************************/

void
cndAvg_host(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double      *ip;
    double      *op;
    double	a;
    int		n;
    int		i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && arg1->hdom > 0) {
	ip = (double *)is->ptr;
	op = (double *)os->ptr;
	n = arg1->hdom;
	a = *ip;
	for (i = 1; i < n; i++) {
	    ip++;
	    a += *ip;
	}
	*op++ = a / n;
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAvg_host(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndAvg_inst(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double      *ip;
    double      *op;
    double	a;
    Metric	*m;
    int		n;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->hdom != 0) {
	ip = (double *)is->ptr;
	op = (double *)os->ptr;
	if (abs(x->hdom) == 1) {
	    n = arg1->e_idom;
	    if (n < 1) {
		x->valid = 0;
		goto done;
	    }
	    a = *ip;
	    for (i = 1; i < n; i++) {
		ip++;
		a += *ip;
	    }
	    *op++ = a / n;
	}
	else {
	    m = x->metrics;
	    for (i = 0; i < x->hdom; i++) {
		n = m->m_idom;
		if (n < 1) {
		    x->valid = 0;
		    goto done;
		}
		a = *ip;
		for (j = 1; j < n; j++){
		    /* Note! no break allowed in this loop */
		    ip++;
		    a += *ip;
		}
		*op++ = a / n;
		m++;
	    }
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

done:
    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAvg_inst(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndAvg_time(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ring = (double *)arg1->ring;
    double      *ip;
    double      *op;
    double	a;
    int		n = arg1->tdom;
    int		tspan;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0 && arg1->tdom > 0) {
	op = (double *)os->ptr;
	tspan = x->tspan;
	for (i = 0; i < tspan; i++) {
	    ip = ring + i;
	    a = *ip;
	    for (j = 1; j < n; j++){
		ip += tspan;
		a += *ip;
	    }
	    *op++ = a / n;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAvg_time(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: aggregate.sk - aggregation and quantification
 ***********************************************************************/

/***********************************************************************
 * operator: cndMax
 ***********************************************************************/

void
cndMax_host(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double      *ip;
    double      *op;
    double	a;
    int		n;
    int		i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && arg1->hdom > 0) {
	ip = (double *)is->ptr;
	op = (double *)os->ptr;
	n = arg1->hdom;
	a = *ip;
	for (i = 1; i < n; i++) {
	    ip++;
	    if (*ip > a) a = *ip;
	}
	*op++ = a;
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMax_host(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndMax_inst(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double      *ip;
    double      *op;
    double	a;
    Metric	*m;
    int		n;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->hdom != 0) {
	ip = (double *)is->ptr;
	op = (double *)os->ptr;
	if (abs(x->hdom) == 1) {
	    n = arg1->e_idom;
	    if (n < 1) {
		x->valid = 0;
		goto done;
	    }
	    a = *ip;
	    for (i = 1; i < n; i++) {
		ip++;
		if (*ip > a) a = *ip;
	    }
	    *op++ = a;
	}
	else {
	    m = x->metrics;
	    for (i = 0; i < x->hdom; i++) {
		n = m->m_idom;
		if (n < 1) {
		    x->valid = 0;
		    goto done;
		}
		a = *ip;
		for (j = 1; j < n; j++){
		    /* Note! no break allowed in this loop */
		    ip++;
		    if (*ip > a) a = *ip;
		}
		*op++ = a;
		m++;
	    }
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

done:
    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMax_inst(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndMax_time(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ring = (double *)arg1->ring;
    double      *ip;
    double      *op;
    double	a;
    int		n = arg1->tdom;
    int		tspan;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0 && arg1->tdom > 0) {
	op = (double *)os->ptr;
	tspan = x->tspan;
	for (i = 0; i < tspan; i++) {
	    ip = ring + i;
	    a = *ip;
	    for (j = 1; j < n; j++){
		ip += tspan;
		if (*ip > a) a = *ip;
	    }
	    *op++ = a;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMax_time(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: aggregate.sk - aggregation and quantification
 ***********************************************************************/

/***********************************************************************
 * operator: cndMin
 ***********************************************************************/

void
cndMin_host(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double      *ip;
    double      *op;
    double	a;
    int		n;
    int		i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && arg1->hdom > 0) {
	ip = (double *)is->ptr;
	op = (double *)os->ptr;
	n = arg1->hdom;
	a = *ip;
	for (i = 1; i < n; i++) {
	    ip++;
	    if (*ip < a) a = *ip;
	}
	*op++ = a;
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMin_host(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndMin_inst(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double      *ip;
    double      *op;
    double	a;
    Metric	*m;
    int		n;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->hdom != 0) {
	ip = (double *)is->ptr;
	op = (double *)os->ptr;
	if (abs(x->hdom) == 1) {
	    n = arg1->e_idom;
	    if (n < 1) {
		x->valid = 0;
		goto done;
	    }
	    a = *ip;
	    for (i = 1; i < n; i++) {
		ip++;
		if (*ip < a) a = *ip;
	    }
	    *op++ = a;
	}
	else {
	    m = x->metrics;
	    for (i = 0; i < x->hdom; i++) {
		n = m->m_idom;
		if (n < 1) {
		    x->valid = 0;
		    goto done;
		}
		a = *ip;
		for (j = 1; j < n; j++){
		    /* Note! no break allowed in this loop */
		    ip++;
		    if (*ip < a) a = *ip;
		}
		*op++ = a;
		m++;
	    }
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

done:
    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMin_inst(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndMin_time(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ring = (double *)arg1->ring;
    double      *ip;
    double      *op;
    double	a;
    int		n = arg1->tdom;
    int		tspan;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0 && arg1->tdom > 0) {
	op = (double *)os->ptr;
	tspan = x->tspan;
	for (i = 0; i < tspan; i++) {
	    ip = ring + i;
	    a = *ip;
	    for (j = 1; j < n; j++){
		ip += tspan;
		if (*ip < a) a = *ip;
	    }
	    *op++ = a;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMin_time(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: unary.sk - unary operator
 ***********************************************************************/

/*
 *  operator: cndNeg
 */

#define OP(x) -(x)

void
cndNeg_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Sample	*is = &arg1->smpls[0];
    Sample	*os = &x->smpls[0];
    double	*ip;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->tspan > 0) {
	ip = (double *) is->ptr;
	op = (double *) os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op = OP(*ip);
	    op++;
	    ip++;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeg_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndNeg_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Sample	*is = &arg1->smpls[0];
    Sample	*os = &x->smpls[0];

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid) {
	*(double *)os->ptr = OP(*(double *)is->ptr);
	os->stamp = is->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeg_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: unary.sk - unary operator
 ***********************************************************************/

/*
 *  operator: cndInstant
 */

#define OP(x) (x)

void
cndInstant_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Sample	*is = &arg1->smpls[0];
    Sample	*os = &x->smpls[0];
    double	*ip;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->tspan > 0) {
	ip = (double *) is->ptr;
	op = (double *) os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op = OP(*ip);
	    op++;
	    ip++;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndInstant_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndInstant_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Sample	*is = &arg1->smpls[0];
    Sample	*os = &x->smpls[0];

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid) {
	*(double *)os->ptr = OP(*(double *)is->ptr);
	os->stamp = is->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndInstant_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndAdd
 */

#define OP(x,y) ((x) + (y))

void
cndAdd_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAdd_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndAdd_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAdd_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndAdd_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAdd_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndAdd_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(double *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAdd_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndSub
 */

#define OP(x,y) ((x) - (y))

void
cndSub_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSub_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndSub_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSub_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndSub_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSub_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndSub_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(double *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSub_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndMul
 */

#define OP(x,y) ((x) * (y))

void
cndMul_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMul_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndMul_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMul_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndMul_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMul_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndMul_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(double *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndMul_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndDiv
 */

#define OP(x,y) ((x) / (y))

void
cndDiv_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndDiv_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndDiv_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndDiv_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndDiv_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    double	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndDiv_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndDiv_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(double *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndDiv_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: merge.sk
 ***********************************************************************/

/*
 *  operator: cndRate
 */

void
cndRate_n(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample	*is1 = &arg1->smpls[0];
    Sample	*is2 = &arg1->smpls[1];
    Sample	*os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    double	*op;
    RealTime	delta;
    int		n;
    int         i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= 2 && x->tspan > 0) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	n = x->tspan;
	delta = is1->stamp - is2->stamp;
	for (i = 0; i < n; i++) {
	    *op = *ip1++ - *ip2++;
	    *op = *op / delta;
	    op++;
	}
	os->stamp = is1->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndRate_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndRate_1(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample	*is1 = &arg1->smpls[0];
    Sample	*is2 = &arg1->smpls[1];
    Sample	*os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    double	*op;
    RealTime	delta;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= 2) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (double *)os->ptr;
	delta = is1->stamp - is2->stamp;
	*op = *ip1 - *ip2;
	*op = *op / delta;
	os->stamp = is1->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndRate_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}


/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndEq
 */

#define OP(x,y) ((x) == (y))

void
cndEq_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndEq_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndEq_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndEq_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndEq_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndEq_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndEq_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(Boolean *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndEq_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary_str.sk - binary string-valued operator
 ***********************************************************************/

/*
 *  operator: cndEqStr
 */

#define OP(x) (x)

void
cndEqStr_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    char	*cp1;
    char	*cp2;
    Sample      *os = &x->smpls[0];
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    cp1 = getStringValue(arg1, i);
	    cp2 = getStringValue(arg2, i);
	    *op++ = cp1 != NULL && cp2 != NULL && OP(strcmp(cp1, cp2) == 0);
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndEqStr_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndEqStr_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    char	*cp1;
    char	*cp2;
    Sample      *os = &x->smpls[0];
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan == (arg1->sem == SEM_CHAR ? 1 : arg1->tspan)) {
	cp2 = getStringValue(arg2, 0);
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    cp1 = getStringValue(arg1, i);
	    *op++ = cp1 != NULL && cp2 != NULL && OP(strcmp(cp1, cp2) == 0);
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndEqStr_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndEqStr_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    char	*cp1;
    char	*cp2;
    Sample      *os = &x->smpls[0];
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan == (arg2->sem == SEM_CHAR ? 1 : arg2->tspan)) {
	op = (Boolean *)os->ptr;
	cp1 = getStringValue(arg1, 0);
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    cp2 = getStringValue(arg2, i);
	    *op++ = cp1 != NULL && cp2 != NULL && OP(strcmp(cp1, cp2) == 0);
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndEqStr_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndEqStr_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    char	*cp1;
    char	*cp2;
    Sample      *os = &x->smpls[0];
    Boolean	*op;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan == (arg1->sem == SEM_CHAR ? 1 : arg1->tspan) && x->tspan == (arg2->sem == SEM_CHAR ? 1 : arg2->tspan)) {
	op = (Boolean *)os->ptr;
	cp1 = getStringValue(arg1, 0);
	cp2 = getStringValue(arg2, 0);
	*op = cp1 != NULL && cp2 != NULL && OP(strcmp(cp1, cp2) == 0);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndEqStr_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndNeq
 */

#define OP(x,y) ((x) != (y))

void
cndNeq_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeq_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndNeq_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeq_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndNeq_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeq_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndNeq_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(Boolean *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeq_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary_str.sk - binary string-valued operator
 ***********************************************************************/

/*
 *  operator: cndNeqStr
 */

#define OP(x) !(x)

void
cndNeqStr_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    char	*cp1;
    char	*cp2;
    Sample      *os = &x->smpls[0];
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    cp1 = getStringValue(arg1, i);
	    cp2 = getStringValue(arg2, i);
	    *op++ = cp1 != NULL && cp2 != NULL && OP(strcmp(cp1, cp2) == 0);
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeqStr_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndNeqStr_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    char	*cp1;
    char	*cp2;
    Sample      *os = &x->smpls[0];
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan == (arg1->sem == SEM_CHAR ? 1 : arg1->tspan)) {
	cp2 = getStringValue(arg2, 0);
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    cp1 = getStringValue(arg1, i);
	    *op++ = cp1 != NULL && cp2 != NULL && OP(strcmp(cp1, cp2) == 0);
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeqStr_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndNeqStr_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    char	*cp1;
    char	*cp2;
    Sample      *os = &x->smpls[0];
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan == (arg2->sem == SEM_CHAR ? 1 : arg2->tspan)) {
	op = (Boolean *)os->ptr;
	cp1 = getStringValue(arg1, 0);
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    cp2 = getStringValue(arg2, i);
	    *op++ = cp1 != NULL && cp2 != NULL && OP(strcmp(cp1, cp2) == 0);
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeqStr_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndNeqStr_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    char	*cp1;
    char	*cp2;
    Sample      *os = &x->smpls[0];
    Boolean	*op;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan == (arg1->sem == SEM_CHAR ? 1 : arg1->tspan) && x->tspan == (arg2->sem == SEM_CHAR ? 1 : arg2->tspan)) {
	op = (Boolean *)os->ptr;
	cp1 = getStringValue(arg1, 0);
	cp2 = getStringValue(arg2, 0);
	*op = cp1 != NULL && cp2 != NULL && OP(strcmp(cp1, cp2) == 0);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNeqStr_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndLt
 */

#define OP(x,y) ((x) < (y))

void
cndLt_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndLt_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndLt_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndLt_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndLt_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndLt_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndLt_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(Boolean *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndLt_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndLte
 */

#define OP(x,y) ((x) <= (y))

void
cndLte_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndLte_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndLte_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndLte_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndLte_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndLte_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndLte_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(Boolean *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndLte_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndGt
 */

#define OP(x,y) ((x) > (y))

void
cndGt_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndGt_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndGt_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndGt_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndGt_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndGt_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndGt_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(Boolean *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndGt_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: binary.sk - binary operator
 ***********************************************************************/

/*
 *  operator: cndGte
 */

#define OP(x,y) ((x) >= (y))

void
cndGte_n_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan && x->tspan == arg2->tspan) {
	ip1 = (double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, *ip2);
	    ip1++;
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndGte_n_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndGte_n_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	*ip1;
    double	iv2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg1->tspan) {
	ip1 = (double *)is1->ptr;
	iv2 = *(double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(*ip1, iv2);
	    ip1++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndGte_n_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndGte_1_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];
    double	iv1;
    double	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid && x->tspan > 0 && x->tspan == arg2->tspan) {
	iv1 = *(double *)is1->ptr;
	ip2 = (double *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op++ = OP(iv1, *ip2);
	    ip2++;
	}
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndGte_1_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndGte_1_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Expr        *arg2 = x->arg2;
    Sample      *is1 = &arg1->smpls[0];
    Sample      *is2 = &arg2->smpls[0];
    Sample      *os = &x->smpls[0];

    EVALARG(arg1)
    EVALARG(arg2)
    ROTATE(x)

    if (arg1->valid && arg2->valid) {
	*(Boolean *)os->ptr = OP(*(double *)is1->ptr, *(double *)is2->ptr);
	os->stamp = (is1->stamp > is2->stamp) ? is1->stamp : is2->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndGte_1_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: unary.sk - unary operator
 ***********************************************************************/

/*
 *  operator: cndNot
 */

#define OP(x) (((x) == B_TRUE || (x) == B_FALSE) ? !(x) : B_UNKNOWN)

void
cndNot_n(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Sample	*is = &arg1->smpls[0];
    Sample	*os = &x->smpls[0];
    Boolean	*ip;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->tspan > 0) {
	ip = (Boolean *) is->ptr;
	op = (Boolean *) os->ptr;
	n = x->tspan;
	for (i = 0; i < n; i++) {
	    *op = OP(*ip);
	    op++;
	    ip++;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNot_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndNot_1(Expr *x)
{
    Expr        *arg1 = x->arg1;
    Sample	*is = &arg1->smpls[0];
    Sample	*os = &x->smpls[0];

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid) {
	*(Boolean *)os->ptr = OP(*(Boolean *)is->ptr);
	os->stamp = is->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndNot_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

#undef OP

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: merge.sk
 ***********************************************************************/

/*
 *  operator: cndRise
 */

void
cndRise_n(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample	*is1 = &arg1->smpls[0];
    Sample	*is2 = &arg1->smpls[1];
    Sample	*os = &x->smpls[0];
    Boolean	*ip1;
    Boolean	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= 2 && x->tspan > 0) {
	ip1 = (Boolean *)is1->ptr;
	ip2 = (Boolean *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	
	for (i = 0; i < n; i++) {
	    *op = *ip1++ > *ip2++;
	    
	    op++;
	}
	os->stamp = is1->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndRise_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndRise_1(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample	*is1 = &arg1->smpls[0];
    Sample	*is2 = &arg1->smpls[1];
    Sample	*os = &x->smpls[0];
    Boolean	*ip1;
    Boolean	*ip2;
    Boolean	*op;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= 2) {
	ip1 = (Boolean *)is1->ptr;
	ip2 = (Boolean *)is2->ptr;
	op = (Boolean *)os->ptr;
	
	*op = *ip1 > *ip2;
	
	os->stamp = is1->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndRise_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}


/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: merge.sk
 ***********************************************************************/

/*
 *  operator: cndFall
 */

void
cndFall_n(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample	*is1 = &arg1->smpls[0];
    Sample	*is2 = &arg1->smpls[1];
    Sample	*os = &x->smpls[0];
    Boolean	*ip1;
    Boolean	*ip2;
    Boolean	*op;
    int		n;
    int         i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= 2 && x->tspan > 0) {
	ip1 = (Boolean *)is1->ptr;
	ip2 = (Boolean *)is2->ptr;
	op = (Boolean *)os->ptr;
	n = x->tspan;
	
	for (i = 0; i < n; i++) {
	    *op = *ip1++ < *ip2++;
	    
	    op++;
	}
	os->stamp = is1->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndFall_n(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndFall_1(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample	*is1 = &arg1->smpls[0];
    Sample	*is2 = &arg1->smpls[1];
    Sample	*os = &x->smpls[0];
    Boolean	*ip1;
    Boolean	*ip2;
    Boolean	*op;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= 2) {
	ip1 = (Boolean *)is1->ptr;
	ip2 = (Boolean *)is2->ptr;
	op = (Boolean *)os->ptr;
	
	*op = *ip1 < *ip2;
	
	os->stamp = is1->stamp;
	x->valid++;
    }
    else x->valid = 0;

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndFall_1(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}


/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: aggregate.sk - aggregation and quantification
 ***********************************************************************/

/***********************************************************************
 * operator: cndAll
 ***********************************************************************/

void
cndAll_host(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean      *ip;
    Boolean      *op;
    Boolean	a;
    int		n;
    int		i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && arg1->hdom > 0) {
	ip = (Boolean *)is->ptr;
	op = (Boolean *)os->ptr;
	n = arg1->hdom;
	a = *ip;
	for (i = 1; i < n; i++) {
	    ip++;
	    if (*ip == B_FALSE) a = B_FALSE;
		else if (*ip == B_UNKNOWN && a != B_UNKNOWN) a = B_UNKNOWN;
	}
	*op++ = a;
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAll_host(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndAll_inst(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean      *ip;
    Boolean      *op;
    Boolean	a;
    Metric	*m;
    int		n;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->hdom != 0) {
	ip = (Boolean *)is->ptr;
	op = (Boolean *)os->ptr;
	if (abs(x->hdom) == 1) {
	    n = arg1->e_idom;
	    if (n < 1) {
		*op++ = B_UNKNOWN; os->stamp = is->stamp; x->valid++;
		goto done;
	    }
	    a = *ip;
	    for (i = 1; i < n; i++) {
		ip++;
		if (*ip == B_FALSE) a = B_FALSE;
		else if (*ip == B_UNKNOWN && a != B_UNKNOWN) a = B_UNKNOWN;
	    }
	    *op++ = a;
	}
	else {
	    m = x->metrics;
	    for (i = 0; i < x->hdom; i++) {
		n = m->m_idom;
		if (n < 1) {
		    *op++ = B_UNKNOWN; os->stamp = is->stamp; x->valid++;
		    goto done;
		}
		a = *ip;
		for (j = 1; j < n; j++){
		    /* Note! no break allowed in this loop */
		    ip++;
		    if (*ip == B_FALSE) a = B_FALSE;
		else if (*ip == B_UNKNOWN && a != B_UNKNOWN) a = B_UNKNOWN;
		}
		*op++ = a;
		m++;
	    }
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

done:
    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAll_inst(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndAll_time(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean	*ring = (Boolean *)arg1->ring;
    Boolean      *ip;
    Boolean      *op;
    Boolean	a;
    int		n = arg1->tdom;
    int		tspan;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0 && arg1->tdom > 0) {
	op = (Boolean *)os->ptr;
	tspan = x->tspan;
	for (i = 0; i < tspan; i++) {
	    ip = ring + i;
	    a = *ip;
	    for (j = 1; j < n; j++){
		ip += tspan;
		if (*ip == B_FALSE) a = B_FALSE;
		else if (*ip == B_UNKNOWN && a != B_UNKNOWN) a = B_UNKNOWN;
	    }
	    *op++ = a;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndAll_time(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: aggregate.sk - aggregation and quantification
 ***********************************************************************/

/***********************************************************************
 * operator: cndSome
 ***********************************************************************/

void
cndSome_host(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean      *ip;
    Boolean      *op;
    Boolean	a;
    int		n;
    int		i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && arg1->hdom > 0) {
	ip = (Boolean *)is->ptr;
	op = (Boolean *)os->ptr;
	n = arg1->hdom;
	a = *ip;
	for (i = 1; i < n; i++) {
	    ip++;
	    if (*ip == B_TRUE) a = B_TRUE;
		else if (*ip == B_UNKNOWN && a != B_UNKNOWN) a = B_UNKNOWN;
	}
	*op++ = a;
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSome_host(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndSome_inst(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean      *ip;
    Boolean      *op;
    Boolean	a;
    Metric	*m;
    int		n;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->hdom != 0) {
	ip = (Boolean *)is->ptr;
	op = (Boolean *)os->ptr;
	if (abs(x->hdom) == 1) {
	    n = arg1->e_idom;
	    if (n < 1) {
		*op++ = B_UNKNOWN; os->stamp = is->stamp; x->valid++;
		goto done;
	    }
	    a = *ip;
	    for (i = 1; i < n; i++) {
		ip++;
		if (*ip == B_TRUE) a = B_TRUE;
		else if (*ip == B_UNKNOWN && a != B_UNKNOWN) a = B_UNKNOWN;
	    }
	    *op++ = a;
	}
	else {
	    m = x->metrics;
	    for (i = 0; i < x->hdom; i++) {
		n = m->m_idom;
		if (n < 1) {
		    *op++ = B_UNKNOWN; os->stamp = is->stamp; x->valid++;
		    goto done;
		}
		a = *ip;
		for (j = 1; j < n; j++){
		    /* Note! no break allowed in this loop */
		    ip++;
		    if (*ip == B_TRUE) a = B_TRUE;
		else if (*ip == B_UNKNOWN && a != B_UNKNOWN) a = B_UNKNOWN;
		}
		*op++ = a;
		m++;
	    }
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

done:
    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSome_inst(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndSome_time(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean	*ring = (Boolean *)arg1->ring;
    Boolean      *ip;
    Boolean      *op;
    Boolean	a;
    int		n = arg1->tdom;
    int		tspan;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0 && arg1->tdom > 0) {
	op = (Boolean *)os->ptr;
	tspan = x->tspan;
	for (i = 0; i < tspan; i++) {
	    ip = ring + i;
	    a = *ip;
	    for (j = 1; j < n; j++){
		ip += tspan;
		if (*ip == B_TRUE) a = B_TRUE;
		else if (*ip == B_UNKNOWN && a != B_UNKNOWN) a = B_UNKNOWN;
	    }
	    *op++ = a;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndSome_time(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: aggregate.sk - aggregation and quantification
 ***********************************************************************/

/***********************************************************************
 * operator: cndPcnt
 ***********************************************************************/

void
cndPcnt_host(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean      *ip;
    Boolean      *op;
    int		a;
    int		n;
    int		i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && arg1->hdom > 0) {
	ip = (Boolean *)is->ptr;
	op = (Boolean *)os->ptr;
	n = arg1->hdom;
	a = *ip;
	for (i = 1; i < n; i++) {
	    ip++;
	    a += *ip;
	}
	*op++ = (a >= (int)(0.5 + *(double *)x->arg2->ring * n)) ? B_TRUE : B_FALSE;
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndPcnt_host(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndPcnt_inst(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean      *ip;
    Boolean      *op;
    int		a;
    Metric	*m;
    int		n;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->hdom != 0) {
	ip = (Boolean *)is->ptr;
	op = (Boolean *)os->ptr;
	if (abs(x->hdom) == 1) {
	    n = arg1->e_idom;
	    if (n < 1) {
		*op++ = B_UNKNOWN; os->stamp = is->stamp; x->valid++;
		goto done;
	    }
	    a = *ip;
	    for (i = 1; i < n; i++) {
		ip++;
		a += *ip;
	    }
	    *op++ = (a >= (int)(0.5 + *(double *)x->arg2->ring * n)) ? B_TRUE : B_FALSE;
	}
	else {
	    m = x->metrics;
	    for (i = 0; i < x->hdom; i++) {
		n = m->m_idom;
		if (n < 1) {
		    *op++ = B_UNKNOWN; os->stamp = is->stamp; x->valid++;
		    goto done;
		}
		a = *ip;
		for (j = 1; j < n; j++){
		    /* Note! no break allowed in this loop */
		    ip++;
		    a += *ip;
		}
		*op++ = (a >= (int)(0.5 + *(double *)x->arg2->ring * n)) ? B_TRUE : B_FALSE;
		m++;
	    }
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

done:
    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndPcnt_inst(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndPcnt_time(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean	*ring = (Boolean *)arg1->ring;
    Boolean      *ip;
    Boolean      *op;
    int		a;
    int		n = arg1->tdom;
    int		tspan;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0 && arg1->tdom > 0) {
	op = (Boolean *)os->ptr;
	tspan = x->tspan;
	for (i = 0; i < tspan; i++) {
	    ip = ring + i;
	    a = *ip;
	    for (j = 1; j < n; j++){
		ip += tspan;
		a += *ip;
	    }
	    *op++ = (a >= (int)(0.5 + *(double *)x->arg2->ring * n)) ? B_TRUE : B_FALSE;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndPcnt_time(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: aggregate.sk - aggregation and quantification
 ***********************************************************************/

/***********************************************************************
 * operator: cndCount
 ***********************************************************************/

void
cndCount_host(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean      *ip;
    double      *op;
    int		a;
    int		n;
    int		i;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && arg1->hdom > 0) {
	ip = (Boolean *)is->ptr;
	op = (double *)os->ptr;
	n = arg1->hdom;
	a = *ip == B_TRUE ? 1 : 0;
	for (i = 1; i < n; i++) {
	    ip++;
	    if (*ip == B_TRUE) a++;
	}
	*op++ = a;
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndCount_host(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndCount_inst(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean      *ip;
    double      *op;
    int		a;
    Metric	*m;
    int		n;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid && x->hdom != 0) {
	ip = (Boolean *)is->ptr;
	op = (double *)os->ptr;
	if (abs(x->hdom) == 1) {
	    n = arg1->e_idom;
	    if (n < 1) {
		x->valid = 0;
		goto done;
	    }
	    a = *ip == B_TRUE ? 1 : 0;
	    for (i = 1; i < n; i++) {
		ip++;
		if (*ip == B_TRUE) a++;
	    }
	    *op++ = a;
	}
	else {
	    m = x->metrics;
	    for (i = 0; i < x->hdom; i++) {
		n = m->m_idom;
		if (n < 1) {
		    x->valid = 0;
		    goto done;
		}
		a = *ip == B_TRUE ? 1 : 0;
		for (j = 1; j < n; j++){
		    /* Note! no break allowed in this loop */
		    ip++;
		    if (*ip == B_TRUE) a++;
		}
		*op++ = a;
		m++;
	    }
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

done:
    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndCount_inst(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

void
cndCount_time(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Sample      *is = &arg1->smpls[0];
    Sample      *os = &x->smpls[0];
    Boolean	*ring = (Boolean *)arg1->ring;
    Boolean      *ip;
    double      *op;
    int		a;
    int		n = arg1->tdom;
    int		tspan;
    int		i, j;

    EVALARG(arg1)
    ROTATE(x)

    if (arg1->valid >= n && x->tspan > 0 && arg1->tdom > 0) {
	op = (double *)os->ptr;
	tspan = x->tspan;
	for (i = 0; i < tspan; i++) {
	    ip = ring + i;
	    a = *ip == B_TRUE ? 1 : 0;
	    for (j = 1; j < n; j++){
		ip += tspan;
		if (*ip == B_TRUE) a++;
	    }
	    *op++ = a;
	}
	os->stamp = is->stamp;
	x->valid++;
    }
    else {
	x->valid = 0;
    }

    if (pmDebugOptions.appl2) {
	fprintf(stderr, "cndCount_time(" PRINTF_P_PFX "%p) ...\n", x);
	dumpExpr(x);
    }
}

/*
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/***********************************************************************
 * skeleton: act.sk - actions
 *
 ***********************************************************************/

/*
 *  operator: actAnd
 */
void
actAnd(Expr *x)
{
    Expr    *arg1 = x->arg1;
    Expr    *arg2 = x->arg2;

    EVALARG(arg1)
    EVALARG(arg2)
    *(Boolean *)x->ring = (*(Boolean *)arg1->ring == B_TRUE) && (*(Boolean *)arg2->ring == B_TRUE);
}


/*
 *  operator: actOr
 */
void
actOr(Expr *x)
{
    Expr    *arg1 = x->arg1;
    Expr    *arg2 = x->arg2;

    EVALARG(arg1)
    if (*(Boolean *)arg1->ring == B_FALSE) {
	EVALARG(arg2)
	*(Boolean *)x->ring = *(Boolean *)arg2->ring;
    }
    else *(Boolean *)x->ring = B_TRUE;
}


/*
 *  operator: actShell
 */
void
actShell(Expr *x)
{
    static char	*path;
    Expr    *arg1 = x->arg1;
    Expr    *arg2 = x->arg2;
#ifndef IS_MINGW
    pid_t   pid;
#endif
    int	    sts;

    /*
     * one trip to get PATH for system(3)
     */
    if (path == NULL) {
	char	*all_platform_paths = pmGetConfig("PCP_PLATFORM_PATHS");
	char	*pcp_binadm_path = pmGetConfig("PCP_BINADM_DIR");
	char	*pcp_bin_path = pmGetConfig("PCP_BIN_DIR");
#define DEFAULT_PATH "PATH=/usr/sbin:/sbin:/usr/bin:/bin"
	int	i, size = sizeof(DEFAULT_PATH) + 1;

	size += strlen(all_platform_paths) + 1;
	size += strlen(pcp_binadm_path) + 1;
	size += strlen(pcp_bin_path) + 1;
	if ((path = malloc(size)) != NULL) {
	    if ((i = pmsprintf(path, size-1, "%s:%s:%s:%s\n", DEFAULT_PATH,
			pcp_bin_path, pcp_binadm_path, all_platform_paths)) <= 0) {
		free(path);
		path = DEFAULT_PATH;	/* fallback to basic defaults */
	    }
	    else if (path[i-2] == ':')
		path[i-2] = '\0';	/* PCP_PLATFORM_PATHS may be null */
	    else
		path[i] = '\0';
	}
	else {
	    pmNoMem("actShell:path", size, PM_RECOV_ERR);
	    path = DEFAULT_PATH;	/* set a basic default anyway */
	}
    }

    if ((arg2 == NULL) ||
	(x->smpls[0].stamp == 0) ||
	(now >= *(RealTime *)arg2->ring + x->smpls[0].stamp))
    {
	EVALARG(arg1)
	fflush(stdout);
	fflush(stderr);
#ifdef IS_MINGW
	putenv(path);
	putenv("IFS=\t\n");
	sts = system((char *)arg1->ring);
	need_wait = 1;
	if (sts < 0) {
	    pmNotifyErr(LOG_ERR, "spawn for shell failed\n");
	    *(Boolean *)x->ring = B_FALSE;
	}
	else {
	    *(Boolean *)x->ring = B_TRUE;
	    x->smpls[0].stamp = now;
	    x->valid = 0;
	}
#else /*POSIX*/
	pid = fork();
	if (pid == 0) {
	    /* child, run the command */
	    setsid();
	    putenv(path);
	    putenv("IFS=\t\n");
	    sts = system((char *)arg1->ring);
	    _exit(WEXITSTATUS(sts));	/* avoid atexit() handler */
	}
	else if (pid > 0) {
	    /* parent, wait for child to exit to catch status */
	    if (pmDebugOptions.appl2) {
		fprintf(stderr, "actShell: fork: pid=%" FMT_PID "\n", pid);
	    }
	    sts = waitpid(pid, &x->valid, 0);
	    if (pmDebugOptions.appl2) {
		fprintf(stderr, "actShell: wait: pid=%" FMT_PID " status=0x%x", pid, x->valid);
		if (WIFEXITED(x->valid))
		    fprintf(stderr, " exit=%d", WEXITSTATUS(x->valid));
		if (WIFSIGNALED(x->valid))
		    fprintf(stderr, " signal=%d", WTERMSIG(x->valid));
		fprintf(stderr, " (wait returns %d)\n", sts);
	    }
	    if (WIFEXITED(x->valid))
		x->valid = WEXITSTATUS(x->valid);
	    else
		/* if no exit, then assume non-zero exit, hence failure! */
		x->valid = 1;
	    if (sts < 0 || x->valid != 0)
		*(Boolean *)x->ring = B_FALSE;
	    else
		*(Boolean *)x->ring = B_TRUE;
	    x->smpls[0].stamp = now;
	}
	else {
	    pmNotifyErr(LOG_ERR, "fork for shell failed\n");
	    *(Boolean *)x->ring = B_FALSE;
	}
#endif
	perf->actions++;
    }
}


/*
 *  operator: actAlarm
 */
void
actAlarm(Expr *x)
{
    static char *alarmv[] = {
	NULL,		/* path to PCP_XCONFIRM_PROG inserted here */
	    "-header", "Performance Co-Pilot Alarm",
	    "-b", "Cancel",
	    "-icon", "warning",
	    "-t", NULL,
	    "-t", NULL,
	    NULL};

    char    ctime[26];
    Expr    *arg1 = x->arg1;
    Expr    *arg2 = x->arg2;
    time_t  clock;
    int     sts;

    if (alarmv[0] == NULL) {
	/*
	 * one trip to get path for xconfirm(1)
	 */
	alarmv[0] = pmGetConfig("PCP_XCONFIRM_PROG");
	if (strcmp(alarmv[0], "") == 0) {
	    pmNotifyErr(LOG_ERR, "PCP_XCONFIRM_PROG not found, using echo(1)\n");
	    alarmv[0] = "/bin/echo";
	}
    }

#ifndef IS_MINGW
    /* if old alarm still active, don't post new one */
    if (x->valid != 0) {
	pid_t   pid;
	pid = waitpid((pid_t)x->valid, &sts, WNOHANG);
	if (pid <= 0) {
	    if (pmDebugOptions.appl2) {
		fprintf(stderr, "actAlarm: wait: pid=%d not done (wait returns %" FMT_PID ")\n", x->valid, pid);
	    }
	    return;
	}
	if (pmDebugOptions.appl2) {
	    fprintf(stderr, "actAlarm: wait: pid=%d done status=0x%x", x->valid, sts);
	    if (WIFEXITED(sts))
		fprintf(stderr, " exit=%d", WEXITSTATUS(sts));
	    if (WIFSIGNALED(sts))
		fprintf(stderr, " signal=%d", WTERMSIG(sts));
	    fprintf(stderr, " (wait returns %" FMT_PID ")\n", pid);
	}
	x->valid = 0;
    }
#endif

    if ((arg2 == NULL) ||
	(x->smpls[0].stamp == 0) ||
	(now >= *(RealTime *)arg2->ring + x->smpls[0].stamp))
    {
	EVALARG(arg1)
	clock = (time_t)(now+0.5);
	pmCtime(&clock, ctime);
#ifdef IS_MINGW
	alarmv[8] = ctime;
	alarmv[10] = (char *)arg1->ring;
	sts = spawnvp(_P_DETACH, alarmv[0], alarmv);
	if (sts < 0) {
	    pmNotifyErr(LOG_ERR, "spawn for PCP_XCONFIRM_PROG failed\n");
	    *(Boolean *)x->ring = B_FALSE;
	}
	else {
	    *(Boolean *)x->ring = B_TRUE;
	    x->smpls[0].stamp = now;
	    x->valid = 0;
	}
#else
	sts = fork();
	if (sts == 0) {
	    alarmv[8] = ctime;
	    alarmv[10] = (char *)arg1->ring;
	    setsid();
	    if (strcmp(alarmv[0], "/bin/echo") != 0) {
		/* only echo needs stdio, when xconfirm cannot be found */
		fclose(stdin);
		fclose(stdout);
		fclose(stderr);
	    }
	    execvp(alarmv[0], alarmv);
	    _exit(1);	/* avoid atexit() handler */
	}
	else if (sts > 0) {
	    need_wait = 1;
	    if (pmDebugOptions.appl2) {
		fprintf(stderr, "actAlarm: fork: pid=%d\n", sts);
	    }
	    x->valid = sts;
	    *(Boolean *)x->ring = B_TRUE;
	    x->smpls[0].stamp = now;
	}
	else {
	    pmNotifyErr(LOG_ERR, "fork for alarm failed\n");
	    *(Boolean *)x->ring = B_FALSE;
	}
#endif
	perf->actions++;
    }
}


/*
 *  operator: actSyslog
 */
void
actSyslog(Expr *x)
{
    Expr	*arg1 = x->arg1;
    Expr	*arg2 = x->arg2;
    int		*pri;
    char	*tag;

    if ((arg2 == NULL) ||
	(x->smpls[0].stamp == 0) ||
	(now >= *(RealTime *)arg2->ring + x->smpls[0].stamp))
    {
	pri = (int *)arg1->arg2->ring;
	tag = &((char *)arg1->arg2->ring)[sizeof(int)];
	EVALARG(arg1)
	openlog(tag, LOG_PID|LOG_CONS, LOG_DAEMON);
	if (arg1->ring == NULL)
	    syslog(*pri, "%s",  "");
	else
	    syslog(*pri, "%s", (char *)arg1->ring);
	closelog();
	*(Boolean *)x->ring = B_TRUE;
	x->smpls[0].stamp = now;
	perf->actions++;
    }
}


/*
 *  operator: actPrint
 */
void
actPrint(Expr *x)
{
    Expr    *arg1 = x->arg1;
    Expr    *arg2 = x->arg2;
    time_t  clock = (time_t)now;
    char    bfr[26];

    if ((arg2 == NULL) ||
	(x->smpls[0].stamp == 0) ||
	(now >= *(RealTime *)arg2->ring + x->smpls[0].stamp))
    {
	EVALARG(arg1)
	*(Boolean *)x->ring = B_TRUE;
	x->smpls[0].stamp = now;
	pmCtime(&clock, bfr);
	bfr[24] = '\0';
	printf("%s: %s\n", bfr, (char *)arg1->ring);
	fflush(stdout);
	perf->actions++;
    }
}


/*
 *  operator: actStomp
 */
void
actStomp(Expr *x)
{
    Expr    *arg1 = x->arg1;
    Expr    *arg2 = x->arg2;

    if ((arg2 == NULL) ||
	(x->smpls[0].stamp == 0) ||
	(now >= *(RealTime *)arg2->ring + x->smpls[0].stamp))
    {
	EVALARG(arg1)
	x->smpls[0].stamp = now;
	if (stompSend((const char *)arg1->ring) != 0)
	    *(Boolean *)x->ring = B_FALSE;
	else
	    *(Boolean *)x->ring = B_TRUE;
	perf->actions++;
    }
}


/*
 * action argument handling ... including %h, %v and %i substitution
 */
void
actArg(Expr *x)
{
    Expr    *sp = x->arg1;
    char    *string = (char *)0;
    size_t  length = 0;

    for (sp = x->arg1; sp != NULL; sp = sp->arg1)
	length = formatSatisfyingValue((char *)sp->ring, length, &string);

    newStringBfr(x, length, string);
}


/*
 * fake actions for archive mode
 */

/* first -f|--format support ... */
typedef struct {
    int		type;
    void	*data;
} msg_fmt;

#define FMT_UNKNOWN	-1
#define FMT_STR		0
#define FMT_ACTION	1
#define FMT_DATETIME	2
#define FMT_FILE	3
#define FMT_LINENO	4
#define FMT_MSG		5
#define FMT_USECDATE	6
#define FMT_END		99

static msg_fmt *parse_fmt(char *fmt)
{
    msg_fmt	*res = NULL;
    msg_fmt	*rp;
    int		npart = 0;
    char	*p;
    char	*q;

    p = q = fmt;

    while (*q) {
	if (*q == '%') {
	    int		type = FMT_UNKNOWN;
	    if (q > p) {
		/* string before % */
		npart++;
		if ((rp = (msg_fmt *)realloc(res, npart*sizeof(msg_fmt))) == NULL) {
		    fprintf(stderr, "parse_fmt: realloc for part %d failed\n", npart);
		    free(res);
		    return NULL;
		}
		res = rp;
		rp = &res[npart-1];
		rp->type = FMT_STR;
		rp->data = (void *)strndup(p, q-p);
	    }
	    /* look at next char ... */
	    switch (q[1]) {
		case 'a':
			type = FMT_ACTION;
			break;

		case 'd':
			type = FMT_DATETIME;
			break;

		case 'f':
			type = FMT_FILE;
			break;

		case 'l':
			type = FMT_LINENO;
			break;

		case 'm':
			type = FMT_MSG;
			break;

		case 'u':
			type = FMT_USECDATE;
			break;

		case '%':
			p = ++q;
			break;
		case '\0':
			p = q;
			break;
		default:
			fprintf(stderr, "Warning: unrecognized field specifier '%%%c' in format\n", q[1]);
			p = q;
			break;
	    }
	    if (type != FMT_UNKNOWN) {
		npart++;
		if ((rp = (msg_fmt *)realloc(res, npart*sizeof(msg_fmt))) == NULL) {
		    fprintf(stderr, "parse_fmt: realloc for part %d (field %%%c) failed\n", npart, q[1]);
		    free(res);
		    return NULL;
		}
		res = rp;
		rp = &res[npart-1];
		rp->type = type;
		rp->data = NULL;
		++q;
		p = ++q;
	    }
	    else
		++q;
	}
	else
	    ++q;
    }

    if (*p != '\0') {
	/* trailing string */
	npart++;
	if ((rp = (msg_fmt *)realloc(res, npart*sizeof(msg_fmt))) == NULL) {
	    fprintf(stderr, "parse_fmt: realloc for part %d failed\n", npart);
	    free(res);
	    return NULL;
	}
	res = rp;
	rp = &res[npart-1];
	rp->type = FMT_STR;
	rp->data = (void *)strndup(p, q-p);
    }

    /* end-of-format */
    npart++;
    if ((rp = (msg_fmt *)realloc(res, npart*sizeof(msg_fmt))) == NULL) {
	fprintf(stderr, "parse_fmt: realloc for part END failed\n");
	free(res);
	return NULL;
    }
    res = rp;
    rp = &res[npart-1];
    rp->type = FMT_END;
    rp->data = NULL;

    return res;
}

void
actFake(Expr *x)
{
    Expr    		*arg1 = x->arg1;
    Expr    		*arg2 = x->arg2;
    aux_action		*aap = (aux_action *)x->auxdata;
    time_t  		clock = (time_t)now;
    char    		bfr[26];
    static msg_fmt	*fmt = NULL;
    extern char		*format;

    if ((arg2 == NULL) ||
	(x->smpls[0].stamp == 0) ||
	(now >= *(RealTime *)arg2->ring + x->smpls[0].stamp))
    {
	EVALARG(arg1)
	*(Boolean *)x->ring = B_TRUE;
	x->smpls[0].stamp = now;
	pmCtime(&clock, bfr);
	bfr[24] = '\0';

	if (format != NULL && fmt == NULL) {
	    /*
	     * one-trip for -o|--format option
	     */
	    fmt = parse_fmt(format);
	    if (fmt == NULL) {
		/* fallback to default */
		format = NULL;
	    }
	}

	if (format) {
	    int		i;
	    /* -o|--format in play */
	    for (i = 0; ; i++) {
		switch (fmt[i].type) {
		    case FMT_STR:
			printf("%s", (char *)fmt[i].data);
			break;
		    case FMT_ACTION:
			printf("%s", opStrings(x->op));
			break;
		    case FMT_DATETIME:
			printf("%s", bfr);
			break;
		    case FMT_FILE:
			printf("%s", aap->fname);
			break;
		    case FMT_LINENO:
			printf("%d", aap->lineno);
			break;
		    case FMT_MSG:
			printf("%s", (char *)arg1->ring);
			break;
		    case FMT_USECDATE:
			/*
			 * bfr[18] is where the time (in seconds) from
			 * pmCtime() ends
			 */
			printf("%19.19s.", bfr);
			printf("%06ld", (long)((now - clock) * 1000000));
			printf("%s", &bfr[19]);
			break;
		    case FMT_END:
			putchar('\n');
			break;
		}
		if (fmt[i].type == FMT_END)
		    break;
	    }
	}
	else {
	    /* default */
	    printf("%s %s: %s\n", opStrings(x->op), bfr, (char *)arg1->ring);
	}
    }
}

