コード例 #1
0
ファイル: aiRecord.c プロジェクト: T-A-R-L-A/EPICS-Base
static long special(DBADDR *paddr,int after)
{
    aiRecord  	*prec = (aiRecord *)(paddr->precord);
    aidset 	*pdset = (aidset *) (prec->dset);
    int          special_type = paddr->special;

    switch(special_type) {
    case(SPC_LINCONV):
	if(pdset->number<6) {
	    recGblDbaddrError(S_db_noMod,paddr,"ai: special");
	    return(S_db_noMod);
	}
	prec->init=TRUE;
	if ((prec->linr == menuConvertLINEAR) && pdset->special_linconv) {
	    double eoff = prec->eoff;
	    double eslo = prec->eslo;
	    long status;
	    prec->eoff = prec->egul;
	    status = (*pdset->special_linconv)(prec,after);
	    if (eoff != prec->eoff)
		db_post_events(prec, &prec->eoff, DBE_VALUE|DBE_LOG);
	    if (eslo != prec->eslo)
		db_post_events(prec, &prec->eslo, DBE_VALUE|DBE_LOG);
	    return(status);
	}
	return(0);
    default:
	recGblDbaddrError(S_db_badChoice,paddr,"ai: special");
	return(S_db_badChoice);
    }
}
コード例 #2
0
ファイル: dbFastLinkConv.c プロジェクト: ukaea/epics
/* Convert String to Device */
static long cvt_st_device(
    char *from,
    epicsEnum16 *to,
    const dbAddr *paddr)
{
    dbFldDes		*pdbFldDes = paddr->pfldDes;
    dbDeviceMenu	*pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
    char		**papChoice;
    char		*pchoice;
    unsigned int	nChoice,ind;
    int			nargs,nchars;

    if( pdbDeviceMenu  && (papChoice = pdbDeviceMenu->papChoice)) {
        nChoice = pdbDeviceMenu->nChoice;
        for(ind=0; ind<nChoice; ind++) {
            if(!(pchoice=papChoice[ind])) continue;
            if(strcmp(pchoice,from)==0) {
                *to = ind;
                return(0);
            }
        }
        nargs = sscanf(from,"%u%n",&ind,&nchars);
        if(nargs==1 && nchars==strlen(from) && ind<nChoice) {
            *to = ind;
            return(0);
        }
    }
    recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_st_device)");
    return(S_db_badChoice);
}
コード例 #3
0
ファイル: dbAccess.c プロジェクト: ukaea/epics
long dbPutSpecial(DBADDR *paddr,int pass)
{
    long int	(*pspecial)()=NULL;
    struct rset	*prset;
    dbCommon 	*precord = paddr->precord;
    long	status=0;
    long	special=paddr->special;

    prset = dbGetRset(paddr);
    if(special<100) { /*global processing*/
	if((special==SPC_NOMOD) && (pass==0)) {
	    status = S_db_noMod;
	    recGblDbaddrError(status,paddr,"dbPut");
	    return(status);
	}else if(special==SPC_SCAN){
	    if(pass==0)
		scanDelete(precord);
	    else
		scanAdd(precord);
	}else if((special==SPC_AS) && (pass==1)) {
            if(spcAsCallback) (*spcAsCallback)(precord);
	}
    }else {
	if( prset && (pspecial = (prset->special))) {
	    status=(*pspecial)(paddr,pass);
	    if(status) return(status);
	} else if(pass==0){
	    recGblRecSupError(S_db_noSupport,paddr,"dbPut", "special");
	    return(S_db_noSupport);
	}
    }
    return(0);
}
コード例 #4
0
ファイル: compressRecord.c プロジェクト: zlxmsu/TestEpics
static long special(DBADDR *paddr, int after)
{
    compressRecord   *prec = (compressRecord *)(paddr->precord);
    int                 special_type = paddr->special;

    if(!after) return(0);
    switch(special_type) {
    case(SPC_RESET):
	reset(prec);
        return(0);
    default:
        recGblDbaddrError(S_db_badChoice,paddr,"compress: special");
        return(S_db_badChoice);
    }
}
コード例 #5
0
ファイル: dbFastLinkConv.c プロジェクト: ukaea/epics
/* Get Device to String */
static long cvt_device_st(
    epicsEnum16 *from,
    char *to,
    const dbAddr *paddr)
{
    dbFldDes		*pdbFldDes;
    dbDeviceMenu		*pdbDeviceMenu;
    char			**papChoice;
    char			*pchoice;

    if(!paddr
            || !(pdbFldDes = paddr->pfldDes)
            || !(pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
            || *from>=pdbDeviceMenu->nChoice
            || !(papChoice= pdbDeviceMenu->papChoice)
            || !(pchoice=papChoice[*from])) {
        recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_device_st)");
        return(S_db_badChoice);
    }
    strncpy(to,pchoice,MAX_STRING_SIZE);
    return(0);
}
コード例 #6
0
ファイル: aliveRecord.c プロジェクト: epics-modules/alive
static long special(DBADDR *paddr, int after)
{
  struct aliveRecord *prec = (aliveRecord *)paddr->precord;
  struct rpvtStruct   *prpvt = prec->rpvt;
  int    special_type = paddr->special;

  int   fieldIndex = dbGetFieldIndex(paddr);
  
  int relIndex;
  int f;

  if( !after) 
    return 0;

  if( special_type != SPC_MOD)
    {
      recGblDbaddrError(S_db_badChoice, paddr, "alive: special");
      return (S_db_badChoice);
    }

  switch(fieldIndex) 
    {
    case(aliveRecordRHOST):
#if defined (vxWorks)
      if( (prpvt->h_addr.sin_addr.s_addr = inet_addr (prec->rhost)) == ERROR)
#elif defined (_WIN32)
      if( (prpvt->h_addr.sin_addr.s_addr = inet_addr(prec->rhost)) == INADDR_NONE)
#else
      if( !inet_aton( prec->rhost, &(prpvt->h_addr.sin_addr)) )
#endif
        prpvt->ready_flag = 0;
      else
        prpvt->ready_flag = 1;
      break;
    case(aliveRecordRPORT):
      prpvt->h_addr.sin_port = htons(prec->rport);
      break;
    case(aliveRecordISUP):
      if( prec->isup )
        prpvt->flags |= ((uint16_t) 2);
      else
        prpvt->flags &= ~((uint16_t) 2);
      break;
    case(aliveRecordITRIG):
      // falls through to trigger reread
      break;
    case(aliveRecordENV1):
    case(aliveRecordENV2):
    case(aliveRecordENV3):
    case(aliveRecordENV4):
    case(aliveRecordENV5):
    case(aliveRecordENV6):
    case(aliveRecordENV7):
    case(aliveRecordENV8):
    case(aliveRecordENV9):
    case(aliveRecordENV10):
    case(aliveRecordENV11):
    case(aliveRecordENV12):
    case(aliveRecordENV13):
    case(aliveRecordENV14):
    case(aliveRecordENV15):
    case(aliveRecordENV16):
      relIndex = fieldIndex - aliveRecordENV1;
      f = sscanf( *(&prec->env1 + relIndex), "%s", prpvt->env[relIndex]);
      if( !f)
        prpvt->env[relIndex][0] = '\0';
      break;
    default:
      recGblDbaddrError(S_db_badChoice, paddr, "alive: special");
      return(S_db_badChoice);
    }

  // everything turns on request flag
  prpvt->flags |= ((uint16_t) 1);
  
  return 0;
}
コード例 #7
0
ファイル: aCalcoutRecord.c プロジェクト: ukaea/epics
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);
}
コード例 #8
0
ファイル: digitelRecord.c プロジェクト: epicsdeb/synapps
/*****************************************************************************
 *
 * This function is called before and after any field that is labeled (SPC_MOD)
 * is altered by a dbPutfield().  The use of this function is to simply take
 * note of what fields have been altered since the last time the record was
 * processed.  The record of what fields have been altered is kept in
 * precord->flgs.
 *
 * A secondary purpose of this function is to clamp the limits of the
 * SP1, SP2, and SP3 setpoint and hysteresis fields.
 *
 ******************************************************************************/
static long special(DBADDR *paddr, int after)
{
    void *p;
    digitelRecord *pdg = (digitelRecord *) (paddr->precord);

    if (!after)
	return (0);

    if (recDigitelDebug >= 25)
	printf("recDigitel.c: special()\n");

    /*** Make sure we have the proper special flag type spec'd ***/
    if (paddr->special != SPC_MOD) {
	recGblDbaddrError(S_db_badChoice, paddr, "dg: special");
	return (S_db_badChoice);
    }
    p = (void *) (paddr->pfield);
    /*** Figure out which field has been changed ***/
    if (p == &(pdg->dspl)) {
	pdg->flgs |= MOD_DSPL;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< DSPL changed to %d\n", pdg->name, pdg->dspl);
    } else if (p == &(pdg->klck)) {
	pdg->flgs |= MOD_KLCK;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< KLCK changed to %d\n", pdg->name, pdg->klck);
    } else if (p == &(pdg->mods)) {
	pdg->flgs |= MOD_MODS;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< MODS changed to %d\n", pdg->name, pdg->mods);
    } else if (p == &(pdg->baks)) {
	pdg->flgs |= MOD_BAKE;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< BAKS changed to %d\n", pdg->name, pdg->baks);
    } else if (p == &(pdg->sp1s)) {
	if (pdg->sp1s > DIGITEL_MAXSP)
	    pdg->sp1s = DIGITEL_MAXSP;
	else if (pdg->sp1s < DIGITEL_MINSP)
	    pdg->sp1s = DIGITEL_MINSP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< SP1S changed to %e\n", pdg->name, pdg->sp1s);
	pdg->spfg |= MOD_SP1S;
	pdg->flgs |= MOD_SETP;
    } else if (p == &(pdg->s1hs)) {
	if (pdg->s1hs > DIGITEL_MAXHY)
	    pdg->s1hs = DIGITEL_MAXHY;
	else if (pdg->s1hs < DIGITEL_MINHY)
	    pdg->s1hs = DIGITEL_MINHY;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S1HS changed to %e\n", pdg->name, pdg->s1hs);
	pdg->spfg |= MOD_S1HS;
	pdg->flgs |= MOD_SETP;
    } else if (p == &(pdg->s1ms)) {
	pdg->spfg |= MOD_S1MS;
	pdg->flgs |= MOD_SETP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S1MS changed to %d\n", pdg->name, pdg->s1ms);
    } else if (p == &(pdg->s1vs)) {
	pdg->spfg |= MOD_S1VS;
	pdg->flgs |= MOD_SETP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S1VS changed to %d\n", pdg->name, pdg->s1vs);
    } else if (p == &(pdg->sp2s)) {
	if (pdg->sp2s > DIGITEL_MAXSP)
	    pdg->sp2s = DIGITEL_MAXSP;
	else if (pdg->sp2s < DIGITEL_MINSP)
	    pdg->sp2s = DIGITEL_MINSP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< SP2S changed to %e\n", pdg->name, pdg->sp2s);
	pdg->spfg |= MOD_SP2S;
	pdg->flgs |= MOD_SETP;
    } else if (p == &(pdg->s2hs)) {
	if (pdg->s2hs > DIGITEL_MAXHY)
	    pdg->s2hs = DIGITEL_MAXHY;
	else if (pdg->s2hs < DIGITEL_MINHY)
	    pdg->s2hs = DIGITEL_MINHY;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S2HS changed to %e\n", pdg->name, pdg->s2hs);
	pdg->spfg |= MOD_S2HS;
	pdg->flgs |= MOD_SETP;
    } else if (p == &(pdg->s2ms)) {
	pdg->spfg |= MOD_S2MS;
	pdg->flgs |= MOD_SETP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S2MS changed to %d\n", pdg->name, pdg->s2ms);
    } else if (p == &(pdg->s2vs)) {
	pdg->spfg |= MOD_S2VS;
	pdg->flgs |= MOD_SETP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S2VS changed to %d\n", pdg->name, pdg->s2vs);
    } else if (p == &(pdg->sp3s)) {
	if (pdg->sp3s > DIGITEL_MAXSP)
	    pdg->sp3s = DIGITEL_MAXSP;
	else if (pdg->sp3s < DIGITEL_MINSP)
	    pdg->sp3s = DIGITEL_MINSP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< SP3S changed to %e\n", pdg->name, pdg->sp3s);
	pdg->spfg |= MOD_SP3S;
	pdg->flgs |= MOD_SETP;
    } else if (p == &(pdg->s3hs)) {
	if (pdg->s3hs > DIGITEL_MAXHY)
	    pdg->s3hs = DIGITEL_MAXHY;
	else if (pdg->s3hs < DIGITEL_MINHY)
	    pdg->s3hs = DIGITEL_MINHY;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S3HS changed to %e\n", pdg->name, pdg->s3hs);
	pdg->spfg |= MOD_S3HS;
	pdg->flgs |= MOD_SETP;
    } else if (p == &(pdg->s3ms)) {
	pdg->spfg |= MOD_S3MS;
	pdg->flgs |= MOD_SETP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S3MS changed to %d\n", pdg->name, pdg->s3ms);
    } else if (p == &(pdg->s3vs)) {
	pdg->spfg |= MOD_S3VS;
	pdg->flgs |= MOD_SETP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S3VS changed to %d\n", pdg->name, pdg->s3vs);
    } else if (p == &(pdg->s3bs)) {
	pdg->spfg |= MOD_S3BS;
	pdg->flgs |= MOD_SETP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S3BS changed to %d\n", pdg->name, pdg->s3bs);
    } else if (p == &(pdg->s3ts)) {
	pdg->spfg |= MOD_S3TS;
	pdg->flgs |= MOD_SETP;
	if (recDigitelDebug >= 15)
	    printf("recDigitel.c: >%s< S3TS changed to %f\n", pdg->name, pdg->s3ts);
    }
    return (0);
}
コード例 #9
0
ファイル: calcoutRecord.c プロジェクト: epicsdeb/epics-base
static long special(DBADDR *paddr, int after)
{
    calcoutRecord *prec = (calcoutRecord *)paddr->precord;
    rpvtStruct  *prpvt = prec->rpvt;
    DBADDR      dbaddr;
    DBADDR      *pAddr = &dbaddr;
    short       error_number;
    int         fieldIndex = dbGetFieldIndex(paddr);
    int         lnkIndex;
    DBLINK      *plink;
    double      *pvalue;
    epicsEnum16 *plinkValid;

    if (!after) return 0;
    switch(fieldIndex) {
      case(calcoutRecordCALC):
        prec->clcv = postfix(prec->calc, prec->rpcl, &error_number);
        if (prec->clcv){
            recGblRecordError(S_db_badField, (void *)prec,
                      "calcout: special(): Illegal CALC field");
            errlogPrintf("%s.CALC: %s in expression \"%s\"\n",
                         prec->name, calcErrorStr(error_number), prec->calc);
        }
        db_post_events(prec, &prec->clcv, DBE_VALUE);
        return 0;

      case(calcoutRecordOCAL):
        prec->oclv = postfix(prec->ocal, prec->orpc, &error_number);
        if (prec->dopt == calcoutDOPT_Use_OVAL && prec->oclv){
            recGblRecordError(S_db_badField, (void *)prec,
                    "calcout: special(): Illegal OCAL field");
            errlogPrintf("%s.OCAL: %s in expression \"%s\"\n",
                         prec->name, calcErrorStr(error_number), prec->ocal);
        }
        db_post_events(prec, &prec->oclv, DBE_VALUE);
        return 0;
      case(calcoutRecordINPA):
      case(calcoutRecordINPB):
      case(calcoutRecordINPC):
      case(calcoutRecordINPD):
      case(calcoutRecordINPE):
      case(calcoutRecordINPF):
      case(calcoutRecordINPG):
      case(calcoutRecordINPH):
      case(calcoutRecordINPI):
      case(calcoutRecordINPJ):
      case(calcoutRecordINPK):
      case(calcoutRecordINPL):
      case(calcoutRecordOUT):
        lnkIndex = fieldIndex - calcoutRecordINPA;
        plink   = &prec->inpa + lnkIndex;
        pvalue  = &prec->a    + lnkIndex;
        plinkValid = &prec->inav + lnkIndex;
        if (plink->type == CONSTANT) {
            if (fieldIndex != calcoutRecordOUT) {
                recGblInitConstantLink(plink, DBF_DOUBLE, pvalue);
                db_post_events(prec, pvalue, DBE_VALUE);
            }
            *plinkValid = calcoutINAV_CON;
        } else if (!dbNameToAddr(plink->value.pv_link.pvname, pAddr)) {
            /* if the PV resides on this ioc */
            *plinkValid = calcoutINAV_LOC;
        } else {
            /* pv is not on this ioc. Callback later for connection stat */
            *plinkValid = calcoutINAV_EXT_NC;
            /* DO_CALLBACK, if not already scheduled */
            if (!prpvt->cbScheduled) {
                callbackRequestDelayed(&prpvt->checkLinkCb, .5);
                prpvt->cbScheduled = 1;
                prpvt->caLinkStat = CA_LINKS_NOT_OK;
            }
        }
        db_post_events(prec, plinkValid, DBE_VALUE);
        return 0;
      case(calcoutRecordOEVT):
        prec->epvt = eventNameToHandle(prec->oevt);
        return 0;
      default:
        recGblDbaddrError(S_db_badChoice, paddr, "calc: special");
        return(S_db_badChoice);
    }
}
コード例 #10
0
ファイル: dbAccess.c プロジェクト: ukaea/epics
long dbGet(DBADDR *paddr, short dbrType,
    void *pbuffer, long *options, long *nRequest, void *pflin)
{
    char *pbuf = pbuffer;
    void *pfieldsave = paddr->pfield;
    db_field_log *pfl = (db_field_log *)pflin;
    short field_type;
    long capacity, no_elements, offset;
    struct rset *prset;
    long status = 0;

    if (options && *options)
        getOptions(paddr, &pbuf, options, pflin);
    if (nRequest && *nRequest == 0)
        return 0;

    if (!pfl || pfl->type == dbfl_type_rec) {
        field_type = paddr->field_type;
        no_elements = capacity = paddr->no_elements;

        /* Update field info from record
         * may modify paddr->pfield
         */
        if (paddr->pfldDes->special == SPC_DBADDR &&
            (prset = dbGetRset(paddr)) &&
            prset->get_array_info) {
            status = prset->get_array_info(paddr, &no_elements, &offset);
        } else
            offset = 0;
    } else {
        field_type = pfl->field_type;
        no_elements = capacity = pfl->no_elements;
        offset = 0;
    }

    if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) {
        status = getLinkValue(paddr, dbrType, pbuf, nRequest);
        goto done;
    }

    if (paddr->special == SPC_ATTRIBUTE) {
        status = getAttrValue(paddr, dbrType, pbuf, nRequest);
        goto done;
    }

    /* Check for valid request */
    if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbGet: Request type is %d\n", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        status = S_db_badDbrtype;
        goto done;
    }

    if (offset == 0 && (!nRequest || no_elements == 1)) {
        if (nRequest)
            *nRequest = 1;
        if (!pfl || pfl->type == dbfl_type_rec) {
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (paddr->pfield, pbuf, paddr);
        } else {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.field_type = pfl->field_type;
            localAddr.field_size = pfl->field_size;
            localAddr.no_elements = pfl->no_elements;
            if (pfl->type == dbfl_type_val)
                localAddr.pfield = (char *) &pfl->u.v.field;
            else
                localAddr.pfield = (char *)  pfl->u.r.field;
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (localAddr.pfield, pbuf, &localAddr);
        }
    } else {
        long n;
        GETCONVERTFUNC convert;

        if (nRequest) {
            if (no_elements < *nRequest)
                *nRequest = no_elements;
            n = *nRequest;
        } else {
            n = 1;
        }
        convert = dbGetConvertRoutine[field_type][dbrType];
        if (!convert) {
            char message[80];

            sprintf(message, "dbGet: Missing conversion for [%d][%d]\n",
                    field_type, dbrType);
            recGblDbaddrError(S_db_badDbrtype, paddr, message);
            status = S_db_badDbrtype;
            goto done;
        }
        /* convert data into the caller's buffer */
        if (n <= 0) {
            ;/*do nothing*/
        } else if (!pfl || pfl->type == dbfl_type_rec) {
            status = convert(paddr, pbuf, n, capacity, offset);
        } else {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.field_type = pfl->field_type;
            localAddr.field_size = pfl->field_size;
            localAddr.no_elements = pfl->no_elements;
            if (pfl->type == dbfl_type_val)
                localAddr.pfield = (char *) &pfl->u.v.field;
            else
                localAddr.pfield = (char *)  pfl->u.r.field;
            status = convert(&localAddr, pbuf, n, capacity, offset);
        }
    }
done:
    paddr->pfield = pfieldsave;
    return status;
}
コード例 #11
0
ファイル: dbAccess.c プロジェクト: ukaea/epics
long dbPut(DBADDR *paddr, short dbrType,
    const void *pbuffer, long nRequest)
{
    dbCommon *precord = paddr->precord;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long special      = paddr->special;
    void *pfieldsave  = paddr->pfield;
    struct rset *prset = dbGetRset(paddr);
    long status = 0;
    long offset;
    dbFldDes *pfldDes;
    int isValueField;

    if (special == SPC_ATTRIBUTE)
        return S_db_noMod;

    if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) {
        return putAckt(paddr, pbuffer, 1, 1, 0);
    } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) {
        return putAcks(paddr, pbuffer, 1, 1, 0);
    } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbPut: Request type is %d", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    if (special) {
        status = dbPutSpecial(paddr, 0);
        if (status) return status;
    }

    if (paddr->pfldDes->special == SPC_DBADDR &&
        prset && prset->get_array_info) {
        long dummy;

        status = prset->get_array_info(paddr, &dummy, &offset);
        /* paddr->pfield may be modified */
        if (status) goto done;
    } else
        offset = 0;

    if (no_elements <= 1) {
        status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
            paddr->pfield, paddr);
        nRequest = 1;
    } else {
        if (no_elements < nRequest)
            nRequest = no_elements;
        status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
            nRequest, no_elements, offset);
    }

    /* update array info */
    if (!status &&
        paddr->pfldDes->special == SPC_DBADDR &&
        prset && prset->put_array_info) {
        status = prset->put_array_info(paddr, nRequest);
    }

    /* Always do special processing if needed */
    if (special) {
        long status2 = dbPutSpecial(paddr, 1);
        if (status2) goto done;
    }
    if (status) goto done;

    /* Propagate monitor events for this field, */
    /* unless the field is VAL and PP is true. */
    pfldDes = paddr->pfldDes;
    isValueField = dbIsValueField(pfldDes);
    if (isValueField) precord->udf = FALSE;
    if (precord->mlis.count &&
        !(isValueField && pfldDes->process_passive))
        db_post_events(precord, pfieldsave, DBE_VALUE | DBE_LOG);
    /* If this field is a property (metadata) field,
     * then post a property change event (even if the field
     * didn't change).
     */
    if (precord->mlis.count && pfldDes->prop)
        db_post_events(precord, NULL, DBE_PROPERTY);
done:
    paddr->pfield = pfieldsave;
    return status;
}
コード例 #12
0
ファイル: dbAccess.c プロジェクト: T-A-R-L-A/EPICS-Base
long epicsShareAPI dbGet(DBADDR *paddr, short dbrType,
    void *pbuffer, long *options, long *nRequest, void *pflin)
{
    db_field_log *pfl = (db_field_log *)pflin;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long offset;
    struct rset *prset;
    long status = 0;

    if (options && *options) {
        char *pbuf = pbuffer;

        getOptions(paddr, &pbuf, options, pflin);
        pbuffer = pbuf;
    }
    if (nRequest && *nRequest == 0) return 0;

    if (paddr->special == SPC_ATTRIBUTE) {
        char *pbuf = pbuffer;
        int maxlen;

        if (!paddr->pfield) return S_db_badField;

        switch (dbrType) {
        case DBR_STRING:
            maxlen = MAX_STRING_SIZE - 1;
            if (nRequest && *nRequest > 1) *nRequest = 1;
            break;

        case DBR_CHAR:
        case DBR_UCHAR:
            if (nRequest && *nRequest > 0) {
                maxlen = *nRequest - 1;
                break;
            }
            /* else fall through ... */
        default:
            return S_db_badDbrtype;
        }

        strncpy(pbuf, (char *)paddr->pfield, maxlen);
        pbuf[maxlen] = 0;
        return 0;
    }

    /* Check for valid request */
    if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbGet: Request type is %d\n", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    /* check for array */
    if (paddr->special == SPC_DBADDR &&
        no_elements > 1 &&
        (prset = dbGetRset(paddr)) &&
        prset->get_array_info) {
        status = prset->get_array_info(paddr, &no_elements, &offset);
    } else
        offset = 0;

    if (offset == 0 && (!nRequest || no_elements == 1)) {
        if (nRequest) *nRequest = 1;
        if (pfl != NULL) {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.pfield = (char *)&pfl->field;
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (localAddr.pfield, pbuffer, &localAddr);
        } else {
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (paddr->pfield, pbuffer, paddr);
        }
    } else {
        long n;
        long (*convert)();

        if (nRequest) {
            if (no_elements<(*nRequest)) *nRequest = no_elements;
            n = *nRequest;
        } else {
            n = 1;
        }
        convert = dbGetConvertRoutine[field_type][dbrType];
        if (!convert) {
            char message[80];

            sprintf(message, "dbGet: Missing conversion for [%d][%d]\n",
                    field_type, dbrType);
            recGblDbaddrError(S_db_badDbrtype, paddr, message);
            return S_db_badDbrtype;
        }
        /* convert database field  and place it in the buffer */
        if (n <= 0) {
            ;/*do nothing*/
        } else if (pfl) {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.pfield = (char *)&pfl->field;
            status = convert(&localAddr, pbuffer, n, no_elements, offset);
        } else {
            status = convert(paddr, pbuffer, n, no_elements, offset);
        }
    }
    return status;
}
コード例 #13
0
ファイル: dbAccess.c プロジェクト: T-A-R-L-A/EPICS-Base
long epicsShareAPI dbPut(DBADDR *paddr, short dbrType,
    const void *pbuffer, long nRequest)
{
    dbCommon *precord = paddr->precord;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long special      = paddr->special;
    long offset;
    long status = 0;
    dbFldDes *pfldDes;
    int isValueField;

    if (special == SPC_ATTRIBUTE) return S_db_noMod;

    if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) {
        return putAckt(paddr, (unsigned short *)pbuffer, 1, 1, 0);
    } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) {
        return putAcks(paddr, (unsigned short *)pbuffer, 1, 1, 0);
    } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbPut: Request type is %d", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    if (special) {
        status = dbPutSpecial(paddr, 0);
        if (status) return status;
    }

    if (no_elements <= 1) {
        status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
            paddr->pfield, paddr);
    } else {
        struct rset *prset = dbGetRset(paddr);

        if (paddr->special == SPC_DBADDR &&
            prset && prset->get_array_info) {
            long dummy;

            status = prset->get_array_info(paddr, &dummy, &offset);
        }
        else
            offset = 0;
        if (no_elements < nRequest) nRequest = no_elements;
        if (!status)
            status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
                nRequest, no_elements, offset);

        /* update array info */
        if (!status &&
            paddr->special == SPC_DBADDR &&
            prset && prset->put_array_info) {
            status = prset->put_array_info(paddr, nRequest);
        }
    }
    if (status) return status;

    /* check if special processing is required */
    if (special) {
        status = dbPutSpecial(paddr,1);
        if (status) return status;
    }

    /* Propagate monitor events for this field, */
    /* unless the field field is VAL and PP is true. */
    pfldDes = paddr->pfldDes;
    isValueField = dbIsValueField(pfldDes);
    if (isValueField) precord->udf = FALSE;
    if (precord->mlis.count &&
        !(isValueField && pfldDes->process_passive))
        db_post_events(precord, paddr->pfield, DBE_VALUE | DBE_LOG);

    return status;
}