g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  Index 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014 
<== Date ==> <== Thread ==>

Subject: [Merge] lp:~dirk.zimoch/epics-base/non-val-attributes into lp:epics-base
From: Dirk Zimoch <dirk.zimoch@psi.ch>
To: mp+26189@code.launchpad.net
Date: Thu, 27 May 2010 15:14:25 -0000
Dirk Zimoch has proposed merging lp:~dirk.zimoch/epics-base/non-val-attributes into lp:epics-base.

Requested reviews:
  EPICS Core Developers (epics-core)


The attributes (units, precision, graphic and control limits) of non-VAL fields used to be mainly nonsense.

Now EGU and PREC are used only for VAL-equivalent fields (i.e.VAL, OVAL, HOPR, LOPR,...). (The histogram record is an exception as it uses units and precision on its input, not on the VAL field, which is an array of counters.)
Records with variable type (->FTVL) now ignore EGU for the VAL field when using STRING or ENUM types.

All delay fields (bo.HIGH, seq.DLYn, calcout.ODLY) now report precision=2, units="s", graphic limits=0...10.

Calc-like records with many inputs of probably different units and precisions (calc, calcout, sub, aSub, seq) now fetch the attributes of these values (A...L, LA...LL) from the corresponding INPn link (aSub.VALn from the corresponding OUTn link). Constant links get precision and units from PREC and EGU if possible, precision=15 and units="" otherwise.

Discussion and future work:
* Set the severity and status attributes only on the VAL field?
* Should SPC_NOMOD fields report Nan for control limits?
* Precision is limited to 0...15 for most double fields except VAL. Remove this feature and trust the user?
* Implement common code for similar records (like base classes). This might involve re-ordering of the fields and may expand the number of similar inputs to a common number for calc-like records. This is probably a separate work package.
-- 
https://code.launchpad.net/~dirk.zimoch/epics-base/non-val-attributes/+merge/26189
Your team EPICS Core Developers is requested to review the proposed merge of lp:~dirk.zimoch/epics-base/non-val-attributes into lp:epics-base.
=== modified file 'src/rec/aSubRecord.c'
--- src/rec/aSubRecord.c	2010-04-20 22:13:54 +0000
+++ src/rec/aSubRecord.c	2010-05-27 15:14:24 +0000
@@ -53,14 +53,14 @@
 static long cvt_dbaddr(DBADDR *);
 static long get_array_info(DBADDR *, long *, long *);
 static long put_array_info(DBADDR *, long );
-#define get_units          NULL
+static long get_units(DBADDR *, char *);
 static long get_precision(DBADDR *, long *);
 #define get_enum_str       NULL
 #define get_enum_strs      NULL
 #define put_enum_str       NULL
-#define get_graphic_double NULL
-#define get_control_double NULL
-#define get_alarm_double   NULL
+static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
+static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
 
 rset aSubRSET = {
     RSETNUMBER,
@@ -330,15 +330,116 @@
     return 0;
 }
 
-static long get_precision(DBADDR *paddr, long *precision)
-{
-    aSubRecord *prec = (aSubRecord *)paddr->precord;
-
-    *precision = prec->prec;
-    recGblGetPrec(paddr, precision);
-    return 0;
-}
-
+#define indexof(field) aSubRecord##field
+
+static long get_inlinkNumber(int fieldIndex) {
+    if (fieldIndex >= indexof(A) && fieldIndex <= indexof(U))
+        return fieldIndex - indexof(A);
+    return -1;
+}
+
+static long get_outlinkNumber(int fieldIndex) {
+    if (fieldIndex >= indexof(VALA) && fieldIndex <= indexof(VALU))
+        return fieldIndex - indexof(VALA);
+    return -1;
+}
+
+static long get_units(DBADDR *paddr, char *units)
+{
+    aSubRecord *prec = (aSubRecord *)paddr->precord;
+    int linkNumber;
+
+    linkNumber = get_inlinkNumber(dbGetFieldIndex(paddr));
+    if (linkNumber >= 0) {
+        dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
+        return 0;
+    }
+    linkNumber = get_outlinkNumber(dbGetFieldIndex(paddr));
+    if (linkNumber >= 0) {
+        dbGetUnits(&prec->outa + linkNumber, units, DB_UNITS_SIZE);
+    }
+    return 0;
+}
+
+static long get_precision(DBADDR *paddr, long *pprecision)
+{
+    aSubRecord *prec = (aSubRecord *)paddr->precord;
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
+    short precision;
+
+    *pprecision = prec->prec;
+    linkNumber = get_inlinkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
+            *pprecision = precision;
+        return 0;
+    } 
+    linkNumber = get_outlinkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        if (dbGetPrecision(&prec->outa + linkNumber, &precision) == 0)
+            *pprecision = precision;
+        return 0;
+    } 
+    recGblGetPrec(paddr, pprecision);
+    return 0;
+}
+
+static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
+{
+    aSubRecord *prec = (aSubRecord *)paddr->precord;
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
+    
+    linkNumber = get_inlinkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        dbGetGraphicLimits(&prec->inpa + linkNumber,
+            &pgd->lower_disp_limit,
+            &pgd->upper_disp_limit);
+        return 0;
+    }
+    linkNumber = get_outlinkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        dbGetGraphicLimits(&prec->outa + linkNumber,
+            &pgd->lower_disp_limit,
+            &pgd->upper_disp_limit);
+    }
+    return 0;
+}
+
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
+{
+    recGblGetControlDouble(paddr,pcd);
+    return 0;
+}
+
+static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
+{
+    aSubRecord *prec = (aSubRecord *)paddr->precord;
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
+
+    linkNumber = get_inlinkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        dbGetAlarmLimits(&prec->inpa + linkNumber,
+            &pad->lower_alarm_limit,
+            &pad->lower_warning_limit,
+            &pad->upper_warning_limit,
+            &pad->upper_alarm_limit);
+        return 0;
+    }
+    linkNumber = get_outlinkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        dbGetAlarmLimits(&prec->outa + linkNumber,
+            &pad->lower_alarm_limit,
+            &pad->lower_warning_limit,
+            &pad->upper_warning_limit,
+            &pad->upper_alarm_limit);
+        return 0;
+    }
+    recGblGetAlarmDouble(paddr, pad);
+    return 0;
+}
 
 static void monitor(aSubRecord *prec)
 {

=== modified file 'src/rec/aaiRecord.c'
--- src/rec/aaiRecord.c	2009-07-08 18:14:11 +0000
+++ src/rec/aaiRecord.c	2010-05-27 15:14:24 +0000
@@ -191,11 +191,20 @@
     return 0;
 }
 
+#define indexof(field) aaiRecord##field
+
 static long get_units(DBADDR *paddr, char *units)
 {
     aaiRecord *prec = (aaiRecord *)paddr->precord;
 
-    strncpy(units, prec->egu, DB_UNITS_SIZE);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
+                break; 
+        case indexof(HOPR):
+        case indexof(LOPR):
+            strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return 0;
 }
 
@@ -204,8 +213,8 @@
     aaiRecord *prec = (aaiRecord *)paddr->precord;
 
     *precision = prec->prec;
-    if (paddr->pfield == (void *)prec->bptr) return 0;
-    recGblGetPrec(paddr, precision);
+    if (dbGetFieldIndex(paddr) != indexof(VAL))
+        recGblGetPrec(paddr, precision);
     return 0;
 }
 
@@ -213,10 +222,18 @@
 {
     aaiRecord *prec = (aaiRecord *)paddr->precord;
 
-    if (paddr->pfield == (void *)prec->bptr) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr, pgd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        case indexof(NORD):
+            pgd->upper_disp_limit = prec->nelm;
+            pgd->lower_disp_limit = 0;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr, pgd);
+    }
     return 0;
 }
 
@@ -224,10 +241,18 @@
 {
     aaiRecord *prec = (aaiRecord *)paddr->precord;
 
-    if (paddr->pfield == (void *)prec->bptr) {
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-    } else recGblGetControlDouble(paddr, pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            pcd->upper_ctrl_limit = prec->hopr;
+            pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        case indexof(NORD):
+            pcd->upper_ctrl_limit = prec->nelm;
+            pcd->lower_ctrl_limit = 0;
+            break;
+        default:
+            recGblGetControlDouble(paddr, pcd);
+    }
     return 0;
 }
 

=== modified file 'src/rec/aaoRecord.c'
--- src/rec/aaoRecord.c	2009-07-08 18:14:11 +0000
+++ src/rec/aaoRecord.c	2010-05-27 15:14:24 +0000
@@ -188,11 +188,20 @@
     return 0;
 }
 
+#define indexof(field) aaoRecord##field
+
 static long get_units(DBADDR *paddr, char *units)
 {
     aaoRecord *prec = (aaoRecord *)paddr->precord;
 
-    strncpy(units, prec->egu, DB_UNITS_SIZE);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
+                break; 
+        case indexof(HOPR):
+        case indexof(LOPR):
+            strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return 0;
 }
 
@@ -201,8 +210,8 @@
     aaoRecord *prec = (aaoRecord *)paddr->precord;
 
     *precision = prec->prec;
-    if (paddr->pfield == (void *)prec->bptr) return 0;
-    recGblGetPrec(paddr, precision);
+    if (dbGetFieldIndex(paddr) != indexof(VAL))
+        recGblGetPrec(paddr, precision);
     return 0;
 }
 
@@ -210,10 +219,18 @@
 {
     aaoRecord *prec = (aaoRecord *)paddr->precord;
 
-    if (paddr->pfield == (void *)prec->bptr) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr,pgd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        case indexof(NORD):
+            pgd->upper_disp_limit = prec->nelm;
+            pgd->lower_disp_limit = 0;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr, pgd);
+    }
     return 0;
 }
 
@@ -221,10 +238,18 @@
 {
     aaoRecord *prec = (aaoRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)prec->bptr){
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-    } else recGblGetControlDouble(paddr,pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            pcd->upper_ctrl_limit = prec->hopr;
+            pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        case indexof(NORD):
+            pcd->upper_ctrl_limit = prec->nelm;
+            pcd->lower_ctrl_limit = 0;
+            break;
+        default:
+            recGblGetControlDouble(paddr, pcd);
+    }
     return 0;
 }
 

=== modified file 'src/rec/aiRecord.c'
--- src/rec/aiRecord.c	2010-04-05 18:49:18 +0000
+++ src/rec/aiRecord.c	2010-05-27 15:14:24 +0000
@@ -217,11 +217,22 @@
     }
 }
 
+#define indexof(field) aiRecord##field
+
 static long get_units(DBADDR *paddr, char *units)
 {
     aiRecord	*prec=(aiRecord *)paddr->precord;
 
-    strncpy(units,prec->egu,DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+        switch (dbGetFieldIndex(paddr)) {
+            case indexof(ASLO):
+            case indexof(AOFF):
+            case indexof(SMOO):
+                break;
+            default:
+                strncpy(units,prec->egu,DB_UNITS_SIZE);
+        }
+    }
     return(0);
 }
 
@@ -230,7 +241,7 @@
     aiRecord	*prec=(aiRecord *)paddr->precord;
 
     *precision = prec->prec;
-    if(paddr->pfield == (void *)&prec->val) return(0);
+    if (dbGetFieldIndex(paddr) == indexof(VAL)) return(0);
     recGblGetPrec(paddr,precision);
     return(0);
 }
@@ -238,43 +249,54 @@
 static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
 {
     aiRecord	*prec=(aiRecord *)paddr->precord;
-    int		fieldIndex = dbGetFieldIndex(paddr);
 
-    if(fieldIndex == aiRecordVAL
-    || fieldIndex == aiRecordHIHI
-    || fieldIndex == aiRecordHIGH
-    || fieldIndex == aiRecordLOW
-    || fieldIndex == aiRecordLOLO
-    || fieldIndex == aiRecordHOPR
-    || fieldIndex == aiRecordLOPR) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr,pgd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+        case indexof(SVAL):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr,pgd);
+    }
     return(0);
 }
 
 static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
 {
     aiRecord	*prec=(aiRecord *)paddr->precord;
-    int		fieldIndex = dbGetFieldIndex(paddr);
 
-    if(fieldIndex == aiRecordVAL
-    || fieldIndex == aiRecordHIHI
-    || fieldIndex == aiRecordHIGH
-    || fieldIndex == aiRecordLOW
-    || fieldIndex == aiRecordLOLO) {
-	pcd->upper_ctrl_limit = prec->hopr;
-	pcd->lower_ctrl_limit = prec->lopr;
-    } else recGblGetControlDouble(paddr,pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+        case indexof(SVAL):
+	    pcd->upper_ctrl_limit = prec->hopr;
+	    pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return(0);
 }
 
 static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
 {
     aiRecord	*prec=(aiRecord *)paddr->precord;
-    int		fieldIndex = dbGetFieldIndex(paddr);
 
-    if(fieldIndex == aiRecordVAL) {
+    if (dbGetFieldIndex(paddr) == indexof(VAL)) {
         pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
         pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
         pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;

=== modified file 'src/rec/aoRecord.c'
--- src/rec/aoRecord.c	2010-04-05 18:49:18 +0000
+++ src/rec/aoRecord.c	2010-05-27 15:14:24 +0000
@@ -276,11 +276,21 @@
     }
 }
 
+#define indexof(field) aoRecord##field
+
 static long get_units(DBADDR * paddr,char *units)
 {
     aoRecord	*prec=(aoRecord *)paddr->precord;
 
-    strncpy(units,prec->egu,DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+        switch (dbGetFieldIndex(paddr)) {
+            case indexof(ASLO):
+            case indexof(AOFF):
+                break;
+            default:
+                strncpy(units,prec->egu,DB_UNITS_SIZE);
+        }
+    }
     return(0);
 }
 
@@ -289,10 +299,14 @@
     aoRecord	*prec=(aoRecord *)paddr->precord;
 
     *precision = prec->prec;
-    if(paddr->pfield == (void *)&prec->val
-    || paddr->pfield == (void *)&prec->oval
-    || paddr->pfield == (void *)&prec->pval) return(0);
-    recGblGetPrec(paddr,precision);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(OVAL):
+        case indexof(PVAL):
+            break;
+        default:
+            recGblGetPrec(paddr,precision);
+    }
     return(0);
 }
 
@@ -300,16 +314,24 @@
 {
     aoRecord	*prec=(aoRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)&prec->val
-    || paddr->pfield==(void *)&prec->hihi
-    || paddr->pfield==(void *)&prec->high
-    || paddr->pfield==(void *)&prec->low
-    || paddr->pfield==(void *)&prec->lolo
-    || paddr->pfield==(void *)&prec->oval
-    || paddr->pfield==(void *)&prec->pval){
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr,pgd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(OVAL):
+        case indexof(PVAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+        case indexof(IVOV):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr,pgd);
+    }
     return(0);
 }
 
@@ -317,23 +339,30 @@
 {
     aoRecord	*prec=(aoRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)&prec->val
-    || paddr->pfield==(void *)&prec->hihi
-    || paddr->pfield==(void *)&prec->high
-    || paddr->pfield==(void *)&prec->low
-    || paddr->pfield==(void *)&prec->lolo
-    || paddr->pfield==(void *)&prec->oval
-    || paddr->pfield==(void *)&prec->pval){
-        pcd->upper_ctrl_limit = prec->drvh;
-        pcd->lower_ctrl_limit = prec->drvl;
-    } else recGblGetControlDouble(paddr,pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(OVAL):
+        case indexof(PVAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pcd->upper_ctrl_limit = prec->drvh;
+            pcd->lower_ctrl_limit = prec->drvl;
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return(0);
 }
 static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
 {
     aoRecord	*prec=(aoRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)&prec->val){
+    if(dbGetFieldIndex(paddr) == indexof(VAL)){
         pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
         pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
         pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;

=== modified file 'src/rec/boRecord.c'
--- src/rec/boRecord.c	2010-04-05 18:49:18 +0000
+++ src/rec/boRecord.c	2010-05-27 15:14:24 +0000
@@ -51,13 +51,13 @@
 #define cvt_dbaddr NULL
 #define get_array_info NULL
 #define put_array_info NULL
-#define get_units NULL
+static long get_units(DBADDR *, char *);
 static long get_precision(DBADDR *, long *);
 static long get_enum_str(DBADDR *, char *);
 static long get_enum_strs(DBADDR *, struct dbr_enumStrs *);
 static long put_enum_str(DBADDR *, char *);
 #define get_graphic_double NULL
-#define get_control_double NULL
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
 #define get_alarm_double NULL
 
 rset boRSET={
@@ -268,12 +268,31 @@
 	return(status);
 }
 
+#define indexof(field) boRecord##field
+
+static long get_units(DBADDR *paddr, char *units)
+{
+    if(dbGetFieldIndex(paddr) == indexof(HIGH))
+        strcpy(units, "s");
+    return(0);
+}
+
 static long get_precision(DBADDR *paddr, long *precision)
 {
-    boRecord	*prec=(boRecord *)paddr->precord;
+    if(dbGetFieldIndex(paddr) == indexof(HIGH))
+        *precision = 2;
+    else
+        recGblGetPrec(paddr,precision);
+    return(0);
+}
 
-    if(paddr->pfield == (void *)&prec->high) *precision=2;
-    else recGblGetPrec(paddr,precision);
+static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
+{
+    if(dbGetFieldIndex(paddr) == indexof(HIGH)) {
+        pcd->lower_ctrl_limit = 0.0;
+        pcd->upper_ctrl_limit = 10.0;
+    } else
+        recGblGetControlDouble(paddr,pcd);
     return(0);
 }
 
@@ -285,7 +304,7 @@
 
 
     index = dbGetFieldIndex(paddr);
-    if(index!=boRecordVAL) {
+    if(index!=indexof(VAL)) {
 	strcpy(pstring,"Illegal_Value");
     } else if(*pfield==0) {
 	strncpy(pstring,prec->znam,sizeof(prec->znam));

=== modified file 'src/rec/calcRecord.c'
--- src/rec/calcRecord.c	2009-04-03 14:40:13 +0000
+++ src/rec/calcRecord.c	2010-05-27 15:14:24 +0000
@@ -54,7 +54,7 @@
 #define get_enum_strs NULL
 #define put_enum_str NULL
 static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd);
-static long get_ctrl_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd);
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd);
 static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad);
 
 rset calcRSET={
@@ -74,7 +74,7 @@
 	get_enum_strs,
 	put_enum_str,
 	get_graphic_double,
-	get_ctrl_double,
+	get_control_double,
 	get_alarm_double
 };
 epicsExportAddress(rset, calcRSET);
@@ -148,97 +148,126 @@
     return S_db_badChoice;
 }
 
+#define indexof(field) calcRecord##field
+
+static long get_linkNumber(int fieldIndex) {
+    if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
+        return fieldIndex - indexof(A);
+    if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
+        return fieldIndex - indexof(LA);
+    return -1;
+}
+
 static long get_units(DBADDR *paddr, char *units)
 {
     calcRecord *prec = (calcRecord *)paddr->precord;
+    int linkNumber;
 
-    strncpy(units, prec->egu, DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+        linkNumber = get_linkNumber(dbGetFieldIndex(paddr));
+        if (linkNumber >= 0)
+            dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
+        else
+            strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return 0;
 }
 
 static long get_precision(DBADDR *paddr, long *pprecision)
 {
     calcRecord *prec = (calcRecord *)paddr->precord;
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
 
-    if (paddr->pfield == (void *)&prec->val) {
-	*pprecision = prec->prec;
-    } else {
-	recGblGetPrec(paddr, pprecision);
+    *pprecision = prec->prec;
+    if (fieldIndex == indexof(VAL)) {
+	return 0;
     }
+    linkNumber = get_linkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        short precision;
+        if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
+            *pprecision = precision;
+        else
+            *pprecision = 15;
+    } else
+        recGblGetPrec(paddr, pprecision);
     return 0;
 }
 
 static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
 {
     calcRecord *prec = (calcRecord *)paddr->precord;
-
-    if (paddr->pfield == (void *)&prec->val ||
-	paddr->pfield == (void *)&prec->hihi ||
-	paddr->pfield == (void *)&prec->high ||
-	paddr->pfield == (void *)&prec->low ||
-	paddr->pfield == (void *)&prec->lolo) {
-	pgd->upper_disp_limit = prec->hopr;
-	pgd->lower_disp_limit = prec->lopr;
-	return 0;
-    }
-
-    if (paddr->pfield >= (void *)&prec->a &&
-	paddr->pfield <= (void *)&prec->l) {
-	pgd->upper_disp_limit = prec->hopr;
-	pgd->lower_disp_limit = prec->lopr;
-	return 0;
-    }
-    if (paddr->pfield >= (void *)&prec->la &&
-	paddr->pfield <= (void *)&prec->ll) {
-	pgd->upper_disp_limit = prec->hopr;
-	pgd->lower_disp_limit = prec->lopr;
-	return 0;
-    }
-    recGblGetGraphicDouble(paddr, pgd);
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
+    
+    switch (fieldIndex) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pgd->lower_disp_limit = prec->lopr;
+            pgd->upper_disp_limit = prec->hopr;
+            break;
+        default:
+            linkNumber = get_linkNumber(fieldIndex);
+            if (linkNumber >= 0) {
+                dbGetGraphicLimits(&prec->inpa + linkNumber,
+                    &pgd->lower_disp_limit,
+                    &pgd->upper_disp_limit);
+            } else
+                recGblGetGraphicDouble(paddr,pgd);
+    }
     return 0;
 }
 
-static long get_ctrl_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
 {
     calcRecord *prec = (calcRecord *)paddr->precord;
-
-    if (paddr->pfield == (void *)&prec->val ||
-	paddr->pfield == (void *)&prec->hihi ||
-	paddr->pfield == (void *)&prec->high ||
-	paddr->pfield == (void *)&prec->low ||
-	paddr->pfield == (void *)&prec->lolo) {
-	pcd->upper_ctrl_limit = prec->hopr;
-	pcd->lower_ctrl_limit = prec->lopr;
-	return 0;
-    }
-
-    if (paddr->pfield >= (void *)&prec->a &&
-	paddr->pfield <= (void *)&prec->l) {
-	pcd->upper_ctrl_limit = prec->hopr;
-	pcd->lower_ctrl_limit = prec->lopr;
-	return 0;
-    }
-    if (paddr->pfield >= (void *)&prec->la &&
-	paddr->pfield <= (void *)&prec->ll) {
-	pcd->upper_ctrl_limit = prec->hopr;
-	pcd->lower_ctrl_limit = prec->lopr;
-	return 0;
-    }
-    recGblGetControlDouble(paddr, pcd);
+    
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pcd->lower_ctrl_limit = prec->lopr;
+            pcd->upper_ctrl_limit = prec->hopr;
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return 0;
 }
 
 static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
 {
     calcRecord *prec = (calcRecord *)paddr->precord;
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
 
-    if (paddr->pfield == (void *)&prec->val) {
+    if (fieldIndex == indexof(VAL)) {
+        pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
+        pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
+        pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
         pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
-        pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
-        pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
-        pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
     } else {
-	recGblGetAlarmDouble(paddr, pad);
+        linkNumber = get_linkNumber(fieldIndex);
+        if (linkNumber >= 0) {
+            dbGetAlarmLimits(&prec->inpa + linkNumber,
+                &pad->lower_alarm_limit,
+                &pad->lower_warning_limit,
+                &pad->upper_warning_limit,
+                &pad->upper_alarm_limit);
+        } else
+	    recGblGetAlarmDouble(paddr, pad);
     }
     return 0;
 }

=== modified file 'src/rec/calcoutRecord.c'
--- src/rec/calcoutRecord.c	2010-04-05 18:49:18 +0000
+++ src/rec/calcoutRecord.c	2010-05-27 15:14:24 +0000
@@ -59,7 +59,7 @@
 #define get_enum_strs NULL
 #define put_enum_str NULL
 static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
-static long get_ctrl_double(DBADDR *, struct dbr_ctrlDouble *);
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
 static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
 
 rset calcoutRSET = {
@@ -79,7 +79,7 @@
     get_enum_strs,
     put_enum_str,
     get_graphic_double,
-    get_ctrl_double,
+    get_control_double,
     get_alarm_double
 };
 epicsExportAddress(rset, calcoutRSET);
@@ -363,97 +363,144 @@
     }
 }
 
+#define indexof(field) calcoutRecord##field
+
+static long get_linkNumber(int fieldIndex) {
+    if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
+        return fieldIndex - indexof(A);
+    if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
+        return fieldIndex - indexof(LA);
+    return -1;
+}
+
 static long get_units(DBADDR *paddr, char *units)
 {
     calcoutRecord *prec = (calcoutRecord *)paddr->precord;
-
-    strncpy(units, prec->egu, DB_UNITS_SIZE);
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
+
+    if(fieldIndex == indexof(ODLY)) {
+        strcpy(units, "s");
+        return 0;
+    }
+
+    if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+        linkNumber = get_linkNumber(dbGetFieldIndex(paddr));
+        if (linkNumber >= 0)
+            dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
+        else
+            strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return 0;
 }
 
 static long get_precision(DBADDR *paddr, long *pprecision)
 {
     calcoutRecord *prec = (calcoutRecord *)paddr->precord;
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
 
-    if (paddr->pfield == (void *)&prec->val) {
-        *pprecision = prec->prec;
-    } else {
+    if(fieldIndex == indexof(ODLY)) {
+        *pprecision = 2;
+        return 0;
+    }
+    *pprecision = prec->prec;
+    if (fieldIndex == indexof(VAL)) {
+	return 0;
+    }
+    linkNumber = get_linkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        short precision;
+        if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
+            *pprecision = precision;
+        else
+            *pprecision = 15;
+    } else
         recGblGetPrec(paddr, pprecision);
-    }
     return 0;
 }
 
 static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
 {
     calcoutRecord *prec = (calcoutRecord *)paddr->precord;
-
-    if (paddr->pfield == (void *)&prec->val ||
-        paddr->pfield == (void *)&prec->hihi ||
-        paddr->pfield == (void *)&prec->high ||
-        paddr->pfield == (void *)&prec->low ||
-        paddr->pfield == (void *)&prec->lolo) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-        return 0;
-    }
-
-    if (paddr->pfield >= (void *)&prec->a &&
-        paddr->pfield <= (void *)&prec->l) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-        return 0;
-    }
-    if (paddr->pfield >= (void *)&prec->la &&
-        paddr->pfield <= (void *)&prec->ll) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-        return 0;
-    }
-    recGblGetGraphicDouble(paddr, pgd);
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
+    
+    switch (fieldIndex) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pgd->lower_disp_limit = prec->lopr;
+            pgd->upper_disp_limit = prec->hopr;
+            break;
+        case indexof(ODLY):
+            recGblGetGraphicDouble(paddr,pgd);
+            pgd->lower_disp_limit = 0.0;
+            break;       
+        default:
+            linkNumber = get_linkNumber(fieldIndex);
+            if (linkNumber >= 0) {
+                dbGetGraphicLimits(&prec->inpa + linkNumber,
+                    &pgd->lower_disp_limit,
+                    &pgd->upper_disp_limit);
+            } else
+                recGblGetGraphicDouble(paddr,pgd);
+    }
     return 0;
 }
 
-static long get_ctrl_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
 {
     calcoutRecord *prec = (calcoutRecord *)paddr->precord;
-
-    if (paddr->pfield == (void *)&prec->val ||
-        paddr->pfield == (void *)&prec->hihi ||
-        paddr->pfield == (void *)&prec->high ||
-        paddr->pfield == (void *)&prec->low ||
-        paddr->pfield == (void *)&prec->lolo) {
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-        return 0;
-    }
-
-    if (paddr->pfield >= (void *)&prec->a &&
-        paddr->pfield <= (void *)&prec->l) {
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-        return 0;
-    }
-    if (paddr->pfield >= (void *)&prec->la &&
-        paddr->pfield <= (void *)&prec->ll) {
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-        return 0;
-    }
-    recGblGetControlDouble(paddr, pcd);
+    
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pcd->lower_ctrl_limit = prec->lopr;
+            pcd->upper_ctrl_limit = prec->hopr;
+            break;
+        case indexof(ODLY):
+            pcd->lower_ctrl_limit = 0.0;
+            pcd->upper_ctrl_limit = 10.0;
+            break;       
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return 0;
 }
 
 static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
 {
     calcoutRecord *prec = (calcoutRecord *)paddr->precord;
+    int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
 
-    if (paddr->pfield == (void *)&prec->val) {
+    if (fieldIndex == indexof(VAL)) {
         pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
         pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
         pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
         pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
     } else {
-        recGblGetAlarmDouble(paddr, pad);
+        linkNumber = get_linkNumber(fieldIndex);
+        if (linkNumber >= 0) {
+            dbGetAlarmLimits(&prec->inpa + linkNumber,
+                &pad->lower_alarm_limit,
+                &pad->lower_warning_limit,
+                &pad->upper_warning_limit,
+                &pad->upper_alarm_limit);
+        } else
+	    recGblGetAlarmDouble(paddr, pad);
     }
     return 0;
 }

=== modified file 'src/rec/compressRecord.c'
--- src/rec/compressRecord.c	2010-04-02 21:26:17 +0000
+++ src/rec/compressRecord.c	2010-05-27 15:14:24 +0000
@@ -398,11 +398,16 @@
     return(0);
 }
 
+#define indexof(field) compressRecord##field
+
 static long get_units(DBADDR *paddr,char *units)
 {
     compressRecord *prec=(compressRecord *)paddr->precord;
 
-    strncpy(units,prec->egu,DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_DOUBLE
+    || dbGetFieldIndex(paddr) == indexof(VAL)) {
+        strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return(0);
 }
 
@@ -411,7 +416,7 @@
     compressRecord	*prec=(compressRecord *)paddr->precord;
 
     *precision = prec->prec;
-    if(paddr->pfield == (void *)prec->bptr) return(0);
+    if(dbGetFieldIndex(paddr) == indexof(BPTR)) return(0);
     recGblGetPrec(paddr,precision);
     return(0);
 }
@@ -420,12 +425,16 @@
 {
     compressRecord *prec=(compressRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)prec->bptr
-    || paddr->pfield==(void *)&prec->ihil
-    || paddr->pfield==(void *)&prec->ilil){
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr,pgd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(BPTR):
+        case indexof(IHIL):
+        case indexof(ILIL):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr,pgd);
+    }
     return(0);
 }
 
@@ -433,11 +442,15 @@
 {
     compressRecord *prec=(compressRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)prec->bptr
-    || paddr->pfield==(void *)&prec->ihil
-    || paddr->pfield==(void *)&prec->ilil){
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-    } else recGblGetControlDouble(paddr,pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(BPTR):
+        case indexof(IHIL):
+        case indexof(ILIL):
+            pcd->upper_ctrl_limit = prec->hopr;
+            pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return(0);
 }

=== modified file 'src/rec/dfanoutRecord.c'
--- src/rec/dfanoutRecord.c	2009-04-03 14:40:13 +0000
+++ src/rec/dfanoutRecord.c	2010-05-27 15:14:24 +0000
@@ -126,73 +126,72 @@
     return(status);
 }
 
+#define indexof(field) dfanoutRecord##field
+
 static long get_units(DBADDR *paddr,char *units)
 {
     dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
 
-    strncpy(units,prec->egu,DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+        strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return(0);
 }
 
 static long get_precision(DBADDR *paddr,long *precision)
 {
     dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
-    int   fieldIndex = dbGetFieldIndex(paddr);
-
-    if(fieldIndex == dfanoutRecordVAL
-    || fieldIndex == dfanoutRecordHIHI
-    || fieldIndex == dfanoutRecordHIGH
-    || fieldIndex == dfanoutRecordLOW
-    || fieldIndex == dfanoutRecordLOLO
-    || fieldIndex == dfanoutRecordHOPR
-    || fieldIndex == dfanoutRecordLOPR) {
-        *precision = prec->prec;
-    } else {
-        recGblGetPrec(paddr,precision);
+
+    *precision = prec->prec;
+    if (dbGetFieldIndex(paddr) == indexof(VAL)) return(0);
+    recGblGetPrec(paddr,precision);
+    return(0);
+}
+
+static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
+{
+    dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
+
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr,pgd);
     }
     return(0);
 }
 
-static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble	*pgd)
-{
-    dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
-    int   fieldIndex = dbGetFieldIndex(paddr);
-
-    if(fieldIndex == dfanoutRecordVAL
-    || fieldIndex == dfanoutRecordHIHI
-    || fieldIndex == dfanoutRecordHIGH
-    || fieldIndex == dfanoutRecordLOW
-    || fieldIndex == dfanoutRecordLOLO
-    || fieldIndex == dfanoutRecordHOPR
-    || fieldIndex == dfanoutRecordLOPR) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr,pgd);
-    return(0);
-}
-
 static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
 {
     dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
-    int   fieldIndex = dbGetFieldIndex(paddr);
 
-    if(fieldIndex == dfanoutRecordVAL
-    || fieldIndex == dfanoutRecordHIHI
-    || fieldIndex == dfanoutRecordHIGH
-    || fieldIndex == dfanoutRecordLOW
-    || fieldIndex == dfanoutRecordLOLO) {
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-    } else recGblGetControlDouble(paddr,pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+	    pcd->upper_ctrl_limit = prec->hopr;
+	    pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return(0);
 }
 static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
 {
     dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
-    int   fieldIndex = dbGetFieldIndex(paddr);
-
     
-    if(fieldIndex == dfanoutRecordVAL) {
+    if(dbGetFieldIndex(paddr) == indexof(VAL)) {
         pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
         pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
         pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;

=== modified file 'src/rec/histogramRecord.c'
--- src/rec/histogramRecord.c	2009-07-08 18:14:11 +0000
+++ src/rec/histogramRecord.c	2010-05-27 15:14:24 +0000
@@ -52,7 +52,7 @@
 static long cvt_dbaddr(DBADDR *);
 static long get_array_info(DBADDR *, long *, long *);
 #define  put_array_info NULL
-#define get_units NULL
+static long get_units(DBADDR *, char *);
 static long get_precision(DBADDR *paddr,long *precision);
 #define get_enum_str NULL
 #define get_enum_strs NULL
@@ -386,42 +386,71 @@
         return(status);
 }
 
+#define indexof(field) histogramRecord##field
+
+static long get_units(DBADDR *paddr, char *units)
+{
+    if (dbGetFieldIndex(paddr) == indexof(SDEL)) {
+        strcpy(units,"s");
+    }
+    /* We should have EGU for other DOUBLE values or probably get it from input link SVL */
+    return(0);
+}
+
 static long get_precision(DBADDR *paddr,long *precision)
 {
     histogramRecord *prec=(histogramRecord *)paddr->precord;
-    int     fieldIndex = dbGetFieldIndex(paddr);
 
-    *precision = prec->prec;
-    if(fieldIndex == histogramRecordULIM
-    || fieldIndex == histogramRecordLLIM
-    || fieldIndex == histogramRecordSDEL
-    || fieldIndex == histogramRecordSGNL
-    || fieldIndex == histogramRecordSVAL
-    || fieldIndex == histogramRecordWDTH) {
-       *precision = prec->prec;
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(ULIM):
+        case indexof(LLIM):
+        case indexof(SGNL):
+        case indexof(SVAL):
+        case indexof(WDTH):
+            *precision = prec->prec;
+            break;
+        case indexof(SDEL):
+            *precision = 2;
+            break;
+        default:
+            recGblGetPrec(paddr,precision);
     }
-    recGblGetPrec(paddr,precision);
     return(0);
 }
+
 static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
 {
     histogramRecord *prec=(histogramRecord *)paddr->precord;
-    int     fieldIndex = dbGetFieldIndex(paddr);
 
-    if(fieldIndex == histogramRecordBPTR){
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr,pgd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(BPTR):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        case indexof(WDTH):
+            pgd->upper_disp_limit = prec->ulim-prec->llim;
+            pgd->lower_disp_limit = 0.0;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr,pgd);
+    }
     return(0);
 }
 static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
 {
     histogramRecord *prec=(histogramRecord *)paddr->precord;
-    int     fieldIndex = dbGetFieldIndex(paddr);
 
-    if(fieldIndex == histogramRecordBPTR){
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-    } else recGblGetControlDouble(paddr,pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(BPTR):
+            pcd->upper_ctrl_limit = prec->hopr;
+            pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        case indexof(WDTH):
+            pcd->upper_ctrl_limit = prec->ulim-prec->llim;
+            pcd->lower_ctrl_limit = 0.0;
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return(0);
 }

=== modified file 'src/rec/longinRecord.c'
--- src/rec/longinRecord.c	2010-04-05 18:49:18 +0000
+++ src/rec/longinRecord.c	2010-05-27 15:14:24 +0000
@@ -158,11 +158,15 @@
 	return(status);
 }
 
+#define indexof(field) longinRecord##field
+
 static long get_units(DBADDR *paddr,char *units)
 {
     longinRecord *prec=(longinRecord *)paddr->precord;
 
-    strncpy(units,prec->egu,DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_LONG) {
+        strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return(0);
 }
 
@@ -171,14 +175,22 @@
 {
     longinRecord *prec=(longinRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)&prec->val
-    || paddr->pfield==(void *)&prec->hihi
-    || paddr->pfield==(void *)&prec->high
-    || paddr->pfield==(void *)&prec->low
-    || paddr->pfield==(void *)&prec->lolo){
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr,pgd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+        case indexof(SVAL):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr,pgd);
+    }
     return(0);
 }
 
@@ -186,14 +198,22 @@
 {
     longinRecord *prec=(longinRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)&prec->val
-    || paddr->pfield==(void *)&prec->hihi
-    || paddr->pfield==(void *)&prec->high
-    || paddr->pfield==(void *)&prec->low
-    || paddr->pfield==(void *)&prec->lolo){
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-    } else recGblGetControlDouble(paddr,pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+        case indexof(SVAL):
+            pcd->upper_ctrl_limit = prec->hopr;
+            pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return(0);
 }
 
@@ -201,7 +221,7 @@
 {
     longinRecord *prec=(longinRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)&prec->val){
+    if(dbGetFieldIndex(paddr) == indexof(VAL)){
          pad->upper_alarm_limit = prec->hihi;
          pad->upper_warning_limit = prec->high;
          pad->lower_warning_limit = prec->low;

=== modified file 'src/rec/longoutRecord.c'
--- src/rec/longoutRecord.c	2010-04-05 18:49:18 +0000
+++ src/rec/longoutRecord.c	2010-05-27 15:14:24 +0000
@@ -190,58 +190,73 @@
 	return(status);
 }
 
+#define indexof(field) longoutRecord##field
+
 static long get_units(DBADDR *paddr,char *units)
 {
     longoutRecord *prec=(longoutRecord *)paddr->precord;
 
-    strncpy(units,prec->egu,DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_LONG) {
+        strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return(0);
 }
 
 static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
 {
     longoutRecord *prec=(longoutRecord *)paddr->precord;
-    int fieldIndex = dbGetFieldIndex(paddr);
-
-    if(fieldIndex == longoutRecordVAL
-    || fieldIndex == longoutRecordHIHI
-    || fieldIndex == longoutRecordHIGH
-    || fieldIndex == longoutRecordLOW
-    || fieldIndex == longoutRecordLOLO) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else recGblGetGraphicDouble(paddr,pgd);
+    
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr,pgd);
+    }
     return(0);
 }
 
-
 static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
 {
     longoutRecord *prec=(longoutRecord *)paddr->precord;
-    int fieldIndex = dbGetFieldIndex(paddr);
 
-    if(fieldIndex == longoutRecordVAL
-    || fieldIndex == longoutRecordHIHI
-    || fieldIndex == longoutRecordHIGH
-    || fieldIndex == longoutRecordLOW
-    || fieldIndex == longoutRecordLOLO) {
-        /* do not change pre drvh/drvl behavior */
-        if(prec->drvh > prec->drvl) {
-            pcd->upper_ctrl_limit = prec->drvh;
-            pcd->lower_ctrl_limit = prec->drvl;
-        } else {
-            pcd->upper_ctrl_limit = prec->hopr;
-            pcd->lower_ctrl_limit = prec->lopr;
-        }
-    } else recGblGetControlDouble(paddr,pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            /* do not change pre drvh/drvl behavior */
+            if(prec->drvh > prec->drvl) {
+                pcd->upper_ctrl_limit = prec->drvh;
+                pcd->lower_ctrl_limit = prec->drvl;
+            } else {
+                pcd->upper_ctrl_limit = prec->hopr;
+                pcd->lower_ctrl_limit = prec->lopr;
+            }
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
+    }
     return(0);
 }
+
 static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
 {
     longoutRecord    *prec=(longoutRecord *)paddr->precord;
-    int     fieldIndex = dbGetFieldIndex(paddr);
 
-    if(fieldIndex == longoutRecordVAL) {
+    if(dbGetFieldIndex(paddr) == indexof(VAL)) {
          pad->upper_alarm_limit = prec->hihi;
          pad->upper_warning_limit = prec->high;
          pad->lower_warning_limit = prec->low;

=== modified file 'src/rec/selRecord.c'
--- src/rec/selRecord.c	2009-08-25 18:19:49 +0000
+++ src/rec/selRecord.c	2010-05-27 15:14:24 +0000
@@ -132,11 +132,15 @@
 }
 
 
+#define indexof(field) selRecord##field
+
 static long get_units(DBADDR *paddr, char *units)
 {
     selRecord	*prec=(selRecord *)paddr->precord;
 
-    strncpy(units,prec->egu,DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+        strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return(0);
 }
 
@@ -166,56 +170,68 @@
 static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
 {
     selRecord	*prec=(selRecord *)paddr->precord;
-
-    if(paddr->pfield==(void *)&prec->val
-    || paddr->pfield==(void *)&prec->hihi
-    || paddr->pfield==(void *)&prec->high
-    || paddr->pfield==(void *)&prec->low
-    || paddr->pfield==(void *)&prec->lolo){
-	pgd->upper_disp_limit = prec->hopr;
-	pgd->lower_disp_limit = prec->lopr;
-	return(0);
-    }
-
-    if(paddr->pfield>=(void *)&prec->a && paddr->pfield<=(void *)&prec->l){
-	pgd->upper_disp_limit = prec->hopr;
-	pgd->lower_disp_limit = prec->lopr;
-	return(0);
-    }
-    if(paddr->pfield>=(void *)&prec->la && paddr->pfield<=(void *)&prec->ll){
-	pgd->upper_disp_limit = prec->hopr;
-	pgd->lower_disp_limit = prec->lopr;
-	return(0);
-    }
-    recGblGetGraphicDouble(paddr,pgd);
+    int index = dbGetFieldIndex(paddr);
+    
+    switch (index) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+#ifdef __GNUC__
+        case indexof(A) ... indexof(L):
+        case indexof(LA) ... indexof(LL):
+            break;
+        default:
+#else
+            break;
+        default:
+            if((index >= indexof(A) && index <= indexof(L))
+            || (index >= indexof(LA) && index <= indexof(LL)))
+                break;
+#endif
+            recGblGetGraphicDouble(paddr,pgd);
+            return(0);
+    }
+    pgd->upper_disp_limit = prec->hopr;
+    pgd->lower_disp_limit = prec->lopr;
     return(0);
 }
 
 static long get_control_double(struct dbAddr *paddr, struct dbr_ctrlDouble *pcd)
 {
     selRecord	*prec=(selRecord *)paddr->precord;
-
-    if(paddr->pfield==(void *)&prec->val
-    || paddr->pfield==(void *)&prec->hihi
-    || paddr->pfield==(void *)&prec->high
-    || paddr->pfield==(void *)&prec->low
-    || paddr->pfield==(void *)&prec->lolo){
-	pcd->upper_ctrl_limit = prec->hopr;
-	pcd->lower_ctrl_limit = prec->lopr;
-	return(0);
-    }
-
-    if(paddr->pfield>=(void *)&prec->a && paddr->pfield<=(void *)&prec->l){
-	pcd->upper_ctrl_limit = prec->hopr;
-	pcd->lower_ctrl_limit = prec->lopr;
-	return(0);
-    }
-    if(paddr->pfield>=(void *)&prec->la && paddr->pfield<=(void *)&prec->ll){
-	pcd->upper_ctrl_limit = prec->hopr;
-	pcd->lower_ctrl_limit = prec->lopr;
-	return(0);
-    }
-    recGblGetControlDouble(paddr,pcd);
+    int index = dbGetFieldIndex(paddr);
+    
+    switch (index) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+#ifdef __GNUC__
+        case indexof(A) ... indexof(L):
+        case indexof(LA) ... indexof(LL):
+            break;
+        default:
+#else
+            break;
+        default:
+            if((index >= indexof(A) && index <= indexof(L))
+            || (index >= indexof(LA) && index <= indexof(LL)))
+                break;
+#endif
+            recGblGetControlDouble(paddr,pcd);
+            return(0);
+    }
+    pcd->upper_ctrl_limit = prec->hopr;
+    pcd->lower_ctrl_limit = prec->lopr;
     return(0);
 }
 
@@ -223,7 +239,7 @@
 {
     selRecord	*prec=(selRecord *)paddr->precord;
 
-    if(paddr->pfield==(void *)&prec->val ){
+    if(dbGetFieldIndex(paddr) == indexof(VAL)) {
         pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
         pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
         pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;

=== modified file 'src/rec/seqRecord.c'
--- src/rec/seqRecord.c	2009-04-02 21:41:45 +0000
+++ src/rec/seqRecord.c	2010-05-27 15:14:24 +0000
@@ -6,7 +6,7 @@
 * EPICS BASE is distributed subject to a Software License Agreement found
 * in file LICENSE that is included with this distribution. 
 \*************************************************************************/
-
+ 
 /*
  * $Id$
  *
@@ -39,34 +39,48 @@
 
 int	seqRecDebug = 0;
 
+static int processNextLink(seqRecord *prec);
+static long asyncFinish(seqRecord *prec);
+static void processCallback(CALLBACK *arg);
+
 /* Create RSET - Record Support Entry Table*/
+#define report NULL
+#define initialize NULL
 static long init_record(seqRecord *prec, int pass);
 static long process(seqRecord *prec);
-static int processNextLink(seqRecord *prec);
-static long asyncFinish(seqRecord *prec);
-static void processCallback(CALLBACK *arg);
-static long get_precision(dbAddr *paddr, long *pprecision);
+#define special NULL
+#define get_value NULL
+#define cvt_dbaddr NULL
+#define get_array_info NULL
+#define put_array_info NULL
+static long get_units(DBADDR *, char *);
+static long get_precision(dbAddr *paddr, long *);
+#define get_enum_str NULL
+#define get_enum_strs NULL
+#define put_enum_str NULL
+static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
+static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
 
 rset seqRSET={
 	RSETNUMBER,
-	NULL,			/* report */
-	NULL,			/* initialize */
+	report,			/* report */
+	initialize,		/* initialize */
 	init_record,		/* init_record */
 	process,		/* process */
-	NULL,			/* special */
-	NULL,			/* get_value */
-	NULL,			/* cvt_dbaddr */
-	NULL,			/* get_array_info */
-	NULL,			/* put_array_info */
-	NULL,			/* get_units */
+	special,		/* special */
+	get_value,		/* get_value */
+	cvt_dbaddr,		/* cvt_dbaddr */
+	get_array_info,		/* get_array_info */
+	put_array_info,		/* put_array_info */
+	get_units,		/* get_units */
 	get_precision,		/* get_precision */
-	NULL,			/* get_enum_str */
-	NULL,			/* get_enum_strs */
-	NULL,			/* put_enum_str */
-	NULL,			/* get_graphic_double */
-	NULL,			/* get_control_double */
-	NULL 			/* get_alarm_double */
-
+	get_enum_str,		/* get_enum_str */
+	get_enum_strs,		/* get_enum_strs */
+	put_enum_str,		/* put_enum_str */
+	get_graphic_double,	/* get_graphic_double */
+	get_control_double,	/* get_control_double */
+	get_alarm_double 	/* get_alarm_double */
 };
 epicsExportAddress(rset,seqRSET);
 
@@ -406,15 +420,91 @@
  * Return the precision value from PREC
  *
  *****************************************************************************/
+#define indexof(field) seqRecord##field
+#define get_dol(prec, fieldOffset) \
+    &((linkDesc*)&prec->dly1)[fieldOffset>>2].dol
+
+static long get_units(DBADDR *paddr, char *units)
+{
+    seqRecord	*prec = (seqRecord *) paddr->precord;
+    int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+
+    if (fieldOffset >= 0) switch (fieldOffset & 2) {
+        case 0: /* DLYn */
+            strcpy(units, "s");
+            break;
+        case 2: /* DOn */
+            dbGetUnits(get_dol(prec, fieldOffset),
+                units, DB_UNITS_SIZE);
+    }
+    return(0);
+}
+
 static long get_precision(dbAddr *paddr, long *pprecision)
 {
     seqRecord	*prec = (seqRecord *) paddr->precord;
+    int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+    short precision;
 
+    if (fieldOffset >= 0) switch (fieldOffset & 2) {
+        case 0: /* DLYn */
+            *pprecision = 2;
+            return 0;
+        case 2: /* DOn */
+            if (dbGetPrecision(get_dol(prec, fieldOffset),
+                &precision) == 0) {
+                *pprecision = precision;
+                return 0;
+            }
+    }
     *pprecision = prec->prec;
-
-    if(paddr->pfield < (void *)&prec->val)
-	return 0;			/* Field is NOT in dbCommon */
-
-    recGblGetPrec(paddr, pprecision);	/* Field is in dbCommon */
-    return 0;
-}
+    recGblGetPrec(paddr, pprecision);
+    return 0;
+}
+
+static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
+{
+    seqRecord	*prec = (seqRecord *) paddr->precord;
+    int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+    
+    if (fieldOffset >= 0) switch (fieldOffset & 2) {
+        case 0: /* DLYn */
+            pgd->lower_disp_limit = 0.0;
+            pgd->lower_disp_limit = 10.0;
+            return 0;
+        case 2: /* DOn */
+            dbGetGraphicLimits(get_dol(prec, fieldOffset),
+                &pgd->lower_disp_limit,
+                &pgd->upper_disp_limit);
+            return 0;
+    }
+    recGblGetGraphicDouble(paddr,pgd);
+    return 0;
+}    
+    
+static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
+{
+    int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+
+    recGblGetControlDouble(paddr,pcd);
+    if (fieldOffset >= 0 && (fieldOffset & 2) == 0) /* DLYn */
+        pcd->lower_ctrl_limit = 0.0;
+    return(0);
+}
+
+static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
+{
+    seqRecord	*prec = (seqRecord *) paddr->precord;
+    int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+
+    if (fieldOffset >= 0 && (fieldOffset & 2) == 2)  /* DOn */
+        dbGetAlarmLimits(get_dol(prec, fieldOffset),
+            &pad->lower_alarm_limit,
+            &pad->lower_warning_limit,
+            &pad->upper_warning_limit,
+            &pad->upper_alarm_limit);
+    else
+        recGblGetAlarmDouble(paddr, pad);
+    return 0;
+}
+

=== modified file 'src/rec/subArrayRecord.c'
--- src/rec/subArrayRecord.c	2009-04-23 22:19:46 +0000
+++ src/rec/subArrayRecord.c	2010-05-27 15:14:24 +0000
@@ -201,25 +201,30 @@
     return 0;
 }
 
+#define indexof(field) subArrayRecord##field
+
 static long get_units(DBADDR *paddr, char *units)
 {
     subArrayRecord *prec = (subArrayRecord *) paddr->precord;
 
-    strncpy(units, prec->egu, DB_UNITS_SIZE);
-
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
+                break; 
+        case indexof(HOPR):
+        case indexof(LOPR):
+            strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return 0;
 }
 
 static long get_precision(DBADDR *paddr, long *precision)
 {
     subArrayRecord *prec = (subArrayRecord *) paddr->precord;
-    int fieldIndex = dbGetFieldIndex(paddr);
 
     *precision = prec->prec;
-
-    if (fieldIndex != subArrayRecordVAL)
+    if (dbGetFieldIndex(paddr) != indexof(VAL))
         recGblGetPrec(paddr, precision);
-
     return 0;
 }
 
@@ -228,25 +233,29 @@
     subArrayRecord *prec = (subArrayRecord *) paddr->precord;
 
     switch (dbGetFieldIndex(paddr)) {
-    case subArrayRecordVAL:
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-        break;
-
-    case subArrayRecordINDX:
-        pgd->upper_disp_limit = prec->malm - 1;
-        pgd->lower_disp_limit = 0;
-        break;
-
-    case subArrayRecordNELM:
-        pgd->upper_disp_limit = prec->malm;
-        pgd->lower_disp_limit = 1;
-        break;
-
-    default:
-        recGblGetGraphicDouble(paddr, pgd);
+        case indexof(VAL):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        case indexof(INDX):
+            pgd->upper_disp_limit = prec->malm - 1;
+            pgd->lower_disp_limit = 0;
+            break;
+        case indexof(NELM):
+            pgd->upper_disp_limit = prec->malm;
+            pgd->lower_disp_limit = 0;
+            break;
+        case indexof(NORD):
+            pgd->upper_disp_limit = prec->malm;
+            pgd->lower_disp_limit = 0;
+            break;
+         case indexof(BUSY):
+            pgd->upper_disp_limit = 1;
+            pgd->lower_disp_limit = 0;
+            break;
+       default:
+            recGblGetGraphicDouble(paddr, pgd);
     }
-
     return 0;
 }
 
@@ -255,25 +264,29 @@
     subArrayRecord *prec = (subArrayRecord *) paddr->precord;
 
     switch (dbGetFieldIndex(paddr)) {
-    case subArrayRecordVAL:
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-        break;
-
-    case subArrayRecordINDX:
-        pcd->upper_ctrl_limit = prec->malm - 1;
-        pcd->lower_ctrl_limit = 0;
-        break;
-
-    case subArrayRecordNELM:
-        pcd->upper_ctrl_limit = prec->malm;
-        pcd->lower_ctrl_limit = 1;
-        break;
-
-    default:
-        recGblGetControlDouble(paddr, pcd);
+        case indexof(VAL):
+            pcd->upper_ctrl_limit = prec->hopr;
+            pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        case indexof(INDX):
+            pcd->upper_ctrl_limit = prec->malm - 1;
+            pcd->lower_ctrl_limit = 0;
+            break;
+        case indexof(NELM):
+            pcd->upper_ctrl_limit = prec->malm;
+            pcd->lower_ctrl_limit = 1;
+            break;
+        case indexof(NORD):
+            pcd->upper_ctrl_limit = prec->malm;
+            pcd->lower_ctrl_limit = 0;
+            break;
+        case indexof(BUSY):
+            pcd->upper_ctrl_limit = 1;
+            pcd->lower_ctrl_limit = 0;
+            break;
+        default:
+            recGblGetControlDouble(paddr, pcd);
     }
-
     return 0;
 }
 

=== modified file 'src/rec/subRecord.c'
--- src/rec/subRecord.c	2010-04-05 18:49:18 +0000
+++ src/rec/subRecord.c	2010-05-27 15:14:24 +0000
@@ -191,54 +191,79 @@
     return S_db_BadSub;
 }
 
+#define indexof(field) subRecord##field
+
+static long get_linkNumber(int fieldIndex) {
+    if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
+        return fieldIndex - indexof(A);
+    if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
+        return fieldIndex - indexof(LA);
+    return -1;
+}
+
 static long get_units(DBADDR *paddr, char *units)
 {
     subRecord *prec = (subRecord *)paddr->precord;
+    int linkNumber;
 
-    strncpy(units, prec->egu, DB_UNITS_SIZE);
+    if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+        linkNumber = get_linkNumber(dbGetFieldIndex(paddr));
+        if (linkNumber >= 0)
+            dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
+        else
+            strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return 0;
 }
 
-static long get_precision(DBADDR *paddr, long *precision)
+static long get_precision(DBADDR *paddr, long *pprecision)
 {
     subRecord *prec = (subRecord *)paddr->precord;
     int fieldIndex = dbGetFieldIndex(paddr);
-
-    *precision = prec->prec;
-    if (fieldIndex != subRecordVAL)
-        recGblGetPrec(paddr, precision);
-
+    int linkNumber;
+
+    *pprecision = prec->prec;
+    if (fieldIndex == indexof(VAL)) {
+	return 0;
+    }
+    linkNumber = get_linkNumber(fieldIndex);
+    if (linkNumber >= 0) {
+        short precision;
+        if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
+            *pprecision = precision;
+        else
+            *pprecision = 15;
+    } else
+        recGblGetPrec(paddr, pprecision);
     return 0;
 }
 
-
 static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
 {
     subRecord *prec = (subRecord *)paddr->precord;
     int fieldIndex = dbGetFieldIndex(paddr);
-
+    int linkNumber;
+    
     switch (fieldIndex) {
-    case subRecordVAL:
-    case subRecordHIHI:     case subRecordHIGH:
-    case subRecordLOW:      case subRecordLOLO:
-    case subRecordA:        case subRecordB:
-    case subRecordC:        case subRecordD:
-    case subRecordE:        case subRecordF:
-    case subRecordG:        case subRecordH:
-    case subRecordI:        case subRecordJ:
-    case subRecordK:        case subRecordL:
-    case subRecordLA:       case subRecordLB:
-    case subRecordLC:       case subRecordLD:
-    case subRecordLE:       case subRecordLF:
-    case subRecordLG:       case subRecordLH:
-    case subRecordLI:       case subRecordLJ:
-    case subRecordLK:       case subRecordLL:
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-        break;
-
-    default:
-        recGblGetGraphicDouble(paddr, pgd);
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pgd->lower_disp_limit = prec->lopr;
+            pgd->upper_disp_limit = prec->hopr;
+            break;
+        default:
+            linkNumber = get_linkNumber(fieldIndex);
+            if (linkNumber >= 0) {
+                dbGetGraphicLimits(&prec->inpa + linkNumber,
+                    &pgd->lower_disp_limit,
+                    &pgd->upper_disp_limit);
+            } else
+                recGblGetGraphicDouble(paddr,pgd);
     }
     return 0;
 }
@@ -246,24 +271,21 @@
 static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
 {
     subRecord *prec = (subRecord *)paddr->precord;
-    int fieldIndex = dbGetFieldIndex(paddr);
-
-    switch (fieldIndex) {
-    case subRecordVAL:
-    case subRecordHIHI:     case subRecordHIGH:
-    case subRecordLOW:      case subRecordLOLO:
-    case subRecordA:        case subRecordB:
-    case subRecordC:        case subRecordD:
-    case subRecordE:        case subRecordF:
-    case subRecordG:        case subRecordH:
-    case subRecordI:        case subRecordJ:
-    case subRecordK:        case subRecordL:
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-        break;
-
-    default:
-        recGblGetControlDouble(paddr, pcd);
+    
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+        case indexof(HIHI):
+        case indexof(HIGH):
+        case indexof(LOW):
+        case indexof(LOLO):
+        case indexof(LALM):
+        case indexof(ALST):
+        case indexof(MLST):
+            pcd->lower_ctrl_limit = prec->lopr;
+            pcd->upper_ctrl_limit = prec->hopr;
+            break;
+        default:
+            recGblGetControlDouble(paddr,pcd);
     }
     return 0;
 }
@@ -272,6 +294,7 @@
 {
     subRecord *prec = (subRecord *)paddr->precord;
     int fieldIndex = dbGetFieldIndex(paddr);
+    int linkNumber;
 
     if (fieldIndex == subRecordVAL) {
         pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
@@ -279,7 +302,15 @@
         pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
         pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
     } else {
-        recGblGetAlarmDouble(paddr, pad);
+        linkNumber = get_linkNumber(fieldIndex);
+        if (linkNumber >= 0) {
+            dbGetAlarmLimits(&prec->inpa + linkNumber,
+                &pad->lower_alarm_limit,
+                &pad->lower_warning_limit,
+                &pad->upper_warning_limit,
+                &pad->upper_alarm_limit);
+        } else
+	    recGblGetAlarmDouble(paddr, pad);
     }
     return 0;
 }

=== modified file 'src/rec/waveformRecord.c'
--- src/rec/waveformRecord.c	2009-07-08 18:14:11 +0000
+++ src/rec/waveformRecord.c	2010-05-27 15:14:24 +0000
@@ -194,25 +194,30 @@
     return 0;
 }
 
+#define indexof(field) waveformRecord##field
+
 static long get_units(DBADDR *paddr, char *units)
 {
     waveformRecord *prec = (waveformRecord *) paddr->precord;
 
-    strncpy(units,prec->egu,DB_UNITS_SIZE);
-
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
+                break; 
+        case indexof(HOPR):
+        case indexof(LOPR):
+            strncpy(units,prec->egu,DB_UNITS_SIZE);
+    }
     return 0;
 }
 
 static long get_precision(DBADDR *paddr, long *precision)
 {
     waveformRecord *prec = (waveformRecord *) paddr->precord;
-    int fieldIndex = dbGetFieldIndex(paddr);
 
     *precision = prec->prec;
-
-    if (fieldIndex != waveformRecordVAL)
+    if (dbGetFieldIndex(paddr) != indexof(VAL))
         recGblGetPrec(paddr, precision);
-
     return 0;
 }
 
@@ -220,11 +225,22 @@
 {
     waveformRecord *prec = (waveformRecord *) paddr->precord;
 
-    if (dbGetFieldIndex(paddr) == waveformRecordVAL) {
-        pgd->upper_disp_limit = prec->hopr;
-        pgd->lower_disp_limit = prec->lopr;
-    } else
-        recGblGetGraphicDouble(paddr, pgd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            pgd->upper_disp_limit = prec->hopr;
+            pgd->lower_disp_limit = prec->lopr;
+            break;
+        case indexof(BUSY):
+            pgd->upper_disp_limit = 1;
+            pgd->lower_disp_limit = 0;
+            break;
+        case indexof(NORD):
+            pgd->upper_disp_limit = prec->nelm;
+            pgd->lower_disp_limit = 0;
+            break;
+        default:
+            recGblGetGraphicDouble(paddr, pgd);
+    }
     return 0;
 }
 
@@ -232,11 +248,22 @@
 {
     waveformRecord *prec = (waveformRecord *) paddr->precord;
 
-    if (dbGetFieldIndex(paddr) == waveformRecordVAL) {
-        pcd->upper_ctrl_limit = prec->hopr;
-        pcd->lower_ctrl_limit = prec->lopr;
-    } else
-        recGblGetControlDouble(paddr, pcd);
+    switch (dbGetFieldIndex(paddr)) {
+        case indexof(VAL):
+            pcd->upper_ctrl_limit = prec->hopr;
+            pcd->lower_ctrl_limit = prec->lopr;
+            break;
+        case indexof(BUSY):
+            pcd->upper_ctrl_limit = 1;
+            pcd->lower_ctrl_limit = 0;
+            break;
+        case indexof(NORD):
+            pcd->upper_ctrl_limit = prec->nelm;
+            pcd->lower_ctrl_limit = 0;
+            break;
+        default:
+            recGblGetControlDouble(paddr, pcd);
+    }
     return 0;
 }
 


Navigate by Date:
Prev: Re: [Merge] lp:~khkim/epics-base/fix-timestamp into lp:epics-base Ralph Lange
Next: [Merge] lp:~dirk.zimoch/epics-base/named-soft-events into lp:epics-base Dirk Zimoch
Index: 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014 
Navigate by Thread:
Prev: Re: [Merge] lp:~ronaldo-mercado/epics-base/capr into lp:epics-base Ronaldo Mercado
Next: Re: [Merge] lp:~dirk.zimoch/epics-base/non-val-attributes into lp:epics-base Dirk Zimoch
Index: 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·