35 #define GEN_SIZE_OFFSET 36 #include "aSubRecord.h" 37 #undef GEN_SIZE_OFFSET 46 #define initialize NULL 48 static long process(
struct dbCommon *);
49 static long special(DBADDR *,
int);
50 #define get_value NULL 56 #define get_enum_str NULL 57 #define get_enum_strs NULL 58 #define put_enum_str NULL 86 epicsUInt32 *pon,
const char **fldnames,
void **pval,
void **povl);
87 static long fetch_values(aSubRecord *
prec);
88 static void monitor(aSubRecord *);
89 static long do_sub(aSubRecord *);
94 static const char *Ifldnames[] = {
95 "A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
96 "L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U" 100 static const char *Ofldnames[] = {
101 "VALA",
"VALB",
"VALC",
"VALD",
"VALE",
"VALF",
"VALG",
102 "VALH",
"VALI",
"VALJ",
"VALK",
"VALL",
"VALM",
"VALN",
103 "VALO",
"VALP",
"VALQ",
"VALR",
"VALS",
"VALT",
"VALU" 107 static long init_record(
struct dbCommon *pcommon,
int pass)
109 struct aSubRecord *
prec = (
struct aSubRecord *)pcommon;
116 initFields(&prec->fta, &prec->noa, &prec->nea,
NULL,
117 Ifldnames, &prec->a,
NULL);
118 initFields(&prec->ftva, &prec->nova, &prec->neva, &prec->onva,
119 Ofldnames, &prec->vala, &prec->ovla);
124 recGblInitConstantLink(&prec->subl,
DBF_STRING, prec->snam);
128 struct link *plink = &(&prec->inpa)[i];
129 short dbr = (&prec->fta)[i];
130 long n = (&prec->noa)[i];
132 dbLoadLinkArray(plink, dbr, (&prec->a)[i], &n);
138 if (prec->inam[0] != 0) {
143 recGblRecordError(S_db_BadSub, (
void *)prec,
144 "aSubRecord::init_record - INAM subr not found");
149 if (prec->lflg == aSubLFLG_IGNORE &&
150 prec->snam[0] != 0) {
155 recGblRecordError(S_db_BadSub, (
void *)prec,
156 "aSubRecord::init_record - SNAM subr not found");
160 strcpy(prec->onam, prec->snam);
161 prec->oval = prec->val;
165 (&prec->onva)[i] = nev;
167 memcpy((&prec->ovla)[i], (&prec->vala)[i],
168 dbValueSize((&prec->ftva)[i]) * nev);
175 epicsUInt32 *pon,
const char **fldnames,
void **pval,
void **povl)
180 for (i = 0; i <
NUM_ARGS; i++, pft++, pno++, pne++, pval++) {
190 flen = dbValueSize(*pft);
199 "aSubRecord::init_record");
208 static long process(
struct dbCommon *pcommon)
210 struct aSubRecord *
prec = (
struct aSubRecord *)pcommon;
211 int pact = prec->pact;
216 status = fetch_values(prec);
221 status = do_sub(prec);
225 if (!pact && prec->pact)
235 dbPutLink(&(&prec->outa)[i], (&prec->ftva)[i], (&prec->vala)[i],
239 recGblGetTimeStamp(prec);
247 static long fetch_values(aSubRecord *
prec)
252 if (prec->lflg == aSubLFLG_READ) {
254 status = dbGetLink(&prec->subl,
DBR_STRING, prec->snam, 0, 0);
258 if (prec->snam[0] != 0 &&
259 strcmp(prec->snam, prec->onam)) {
265 if (prec->sadr!=pfunc && prec->cadr) {
271 strcpy(prec->onam, prec->snam);
277 long nRequest = (&prec->noa)[i];
278 status = dbGetLink(&(&prec->inpa)[i], (&prec->fta)[i], (&prec->a)[i], 0,
281 (&prec->nea)[i] = nRequest;
288 #define indexof(field) aSubRecord##field 290 static long get_inlinkNumber(
int fieldIndex) {
292 return fieldIndex -
indexof(A);
296 static long get_outlinkNumber(
int fieldIndex) {
298 return fieldIndex -
indexof(VALA);
302 static long get_units(DBADDR *paddr,
char *units)
304 aSubRecord *
prec = (aSubRecord *)paddr->precord;
307 linkNumber = get_inlinkNumber(dbGetFieldIndex(paddr));
308 if (linkNumber >= 0) {
309 dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
312 linkNumber = get_outlinkNumber(dbGetFieldIndex(paddr));
313 if (linkNumber >= 0) {
314 dbGetUnits(&prec->outa + linkNumber, units, DB_UNITS_SIZE);
319 static long get_precision(
const DBADDR *paddr,
long *pprecision)
321 aSubRecord *
prec = (aSubRecord *)paddr->precord;
322 int fieldIndex = dbGetFieldIndex(paddr);
325 *pprecision = prec->prec;
326 linkNumber = get_inlinkNumber(fieldIndex);
327 if (linkNumber >= 0) {
330 if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
331 *pprecision = precision;
335 linkNumber = get_outlinkNumber(fieldIndex);
336 if (linkNumber >= 0) {
339 if (dbGetPrecision(&prec->outa + linkNumber, &precision) == 0)
340 *pprecision = precision;
342 recGblGetPrec(paddr, pprecision);
348 aSubRecord *
prec = (aSubRecord *)paddr->precord;
349 int fieldIndex = dbGetFieldIndex(paddr);
352 linkNumber = get_inlinkNumber(fieldIndex);
353 if (linkNumber >= 0) {
354 dbGetGraphicLimits(&prec->inpa + linkNumber,
355 &pgd->lower_disp_limit,
356 &pgd->upper_disp_limit);
359 linkNumber = get_outlinkNumber(fieldIndex);
360 if (linkNumber >= 0) {
361 dbGetGraphicLimits(&prec->outa + linkNumber,
362 &pgd->lower_disp_limit,
363 &pgd->upper_disp_limit);
370 recGblGetControlDouble(paddr,pcd);
376 aSubRecord *
prec = (aSubRecord *)paddr->precord;
377 int fieldIndex = dbGetFieldIndex(paddr);
380 linkNumber = get_inlinkNumber(fieldIndex);
381 if (linkNumber >= 0) {
382 dbGetAlarmLimits(&prec->inpa + linkNumber,
383 &pad->lower_alarm_limit,
384 &pad->lower_warning_limit,
385 &pad->upper_warning_limit,
386 &pad->upper_alarm_limit);
389 linkNumber = get_outlinkNumber(fieldIndex);
390 if (linkNumber >= 0) {
391 dbGetAlarmLimits(&prec->outa + linkNumber,
392 &pad->lower_alarm_limit,
393 &pad->lower_warning_limit,
394 &pad->upper_warning_limit,
395 &pad->upper_alarm_limit);
398 recGblGetAlarmDouble(paddr, pad);
402 static void monitor(aSubRecord *
prec)
405 unsigned short monitor_mask;
410 if (prec->val != prec->oval) {
411 db_post_events(prec, &prec->val, monitor_mask);
412 prec->oval = prec->val;
416 switch (prec->eflg) {
419 case aSubEFLG_ON_CHANGE:
421 void *povl = (&prec->ovla)[i];
422 void *pval = (&prec->vala)[i];
427 epicsUInt32 alen = dbValueSize((&prec->ftva)[i]) * nev;
429 if (nev != onv || memcmp(povl, pval, alen)) {
430 memcpy(povl, pval, alen);
431 db_post_events(prec, pval, monitor_mask);
434 db_post_events(prec, pnev, monitor_mask);
439 case aSubEFLG_ALWAYS:
441 db_post_events(prec, (&prec->vala)[i], monitor_mask);
442 db_post_events(prec, &(&prec->neva)[i], monitor_mask);
450 static long do_sub(aSubRecord *
prec)
455 if (prec->snam[0] == 0)
462 status = pfunc(prec);
474 aSubRecord *
prec = (aSubRecord *)paddr->precord;
475 int fieldIndex = dbGetFieldIndex(paddr);
477 if (fieldIndex >= aSubRecordA &&
478 fieldIndex <= aSubRecordU) {
479 int offset = fieldIndex - aSubRecordA;
481 paddr->pfield = (&prec->a )[offset];
482 paddr->no_elements = (&prec->noa)[offset];
483 paddr->field_type = (&prec->fta)[offset];
485 else if (fieldIndex >= aSubRecordVALA &&
486 fieldIndex <= aSubRecordVALU) {
487 int offset = fieldIndex - aSubRecordVALA;
489 paddr->pfield = (&prec->vala)[offset];
490 paddr->no_elements = (&prec->nova)[offset];
491 paddr->field_type = (&prec->ftva)[offset];
494 errlogPrintf(
"aSubRecord::cvt_dbaddr called for %s.%s\n",
495 prec->name, paddr->pfldDes->name);
498 paddr->dbr_field_type = paddr->field_type;
499 paddr->field_size = dbValueSize(paddr->field_type);
504 static long get_array_info(DBADDR *paddr,
long *no_elements,
long *offset)
506 aSubRecord *
prec = (aSubRecord *)paddr->precord;
507 int fieldIndex = dbGetFieldIndex(paddr);
509 if (fieldIndex >= aSubRecordA &&
510 fieldIndex <= aSubRecordU) {
511 *no_elements = (&prec->nea)[fieldIndex - aSubRecordA];
513 else if (fieldIndex >= aSubRecordVALA &&
514 fieldIndex <= aSubRecordVALU) {
515 *no_elements = (&prec->neva)[fieldIndex - aSubRecordVALA];
518 errlogPrintf(
"aSubRecord::get_array_info called for %s.%s\n",
519 prec->name, paddr->pfldDes->name);
529 aSubRecord *
prec = (aSubRecord *)paddr->precord;
530 int fieldIndex = dbGetFieldIndex(paddr);
532 if (fieldIndex >= aSubRecordA &&
533 fieldIndex <= aSubRecordU) {
534 (&prec->nea)[fieldIndex - aSubRecordA] = nNew;
536 else if (fieldIndex >= aSubRecordVALA &&
537 fieldIndex <= aSubRecordVALU) {
538 (&prec->neva)[fieldIndex - aSubRecordVALA] = nNew;
541 errlogPrintf(
"aSubRecord::put_array_info called for %s.%s\n",
542 prec->name, paddr->pfldDes->name);
548 static long special(DBADDR *paddr,
int after)
550 aSubRecord *
prec = (aSubRecord *)paddr->precord;
554 prec->lflg == aSubLFLG_IGNORE) {
556 if (prec->snam[0] == 0)
562 recGblRecordError(
status, (
void *)prec, prec->snam);
566 if (prec->sadr != pfunc && prec->cadr) {
epicsExportAddress(rset, aSubRSET)
long(* GENFUNCPTR)(struct aSubRecord *)
Miscellaneous macro definitions.
#define get_control_double
#define STATIC_ASSERT(expr)
Declare a condition that should be true at compile-time.
LIBCOM_API void * callocMustSucceed(size_t count, size_t size, const char *msg)
A calloc() that never returns NULL.
int errlogPrintf(const char *pFormat,...)
epicsShareFunc REGISTRYFUNCTION registryFunctionFind(const char *name)
Routines for code that can't continue or return after an error.
#define get_graphic_double