Example #1
0
static void testAValExpr(const char* expr, double* args, double** aargs, double* expected, int length)
{	
	unsigned char rpn[255];
	short err;
	
	double val;
	double aval[12];
	
	epicsUInt32 amask;
	
	if (aCalcPostfix(expr, rpn, &err))
	{
		testDiag("postfix: %s in expression '%s'", aCalcErrorStr(err), expr);
		return;
	}
	
	if (aCalcPerform(args, 12, aargs, 12, 12, &val, aval, rpn, 12, &amask))
	{
		testDiag("calcPerform: error evaluating '%s'", expr);
		return;
	}
	
	bool pass = true;
	int i = 0;
	
	for (i = 0; i < length; i += 1)
	{
		if (finite(expected[i]) && finite(aval[i]))
		{
			if (fabs(expected[i] - aval[i]) > 1e-8)
			{
				pass = false;
				break;
			}
		}
		else if (isnan(expected[i]) && !isnan(aval[i]))
		{
			pass = false;
			break;
		}
		else if (aval[i] != expected[i])
		{
			pass = false;
			break;
		}
	}
	
	if(!testOk(pass, "%s", expr))
	{	
		testDiag("Expected aval[%d]: %f, Got: %f", i, expected[i], aval[i]);
	}	
}
Example #2
0
static void testValExpr(const char* expr, double* args, double** aargs, double expected)
{	
	unsigned char rpn[255];
	short err;
	
	double val;
	double aval[1];
	
	epicsUInt32 amask;
	
	if (aCalcPostfix(expr, rpn, &err))
	{
		testDiag("postfix: %s in expression '%s'", aCalcErrorStr(err), expr);
		return;
	}
	
	if (aCalcPerform(args, 12, aargs, 12, 3, &val, aval, rpn, 1, &amask))
	{
		testDiag("calcPerform: error evaluating '%s'", expr);
		return;
	}
	
	
	bool pass;
	
	if (finite(expected) && finite(val))
	{
		pass = fabs(expected - val) < 1e-8;
	}
	else if (isnan(expected))
	{
		pass = (bool) isnan(val);
	}
	else
	{
		pass = (val == expected);
	}
	
	if(!testOk(pass, "%s", expr))
	{
		testDiag("Expected: %f, Got: %f", expected, val);
	}	
}
Example #3
0
static long special(dbAddr	*paddr, int after)
{
	acalcoutRecord	*pcalc = (acalcoutRecord *)(paddr->precord);
	rpvtStruct		*prpvt = (struct rpvtStruct *)pcalc->rpvt;
	dbAddr			Addr;
	dbAddr			*pAddr = &Addr;
	short			error_number;
	int				fieldIndex = dbGetFieldIndex(paddr);
	int				lnkIndex;
	DBLINK			*plink;
	double			*pvalue;
	unsigned short	*plinkValid;

	if (!after) return(0);
	switch (fieldIndex) {
	case acalcoutRecordCALC:
		pcalc->clcv = aCalcPostfix(pcalc->calc, pcalc->rpcl, &error_number);
		if (pcalc->clcv) {
			recGblRecordError(S_db_badField,(void *)pcalc,
				"acalcout: special(): Illegal CALC field");
			if (aCalcoutRecordDebug >= 10)
				printf("acalcPostfix returns: %d\n", error_number);
		}
		db_post_events(pcalc,&pcalc->clcv,DBE_VALUE);
		return(0);
		break;

	case acalcoutRecordOCAL:
		pcalc->oclv = aCalcPostfix(pcalc->ocal, pcalc->orpc, &error_number);
		if (pcalc->oclv) {
			recGblRecordError(S_db_badField,(void *)pcalc,
				"acalcout: special(): Illegal OCAL field");
			if (aCalcoutRecordDebug >= 10)
				printf("acalcPostfix returns: %d\n", error_number);
		}
		db_post_events(pcalc,&pcalc->oclv,DBE_VALUE);
		return(0);
		break;

	case acalcoutRecordNUSE:
		if ((pcalc->nuse < 0) || (pcalc->nuse > pcalc->nelm)) {
			pcalc->nuse = pcalc->nelm;
			db_post_events(pcalc,&pcalc->nuse,DBE_VALUE);
			return(-1);
		}
		return(0);
		break;

	case(acalcoutRecordINPA):
	case(acalcoutRecordINPB):
	case(acalcoutRecordINPC):
	case(acalcoutRecordINPD):
	case(acalcoutRecordINPE):
	case(acalcoutRecordINPF):
	case(acalcoutRecordINPG):
	case(acalcoutRecordINPH):
	case(acalcoutRecordINPI):
	case(acalcoutRecordINPJ):
	case(acalcoutRecordINPK):
	case(acalcoutRecordINPL):
	case(acalcoutRecordINAA):
	case(acalcoutRecordINBB):
	case(acalcoutRecordINCC):
	case(acalcoutRecordINDD):
	case(acalcoutRecordINEE):
	case(acalcoutRecordINFF):
	case(acalcoutRecordINGG):
	case(acalcoutRecordINHH):
	case(acalcoutRecordINII):
	case(acalcoutRecordINJJ):
	case(acalcoutRecordINKK):
	case(acalcoutRecordINLL):
	case(acalcoutRecordOUT):
		lnkIndex = fieldIndex - acalcoutRecordINPA;
		plink   = &pcalc->inpa + lnkIndex;
		pvalue  = &pcalc->a    + lnkIndex;
		plinkValid = &pcalc->inav + lnkIndex;

		if (plink->type == CONSTANT) {
			if (fieldIndex <= acalcoutRecordINPL) {
				recGblInitConstantLink(plink,DBF_DOUBLE,pvalue);
				db_post_events(pcalc,pvalue,DBE_VALUE);
			}
			*plinkValid = acalcoutINAV_CON;
			if (fieldIndex == acalcoutRecordOUT)
				prpvt->outlink_field_type = DBF_NOACCESS;
		} else if (!dbNameToAddr(plink->value.pv_link.pvname, pAddr)) {
			/* PV resides on this ioc */
			*plinkValid = acalcoutINAV_LOC;
			if (fieldIndex == acalcoutRecordOUT) {
				prpvt->outlink_field_type = pAddr->field_type;
				if ((pAddr->field_type >= DBF_INLINK) && (pAddr->field_type <= DBF_FWDLINK)) {
					if (!(plink->value.pv_link.pvlMask & pvlOptCA)) {
						printf("aCalcoutRecord(%s):special:non-CA link to link field\n",
							plink->value.pv_link.pvname);
					}
				}
				if (pcalc->wait && !(plink->value.pv_link.pvlMask & pvlOptCA)) {
					printf("aCalcoutRecord(%s):special: Can't wait with non-CA link attribute\n",
						plink->value.pv_link.pvname);
				}
			}
		} else {
			/* pv is not on this ioc. Callback later for connection stat */
			*plinkValid = acalcoutINAV_EXT_NC;
			/* DO_CALLBACK, if not already scheduled */
			if (!prpvt->wd_id_1_LOCK) {
				callbackRequestDelayed(&prpvt->checkLinkCb,.5);
				prpvt->wd_id_1_LOCK = 1;
				prpvt->caLinkStat = CA_LINKS_NOT_OK;
			}
			if (fieldIndex == acalcoutRecordOUT)
				prpvt->outlink_field_type = DBF_NOACCESS; /* don't know */
		}
        db_post_events(pcalc,plinkValid,DBE_VALUE);
		return(0);
		break;

	default:
		recGblDbaddrError(S_db_badChoice,paddr,"calc: special");
		return(S_db_badChoice);
	}
	return(0);
}
Example #4
0
static long init_record(acalcoutRecord *pcalc, int pass)
{
	DBLINK *plink;
	int i;
	double *pvalue;
	unsigned short *plinkValid;
	short error_number;
    acalcoutDSET *pacalcoutDSET;

	dbAddr       Addr;
	dbAddr       *pAddr = &Addr;
	rpvtStruct   *prpvt;

	if (pass==0) {
		pcalc->vers = VERSION;
		pcalc->rpvt = (void *)calloc(1, sizeof(struct rpvtStruct));
		if ((pcalc->nuse < 0) || (pcalc->nuse > pcalc->nelm)) {
			pcalc->nuse = pcalc->nelm;
			db_post_events(pcalc,&pcalc->nuse,DBE_VALUE|DBE_LOG);
		}
		return(0);
	}

	if (!(pacalcoutDSET = (acalcoutDSET *)pcalc->dset)) {
		recGblRecordError(S_dev_noDSET,(void *)pcalc,"acalcout:init_record");
		return(S_dev_noDSET);
	}
	/* must have write defined */
	if ((pacalcoutDSET->number < 5) || (pacalcoutDSET->write == NULL)) {
		recGblRecordError(S_dev_missingSup,(void *)pcalc,"acalcout:init_record");
		return(S_dev_missingSup);
	}

	prpvt = (rpvtStruct *)pcalc->rpvt;
	plink = &pcalc->inpa;
	pvalue = &pcalc->a;
	plinkValid = &pcalc->inav;
	for (i=0; i<(MAX_FIELDS+ARRAY_MAX_FIELDS+1); i++, plink++, pvalue++, plinkValid++) {
		if (plink->type == CONSTANT) {
			/* Don't InitConstantLink the array links or the output link. */
			if (i < MAX_FIELDS) { 
				recGblInitConstantLink(plink,DBF_DOUBLE,pvalue);
				db_post_events(pcalc,pvalue,DBE_VALUE);
			}
			*plinkValid = acalcoutINAV_CON;
			if (plink == &pcalc->out)
				prpvt->outlink_field_type = DBF_NOACCESS;
		} else if (!dbNameToAddr(plink->value.pv_link.pvname, pAddr)) {
			/* the PV we're linked to resides on this ioc */
			*plinkValid = acalcoutINAV_LOC;
			if (plink == &pcalc->out) {
				prpvt->outlink_field_type = pAddr->field_type;
				if ((pAddr->field_type >= DBF_INLINK) && (pAddr->field_type <= DBF_FWDLINK)) {
					if (!(plink->value.pv_link.pvlMask & pvlOptCA)) {
						printf("aCalcoutRecord(%s):init_record:non-CA link to link field\n",
							plink->value.pv_link.pvname);
					}
				}
				if (pcalc->wait && !(plink->value.pv_link.pvlMask & pvlOptCA)) {
					printf("aCalcoutRecord(%s):init_record: Can't wait with non-CA link attribute\n",
						plink->value.pv_link.pvname);
				}
			}
		} else {
			/* pv is not on this ioc. Callback later for connection stat */
			*plinkValid = acalcoutINAV_EXT_NC;
			prpvt->caLinkStat = CA_LINKS_NOT_OK;
			if (plink == &pcalc->out)
				prpvt->outlink_field_type = DBF_NOACCESS; /* don't know field type */
		}
		db_post_events(pcalc,plinkValid,DBE_VALUE);
	}

	pcalc->clcv = aCalcPostfix(pcalc->calc,pcalc->rpcl,&error_number);
	if (pcalc->clcv) {
		recGblRecordError(S_db_badField,(void *)pcalc,
			"acalcout: init_record: Illegal CALC field");
		if (aCalcoutRecordDebug >= 10)
			printf("acalcPostfix returns: %d\n", error_number);
	}
	db_post_events(pcalc,&pcalc->clcv,DBE_VALUE);

	pcalc->oclv = aCalcPostfix(pcalc->ocal, pcalc->orpc,&error_number);
	if (pcalc->oclv) {
		recGblRecordError(S_db_badField,(void *)pcalc,
			"acalcout: init_record: Illegal OCAL field");
		if (aCalcoutRecordDebug >= 10)
			printf("acalcPostfix returns: %d\n", error_number);
	}
	db_post_events(pcalc,&pcalc->oclv,DBE_VALUE);

	callbackSetCallback(checkLinksCallback, &prpvt->checkLinkCb);
	callbackSetPriority(0, &prpvt->checkLinkCb);
	callbackSetUser(pcalc, &prpvt->checkLinkCb);
	prpvt->wd_id_1_LOCK = 0;

	if (prpvt->caLinkStat == CA_LINKS_NOT_OK) {
		callbackRequestDelayed(&prpvt->checkLinkCb,1.0);
		prpvt->wd_id_1_LOCK = 1;
	}

	if (pacalcoutDSET->init_record ) {
		return (*pacalcoutDSET->init_record)(pcalc);
	}
	return(0);
}