#include <string.h>
#include <malloc.h>
#include <math.h>
#include <UT/UT_DSOVersion.h>
#include <EXPR/EXPR.h>
#include <EXPR/EX_Vector.h>
#include <OP/OP_Director.h>
#include <OP/OP_Operator.h>
#include <OP/OP_Channels.h>
#include <PRM/PRM_RefId.h>
#include <CH/CH_Support.h>
#include <CMD/CMD_Manager.h>
static void
fn_addOpNameDepend1(EV_FUNCTION *func, EV_SYMBOL **argv, void *ref_id)
{
OP_InterestType type;
if( argv[0] == NULL )
return;
if (func->getUserFlags() & CH_EXPRDATA)
type = OP_INTEREST_NAMEDATA;
else
type = OP_INTEREST_NAME;
OP_Node::addExprOpDependency(argv[0]->value.sval, *((PRM_RefId *)ref_id),
type);
}
static void
fn_changeOpRef1(EV_FUNCTION *func, EV_SYMBOL **argv, char **new_args,
const char *new_fullpath, const char *old_fullpath,
const char *old_cwd, const char * ,
const char * )
{
if( argv[0] == NULL )
return;
OP_Node::changeExprOpRef(argv[0]->value.sval, new_args[0], new_fullpath,
old_fullpath, old_cwd);
}
static OP_Node *
findOp(int thread,
const char *object, OP_InterestType interest_type = OP_INTEREST_DATA)
{
OP_InterestRef eval_ref(OP_InterestRef::EvalChannel, thread);
OP_Node *cwd;
OP_Node *here;
OP_Node *src;
here = eval_ref.node();
if (!here) return 0;
cwd = (*object == '/') ? OPgetDirector() : here;
if (*object == '\0' || !strcmp(object, "."))
src = (OP_Node *)cwd;
else src = (OP_Node *)cwd->findNode(object);
if (!src) return 0;
OP_Node::addExtraInput(eval_ref, OP_InterestRef(*src, interest_type));
return src;
}
#ifndef EV_START_FN
#define EV_START_FN(name) \
static void name(EV_FUNCTION *, EV_SYMBOL *result,\
EV_SYMBOL **argv, int thread)
#endif // EV_START_FN
EV_START_FN(fn_max)
{
if (argv[0]->value.fval > argv[1]->value.fval)
result->value.fval = argv[0]->value.fval;
else result->value.fval = argv[1]->value.fval;
}
EV_START_FN(fn_min)
{
if (argv[0]->value.fval > argv[1]->value.fval)
result->value.fval = argv[1]->value.fval;
else result->value.fval = argv[0]->value.fval;
}
EV_START_FN(fn_optype_proto)
{
OP_Node *node;
const OP_Operator *opdef;
if (node = findOp(thread, argv[0]->value.sval))
{
opdef = node->getOperator();
result->value.sval = strdup(opdef->getName());
}
else result->value.sval = 0;
}
EV_START_FN(fn_vectorsum)
{
ev_Vector *v0 = (ev_Vector *)argv[0]->value.data;
ev_Vector *v1 = (ev_Vector *)argv[1]->value.data;
ev_Vector *sum = (ev_Vector *)result->value.data;
sum->copy(*v0);
sum->add(*v1);
}
#define EVF EV_TYPEFLOAT
#define EVS EV_TYPESTRING
#define EVV EV_TYPEVECTOR
static int floatArgs[] = { EVF, EVF };
static int stringArgs[] = { EVS };
static int vectorArgs[] = { EVV, EVV };
static EV_FUNCTION funcTable[] = {
EV_FUNCTION(0, "max", 2, EVF, floatArgs, fn_max),
EV_FUNCTION(0, "min", 2, EVF, floatArgs, fn_min),
EV_FUNCTION(0, "optype_proto", 1, EVS, stringArgs, fn_optype_proto),
EV_FUNCTION(0, "vectorsum", 2, EVV, vectorArgs, fn_vectorsum),
EV_FUNCTION(),
};
void
CMDextendLibrary(CMD_Manager *)
{
int i;
for (i = 0; funcTable[i].getName(); i++)
ev_AddFunction(&funcTable[i]);
ev_SetFunctionDependencyCallbacks("optype_proto", fn_addOpNameDepend1,
fn_changeOpRef1);
}