long dbPutSpecial(DBADDR *paddr,int pass) { long int (*pspecial)()=NULL; struct rset *prset; dbCommon *precord = paddr->precord; long status=0; long special=paddr->special; prset = dbGetRset(paddr); if(special<100) { /*global processing*/ if((special==SPC_NOMOD) && (pass==0)) { status = S_db_noMod; recGblDbaddrError(status,paddr,"dbPut"); return(status); }else if(special==SPC_SCAN){ if(pass==0) scanDelete(precord); else scanAdd(precord); }else if((special==SPC_AS) && (pass==1)) { if(spcAsCallback) (*spcAsCallback)(precord); } }else { if( prset && (pspecial = (prset->special))) { status=(*pspecial)(paddr,pass); if(status) return(status); } else if(pass==0){ recGblRecSupError(S_db_noSupport,paddr,"dbPut", "special"); return(S_db_noSupport); } } return(0); }
/* Convert Float to String */ static long cvt_f_st( epicsFloat32 *from, char *to, const dbAddr *paddr) { struct rset *prset = 0; long status = 0; long precision = 6; if(paddr) prset = dbGetRset(paddr); if (prset && prset->get_precision) status = (*prset->get_precision)(paddr, &precision); cvtFloatToString(*from, to, (unsigned short)precision); return(status); }
/* Convert Double to String */ static long cvt_d_st( epicsFloat64 *from, char *to, const dbAddr *paddr) { struct rset *prset = 0; long status = 0; long precision = 6; if(paddr) prset = dbGetRset(paddr); if (prset && prset->get_precision) status = (*prset->get_precision)(paddr, &precision); cvtDoubleToString(*from, to, precision); return(status); }
/* Get Enumerated to String */ static long cvt_e_st_get( epicsEnum16 *from, char *to, const dbAddr *paddr) { struct rset *prset = 0; long status; if(paddr) prset = dbGetRset(paddr); if (prset && prset->get_enum_str) return (*prset->get_enum_str)(paddr, to); status = S_db_noRSET; recGblRecSupError(status, paddr, "dbGetField", "get_enum_str"); return(S_db_badDbrtype); }
/* Convert String to Enumerated */ static long cvt_st_e( char *from, epicsEnum16 *to, const dbAddr *paddr) { struct rset *prset = 0; long status; epicsEnum16 *pfield= (epicsEnum16*)(paddr->pfield); unsigned int nchoices,ind; int nargs,nchars; struct dbr_enumStrs enumStrs; if(paddr && (prset=dbGetRset(paddr)) && (prset->put_enum_str)) { status = (*prset->put_enum_str)(paddr,from); if(!status) return(0); if(prset->get_enum_strs) { status = (*prset->get_enum_strs)(paddr,&enumStrs); if(!status) { nchoices = enumStrs.no_str; nargs = sscanf(from,"%u%n",&ind,&nchars); if(nargs==1 && nchars==strlen(from) && ind<nchoices) { *pfield = ind; return(0); } status = S_db_badChoice; } } else { status=S_db_noRSET; } } else { status=S_db_noRSET; } if(status == S_db_noRSET) { recGblRecSupError(status,paddr,"dbPutField","put_enum_str"); } else { recGblRecordError(status,(void *)paddr->precord,from); } return(status); }
static void hookPass1(initHookState state) { DBENTRY entry; DBADDR addr; if(state!=initHookAfterInitDatabase) return; testDiag("initHookAfterInitDatabase"); dbInitEntry(pdbbase, &entry); if(dbFindRecord(&entry, "rec0.VAL")==0) { aoRecord *prec = entry.precnode->precord; testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val); testOk1(dbPutString(&entry, "4")==0); testOk(prec->val==4, "VAL %d==4", (int)prec->val); } else{ testFail("Missing rec0"); testSkip(1, "missing record"); } /* Can't restore links in pass 1 */ if(dbNameToAddr("rec1.VAL", &addr)) { testFail("missing rec1"); testSkip(3, "missing record"); } else { struct rset *prset = dbGetRset(&addr); dbfType ftype = addr.field_type; long count=-1, offset=-1, maxcount = addr.no_elements; testOk1(prset && prset->get_array_info && prset->put_array_info); testOk1((*prset->get_array_info)(&addr, &count, &offset)==0); /* count is ignored */ testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0); testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0); } dbFinishEntry(&entry); }
dbChannel * dbChannelCreate(const char *name) { const char *pname = name; DBENTRY dbEntry; dbChannel *chan = NULL; char *cname; dbAddr *paddr; dbFldDes *pflddes; long status; short dbfType; if (!name || !*name || !pdbbase) return NULL; status = pvNameLookup(&dbEntry, &pname); if (status) goto finish; chan = freeListCalloc(dbChannelFreeList); if (!chan) goto finish; cname = malloc(strlen(name) + 1); if (!cname) goto finish; strcpy(cname, name); chan->name = cname; ellInit(&chan->filters); ellInit(&chan->pre_chain); ellInit(&chan->post_chain); paddr = &chan->addr; pflddes = dbEntry.pflddes; dbfType = pflddes->field_type; paddr->precord = dbEntry.precnode->precord; paddr->pfield = dbEntry.pfield; paddr->pfldDes = pflddes; paddr->no_elements = 1; paddr->field_type = dbfType; paddr->field_size = pflddes->size; paddr->special = pflddes->special; paddr->dbr_field_type = mapDBFToDBR[dbfType]; if (paddr->special == SPC_DBADDR) { struct rset *prset = dbGetRset(paddr); /* Let record type modify paddr */ if (prset && prset->cvt_dbaddr) { status = prset->cvt_dbaddr(paddr); if (status) goto finish; dbfType = paddr->field_type; } } /* Handle field modifiers */ if (*pname) { if (*pname == '$') { /* Some field types can be accessed as char arrays */ if (dbfType == DBF_STRING) { paddr->no_elements = paddr->field_size; paddr->field_type = DBF_CHAR; paddr->field_size = 1; paddr->dbr_field_type = DBR_CHAR; } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { /* Clients see a char array, but keep original dbfType */ paddr->no_elements = PVNAME_STRINGSZ + 12; paddr->field_size = 1; paddr->dbr_field_type = DBR_CHAR; } else { status = S_dbLib_fieldNotFound; goto finish; } pname++; } if (*pname == '[') { status = parseArrayRange(chan, pname, &pname); if (status) goto finish; } /* JSON may follow */ if (*pname == '{') { status = chf_parse(chan, &pname); if (status) goto finish; } /* Make sure there's nothing else */ if (*pname) { status = S_dbLib_fieldNotFound; goto finish; } } finish: if (status && chan) { dbChannelDelete(chan); chan = NULL; } dbFinishEntry(&dbEntry); return chan; }
long dbGet(DBADDR *paddr, short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { char *pbuf = pbuffer; void *pfieldsave = paddr->pfield; db_field_log *pfl = (db_field_log *)pflin; short field_type; long capacity, no_elements, offset; struct rset *prset; long status = 0; if (options && *options) getOptions(paddr, &pbuf, options, pflin); if (nRequest && *nRequest == 0) return 0; if (!pfl || pfl->type == dbfl_type_rec) { field_type = paddr->field_type; no_elements = capacity = paddr->no_elements; /* Update field info from record * may modify paddr->pfield */ if (paddr->pfldDes->special == SPC_DBADDR && (prset = dbGetRset(paddr)) && prset->get_array_info) { status = prset->get_array_info(paddr, &no_elements, &offset); } else offset = 0; } else { field_type = pfl->field_type; no_elements = capacity = pfl->no_elements; offset = 0; } if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) { status = getLinkValue(paddr, dbrType, pbuf, nRequest); goto done; } if (paddr->special == SPC_ATTRIBUTE) { status = getAttrValue(paddr, dbrType, pbuf, nRequest); goto done; } /* Check for valid request */ if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) { char message[80]; sprintf(message, "dbGet: Request type is %d\n", dbrType); recGblDbaddrError(S_db_badDbrtype, paddr, message); status = S_db_badDbrtype; goto done; } if (offset == 0 && (!nRequest || no_elements == 1)) { if (nRequest) *nRequest = 1; if (!pfl || pfl->type == dbfl_type_rec) { status = dbFastGetConvertRoutine[field_type][dbrType] (paddr->pfield, pbuf, paddr); } else { DBADDR localAddr = *paddr; /* Structure copy */ localAddr.field_type = pfl->field_type; localAddr.field_size = pfl->field_size; localAddr.no_elements = pfl->no_elements; if (pfl->type == dbfl_type_val) localAddr.pfield = (char *) &pfl->u.v.field; else localAddr.pfield = (char *) pfl->u.r.field; status = dbFastGetConvertRoutine[field_type][dbrType] (localAddr.pfield, pbuf, &localAddr); } } else { long n; GETCONVERTFUNC convert; if (nRequest) { if (no_elements < *nRequest) *nRequest = no_elements; n = *nRequest; } else { n = 1; } convert = dbGetConvertRoutine[field_type][dbrType]; if (!convert) { char message[80]; sprintf(message, "dbGet: Missing conversion for [%d][%d]\n", field_type, dbrType); recGblDbaddrError(S_db_badDbrtype, paddr, message); status = S_db_badDbrtype; goto done; } /* convert data into the caller's buffer */ if (n <= 0) { ;/*do nothing*/ } else if (!pfl || pfl->type == dbfl_type_rec) { status = convert(paddr, pbuf, n, capacity, offset); } else { DBADDR localAddr = *paddr; /* Structure copy */ localAddr.field_type = pfl->field_type; localAddr.field_size = pfl->field_size; localAddr.no_elements = pfl->no_elements; if (pfl->type == dbfl_type_val) localAddr.pfield = (char *) &pfl->u.v.field; else localAddr.pfield = (char *) pfl->u.r.field; status = convert(&localAddr, pbuf, n, capacity, offset); } } done: paddr->pfield = pfieldsave; return status; }
/* * Fill out a database structure (*paddr) for * a record given by the name "pname." * * Returns error codes from StaticLib module, not * from dbAccess. */ long dbNameToAddr(const char *pname, DBADDR *paddr) { DBENTRY dbEntry; dbFldDes *pflddes; long status = 0; short dbfType; if (!pname || !*pname || !pdbbase) return S_db_notFound; dbInitEntry(pdbbase, &dbEntry); status = dbFindRecordPart(&dbEntry, &pname); if (status) goto finish; if (*pname == '.') ++pname; status = dbFindFieldPart(&dbEntry, &pname); if (status == S_dbLib_fieldNotFound) status = dbGetAttributePart(&dbEntry, &pname); if (status) goto finish; pflddes = dbEntry.pflddes; dbfType = pflddes->field_type; paddr->precord = dbEntry.precnode->precord; paddr->pfield = dbEntry.pfield; paddr->pfldDes = pflddes; paddr->no_elements = 1; paddr->field_type = dbfType; paddr->field_size = pflddes->size; paddr->special = pflddes->special; paddr->dbr_field_type = mapDBFToDBR[dbfType]; if (paddr->special == SPC_DBADDR) { struct rset *prset = dbGetRset(paddr); /* Let record type modify paddr */ if (prset && prset->cvt_dbaddr) { status = prset->cvt_dbaddr(paddr); if (status) goto finish; dbfType = paddr->field_type; } } /* Handle field modifiers */ if (*pname++ == '$') { /* Some field types can be accessed as char arrays */ if (dbfType == DBF_STRING) { paddr->no_elements = paddr->field_size; paddr->field_type = DBF_CHAR; paddr->field_size = 1; paddr->dbr_field_type = DBR_CHAR; } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { /* Clients see a char array, but keep original dbfType */ paddr->no_elements = PVNAME_STRINGSZ + 12; paddr->field_size = 1; paddr->dbr_field_type = DBR_CHAR; } else { status = S_dbLib_fieldNotFound; goto finish; } } finish: dbFinishEntry(&dbEntry); return status; }
/* * This code relies on *poriginal being aligned and all increments done by the * blocks only changing the buffer pointer in a way that does not break alignment. */ static void getOptions(DBADDR *paddr, char **poriginal, long *options, void *pflin) { db_field_log *pfl= (db_field_log *)pflin; struct rset *prset; short field_type; dbCommon *pcommon; char *pbuffer = *poriginal; if (!pfl || pfl->type == dbfl_type_rec) field_type = paddr->field_type; else field_type = pfl->field_type; prset=dbGetRset(paddr); /* Process options */ pcommon = paddr->precord; if( (*options) & DBR_STATUS ) { unsigned short *pushort = (unsigned short *)pbuffer; if (!pfl || pfl->type == dbfl_type_rec) { *pushort++ = pcommon->stat; *pushort++ = pcommon->sevr; } else { *pushort++ = pfl->stat; *pushort++ = pfl->sevr; } *pushort++ = pcommon->acks; *pushort++ = pcommon->ackt; pbuffer = (char *)pushort; } if( (*options) & DBR_UNITS ) { memset(pbuffer,'\0',dbr_units_size); if( prset && prset->get_units ){ (*prset->get_units)(paddr, pbuffer); pbuffer[DB_UNITS_SIZE-1] = '\0'; } else { *options ^= DBR_UNITS; /*Turn off DBR_UNITS*/ } pbuffer += dbr_units_size; } if( (*options) & DBR_PRECISION ) { memset(pbuffer, '\0', dbr_precision_size); if((field_type==DBF_FLOAT || field_type==DBF_DOUBLE) && prset && prset->get_precision ){ (*prset->get_precision)(paddr,pbuffer); } else { *options ^= DBR_PRECISION; /*Turn off DBR_PRECISION*/ } pbuffer += dbr_precision_size; } if( (*options) & DBR_TIME ) { epicsUInt32 *ptime = (epicsUInt32 *)pbuffer; if (!pfl || pfl->type == dbfl_type_rec) { *ptime++ = pcommon->time.secPastEpoch; *ptime++ = pcommon->time.nsec; } else { *ptime++ = pfl->time.secPastEpoch; *ptime++ = pfl->time.nsec; } pbuffer = (char *)ptime; } if( (*options) & DBR_ENUM_STRS ) get_enum_strs(paddr, &pbuffer, prset, options); if( (*options) & (DBR_GR_LONG|DBR_GR_DOUBLE )) get_graphics(paddr, &pbuffer, prset, options); if((*options) & (DBR_CTRL_LONG | DBR_CTRL_DOUBLE )) get_control(paddr, &pbuffer, prset, options); if((*options) & (DBR_AL_LONG | DBR_AL_DOUBLE )) get_alarm(paddr, &pbuffer, prset, options); *poriginal = pbuffer; }
long dbPut(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest) { dbCommon *precord = paddr->precord; short field_type = paddr->field_type; long no_elements = paddr->no_elements; long special = paddr->special; void *pfieldsave = paddr->pfield; struct rset *prset = dbGetRset(paddr); long status = 0; long offset; dbFldDes *pfldDes; int isValueField; if (special == SPC_ATTRIBUTE) return S_db_noMod; if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) { return putAckt(paddr, pbuffer, 1, 1, 0); } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) { return putAcks(paddr, pbuffer, 1, 1, 0); } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) { char message[80]; sprintf(message, "dbPut: Request type is %d", dbrType); recGblDbaddrError(S_db_badDbrtype, paddr, message); return S_db_badDbrtype; } if (special) { status = dbPutSpecial(paddr, 0); if (status) return status; } if (paddr->pfldDes->special == SPC_DBADDR && prset && prset->get_array_info) { long dummy; status = prset->get_array_info(paddr, &dummy, &offset); /* paddr->pfield may be modified */ if (status) goto done; } else offset = 0; if (no_elements <= 1) { status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer, paddr->pfield, paddr); nRequest = 1; } else { if (no_elements < nRequest) nRequest = no_elements; status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer, nRequest, no_elements, offset); } /* update array info */ if (!status && paddr->pfldDes->special == SPC_DBADDR && prset && prset->put_array_info) { status = prset->put_array_info(paddr, nRequest); } /* Always do special processing if needed */ if (special) { long status2 = dbPutSpecial(paddr, 1); if (status2) goto done; } if (status) goto done; /* Propagate monitor events for this field, */ /* unless the field is VAL and PP is true. */ pfldDes = paddr->pfldDes; isValueField = dbIsValueField(pfldDes); if (isValueField) precord->udf = FALSE; if (precord->mlis.count && !(isValueField && pfldDes->process_passive)) db_post_events(precord, pfieldsave, DBE_VALUE | DBE_LOG); /* If this field is a property (metadata) field, * then post a property change event (even if the field * didn't change). */ if (precord->mlis.count && pfldDes->prop) db_post_events(precord, NULL, DBE_PROPERTY); done: paddr->pfield = pfieldsave; return status; }
long epicsShareAPI dbGet(DBADDR *paddr, short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { db_field_log *pfl = (db_field_log *)pflin; short field_type = paddr->field_type; long no_elements = paddr->no_elements; long offset; struct rset *prset; long status = 0; if (options && *options) { char *pbuf = pbuffer; getOptions(paddr, &pbuf, options, pflin); pbuffer = pbuf; } if (nRequest && *nRequest == 0) return 0; if (paddr->special == SPC_ATTRIBUTE) { char *pbuf = pbuffer; int maxlen; if (!paddr->pfield) return S_db_badField; switch (dbrType) { case DBR_STRING: maxlen = MAX_STRING_SIZE - 1; if (nRequest && *nRequest > 1) *nRequest = 1; break; case DBR_CHAR: case DBR_UCHAR: if (nRequest && *nRequest > 0) { maxlen = *nRequest - 1; break; } /* else fall through ... */ default: return S_db_badDbrtype; } strncpy(pbuf, (char *)paddr->pfield, maxlen); pbuf[maxlen] = 0; return 0; } /* Check for valid request */ if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) { char message[80]; sprintf(message, "dbGet: Request type is %d\n", dbrType); recGblDbaddrError(S_db_badDbrtype, paddr, message); return S_db_badDbrtype; } /* check for array */ if (paddr->special == SPC_DBADDR && no_elements > 1 && (prset = dbGetRset(paddr)) && prset->get_array_info) { status = prset->get_array_info(paddr, &no_elements, &offset); } else offset = 0; if (offset == 0 && (!nRequest || no_elements == 1)) { if (nRequest) *nRequest = 1; if (pfl != NULL) { DBADDR localAddr = *paddr; /* Structure copy */ localAddr.pfield = (char *)&pfl->field; status = dbFastGetConvertRoutine[field_type][dbrType] (localAddr.pfield, pbuffer, &localAddr); } else { status = dbFastGetConvertRoutine[field_type][dbrType] (paddr->pfield, pbuffer, paddr); } } else { long n; long (*convert)(); if (nRequest) { if (no_elements<(*nRequest)) *nRequest = no_elements; n = *nRequest; } else { n = 1; } convert = dbGetConvertRoutine[field_type][dbrType]; if (!convert) { char message[80]; sprintf(message, "dbGet: Missing conversion for [%d][%d]\n", field_type, dbrType); recGblDbaddrError(S_db_badDbrtype, paddr, message); return S_db_badDbrtype; } /* convert database field and place it in the buffer */ if (n <= 0) { ;/*do nothing*/ } else if (pfl) { DBADDR localAddr = *paddr; /* Structure copy */ localAddr.pfield = (char *)&pfl->field; status = convert(&localAddr, pbuffer, n, no_elements, offset); } else { status = convert(paddr, pbuffer, n, no_elements, offset); } } return status; }
/* * Fill out a database structure (*paddr) for * a record given by the name "pname." * * Returns error codes from StaticLib module, not * from dbAccess. */ long epicsShareAPI dbNameToAddr(const char *pname, DBADDR *paddr) { DBENTRY dbEntry; dbFldDes *pflddes; struct rset *prset; long status = 0; long no_elements = 1; short dbfType, dbrType, field_size; if (!pname || !*pname || !pdbbase) return S_db_notFound; dbInitEntry(pdbbase, &dbEntry); status = dbFindRecordPart(&dbEntry, &pname); if (status) goto finish; if (*pname == '.') ++pname; status = dbFindFieldPart(&dbEntry, &pname); if (status == S_dbLib_fieldNotFound) status = dbGetAttributePart(&dbEntry, &pname); if (status) goto finish; paddr->precord = dbEntry.precnode->precord; paddr->pfield = dbEntry.pfield; pflddes = dbEntry.pflddes; dbfType = pflddes->field_type; dbrType = mapDBFToDBR[dbfType]; field_size = pflddes->size; if (*pname++ == '$') { /* Some field types can be accessed as char arrays */ if (dbfType == DBF_STRING) { dbfType = DBF_CHAR; dbrType = DBR_CHAR; no_elements = field_size; field_size = 1; } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { /* Clients see a char array, but keep original dbfType */ dbrType = DBR_CHAR; no_elements = PVNAME_STRINGSZ + 12; field_size = 1; } else { status = S_dbLib_fieldNotFound; goto finish; } } paddr->pfldDes = pflddes; paddr->field_type = dbfType; paddr->dbr_field_type = dbrType; paddr->field_size = field_size; paddr->special = pflddes->special; paddr->no_elements = no_elements; if ((paddr->special == SPC_DBADDR) && (prset = dbGetRset(paddr)) && prset->cvt_dbaddr) /* cvt_dbaddr routine may change any of these elements of paddr: * pfield, no_elements, element_offset, field_type, * dbr_field_type, field_size, and/or special. */ status = prset->cvt_dbaddr(paddr); finish: dbFinishEntry(&dbEntry); return status; }
long epicsShareAPI dbPut(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest) { dbCommon *precord = paddr->precord; short field_type = paddr->field_type; long no_elements = paddr->no_elements; long special = paddr->special; long offset; long status = 0; dbFldDes *pfldDes; int isValueField; if (special == SPC_ATTRIBUTE) return S_db_noMod; if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) { return putAckt(paddr, (unsigned short *)pbuffer, 1, 1, 0); } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) { return putAcks(paddr, (unsigned short *)pbuffer, 1, 1, 0); } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) { char message[80]; sprintf(message, "dbPut: Request type is %d", dbrType); recGblDbaddrError(S_db_badDbrtype, paddr, message); return S_db_badDbrtype; } if (special) { status = dbPutSpecial(paddr, 0); if (status) return status; } if (no_elements <= 1) { status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer, paddr->pfield, paddr); } else { struct rset *prset = dbGetRset(paddr); if (paddr->special == SPC_DBADDR && prset && prset->get_array_info) { long dummy; status = prset->get_array_info(paddr, &dummy, &offset); } else offset = 0; if (no_elements < nRequest) nRequest = no_elements; if (!status) status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer, nRequest, no_elements, offset); /* update array info */ if (!status && paddr->special == SPC_DBADDR && prset && prset->put_array_info) { status = prset->put_array_info(paddr, nRequest); } } if (status) return status; /* check if special processing is required */ if (special) { status = dbPutSpecial(paddr,1); if (status) return status; } /* Propagate monitor events for this field, */ /* unless the field field is VAL and PP is true. */ pfldDes = paddr->pfldDes; isValueField = dbIsValueField(pfldDes); if (isValueField) precord->udf = FALSE; if (precord->mlis.count && !(isValueField && pfldDes->process_passive)) db_post_events(precord, paddr->pfield, DBE_VALUE | DBE_LOG); return status; }