static void dbRecordField(char *name,char *value) { DBENTRY *pdbentry; tempListNode *ptempListNode; long status; if(duplicate) return; ptempListNode = (tempListNode *)ellFirst(&tempList); pdbentry = ptempListNode->item; status = dbFindField(pdbentry,name); if(status) { epicsPrintf("Record \"%s\" does not have a field \"%s\"\n", dbGetRecordName(pdbentry), name); yyerror(NULL); return; } dbTranslateEscape(value, value); /* yuck: in-place, but safe */ status = dbPutString(pdbentry,value); if(status) { epicsPrintf("Can't set \"%s.%s\" to \"%s\"\n", dbGetRecordName(pdbentry), name, value); yyerror(NULL); return; } }
long epicsShareAPI dbla(const char *pmask) { DBENTRY dbentry; DBENTRY *pdbentry = &dbentry; long status; if (!pdbbase) { printf("No database loaded\n"); return 0; } dbInitEntry(pdbbase, pdbentry); status = dbFirstRecordType(pdbentry); while (!status) { for (status = dbFirstRecord(pdbentry); !status; status = dbNextRecord(pdbentry)) { char *palias; if (!dbIsAlias(pdbentry)) continue; palias = dbGetRecordName(pdbentry); if (pmask && *pmask && !epicsStrGlobMatch(palias, pmask)) continue; dbFindField(pdbentry, "NAME"); printf("%s -> %s\n", palias, dbGetString(pdbentry)); } status = dbNextRecordType(pdbentry); } dbFinishEntry(pdbentry); return 0; }
long epicsShareAPI dbGetField(DBADDR *paddr,short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { short dbfType = paddr->field_type; dbCommon *precord = paddr->precord; long status = 0; dbScanLock(precord); if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { DBENTRY dbEntry; dbFldDes *pfldDes = paddr->pfldDes; char *rtnString; char *pbuf = (char *)pbuffer; int maxlen; if (options && (*options)) getOptions(paddr, &pbuf, options, pflin); if (nRequest && *nRequest == 0) goto done; 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: status = S_db_badDbrtype; goto done; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, precord->name); if (!status) status = dbFindField(&dbEntry, pfldDes->name); if (!status) { rtnString = dbGetString(&dbEntry); strncpy(pbuf, rtnString, maxlen); pbuf[maxlen] = 0; } dbFinishEntry(&dbEntry); } else { status = dbGet(paddr, dbrType, pbuffer, options, nRequest, pflin); } done: dbScanUnlock(precord); return status; }
static long getLinkValue(DBADDR *paddr, short dbrType, char *pbuf, long *nRequest) { dbCommon *precord = paddr->precord; dbFldDes *pfldDes = paddr->pfldDes; int maxlen; DBENTRY dbEntry; long status; switch (dbrType) { case DBR_STRING: maxlen = MAX_STRING_SIZE - 1; if (nRequest && *nRequest > 1) *nRequest = 1; break; case DBR_DOUBLE: /* Needed for dbCa links */ if (nRequest && *nRequest) *nRequest = 1; *(double *)pbuf = epicsNAN; return 0; case DBR_CHAR: case DBR_UCHAR: if (nRequest && *nRequest > 0) { maxlen = *nRequest - 1; break; } /* else fall through ... */ default: return S_db_badDbrtype; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, precord->name); if (!status) status = dbFindField(&dbEntry, pfldDes->name); if (!status) { char *rtnString = dbGetString(&dbEntry); strncpy(pbuf, rtnString, --maxlen); pbuf[maxlen] = 0; } dbFinishEntry(&dbEntry); return status; }
static int dbpr_report( const char *pname, DBADDR *paddr, int interest_level, TAB_BUFFER *pMsgBuff, int tab_size) { char *pmsg; dbFldDes *pdbFldDes = paddr->pfldDes; dbRecordType *pdbRecordType = pdbFldDes->pdbRecordType; short n2; void *pfield; char *pfield_name; char *pfield_value; DBENTRY dbentry; DBENTRY *pdbentry = &dbentry; long status; dbInitEntry(pdbbase,pdbentry); status = dbFindRecord(pdbentry,pname); if (status) { errMessage(status,pname); return -1; } pmsg = pMsgBuff->message; for (n2 = 0; n2 <= pdbRecordType->no_fields - 1; n2++) { pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->sortFldInd[n2]]; pfield_name = pdbFldDes->name; pfield = ((char *)paddr->precord) + pdbFldDes->offset; if (pdbFldDes->interest > interest_level ) continue; switch (pdbFldDes->field_type) { case DBF_STRING: case DBF_USHORT: case DBF_ENUM: case DBF_FLOAT: case DBF_CHAR: case DBF_UCHAR: case DBF_SHORT: case DBF_LONG: case DBF_ULONG: case DBF_DOUBLE: case DBF_MENU: case DBF_DEVICE: status = dbFindField(pdbentry,pfield_name); pfield_value = dbGetString(pdbentry); sprintf(pmsg, "%s: %s", pfield_name, (pfield_value ? pfield_value : "<nil>")); dbpr_msgOut(pMsgBuff, tab_size); break; case DBF_INLINK: case DBF_OUTLINK: case DBF_FWDLINK: { DBLINK *plink = (DBLINK *)pfield; int ind; status = dbFindField(pdbentry,pfield_name); for (ind=0; ind<LINK_NTYPES; ind++) { if (pamaplinkType[ind].value == plink->type) break; } if (ind>=LINK_NTYPES) { sprintf(pmsg,"%s: Illegal Link Type", pfield_name); } else { sprintf(pmsg,"%s:%s %s", pfield_name, pamaplinkType[ind].strvalue,dbGetString(pdbentry)); } dbpr_msgOut(pMsgBuff, tab_size); } break; case DBF_NOACCESS: if (pfield == (void *)&paddr->precord->time) { /* Special for the TIME field, make it human-readable */ char time_buf[40]; epicsTimeToStrftime(time_buf, 40, "%Y-%m-%d %H:%M:%S.%09f", &paddr->precord->time); sprintf(pmsg, "%s: %s", pfield_name, time_buf); dbpr_msgOut(pMsgBuff, tab_size); } else if (pdbFldDes->size == sizeof(void *) && strchr(pdbFldDes->extra, '*')) { /* Special for pointers, needed on little-endian CPUs */ sprintf(pmsg, "%s: %p", pfield_name, *(void **)pfield); dbpr_msgOut(pMsgBuff, tab_size); } else { /* just print field as hex bytes */ unsigned char *pchar = (unsigned char *)pfield; char temp_buf[61]; char *ptemp_buf = &temp_buf[0]; short n = pdbFldDes->size; short i; unsigned int value; if (n > sizeof(temp_buf)/3) n = sizeof(temp_buf)/3; for (i=0; i<n; i++, ptemp_buf += 3, pchar++) { value = (unsigned int)*pchar; sprintf(ptemp_buf, "%02x ", value); } sprintf(pmsg, "%s: %s", pfield_name,temp_buf); dbpr_msgOut(pMsgBuff, tab_size); } break; default: sprintf(pmsg, "%s: dbpr: Unknown field_type", pfield_name); dbpr_msgOut(pMsgBuff, tab_size); break; } } pmsg[0] = '\0'; dbpr_msgOut(pMsgBuff, tab_size); dbFinishEntry(pdbentry); return (0); }
long epicsShareAPI dbl(const char *precordTypename, const char *fields) { DBENTRY dbentry; DBENTRY *pdbentry=&dbentry; long status; int nfields = 0; int ifield; char *fieldnames = 0; char **papfields = 0; if (!pdbbase) { printf("No database loaded\n"); return 0; } if (precordTypename && ((*precordTypename == '\0') || !strcmp(precordTypename,"*"))) precordTypename = NULL; if (fields && (*fields == '\0')) fields = NULL; if (fields) { char *pnext; fieldnames = epicsStrDup(fields); nfields = 1; pnext = fieldnames; while (*pnext && (pnext = strchr(pnext,' '))) { nfields++; while (*pnext == ' ') pnext++; } papfields = dbCalloc(nfields,sizeof(char *)); pnext = fieldnames; for (ifield = 0; ifield < nfields; ifield++) { papfields[ifield] = pnext; if (ifield < nfields - 1) { pnext = strchr(pnext, ' '); *pnext++ = 0; while (*pnext == ' ') pnext++; } } } dbInitEntry(pdbbase, pdbentry); if (!precordTypename) status = dbFirstRecordType(pdbentry); else status = dbFindRecordType(pdbentry,precordTypename); if (status) { printf("No record type\n"); } while (!status) { status = dbFirstRecord(pdbentry); while (!status) { printf("%s", dbGetRecordName(pdbentry)); for (ifield = 0; ifield < nfields; ifield++) { char *pvalue; status = dbFindField(pdbentry, papfields[ifield]); if (status) { if (!strcmp(papfields[ifield], "recordType")) { pvalue = dbGetRecordTypeName(pdbentry); } else { printf(", "); continue; } } else { pvalue = dbGetString(pdbentry); } printf(", \"%s\"", pvalue ? pvalue : ""); } printf("\n"); status = dbNextRecord(pdbentry); } if (precordTypename) break; status = dbNextRecordType(pdbentry); } if (nfields > 0) { free((void *)papfields); free((void *)fieldnames); } dbFinishEntry(pdbentry); return 0; }
static long dbPutFieldLink(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest) { dbCommon *precord = paddr->precord; dbFldDes *pfldDes = paddr->pfldDes; long special = paddr->special; DBLINK *plink = (DBLINK *)paddr->pfield; const char *pstring = (const char *)pbuffer; DBENTRY dbEntry; DBADDR dbaddr; struct dsxt *old_dsxt = NULL; struct dset *new_dset = NULL; struct dsxt *new_dsxt = NULL; long status; int isDevLink; short scan; switch (dbrType) { case DBR_CHAR: case DBR_UCHAR: if (pstring[nRequest - 1] != '\0') return S_db_badDbrtype; break; case DBR_STRING: break; default: return S_db_badDbrtype; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, precord->name); if (!status) status = dbFindField(&dbEntry, pfldDes->name); if (status) goto finish; isDevLink = ellCount(&precord->rdes->devList) > 0 && (strcmp(pfldDes->name, "INP") == 0 || strcmp(pfldDes->name, "OUT") == 0); dbLockSetGblLock(); dbLockSetRecordLock(precord); scan = precord->scan; if (isDevLink) { devSup *pdevSup = dbDTYPtoDevSup(precord->rdes, precord->dtyp); if (pdevSup) { new_dset = pdevSup->pdset; new_dsxt = pdevSup->pdsxt; } if (precord->dset) { pdevSup = dbDSETtoDevSup(precord->rdes, precord->dset); if (pdevSup) old_dsxt = pdevSup->pdsxt; } if (new_dsxt == NULL || new_dsxt->add_record == NULL || (precord->dset && old_dsxt == NULL) || (old_dsxt && old_dsxt->del_record == NULL)) { status = S_db_noSupport; goto unlock; } if (scan == menuScanI_O_Intr) { scanDelete(precord); precord->scan = menuScanPassive; } if (old_dsxt) { status = old_dsxt->del_record(precord); if (status) goto restoreScan; } } switch (plink->type) { /* Old link type */ case DB_LINK: free(plink->value.pv_link.pvt); plink->value.pv_link.pvt = 0; plink->type = PV_LINK; plink->value.pv_link.getCvt = 0; plink->value.pv_link.pvlMask = 0; plink->value.pv_link.lastGetdbrType = 0; dbLockSetSplit(precord); break; case CA_LINK: dbCaRemoveLink(plink); plink->type = PV_LINK; plink->value.pv_link.getCvt = 0; plink->value.pv_link.pvlMask = 0; plink->value.pv_link.lastGetdbrType = 0; break; case CONSTANT: break; /* do nothing */ case PV_LINK: case MACRO_LINK: break; /* should never get here */ default: /* Hardware address */ if (!isDevLink) { status = S_db_badHWaddr; goto restoreScan; } break; } if (special) status = dbPutSpecial(paddr, 0); if (!status) status = dbPutString(&dbEntry, pstring); if (!status && special) status = dbPutSpecial(paddr, 1); if (status) { if (isDevLink) { precord->dset = NULL; precord->pact = TRUE; } goto postScanEvent; } if (isDevLink) { precord->dpvt = NULL; precord->dset = new_dset; precord->pact = FALSE; status = new_dsxt->add_record(precord); if (status) { precord->dset = NULL; precord->pact = TRUE; goto postScanEvent; } } switch (plink->type) { /* New link type */ case PV_LINK: if (plink == &precord->tsel) recGblTSELwasModified(plink); plink->value.pv_link.precord = precord; if (!(plink->value.pv_link.pvlMask & (pvlOptCA|pvlOptCP|pvlOptCPP)) && (dbNameToAddr(plink->value.pv_link.pvname, &dbaddr) == 0)) { /* It's a DB link */ DBADDR *pdbAddr; plink->type = DB_LINK; pdbAddr = dbMalloc(sizeof(struct dbAddr)); *pdbAddr = dbaddr; /* NB: structure copy */; plink->value.pv_link.pvt = pdbAddr; dbLockSetRecordLock(pdbAddr->precord); dbLockSetMerge(precord, pdbAddr->precord); } else { /* Make it a CA link */ char *pperiod; plink->type = CA_LINK; if (pfldDes->field_type == DBF_INLINK) { plink->value.pv_link.pvlMask |= pvlOptInpNative; } dbCaAddLink(plink); if (pfldDes->field_type == DBF_FWDLINK) { pperiod = strrchr(plink->value.pv_link.pvname, '.'); if (pperiod && strstr(pperiod, "PROC")) plink->value.pv_link.pvlMask |= pvlOptFWD; } } break; case CONSTANT: break; case DB_LINK: case CA_LINK: case MACRO_LINK: break; /* should never get here */ default: /* Hardware address */ if (!isDevLink) { status = S_db_badHWaddr; goto postScanEvent; } break; } db_post_events(precord, plink, DBE_VALUE | DBE_LOG); restoreScan: if (isDevLink && scan == menuScanI_O_Intr) { /* undo scanDelete() */ precord->scan = scan; scanAdd(precord); } postScanEvent: if (scan != precord->scan) db_post_events(precord, &precord->scan, DBE_VALUE|DBE_LOG); unlock: dbLockSetGblUnlock(); finish: dbFinishEntry(&dbEntry); return status; }