diff --git a/src/db/dbAccess.c b/src/db/dbAccess.c new file mode 100644 index 000000000..11101caba --- /dev/null +++ b/src/db/dbAccess.c @@ -0,0 +1,5905 @@ + +/* dbAccess.c */ +/* share/src/db $Id$ */ + + +/*dbAccess.c + * + * This is the former IOCDBACCESS.C + * + * database access subroutines + * + * Author: Bob Dalesio(LANL) and Marty Kraimer(ANL) + * Date: 11/7/90 + * + * Control System Software for the GTA Project + * + * Copyright 1988, 1989, the Regents of the University of California. + * + * This software was produced under a U.S. Government contract + * (W-7405-ENG-36) at the Los Alamos National Laboratory, which is + * operated by the University of California for the U.S. Department + * of Energy. + * + * Developed by the Controls and Automation Group (AT-8) + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Direct inqueries to: + * Bob Dalesio, AT-8, Mail Stop H820 + * Los Alamos National Laboratory + * Los Alamos, New Mexico 87545 + * Phone: (505) 667-3414 + * E-mail: dalesio@luke.lanl.gov + * + * Modification Log: + * ----------------- + * .xx mm-dd-yy mrk Comment + * + */ + +/* Global Database Access Routines + * + * dbScanLock(precord) Lock for scanning records + * caddr_t precord; + * returns void + * + * dbScanUnlock(precord) Unlock for scanning records + * caddr_t precord; + * returns void + * + * dbScanLockInit(nset) Initialize scan lock + * int nset; + * + * dbScanPassive(paddr) process if record is passively scanned + * struct dbAddr *paddr; pointer to database address structure + * + * dbProcess(paddr) process a database record + * struct dbAddr *paddr; pointer to database address structure + * + * dbNameToAddr(pname,paddr) Given "pv<.field>" compute dbAddr + * char *pname + * struct dbAddr *paddr; pointer to database address structure + * + * dbGetLink(paddr,dbrType,pbuffer,options,nRequest) + * struct dbAddr *paddr; + * short dbrType; DBR_xxx + * caddr_t pbuffer; addr of returned data + * long *options; addr of options + * long *nRequest; addr of number of elements + * + * dbPutField(paddr,dbrType,pbuffer,nRequest) + * struct dbAddr *paddr; + * short dbrType; DBR_xxx + * caddr_t pbuffer; addr of input data + * long nRequest; + * + * dbBufferSize(dbr_type,options,no_elements) + * short dbr_type; + * long options; + * long no_elements; + * returns: number of bytes as a long + * + * dbGetField(paddr,dbrType,pbuffer,options,nRequest) + * struct dbAddr *paddr; + * short dbrType; DBR_xxx + * caddr_t pbuffer; addr of returned data + * long *options; addr of options + * long *nRequest; addr of number of elements + * + * dbPutLink(paddr,dbrType,pbuffer,nRequest) + * struct dbAddr *paddr; + * short dbrType; DBR_xxx + * caddr_t pbuffer; addr of input data + * long nRequest; + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long dbPut(); + +#define MIN(x,y) ((x < y)?x:y) +#define MAX(x,y) ((x > y)?x:y) + +struct scanLock{ + FAST_LOCK lock; + caddr_t precord; + ULONG start_time; + int task_id; +}; +static struct { + int nset; /* Number of sets */ + struct scanLock *pscanLock; /*addr of array of struct scanLock */ +} dbScanPvt; + +void dbScanLock(precord) + caddr_t precord; +{ + struct scanLock *pscanLock; + short lset=((struct dbCommon *)precord)->lset - 1; + + if(lset<0 || lset>=dbScanPvt.nset) { + errMessage(S_db_badLset,"Lock Set out of range"); + exit(1); + } + pscanLock = dbScanPvt.pscanLock + lset; + FASTLOCK(&pscanLock->lock); + pscanLock->start_time = tickGet(); + pscanLock->task_id = taskIdSelf(); + pscanLock->precord = precord; + return; +} + +void dbScanUnlock(precord) + caddr_t precord; +{ + struct scanLock *pscanLock; + short lset=((struct dbCommon *)precord)->lset - 1; + + if(lset<0 || lset>=dbScanPvt.nset) { + errMessage(S_db_badLset,"Lock Set out of range"); + return; + } + pscanLock = dbScanPvt.pscanLock + lset; + pscanLock->precord = NULL; + FASTUNLOCK(&pscanLock->lock); + return; +} + +void dbScanLockInit(nset) + int nset; +{ + struct scanLock *pscanLock; + int i; + + dbScanPvt.nset = nset; + pscanLock = (struct scanLock *)calloc((size_t)nset, + (size_t)sizeof(struct scanLock)); + dbScanPvt.pscanLock = pscanLock; + for (i=0; ilock); + pscanLock->precord=NULL; + pscanLock->start_time=0; + pscanLock->task_id=0; + } + return; +} + +long dbScanPassive(paddr) + struct dbAddr *paddr; +{ + struct dbCommon *precord=(struct dbCommon *)(paddr->precord); + + /* if not passive just return success */ + if(precord->scan != 0) return(0); + + /* return result of process */ + return(dbProcess(paddr)); +} + +long dbProcess(paddr) + struct dbAddr *paddr; +{ + struct rset *prset; + struct dbCommon *precord=(struct dbCommon *)(paddr->precord); + long status; + long options=0; + long nRequest=1; + + + /* If already active dont process */ + if(precord->pact) return(0); + + /* get the scan disable link if defined*/ + if(precord->sdis.type == DB_LINK) { + (status = dbGetLink(precord->sdis.value.db_link, + DBR_SHORT,(caddr_t)(&(precord->disa)),&options,&nRequest)); + if(!RTN_SUCCESS(status)) { + recGblDbaddrError(status,paddr,"dbProcess"); + return(status); + } + } + /* if disabled just return success */ + if(precord->disa) return(0); + + /* locate record processing routine */ + precord->pact=1; + if(!(prset=GET_PRSET(paddr->record_type)) || !(prset->process)) { + recGblRecSupError(S_db_noRSET,paddr,"dbProcess","process"); + return(S_db_noRSET); + } + + /* process record */ + status = (*prset->process)(paddr); + return(status); + +} + +/* forward reference for pvdGetFld */ +struct fldDes *pvdGetFld(); + +long dbNameToAddr(pname,paddr) +char *pname; +struct dbAddr *paddr; +{ + char *pbuffer; + char buffer[PVNAME_SZ+FLDNAME_SZ+2]; + short field_offset; + short record_number; + short n; + long status; + struct rset *prset; + struct recLoc *precLoc; + char* precord; + struct fldDes *pfldDes; + + /* convert the record name */ + pbuffer = &buffer[0]; + n=0; + while(*pname && (*pname != '.') && nrecord_type),&record_number) < 0){ + (long)(paddr->precord) = -1; + paddr->record_type = -1; + return(S_db_notFound); + } + + /* convert the field name */ + if (*pname) pname++; + if (!(pfldDes=pvdGetFld(paddr->record_type,pname))){ + paddr->field_type = -1; + (long)(paddr->pfield) = -1; + paddr->field_size = -1; + return(S_db_notFound); + } + paddr->pfldDes = (caddr_t)pfldDes; + paddr->field_type = pfldDes->field_type; + paddr->dbr_field_type = pfldDes->dbr_field_type; + paddr->field_size = pfldDes->size; + paddr->choice_set = pfldDes->choice_set; + paddr->special = pfldDes->special; + field_offset = pfldDes->offset; + + /* get the memory location of the record and field */ + if(!(precLoc=GET_PRECLOC(paddr->record_type)) + || !(precord=GET_PRECORD(precLoc,record_number)) + || (paddr->field_size+field_offset) > (precLoc->rec_size)) { + recGblDbaddrError(S_db_notFound,paddr,"field_spec_to_mem_loc"); + (long)(paddr->pfield) = -1; + (long)(paddr->precord) = -1; + return(S_db_notFound); + } + paddr->precord=precord; + paddr->pfield=precord+field_offset; + + /*if special is SPC_DBADDR then call cvt_dbaddr */ + /*it may change pfield,no_elements,field_type,dbr_field_type,*/ + /*field_size,and special*/ + paddr->no_elements=1; + if( ((paddr->special)==SPC_DBADDR) + && (prset=GET_PRSET(paddr->record_type)) + && (prset->cvt_dbaddr) ) + status = (*prset->cvt_dbaddr)(paddr); + + return(status); +} + +long dbGetLink(pdblink,dbrType,pbuffer,options,nRequest) + struct db_link *pdblink; + short dbrType; + caddr_t pbuffer; + long *options; + long *nRequest; +{ + struct dbAddr *paddr=(struct dbAddr*)(pdblink->paddr); + long status; + + if(pdblink->process_passive) { + status=dbScanPassive(paddr); + if(!RTN_SUCCESS(status)) return(status); + } + return(dbGetField(paddr,dbrType,pbuffer,options,nRequest)); +} + +long dbPutLink(pdblink,dbrType,pbuffer,options,nRequest) + struct db_link *pdblink; + short dbrType; + caddr_t pbuffer; + long *options; + long *nRequest; +{ + struct dbAddr *paddr=(struct dbAddr*)(pdblink->paddr); + long status; + + status=dbPut(paddr,dbrType,pbuffer,nRequest); + if(!RTN_SUCCESS(status)) return(status); + if(pdblink->process_passive) status=dbScanPassive(paddr); + return(status); +} + +long dbPutField(paddr,dbrType,pbuffer,nRequest) + struct dbAddr *paddr; + short dbrType; + caddr_t pbuffer; + long nRequest; +{ + long status; + struct fldDes *pfldDes=(struct fldDes *)(paddr->pfldDes); + + dbScanLock(paddr->precord); + status=dbPut(paddr,dbrType,pbuffer,nRequest); + if(RTN_SUCCESS(status) && pfldDes->process_passive) status=dbScanPassive(paddr); + dbScanUnlock(paddr->precord); + return(status); +} + +long dbBufferSize(dbr_type,options,no_elements) + short dbr_type; + long options; + long no_elements; +{ + long nbytes=0; + + nbytes += dbr_value_size[dbr_type] * no_elements; + if(options & DBR_STATUS) nbytes += dbr_status_size; + if(options & DBR_UNITS) nbytes += dbr_units_size; + if(options & DBR_PRECISION) nbytes += dbr_precision_size; + if(options & DBR_TIME) nbytes += dbr_time_size; + if(options & DBR_ENUM_STRS) nbytes += dbr_enumStrs_size; + if(options& + (DBR_GR_UCHAR|DBR_GR_SHORT|DBR_GR_LONG|DBR_GR_ULONG|DBR_GR_FLOAT + |DBR_GR_DOUBLE)) { + if(options & DBR_GR_UCHAR)nbytes += dbr_grUchar_size; + else if(options & DBR_GR_SHORT) nbytes += dbr_grShort_size; + else if(options & DBR_GR_LONG) nbytes += dbr_grLong_size; + else if(options & DBR_GR_ULONG) nbytes += dbr_grUlong_size; + else if(options & DBR_GR_FLOAT) nbytes += dbr_grFloat_size; + else if(options & DBR_GR_DOUBLE)nbytes += dbr_grDouble_size; + } + if(options& + (DBR_CTRL_UCHAR|DBR_CTRL_SHORT|DBR_CTRL_LONG|DBR_CTRL_ULONG|DBR_CTRL_FLOAT + |DBR_CTRL_DOUBLE)) { + if(options & DBR_CTRL_UCHAR) nbytes += dbr_ctrlUchar_size; + else if(options & DBR_CTRL_SHORT)nbytes += dbr_ctrlShort_size; + else if(options & DBR_CTRL_LONG) nbytes += dbr_ctrlLong_size; + else if(options & DBR_CTRL_ULONG)nbytes += dbr_ctrlUlong_size; + else if(options & DBR_CTRL_FLOAT)nbytes += dbr_ctrlFloat_size; + else if(options & DBR_CTRL_DOUBLE)nbytes += dbr_ctrlDouble_size; + } + return(nbytes); +} + +/* + * F_TO_STR + * + * converts floating point numbers to NULL terminated strings + * + * This routine was written to provide fast conversion. + * Timing figures on a 68020 + * F_TO_STR .316 msec + * gcvt 2.6 msec + * sprintf[%9.3E] 33 msecs + * + * This routine will call gcvt for any number with an absolute value + * greater than or equal to 10,000,000.00 + * + */ +static long f_to_str(flt_value,pstr_value,precision) +double flt_value; +char *pstr_value; +int precision; +{ + unsigned short got_one; + double place; + short number; + char *pfirst_digit; + + pfirst_digit = pstr_value; + if (flt_value < 0){ + *pstr_value = '-'; + pstr_value++; + pfirst_digit++; + flt_value = -flt_value; + } + + if (flt_value >= 10000000 ){ + gcvt(flt_value,10,pstr_value); + return(0); + } + + /* whole numbers */ + got_one = 0; + for (place = 1000000; place >= 1; place /= 10){ + if (flt_value >= place){ + got_one = 1; + number = flt_value / place; + flt_value = flt_value - (number * place); + *pstr_value = number + '0'; + pstr_value++; + }else if (got_one){ + *pstr_value = '0'; + pstr_value++; + } + } + if (!got_one){ + *pstr_value = '0'; + pstr_value++; + } + + /* fraction */ + if (precision > 0){ + *pstr_value = '.'; + pstr_value++; + for (place = .1; precision > 0; place /= 10, precision--){ + number = flt_value / place; + flt_value = flt_value - (number * place); + *pstr_value = number + '0'; + pstr_value++; + } + } + *pstr_value = 0; + + /* rounding */ + if (flt_value >= (place * 5)){ + number = pstr_value - pfirst_digit; + pstr_value--; + while ((pstr_value >= pfirst_digit) && + ((*pstr_value == '9') || (*pstr_value == '.'))){ + if (*pstr_value == '9') + *pstr_value = '0'; + pstr_value--; + } + if (pstr_value < pfirst_digit){ + while (number >= 0){ + *(pfirst_digit + number + 1) = *(pfirst_digit + number); + number--; + } + *pfirst_digit = '1'; + }else{ + *pstr_value += 1; + } + } + return(0); +} + +/* Convert various integer types to ascii */ + +static char digit_to_ascii[10]={'0','1','2','3','4','5','6','7','8','9'}; + +static void char_to_str(source,pdest) + char source; + char *pdest; +{ + unsigned char val,temp; + char digit[3]; + int i,j; + + if(source==0) { + *pdest++ = '0'; + *pdest = 0; + return; + } + if(source<0) { + *pdest++ = '-'; + if(source == -128) { + strcpy(pdest,"128"); + return; + } + source = -source; + } + val = source; + for(i=0; val!=0; i++) { + temp = val/10; + digit[i] = digit_to_ascii[val - temp*10]; + val = temp; + } + for(j=i-1; j>=0; j--) { + *pdest++ = digit[j]; + } + *pdest = 0; + return; +} + +static void uchar_to_str(source,pdest) + unsigned char source; + char *pdest; +{ + unsigned char val,temp; + char digit[3]; + int i,j; + + if(source==0) { + *pdest++ = '0'; + *pdest = 0; + return; + } + val = source; + for(i=0; val!=0; i++) { + temp = val/10; + digit[i] = digit_to_ascii[val - temp*10]; + val = temp; + } + for(j=i-1; j>=0; j--) { + *pdest++ = digit[j]; + } + *pdest = 0; + return; +} + +static void short_to_str(source,pdest) + short source; + char *pdest; +{ + short val,temp; + char digit[6]; + int i,j; + + if(source==0) { + *pdest++ = '0'; + *pdest = 0; + return; + } + if(source<0) { + *pdest++ = '-'; + if(source == -32768) { + strcpy(pdest,"32768"); + return; + } + source = -source; + } + val = source; + for(i=0; val!=0; i++) { + temp = val/10; + digit[i] = digit_to_ascii[val - temp*10]; + val = temp; + } + for(j=i-1; j>=0; j--) { + *pdest++ = digit[j]; + } + *pdest = 0; + return; +} + +static void ushort_to_str(source,pdest) + unsigned short source; + char *pdest; +{ + unsigned short val,temp; + char digit[5]; + int i,j; + + if(source==0) { + *pdest++ = '0'; + *pdest = 0; + return; + } + val = source; + for(i=0; val!=0; i++) { + temp = val/10; + digit[i] = digit_to_ascii[val - temp*10]; + val = temp; + } + for(j=i-1; j>=0; j--) { + *pdest++ = digit[j]; + } + *pdest = 0; + return; +} + +static void long_to_str(source,pdest) + long source; + char *pdest; +{ + long val,temp; + char digit[11]; + int i,j; + + if(source==0) { + *pdest++ = '0'; + *pdest = 0; + return; + } + if(source<0) { + *pdest++ = '-'; + if(source == -2147483648) { + strcpy(pdest,"2147483648"); + return; + } + source = -source; + } + val = source; + for(i=0; val!=0; i++) { + temp = val/10; + digit[i] = digit_to_ascii[val - temp*10]; + val = temp; + } + for(j=i-1; j>=0; j--) { + *pdest++ = digit[j]; + } + *pdest = 0; + return; +} + +static void ulong_to_str(source,pdest) + unsigned long source; + char *pdest; +{ + unsigned long val,temp; + char digit[10]; + int i,j; + + if(source==0) { + *pdest++ = '0'; + *pdest = 0; + return; + } + val = source; + for(i=0; val!=0; i++) { + temp = val/10; + digit[i] = digit_to_ascii[val - temp*10]; + val = temp; + } + for(j=i-1; j>=0; j--) { + *pdest++ = digit[j]; + } + *pdest = 0; + return; +} + +/* DATABASE ACCESS GET CONVERSION SUPPORT */ + +static long getStringString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=paddr->pfield; + short size=paddr->field_size; + + if(nRequest==1 && offset==0) { + strncpy(pbuffer,psrc,size); + return(0); + } + psrc+= (size*offset); + while (nRequest) { + strncpy(pbuffer,psrc,size); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=paddr->pfield; + else + psrc += size; + nRequest--; + } + return(0); +} + +static long getCharString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + char_to_str(*psrc,pbuffer); + return(0); + } + psrc += offset; + while (nRequest) { + char_to_str(*psrc,pbuffer); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=(char *)paddr->pfield; + else + psrc++; + nRequest--; + } + return(0); +} + +static long getCharChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getCharUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getCharShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getCharUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getCharLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getCharUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getCharFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getCharDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getCharEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *psrc=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + uchar_to_str(*psrc,pbuffer); + return(0); + } + psrc += offset; + while (nRequest) { + uchar_to_str(*psrc,pbuffer); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=(unsigned char *)paddr->pfield; + else + psrc++; + nRequest--; + } + return(0); +} + +static long getUcharChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUcharEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *psrc=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getShortString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + short_to_str(*psrc,pbuffer); + return(0); + } + psrc += offset; + while (nRequest) { + short_to_str(*psrc,pbuffer); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=(short *)paddr->pfield; + else + psrc++; + nRequest--; + } + return(0); +} + +static long getShortChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getShortUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} +static long getShortShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getShortUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getShortLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getShortUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getShortFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getShortDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getShortEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *psrc=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUshortString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + ushort_to_str(*psrc,pbuffer); + return(0); + } + psrc += offset; + while (nRequest) { + ushort_to_str(*psrc,pbuffer); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=(unsigned short *)paddr->pfield; + else + psrc++; + nRequest--; + } + return(0); +} + +static long getUshortChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUshortUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} +static long getUshortShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUshortUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUshortLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUshortUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUshortFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUshortDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUshortEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + long_to_str(*psrc,pbuffer); + return(0); + } + psrc += offset; + while (nRequest) { + long_to_str(*psrc,pbuffer); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=(long *)paddr->pfield; + else + psrc++; + nRequest--; + } + return(0); +} + +static long getLongChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getLongEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *psrc=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + ulong_to_str(*psrc,pbuffer); + return(0); + } + psrc += offset; + while (nRequest) { + ulong_to_str(*psrc,pbuffer); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=(unsigned long *)paddr->pfield; + else + psrc++; + nRequest--; + } + return(0); +} + +static long getUlongChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getUlongEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *psrc=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + long status; + int precision; + short record_type=paddr->record_type; + struct rset *prset; + + if((prset=GET_PRSET(record_type)) && (prset->get_precision)) + status = (*prset->get_precision)(paddr,&precision); + else + status=S_db_precision; + if(!RTN_SUCCESS(status)) { + recGblRecSupError(status,paddr,"db_get_field","get_precision"); + return(status); + } + + if(nRequest==1 && offset==0) { + return(f_to_str((double)(*psrc),pbuffer,precision)); + } + psrc += offset; + while (nRequest) { + status=f_to_str((double)(*psrc),pbuffer,precision); + if(!RTN_SUCCESS(status)) return(status); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=(float *)paddr->pfield; + else + psrc++; + nRequest--; + } + return(0); +} + +static long getFloatChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + long ltemp; /*vxWorks does not support float to unsigned long*/ + + if(nRequest==1 && offset==0) { + ltemp = *psrc; + *pbuffer = ltemp; + return(0); + } + psrc += offset; + while (nRequest) { + ltemp = *psrc++; + *pbuffer++ = ltemp; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getFloatEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *psrc=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + long status; + int precision; + short record_type=paddr->record_type; + struct rset *prset; + + if((prset=GET_PRSET(record_type)) && (prset->get_precision)) + status = (*prset->get_precision)(paddr,&precision); + else + status=S_db_precision; + if(!RTN_SUCCESS(status)) { + recGblRecSupError(status,paddr,"db_get_field","get_precision"); + return(status); + } + + if(nRequest==1 && offset==0) { + return(f_to_str(*psrc,pbuffer,precision)); + } + psrc += offset; + while (nRequest) { + status=f_to_str(*psrc,pbuffer,precision); + if(!RTN_SUCCESS(status)) return(status); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + psrc=(double *)paddr->pfield; + else + psrc++; + nRequest--; + } + return(0); +} + +static long getDoubleChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + long ltemp; /*vxWorks does not support double to unsigned long*/ + + if(nRequest==1 && offset==0) { + ltemp = *psrc; + *pbuffer = ltemp; + return(0); + } + psrc += offset; + while (nRequest) { + ltemp = *psrc++; + *pbuffer++ = ltemp; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getDoubleEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *psrc=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + struct rset *prset; + short record_type=(paddr->record_type); + long status; + + if((prset=GET_PRSET(record_type)) && (prset->get_enum_str)) + return( (*prset->get_enum_str)(paddr,pbuffer) ); + status=S_db_noRSET; + recGblRecSupError(status,paddr,"db_get_field","get_enum_str"); + return(S_db_badDbrtype); +} + +static long getEnumChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getEnumEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pbuffer = *psrc; + return(0); + } + psrc += offset; + while (nRequest) { + *pbuffer++ = *psrc++; + if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long getGchoiceString(paddr,pbuffer,nRequest,no_elements,offset) + struct dbAddr *paddr; + char *pbuffer; + long nRequest; + long no_elements; + long offset; +{ + short choice_set=paddr->choice_set; + short choice_ind= *((short*)paddr->pfield); + char *pchoice; + struct choiceSet *pchoiceSet; + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbGetField(getGchoiceString)"); + return(S_db_onlyOne); + } + if((!(pchoiceSet=GET_PCHOICE_SET(choiceGbl,choice_set))) + || (!(pchoice=GET_CHOICE(pchoiceSet,choice_ind))) ) { + recGblDbaddrError(S_db_badChoice,paddr,"dbGetField(getGchoiceString)"); + return(S_db_badChoice); + } + strncpy(pbuffer,pchoice,MAX_STRING_SIZE); + return(0); +} + +static long getGchoiceEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbGetField(getGchoiceEnum)"); + return(S_db_onlyOne); + } + *pbuffer = *psrc; + return(0); +} + +static long getCchoiceString(paddr,pbuffer,nRequest,no_elements,offset) + struct dbAddr *paddr; + char *pbuffer; + long nRequest; + long no_elements; + long offset; +{ + short choice_ind= *((short*)paddr->pfield); + char *pchoice; + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbGetField(getCchoiceString)"); + return(S_db_onlyOne); + } + if (!(pchoice=GET_CHOICE(choiceCvt,choice_ind))) { + recGblDbaddrError(S_db_badChoice,paddr,"dbGetField(getCchoiceString)"); + return(S_db_badChoice); + } + strncpy(pbuffer,pchoice,MAX_STRING_SIZE); + return(0); +} + +static long getCchoiceEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbGetField(getCchoiceEnum)"); + return(S_db_onlyOne); + } + *pbuffer = *psrc; + return(0); +} + +static long getRchoiceString(paddr,pbuffer,nRequest,no_elements,offset) + struct dbAddr *paddr; + char *pbuffer; + long nRequest; + long no_elements; + long offset; +{ + short choice_set=paddr->choice_set; + short choice_ind= *((short*)paddr->pfield); + struct choiceSet *pchoiceSet; + struct arrChoiceSet *parrChoiceSet; + char *pchoice; + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbGetField(getRchoiceString)"); + return(S_db_onlyOne); + } + if((!(parrChoiceSet=GET_PARR_CHOICE_SET(choiceRec,(paddr->record_type)))) + || (!(pchoiceSet=GET_PCHOICE_SET(parrChoiceSet,choice_set))) + || (!(pchoice=GET_CHOICE(pchoiceSet,choice_ind))) ) { + recGblDbaddrError(S_db_badChoice,paddr,"dbGetField(getRchoiceString)"); + return(S_db_badChoice); + } + strncpy(pbuffer,pchoice,MAX_STRING_SIZE); + return(0); +} + +static long getRchoiceEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbGetField(getRchoiceEnum)"); + return(S_db_onlyOne); + } + *pbuffer = *psrc; + return(0); +} + +static long getDchoiceString(paddr,pbuffer,nRequest,no_elements,offset) + struct dbAddr *paddr; + char *pbuffer; + long nRequest; + long no_elements; + long offset; +{ + short choice_ind= *((short*)paddr->pfield); + struct devChoiceSet *pdevChoiceSet; + struct devChoice *pdevChoice; + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbGetField(getDchoiceString)"); + return(S_db_onlyOne); + } + if((!(pdevChoiceSet=GET_PDEV_CHOICE_SET(choiceDev,paddr->record_type))) + || (!(pdevChoice=GET_DEV_CHOICE(pdevChoiceSet,choice_ind))) ) { + recGblDbaddrError(S_db_badChoice,paddr,"dbGetField(getRchoiceString)"); + return(S_db_badChoice); + } + strncpy(pbuffer,pdevChoice->pchoice,MAX_STRING_SIZE); + return(0); +} + +static long getDchoiceEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *psrc=(unsigned short *)(paddr->pfield); + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbGetField(getDchoiceEnum)"); + return(S_db_onlyOne); + } + *pbuffer = *psrc; + return(0); +} + +/* This is the table of routines for converting database fields */ +/* the rows represent the field type of the database field */ +/* the columns represent the types of the buffer in which they are placed */ + +/* buffer types are******************************************************** + DBR_STRING, DBR_CHR, DBR_UCHAR, DBR_SHORT, DBR_USHORT, + DBR_LONG, DBR_ULONG, DBR_FLOAT, DBR_DOUBLE, DBR_ENUM + ***************************************************************************/ + +long (*get_convert_table[DBF_DEVCHOICE+1][DBR_ENUM+1])() = { + +/* source is a DBF_STRING */ +{getStringString, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL}, +/* source is a DBF_CHAR */ +{getCharString, getCharChar, getCharUchar, getCharShort, getCharUshort, + getCharLong, getCharUlong, getCharFloat, getCharDouble, getCharEnum}, +/* source is a DBF_UCHAR */ +{getUcharString, getUcharChar, getUcharUchar, getUcharShort, getUcharUshort, + getUcharLong, getUcharUlong, getUcharFloat, getUcharDouble, getUcharEnum}, +/* source is a DBF_SHORT */ +{getShortString, getShortChar, getShortUchar, getShortShort, getShortUshort, + getShortLong, getShortUlong, getShortFloat, getShortDouble, getShortEnum}, +/* source is a DBF_USHORT */ +{getUshortString, getUshortChar, getUshortUchar, getUshortShort, getUshortUshort, + getUshortLong, getUshortUlong, getUshortFloat, getUshortDouble, getUshortEnum}, +/* source is a DBF_LONG */ +{getLongString, getLongChar, getLongUchar, getLongShort, getLongUshort, + getLongLong, getLongUlong, getLongFloat, getLongDouble, getLongEnum}, +/* source is a DBF_ULONG */ +{getUlongString, getUlongChar, getUlongUchar, getUlongShort, getUlongUshort, + getUlongLong, getUlongUlong, getUlongFloat, getUlongDouble, getUlongEnum}, +/* source is a DBF_FLOAT */ +{getFloatString, getFloatChar, getFloatUchar, getFloatShort, getFloatUshort, + getFloatLong, getFloatUlong, getFloatFloat, getFloatDouble, getFloatEnum}, +/* source is a DBF_DOUBLE */ +{getDoubleString, getDoubleChar, getDoubleUchar, getDoubleShort, getDoubleUshort, + getDoubleLong, getDoubleUlong, getDoubleFloat, getDoubleDouble, getDoubleEnum}, +/* source is a DBF_ENUM */ +{getEnumString, getEnumChar, getEnumUchar, getEnumShort, getEnumUshort, + getEnumLong, getEnumUlong, getEnumFloat, getEnumDouble, getEnumEnum}, +/* source is a DBF_GBLCHOICE */ +{getGchoiceString,NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, getGchoiceEnum}, +/* source is a DBF_CVTCHOICE */ +{getCchoiceString,NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, getCchoiceEnum}, +/* source is a DBF_RECCHOICE */ +{getRchoiceString,NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, getRchoiceEnum}, +/* source is a DBF_DEVCHOICE */ +{getDchoiceString,NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, getDchoiceEnum} +}; + + +long dbGetField(paddr,dbrType,pbuffer,options,nRequest) +struct dbAddr *paddr; +short dbrType; +caddr_t pbuffer; +long *options; +long *nRequest; +{ + long no_elements=paddr->no_elements; + long offset; + struct rset *prset; + short field_type=paddr->field_type; + long (*pconvert_routine)(); + struct dbCommon *pcommon; + long status; + + + prset=GET_PRSET(paddr->record_type); + + if(!(*options)) goto GET_DATA; + + /* Process options */ + pcommon = (struct dbCommon *)(paddr->precord); + if( (*options) & DBR_STATUS ) { + *((unsigned short *)pbuffer)++ = pcommon->stat; + *((unsigned short *)pbuffer)++ = pcommon->sevr; + } + if( (*options) & DBR_UNITS ) { + if( prset && prset->get_units ){ + (*prset->get_units)(paddr,pbuffer); + } else { + bzero(pbuffer,dbr_units_size); + *options = (*options) ^ DBR_UNITS; /*Turn off DBR_UNITS*/ + } + pbuffer += dbr_units_size; + } + if( (*options) & DBR_PRECISION ) { + if((field_type==DBF_FLOAT || field_type==DBF_DOUBLE) && prset && prset->get_precision ){ + (*prset->get_precision)(paddr,pbuffer); + } else { + bzero(pbuffer,dbr_precision_size); + *options = (*options) ^ DBR_PRECISION; /*Turn off DBR_PRECISION*/ + } + pbuffer += dbr_precision_size; + } + if( (*options) & DBR_TIME ) { + *((unsigned long *)pbuffer)++ = pcommon->esec; + *((unsigned long *)pbuffer)++ = pcommon->nsec; + } + /* get_enum_strs, get_graphics, and get_control follow this procedure*/ + if( (*options) & DBR_ENUM_STRS ) get_enum_strs(paddr,&pbuffer,prset,options); + if( (*options) & (DBR_GR_UCHAR | DBR_GR_SHORT | DBR_GR_LONG + | DBR_GR_ULONG | DBR_GR_FLOAT | DBR_GR_DOUBLE )) + get_graphics(paddr,&pbuffer,prset,options); + if((*options) & (DBR_CTRL_UCHAR | DBR_CTRL_SHORT | DBR_CTRL_LONG + | DBR_CTRL_ULONG | DBR_CTRL_FLOAT | DBR_CTRL_DOUBLE )) + get_control(paddr,&pbuffer,prset,options); + + +GET_DATA: + + if(*nRequest==0) return(0); + /* Check for valid request */ + if( INVALID_DB_REQ(dbrType) || (field_type>DBF_DEVCHOICE) ){ + char message[80]; + + sprintf(message,"dbGetField - database request type is %d",dbrType); + recGblDbaddrError(S_db_badDbrtype,paddr,message); + return(S_db_badDbrtype); + } + + /* check for array */ + if( no_elements>1 && prset && (prset->get_array_info) ) { + status = (*prset->get_array_info)(paddr,&no_elements,&offset); + } + else offset=0; + if(no_elements<(*nRequest)) *nRequest = no_elements; + if(!(pconvert_routine=get_convert_table[field_type][dbrType])) { + char message[80]; + + sprintf(message,"dbGetField - database request type is %d",dbrType); + recGblDbaddrError(S_db_badDbrtype,paddr,message); + return(S_db_badDbrtype); + } + /* convert database field to buffer type and place it in the buffer */ + status=(*pconvert_routine)(paddr,pbuffer,*nRequest,no_elements,offset); + return(status); +} + +static get_enum_strs(paddr,ppbuffer,prset,options) +struct dbAddr *paddr; +char **ppbuffer; +struct rset *prset; +long *options; +{ + char *pbuffer=*ppbuffer; + short field_type=paddr->field_type; + struct choiceSet *pchoiceSet; + struct arrChoiceSet *parrChoiceSet; + struct devChoice *pdevChoice; + struct devChoiceSet *pdevChoiceSet; + unsigned long no_str; + char *ptemp; + int i; + + switch(field_type) { + case DBF_ENUM: + if( prset && prset->get_enum_strs ) { + (*prset->get_enum_strs)(paddr,pbuffer); + } else { + bzero(pbuffer,dbr_enumStrs_size); + *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/ + } + break; + case DBF_GBLCHOICE: + pchoiceSet=GET_PCHOICE_SET(choiceGbl,paddr->choice_set); + goto choice_common; + case DBF_CVTCHOICE: + pchoiceSet=choiceCvt; + goto choice_common; + case DBF_RECCHOICE: + parrChoiceSet=GET_PARR_CHOICE_SET(choiceRec, + paddr->record_type); + pchoiceSet=GET_PCHOICE_SET(parrChoiceSet,paddr->choice_set); +choice_common: + if(pchoiceSet==NULL) { + bzero(pbuffer,dbr_enumStrs_size); + *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/ + break; + } + no_str=MIN(pchoiceSet->number,16); + *(unsigned long*)pbuffer = no_str; + ptemp = pbuffer + sizeof(unsigned long); + for (i=0; ipapChoice[i]==NULL) + *ptemp=0; + else + strncpy(ptemp,pchoiceSet->papChoice[i],26); + ptemp += 26; + } + break; + case DBF_DEVCHOICE: + pdevChoiceSet=GET_PDEV_CHOICE_SET(choiceDev, + paddr->record_type); + if(pdevChoiceSet==NULL) { + bzero(pbuffer,dbr_enumStrs_size); + *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/ + break; + } + no_str=MIN(pdevChoiceSet->number,16); + *(unsigned long*)pbuffer = no_str; + ptemp = pbuffer + sizeof(unsigned long); + for (i=0; ipchoice==NULL) + *ptemp=0; + else + strncpy(ptemp,pdevChoice->pchoice,26); + ptemp += 26; + } + break; + default: + bzero(pbuffer,dbr_enumStrs_size); + *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/ + break; + } + *ppbuffer += dbr_enumStrs_size; + return; +} + +static get_graphics(paddr,ppbuffer,prset,options) +struct dbAddr *paddr; +char **ppbuffer; +struct rset *prset; +long *options; +{ + short field_type=paddr->field_type; + struct dbr_grDouble grd; + int got_data=FALSE; + long ltemp;/*vxWorks does not support double to unsigned long*/ + + if( prset && prset->get_graphic_double ) { + (*prset->get_graphic_double)(paddr,&grd); + got_data=TRUE; + } + if( (*options) & (DBR_GR_UCHAR) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_grUchar *pgr=(struct dbr_grUchar*)pbuffer; + pgr->upper_disp_limit=MIN(255,MAX(0,grd.upper_disp_limit)); + pgr->lower_disp_limit=MIN(255,MAX(0,grd.lower_disp_limit)); + pgr->upper_alarm_limit=MIN(255,MAX(0,grd.upper_alarm_limit)); + pgr->upper_warning_limit= + MIN(255,MAX(0,grd.upper_warning_limit)); + pgr->lower_warning_limit= + MIN(255,MAX(0,grd.lower_warning_limit)); + pgr->lower_alarm_limit= + MIN(255,MAX(0,grd.lower_alarm_limit)); + } else { + bzero(pbuffer,dbr_grUchar_size); + *options = (*options) ^ DBR_GR_UCHAR; /*Turn off option*/ + } + *ppbuffer += dbr_grUchar_size; + } + if( (*options) & (DBR_GR_SHORT) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_grShort *pgr=(struct dbr_grShort*)pbuffer; + pgr->upper_disp_limit = + MIN(32767,MAX(-32768,grd.upper_disp_limit)); + pgr->lower_disp_limit = + MIN(32767,MAX(-32768,grd.lower_disp_limit)); + pgr->upper_alarm_limit = + MIN(32767,MAX(-32768,grd.upper_alarm_limit)); + pgr->upper_warning_limit = + MIN(32767,MAX(-32768,grd.upper_warning_limit)); + pgr->lower_warning_limit = + MIN(32767,MAX(-32768,grd.lower_warning_limit)); + pgr->lower_alarm_limit = + MIN(32767,MAX(-32768,grd.lower_alarm_limit)); + } else { + bzero(pbuffer,dbr_grShort_size); + *options = (*options) ^ DBR_GR_SHORT; /*Turn off option*/ + } + *ppbuffer += dbr_grShort_size; + } + if( (*options) & (DBR_GR_LONG) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_grLong *pgr=(struct dbr_grLong*)pbuffer; + pgr->upper_disp_limit = grd.upper_disp_limit; + pgr->lower_disp_limit = grd.lower_disp_limit; + pgr->upper_alarm_limit = grd.upper_alarm_limit; + pgr->upper_warning_limit = grd.upper_warning_limit; + pgr->lower_warning_limit = grd.lower_warning_limit; + pgr->lower_alarm_limit = grd.lower_alarm_limit; + } else { + bzero(pbuffer,dbr_grLong_size); + *options = (*options) ^ DBR_GR_LONG; /*Turn off option*/ + } + *ppbuffer += dbr_grLong_size; + } + if( (*options) & (DBR_GR_ULONG) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_grUlong *pgr=(struct dbr_grUlong*)pbuffer; + ltemp = grd.upper_disp_limit; + pgr->upper_disp_limit = ltemp; + ltemp = grd.lower_disp_limit; + pgr->lower_disp_limit = ltemp; + ltemp = grd.upper_alarm_limit; + pgr->upper_alarm_limit = ltemp; + ltemp = grd.upper_warning_limit; + pgr->upper_warning_limit = ltemp; + ltemp = grd.lower_warning_limit; + pgr->lower_warning_limit = ltemp; + ltemp = grd.lower_alarm_limit; + pgr->lower_alarm_limit = ltemp; + } else { + bzero(pbuffer,dbr_grUlong_size); + *options = (*options) ^ DBR_GR_ULONG; /*Turn off option*/ + } + *ppbuffer += dbr_grUlong_size; + } + if( (*options) & (DBR_GR_FLOAT) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_grFloat *pgr=(struct dbr_grFloat*)pbuffer; + pgr->upper_disp_limit = grd.upper_disp_limit; + pgr->lower_disp_limit = grd.lower_disp_limit; + pgr->upper_alarm_limit = grd.upper_alarm_limit; + pgr->upper_warning_limit = grd.upper_warning_limit; + pgr->lower_warning_limit = grd.lower_warning_limit; + pgr->lower_alarm_limit = grd.lower_alarm_limit; + } else { + bzero(pbuffer,dbr_grFloat_size); + *options = (*options) ^ DBR_GR_FLOAT; /*Turn off option*/ + } + *ppbuffer += dbr_grFloat_size; + } + if( (*options) & (DBR_GR_DOUBLE) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_grDouble *pgr=(struct dbr_grDouble*)pbuffer; + pgr->upper_disp_limit = grd.upper_disp_limit; + pgr->lower_disp_limit = grd.lower_disp_limit; + pgr->upper_alarm_limit = grd.upper_alarm_limit; + pgr->upper_warning_limit = grd.upper_warning_limit; + pgr->lower_warning_limit = grd.lower_warning_limit; + pgr->lower_alarm_limit = grd.lower_alarm_limit; + } else { + bzero(pbuffer,dbr_grDouble_size); + *options = (*options) ^ DBR_GR_DOUBLE; /*Turn off option*/ + } + *ppbuffer += dbr_grDouble_size; + } + return; +} + +static get_control(paddr,ppbuffer,prset,options) +struct dbAddr *paddr; +char **ppbuffer; +struct rset *prset; +long *options; +{ + short field_type=paddr->field_type; + struct dbr_ctrlDouble ctrld; + int got_data=FALSE; + long ltemp;/*vxWorks does not support double to unsigned long*/ + + if( prset && prset->get_control_double ) { + (*prset->get_control_double)(paddr,&ctrld); + got_data=TRUE; + } + if( (*options) & (DBR_CTRL_UCHAR) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_ctrlUchar *pctrl=(struct dbr_ctrlUchar*)pbuffer; + pctrl->upper_ctrl_limit = + MIN(255,MAX(0,ctrld.upper_ctrl_limit)); + pctrl->lower_ctrl_limit = + MIN(255,MAX(0,ctrld.lower_ctrl_limit)); + } else { + bzero(pbuffer,dbr_ctrlUchar_size); + *options = (*options) ^ DBR_CTRL_UCHAR; /*Turn off option*/ + } + *ppbuffer += dbr_ctrlUchar_size; + } + if( (*options) & (DBR_CTRL_SHORT) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_ctrlShort *pctrl=(struct dbr_ctrlShort*)pbuffer; + pctrl->upper_ctrl_limit = + MIN(32767,MAX(-32768,ctrld.upper_ctrl_limit)); + pctrl->lower_ctrl_limit = + MIN(32767,MAX(-32768,ctrld.lower_ctrl_limit)); + } else { + bzero(pbuffer,dbr_ctrlShort_size); + *options = (*options) ^ DBR_CTRL_SHORT; /*Turn off option*/ + } + *ppbuffer += dbr_ctrlShort_size; + } + if( (*options) & (DBR_CTRL_LONG) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_ctrlLong *pctrl=(struct dbr_ctrlLong*)pbuffer; + pctrl->upper_ctrl_limit = ctrld.upper_ctrl_limit; + pctrl->lower_ctrl_limit = ctrld.lower_ctrl_limit; + } else { + bzero(pbuffer,dbr_ctrlLong_size); + *options = (*options) ^ DBR_CTRL_LONG; /*Turn off option*/ + } + *ppbuffer += dbr_ctrlLong_size; + } + if( (*options) & (DBR_CTRL_ULONG) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_ctrlUlong *pctrl=(struct dbr_ctrlUlong*)pbuffer; + ltemp = ctrld.upper_ctrl_limit; + pctrl->upper_ctrl_limit = ltemp; + ltemp = ctrld.lower_ctrl_limit; + pctrl->lower_ctrl_limit = ltemp; + } else { + bzero(pbuffer,dbr_ctrlUlong_size); + *options = (*options) ^ DBR_CTRL_ULONG; /*Turn off option*/ + } + *ppbuffer += dbr_ctrlUlong_size; + } + if( (*options) & (DBR_CTRL_FLOAT) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_ctrlFloat *pctrl=(struct dbr_ctrlFloat*)pbuffer; + pctrl->upper_ctrl_limit = ctrld.upper_ctrl_limit; + pctrl->lower_ctrl_limit = ctrld.lower_ctrl_limit; + } else { + bzero(pbuffer,dbr_ctrlFloat_size); + *options = (*options) ^ DBR_CTRL_FLOAT; /*Turn off option*/ + } + *ppbuffer += dbr_ctrlFloat_size; + } + if( (*options) & (DBR_CTRL_DOUBLE) ) { + char *pbuffer=*ppbuffer; + + if(got_data) { + struct dbr_ctrlDouble *pctrl=(struct dbr_ctrlDouble*)pbuffer; + pctrl->upper_ctrl_limit = ctrld.upper_ctrl_limit; + pctrl->lower_ctrl_limit = ctrld.lower_ctrl_limit; + } else { + bzero(pbuffer,dbr_ctrlDouble_size); + *options = (*options) ^ DBR_CTRL_DOUBLE; /*Turn off option*/ + } + *ppbuffer += dbr_ctrlDouble_size; + } + return; +} + +/* DATABASE ACCESS PUT CONVERSION SUPPORT */ + +static long putStringString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=paddr->pfield; + short size=paddr->field_size; + + if(nRequest==1 && offset==0) { + strncpy(pdest,pbuffer,size); + return(0); + } + pdest+= (size*offset); + while (nRequest) { + strncpy(pdest,pbuffer,size); + pbuffer += MAX_STRING_SIZE; + if(++offset==no_elements) + pdest=paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putStringChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)paddr->pfield; + short value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%hd",&value) == 1) { + *pdest = (char)value; + return(0); + } + else return(-1); + } + return(-1); +} + +static long putStringUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)paddr->pfield; + unsigned short value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%hu",&value) == 1) { + *pdest = (unsigned char)value; + return(0); + } + else return(-1); + } + return(-1); +} + +static long putStringShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)paddr->pfield; + short value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%hd",&value) == 1) { + *pdest = value; + return(0); + } + else return(-1); + } + return(-1); +} + +static long putStringUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)paddr->pfield; + unsigned short value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%hu",&value) == 1) { + *pdest = value; + return(0); + } + else return(-1); + } + return(-1); +} + +static long putStringLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)paddr->pfield; + long value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%ld",&value) == 1) { + *pdest = value; + return(0); + } + else return(-1); + } + return(-1); +} + +static long putStringUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)paddr->pfield; + unsigned long value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%lu",&value) == 1) { + *pdest = value; + return(0); + } + else return(-1); + } + return(-1); +} + +static long putStringFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)paddr->pfield; + float value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%f",&value) == 1) { + *pdest = value; + return(0); + } + } + return(-1); +} + +static long putStringDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)paddr->pfield; + float value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%lf",&value) == 1) { + *pdest = (double)value; + return(0); + } + } + return(-1); +} + +static long putStringEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=( unsigned short *)paddr->pfield; + short value; + + if(nRequest==1 && offset==0) { + if(sscanf(pbuffer,"%u",&value) == 1) { + *pdest = value; + return(0); + } + else return(-1); + } + return(-1); +} + +/* The next four routines are not used. I don't think that they should!!!*/ + + +static long putStringGchoice(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short choice_set=paddr->choice_set; + unsigned short *pfield= (unsigned short*)(paddr->pfield); + char *pchoice; + struct choiceSet *pchoiceSet; + unsigned short i; + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbPutLink(putStringGchoice)"); + return(S_db_onlyOne); + } + if(pchoiceSet=GET_PCHOICE_SET(choiceGbl,choice_set)) { + for(i=0; inumber; i++) { + if(!(pchoice=pchoiceSet->papChoice[i])) continue; + if(strcmp(pchoice,pbuffer)==0) { + *pfield=i; + return(0); + } + } + } + recGblDbaddrError(S_db_badChoice,paddr,"dbPutLink(putStringGchoice)"); + return(S_db_badChoice); +} + +static long putStringCchoice(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pfield= (unsigned short*)(paddr->pfield); + char *pchoice; + struct choiceSet *pchoiceSet; + unsigned short i; + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbPutLink(putStringCchoice)"); + return(S_db_onlyOne); + } + if(pchoiceSet=choiceCvt) { + for(i=0; inumber; i++) { + if(!(pchoice=pchoiceSet->papChoice[i])) continue; + if(strcmp(pchoice,pbuffer)==0) { + *pfield=i; + return(0); + } + } + } + recGblDbaddrError(S_db_badChoice,paddr,"dbPutLink(putStringCchoice)"); + return(S_db_badChoice); +} + +static long putStringRchoice(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short choice_set=paddr->choice_set; + unsigned short *pfield= (unsigned short*)(paddr->pfield); + char *pchoice; + struct choiceSet *pchoiceSet; + struct arrChoiceSet *parrChoiceSet; + unsigned short i; + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbPutLink(putStringRchoice)"); + return(S_db_onlyOne); + } + if((parrChoiceSet=GET_PARR_CHOICE_SET(choiceRec,(paddr->record_type))) + && (pchoiceSet=GET_PCHOICE_SET(parrChoiceSet,choice_set))) { + for(i=0; inumber; i++) { + if(!(pchoice=pchoiceSet->papChoice[i])) continue; + if(strcmp(pchoice,pbuffer)==0) { + *pfield=i; + return(0); + } + } + } + recGblDbaddrError(S_db_badChoice,paddr,"dbPutLink(putStringRchoice)"); + return(S_db_badChoice); +} + +static long putStringDchoice(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pfield= (unsigned short*)(paddr->pfield); + struct devChoiceSet *pdevChoiceSet; + char *pchoice; + unsigned short i; + + if(no_elements!=1){ + recGblDbaddrError(S_db_onlyOne,paddr,"dbPutLink(putStringDchoice)"); + return(S_db_onlyOne); + } + if(pdevChoiceSet=GET_PDEV_CHOICE_SET(choiceDev,paddr->record_type)) { + for(i=0; inumber; i++) { + if(!(pchoice=pdevChoiceSet->papDevChoice[i]->pchoice)) continue; + if(strcmp(pchoice,pbuffer)==0) { + *pfield=i; + return(0); + } + } + } + recGblDbaddrError(S_db_badChoice,paddr,"dbPutLink(putStringDchoice)"); + return(S_db_badChoice); +} + +static long putCharString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + short size=paddr->field_size; + + + if(nRequest==1 && offset==0) { + char_to_str(*pbuffer,pdest); + return(0); + } + pdest += (size*offset); + while (nRequest) { + char_to_str(*pbuffer,pdest); + pbuffer++; + if(++offset==no_elements) + pdest=paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putCharChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putCharUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putCharShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putCharUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putCharLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putCharUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putCharFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putCharDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putCharEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + short size=paddr->field_size; + + + if(nRequest==1 && offset==0) { + uchar_to_str(*pbuffer,pdest); + return(0); + } + pdest += (size*offset); + while (nRequest) { + uchar_to_str(*pbuffer,pdest); + pbuffer++; + if(++offset==no_elements) + pdest=paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putUcharChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUcharEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned char *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + short size=paddr->field_size; + + + if(nRequest==1 && offset==0) { + short_to_str(*pbuffer,pdest); + return(0); + } + pdest += (size*offset); + while (nRequest) { + short_to_str(*pbuffer,pdest); + pbuffer++; + if(++offset==no_elements) + pdest=(char *)paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putShortChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putShortEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + short size=paddr->field_size; + + + if(nRequest==1 && offset==0) { + ushort_to_str(*pbuffer,pdest); + return(0); + } + pdest += (size*offset); + while (nRequest) { + ushort_to_str(*pbuffer,pdest); + pbuffer++; + if(++offset==no_elements) + pdest=(char *)paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putUshortChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUshortEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + short size=paddr->field_size; + + + if(nRequest==1 && offset==0) { + long_to_str(*pbuffer,pdest); + return(0); + } + pdest += (size*offset); + while (nRequest) { + long_to_str(*pbuffer,pdest); + pbuffer++; + if(++offset==no_elements) + pdest=(char *)paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putLongChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putLongEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + short size=paddr->field_size; + + + if(nRequest==1 && offset==0) { + ulong_to_str(*pbuffer,pdest); + return(0); + } + pdest += (size*offset); + while (nRequest) { + ulong_to_str(*pbuffer,pdest); + pbuffer++; + if(++offset==no_elements) + pdest=(char *)paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putUlongChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putUlongEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned long *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + long status; + int precision; + short record_type=paddr->record_type; + struct rset *prset; + short size=paddr->field_size; + + if((prset=GET_PRSET(record_type)) && (prset->get_precision)) + status = (*prset->get_precision)(paddr,&precision); + else + status=S_db_precision; + if(!RTN_SUCCESS(status)) { + recGblRecSupError(status,paddr,"db_put_field","get_precision"); + return(status); + } + + if(nRequest==1 && offset==0) { + status = f_to_str((double)(*pbuffer),pdest,precision); + return(0); + } + pdest += (size*offset); + while (nRequest) { + status = f_to_str((double)(*pbuffer),pdest,precision); + pbuffer++; + if(++offset==no_elements) + pdest=(char *)paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putFloatChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + long ltemp;/*vxWorks does not support float to unsigned long*/ + + if(nRequest==1 && offset==0) { + ltemp = *pbuffer; + *pdest = ltemp; + return(0); + } + pdest += offset; + while (nRequest) { + ltemp = *pbuffer++; + *pdest++ = ltemp; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putFloatEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +float *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + long status; + int precision; + short record_type=paddr->record_type; + struct rset *prset; + short size=paddr->field_size; + + if((prset=GET_PRSET(record_type)) && (prset->get_precision)) + status = (*prset->get_precision)(paddr,&precision); + else + status=S_db_precision; + if(!RTN_SUCCESS(status)) { + recGblRecSupError(status,paddr,"db_put_field","get_precision"); + return(status); + } + + if(nRequest==1 && offset==0) { + status = f_to_str(*pbuffer,pdest,precision); + return(0); + } + pdest += (size*offset); + while (nRequest) { + status = f_to_str(*pbuffer,pdest,precision); + pbuffer++; + if(++offset==no_elements) + pdest=(char *)paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putDoubleChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + long ltemp;/*vxWorks does not support double to unsigned long*/ + + if(nRequest==1 && offset==0) { + ltemp = *pbuffer; + *pdest = ltemp; + return(0); + } + pdest += offset; + while (nRequest) { + ltemp = *pbuffer++; + *pdest++ = ltemp; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putDoubleEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +double *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumString(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + short size=paddr->field_size; + + + if(nRequest==1 && offset==0) { + uchar_to_str(*pbuffer,pdest); + return(0); + } + pdest += (size*offset); + while (nRequest) { + uchar_to_str(*pbuffer,pdest); + pbuffer++; + if(++offset==no_elements) + pdest=(char *)paddr->pfield; + else + pdest += size; + nRequest--; + } + return(0); +} + +static long putEnumChar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + char *pdest=(char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumUchar(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned char *pdest=(unsigned char *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumShort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + short *pdest=(short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumUshort(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumLong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + long *pdest=(long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumUlong(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned long *pdest=(unsigned long *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumFloat(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + float *pdest=(float *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(float *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumDouble(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + double *pdest=(double *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(double *)paddr->pfield; + nRequest--; + } + return(0); +} + +static long putEnumEnum(paddr,pbuffer,nRequest,no_elements,offset) +struct dbAddr *paddr; +unsigned short *pbuffer; +long nRequest; +long no_elements; +long offset; +{ + unsigned short *pdest=(unsigned short *)(paddr->pfield); + + if(nRequest==1 && offset==0) { + *pdest = *pbuffer; + return(0); + } + pdest += offset; + while (nRequest) { + *pdest++ = *pbuffer++; + if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield; + nRequest--; + } + return(0); +} + +/* This is the table of routines for converting database fields */ +/* the rows represent the buffer types */ +/* the columns represent the field types */ + +/* field types are******************************************************** + DBF_STRING, DBF_CHAR, DBF_UCHAR, DBF_SHORT, DBF_USHORT, + DBF_LONG, DBF_ULONG, DBF_FLOAT, DBF_DOUBLE, DBF_ENUM + DBF_GBLCHOICE, DBF_CVTCHOICE, DBF_RECCHOICE, DBF_DEVCHOICE + ***************************************************************************/ + +long (*put_convert_table[DBR_ENUM+1][DBF_DEVCHOICE+1])() = { +/* source is a DBR_STRING */ +{putStringString, putStringChar, putStringUchar, putStringShort, putStringUshort, + putStringLong, putStringUlong, putStringFloat, putStringDouble, putStringEnum, + putStringEnum, putStringEnum, putStringEnum, putStringEnum}, +/* source is a DBR_CHAR */ +{putCharString, putCharChar, putCharUchar, putCharShort, putCharUshort, + putCharLong, putCharUlong, putCharFloat, putCharDouble, putCharEnum, + putCharEnum, putCharEnum, putCharEnum, putCharEnum}, +/* source is a DBR_UCHAR */ +{putUcharString, putUcharChar, putUcharUchar, putUcharShort, putUcharUshort, + putUcharLong, putUcharUlong, putUcharFloat, putUcharDouble, putUcharEnum, + putUcharEnum, putUcharEnum, putUcharEnum, putUcharEnum}, +/* source is a DBR_SHORT */ +{putShortString, putShortChar, putShortUchar, putShortShort, putShortUshort, + putShortLong, putShortUlong, putShortFloat, putShortDouble, putShortEnum, + putShortEnum, putShortEnum, putShortEnum, putShortEnum}, +/* source is a DBR_USHORT */ +{putUshortString, putUshortChar, putUshortUchar, putUshortShort, putUshortUshort, + putUshortLong, putUshortUlong, putUshortFloat, putUshortDouble, putUshortEnum, + putUshortEnum, putUshortEnum, putUshortEnum, putUshortEnum}, +/* source is a DBR_LONG */ +{putLongString, putLongChar, putLongUchar, putLongShort, putLongUshort, + putLongLong, putLongUlong, putLongFloat, putLongDouble, putLongEnum, + putLongEnum, putLongEnum, putLongEnum, putLongEnum}, +/* source is a DBR_ULONG */ +{putUlongString, putUlongChar, putUlongUchar, putUlongShort, putUlongUshort, + putUlongLong, putUlongUlong, putUlongFloat, putUlongDouble, putUlongEnum, + putUlongEnum, putUlongEnum, putUlongEnum, putUlongEnum}, +/* source is a DBR_FLOAT */ +{putFloatString, putFloatChar, putFloatUchar, putFloatShort, putFloatUshort, + putFloatLong, putFloatUlong, putFloatFloat, putFloatDouble, putFloatEnum, + putFloatEnum, putFloatEnum, putFloatEnum, putFloatEnum}, +/* source is a DBR_DOUBLE */ +{putDoubleString, putDoubleChar, putDoubleUchar, putDoubleShort, putDoubleUshort, + putDoubleLong, putDoubleUlong, putDoubleFloat, putDoubleDouble, putDoubleEnum, + putDoubleEnum, putDoubleEnum, putDoubleEnum, putDoubleEnum}, +/* source is a DBR_ENUM */ +{putEnumString, putEnumChar, putEnumUchar, putEnumShort, putEnumUshort, + putEnumLong, putEnumUlong, putEnumFloat, putEnumDouble, putEnumEnum, + putEnumEnum, putEnumEnum, putEnumEnum, putEnumEnum} +}; + +long dbPut(paddr,dbrType,pbuffer,nRequest) +struct dbAddr *paddr; +short dbrType; +caddr_t pbuffer; +long nRequest; +{ + long no_elements=paddr->no_elements; + long dummy; + long offset; + long (*pconvert_routine)(); + long int (*pspecial)()=NULL; + struct rset *prset; + struct dbCommon *precord=(struct dbCommon *)(paddr->precord); + long status=0; + static char val[4]={'V','A','L',' '}; + long *pval=(long *)&val[0]; + struct fldDes *pfldDes; + long *pfield_name; + long special=paddr->special; + short field_type=paddr->field_type; + + /* Check for valid request */ + if( INVALID_DB_REQ(dbrType) || (field_type>DBF_DEVCHOICE) + || (!(pconvert_routine=put_convert_table[dbrType][field_type])) ) + { + char message[80]; + + sprintf(message,"dbPut - database request type is %d",dbrType); + recGblDbaddrError(S_db_badDbrtype,paddr,message); + return(S_db_badDbrtype); + } + + prset=GET_PRSET(paddr->record_type); + + /* check for special processing is required */ + if(special) { + if(special<100) { /*global processing*/ + if(special==SPC_NOMOD) return(S_db_noMod); + if(special==SPC_SCAN) delete_from_scan_list(paddr); + } + else { + if( prset && (pspecial = (prset->special))) { + status=(*pspecial)(paddr,0); + if(!RTN_SUCCESS(status)) goto all_done; + } else { + recGblRecSupError(S_db_noSupport,paddr,"dbPutLink", + "special"); + return(S_db_noSupport); + } + } + } + + /* check for array */ + if( no_elements>1 && prset && (prset->get_array_info) ) { + status= (*prset->get_array_info)(paddr,&dummy,&offset); + } + else offset=0; + if(no_elements<(nRequest)) nRequest = no_elements; + + /* convert database field to buffer type and place it in the buffer */ + status=(*pconvert_routine)(paddr,pbuffer,nRequest,no_elements,offset); + + /* update array info */ + if( no_elements>1 && prset && (prset->put_array_info) ) { + status= (*prset->put_array_info)(paddr,nRequest); + } + + if(!RTN_SUCCESS(status)) goto all_done; + + /* check for special processing is required */ + if(special) { + if(special<=100) { /*global processing*/ + if(special==SPC_SCAN) add_to_scan_list(paddr,0xffff); + } + else { + status=(*pspecial)(paddr,1); + if(!RTN_SUCCESS(status)) goto all_done; + } + } + + /* propagate events for this field (except for VAL)*/ + pfldDes = (struct fldDes *)(paddr->pfldDes); + pfield_name = (long *)&(pfldDes->fldname[0]); + if(precord->mlis.count && (*pval != *pfield_name)) + db_post_events(precord,paddr->pfield,DBE_VALUE); + +all_done: + + return(status); +} diff --git a/src/db/dbEvent.c b/src/db/dbEvent.c new file mode 100644 index 000000000..442a23f83 --- /dev/null +++ b/src/db/dbEvent.c @@ -0,0 +1,751 @@ + +/* dbEvent.c */ +/* share/src/db $Id$ */ + +/* + +dbEvent.c + +routines for scheduling events to lower priority tasks via the RT kernel + +Modification History +joh 00 30Mar89 Created +joh 01 Apr 89 Init Release +joh 02 06-14-89 changed DBCHK to PADDRCHK since we are checking + precord instead of pfield now. +joh 03 07-28-89 Added dynamic que size increase proportional + to nevents +joh 04 08-21-89 Added init function to args of db_start_events() +joh 05 12-21-89 fixed bug where event que not completely + dealloated when there are many events. +joh 06 02-16-90 changed names here and in dbcommon to avoid + confusion for those maintaining this code + (this change does not modify obj code). + mlok became mon_lock + mlst became mon_list +mrk(anl)07 09-18-90 Made changes for new record and device support +*/ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +struct event_block{ + NODE node; + struct dbAddr addr; + void *pfield; /* I modify the copy of pfield above */ + void (*user_sub)(); + void *user_arg; + struct event_que *ev_que; + unsigned char select; + char valque; + unsigned short npend; /* number of times this event is on the que */ +}; + +union native_value{ + short bval; + short eval; + float rval; +/* + Strings left off for now + - reliable interprocess communication may not be provided with strings + since they will slow down events for more reasonable size values. + + char sval[MAXSTRINGSIZE]; +*/ +}; + +#define EVENTQUESIZE EVENTENTRIES *32 +#define EVENTENTRIES 16 /* the number of que entries for each event */ +#define EVENTQEMPTY ((struct event_block *)NULL) + +/* + Reliable intertask communication requires copying the current value + of the channel for later queing so 3 stepper motor steps of 10 each + do not turn into only 10 or 20 total steps part of the time. + + NOTE: locks on this data structure are optimized so a test and set + call is made first. If the lock is allready set then the task + pends on the lock pend sem. Test and set call is much faster than + a semaphore. See LOCKEVUSER. +*/ +/* +really a ring buffer +*/ +struct event_que{ + struct event_block *evque[EVENTQUESIZE]; + union native_value valque[EVENTQUESIZE]; + unsigned short putix; + unsigned short getix; + unsigned short quota; /* the number of assigned entries*/ + + /* lock writers to the ring buffer only */ + /* readers must never slow up writers */ + FAST_LOCK writelock; + + struct event_que *nextque; /* in case que quota exceeded */ + struct event_user *evuser; /* event user parent struct */ +}; + +struct event_user{ + int taskid; /* event handler task id */ + int taskpri; /* event handler task priority */ + + char pendlck; /* Only one task can pend */ + SEMAPHORE pendsem; /* Wait while empty */ + unsigned char pendexit; /* exit pend task */ + + unsigned short queovr; /* event que overflow count */ + void (*overflow_sub)(); /* executed for overflow detect */ + void *overflow_arg; /* parameter to above routine */ + + struct event_que firstque; /* the first event que */ +}; + + + + +#define RNGINC(OLD)\ +((OLD)+1)>=EVENTQUESIZE ? 0 : ((OLD)+1) + + +#define LOCKEVQUE(EV_QUE)\ +FASTLOCK(&(EV_QUE)->writelock); + +#define UNLOCKEVQUE(EV_QUE)\ +FASTUNLOCK(&(EV_QUE)->writelock); + +#define LOCKREC(RECPTR)\ +FASTLOCK(&(RECPTR)->mlok); + +#define UNLOCKREC(RECPTR)\ +FASTUNLOCK(&(RECPTR)->mlok); + + +#define VXTASKIDSELF 0 + +/* + >> kernel dependent << + + This is so if we go to a kernel which has different + priority order I can switch all priority inc/dec at once -joh + + on VRTX a lower priority number runs first- hence the minus one +*/ +#define HIGHERPRIORITYINC (-1) +#define HIGHER_OR_SAME_PRIORITY_THAN <= + +db_event_list(name) +char *name; +{ + struct dbAddr addr; + int status; + struct event_block *pevent; + register struct dbCommon *precord; + + status = dbNameToAddr(name, &addr); + if(status==ERROR) + return ERROR; + + precord = (struct dbCommon *) addr.precord; + + LOCKREC(precord); + for( pevent = (struct event_block *) precord->mlis.node.next; + pevent; + pevent = (struct event_block *) pevent->node.next){ +printf(" ev %x\n",pevent); +printf(" ev que %x\n",pevent->ev_que); +printf(" ev user %x\n",pevent->ev_que->evuser); + logMsg("Event for task %x \n", pevent->ev_que->evuser->taskid); + } + UNLOCKREC(precord); + +} + + +/* + Initialize the event facility for this task + Must be called at least once by each task which uses the db event facility + + returns: + ptr to event user block or NULL if memory can't be allocated +*/ +struct event_user +*db_init_events() +{ + register struct event_user *evuser; + int logMsg(); + + evuser = (struct event_user *) malloc(sizeof(*evuser)); + if(!evuser) + return NULL; + + bfill(evuser, sizeof(*evuser), NULL); + evuser->firstque.evuser = evuser; +/* + init_event_que(&evuser->firstevent); + + evuser->overflow_sub = NULL; + evuser->overflow_arg = NULL; + evuser->pendlck = FALSE; + evuser->taskid = VXTASKIDSELF; +*/ + + return evuser; +} + +#ifdef ZEBRA +static +init_event_que(ev_que) +struct event_que *ev_que; +{ + register int i; + + bfill(ev_que, sizeof*ev_que), NULL); + +/* + FASTLOCKINIT(&ev_que->writelock); + semInit(&ev_que->pendsem); + ev_que->putix = 0; + ev_que->getix = 0; + ev_que->queovr = 0; + ev_que->quota = 0; + ev_que->nextque = NULL; + for(i=0; ievque[i] = (struct event_block *) EVENTQEMPTY; +*/ +} +#endif + +db_close_events(evuser) +register struct event_user *evuser; +{ + /* + Exit not forced on event blocks for now + - this is left to channel access and any other tasks + using this facility which can find them more efficiently. + + NOTE: not deleting events before calling this routine + could be hazardous to the system's health. + */ + + evuser->pendexit = TRUE; + + /* notify the waiting task */ + semGive(&evuser->pendsem); + + + return OK; +} + +/* +So the event block structure size but not structure is exported +(used by those who wish for the event block to be a sub structure) +see pevent != NULL on db_add_event() +*/ +db_sizeof_event_block() +{ + return sizeof(struct event_block); +} + +db_add_event(evuser, paddr, user_sub, user_arg, select, pevent) +register struct event_user *evuser; +register struct dbAddr *paddr; +register void (*user_sub)(); +register void *user_arg; +register unsigned int select; +register struct event_block *pevent; /* ptr to event blk (not required) */ +{ + register struct dbCommon *precord; + register struct event_que *ev_que; + register struct event_que *tmp_que; + + precord = (struct dbCommon *) paddr->precord; + + /* + Don't add events which will not be triggered + */ + if(!select) + return ERROR; + + /* find an event que block with enough quota */ + /* otherwise add a new one to the list */ + ev_que = &evuser->firstque; + while(TRUE){ + if(ev_que->quota < EVENTQUESIZE - EVENTENTRIES) + break; + if(!ev_que->nextque){ + tmp_que = (struct event_que *) malloc(sizeof(*tmp_que)); + if(!tmp_que) + return ERROR; + bfill(tmp_que, sizeof(*tmp_que), NULL); + tmp_que->evuser = evuser; + ev_que->nextque = tmp_que; + ev_que = tmp_que; + break; + } + ev_que = ev_que->nextque; + } + + if(!pevent){ + pevent = (struct event_block *) malloc(sizeof(*pevent)); + if(!pevent) + return ERROR; + } + + pevent->npend = 0; + pevent->user_sub = user_sub; + pevent->user_arg = user_arg; + pevent->addr = *paddr; + pevent->pfield = (void *) paddr->pfield; /* I modify the one above */ + pevent->select = select; + + ev_que->quota += EVENTENTRIES; + pevent->ev_que = ev_que; + + + /* + Simple types values queued up for reliable interprocess communication + (for other types they get whatever happens to be there upon wakeup) + */ + if(paddr->no_elements != 1) + pevent->valque = FALSE; + else + switch(paddr->field_type){ + case DBR_UCHAR: + case DBR_SHORT: + case DBR_LONG: + case DBR_ULONG: + case DBR_FLOAT: + case DBR_ENUM: + /* change pfield to point to the value que entry */ + pevent->valque = TRUE; + break; + default: + /* leave pfield pointing to the database */ + pevent->valque = FALSE; + break; + } + + LOCKREC(precord); + lstAdd(&precord->mlis, pevent); + UNLOCKREC(precord); + + return OK; + +} + + +/* + This routine does not prevent two threads from deleting one block at + the same time. + + This routine does not deallocate the event block since it normally + will be part of a larger structure. +*/ +db_cancel_event(pevent) +register struct event_block *pevent; +{ + register struct dbCommon *precord; + int myprio; + int evprio; + + + /* + Disable this event block + */ + pevent->select = NULL; + + precord = (struct dbCommon *) pevent->addr.precord; + + LOCKREC(precord); + lstDelete( &precord->mlis, pevent); + UNLOCKREC(precord); + + /* + Decrement event que quota + */ + pevent->ev_que->quota -= EVENTENTRIES; + + /* + Flush the event que so we know event block not left in use + This requires temporarily dropping below the priority of the + event handler. This task will not run again until the + handler has flushed its que. + */ + evprio = pevent->ev_que->evuser->taskpri; + if(taskPriorityGet(VXTASKIDSELF, &myprio)==ERROR) + taskSuspend(VXTASKIDSELF); + + /* + go to a lower priority than the event handler- if not there allready + */ + if(myprio HIGHER_OR_SAME_PRIORITY_THAN evprio){ + if(taskPrioritySet(VXTASKIDSELF, evprio-HIGHERPRIORITYINC)==ERROR) + taskSuspend(VXTASKIDSELF); + + /* + Insure that the que is purged of this event + (in case the event task is pending in a user subroutine) + */ + while(pevent->npend) + taskDelay(10); + + /* return to origional priority */ + if(taskPrioritySet(VXTASKIDSELF, myprio)==ERROR) + taskSuspend(VXTASKIDSELF); + } + else + while(pevent->npend) + taskDelay(10); + + return OK; +} + + +/* + Specify a routine to be executed for event que overflow condition +*/ +db_add_overflow_event(evuser, overflow_sub, overflow_arg) +register struct event_user *evuser; +register void (*overflow_sub)(); +register void *overflow_arg; +{ + + evuser->overflow_sub = overflow_sub; + evuser->overflow_arg = overflow_arg; + + return OK; +} + + +db_post_single_event(pevent) +register struct event_block *pevent; +{ + register struct event_que *ev_que = pevent->ev_que; + register unsigned int putix; + + /* + evuser ring buffer must be locked for the multiple + threads writing to it + */ + LOCKEVQUE(ev_que) + putix = ev_que->putix; + + /* add to task local event que */ + if(ev_que->evque[putix] == EVENTQEMPTY){ + pevent->npend++; + ev_que->evque[putix] = pevent; + ev_que->valque[putix] = *(union native_value *)pevent->pfield; + + /* notify the event handler */ + semGive(&ev_que->evuser->pendsem); + ev_que->putix = RNGINC(putix); + } + else + ev_que->evuser->queovr++; + + UNLOCKEVQUE(ev_que) + + return OK; +} + +db_post_events(precord,pvalue,select) +register struct dbCommon *precord; +register union native_value *pvalue; +register unsigned int select; +{ + register struct event_block *event; + register struct event_que *ev_que; + register unsigned int putix; + + LOCKREC(precord); + + for( event = (struct event_block *) precord->mlis.node.next; + event; + event = (struct event_block *) event->node.next){ + + ev_que = event->ev_que; + /* + Only send event msg if they are waiting on the field which changed + */ + if( (event->pfield == (void *)pvalue) && (select & event->select) ){ + /* + evuser ring buffer must be locked for the multiple + threads writing to it + */ + LOCKEVQUE(ev_que) + putix = ev_que->putix; + + /* add to task local event que */ + if(ev_que->evque[putix] == EVENTQEMPTY){ + + event->npend++; + ev_que->evque[putix] = event; + ev_que->valque[putix] = *pvalue; + + /* notify the event handler */ + semGive(&ev_que->evuser->pendsem); + + ev_que->putix = RNGINC(putix); + } + else + ev_que->evuser->queovr++; + + UNLOCKEVQUE(ev_que) + + } + + } + + UNLOCKREC(precord); + return OK; + +} + + +db_start_events(evuser,taskname,init_func,init_func_arg) +struct event_user *evuser; +char *taskname; /* defaulted if NULL */ +void (*init_func)(); +int init_func_arg; +{ + int myprio; + int status; + int event_task(); + + /* only one ca_pend_event thread may be started for each evuser ! */ + while(!vxTas(&evuser->pendlck)) + return ERROR; + + status = taskPriorityGet(VXTASKIDSELF, &evuser->taskpri); + if(status == ERROR) + return ERROR; + + evuser->taskpri += HIGHERPRIORITYINC; + + evuser->pendexit = FALSE; + + if(!taskname) + taskname = EVENT_PEND_NAME; + status = + taskSpawn( taskname, + evuser->taskpri, + EVENT_PEND_OPT, + EVENT_PEND_STACK, + event_task, + evuser, + init_func, + init_func_arg); + if(status == ERROR) + return ERROR; + + evuser->taskid = status; + + return OK; +} + + +event_task(evuser, init_func, init_func_arg) +register struct event_user *evuser; +register void (*init_func)(); +register int init_func_arg; +{ + register struct event_que *ev_que; + + /* init hook */ + if(init_func) + (*init_func)(init_func_arg); + + /* + No need to lock getix as I only allow one thread to call this routine at a time + */ + do{ + semTake(&evuser->pendsem); + + for(ev_que= &evuser->firstque; ev_que; ev_que = ev_que->nextque) + event_read(ev_que); + + /* + The following do not introduce event latency since they are + not between notification and posting events. + */ + if(evuser->queovr){ + if(evuser->overflow_sub) + (*evuser->overflow_sub)(evuser->overflow_arg, evuser->queovr); + else + logMsg("Events lost, discard count was %d\n",evuser->queovr); + evuser->queovr = 0; + } + + }while(!evuser->pendexit); + + evuser->pendlck = FALSE; + + /* joh- added this code to free additional event ques */ + { + struct event_que *nextque; + for(ev_que = evuser->firstque.nextque; ev_que; ev_que = nextque){ + nextque = ev_que->nextque; + if(free(ev_que)) + logMsg("evtsk: event user sub que free fail\n"); + } + } + /* end added code */ + + if(free(evuser)) + logMsg("evtsk: evuser free fail\n"); + + return OK; +} + + +event_read(ev_que) +register struct event_que *ev_que; +{ + register struct event_block *event; + register unsigned int getix; + register unsigned int nextgetix; + register struct dbAddr *paddr; + register char *pfield; + + /* + Fetch fast register copy + */ + getix = ev_que->getix; + + /* + No need to lock getix as I only allow one thread to call this routine at a time + */ + + for( event=ev_que->evque[getix]; + (event) != EVENTQEMPTY; + getix = nextgetix, event = ev_que->evque[nextgetix]){ + + /* + So I can tell em if more are comming + */ + nextgetix = RNGINC(getix); + + paddr = &event->addr; + + /* + Simple type values queued up for reliable interprocess communication. + (for other types they get whatever happens to be there upon wakeup) + */ + if(event->valque) + paddr->pfield = (char *) &ev_que->valque[getix]; + + + /* + Next event pointer can be used by event tasks to determine + if more events are waiting in the queue + */ + (*event->user_sub)( event->user_arg, + paddr, + ev_que->evque[nextgetix]); /* NULL if no next event */ + + ev_que->evque[getix] = (struct event_block *) NULL; + event->npend--; + + } + + /* + Store back to RAM copy + */ + ev_que->getix = getix; + + return OK; +} + +#ifdef ZEBRA + +struct event_user *tevuser; +struct dbAddr taddr; + + +db_test_event(precord_name) +register char *precord_name; +{ + int status; + int i; + + if(!tevuser){ + tevuser = db_init_events(); + + status = dbNameToAddr(precord_name, &taddr); + if(status==ERROR) + return ERROR; + + + status = db_start_events(tevuser); + if(status==ERROR) + return ERROR; + + status = db_add_event(tevuser, &taddr, logMsg, "Val\n", DBE_VALUE, NULL); + if(status==ERROR) + return ERROR; + status = db_add_event(tevuser, &taddr, logMsg, "Log\n", DBE_LOG, NULL); + if(status==ERROR) + return ERROR; + status = db_add_event(tevuser, &taddr, logMsg, "Alarm\n", DBE_ALARM, NULL); + if(status==ERROR) + return ERROR; + + } +/* + timexN(db_post_events, taddr.precord, taddr.pfield, DBE_VALUE | DBE_LOG); +*/ +/* + gremlin(taddr.precord, taddr.pfield); + while(TRUE)taskDelay(100); +*/ + + return OK; + +} + +gremlin(p1,p2) +void *p1; +void *p2; +{ + static unsigned int myprio = 250; + static unsigned int delay; + static unsigned int cnt; + + if(cnt<200) + { +/* + taskDelay((delay++)&0x3); +*/ + taskSpawn( "gremlin", + myprio-- & 0xff, + EVENT_PEND_OPT, + EVENT_PEND_STACK, + gremlin, + p1, + p2); + + taskSpawn( "gremlin", + myprio-- & 0xff, + EVENT_PEND_OPT, + EVENT_PEND_STACK, + gremlin, + p1, + p2); + db_post_events(p1,p2,DBE_VALUE | DBE_LOG); + cnt++; + } +} + + +#endif diff --git a/src/db/dbScan.c b/src/db/dbScan.c new file mode 100644 index 000000000..850820d61 --- /dev/null +++ b/src/db/dbScan.c @@ -0,0 +1,1746 @@ + +/* dbScan.c */ +/* share/src/db $Id$ */ + +/* + * dbScan.c - Database scanners + * + * tasks and subroutines to scan the database + * + * Author: Bob Dalesio + * Date: 11-30-88 + * @(#)dbscan.c 1.1S + * + * Control System Software for the GTA Project + * + * Copyright 1988, 1989, the Regents of the University of California. + * + * This software was produced under a U.S. Government contract + * (W-7405-ENG-36) at the Los Alamos National Laboratory, which is + * operated by the University of California for the U.S. Department + * of Energy. + * + * Developed by the Controls and Automation Group (AT-8) + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Direct inqueries to: + * Bob Dalesio, AT-8, Mail Stop H820 + * Los Alamos National Laboratory + * Los Alamos, New Mexico 87545 + * Phone: (505) 667-3414 + * E-mail: dalesio@luke.lanl.gov + * + * Modification Log: + * ----------------- + * .01 02-24-89 lrd modified for vxWorks 4.0 + * changed spawn to taskSpawn and changed args + * .02 02-24-89 lrd moved task info into task_params.h + * linked to vw for vx include files + * .03 02-28-89 lrd added check in build_scan_lists to verify the + * database section is loaded + * .04 03-14-89 lrd change task id's to int + * .05 03-23-89 lrd add restart logic + * .06 03-27-89 lrd modified to use the dbcommon structure + * deleted subroutine set_alarm + * .07 04-05-89 lrd added flag to signal drivers when we're ready to + * accept events + * .08 05-03-89 lrd removed process mask from dbProcess calls + * .09 05-25-89 lrd added support for the PID record + * .10 06-06-89 lrd added support for the SEL record + * .11 06-28-89 lrd only give undefined event msg on the first + * occurance of the event - keep a list of the + * undefined ones + * .10 07-21-89 lrd added support for the COMPRESS record + * .11 01-25-90 lrd added support for SUB records + * .12 04-05-90 lrd added the momentary output task + * .13 05-22-89 mrk periodic scan now scans at correct rate + * .14 08-08-90 lrd removed T_AI from initialization at start up + * only outputs need to be read at initialization + * .15 08-30-90 lrd renamed the interrupt scanner wakeup from + * intr_event_poster to io_scanner_wakeup + * .16 09-14-90 mrk changed for new record/device support + */ + +/* + * Code Portions: + * + * periodicScanTask Task which processes the periodic records + * ioEventTask Task which processes records on I/O interrupt + * eventTask Task which processes records on global events + * wdScanTask Task which restarts other tasks when suspended + * momentaryTask Task that turns off momentary outputs + * scan_init Build the scan lists and start the tasks + * remove_scan_tasks Delete scan tasks, free any malloc'd memory + * args + * tasks flags which tasks to remove + * build_scan_lists Looks through database and builds scan lists + * args + * lists flags which lists to build + * intialize_ring_buffers Initializes the ring buffers for the events + * args + * lists flags which ring buffers to initialize + * start_scan_tasks Start the scan tasks + * args + * tasks flags which scan tasks to start + * add_to_scan_list Adds an entry to a scan list + * args + * paddr pointer to this record + * lists which lists to build + * add_to_periodic_list Add an entry to the periodic scan list + * args + * paddr pointer to this record + * phase phase on which this record is scanned + * list_index which periodic list to place this record on + * returns + * 0 successful + * -1 failed + * add_to_io_event_list Add an entry to the I/O event list + * args + * paddr pointer to this record + * phase phase on which this record is scanned + * io_type I/O type of this record + * card_type card type of this records input + * card_number card number of this records input + * returns + * 0 successful + * -1 failed + * add_to_event_list Add an entry to the global event scanner + * args + * paddr pointer to this record + * phase phase on which this record is scanned + * event event on which this record will be scanned + * returns + * 0 successful + * -1 failed + * delete_from_scan_list Delete an entry from a scan list + * args + * paddr pointer to this record + * returns + * 0 successful + * -1 failed + * + * delete_from_periodic_list Delete an entry from the periodic scan list + * args + * paddr pointer to this record + * list_index which periodic list to remove this record from + * returns + * 0 successful + * -1 failed + * delete_from_io_event_list Delete an entry from the I/O event list + * args + * paddr pointer to this record + * phase phase on which this record is scanned + * io_type i/o type of this record + * card_type type of this records io card + * card_number card number of this record + * returns + * 0 successful + * -1 failed + * delete_from_event_list Delete an entry from the global event list + * args + * paddr pointer to this record + * phase phase on which this record is scanned + * event event on which this record is scanned + * returns + * 0 successful + * -1 failed + * get_io_info get io_type,card_type,card_number + * args + * paddr + * &pio_type + * &card_type + * &card_number + * print_lists Prints the periodic scan lists + * print_io_event_lists Print the I/O event lists + * print_event_lists Print the event lists + * + * io_scanner_wakeup Post an I/O event + * args + * io_type io type from which the event has come + * card_type card type from which the event has come + * card_number card number from which the event has come +} + * post_event Post an event + * args + * event event number + */ + +#include +#include +#include +#include /* library for semaphore support */ +#include /* library for ring buffer support */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +typedef unsigned long TIME; + +/* number of addr records in each set (malloc'ed at a time) */ +#define NUM_RECS_PER_SET 100 +#define NUM_SETS 4 + +/* db address struct: will contain the scan lists for all tasks */ +struct scan_list{ + unsigned short lock; + unsigned short scan_type; + unsigned short num_records; + unsigned short num_scan; + unsigned short scan_index; + unsigned short set; + unsigned short index; + unsigned int diagnostic; + struct scan_element *pscan; + struct scan_element *psets[NUM_SETS]; +}; +/* scan types */ +/* These must match the GBL_SCAN choices in choiceGbl.ascii */ +#define PASSIVE 0 +#define P2SECOND 1 +#define PSECOND 2 +#define PHALFSECOND 3 +#define PFIFTHSECOND 4 +#define PTENTHSECOND 5 +#define E_IO_INTERRUPT 6 +#define E_EXTERNAL 7 + +#define SL2SECOND 0 +#define SLSECOND 1 +#define SLHALFSECOND 2 +#define SLFIFTHSECOND 3 +#define SLTENTHSECOND 4 +#define NUM_LISTS (SLTENTHSECOND+1) + +struct scan_element{ + struct dbAddr dbAddr; + short phase; +}; + +#define PERIOD_BASE_RATE 6 /* 60 ticks per second */ + +/* I/O event driven scanner information */ + +#define IO_EVENT_PRIORITY 99 +#define MAX_IO_EVENTS 10 +#define MAX_IO_EVENT_CHANS 32 +struct io_event_list{ + short lock; + short defined; + short io_type; + short card_type; + short card_number; + short number_defined; + struct scan_element element[MAX_IO_EVENT_CHANS]; +}; + + +/* Event driven scanner information */ +#define MAX_EVENTS 100 +#define MAX_EVENT_CHANS 10 +struct event_list{ + short lock; + short defined; + short event_number; + short number_defined; + struct scan_element element[MAX_EVENT_CHANS]; +}; + + + +/* initialization field in database records */ +#define ARCH_INIT 2 /* first archive msg sent */ + + + +#define IO_EVENT 0x01 +#define EVENT 0x02 +#define PERIODIC 0x04 +#define WDSCAN 0x08 +#define MOMENTARY 0x10 + +int fd; /* used for the print list diagnostics */ + +/* link to the interrupable table from module_types.h */ +extern short *pinterruptable[]; + +/* PERIODIC SCANNER GLOBALS */ +/* periodic scan lists */ +static struct scan_list lists[NUM_LISTS]; + +/* number of periods in each scan list */ +static short periods_to_complete[] = {20,10,5,2,1}; + +static int periodicScanTaskId = 0; + + +/* I/O EVENT GLOBALS */ +/* I/O event scan list */ +static struct io_event_list io_event_lists[MAX_IO_EVENTS]; +static struct io_event_list io_events_undefined[MAX_IO_EVENTS]; + +/* semaphore on which the I/O scan task waits */ +static SEMAPHORE ioEventSem; + +/* ring buffer into which the drivers place the events which occured */ +static RING_ID ioEventQ; + +static int ioEventTaskId = 0; + + +/* EVENT GLOBALS */ +/* Event scan list */ +static struct event_list event_lists[MAX_EVENTS]; + +/* semaphore on which the I/O scan task waits */ +static SEMAPHORE eventSem; + +/* ring buffer into which the drivers place the events which occured */ +static RING_ID eventQ; + +static int eventTaskId = 0; + + +/* WATCHDOG GLOBALS */ +static int wdScanTaskId = 0; +static int wdScanOff = 0; + + +/* MOMENTARY GLOBALS */ +/* semaphore on which the momentary output task waits */ +SEMAPHORE momentarySem; + +/* ring buffer into which the drivers place the binary outputs to zero */ +RING_ID momentaryQ; + +static int momentaryTaskId = 0; +extern long masks[]; /* masks for bit numbers */ + +/* flag to the drivers that they can start to send events to the event tasks */ +short wakeup_init; + + +/* + * periodicScanTask + * + * scan all periodic scan lists + */ +periodicScanTask() +{ + long start_time,delay; + register short list,scan; + register struct scan_list *plist; + short disableListScan[NUM_LISTS]; + short periodsComplete[NUM_LISTS]; + int i; + + for(i=0; i < NUM_LISTS; i++){ + periodsComplete[i] = 0; + disableListScan[i] = FALSE; + } + + while(1){ + + /* get the start timex */ + start_time = tickGet(); + + /* do for all records */ + plist = &lists[0]; + for (list = 0; list < NUM_LISTS; list++,plist++){ + if (plist->num_records == 0){ + continue; + } + + /*enable processing list every periods_to_complete*/ + if(periodsComplete[list] >= periods_to_complete[list] ){ + disableListScan[list] = FALSE; + periodsComplete[list] = 0; + } + periodsComplete[list]++; + /*after processing all records in list , wait until enabled*/ + if(disableListScan[list]) continue; + + /* lock the list */ + if (!vxTas(&plist->lock)) continue; + + /* process each set in each scan list */ + for (scan=0; scan < plist->num_scan; scan++){ + struct dbAddr *paddr=&plist->pscan->dbAddr; + struct dbCommon *precord= + (struct dbCommon *)(paddr->precord); + + /* process this record */ + dbScanLock(precord); + if(!(precord->pact))dbProcess(paddr); + dbScanUnlock(precord); + + /* get the pointer to the next record */ + plist->scan_index++; + plist->index++; + if (plist->scan_index >= plist->num_records){ + /*when all records in list processed*/ + /* disable processing list*/ + plist->index = 0; + plist->set = 0; + plist->scan_index = 0; + plist->pscan = plist->psets[0]; + disableListScan[list] = TRUE; + }else if (plist->index >= NUM_RECS_PER_SET){ + plist->index = 0; + plist->set++; + if (plist->set > NUM_SETS) plist->set = 0; + plist->pscan = plist->psets[plist->set]; + }else{ + plist->pscan++; + } + } + /* unlock it */ + plist->lock = 0; + } + + /* sleep until next tenth second */ + delay = 60/10 - (tickGet() - start_time); + if (delay > 0) + taskDelay(delay); + } +} + +/* + * ioEventTask + * + * interrupt event scanner + */ +ioEventTask() +{ + struct intr_event intr_event; + register short event_index; + register short index; + register short found; + register struct io_event_list *pio_event_list; + register struct scan_element *pelement; + register struct intr_event *pintr_event = &intr_event; + + /* forever */ + FOREVER { + /* wait for somebody to wake us up */ + semTake(&ioEventSem); + + /* process requests in the command ring buffer */ + while (rngBufGet(ioEventQ,pintr_event,INTR_EVENT_SZ) == INTR_EVENT_SZ){ + /* find the event list */ + event_index = 0; + pio_event_list = &io_event_lists[0]; + found = FALSE; + while ((event_index < MAX_IO_EVENTS) && (!found)){ + if ((pio_event_list->defined) + && ((pio_event_list->io_type == pintr_event->io_type) + && (pio_event_list->card_type == pintr_event->card_type) + && (pio_event_list->card_number == pintr_event->card_number))){ + found = TRUE; + }else{ + pio_event_list++; + event_index++; + } + } + if (!found){ + /* only give a message the first time an undefined */ + /* event occurs */ + pio_event_list = &io_events_undefined[0]; + found = FALSE; + while ((event_index < MAX_IO_EVENTS) && (!found) && (pio_event_list->defined)){ + if ((pio_event_list->io_type == pintr_event->io_type) + && (pio_event_list->card_type == pintr_event->card_type) + && (pio_event_list->card_number == pintr_event->card_number)){ + found = TRUE; + }else{ + pio_event_list++; + event_index++; + } + } + if (!found){ + printf("no event list for iotype: %d card type: %d card number: %d\n", + pintr_event->io_type, + pintr_event->card_type, + pintr_event->card_number); + + /* add this to the list */ + if (pio_event_list->defined == 0){ + pio_event_list->defined = 1; + pio_event_list->io_type = pintr_event->io_type; + pio_event_list->card_type = pintr_event->card_type; + pio_event_list->card_number = pintr_event->card_number; + } + } + continue; + } + + /* process each record in the scan list */ + if (!vxTas(&pio_event_list->lock)) return; /* lock it */ + index = 0; + pelement = &pio_event_list->element[0]; + while (index < pio_event_list->number_defined){ + struct dbAddr *paddr=&pelement->dbAddr; + struct dbCommon *precord= + (struct dbCommon *)(paddr->precord); + + /* process this record */ + dbScanLock(precord); + if(!(precord->pact))dbProcess(paddr); + dbScanUnlock(precord); + + pelement++; + index++; + } + pio_event_list->lock = 0; /* unlock it */ + } + } +} + +/* + * eventTask + * + * event scanner + */ +eventTask() +{ + short event; + register short event_index; + register short index; + register short found; + register struct event_list *pevent_list; + register struct scan_element *pelement; + + /* forever */ + FOREVER { + /* wait for somebody to wake us up */ + semTake(&eventSem); + + /* process requests in the command ring buffer */ + while (rngBufGet(eventQ,&event,sizeof(short)) == sizeof(short)){ + + /* find the event list */ + event_index = 0; + pevent_list = &event_lists[0]; + found = FALSE; + while ((event_index < MAX_EVENTS) && (!found)){ + if ((pevent_list->defined) + && (pevent_list->event_number == event)){ + found = TRUE; + }else{ + pevent_list++; + event_index++; + } + } + if (!found){ + printf("no event list for event: %d\n",event); + continue; + } + + /* process each record in the scan list */ + if (!vxTas(&pevent_list->lock)) return; /* lock it */ + index = 0; + pelement = &pevent_list->element[0]; + while (index < pevent_list->number_defined){ + struct dbAddr *paddr=&pelement->dbAddr; + struct dbCommon *precord= + (struct dbCommon *)(paddr->precord); + + /* process this record */ + dbScanLock(precord); + if(!(precord->pact))dbProcess(paddr); + dbScanUnlock(precord); + + pelement++; + index++; + } + pevent_list->lock = 0; /* unlock it */ + } + } +} + +/* + * wdScanTask + * + * watch dog scan task + */ +wdScanTask() +{ + short lists; + + while(1){ + + /* verify the watchdog is desired */ + if (wdScanOff == 0){ + lists = 0; + + /* check the I/O Event Task */ + if (taskIsSuspended(ioEventTaskId)){ + printf("wdScanTask: Restarting ioEventTask\n"); + lists |= IO_EVENT; + } + + /* check the Event Task */ + if (taskIsSuspended(eventTaskId)){ + printf("wdScanTask: Restarting eventTask\n"); + lists |= EVENT; + } + + /* check the Periodic Scan Task */ + if (taskIsSuspended(periodicScanTaskId)){ + printf("wdScanTask: Restarting periodicScanTask\n"); + lists |= PERIODIC; + } + + /* if any are suspended - restart them */ + if (lists){ + /* remove scan tasks */ + remove_scan_tasks(lists); + + /* build the scan lists */ + build_scan_lists(lists); + + /* create event ring buffers */ + initialize_ring_buffers(lists); + + /* Spawn scanner tasks */ + start_scan_tasks(lists); + } + } + + /* sleep awhile */ + taskDelay(WDSCAN_DELAY); + } +} + +/* + * Momentary output task + * + * turns off momentary outputs after expired time + */ +momentaryTask(){ + struct intr_momentary intr_data; + + FOREVER { + /* wait for somebody to wake us up */ + semTake (&momentarySem); + + /* process requests in the command ring buffer */ + while (rngBufGet(momentaryQ,&intr_data,sizeof(intr_data))) { + (*intr_data.callback)(intr_data.arg); + } + } +} + +/* + * SCAN_INIT + * + * scanner intialization code: + * builds scan lists + * spawns the scan and watchdog tasks + */ +scan_init() +{ + /* remove scan tasks */ + remove_scan_tasks(EVENT | IO_EVENT | PERIODIC | MOMENTARY); + + /* build the scan lists */ + build_scan_lists(EVENT | IO_EVENT | PERIODIC); + + /* create event ring buffers */ + initialize_ring_buffers(EVENT | IO_EVENT | MOMENTARY); + + /* Spawn scanner tasks */ + start_scan_tasks(EVENT | IO_EVENT | PERIODIC | WDSCAN | MOMENTARY); + + /* let drivers know we're ready to accept events */ + wakeup_init = 1; + + return; +} + +/* + * REMOVE_SCAN_TASKS + * + * remove any tasks which are in existance + */ +remove_scan_tasks(tasks) +register short tasks; +{ + + register short set; + register short list_index; + + /* delete the ioEventTask if it is running */ + if (tasks & IO_EVENT){ + if (ioEventTaskId) + if (td(ioEventTaskId) != 0) + ioEventTaskId = 0; + + /* initialize the IO event lists */ + fill(io_event_lists,sizeof(struct event_list)*MAX_IO_EVENTS,0); + } + + /* delete the eventTask if it is running */ + if (tasks & EVENT){ + if (eventTaskId) + if (td(eventTaskId) != 0) + eventTaskId = 0; + + /* initialize the event lists */ + fill(event_lists,sizeof(struct event_list)*MAX_EVENTS,0); + } + + /* delete the momentaryTask if it is running */ + if (tasks & MOMENTARY){ + if (momentaryTaskId) + if (td(momentaryTaskId) != 0) + momentaryTaskId = 0; + } + + /* delete the periodicScanTask if it is running */ + if (tasks & PERIODIC){ + if (periodicScanTaskId){ + if (td(periodicScanTaskId) != 0) + periodicScanTaskId = 0; + for(list_index = 0; list_index < NUM_LISTS; list_index++){ + for (set = 0; set < NUM_SETS; set++){ + if (lists[list_index].psets[set]){ + free(lists[list_index].psets[set]); + } + } + } + } + + /* initialize the scan lists */ + fill(lists,sizeof(lists),0); + } + + /* delete the watchdog scan task */ + if (tasks & WDSCAN){ + if (wdScanTaskId){ + if (td(wdScanTaskId) != 0) + wdScanTaskId = 0; + } + } + +} + +/* + * BUILD_SCAN_LISTS + * + * build the specified scan lists + */ +build_scan_lists(lists) +register short lists; +{ + struct dbAddr dbAddr; /* database address */ + struct recLoc *precLoc; + struct dbCommon *precord; /* pointer to record */ + long status; + int i,j; + + if(dbRecords==NULL) { + errMessage(S_record_noRecords, + "Error detected in build_scan_lists"); + exit(0); + } + /* look through all of the database records and place them on lists */ + for (i=0; inumber; i++) { + if((precLoc=dbRecords->papRecLoc[i])==NULL) continue; + for(j=0, precord=(struct dbCommon*)(precLoc->pFirst); + jno_records; + j++, precord = (struct dbCommon *) + ((char *)precord + precLoc->rec_size)) { + if(precord->name[0]==0) continue; + /* get database address from access routines */ + if ((status=dbNameToAddr(precord->name,&dbAddr)) == 0){ + /* add it to a scan list */ + add_to_scan_list(&dbAddr,lists); + } else { + recGblDbaddrError(status,&dbAddr, + "build_scan_lists"); + } + } + } +} + +/* + * INITIALIZE_RING_BUFFERS + * + * initialize the ring buffers for the event tasks + */ +initialize_ring_buffers(lists) +register short lists; +{ + /* create the interrupt event ring buffer and semaphore */ + if (lists & IO_EVENT){ + /* clear it if it is created */ + if (ioEventQ){ + rngFlush(ioEventQ); + /* create it if it does not exist */ + }else if ((ioEventQ = rngCreate(INTR_EVENT_SZ * MAX_EVENTS)) + == (RING_ID)NULL){ + panic ("scan_init: ioEventQ not created\n"); + } + semInit(&ioEventSem); + } + + /* create the event ring buffer and semaphore */ + if (lists & EVENT){ + /* clear it if it is created */ + if (eventQ){ + rngFlush(eventQ); + /* create it if it does not exist */ + }else if ((eventQ = rngCreate(sizeof(short) * MAX_EVENTS)) + == (RING_ID)NULL){ + panic ("scan_init: eventQ not created\n"); + } + semInit(&eventSem); + } + + /* create the momentary ring buffer and semaphore */ + if (lists & MOMENTARY){ + /* clear it if it is created */ + if (momentaryQ){ + rngFlush(momentaryQ); + /* create it if it does not exist */ + }else if ((momentaryQ = rngCreate(sizeof(struct intr_momentary) * MAX_EVENTS)) + == (RING_ID)NULL){ + panic ("scan_init: momentaryQ not created\n"); + } + semInit(&momentarySem); + } +} + +/* + * START_SCAN_TASKS + * + * start the specified scan tasks + * parameters are from task_params.h + */ +start_scan_tasks(tasks) +register short tasks; +{ + if (tasks & IO_EVENT){ + ioEventTaskId = + taskSpawn(IOEVENTSCAN_NAME, + IOEVENTSCAN_PRI, + IOEVENTSCAN_OPT, + IOEVENTSCAN_STACK, + ioEventTask); + } + + if (tasks & EVENT){ + eventTaskId = + taskSpawn(EVENTSCAN_NAME, + EVENTSCAN_PRI, + EVENTSCAN_OPT, + EVENTSCAN_STACK, + eventTask); + } + + if (tasks & PERIODIC){ + periodicScanTaskId = + taskSpawn(PERIODSCAN_NAME, + PERIODSCAN_PRI, + PERIODSCAN_OPT, + PERIODSCAN_STACK, + periodicScanTask); + } + + if (tasks & WDSCAN){ + wdScanTaskId = + taskSpawn(WDSCAN_NAME, + WDSCAN_PRI, + WDSCAN_OPT, + WDSCAN_STACK, + wdScanTask); + } + + if (tasks & MOMENTARY){ + momentaryTaskId = + taskSpawn(MOMENTARY_NAME, + MOMENTARY_PRI, + MOMENTARY_OPT, + MOMENTARY_STACK, + momentaryTask); + } +} + +/* + * ADD_TO_SCAN_LIST + * + * add a new record's address to a scan list + */ +add_to_scan_list(paddr,lists) +register struct dbAddr *paddr; +register short lists; +{ + struct dbCommon *precord= (struct dbCommon *)(paddr->precord); + short scan_type; + short phase; + short event; + register short status; + + /* get the list on which this record belongs */ + scan_type = precord->scan; + phase = precord->phas; + event = precord->evnt; + /* add to the periodic scan or the event list */ + switch (scan_type){ + case (PASSIVE): + break; + case (P2SECOND): + if (lists & PERIODIC) + status = + add_to_periodic_list(paddr,phase,SL2SECOND); + else + return; + break; + + case (PSECOND): + if (lists & PERIODIC) + status = + add_to_periodic_list(paddr,phase,SLSECOND); + else + return; + break; + case (PHALFSECOND): + if (lists & PERIODIC) + status = + add_to_periodic_list(paddr,phase,SLHALFSECOND); + else + return; + break; + case (PFIFTHSECOND): + if (lists & PERIODIC) + status = + add_to_periodic_list(paddr,phase,SLFIFTHSECOND); + else + return; + break; + case (PTENTHSECOND): + if (lists & PERIODIC) + status = + add_to_periodic_list(paddr,phase,SLTENTHSECOND); + else + return; + break; + case (E_IO_INTERRUPT): + if (lists & IO_EVENT) { + short io_type; + short card_type; + short card_number; + + status=get_io_info(paddr,&io_type, + &card_type,&card_number); + if(status!=0) { + recGblDbaddrError(status,paddr, + "dbScan(get_io_info)"); + return; + } + status = add_to_io_event_list(paddr,phase, + io_type,card_type,card_number); + } else return; + break; + case (E_EXTERNAL): + if (lists & EVENT) + status = + add_to_event_list(paddr,phase,event); + else + return; + break; + default: + return; + } + + if (status < 0){ + ((struct dbCommon *)(paddr->precord))->stat = SCAN_ALARM; + ((struct dbCommon *)(paddr->precord))->sevr = MAJOR_ALARM; + } + return; +} + +/* + * ADD_TO_PERIODIC_LIST + * + * add a new record's address to a periodic scan list + */ +static add_to_periodic_list(paddr,phase,list_index) +register struct dbAddr *paddr; +short phase; +short list_index; +{ + register short set,index,found; + register struct scan_element *pspare_element; + register struct scan_element *ptest_element; + + /* lock the list during modification */ + if (!vxTas(&lists[list_index].lock)) return(-1); /* lock it */ + + /* determine if we need to create a new set on this scan list */ + set = lists[list_index].num_records / NUM_RECS_PER_SET; + if ((lists[list_index].num_records % NUM_RECS_PER_SET) == 0){ + if (set >= NUM_SETS){ + lists[list_index].lock = 0; /* unlock it */ + return(-1); + } + if ((lists[list_index].psets[set] = + (struct scan_element *)malloc(NUM_RECS_PER_SET*sizeof(struct scan_element))) == 0){ + lists[list_index].lock = 0; /* unlock it */ + return(-1); + } + fill(lists[list_index].psets[set],NUM_RECS_PER_SET*sizeof(struct scan_element),0); + } + + /* pointer to the slot at the end of the scan list */ + index = lists[list_index].num_records % NUM_RECS_PER_SET; + pspare_element = lists[list_index].psets[set]; + pspare_element += index; + + /* pointer to the last used slot in the scan list */ + index--; + if (index < 0){ + index = NUM_RECS_PER_SET - 1; + set--; + ptest_element = lists[list_index].psets[set]; + ptest_element += index; + }else{ + ptest_element = pspare_element - 1; + } + + /* determine where this record belongs */ + found = FALSE; + while(!found){ + /* beginning of list or test record has higher or equal phase */ + if ((set < 0) || (ptest_element->phase <= phase)){ + /* put the new record into the spare space */ + pspare_element->dbAddr = *paddr; + pspare_element->phase = phase; + found = TRUE; + /* move the tested record into the spare record space */ + }else{ + *pspare_element = *ptest_element; + pspare_element = ptest_element; + } + + /* find the next test element */ + index--; + if (index < 0){ + index = NUM_RECS_PER_SET - 1; + set--; + ptest_element = lists[list_index].psets[set]; + ptest_element += index; + }else{ + ptest_element--; + } + } + + /* adjust the list information */ + lists[list_index].num_records++; + lists[list_index].num_scan = + (lists[list_index].num_records / periods_to_complete[list_index]) + 1; + lists[list_index].pscan = lists[list_index].psets[0]; + lists[list_index].scan_index = 0; + lists[list_index].index = 0; + lists[list_index].set = 0; + + /* unlock it */ + lists[list_index].lock = 0; + + return(0); +} + +/* + * ADD_TO_IO_EVENT_LIST + * + * add a new record's address to an interrupt event scan list + */ +static add_to_io_event_list(paddr,phase,io_type,card_type,card_number) +register struct dbAddr *paddr; +short phase; +short io_type; +short card_type; +short card_number; +{ + struct io_event_list *pio_event_list; + struct scan_element *pelement; + struct scan_element *pspare; + register short event_index; + register short index; + register short found; + + /* verify this card has an interrupt */ + if (!pinterruptable[io_type][card_type]) + return(-1); + + /* is there a list for this iotype and card type */ + pio_event_list = &io_event_lists[0]; + event_index = 0; + found = FALSE; + while ((event_index < MAX_IO_EVENTS) && (!found)){ + if ((pio_event_list->defined) + && ((pio_event_list->io_type == io_type) + && (pio_event_list->card_type == card_type) + && (pio_event_list->card_number == card_number))){ + found = TRUE; + }else{ + pio_event_list++; + event_index++; + } + + } + + /* look for a spare list */ + if (!found){ + pio_event_list = &io_event_lists[0]; + event_index = 0; + found = FALSE; + while ((event_index < MAX_IO_EVENTS) && (!found)){ + if (!pio_event_list->defined){ + found = TRUE; + }else{ + pio_event_list++; + event_index++; + } + } + if (found){ + pio_event_list->defined = TRUE; + pio_event_list->io_type = io_type; + pio_event_list->card_type = card_type; + pio_event_list->card_number = card_number; + }else{ + return(-1); + } + } + + /* check for available space */ + if (pio_event_list->number_defined >= MAX_IO_EVENT_CHANS){ + return(-1); + } + + /* lock the list during modification */ + if (!vxTas(&pio_event_list->lock)) return(-1); + + /* add this record to the list */ + if (pio_event_list->number_defined == 0){ + pio_event_list->element[0].dbAddr = *paddr; + pio_event_list->element[0].phase = phase; + }else{ + index = pio_event_list->number_defined; + pspare = &pio_event_list->element[index]; + pelement = &pio_event_list->element[index-1]; + while ((pelement->phase > phase) && (index > 0)){ + *pspare = *pelement; + pelement--; + pspare--; + index--; + } + pspare->phase = phase; + pspare->dbAddr = *paddr; + } + pio_event_list->number_defined++; + + /* unlock the list */ + pio_event_list->lock = 0; + + return(0); +} + +/* + * ADD_TO_EVENT_LIST + * + * add a new record's address to an event scan list + */ +static add_to_event_list(paddr,phase,event) +register struct dbAddr *paddr; +short phase; +short event; +{ + struct event_list *pevent_list; + struct scan_element *pelement; + struct scan_element *pspare; + register short event_index; + register short index; + register short found; + + /* is there a list for this event */ + pevent_list = &event_lists[0]; + event_index = 0; + found = FALSE; + while ((event_index < MAX_EVENTS) && (!found)){ + if ((pevent_list->defined) + && (pevent_list->event_number == event)){ + found = TRUE; + }else{ + pevent_list++; + event_index++; + } + + } + + /* look for a spare list */ + if (!found){ + pevent_list = &event_lists[0]; + event_index = 0; + found = FALSE; + while ((event_index < MAX_EVENTS) && (!found)){ + if (!pevent_list->defined){ + found = TRUE; + }else{ + pevent_list++; + event_index++; + } + } + if (found){ + pevent_list->defined = TRUE; + pevent_list->event_number = event; + }else{ + return(-1); + } + } + + /* check for available space */ + if (pevent_list->number_defined >= MAX_EVENT_CHANS){ + return(-1); + } + + /* lock the list during modification */ + if (!vxTas(&pevent_list->lock)) return(-1); + + /* add this record to the list */ + if (pevent_list->number_defined == 0){ + pevent_list->element[0].dbAddr = *paddr; + pevent_list->element[0].phase = phase; + }else{ + index = pevent_list->number_defined; + pspare = &pevent_list->element[index]; + pelement = &pevent_list->element[index-1]; + while ((pelement->phase > phase) && (index > 0)){ + *pspare = *pelement; + pelement--; + pspare--; + index--; + } + pspare->phase = phase; + pspare->dbAddr = *paddr; + } + pevent_list->number_defined++; + + /* unlock the list */ + pevent_list->lock = 0; + + return(0); +} + +/* + * DELETE_FROM_SCAN_LIST + * + * delete a record's address from a scan list + */ +delete_from_scan_list(paddr) +register struct dbAddr *paddr; +{ + struct dbCommon *precord= (struct dbCommon *)(paddr->precord); + short scan_type; + short phase; + short event; + register short status; + + /* get the list on which this record belongs */ + scan_type = precord->scan; + phase = precord->phas; + event = precord->evnt; + /* add to the periodic scan or the event list */ + switch (scan_type){ + case (PASSIVE): + return(-1); + case (P2SECOND): + return(delete_from_periodic_list(paddr,SL2SECOND)); + case (PSECOND): + return(delete_from_periodic_list(paddr,SLSECOND)); + case (PHALFSECOND): + return(delete_from_periodic_list(paddr,SLHALFSECOND)); + case (PFIFTHSECOND): + return(delete_from_periodic_list(paddr,SLFIFTHSECOND)); + case (PTENTHSECOND): + return(delete_from_periodic_list(paddr,SLTENTHSECOND)); + case (E_IO_INTERRUPT): { + short io_type; + short card_type; + short card_number; + + status=get_io_info(paddr,&io_type, + &card_type,&card_number); + if(status!=0) { + recGblDbaddrError(status,paddr, + "dbScan(get_io_info)"); + return; + } + return(delete_from_io_event_list(paddr,phase,io_type, + card_type,card_number)); + } + case (E_EXTERNAL): + return(delete_from_event_list(paddr,phase,event)); + default: + return(-1); + } +} + +/* + * DELETE_FROM_PERIODIC_LIST + * + * delete a record's address from a periodic scan list + */ +static delete_from_periodic_list(paddr,list_index) +register struct dbAddr *paddr; +short list_index; +{ + register short set,index,found; + register struct scan_element *pelement; + register struct scan_element *pnext_element; + short end_of_list; + + /* lock the list during modification */ + if (!vxTas(&lists[list_index].lock)) return(-1); + + /* find this record */ + found = FALSE; + set = 0; + index = 0; + end_of_list = FALSE; + pelement = lists[list_index].psets[set]; + while((!found) && (!end_of_list)){ + if (pelement->dbAddr.precord == paddr->precord){ + found = TRUE; + }else{ + index++; + if (index >= NUM_RECS_PER_SET){ + index = 0; + set++; + pelement = lists[list_index].psets[set]; + if (set >= NUM_SETS) end_of_list = TRUE; + }else{ + pelement++; + } + } + } + if (!found){ + lists[list_index].lock = 0; /* unlock it */ + return(-1); + } + + /* move each record in the scan list down */ + while (!end_of_list){ + index++; + if (index >= NUM_RECS_PER_SET){ + index = 0; + set++; + if (set >= NUM_SETS){ + end_of_list = TRUE; + }else{ + pnext_element=lists[list_index].psets[set]; + } + }else{ + pnext_element = pelement + 1; + } + + if (!end_of_list){ + *pelement = *pnext_element; + pelement = pnext_element; + }else{ + fill(pelement,sizeof(struct scan_element),0); + } + } + + /* adjust the list information */ + lists[list_index].num_records--; + lists[list_index].num_scan = + (lists[list_index].num_records/periods_to_complete[list_index])+1; + + /* determine if we need to free the memory for a set */ + if ((lists[list_index].num_records % NUM_RECS_PER_SET) == 0){ + set = lists[list_index].num_records / NUM_RECS_PER_SET; + free(lists[list_index].psets[set]); + lists[list_index].psets[set] = 0; + } + + /* unlock the scan list */ + lists[list_index].lock = 0; + + return(0); +} + +/* + * DELETE_FROM_IO_EVENT_LIST + * + * delete a record's address to an interrupt event scan list + */ +static delete_from_io_event_list(paddr,phase,io_type,card_type,card_number) +register struct dbAddr *paddr; +short phase; +short io_type; +short card_type; +short card_number; +{ + struct io_event_list *pio_event_list; + struct scan_element *pelement; + struct scan_element *pnext_element; + register short event_index; + register short index; + register short found; + + /* is there a list for this iotype,card type and card number */ + pio_event_list = &io_event_lists[0]; + event_index = 0; + found = FALSE; + while ((event_index < MAX_IO_EVENTS) && (!found)){ + if ((pio_event_list->defined) + && ((pio_event_list->io_type == io_type) + && (pio_event_list->card_type == card_type) + && (pio_event_list->card_number == card_number))){ + found = TRUE; + }else{ + pio_event_list++; + event_index++; + } + + } + if (!found) return(-1); + + /* lock the list during modification */ + if (!vxTas(&pio_event_list->lock)) return(-1); + + /* find this record in the list */ + index = 0; + pelement = &pio_event_list->element[0]; + found = FALSE; + while ((!found) + && (index < pio_event_list->number_defined)){ + if (pelement->dbAddr.precord == paddr->precord){ + found = TRUE; + }else{ + pelement++; + index++; + } + } + if (!found){ + pio_event_list->lock = 0; /* unlock it */ + return(-1); + } + + /* delete this record from the list */ + index++; + pnext_element = &pio_event_list->element[index]; + while (index < pio_event_list->number_defined) { + *pelement = *pnext_element; + pelement++; + pnext_element++; + index++; + } + fill(pelement,sizeof(struct scan_element),0); + pio_event_list->number_defined--; + + /* if this is the last scan element in the list - free it */ + if (pio_event_list->number_defined == 0){ + pio_event_list->defined = FALSE; + pio_event_list->io_type = 0; + pio_event_list->card_type = 0; + pio_event_list->card_number = 0; + } + + /* unlock the list */ + pio_event_list->lock = 0; + + return(0); +} + +/* + * DELETE_FROM_EVENT_LIST + * + * delete a record's address to an event scan list + */ +static delete_from_event_list(paddr,phase,event) +register struct dbAddr *paddr; +short phase; +short event; +{ + struct event_list *pevent_list; + struct scan_element *pelement; + struct scan_element *pnext_element; + register short event_index; + register short index; + register short found; + + /* is there a list for this iotype,card type and card number */ + pevent_list = &event_lists[0]; + event_index = 0; + found = FALSE; + while ((event_index < MAX_EVENTS) && (!found)){ + if ((pevent_list->defined) + && (pevent_list->event_number == event)){ + found = TRUE; + }else{ + pevent_list++; + event_index++; + } + + } + if (!found) return(-1); + + /* lock the list during modification */ + if (!vxTas(&pevent_list->lock)) return(-1); + + /* find this record in the list */ + index = 0; + pelement = &pevent_list->element[0]; + found = FALSE; + while ((!found) + && (index < pevent_list->number_defined)){ + if (pelement->dbAddr.precord == paddr->precord){ + found = TRUE; + }else{ + pelement++; + index++; + } + } + if (!found){ + pevent_list->lock = 0; /* unlock it */ + return(-1); + } + + /* delete this record from the list */ + index++; + pnext_element = &pevent_list->element[index]; + while (index < pevent_list->number_defined) { + *pelement = *pnext_element; + pelement++; + pnext_element++; + index++; + } + fill(pelement,sizeof(struct scan_element),0); + pevent_list->number_defined--; + + /* if this is the last scan element in the list - free it */ + if (pevent_list->number_defined == 0){ + pevent_list->defined = FALSE; + pevent_list->event_number = 0; + } + + /* unlock the list */ + pevent_list->lock = 0; + + return(0); +} + +/* + * GET_IO INFO + * + * get the io_type,card_type, and card_number + */ +static long get_io_info(paddr,pio_type,pcard_type,pcard_number) +struct dbAddr *paddr; +short *pio_type; +short *pcard_type; +short *pcard_number; +{ + struct dbCommon *precord=(struct dbCommon *)(paddr->precord); + long status; + + if((precord->dset == NULL) ||(precord->dset->get_ioint_info == NULL )) + return(S_dev_noDevSup); + status=(*precord->dset->get_ioint_info) + (paddr,pio_type,pcard_type,pcard_number); + return(status); +} + +/* + * PRINT_LIST + * + * print the scan lists + */ +print_list() +{ + struct scan_element *pelement; + struct scan_list *plist; + register short set,num_records,index; + short list; + char input[5]; + + fd = fioStdIn(); + + /* print each scan list */ + printf("\n"); + plist = &lists[0]; + for (list = 0; list < NUM_LISTS; list++,plist++){ + if (plist->num_records == 0){ + printf("list %d is empty\n",list); + continue; + } + if (plist->num_records >= NUM_RECS_PER_SET * NUM_SETS){ + printf("list %d is full\n",list); + }else{ + printf("list %d has %d entries\n",list,plist->num_records); + } + + /* print each set in each scan list */ + num_records = 0; + for (set=0; (setnum_records); set++){ + printf("\tset %d\n",set); + + /* print each element in each set */ + pelement = plist->psets[set]; + for (index=0; (indexnum_records); index++,pelement++){ + num_records++; + if ((pelement->dbAddr.precord[0] >= 'A') && (pelement->dbAddr.precord[0] <= 'z')) + printf("\t\t%s\n",pelement->dbAddr.precord); + else + printf("\t\tnot printable\n"); + } + } + + /* wait for a character to print the next set */ + read(fd,input,1); + } +} + +/* + * PRINT_IO_EVENT_LISTS + * + * print the io event lists + */ +print_io_event_lists() +{ + struct io_event_list *plist; + register short set,num_records,index; + short list; + char input[5]; + struct scan_element *pelement; + + fd = fioStdIn(); + + /* print each scan list */ + printf("\n"); + plist = &io_event_lists[0]; + for (list = 0; list < MAX_IO_EVENTS; list++,plist++){ + if (plist->defined == 0){ + printf("event list %d is unused\n",list); + continue; + } + if (plist->number_defined >= MAX_IO_EVENT_CHANS){ + printf("event list %d is full\n",list); + printf("\tio type: %d card type: %d card number: %d\n", + plist->io_type,plist->card_type,plist->card_number); + }else{ + printf("event list %d has %d entries\n",list,plist->number_defined); + printf("\tio type: %d card type: %d card number: %d\n", + plist->io_type,plist->card_type,plist->card_number); + } + + /* print each set in each scan list */ + num_records = 0; + pelement = &plist->element[0]; + for (index=0; (indexnumber_defined); index++,pelement++){ + num_records++; + if ((pelement->dbAddr.precord[0] >= 'A') && (pelement->dbAddr.precord[0] <= 'z')) + printf("\t\t%s\n",pelement->dbAddr.precord); + else + printf("\t\tnot printable\n"); + } + + /* wait for a character to print the next set */ + read(fd,input,1); + } +} + +/* + * PRINT_EVENT_LISTS + * + * print the event lists + */ +print_event_lists() +{ + struct event_list *plist; + register short set,num_records,index; + short list; + char input[5]; + struct scan_element *pelement; + + fd = fioStdIn(); + + /* print each scan list */ + printf("\n"); + plist = &event_lists[0]; + for (list = 0; list < MAX_EVENTS; list++,plist++){ + if (plist->defined == 0){ + printf("event list %d is unused\n",list); + continue; + } + if (plist->number_defined >= MAX_EVENT_CHANS){ + printf("event list %d is full\n",list); + printf("\tevent: %d\n",plist->event_number); + }else{ + printf("event list %d has %d entries\n",list,plist->number_defined); + printf("\tevent: %d\n",plist->event_number); + } + + /* print each set in each scan list */ + num_records = 0; + pelement = &plist->element[0]; + for (index=0; (indexnumber_defined); index++,pelement++){ + num_records++; + if ((pelement->dbAddr.precord[0] >= 'A') && (pelement->dbAddr.precord[0] <= 'z')) + printf("\t\t%s\n",pelement->dbAddr.precord); + else + printf("\t\tnot printable\n"); + } + + /* wait for a character to print the next set */ + read(fd,input,1); + } +} + +/* + * IO_SCANNER_WAKEUP + * + * wake up the I/O interrupt event scanner + */ +io_scanner_wakeup(io_type,card_type,card_number) +short io_type,card_type,card_number; +{ + struct intr_event intr_event; + + if (wakeup_init != 1) return; /* not awake yet */ + intr_event.io_type = io_type; + intr_event.card_type = card_type; + intr_event.card_number = card_number; + + rngBufPut(ioEventQ,&intr_event,INTR_EVENT_SZ); + semGive(&ioEventSem); +} + +/* + * POST_EVENT + * + * wake up the event scanner + */ +post_event(event_number) +short event_number; +{ + if (wakeup_init != 1) return; /* not awake yet */ + /* logMsg("Post Events\n"); */ + rngBufPut(eventQ,&event_number,sizeof(short)); + semGive(&eventSem); +} + + diff --git a/src/db/dbTest.c b/src/db/dbTest.c new file mode 100644 index 000000000..143f581eb --- /dev/null +++ b/src/db/dbTest.c @@ -0,0 +1,780 @@ + +/* dbTest.c */ +/* share/src/db $Id$ */ + +/* dbTest.c + * + * database access test subroutines + * + * Author: Bob Dalesio(LANL) and Marty Kraimer(ANL) + * + * Control System Software for the GTA Project + * + * Copyright 1988, 1989, the Regents of the University of California. + * + * This software was produced under a U.S. Government contract + * (W-7405-ENG-36) at the Los Alamos National Laboratory, which is + * operated by the University of California for the U.S. Department + * of Energy. + * + * Developed by the Controls and Automation Group (AT-8) + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Direct inqueries to: + * Bob Dalesio, AT-8, Mail Stop H820 + * Los Alamos National Laboratory + * Los Alamos, New Mexico 87545 + * Phone: (505) 667-3414 + * E-mail: dalesio@luke.lanl.gov + * + * Modification Log: + * ----------------- + * .xx mm-dd-yy mrk Comment + * + */ + +/* Global Database Test Routines - All can be invoked via vxWorks shell + * + * dbl(ptypeName) list record names. + * char *ptypeName; Record type. If null all record types + * + * dbgf(pname) get field + * char *pname; + * + * dbpf(pname,pvalue) put field + * char *pname; + * char *pvalue + * + * dbpr(pname) print record + * char *pname; + * + * dbtr(pname) test record and print + * char *pname; + * + * dbtgf(pname) test get field + * char *pname; + * + * dbtpf(pname,pvalue) test put field + * char *pname; + * char *pvalue + * + * dbior(pname) io_report + * char *pname Driver name. If null all drivers + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MIN(x,y) ((x < y)?x:y) +#define MAX(x,y) ((x > y)?x:y) + +/* Local Routines */ +printDbAddr(); +printBuffer(); + +long dbl(ptypeName) /* list process variables for specified record type*/ + char *ptypeName; +{ + int rectype,beg,end,recnum; + struct recLoc *precLoc; + struct dbCommon *precord; + char *pstr; + char name[PVNAME_SZ+1]; + + if(dbRecType==NULL || dbRecords==NULL) return(1); + if(ptypeName==NULL) { + beg=0; + end=dbRecords->number - 1; + } + else { + for(rectype=0; rectypenumber; rectype++) { + if(!(pstr=GET_PRECTYPE(rectype))) continue; + if(strcmp(pstr,ptypeName)==0){ + beg=rectype; + end=rectype; + goto got_it; + } + } + printf("Illegal Record Type\n"); + return(1); + } +got_it: + for(rectype=beg; rectype<=end; rectype++) { + if(!(precLoc=GET_PRECLOC(rectype))) continue; + for(recnum=0; precord=(struct dbCommon *)(GET_PRECORD(precLoc,recnum)); + recnum++) { + if(precord->name[0] == 0) continue; /*deleted record*/ + strncpy(name,precord->name,PVNAME_SZ); + name[PVNAME_SZ]=0; + printf("%s\n",name); + } + } + return(0); +} + +long dbgf(pname) /* get field value*/ + char *pname; +{ + /* declare buffer long just to ensure correct alignment */ + long buffer[100]; + long *pbuffer=&buffer[0]; + struct dbAddr addr; + long status; + long options,no_elements; + + status=dbNameToAddr(pname,&addr); + printDbAddr(status,&addr); + if(status) return(1); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + if(addr.dbr_field_type==DBR_ENUM) { + status=dbGetField(&addr,DBR_STRING,pbuffer,&options,&no_elements); + printBuffer(status,DBR_STRING,pbuffer,0L,0L,no_elements); + } + else { + status=dbGetField(&addr,addr.dbr_field_type,pbuffer,&options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + return(0); +} + +long dbpf(pname,pvalue) /* put field value*/ + char *pname; + char *pvalue; +{ + /* declare buffer long just to ensure correct alignment */ + long buffer[100]; + long *pbuffer=&buffer[0]; + struct dbAddr addr; + long status; + long options,no_elements; + + status=dbNameToAddr(pname,&addr); + printDbAddr(status,&addr); + if(status) return(1); + status=dbPutField(&addr,DBR_STRING,pvalue,1L); + if(status!=0) errPrint(status); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer,&options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + return(0); +} + +long dbpr(pname) /* print record */ + char *pname; +{ + struct dbAddr addr; + long status; + long options,no_elements; + struct rset *prset; + long int (*report)()=NULL; + + status=dbNameToAddr(pname,&addr); + printDbAddr(status,&addr); + if(status) return(1); + if(!(prset=GET_PRSET(addr.record_type))) { + printf("No record Support for this record type\n"); + return(1); + } + if(!(report = (prset->report))) { + printf("No report routine in RSET\n"); + return(1); + } + status=(*report)(stdout,&addr); + fflush(stdout); + if(!RTN_SUCCESS(status)) + recGblRecSupError(S_db_noSupport,&addr,"dbpr","report"); + return(0); +} + +long dbtr(pname) /* test record and print*/ + char *pname; +{ + struct dbAddr addr; + long status; + long options,no_elements; + struct rset *prset; + long int (*process)()=NULL; + + status=dbNameToAddr(pname,&addr); + if(status) { + printf("dbNameToAddr failed\n"); + return(1); + } + if(!(prset=GET_PRSET(addr.record_type))) { + printf("No record Support for this record type\n"); + return(1); + } + if(!(process = (prset->process))) { + printf("No process routine in RSET\n"); + return(1); + } + status=(*process)(addr.precord); + if(!RTN_SUCCESS(status)) + recGblRecSupError(S_db_noSupport,&addr,"dbtr","process"); + dbpr(pname); + return(0); +} + +long dbtgf(pname) /* test all options for dbGetField */ + char *pname; +{ + /* declare buffer long just to ensure correct alignment */ + long buffer[300]; + long *pbuffer=&buffer[0]; + struct dbAddr addr; + long status; + long req_options,ret_options,no_elements; + short dbr_type; + + status=dbNameToAddr(pname,&addr); + printDbAddr(status,&addr); + if(status)return; + /* try all options first */ + req_options=0xffffffff; + ret_options=req_options; + no_elements=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &ret_options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer, + req_options,ret_options,no_elements); + /* Now try all request types */ + ret_options=0; + dbr_type=DBR_STRING; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/MAX_STRING_SIZE)); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_CHAR; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(char))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_UCHAR; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(unsigned char))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_SHORT; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(short))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_USHORT; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(unsigned short))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_LONG; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(long))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_ULONG; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(unsigned long))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_FLOAT; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(float))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_DOUBLE; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(double))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + dbr_type=DBR_ENUM; + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/sizeof(unsigned short))); + status=dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements); + printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements); + return(0); +} + +long dbtpf(pname,pvalue)/* test all options for dbPutField */ + char *pname; +{ + /* declare buffer long just to ensure correct alignment */ + long buffer[100]; + long *pbuffer=&buffer[0]; + struct dbAddr addr; + long status; + long options,no_elements; + char cvalue; + unsigned char ucvalue; + short svalue; + unsigned short usvalue; + long lvalue; + unsigned long ulvalue; + float fvalue; + double dvalue; + + status=dbNameToAddr(pname,&addr); + printDbAddr(status,&addr); + if(status) return(1); + /* DBR_STRING */ + status=dbPutField(&addr,DBR_STRING,pvalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_STRING ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + /* DBR_CHAR */ + if(sscanf(pvalue,"%hd",&svalue)==1) { + cvalue = (char)svalue; + status=dbPutField(&addr,DBR_CHAR,&cvalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_UCHAR ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_CHAR\n"); + /* DBR_UCHAR */ + if(sscanf(pvalue,"%hu",&usvalue)==1) { + ucvalue = (unsigned char)usvalue; + status=dbPutField(&addr,DBR_UCHAR,&ucvalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_UCHAR ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_UCHAR\n"); + /* DBR_SHORT */ + if(sscanf(pvalue,"%hd",&svalue)==1) { + status=dbPutField(&addr,DBR_SHORT,&svalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_SHORT ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_SHORT\n"); + /* DBR_USHORT */ + if(sscanf(pvalue,"%hu",&usvalue)==1) { + status=dbPutField(&addr,DBR_USHORT,&usvalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_USHORT ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_USHORT\n"); + /* DBR_LONG */ + if(sscanf(pvalue,"%ld",&lvalue)==1) { + status=dbPutField(&addr,DBR_LONG,&lvalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_LONG ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_LONG\n"); + /* DBR_ULONG */ + if(sscanf(pvalue,"%lu",&ulvalue)==1) { + status=dbPutField(&addr,DBR_ULONG,&ulvalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_ULONG ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_ULONG\n"); + /* DBR_FLOAT */ + if(sscanf(pvalue,"%e",&fvalue)==1) { + status=dbPutField(&addr,DBR_FLOAT,&fvalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_FLOAT ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_FLOAT\n"); + /* DBR_DOUBLE */ + if(sscanf(pvalue,"%le",&dvalue)==1) { + status=dbPutField(&addr,DBR_DOUBLE,&dvalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_DOUBLE ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_DOUBLE\n"); + /* DBR_ENUM */ + if(sscanf(pvalue,"%hu",&svalue)==1) { + status=dbPutField(&addr,DBR_ENUM,&svalue,1L); + if(status!=0) errPrint(status); + else { + printf("DBR_ENUM ok\n"); + no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size)); + options=0; + status=dbGetField(&addr,addr.dbr_field_type,pbuffer, + &options,&no_elements); + printBuffer(status,addr.dbr_field_type,pbuffer,0L,0L,no_elements); + } + } else printf("sscanf failed for DBR_SHORT\n"); + return(0); +} + +long printDbAddr(status,paddr) + long status; + struct dbAddr *paddr; +{ + + if(status!=0) { + errPrint(status); + } + printf("Record Address: 0x%x",paddr->precord); + printf(" Field Address: 0x%x",paddr->pfield); + printf(" Field Description: 0x%x\n",paddr->pfldDes); + printf(" No Elements: %ld\n",paddr->no_elements); + printf(" Record Type: %d\n",paddr->record_type); + printf(" Field Type: %d\n",paddr->field_type); + printf(" Field Size: %d\n",paddr->field_size); + printf(" Special: %d\n",paddr->special); + printf(" Choice Set: %d\n",paddr->choice_set); + printf("DBR Field Type: %d\n",paddr->dbr_field_type); +} + +long printBuffer(status,dbr_type,pbuffer,reqOptions,retOptions,no_elements) + long status; + short dbr_type; + char *pbuffer; + long reqOptions; + long retOptions; + long no_elements; +{ + unsigned short stat,severity; + long precision; + unsigned long epoch_seconds; + unsigned long nano_seconds; + unsigned long no_strs; + short sarr[6]; + short svalue; + unsigned short usarr[6]; + unsigned short usvalue; + int i; + + if(reqOptions&DBR_STATUS) { + if(retOptions&DBR_STATUS) { + stat = *((unsigned short*)pbuffer); + severity = *((unsigned short*)(pbuffer+2)); + printf("status=%u severity=%u\n",stat,severity); + } else printf("status and severity not returned\n"); + pbuffer += dbr_status_size; + } + if(reqOptions&DBR_UNITS) { + if(retOptions&DBR_UNITS) printf("units=%-8s\n",pbuffer); + else printf("units not returned\n"); + pbuffer += dbr_units_size; + } + if(reqOptions&DBR_PRECISION) { + precision = *((long*)pbuffer); + if(retOptions&DBR_PRECISION) printf("precision=%ld\n",precision); + else printf("precision not returned\n"); + pbuffer += dbr_precision_size; + } + if(reqOptions&DBR_TIME) { + epoch_seconds = *((unsigned long*)pbuffer); + nano_seconds = *((unsigned long*)(pbuffer+4)); + if(retOptions&DBR_TIME) + printf("time=%lu %lu\n",epoch_seconds,nano_seconds); + else printf("time not returned\n"); + pbuffer += dbr_time_size; + } + if(reqOptions&DBR_ENUM_STRS) { + if(retOptions&DBR_ENUM_STRS) { + no_strs = *((unsigned long*)pbuffer); + printf("no_strs=%lu\n",no_strs); + for(i=0; i < *((unsigned long *)pbuffer); i++) + printf("%s\n",(pbuffer + 4 + i*26)); + } else printf("enum strings not returned\n"); + pbuffer += dbr_enumStrs_size; + } + if(reqOptions&DBR_GR_UCHAR) { + usarr[0]=*((unsigned char *)pbuffer); + usarr[1]=*((unsigned char *)(pbuffer+1)); + usarr[2]=*((unsigned char *)(pbuffer+2)); + usarr[3]=*((unsigned char *)(pbuffer+3)); + usarr[4]=*((unsigned char *)(pbuffer+4)); + usarr[5]=*((unsigned char *)(pbuffer+5)); + if(retOptions&DBR_GR_UCHAR) + printf("grUchar: %u %u %u %u %u %u\n", + usarr[0],usarr[1],usarr[2],usarr[3],usarr[4],usarr[5]); + else printf("DBRgrUchar not returned\n"); + pbuffer += dbr_grUchar_size; + } + if(reqOptions&DBR_GR_SHORT) { + if(retOptions&DBR_GR_SHORT) + printf("grShort: %d %d %d %d %d %d\n", + *(short *)(pbuffer), + *(short *)(pbuffer+2), + *(short *)(pbuffer+4), + *(short *)(pbuffer+6), + *(short *)(pbuffer+8), + *(short *)(pbuffer+10)); + else printf("DBRgrShort not returned\n"); + pbuffer += dbr_grShort_size; + } + if(reqOptions&DBR_GR_LONG) { + if(retOptions&DBR_GR_LONG) + printf("grLong: %ld %ld %ld %ld %ld %ld\n", + *(long *)(pbuffer), + *(long *)(pbuffer+4), + *(long *)(pbuffer+8), + *(long *)(pbuffer+12), + *(long *)(pbuffer+16), + *(long *)(pbuffer+20)); + else printf("DBRgrLong not returned\n"); + pbuffer += dbr_grLong_size; + } + if(reqOptions&DBR_GR_ULONG) { + if(retOptions&DBR_GR_ULONG) + printf("grUlong: %lu %lu %lu %lu %lu %lu\n", + *(unsigned long *)(pbuffer), + *(unsigned long *)(pbuffer+4), + *(unsigned long *)(pbuffer+8), + *(unsigned long *)(pbuffer+12), + *(unsigned long *)(pbuffer+16), + *(unsigned long *)(pbuffer+20)); + else printf("DBRgrUlong not returned\n"); + pbuffer += dbr_grUlong_size; + } + if(reqOptions&DBR_GR_FLOAT) { + if(retOptions&DBR_GR_FLOAT) + printf("grFloat: %g %g %g %g %g %g\n", + *(float *)(pbuffer), + *(float *)(pbuffer+4), + *(float *)(pbuffer+8), + *(float *)(pbuffer+12), + *(float *)(pbuffer+16), + *(float *)(pbuffer+20)); + else printf("DBRgrFloat not returned\n"); + pbuffer += dbr_grFloat_size; + } + if(reqOptions&DBR_GR_DOUBLE) { + if(retOptions&DBR_GR_DOUBLE) + printf("grDouble: %lg %lg %lg %lg %lg %lg\n", + *(double *)(pbuffer), + *(double *)(pbuffer+8), + *(double *)(pbuffer+16), + *(double *)(pbuffer+24), + *(double *)(pbuffer+32), + *(double *)(pbuffer+40)); + else printf("DBRgrDouble not returned\n"); + pbuffer += dbr_grDouble_size; + } + if(reqOptions&DBR_CTRL_UCHAR) { + usarr[0]=*((unsigned char *)pbuffer); + usarr[1]=*((unsigned char *)(pbuffer+1)); + if(retOptions&DBR_CTRL_UCHAR) + printf("ctrlUchar: %u %u\n", + usarr[0],usarr[1]); + else printf("DBRctrlUchar not returned\n"); + pbuffer += dbr_ctrlUchar_size; + } + if(reqOptions&DBR_CTRL_SHORT) { + if(retOptions&DBR_CTRL_SHORT) + printf("ctrlShort: %d %d\n", + *(short *)(pbuffer), + *(short *)(pbuffer+2)); + else printf("DBRctrlShort not returned\n"); + pbuffer += dbr_ctrlShort_size; + } + if(reqOptions&DBR_CTRL_LONG) { + if(retOptions&DBR_CTRL_LONG) + printf("ctrlLong: %ld %ld\n", + *(long *)(pbuffer), + *(long *)(pbuffer+4)); + else printf("DBRctrlLong not returned\n"); + pbuffer += dbr_ctrlLong_size; + } + if(reqOptions&DBR_CTRL_ULONG) { + if(retOptions&DBR_CTRL_ULONG) + printf("ctrlUlong: %lu %lu\n", + *(unsigned long *)(pbuffer), + *(unsigned long *)(pbuffer+4)); + else printf("DBRctrlUlong not returned\n"); + pbuffer += dbr_ctrlUlong_size; + } + if(reqOptions&DBR_CTRL_FLOAT) { + if(retOptions&DBR_CTRL_FLOAT) + printf("ctrlFloat: %g %g\n", + *(float *)(pbuffer), + *(float *)(pbuffer+4)); + else printf("DBRctrlFloat not returned\n"); + pbuffer += dbr_ctrlFloat_size; + } + if(reqOptions&DBR_CTRL_DOUBLE) { + if(retOptions&DBR_CTRL_DOUBLE) + printf("ctrlDouble: %lg %lg\n", + *(double *)(pbuffer), + *(double *)(pbuffer+8)); + else printf("DBRctrlDouble not returned\n"); + pbuffer += dbr_ctrlDouble_size; + } + /*Now print values*/ + if(no_elements==0)return; + switch(dbr_type) { + case(DBR_STRING): + if(status!=0) {printf("DBR_STRING: failed."); break;} + printf("DBR_STRING: %s",pbuffer); + break; + case(DBR_CHAR): + printf("DBR_CHAR: "); + if(status!=0) {printf(" failed."); break;} + for(i=0; inumber; i++) { + if((pname=drvSup->drvetName[i])==NULL) continue; + if(pdrvName==NULL) + printIt=TRUE; + else { + printIt = (strcmp(pdrvName,pname)==0 ? TRUE : FALSE); + if(!printIt) continue; + } + if((pdrvet=drvSup->papDrvet[i])==NULL) { + printf("No driver entry table is present for %s\n",pname); + continue; + } + if(pdrvet->report==NULL) { + if(printIt&&(pdrvName!=NULL)) printf("No report available\n"); + } + else { + printf("Driver: %s\n",pname); + (*pdrvet->report)(); + } + if(pdrvName!=NULL) break; + } + return(0); +} diff --git a/src/db/db_access.c b/src/db/db_access.c new file mode 100644 index 000000000..f71973b05 --- /dev/null +++ b/src/db/db_access.c @@ -0,0 +1,364 @@ + +/* db_access.c */ +/* share/src/db $Id$ */ +/* db_access.c - Interface between old database access and new */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifndef NULL +#define NULL 0 +#endif + +#define oldDBF_STRING 0 +#define oldDBF_INT 1 +#define oldDBF_FLOAT 2 +#define oldDBF_ENUM 3 +#define oldDBF_NO_ACCESS 4 + +/* data request buffer types */ +#define oldDBR_STRING oldDBF_STRING +#define oldDBR_INT oldDBF_INT +#define oldDBR_FLOAT oldDBF_FLOAT +#define oldDBR_ENUM oldDBF_ENUM +#define oldDBR_STS_STRING 4 +#define oldDBR_STS_INT 5 +#define oldDBR_STS_FLOAT 6 +#define oldDBR_STS_ENUM 7 +#define oldDBR_GR_INT 8 +#define oldDBR_GR_FLOAT 9 +#define oldDBR_CTRL_INT 10 +#define oldDBR_CTRL_FLOAT 11 +#define oldDBR_CTRL_ENUM 12 + +/* structures needed by db_put_field */ +struct dbr_ctrl_short{ + short status; /* status of value */ + short severity; /* severity of alarm */ + char units[8]; /* units of value */ + short upper_disp_limit; /* upper limit of graph */ + short lower_disp_limit; /* lower limit of graph */ + short upper_alarm_limit; + short upper_warning_limit; + short lower_warning_limit; + short lower_alarm_limit; + short upper_ctrl_limit; /* upper control limit */ + short lower_ctrl_limit; /* lower control limit */ + short value; /* current value */ +}; +/* structure for a control floating point field */ +struct dbr_ctrl_float{ + short status; /* status of value */ + short severity; /* severity of alarm */ + short precision; /* number of decimal places */ + char units[8]; /* units of value */ + float upper_disp_limit; /* upper limit of graph */ + float lower_disp_limit; /* lower limit of graph */ + float upper_alarm_limit; + float upper_warning_limit; + float lower_warning_limit; + float lower_alarm_limit; + float upper_ctrl_limit; /* upper control limit */ + float lower_ctrl_limit; /* lower control limit */ + float value; /* current value */ +}; + +/* From $cs/dblib/src/dbiocsubs.c + * subroutines + * + * db_process process a database record + * args + * pdb_addr pointer to a database address + * command_mask mask of operations to perform + * new_alarm send an alarm message (NYI!!!!!) + * fill fill a buffer with a character + * args + * pbuffer pointer to the buffer + * size number of characters + * fillchar character with which to fill + */ + +/* + * DB_PROCESS + * + * process database records + */ +db_process(pdb_addr) +register struct db_addr *pdb_addr; +{ + long status; + + status=dbProcess(pdb_addr); + if(!RTN_SUCCESS(status)) errMessage(status,"db_process failed"); + return; +} + +new_alarm(){ + return; +} +/* FILL fill a buffer with the designated character */ + fill(pbuffer,size,fillchar) + register char *pbuffer; + register short size; + register char fillchar; + { + register short i; + + for (i=0; i" + * to a database address + * args + * pname pointer to the database name + * paddr pointer to the database address structure + * returns + * 0 successful + * -1 not successful + * pv portion failed - node, record type and record number are -1 + * field portion failed - field type, offset, size and ext are -1 + * + * + * db_get_field get a field from the database and convert it to + * the specified type. + * + * args + * paddr pointer to the database address structure + * buffer_type the type of data to return + * see DBR_ defines in db_access.h + * pbuffer return buffer + * no_elements number of elements + * returns + * 0 successful + * -1 failed + * + * db_put_field put a converted buffer into the database + * args + * paddr pointer to the database address structure + * buffer_type the type of data to be converted and stored + * see DBR_ defines in db_access.h + * pbuffer return buffer + * returns + * 0 successful + * -1 failed + * + */ + +/* + * DB_NAME_TO_ADDR + */ +static short mapNewToOld[]={0,1,1,1,1,2,2,3,4}; + +db_name_to_addr(pname,paddr) +register char *pname; +register struct dbAddr *paddr; +{ + long status; + short ftype; + + status=dbNameToAddr(pname,paddr); + if(RTN_SUCCESS(status)) { + ftype = paddr->dbr_field_type; + if(ftype<0 || ftype> (sizeof(mapNewToOld)/sizeof(short))) { + printf("db_name_to_addr: Illegal dbr_field_type\n"); + exit(-1); + } + paddr->dbr_field_type = mapNewToOld[paddr->dbr_field_type]; + return(0); + } + else + return(-1); +} + +/* DB_GET_FIELD get a field and convert it to the desired type */ + +db_get_field(paddr,buffer_type,pbuffer,no_elements) +struct dbAddr *paddr; +short buffer_type; +char *pbuffer; +unsigned short no_elements; +{ + long status; + long options; + long nRequest; + long precision; + short severity; + short no_str; + + + switch(buffer_type) { + case(oldDBR_STRING): + options=0; + nRequest=no_elements; + status = dbGetField(paddr,DBR_STRING,pbuffer,&options,&nRequest); + break; + case(oldDBR_INT): + options=0; + nRequest=no_elements; + status = dbGetField(paddr,DBR_SHORT,pbuffer,&options,&nRequest); + break; + case(oldDBR_FLOAT): + options=0; + nRequest=no_elements; + status = dbGetField(paddr,DBR_FLOAT,pbuffer,&options,&nRequest); + break; + case(oldDBR_ENUM): + options=0; + nRequest=no_elements; + status = dbGetField(paddr,DBR_ENUM,pbuffer,&options,&nRequest); + break; + case(oldDBR_STS_STRING): + options=DBR_STATUS; + nRequest=no_elements; + status = dbGetField(paddr,DBR_STRING,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + break; + case(oldDBR_STS_INT): + options=DBR_STATUS; + nRequest=no_elements; + status = dbGetField(paddr,DBR_SHORT,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + break; + case(oldDBR_STS_FLOAT): + options=DBR_STATUS; + nRequest=no_elements; + status = dbGetField(paddr,DBR_FLOAT,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + break; + case(oldDBR_STS_ENUM): + options=DBR_STATUS; + nRequest=no_elements; + status = dbGetField(paddr,DBR_ENUM,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + break; + case(oldDBR_GR_INT): + options=DBR_STATUS|DBR_UNITS|DBR_GR_SHORT; + nRequest=no_elements; + status = dbGetField(paddr,DBR_SHORT,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + break; + case(oldDBR_GR_FLOAT): + /* First get status and precision */ + options=DBR_STATUS|DBR_PRECISION; + nRequest=0; + status = dbGetField(paddr,DBR_FLOAT,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + pbuffer += 2*sizeof(short);/*point pbuffer to precision value*/ + precision = *((long *)pbuffer); + *(((short *)pbuffer)++) = (short)precision; /* convert it to short*/ + /* get units and graphics float*/ + options=DBR_UNITS|DBR_GR_FLOAT; + nRequest=no_elements; + status = dbGetField(paddr,DBR_FLOAT,pbuffer,&options,&nRequest); + if(status!=0) { + /* VMS OPI asks for this for all variables at init. Must return success*/ + float *pb=(float *)pbuffer; + + while(nRequest>0) { + *pbuffer++ = 0; + nRequest--; + } + status=0; + } + break; + case(oldDBR_CTRL_INT): + options=DBR_STATUS|DBR_UNITS|DBR_GR_SHORT|DBR_CTRL_SHORT; + nRequest=no_elements; + status = dbGetField(paddr,DBR_SHORT,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + break; + case(oldDBR_CTRL_FLOAT): + /* First get status and precision */ + options=DBR_STATUS|DBR_PRECISION; + nRequest=0; + status = dbGetField(paddr,DBR_FLOAT,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + pbuffer += 2*sizeof(short);/*point pbuffer to precision value*/ + precision = *((long *)pbuffer); + *(((short *)pbuffer)++) = (short)precision; /* convert it to short*/ + /* get units and graphics float and control*/ + options=DBR_UNITS|DBR_GR_FLOAT|DBR_CTRL_FLOAT; + nRequest=no_elements; + status = dbGetField(paddr,DBR_FLOAT,pbuffer,&options,&nRequest); + break; + case(oldDBR_CTRL_ENUM): + /* first get status and severity */ + options=DBR_STATUS; + nRequest=0; + status = dbGetField(paddr,DBR_ENUM,pbuffer,&options,&nRequest); + adjust_severity(pbuffer); + /* adjust pbuffer so it points to old severity and save it*/ + pbuffer += sizeof(short); + severity = *((short *)pbuffer); + /* now get enum strs */ + options=DBR_ENUM_STRS; + nRequest=no_elements; + status = dbGetField(paddr,DBR_ENUM,pbuffer,&options,&nRequest); + /* no_str was returned as unsigned long. Convert and restore serv*/ + no_str = (short )(*((unsigned long*)pbuffer)); + *(((short *)pbuffer)++) = severity; + *((short *)pbuffer) = no_str; + break; + default: + return(-1); + } + if(!RTN_SUCCESS(status)) return(-1); + return(0); +} + +/* the old software did not have a severity of INFO */ +static adjust_severity(pbuffer) +struct dbr_ctrl_short *pbuffer; +{ +if (pbuffer->severity > 0) pbuffer->severity--; +} + +/* DB_PUT_FIELD put a field and convert it to the desired type */ + +db_put_field(paddr,src_type,psrc,no_elements) +struct dbAddr *paddr; /* where to put it */ +short src_type,no_elements; +char *psrc; /* where to get it from */ +{ + long status; + + + switch(src_type) { + case(oldDBR_STRING): + status = dbPutField(paddr,DBR_STRING,psrc,(long)no_elements); + break; + case(oldDBR_INT): + status = dbPutField(paddr,DBR_SHORT,psrc,(long)no_elements); + break; + case(oldDBR_FLOAT): + status = dbPutField(paddr,DBR_FLOAT,psrc,(long)no_elements); + break; + case(oldDBR_ENUM): + status = dbPutField(paddr,DBR_ENUM,psrc,(long)no_elements); + break; + case(oldDBR_CTRL_INT): + status = dbPutField(paddr,DBR_SHORT, + &(((struct dbr_ctrl_short *)psrc)->value),(long)no_elements); + break; + case(oldDBR_CTRL_FLOAT): + status = dbPutField(paddr,DBR_FLOAT, + &(((struct dbr_ctrl_float *)psrc)->value),(long)no_elements); + break; + default: + return(-1); + } + if(!RTN_SUCCESS(status)) return(-1); + return(0); +} diff --git a/src/db/db_test.c b/src/db/db_test.c new file mode 100644 index 000000000..5c4d407fb --- /dev/null +++ b/src/db/db_test.c @@ -0,0 +1,341 @@ + +/* db_test.c */ +/* share/src/db $Id$ */ + +/* + * + * database access subroutines + * + * Author: Bob Dalesio + * Date: 4/15/88 + * @(#)iocdbaccess.c 1.1 9/22/88 + * + * Control System Software for the GTA Project + * + * Copyright 1988, 1989, the Regents of the University of California. + * + * This software was produced under a U.S. Government contract + * (W-7405-ENG-36) at the Los Alamos National Laboratory, which is + * operated by the University of California for the U.S. Department + * of Energy. + * + * Developed by the Controls and Automation Group (AT-8) + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Direct inqueries to: + * Bob Dalesio, AT-8, Mail Stop H820 + * Los Alamos National Laboratory + * Los Alamos, New Mexico 87545 + * Phone: (505) 667-3414 + * E-mail: dalesio@luke.lanl.gov + * + * Modification Log: + * ----------------- + */ +#include + +/* + * TGF + * Test get field + */ +char tgf_buffer[1200]; +#define MAX_ELEMS 250 +int tgf(name,index) +char *name; +register short index; +{ + struct db_addr addr; + struct db_addr *paddr = &addr; + short number_elements; + + /* convert name to database address */ + db_name_to_addr(name,&addr,index); + + printf(" Record Type: %d\n",addr.record_type); + printf("Record Address: 0x%x\n",addr.precord); + printf(" Field Type: %d\n",addr.field_type); + printf(" Field Address: 0x%x\n",addr.pfield); + printf(" Field Size: %d\n",addr.field_size); + printf(" No Elements: %d\n",addr.no_elements); + printf(" Special: %d\n",addr.special); + printf(" Choice Set: %d\n",addr.choice_set); + number_elements = + ((addr.no_elements > MAX_ELEMS)?MAX_ELEMS:addr.no_elements); + + /* failedfetch as each type */ + if (db_get_field(paddr,DBR_STRING,tgf_buffer,1) < 0) + printf("DBR_STRING failed\n"); + else print_returned(DBR_STRING,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_INT,tgf_buffer,number_elements) < 0) + printf("DBR_INT failed\n"); + else print_returned(DBR_INT,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_FLOAT,tgf_buffer,number_elements) < 0) + printf("DBR_FLOAT failed\n"); + else print_returned(DBR_FLOAT,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_ENUM,tgf_buffer,number_elements) < 0) + printf("DBR_ENUM failed\n"); + else print_returned(DBR_ENUM,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_STS_STRING,tgf_buffer,1) < 0) + printf("DBR_STS_STRING failed\n"); + else print_returned(DBR_STS_STRING,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_STS_INT,tgf_buffer,number_elements) < 0) + printf("DBR_STS_INT failed\n"); + else print_returned(DBR_STS_INT,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_STS_FLOAT,tgf_buffer,number_elements) < 0) + printf("DBR_STS_FLOAT failed\n"); + else print_returned(DBR_STS_FLOAT,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_STS_ENUM,tgf_buffer,number_elements) < 0) + printf("DBR_STS_ENUM failed\n"); + else print_returned(DBR_STS_ENUM,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_GR_INT,tgf_buffer,number_elements) < 0) + printf("DBR_GR_INT failed\n"); + else print_returned(DBR_GR_INT,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_GR_FLOAT,tgf_buffer,number_elements) < 0) + printf("DBR_GR_FLOAT failed\n"); + else print_returned(DBR_GR_FLOAT,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_CTRL_INT,tgf_buffer,number_elements) < 0) + printf("DBR_CTRL_INT failed\n"); + else print_returned(DBR_CTRL_INT,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_CTRL_FLOAT,tgf_buffer,number_elements) < 0) + printf("DBR_CTRL_FLOAT failed\n"); + else print_returned(DBR_CTRL_FLOAT,tgf_buffer,number_elements); + if (db_get_field(paddr,DBR_CTRL_ENUM,tgf_buffer,number_elements) < 0) + printf("DBR_CTRL_ENUM failed\n"); + else print_returned(DBR_CTRL_ENUM,tgf_buffer,number_elements); + printf("\n"); + return(0); +} + +/* + * TPF + * Test put field + */ +int tpf(pname,pvalue,index) +char *pname; +char *pvalue; +register short index; +{ + struct db_addr addr; + struct db_addr *paddr = &addr; + char buffer[500]; + struct dbr_ctrl_enum test_enum; + register short i; + short shortvalue; + long longvalue; + float floatvalue; + unsigned char charvalue; + double doublevalue; + + if (((*pname < ' ') || (*pname > 'z')) + || ((*pvalue < ' ') || (*pvalue > 'z'))){ + printf("\nusage \"pv name\",\"value\"\n"); + return; + } + + /* convert name to database address */ + db_name_to_addr(pname,&addr,index); + printf(" Record Type: %d\n",addr.record_type); + printf("Record Address: 0x%x\n",addr.precord); + printf(" Field Type: %d\n",addr.field_type); + printf(" Field Address: 0x%x\n",addr.pfield); + printf(" Field Size: %d\n",addr.field_size); + printf(" No Elements: %d\n",addr.no_elements); + printf(" Special: %d\n",addr.special); + printf(" Choice Set: %d\n",addr.choice_set); + if (db_put_field(paddr,DBR_STRING,pvalue,1) < 0) printf(" failed\n"); + if (db_get_field(paddr,DBR_STRING,buffer,1) < 0) printf("failed\n"); + else print_returned(DBR_STRING,buffer,1); + if(addr.field_type<=DBF_STRING || addr.field_type>=DBF_NO_ACCESS)return(0); + if(sscanf(pvalue,"%hd",&shortvalue)==1) { + if (db_put_field(paddr,DBR_INT,&shortvalue,1) < 0) printf(" INT failed\n"); + if (db_get_field(paddr,DBR_INT,buffer,1) < 0) printf("INT GET failed\n"); + else print_returned(DBR_INT,buffer,1); + } + if(sscanf(pvalue,"%f",&floatvalue)==1) { + if (db_put_field(paddr,DBR_FLOAT,&floatvalue,1) < 0) printf("FLOAT failed\n"); + if (db_get_field(paddr,DBR_FLOAT,buffer,1) < 0) printf("FLOAT GET failed\n"); + else print_returned(DBR_FLOAT,buffer,1); + } + if(sscanf(pvalue,"%hu",&shortvalue)==1) { + if (db_put_field(paddr,DBR_ENUM,&shortvalue,1) < 0) printf("ENUM failed\n"); + if (db_get_field(paddr,DBR_ENUM,buffer,1) < 0) printf("ENUM GET failed\n"); + else print_returned(DBR_ENUM,buffer,1); + } + printf("\n"); + return(0); +} + +/* + * PRINT_RETURNED + * + * print out the values in a database access interface structure + */ +static print_returned(type,pbuffer,count) +register short type; +register char *pbuffer; +short count; +{ + register short i; + + switch(type){ + case (DBR_STRING): + printf("DBR_STRING: %s",pbuffer); + break; + case (DBR_INT): + { + register short *pvalue = (short *)pbuffer; + printf("DBR_INT: "); + for (i = 0; i < count; i++,pvalue++){ + printf("%d ",*(short *)pvalue); + if ((i % 16) == 15) printf("\t\n"); + } + break; + } + case (DBR_FLOAT): + { + register float *pvalue = (float *)pbuffer; + printf("DBR_FLOAT: "); + for (i = 0; i < count; i++,pvalue++){ + printf("%6.4f ",*(float *)pvalue); + if ((i % 16) == 15) printf("\n\t"); + } + break; + } + case (DBR_ENUM): + { + register short *pvalue = (short *)pbuffer; + printf("DBR_ENUM: %d",*pvalue); + break; + } + case (DBR_STS_STRING): + { + register struct dbr_sts_string *pvalue + = (struct dbr_sts_string *) pbuffer; + printf("DBR_STS_STRING %2d %2d",pvalue->status,pvalue->severity); + printf("\tValue: %s",pvalue->value); + break; + } + case (DBR_STS_INT): + { + register struct dbr_sts_int *pvalue + = (struct dbr_sts_int *)pbuffer; + register short *pshort = &pvalue->value; + printf("DBR_STS_INT %2d %2d",pvalue->status,pvalue->severity); + printf("\tValue: "); + for (i = 0; i < count; i++,pshort++){ + printf("%d ",*pshort); + if ((i % 16) == 15) printf("\n\t"); + } + break; + } + case (DBR_STS_FLOAT): + { + register struct dbr_sts_float *pvalue + = (struct dbr_sts_float *)pbuffer; + register float *pfloat = &pvalue->value; + printf("DBR_STS_FLOAT %2d %2d",pvalue->status,pvalue->severity); + printf("\tValue: "); + for (i = 0; i < count; i++,pfloat++){ + printf("%6.4f ",*pfloat); + if ((i % 16) == 15) printf("\n\t"); + } + break; + } + case (DBR_STS_ENUM): + { + register struct dbr_sts_enum *pvalue + = (struct dbr_sts_enum *)pbuffer; + printf("DBR_STS_ENUM %2d %2d",pvalue->status,pvalue->severity); + printf("\tValue: %d",pvalue->value); + break; + } + case (DBR_GR_INT): + { + register struct dbr_gr_int *pvalue + = (struct dbr_gr_int *)pbuffer; + register short *pshort = &pvalue->value; + printf("DBR_GR_INT %2d %2d",pvalue->status,pvalue->severity); + printf(" %.8s %6d %6d %6d %6d %6d %6d",pvalue->units, + pvalue->upper_disp_limit,pvalue->lower_disp_limit, + pvalue->upper_alarm_limit,pvalue->upper_warning_limit, + pvalue->lower_warning_limit,pvalue->lower_alarm_limit); + printf("\nValue:\t"); + for (i = 0; i < count; i++,pshort++){ + printf("%d ",*pshort); + if ((i % 16) == 15) printf("\n\t"); + } + break; + } + case (DBR_GR_FLOAT): + { + register struct dbr_gr_float *pvalue + = (struct dbr_gr_float *)pbuffer; + register float *pfloat = &pvalue->value; + printf("DBR_GR_FLOAT%2d %2d",pvalue->status,pvalue->severity); + printf(" %3d %.8s\n\t%6.4f %6.4f %6.4f %6.4f %6.4f %6.4f", + pvalue->precision, pvalue->units, + pvalue->upper_disp_limit,pvalue->lower_disp_limit, + pvalue->upper_alarm_limit,pvalue->upper_warning_limit, + pvalue->lower_warning_limit,pvalue->lower_alarm_limit); + printf("\nValue\t"); + for (i = 0; i < count; i++,pfloat++){ + printf("%6.4f ",*pfloat); + if ((i % 16) == 15) printf("\n\t"); + } + break; + } + case (DBR_CTRL_INT): + { + register struct dbr_ctrl_int *pvalue + = (struct dbr_ctrl_int *)pbuffer; + register short *pshort = &pvalue->value; + printf("DBR_CTRL_INT %2d %2d",pvalue->status,pvalue->severity); + printf(" %.8s\n\t%6d %6d %6d %6d %6d %6d",pvalue->units, + pvalue->upper_disp_limit,pvalue->lower_disp_limit, + pvalue->upper_alarm_limit,pvalue->upper_warning_limit, + pvalue->lower_warning_limit,pvalue->lower_alarm_limit); + printf(" %6d %6d", + pvalue->upper_ctrl_limit,pvalue->lower_ctrl_limit); + printf("\n\t"); + for (i = 0; i < count; i++,pshort++){ + printf("%d ",*pshort); + if ((i % 16) == 15) printf("\n\t"); + } + break; + } + case (DBR_CTRL_FLOAT): + { + register struct dbr_ctrl_float *pvalue + = (struct dbr_ctrl_float *)pbuffer; + register float *pfloat = &pvalue->value; + printf("DBR_CTRL_FLOAT %2d %2d",pvalue->status,pvalue->severity); + printf(" %3d %.8s\n\t%6.4f %6.4f %6.4f %6.4f %6.4f %6.4f", + pvalue->precision, pvalue->units, + pvalue->upper_disp_limit,pvalue->lower_disp_limit, + pvalue->upper_alarm_limit,pvalue->upper_warning_limit, + pvalue->lower_warning_limit,pvalue->lower_alarm_limit); + printf(" %6.4f %6.4f", + pvalue->upper_ctrl_limit,pvalue->lower_ctrl_limit); + printf("\n\t"); + for (i = 0; i < count; i++,pfloat++){ + printf("%6.4f ",*pfloat); + if ((i % 16) == 15) printf("\n\t"); + } + break; + } + case (DBR_CTRL_ENUM): + { + register struct dbr_ctrl_enum *pvalue + = (struct dbr_ctrl_enum *)pbuffer; + printf("DBR_GR_ENUM%2d %2d",pvalue->status,pvalue->severity); + printf("\n\t%3d",pvalue->no_str); + for (i = 0; i < pvalue->no_str; i++) + printf("\n\t%.26s",pvalue->strs[i]); + printf("Value: %d",pvalue->value); + break; + } + } + printf("\n"); +} + diff --git a/src/db/dbls.c b/src/db/dbls.c new file mode 100644 index 000000000..36eafd45c --- /dev/null +++ b/src/db/dbls.c @@ -0,0 +1,1055 @@ + +/* dbls.c - structure listing program */ +/* share/src/db $Id$ */ + +#define SAME 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* forward references */ +void DbRecType(); +void DrvSup(); +void DevSup(); +void DbRecDes(); +void CvtTable(); +void ChoiceRec(); +void ChoiceDev(); +void ChoiceCvt(); +void ChoiceGbl(); +void DbErrDes(); +void DbRecords(); +void RecSup(); +int getSelection(); + +static char buffer[512]; +static char ibuff[20]; +static int i; +static int j; +static int k; +static int inum; +static int begNumI; +static int endNumI; +static int endNumJ; +static int begNumJ; + +static struct PRTAB { + char *msg; /* selection string */ + void (*fp) (); /* print routine */ +} comtab[] = +{ + { + "dbRecType", DbRecType + }, + { + "drvSup", DrvSup + }, + { + "devSup", DevSup + }, + { + "dbRecDes", DbRecDes + }, + { + "cvtTable", CvtTable + }, + { + "choiceRec", ChoiceRec + }, + { + "choiceDev", ChoiceDev + }, + { + "choiceCvt", ChoiceCvt + }, + { + "choiceGbl", ChoiceGbl + }, + { + "dbErrDes", DbErrDes + }, + { + "recSup", RecSup + }, + { + "dbRecords", DbRecords + }, + { + "FFFF", NULL + } +}; +/* + * LISTSTRUCTURES + * + * MAIN PROGRAM + * + */ +dbls() +{ + struct PRTAB *pcomtab = &comtab[0]; + void (*fup) (); /* SUBROUTINE POINTER */ + int pos, + fflag; + FILE *fp, + *fopen(); + char fname[80]; + long status; + + + if (!dbRecType) { + status = S_sdr_notLoaded; + errMessage(status, "dbls: Error - dbRecType not loaded"); + return -1; + } + begNumI = 0; + begNumJ = 0; + + pos = getSelection(pcomtab); + printf("PUT OUTPUT LISTING IN FILE ??? (y|n) : "); + scanf("%s", ibuff); + if (ibuff[0] == 'y') + fflag = 1; + else + fflag = 0; + + if (fflag) { + printf("ENTER FULL_PATH_NAME OF OUTPUT LISTING FILE : "); + scanf("%s", fname); + if ((fp = fopen(fname, "a")) == NULL) { + printf("dblsseStructure: fopen error errno=%d\nfile=%s\n", MYERRNO, fname); + printf("TRY: < cd \"/full_dir_path/.\" > to correct this failure\n"); + return (-1); + } + printf("Warning Note: file %s opened for appending\n", fname); + } + fup = *comtab[pos].fp; /* PREPARE INDIRECT CALL */ + (*fup) (fp, fflag); /* AND CALL SUBROUTINE */ + if (fflag) { + printf("YOUR OUTPUT IS LOCATED IN FILE %s\n", fname); + fclose(fp); + } + return (0); +} /* end of main */ +getRecTypeSel() +{ + endNumI = dbRecType->number; + + printf("DO YOU WANT TO LIST ALL RECORD TYPES ??? (y|n) : "); + scanf("%s", ibuff); + + if (ibuff[0] != 'y') { + FOREVER { + printf("\nRECTYPE MENU:\n"); + for (i = 0; i < dbRecType->number; i++) { + if (dbRecType->papName[i]) { + printf("%d\t%s\n", i, dbRecType->papName[i]); + } + } + printf("ENTER SELECTION NUMBER (X-%d) : ", i - 1); + scanf("%d", &inum); + if ((dbRecType->papName[inum]) + && (inum >= 0) && (inum < i)) { + begNumI = inum; + endNumI = begNumI + 1; + break; + } else { + printf("Not a selection, Please try again\n"); + } + } + } else { + for (i = 0; i < dbRecType->number; i++) { + /* start at first record definition */ + if (dbRecType->papName[i]) { + begNumI = i; + break; + } + } + } + return; +} /* end of getRecTypeSel */ +getSelection(pcomtab) + struct PRTAB *pcomtab; +{ + int pos; + FOREVER { + printf("\nSTRUCTURE LISTING MENU:\n"); + pos = 0; /* POS OF FIRST CMD IN TABLE */ + while (strncmp(pcomtab[pos].msg, "FFFF", 4)) { /* DO UNTIL END OF TABLE */ + printf("\t%d\t%s\n", pos + 1, pcomtab[pos].msg); + pos++; + } + printf("ENTER SELECTION NUMBER (1-%d) : ", pos); + scanf("%d", &inum); + + if (inum > 0 && inum <= pos) + return (inum - 1); + else + printf("Not a selection, Please try again\n"); + + } +} /* end of getSelection */ +bufOut(fp, fflag) + FILE *fp; + int fflag; +{ + if (!fflag) + printf("%s\n", buffer); + else if ((fprintf(fp, "%s\n", buffer)) == EOF) { + printf("Error writing file with fprintf\n"); + exit(1); + } +} /* end of bufOut */ + +static void +DbRecType(fp, fflag) + FILE *fp; + int fflag; +{ + + sprintf(buffer, "\n\ndbls: listing the dbRecType structure\n"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] dbRecType-> recType", &dbRecType, dbRecType); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t number\t [ %d ]\t/* number of types */", + &dbRecType->number, dbRecType->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papName\t\t /* pap to record type */", + &dbRecType->papName, dbRecType->papName); + bufOut(fp, fflag); + for (i = 0; i < dbRecType->number; i++) { + if (dbRecType->papName[i]) { + sprintf(buffer, "%8x[%8x] papName->[%d]->\t\"%s\"", + &dbRecType->papName[i], + dbRecType->papName[i], + i, dbRecType->papName[i]); + bufOut(fp, fflag); + } + } +} /* end of DbRecType */ +static void +ChoiceGbl(fp, fflag) + FILE *fp; + int fflag; +{ + if (!choiceGbl) { + printf("ChoiceGbl: Error - choiceGbl not loaded\n"); + return; + } + sprintf(buffer, "\n\ndbls: listing the choiceGbl structure\n"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] choiceGbl -> arrChoiceSet", &choiceGbl, choiceGbl); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of choice sets */", + &choiceGbl->number, + choiceGbl->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t**papChoiceSet -> choiceSet", + &choiceGbl->papChoiceSet, + choiceGbl->papChoiceSet); + bufOut(fp, fflag); + for (i = 0; i < choiceGbl->number; i++) { + if (choiceGbl->papChoiceSet[i]) { + sprintf(buffer, "%8x[%8x]\t papChoiceSet->[%d]\tINDEX[%d]", + &choiceGbl->papChoiceSet[i], + choiceGbl->papChoiceSet[i], i, i); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number [%d]\t\t/* number of choices */", + &choiceGbl->papChoiceSet[i]->number, + choiceGbl->papChoiceSet[i]->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t **papChoice -> \t\"choice string\"", + &choiceGbl->papChoiceSet[i]->papChoice, + choiceGbl->papChoiceSet[i]->papChoice); + bufOut(fp, fflag); + for (j = 0; j < choiceGbl->papChoiceSet[i]->number; j++) { + if (choiceGbl->papChoiceSet[i]->papChoice[j]) { + sprintf(buffer, "%8x[%8x]\t\t papChoice->[%d]\t\"%s\"", + &choiceGbl->papChoiceSet[i]->papChoice[j], + choiceGbl->papChoiceSet[i]->papChoice[j], + j, + choiceGbl->papChoiceSet[i]->papChoice[j]); + bufOut(fp, fflag); + } + } + } + } +} /* end of ChoiceGbl */ +static void +ChoiceDev(fp, fflag) + FILE *fp; + int fflag; +{ + if (!choiceDev) { + printf("ChoiceDev: Error - choiceDev not loaded\n"); + return; + } + getRecTypeSel(); + sprintf(buffer, "\n\ndbls: listing the choiceDev structure"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]choiceDev-> devChoiceRec ", &choiceDev, choiceDev); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t number\t[%d]\t\t\t/* number of devChoiceSet */", + &choiceDev->number, choiceDev->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papDevChoiceSet -> devChoiceSet ", + &choiceDev->papDevChoiceSet, + choiceDev->papDevChoiceSet); + bufOut(fp, fflag); + for (i = begNumI; i < endNumI; i++) { + if (choiceDev->papDevChoiceSet[i]) { + sprintf(buffer, "\n%8x[%8x]\tpapDevChoiceSet->[%d]\t\tRECTYPE \"%s\"", + &choiceDev->papDevChoiceSet[i], + choiceDev->papDevChoiceSet[i], i, + dbRecType->papName[i]); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number\t[%d]\t\t/*number of choices */ ", + &choiceDev->papDevChoiceSet[i]->number, + choiceDev->papDevChoiceSet[i]->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t **papDevChoice -> devChoice", + &choiceDev->papDevChoiceSet[i]->papDevChoice, + choiceDev->papDevChoiceSet[i]->papDevChoice); + bufOut(fp, fflag); + for (j = 0; j < choiceDev->papDevChoiceSet[i]->number; j++) { + if (choiceDev->papDevChoiceSet[i]->papDevChoice[j]) { + sprintf(buffer, "%8x[%8x]\t papDevChoice[%d]", + &choiceDev->papDevChoiceSet[i]->papDevChoice[j], + choiceDev->papDevChoiceSet[i]->papDevChoice[j], j); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t link_type [%d]", + &choiceDev->papDevChoiceSet[i]->papDevChoice[j]->link_type, + choiceDev->papDevChoiceSet[i]->papDevChoice[j]->link_type); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t\t*pchoice\t\t\"%s\"", + &choiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice, + choiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice, + choiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice); + bufOut(fp, fflag); + } + } + } + } +} /* end ChoiceDev */ +static void +ChoiceCvt(fp, fflag) + FILE *fp; + int fflag; +{ + + if (!choiceCvt) { + printf("ChoiceCvt: Error - choiceCvt not loaded\n"); + return; + } + sprintf(buffer, "\n\ndbls: listing the choiceCvt structure"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] choiceCvt -> choiceCvt", &choiceCvt, choiceCvt); + + bufOut(fp, fflag); + sprintf(buffer, "%8x number\t [ %d ]\t/* number of choices */", + &choiceCvt->number, choiceCvt->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papChoice -> \"choice string\"", + &choiceCvt->papChoice, choiceCvt->papChoice); + bufOut(fp, fflag); + for (i = 0; i < choiceCvt->number; i++) + if (choiceCvt->papChoice[i]) { + sprintf(buffer, "%8x[%8x] papChoice[%d]\t\"%s\" ", + &choiceCvt->papChoice[i], choiceCvt->papChoice[i], i, + choiceCvt->papChoice[i]); + bufOut(fp, fflag); + } + return; +} /* end of ChoiceCvt */ +static void +CvtTable(fp, fflag) + FILE *fp; + int fflag; +{ + if (!cvtTable) { + printf("CvtTable: Error - cvtTable not loaded\n"); + return; + } + begNumI = 0; + endNumI = cvtTable->number; + + printf("DO YOU WANT TO LIST ALL CVT TABLES ??? (y|n) : "); + scanf("%s", ibuff); + + if (ibuff[0] != 'y') { + FOREVER { + printf("\nBRKPOINT MENU:\n"); + for (i = begNumI; i < endNumI; i++) { + if (cvtTable->papBrkTable[i]) { + sprintf(buffer, "%d\t%s", i, cvtTable->papBrkTable[i]->name); + bufOut(fp, 0); + } + } + printf("ENTER SELECTION NUMBER (N-%d) : ", i - 1); + scanf("%d", &inum); + if ((cvtTable->papBrkTable[inum]) && inum < endNumI) { + begNumI = inum; + endNumI = begNumI + 1; + break; + } else { + printf("Not a selection, Please try again\n"); + } + } + } else { + for (i = 0; i < cvtTable->number; i++) { + if (cvtTable->papBrkTable[i]) { + begNumI = i; + break; + } + } + } + sprintf(buffer, "\n\ndbls: listing the cvtTable structure"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] cvtTable -> arrBrkTable", &cvtTable, cvtTable); + bufOut(fp, fflag); + sprintf(buffer, "%8x number\t [ %d ]\t/* number of break tables */", + &cvtTable->number, cvtTable->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papBrkTable -> brkTable", + &cvtTable->papBrkTable, cvtTable->papBrkTable); + bufOut(fp, fflag); + for (i = begNumI; i < endNumI; i++) { + if (cvtTable->papBrkTable[i]) { + sprintf(buffer, "%8x[%8x] papBrkTable[%d] ", + &cvtTable->papBrkTable[i], cvtTable->papBrkTable[i], i); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t *name\t\t\t\"%s\"", + &cvtTable->papBrkTable[i]->name, + cvtTable->papBrkTable[i]->name, + cvtTable->papBrkTable[i]->name); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number [ %d ]\t/* number of brkInt in this table */ ", + &cvtTable->papBrkTable[i]->number, + cvtTable->papBrkTable[i]->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t rawLow\t\t\t%.5f", + &cvtTable->papBrkTable[i]->rawLow, + cvtTable->papBrkTable[i]->rawLow); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t rawHigh\t\t\t%.5f", + &cvtTable->papBrkTable[i]->rawHigh, + cvtTable->papBrkTable[i]->rawHigh); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t papBrkInt", + &cvtTable->papBrkTable[i]->papBrkInt, + cvtTable->papBrkTable[i]->papBrkInt); + bufOut(fp, fflag); + for (j = 0; j < cvtTable->papBrkTable[i]->number; j++) { + if (cvtTable->papBrkTable[i]->papBrkInt[j]) { + sprintf(buffer, "%8x[%8x]\t papBrkInt[%d] -> brkInt", + &cvtTable->papBrkTable[i]->papBrkInt[j], + cvtTable->papBrkTable[i]->papBrkInt[j], j); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t raw\t\t\t%.5f", + &cvtTable->papBrkTable[i]->papBrkInt[j]->raw, + cvtTable->papBrkTable[i]->papBrkInt[j]->raw); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t slope\t\t\t%.5f", + &cvtTable->papBrkTable[i]->papBrkInt[j]->slope, + cvtTable->papBrkTable[i]->papBrkInt[j]->slope); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t eng\t\t\t%.5f", + &cvtTable->papBrkTable[i]->papBrkInt[j]->eng, + cvtTable->papBrkTable[i]->papBrkInt[j]->eng); + bufOut(fp, fflag); + } + } + } + } +} /* end of CvtTable */ +static void +DevSup(fp, fflag) + FILE *fp; + int fflag; +{ + + if (!devSup) { + printf("DevSup: Error - devSup not loaded\n"); + return; + } + getRecTypeSel(); + sprintf(buffer, "\n\ndbls: listing the devSup structure"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] devSup -> recDevSup ", &devSup, devSup); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\tnumber\t [ %d ]\t/* number of record types */", + &devSup->number, devSup->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papDevSup -> devSup ", + &devSup->papDevSup, devSup->papDevSup); + bufOut(fp, fflag); + for (i = begNumI; i < endNumI; i++) { + if (devSup->papDevSup[i]) { + sprintf(buffer, "%8x[%8x] papDevSup->[%d]\t\"%s\"", + &devSup->papDevSup[i], + devSup->papDevSup[i], i, + dbRecType->papName[i]); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number\t[%d]\t/* number of dset */", + &devSup->papDevSup[i]->number, + devSup->papDevSup[i]->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **dsetName", + &devSup->papDevSup[i]->dsetName, + devSup->papDevSup[i]->dsetName); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papDset", + &devSup->papDevSup[i]->papDset, + devSup->papDevSup[i]->papDset); + bufOut(fp, fflag); + for (j = 0; j < devSup->papDevSup[i]->number; j++) { + if (devSup->papDevSup[i]->dsetName[j]) { + sprintf(buffer, "%8x[%8x]\t\tdsetName[%d]\t%s", + &devSup->papDevSup[i]->dsetName[j], + devSup->papDevSup[i]->dsetName[j], + j, + devSup->papDevSup[i]->dsetName[j]); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t\tpapDset[%d]", + &devSup->papDevSup[i]->papDset[j], + devSup->papDevSup[i]->papDset[j], j); + bufOut(fp, fflag); + } + } + } + } +} /* end of DevSup */ +static void +DrvSup(fp, fflag) + FILE *fp; + int fflag; +{ + if (!drvSup) { + printf("DrvSup: Error - drvSup not loaded\n"); + } + sprintf(buffer, "\n\ndbls: listing the drvSup structure"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] drvSup -> drvSup ", &drvSup, drvSup); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number\t[%d]\t/* number of dset */", &drvSup->number, drvSup->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **drvetName -> \t/* pArr of ptr to drvetName */ ", + &drvSup->drvetName, drvSup->drvetName); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papDrvet-> drvet \t/* pArr ptr to drvet */", + &drvSup->papDrvet, drvSup->papDrvet); + bufOut(fp, fflag); + for (i = 0; i < drvSup->number; i++) { + if (drvSup->drvetName[i]) + sprintf(buffer, "%8x[%8x]\t drvetName->[%d]\t\"%s\"", + &drvSup->drvetName[i], + drvSup->drvetName[i], + i, drvSup->drvetName[i]); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t papDrvet->[%d] /* reserved ptr to drvet */", + &drvSup->papDrvet[i], + drvSup->papDrvet[i], i); + bufOut(fp, fflag); + } +} /* end of DrvSup */ +static void +DbRecDes(fp, fflag) + FILE *fp; + int fflag; +{ + char *ptemp; + long buff[6]; + int allJ = 0; + if (!dbRecDes) { + printf("DbRecDes: Error - dbRecDes not loaded\n"); + return; + } + getRecTypeSel(); + begNumJ = 0; + endNumJ = dbRecDes->papRecTypDes[begNumI]->no_fields; + if ((endNumI - begNumI) < 2) { + printf("DO YOU WANT TO LIST ALL FIELDS ??? (y|n) : "); + scanf("%s", ibuff); + if (ibuff[0] != 'y') + FOREVER { + printf("\nFIELDNAME MENU FOR RECTYPE %s:\n", dbRecType->papName[begNumI]); + for (j = 0; j < endNumJ; j++) { + printf("%3d %4.4s", + dbRecDes->papRecTypDes[begNumI]->sortFldInd[j], + &dbRecDes->papRecTypDes[begNumI]->sortFldName[j]); + if (!((j + 1) % 8)) + printf("\n"); + } + printf("\n"); + printf("ENTER SELECTION NUMBER (0-%d) : ", j - 1); + scanf("%d", &inum); + if ((inum >= 0 && inum < j)) { + begNumJ = inum; + endNumJ = begNumJ + 1; + break; + } else { + printf("Not a selection, Please try again\n"); + } + } + } else + allJ = 1; + + sprintf(buffer, "\n\ndbls: listing the dbRecDes structure"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] dbRecDes-> recDes", &dbRecDes, dbRecDes); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\tnumber [%d] \t/* number of recTypDes */", + &dbRecDes->number, dbRecDes->number); + bufOut(fp, fflag); + for (i = begNumI; i < endNumI; i++) { + + if (dbRecDes->papRecTypDes[i]) { + sprintf(buffer, "\n%8x[%8x] **papRecTypDes-> recTypDes\t\"%s\"", + &dbRecDes->papRecTypDes, + dbRecDes->papRecTypDes, + dbRecType->papName[i]); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t rec_size [%d]", + &dbRecDes->papRecTypDes[i]->rec_size, + dbRecDes->papRecTypDes[i]->rec_size); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t no_fields [%d]", + &dbRecDes->papRecTypDes[i]->no_fields, + dbRecDes->papRecTypDes[i]->no_fields); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t no_prompt [%d]", + &dbRecDes->papRecTypDes[i]->no_prompt, + dbRecDes->papRecTypDes[i]->no_prompt); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t no_links [%d]", + &dbRecDes->papRecTypDes[i]->no_links, + dbRecDes->papRecTypDes[i]->no_links); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t *link_ind", + &dbRecDes->papRecTypDes[i]->link_ind, + dbRecDes->papRecTypDes[i]->link_ind); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t *sortFldName", + &dbRecDes->papRecTypDes[i]->sortFldName, + dbRecDes->papRecTypDes[i]->sortFldName); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t *sortFldInd", + &dbRecDes->papRecTypDes[i]->sortFldInd, + dbRecDes->papRecTypDes[i]->sortFldInd); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t **papFldDes-> fldDes", + &dbRecDes->papRecTypDes[i]->papFldDes, + dbRecDes->papRecTypDes[i]->papFldDes); + bufOut(fp, fflag); + + if (allJ) { + endNumJ = dbRecDes->papRecTypDes[i]->no_fields; + /* expand *link_ind */ + for (j = 0; j < dbRecDes->papRecTypDes[i]->no_links; j++) { + sprintf(buffer,"%8x\tlink_ind[%d] offset=[%d]", + &dbRecDes->papRecTypDes[i]->link_ind[j], + j, + dbRecDes->papRecTypDes[i]->link_ind[j]); + bufOut(fp, fflag); + } + /* expand *sortFldName and *sortFldInd */ + ptemp = (char *) dbRecDes->papRecTypDes[i]->sortFldName; + for (j = 0; j < dbRecDes->papRecTypDes[i]->no_fields; j++) { + sprintf(buffer,"[%8x] sortFldName[%2d]=%4.4s [%8x] sortFldInd=%2d", + ptemp, + j, + ptemp, + &dbRecDes->papRecTypDes[i]->sortFldInd[j], + dbRecDes->papRecTypDes[i]->sortFldInd[j] + ); + bufOut(fp, fflag); + ptemp += 4; + } + } + for (j = begNumJ; j < endNumJ; j++) { + sprintf(buffer, "\n"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t **papFldDes->fldDes[%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j], + dbRecDes->papRecTypDes[i]->papFldDes[j], j); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tprompt\t\t\"%s\"", + dbRecDes->papRecTypDes[i]->papFldDes[j]->prompt, + dbRecDes->papRecTypDes[i]->papFldDes[j]->prompt); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tfldname\t\t\"%4.4s\"", + dbRecDes->papRecTypDes[i]->papFldDes[j]->fldname, + dbRecDes->papRecTypDes[i]->papFldDes[j]->fldname); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\toffset [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->offset, + dbRecDes->papRecTypDes[i]->papFldDes[j]->offset); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tsize [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->size, + dbRecDes->papRecTypDes[i]->papFldDes[j]->size); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tspecial [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->special, + dbRecDes->papRecTypDes[i]->papFldDes[j]->special); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tfield_type [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->field_type, + dbRecDes->papRecTypDes[i]->papFldDes[j]->field_type); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tdbr_field_type [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->dbr_field_type, + dbRecDes->papRecTypDes[i]->papFldDes[j]->dbr_field_type); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tchoice_set [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->choice_set, + dbRecDes->papRecTypDes[i]->papFldDes[j]->choice_set); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tcvt_type [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->cvt_type, + dbRecDes->papRecTypDes[i]->papFldDes[j]->cvt_type); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tpromptflag [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->promptflag, + dbRecDes->papRecTypDes[i]->papFldDes[j]->promptflag); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tlowfl [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->lowfl, + dbRecDes->papRecTypDes[i]->papFldDes[j]->lowfl); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\thighfl [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->highfl, + dbRecDes->papRecTypDes[i]->papFldDes[j]->highfl); + bufOut(fp, fflag); + bcopy((caddr_t) & dbRecDes->papRecTypDes[i]->papFldDes[j]->initial, + (caddr_t) buff, 8); + sprintf(buffer, "%8x[%8x][%8x]\tinitial", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->initial, + buff[0], buff[1]); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\trange1.fldnum [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->range1.fldnum, + dbRecDes->papRecTypDes[i]->papFldDes[j]->range1.fldnum); + bufOut(fp, fflag); + bcopy((caddr_t) & dbRecDes->papRecTypDes[i]->papFldDes[j]->range1.value, + (caddr_t) buff, 8); + sprintf(buffer, "%8x[%8x][%8x]\trange1.value", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->range1.value, + buff[0], buff[1]); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\trange2.fldnum [%d]", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->range2.fldnum, + dbRecDes->papRecTypDes[i]->papFldDes[j]->range2.fldnum); + bufOut(fp, fflag); + bcopy((caddr_t) & dbRecDes->papRecTypDes[i]->papFldDes[j]->range2.value, + (caddr_t) buff, 8); + sprintf(buffer, "%8x[%8x][%8x]\trange2.value", + &dbRecDes->papRecTypDes[i]->papFldDes[j]->range2.value, + buff[0], buff[1]); + bufOut(fp, fflag); + } + } + } +} /* end of DbRecDes */ +static void +ChoiceRec(fp, fflag) + FILE *fp; + int fflag; +{ + if (!choiceRec) { + printf("ChoiceRec: Error - choiceRec not loaded\n"); + return; + } + endNumI = dbRecType->number; + + printf("DO YOU WANT TO LIST ALL RECORD TYPES ??? (y|n) : "); + scanf("%s", ibuff); + + if (ibuff[0] != 'y') { + FOREVER { + printf("\nRECTYPE MENU:\n"); + for (i = 0; i < dbRecType->number; i++) { + if (dbRecType->papName[i] + && choiceRec->papArrChoiceSet[i]) { + printf("%d\t%s\n", i, dbRecType->papName[i]); + } + } + printf("ENTER SELECTION NUMBER (X-%d) : ", i - 1); + scanf("%d", &inum); + if ((choiceRec->papArrChoiceSet[inum]) + && (inum >= 0) && (inum < i)) { + begNumI = inum; + endNumI = begNumI + 1; + break; + } else { + printf("Not a selection, Please try again\n"); + } + } + } else { + for (i = 0; i < dbRecType->number; i++) { + /* start at first record definition */ + if (choiceRec->papArrChoiceSet[i]) { + begNumI = i; + break; + } + } + } + sprintf(buffer, "\n\ndbls: listing the choiceRec structure"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] choiceRec -> choiceRec", &choiceRec, choiceRec); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\tnumber\t\t[%d]", &choiceRec->number, choiceRec->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t**papArrChoiceSet -> arrChoiceSet", + &choiceRec->papArrChoiceSet, + choiceRec->papArrChoiceSet); + bufOut(fp, fflag); + + for (i = begNumI; i < endNumI; i++) { + if (choiceRec->papArrChoiceSet[i]) { + sprintf(buffer, "%8x[%8x]\tpapArrChoiceSet[%d] -> arrChoiceSet\t\tRECTYPE \"%s\"", + &choiceRec->papArrChoiceSet[i], + choiceRec->papArrChoiceSet[i], i, + dbRecType->papName[i]); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of choice sets */", + &choiceRec->papArrChoiceSet[i]->number, + choiceRec->papArrChoiceSet[i]->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t **papChoiceSet", + &choiceRec->papArrChoiceSet[i]->papChoiceSet, + choiceRec->papArrChoiceSet[i]->papChoiceSet); + bufOut(fp, fflag); + for (j = 0; j < choiceRec->papArrChoiceSet[i]->number; j++) { + if (choiceRec->papArrChoiceSet[i]->papChoiceSet[j]) { + sprintf(buffer, "%8x[%8x]\t papChoiceSet[%d] -> choiceSet \t\tINDEX[%d]", + + &choiceRec->papArrChoiceSet[i]->papChoiceSet[j], + choiceRec->papArrChoiceSet[i]->papChoiceSet[j], j, j); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t\tnumber\t\t[%d]\t/* number of choices */ ", + &choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number, + choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t\t**papChoice -> \"string\"", + &choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice, + choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice); + bufOut(fp, fflag); + for (k = 0; k < choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number; k++) { + if (choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k]) { + sprintf(buffer, "%8x[%8x]\t\tpapChoice[%d]\t\"%s\"", + &choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k], + choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k], k, + choiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k]); + bufOut(fp, fflag); + } + } + + } + } + + } + } +} /* end of ChoiceRec */ +static void +DbErrDes(fp, fflag) + FILE *fp; + int fflag; +{ + if (!dbErrDes) { + printf("DbErrDes Error - dbErrDes not loaded\n"); + return; + } + sprintf(buffer, "\n\ndbls: listing the dbErrDes structure"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] dbErrDes -> errDes ", &dbErrDes, dbErrDes); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\tnumber\t [ %d ]\t /* dim of err modules */", + &dbErrDes->number, dbErrDes->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papErrSet -> errSet ", + &dbErrDes->papErrSet, dbErrDes->papErrSet); + bufOut(fp, fflag); + for (i = 0; i < dbErrDes->number; i++) { + if (dbErrDes->papErrSet[i]) { + sprintf(buffer, "%8x[%8x] papErrSet->[%d]\tmodule[%d]", + &dbErrDes->papErrSet[i], + dbErrDes->papErrSet[i], i, + i + 501); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number\t[%d]\t/* dim of errSet */", + &dbErrDes->papErrSet[i]->number, + dbErrDes->papErrSet[i]->number); + bufOut(fp, fflag); + for (j = 0; j < dbErrDes->papErrSet[i]->number; j++) { + if (dbErrDes->papErrSet[i]->papName[j]) { + sprintf(buffer, "%8x[%8x]\t\tpapName[%d]\t\"%s\"", + &dbErrDes->papErrSet[i]->papName[j], + dbErrDes->papErrSet[i]->papName[j], + j, + dbErrDes->papErrSet[i]->papName[j]); + bufOut(fp, fflag); + } + } + } + } +} /* end of DbErrDes */ +static void +DbRecords(fp, fflag) + FILE *fp; + int fflag; +{ + if (!dbRecords) { + printf("DbRecords: Error - dbRecords not loaded\n"); + return; + } + getRecTypeSel(); + sprintf(buffer, "\n\ndbls: listing the dbRecords structure\n"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] dbRecords -> recHeader", &dbRecords, dbRecords); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of record types */", + &dbRecords->number, + dbRecords->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t**papRecLoc -> recLoc", + &dbRecords->papRecLoc, + dbRecords->papRecLoc); + bufOut(fp, fflag); + for (i = begNumI; i < endNumI; i++) { + if (dbRecords->papRecLoc[i]) { + sprintf(buffer, "%8x[%8x]\t papRecLoc->[%d]\tRECTYPE[\"%s\"]", + &dbRecords->papRecLoc[i], + dbRecords->papRecLoc[i], + i, + dbRecType->papName[i]); + bufOut(fp, fflag); + + sprintf(buffer, "%8x\t\t no_records [%d]\t\t/* no_records of this type */", + &dbRecords->papRecLoc[i]->no_records, + dbRecords->papRecLoc[i]->no_records); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t no_used [%d]\t\t/* no_used of this type */", + &dbRecords->papRecLoc[i]->no_used, + dbRecords->papRecLoc[i]->no_used); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t rec_size [%d]\t\t/* rec_size in bytes */", + &dbRecords->papRecLoc[i]->rec_size, + dbRecords->papRecLoc[i]->rec_size); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t *pFirst\t\t\t/* ptr to first record */", + &dbRecords->papRecLoc[i]->pFirst, + dbRecords->papRecLoc[i]->pFirst); + bufOut(fp, fflag); + } + } +} /* end of DbRecords */ + +static void +RecSup(fp, fflag) + FILE *fp; + int fflag; +{ + if (!recSup) { + printf("RecSup: Error - recSup not loaded\n"); + return; + } + getRecTypeSel(); + sprintf(buffer, "\n\ndbls: listing the recSup structure\n"); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] recSup -> recSup", &recSup, recSup); + bufOut(fp, fflag); + sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of record types */", + &recSup->number, + recSup->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x] **papRset -> rset", + &recSup->papRset, + recSup->papRset); + bufOut(fp, fflag); + for (i = begNumI; i < endNumI; i++) { + if (recSup->papRset[i]) { + sprintf(buffer, "%8x[%8x]\t papRset->[%d]\t\tRECTYPE[\"%s\"]", + &recSup->papRset[i], + recSup->papRset[i], i, + dbRecType->papName[i]); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t number\t\t/*number of support routines */", + &recSup->papRset[i]->number, + recSup->papRset[i]->number); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t report\t\t/*print report */", + &recSup->papRset[i]->report, + recSup->papRset[i]->report); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t init\t\t/*init support */", + &recSup->papRset[i]->init, + recSup->papRset[i]->init); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t init_record\t/*init record */", + &recSup->papRset[i]->init_record, + recSup->papRset[i]->init_record); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t process\t\t/*process record */", + &recSup->papRset[i]->process, + recSup->papRset[i]->process); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t special\t\t/*special processing */", + &recSup->papRset[i]->special, + recSup->papRset[i]->special); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t get_precision\t/* get_precision of this type */", + &recSup->papRset[i]->get_precision, + recSup->papRset[i]->get_precision); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t get_value\t\t/*get value field */", + &recSup->papRset[i]->get_value, + recSup->papRset[i]->get_value); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t cvt_dbaddr\t\t/*cvt dbAddr */", + &recSup->papRset[i]->cvt_dbaddr, + recSup->papRset[i]->cvt_dbaddr); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t get_array_info\t/* get_array_info of this type */", + &recSup->papRset[i]->get_array_info, + recSup->papRset[i]->get_array_info); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t put_array_info\t/* put_array_info of this type */", + &recSup->papRset[i]->put_array_info, + recSup->papRset[i]->put_array_info); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t get_enum_str\t/*get string from enum item*/", + &recSup->papRset[i]->get_enum_str, + recSup->papRset[i]->get_enum_str); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t get_units \t\t/* get_units of this type */", + &recSup->papRset[i]->get_units, + recSup->papRset[i]->get_units); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t get_graphic_double /* get_graphic_double of this type */", + &recSup->papRset[i]->get_graphic_double, + recSup->papRset[i]->get_graphic_double); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t get_control_double /* get_control_double of this type */", + &recSup->papRset[i]->get_control_double, + recSup->papRset[i]->get_control_double); + bufOut(fp, fflag); + sprintf(buffer, "%8x[%8x]\t get_enum_strs\t/*get all enum strings */", + &recSup->papRset[i]->get_enum_strs, + recSup->papRset[i]->get_enum_strs); + bufOut(fp, fflag); + } + } +} /* end of recSup */ +/****************JUNK*************/ diff --git a/src/db/iocInit.c b/src/db/iocInit.c new file mode 100644 index 000000000..013bf306d --- /dev/null +++ b/src/db/iocInit.c @@ -0,0 +1,398 @@ + +/* iocInit.c ioc initialization */ +/* share/src/db $Id$ */ + +#include +#include +#include +#include +#include +#include +#include /* for sysSymTbl*/ +#include /* for N_TEXT */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static initialized=FALSE; + + +/* define forward references*/ +long initBusController(); +long sdrLoad(); +long initDrvSup(); +long initDevSup(); +long initRecSup(); +long initDatabase(); +long addToSet(); + + +iocInit(pfilename) +char * pfilename; +{ + long status; + + if(initialized) { + logMsg("iocInit can only be called once\n"); + return(-1); + } + initialized = TRUE; + if(status=initBusController()) { + logMsg("iocInit aborting because initBusController failed\n"); + return(-1); + } + if(status=sdrLoad(pfilename)) { + logMsg("iocInit aborting because sdrLoad failed\n"); + return(-1); + } + logMsg("sdrLoad completed\n"); + /* enable interrupt level 5 */ + sysIntEnable(5); + if(initDrvSup()==0) logMsg("Drivers Initialized\n"); + if(initDevSup()==0) logMsg("Device Support Initialized\n"); + if(initRecSup()==0) logMsg("Record Support Initialized\n"); + if(initDatabase()==0) logMsg("Database Initialized\n"); + scan_init(); + logMsg("Scanners Initialized\n"); + rsrv_init(); + logMsg("Channel Access Servers Initialized\n"); + logMsg("iocInit: All initialization complete\n"); + return(0); +} + +#include + +long initBusController(){ /*static */ + char ctemp; + + /* initialize the Xycom SRM010 bus controller card */ + ctemp = XY_LED; + if (vxMemProbe(SRM010_ADDR, WRITE,1,&ctemp) == -1) { + logMsg("Xycom SRM010 Bus Controller Not Present\n"); + return(-1); + } + return(0); +} + +static long initDrvSup() /* Locate all driver support entry tables */ +{ + char *pname; + char name[40]; + int i; + UTINY type; + char message[100]; + long status; + long rtnval=0; + + if(!drvSup) { + status = S_drv_noDrvSup; + errMessage(status,"drvSup is NULL, i.e. No device drivers are defined"); + return(status); + } + for(i=0; i< (drvSup->number); i++) { + if(!(pname = drvSup->drvetName[i])) continue; + strcpy(name,"_"); + strcat(name,pname); + rtnval = symFindByName(sysSymTbl,name,&(drvSup->papDrvet[i]),&type); + if( rtnval!=OK || ( type&N_TEXT == 0) ) { + strcpy(message,"driver entry table not found for "); + strcat(message,pname); + status = S_drv_noDrvet; + errMessage(-1L,message); + if(rtnval==OK) rtnval=status; + continue; + } + status = (*(drvSup->papDrvet[i]->init))(); + if(rtnval==OK) rtnval=status; + } + return(rtnval); +} + +static long initDevSup() /* Locate all device support entry tables */ +{ + char *pname; + char name[40]; + int i,j; + UTINY type; + char message[100]; + struct devSup *pdevSup; + long status; + long rtnval=0; /*rtnval will be 0 or first error found*/ + + if(!devSup) { + status = S_dev_noDevSup; + errMessage(status,"devSup is NULL, i.e. No device support is defined"); + return(status); + } + for(i=0; i< (devSup->number); i++) { + if((pdevSup = devSup->papDevSup[i]) == NULL) continue; + for(j=0; j < (pdevSup->number); j++) { + if(!(pname = pdevSup->dsetName[j])) continue; + strcpy(name,"_"); + strcat(name,pname); + rtnval = (long)symFindByName(sysSymTbl,name, + &(pdevSup->papDset[j]),&type); + if( rtnval!=OK || ( type&N_TEXT == 0) ) { + strcpy(message,"device support entry table not found for "); + strcat(message,pname); + status = S_dev_noDSET; + errMessage(-1L,message); + if(rtnval==OK)rtnval=status; + continue; + } + if(!(pdevSup->papDset[j]->init)) continue; + status = (*(pdevSup->papDset[j]->init))(); + if(rtnval==OK)rtnval=status; + } + } + return(rtnval); +} + +static long initRecSup() +{ + char name[40]; + int i; + UTINY type; + char message[100]; + long status; + long rtnval=0; /*rtnval will be 0 or first error found*/ + int nbytes; + + if(!dbRecType) { + status = S_rectype_noRecs; + errMessage(status,"dbRecType is NULL, i.e. no record types defined"); + return(status); + } + nbytes = sizeof(struct recSup) + dbRecType->number*sizeof(caddr_t); + recSup = (struct recSup *)calloc(1,nbytes); + recSup->number = dbRecType->number; + (long)recSup->papRset = (long)recSup + (long)sizeof(struct recSup); + for(i=0; i< (recSup->number); i++) { + if(dbRecType->papName[i] == NULL)continue; + strcpy(name,"_"); + strcat(name,dbRecType->papName[i]); + strcat(name,"RSET"); + rtnval = symFindByName(sysSymTbl,name,&(recSup->papRset[i]),&type); + if( rtnval!=OK || ( type&N_TEXT == 0) ) { + strcpy(message,"record support entry table not found for "); + strcat(message,name); + status = S_rec_noRSET; + errMessage(-1L,message); + if(rtnval==OK)rtnval=status; + continue; + } + if(!(recSup->papRset[i]->init)) continue; + else { + status = (*(recSup->papRset[i]->init))(); + if(rtnval==OK)rtnval=status; + } + } + return(rtnval); +} + +static long initDatabase() +{ + char name[PVNAME_SZ+FLDNAME_SZ+1]; + short i,j,k; + char message[120]; + long status; + long rtnval=0; /*rtnval will be 0 or first error found*/ + short nset=0; + short lookAhead; + struct recLoc *precLoc; + struct rset *prset; + struct devSup *pdevSup; + struct recTypDes *precTypDes; + struct fldDes *pfldDes; + struct dbCommon *precord; + struct dbAddr dbAddr; + struct link *plink; + + if(!dbRecords) { + status = S_record_noRecords; + errMessage(status,"No database records are defined"); + return(status); + } + for(i=0; i< (dbRecords->number); i++) { + if(!(precLoc = dbRecords->papRecLoc[i]))continue; + if(!(prset=GET_PRSET(i))) { + strcpy(name,dbRecType->papName[i]); + strcat(name,"RSET"); + strcpy(message,"record support entry table not found for "); + strcat(message,name); + status = S_rec_noRSET; + errMessage(-1L,message); + if(rtnval==OK) rtnval = status; + continue; + } + pdevSup=GET_DEVSUP(i); /* pdevSup may be NULL */ + precTypDes = dbRecDes->papRecTypDes[i]; + for(j=0, ((char *)precord) = precLoc->pFirst; + jno_records; + j++, ((char *)precord) += precLoc->rec_size ) { + /* If NAME is null then skip this record*/ + if(!(precord->name[0])) continue; + + /* initialize mlok and mlis*/ + FASTLOCKINIT(&precord->mlok); + lstInit(&(precord->mlis)); + precord->pact=FALSE; + + /* set lset=0 See determine lock set below.*/ + precord->lset = 0; + + /* Init DSET NOTE that result may be NULL*/ + precord->dset=(struct dset *)GET_PDSET(pdevSup,precord->dtyp); + + /* Convert all PV_LINKs to DB_LINKs or CA_LINKs*/ + for(k=0; kno_links; k++) { + pfldDes = precTypDes->papFldDes[precTypDes->link_ind[k]]; + plink = (struct link *)((char *)precord + pfldDes->offset); + if(plink->type == PV_LINK) { + strncpy(name,plink->value.pv_link.pvname,PVNAME_SZ); + strcat(name,"."); + strncat(name,plink->value.pv_link.fldname,FLDNAME_SZ); + if(dbNameToAddr(name,&dbAddr) == 0) { + plink->type = DB_LINK; + plink->value.db_link.paddr = + (caddr_t)calloc(1,sizeof(struct dbAddr)); + *((struct dbAddr *)(plink->value.db_link.paddr))=dbAddr; + /* show that refered to record has link. */ + /* See determine lock set below.*/ + ((struct dbCommon *)(dbAddr.precord))->lset = -1; + } + else { + /*This will be replaced by channel access call*/ + strncpy(message,precord->name,PVNAME_SZ); + strcat(message,"."); + strncat(message,pfldDes->fldname,FLDNAME_SZ); + strcat(message,": link process variable ="); + strcat(message,name); + strcat(message," not found"); + status = S_db_notFound; + errMessage(-1L,message); + if(rtnval==OK) rtnval=status; + } + } + } + + /* call record support init_record routine */ + if(!(recSup->papRset[i]->init_record)) continue; + status = (*(recSup->papRset[i]->init_record))(precord); + if(rtnval==OK)rtnval=status; + } + } + + /* Now determine lock sets*/ + /* When each record is examined lset has one of the following values + * -1 Record is not in a set and at least one following record refers + * to this record + * 0 record is not in a set and no following records refer to it. + * >0 Record is already in a set + */ + for(i=0; inumber; i++) { + if(!(precLoc = dbRecords->papRecLoc[i]))continue; + precTypDes = dbRecDes->papRecTypDes[i]; + for(j=0, ((char *)precord) = precLoc->pFirst; + jno_records; + j++, ((char *)precord) += precLoc->rec_size ) { + /* If NAME is null then skip this record*/ + if(!(precord->name[0])) continue; + if(precord->lset > 0) continue; /*already in a lock set */ + lookAhead = ( (precord->lset == -1) ? TRUE : FALSE); + nset++; + status = addToSet(precord,i,lookAhead,i,j,nset); + if(status) return(status); + } + } + dbScanLockInit(nset); + return(rtnval); +} + +static long addToSet(precord,record_type,lookAhead,i,j,lset) + struct dbCommon *precord; /* record being added to lock set*/ + short record_type; /* record being added to lock set*/ + short lookAhead; /*should following records be checked*/ + short i; /*record before 1st following: index into papRecLoc*/ + short j; /*record before 1st following: record number */ + short lset; /* current lock set */ +{ + short k,in,itemp,jn,j1st; + long status; + struct fldDes *pfldDes; + struct link *plink; + struct dbCommon *ptemp; + struct dbCommon *ptemp1; + struct recTypDes *precTypDes; + struct recLoc *precLoc; + + + if(precord->lset = -1) precord->lset=0; + if(precord->lset != 0) { + if(precord->lset == lset) return(0); + status = S_db_lsetLogic; + errMessage(status,"Logic Error in iocInit(addToSet)"); + return(status); + } + precord->lset = lset; + /* add all DB_LINKs in this record to the set */ + precTypDes = dbRecDes->papRecTypDes[record_type]; + for(k=0; kno_links; k++) { + pfldDes = precTypDes->papFldDes[precTypDes->link_ind[k]]; + plink = (struct link *)((char *)precord + pfldDes->offset); + if(plink->type != DB_LINK) continue; + status = addToSet( + ((struct dbAddr *)(plink->value.db_link.paddr))->precord, + ((struct dbAddr *)(plink->value.db_link.paddr))->record_type, + TRUE,i,j,lset); + if(status) return(status); + } + /* Now look for all later records that refer to this record*/ + /* remember that all earlier records already have lock set determined*/ + if(!lookAhead) return(0); + j1st=j+1; + for(in=i; innumber; in++) { + if(!(precLoc = dbRecords->papRecLoc[in])) continue; + precTypDes = dbRecDes->papRecTypDes[in]; + for(jn=j1st, + (char *)ptemp= (char *)(precLoc->pFirst) + jn*(precLoc->rec_size); + jnno_records; + jn++, ((char *)ptemp) += precLoc->rec_size) { + /* If NAME is null then skip this record*/ + if(!(ptemp->name[0])) continue; + for(k=0; kno_links; k++) { + pfldDes = precTypDes->papFldDes[precTypDes->link_ind[k]]; + plink = (struct link *)((char *)ptemp + pfldDes->offset); + if(plink->type != DB_LINK) continue; + ptemp1 = (struct dbCommon *) + (((struct dbAddr *)(plink->value.db_link.paddr))->precord); + if(ptemp1 != precord) continue; + if(ptemp->lset != 0) { + if(ptemp->lset == lset) continue; + status = S_db_lsetLogic; + errMessage(status,"Logic Error in iocInit(addToSet)"); + return(status); + } + itemp = ((struct dbAddr *)(plink->value.db_link.paddr))->record_type; + status = addToSet(ptemp1,itemp,TRUE,i,j,lset); + if(status) return(status); + } + } + j1st = 0; + } + return(0); +} diff --git a/src/db/recGbl.c b/src/db/recGbl.c new file mode 100644 index 000000000..d3faea476 --- /dev/null +++ b/src/db/recGbl.c @@ -0,0 +1,350 @@ +/* recGbl.c - Global record processing routines */ +/* share/src/db $Id$ */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/*********************************************************************** +* The following are the global record processing rouitines +* +*void recGblDbaddrError(status,paddr,pcaller_name) +* long status; +* struct dbAddr *paddr; +* char *pcaller_name; * calling routine name * +* +*void recGblRecordError(status,precord,pcaller_name) +* long status; +* caddr_t precord; * addr of record * +* char *pcaller_name; * calling routine name * +* +*void recGblRecSupError(status,paddr,pcaller_name,psupport_name) +* long status; +* struct dbAddr *paddr; +* char *pcaller_name; * calling routine name * +* char *psupport_name; * support routine name * +* +* int recGblGetTypeIndex(prec_name,ptypeIndex) +* char *prec_name; +* int *ptypeIndex; +* +* int recGblReportDbCommon(fp,paddr)) +* FILE *fp; +* struct dbAddr *paddr; +* +* int recGblReportLink(fp,pfield_name,plink) +* FILE *fp; +* char *pfield_name; +* struct link *plink; +* +* int recGblReportCvtChoice(fp,pfield_name,choice_value) +* FILE *fp; +* char *pfield_name; +* unsigned short choice_value; +* +* int recGblReportGblChoice(fp,precord,pfield_name,choice_value) +* FILE *fp; +* struct dbCommon *precord; +* char *pfield_name; +* unsigned short choice_value; +* +* int recGblReportRecChoice(fp,precord,pfield_name,choice_value) +* FILE *fp; +* struct dbCommon *precord; +* char *pfield_name; +* unsigned short choice_value; +**************************************************************************/ + +recGblDbaddrError(status,paddr,pcaller_name) +long status; +struct dbAddr *paddr; +char *pcaller_name; /* calling routine name*/ +{ + char buffer[200]; + struct dbCommon *precord; + int i,n; + struct fldDes *pfldDes=(struct fldDes *)(paddr->pfldDes); + + buffer[0]=0; + if(paddr) { /* print process variable name */ + precord=(struct dbCommon *)(paddr->precord); + strcat(buffer,"PV: "); + strncat(buffer,precord->name,PVNAME_SZ); + n=strlen(buffer); + for(i=n; (i>0 && buffer[i]==' '); i--) buffer[i]=0; + strcat(buffer,"."); + strncat(buffer,pfldDes->fldname,FLDNAME_SZ); + strcat(buffer," "); + } + if(pcaller_name) { + strcat(buffer,"error detected in routine: "); + strcat(buffer,pcaller_name); + } + errMessage(status,buffer); + return; +} + + +recGblRecordError(status,precord,pcaller_name) +long status; +struct dbCommon *precord; +char *pcaller_name; /* calling routine name*/ +{ + char buffer[200]; + int i,n; + + buffer[0]=0; + if(precord) { /* print process variable name */ + strcat(buffer,"PV: "); + strncat(buffer,precord->name,PVNAME_SZ); + n=strlen(buffer); + for(i=n; (i>0 && buffer[i]==' '); i--) buffer[i]=0; + strcat(buffer," "); + } + if(pcaller_name) { + strcat(buffer,"error detected in routine: "); + strcat(buffer,pcaller_name); + } + errMessage(status,buffer); + return; +} + +recGblRecSupError(status,paddr,pcaller_name,psupport_name) +long status; +struct dbAddr *paddr; +char *pcaller_name; +char *psupport_name; +{ + char buffer[200]; + char *pstr; + struct dbCommon *precord; + int i,n; + struct fldDes *pfldDes=(struct fldDes *)(paddr->pfldDes); + + buffer[0]=0; + strcat(buffer,"Record Support Routine ("); + if(psupport_name) + strcat(buffer,psupport_name); + else + strcat(buffer,"Unknown"); + strcat(buffer,") not available.\nRecord Type is "); + if(pstr=GET_PRECTYPE(paddr->record_type)) + strcat(buffer,pstr); + else + strcat(buffer,"BAD"); + if(paddr) { /* print process variable name */ + precord=(struct dbCommon *)(paddr->precord); + strcat(buffer,", PV is "); + strncat(buffer,precord->name,PVNAME_SZ); + n=strlen(buffer); + for(i=n; (i>0 && buffer[i]==' '); i--) buffer[i]=0; + strcat(buffer,"."); + strncat(buffer,pfldDes->fldname,FLDNAME_SZ); + strcat(buffer," "); + } + if(pcaller_name) { + strcat(buffer,"\nerror detected in routine: "); + strcat(buffer,pcaller_name); + } + errMessage(status,buffer); + return; +} + +int recGblGetTypeIndex(prec_name,ptypeIndex) + char *prec_name; + int *ptypeIndex; +{ + int i; + + for(i=0; i < dbRecType->number; i++) { + if(!(dbRecType->papName[i])) continue; + if(strcmp(dbRecType->papName[i],prec_name) == 0) { + *ptypeIndex = i; + return(0); + } + } + return(-1); +} + +int recGblReportDbCommon(fp,paddr) + FILE *fp; + struct dbAddr *paddr; +{ + struct dbCommon *precord=(struct dbCommon *)(paddr->precord); + struct devSup *pdevSup; + + if(fprintf(fp,"NAME %-28s\nDESC %-28s\n",precord->name,precord->desc)<0) + return(-1); + if(recGblReportGblChoice(fp,precord,"SCAN",precord->scan)) return(-1); + if(fprintf(fp,"PHAS %d\tEVNT %d\n", + precord->phas,precord->evnt)<0) return(-1); + if(fprintf(fp,"STAT %d\tSEVR %d\nDTYP %5d\n", + precord->stat,precord->sevr,precord->dtyp)<0) return(-1); + if(precord->dset != NULL) { + if(!(pdevSup=GET_DEVSUP(paddr->record_type))) return(-1); + if(fprintf(fp,"DSET %s\n",(pdevSup->dsetName[precord->dtyp]))<0) + return(-1); + } + if(recGblReportLink(fp,"SDIS",&(precord->sdis))) return(-1); + if(fprintf(fp,"DISA %d\tPACT %d\t",precord->disa,precord->pact)<0) + return(-1); + if(fprintf(fp,"LSET %d\n",precord->lset)<0) return(-1); + if(fprintf(fp,"ESEC 0x%lx\tNSEC 0x%lx\n",precord->esec,precord->nsec)<0) + return(-1); + return(0); +} + +int recGblReportLink(fp,pfield_name,plink) + FILE *fp; + char *pfield_name; + struct link *plink; +{ + switch(plink->type) { + case CONSTANT: + if(fprintf(fp,"%4s %12.4G\n", + pfield_name, + plink->value.value)<0) return(-1); + break; + case PV_LINK: + if(fprintf(fp,"%4s %28s.%4s\n", + pfield_name, + plink->value.pv_link.pvname, + plink->value.pv_link.fldname)<0) return(-1); + break; + case VME_IO: + if(fprintf(fp,"%4s VME: card=%2d signal=%2d\n", + pfield_name, + plink->value.vmeio.card,plink->value.vmeio.card)<0) return(-1); + break; + case CAMAC_IO: + if(fprintf(fp, + "%4s CAMAC: branch=%2d crate=%2d slot=%2d channel=%2d\n", + pfield_name, + plink->value.camacio.branch,plink->value.camacio.crate, + plink->value.camacio.slot,plink->value.camacio.channel)<0) + return(-1); + break; + case AB_IO: + if(fprintf(fp, + "%4s ABIO: link=%2d adaptor=%2d card=%2d signal=%2d flag=%1d\n", + pfield_name, + plink->value.abio.link,plink->value.abio.adapter, + plink->value.abio.card,plink->value.abio.signal, + plink->value.abio.plc_flag)<0) return(-1); + break; + case GPIB_IO: + if(fprintf(fp, "%4s GPIB: link=%2d taddr=%2d laddr=%2d signal=%3d\n", + pfield_name, + plink->value.gpibio.link,plink->value.gpibio.taddr, + plink->value.gpibio.laddr,plink->value.gpibio.signal)<0) + return(-1); + break; + case BITBUS_IO: + if(fprintf(fp, "%4s BITBUS: link=%2d addr=%2d signal=%3d\n", + pfield_name, + plink->value.bitbusio.link,plink->value.bitbusio.addr, + plink->value.bitbusio.signal)<0) return(-1); + break; + case DB_LINK: + if(fprintf(fp,"%4s DB_LINK: %28s\n", + pfield_name, + ((struct dbCommon *)( + ((struct dbAddr *)plink->value.db_link.paddr) + ->precord))->name)<0) + return(-1); + break; + case CA_LINK: + if(fprintf(fp,"%4s CA_LINK: Not Yet Implemented\n", + pfield_name)<0) return(-1); + break; + default: + errMessage(S_db_badField,"recGblReportLink: Illegal link.type"); + break; + } + return(0); +} + +int recGblReportCvtChoice(fp,pfield_name,choice_value) + FILE *fp; + char *pfield_name; + unsigned short choice_value; +{ + char *pchoice; + + if(!(pchoice=GET_CHOICE(choiceCvt,choice_value))) { + if(fprintf(fp,"%4s Illegal Choice\n",pfield_name)<0) return(-1); + } + else { + if(fprintf(fp,"%4s: %s\n",pfield_name,pchoice)<0) return(-1); + } + return(0); +} + + +int recGblReportGblChoice(fp,precord,pfield_name,choice_value) + FILE *fp; + struct dbCommon *precord; + char *pfield_name; + unsigned short choice_value; +{ + char name[PVNAME_SZ+1+FLDNAME_SZ+1]; + struct dbAddr dbAddr; + struct choiceSet *pchoiceSet; + char *pchoice; + + strncpy(name,precord->name,PVNAME_SZ); + strcat(name,"."); + strncat(name,pfield_name,FLDNAME_SZ); + if(dbNameToAddr(name,&dbAddr)) { + if(fprintf(fp,"%4s dbNameToAddr failed?\n",pfield_name)<0)return(-1); + return(0); + } + if( !(pchoiceSet=GET_PCHOICE_SET(choiceGbl,dbAddr.choice_set)) + || !(pchoice=GET_CHOICE(pchoiceSet,choice_value))) { + if(fprintf(fp,"%4s Cant find Choice\n",pfield_name)<0) return(-1); + } + else { + if(fprintf(fp,"%4s: %s\n",pfield_name,pchoice)<0) return(-1); + } + return(0); +} + +int recGblReportRecChoice(fp,precord,pfield_name,choice_value) + FILE *fp; + struct dbCommon *precord; + char *pfield_name; + unsigned short choice_value; +{ + char name[PVNAME_SZ+1+FLDNAME_SZ+1]; + struct dbAddr dbAddr; + struct arrChoiceSet *parrChoiceSet; + struct choiceSet *pchoiceSet; + char *pchoice; + + strncpy(name,precord->name,PVNAME_SZ); + strcat(name,"."); + strncat(name,pfield_name,FLDNAME_SZ); + if(dbNameToAddr(name,&dbAddr)) { + if(fprintf(fp,"%4s dbNameToAddr failed?\n",pfield_name)<0)return(-1); + return(0); + } + if( !(parrChoiceSet=GET_PARR_CHOICE_SET(choiceRec,dbAddr.record_type)) + || !(pchoiceSet=GET_PCHOICE_SET(parrChoiceSet,dbAddr.choice_set)) + || !(pchoice=GET_CHOICE(pchoiceSet,choice_value))) { + if(fprintf(fp,"%4s Cant find Choice\n",pfield_name)<0) return(-1); + } + else { + if(fprintf(fp,"%4s: %s\n",pfield_name,pchoice)<0) return(-1); + } + return(0); +}