Merge branch 'aliases' into PSI-7.0

This commit is contained in:
2024-08-26 16:37:57 +02:00
24 changed files with 421 additions and 89 deletions
+56 -53
View File
@@ -145,63 +145,66 @@ long dbPutSpecial(DBADDR *paddr,int pass)
}
static void get_enum_strs(DBADDR *paddr, char **ppbuffer,
rset *prset,long *options)
rset *prset, long *options)
{
short field_type=paddr->field_type;
dbFldDes *pdbFldDes = paddr->pfldDes;
dbMenu *pdbMenu;
dbDeviceMenu *pdbDeviceMenu;
char **papChoice;
unsigned long no_str;
char *ptemp;
struct dbr_enumStrs *pdbr_enumStrs=(struct dbr_enumStrs*)(*ppbuffer);
unsigned int i;
struct dbr_enumStrs *penum=(struct dbr_enumStrs*)(*ppbuffer);
/* advance output buffer on success or failure for next option */
*ppbuffer = dbr_enumStrs_size + (char*)penum;
memset(pdbr_enumStrs,'\0',dbr_enumStrs_size);
switch(field_type) {
case DBF_ENUM:
if( prset && prset->get_enum_strs ) {
(*prset->get_enum_strs)(paddr,pdbr_enumStrs);
} else {
*options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
}
break;
case DBF_MENU:
pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
no_str = pdbMenu->nChoice;
papChoice= pdbMenu->papChoiceValue;
goto choice_common;
case DBF_DEVICE:
pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
if(!pdbDeviceMenu) {
*options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
break;
}
no_str = pdbDeviceMenu->nChoice;
papChoice = pdbDeviceMenu->papChoice;
goto choice_common;
choice_common:
i = sizeof(pdbr_enumStrs->strs)/
sizeof(pdbr_enumStrs->strs[0]);
if(i<no_str) no_str = i;
pdbr_enumStrs->no_str = no_str;
ptemp = &(pdbr_enumStrs->strs[0][0]);
for (i=0; i<no_str; i++) {
if(papChoice[i]==NULL) *ptemp=0;
else {
strncpy(ptemp,papChoice[i],
sizeof(pdbr_enumStrs->strs[0]));
*(ptemp+sizeof(pdbr_enumStrs->strs[0])-1) = 0;
}
ptemp += sizeof(pdbr_enumStrs->strs[0]);
}
break;
default:
*options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
break;
memset(penum, 0, dbr_enumStrs_size);
/* from this point
* on success, return early
* on failure, jump or fall through to clear *options bit.
*/
if(paddr->field_type == DBF_ENUM) {
if( prset && prset->get_enum_strs ) {
(*prset->get_enum_strs)(paddr,penum);
return;
}
} else if(paddr->field_type == DBF_MENU || paddr->field_type == DBF_DEVICE) {
char **ppchoices;
epicsUInt32 i, nchoices = 0;
if(paddr->field_type == DBF_MENU) {
dbMenu *pmenu = paddr->pfldDes->ftPvt;
nchoices = pmenu->nChoice;
ppchoices= pmenu->papChoiceValue;
} else if(paddr->field_type == DBF_DEVICE) {
dbDeviceMenu *pdevs = paddr->pfldDes->ftPvt;
if(!pdevs)
goto nostrs;
nchoices = pdevs->nChoice;
ppchoices = pdevs->papChoice;
}
if(nchoices > NELEMENTS(penum->strs))
nchoices = NELEMENTS(penum->strs); /* availible > capacity, truncated list */
penum->no_str = nchoices;
for(i=0; i<nchoices; i++) {
if(ppchoices[i]) {
strncpy(penum->strs[i], ppchoices[i],
sizeof(penum->strs[i]));
/* strs[i][] allowed to omit trailing nil */
} else {
penum->strs[i][0] = '\0';
}
}
*ppbuffer = ((char *)*ppbuffer) + dbr_enumStrs_size;
return;
} else {
/* other DBF_* fall through to error */
}
nostrs:
/* indicate option data not available. distinct from no_str==0 */
*options = (*options)^DBR_ENUM_STRS;
}
static void get_graphics(DBADDR *paddr, char **ppbuffer,
+1 -1
View File
@@ -165,7 +165,7 @@ unsigned long dbChannelIO::nativeElementCount (
{
guard.assertIdenticalMutex ( this->mutex );
long elements = dbChannelElements ( this->dbch );
if ( elements >= 0u ) {
if ( elements >= 0 ) {
return static_cast < unsigned long > ( elements );
}
return 0u;
+10 -2
View File
@@ -15,13 +15,21 @@ typedef struct dbCommonPvt {
/* Thread which is currently processing this record */
struct epicsThreadOSD* procThread;
struct dbCommon common;
/* actually followed by:
* struct dbCommon common;
*/
} dbCommonPvt;
static EPICS_ALWAYS_INLINE
dbCommonPvt* dbRec2Pvt(struct dbCommon *prec)
{
return CONTAINER(prec, dbCommonPvt, common);
return (dbCommonPvt*)((char*)prec - sizeof(dbCommonPvt));
}
static EPICS_ALWAYS_INLINE
dbCommon* dbPvt2Rec(struct dbCommonPvt *pvt)
{
return (dbCommon*)&pvt[1];
}
#endif // DBCOMMONPVT_H
+1 -1
View File
@@ -94,7 +94,7 @@ static long cvt_st_UInt32(const char *from, void *pfield, const dbAddr *paddr)
status = epicsParseFloat64(from, &dval, &end);
if (!status &&
dval >=0 &&
dval <= ULONG_MAX)
dval <= UINT_MAX)
*to = dval;
}
return status;
+2 -2
View File
@@ -302,7 +302,7 @@ static long getStringUlong(const dbAddr *paddr,
epicsFloat64 dval;
status = epicsParseFloat64(psrc, &dval, &end);
if (!status && 0 <= dval && dval <= ULONG_MAX)
if (!status && 0 <= dval && dval <= UINT_MAX)
*pdst = dval;
}
if (status)
@@ -1052,7 +1052,7 @@ static long putStringUlong(dbAddr *paddr,
epicsFloat64 dval;
status = epicsParseFloat64(psrc, &dval, &end);
if (!status && 0 <= dval && dval <= ULONG_MAX)
if (!status && 0 <= dval && dval <= UINT_MAX)
*pdst = dval;
}
if (status)
+1 -1
View File
@@ -181,7 +181,7 @@ static long cvt_st_ul(const void *f, void *t, const dbAddr *paddr)
status = epicsParseFloat64(from, &dval, &end);
if (!status &&
dval >=0 &&
dval <= ULONG_MAX)
dval <= UINT_MAX)
*to = dval;
}
return status;
@@ -1119,6 +1119,20 @@ static void dbRecordHead(char *recordType, char *name, int visible)
return;
}
if (recordType[0] == '#' && recordType[1] == 0) {
status = dbFindRecord(pdbentry, name);
if (status == 0) {
dbDeleteRecord(pdbentry);
} else {
fprintf(stderr, ERL_WARNING ": Unable to delete record \"%s\". Not found.\n"
" at file %s line %d\n",
name, pinputFileNow->filename, pinputFileNow->line_num);
}
popFirstTemp();
dbFreeEntry(pdbentry);
duplicate = TRUE;
return;
}
status = dbFindRecordType(pdbentry, recordType);
if (status) {
fprintf(stderr, "Record \"%s\" is of unknown type \"%s\"\n",
@@ -1249,24 +1263,50 @@ static void dbRecordInfo(char *name, char *value)
}
}
static long createAlias(DBENTRY *pdbentry, const char *alias)
{
DBENTRY tempEntry;
long status;
dbRecordNode *precnode = pdbentry->precnode;
if (precnode->aliasedRecnode) precnode = precnode->aliasedRecnode;
dbInitEntry(pdbentry->pdbbase, &tempEntry);
status = dbFindRecord(&tempEntry, alias);
if (status == 0) {
if (tempEntry.precnode->aliasedRecnode != precnode) {
if (tempEntry.precnode->aliasedRecnode)
fprintf(stderr, ERL_ERROR ": Alias \"%s\" for \"%s\": name already used by an alias for \"%s\"\n",
alias, dbGetRecordName(pdbentry),
tempEntry.precnode->aliasedRecnode->recordname);
else
fprintf(stderr, ERL_ERROR ": Alias \"%s\" for \"%s\": name already used by a record\n",
alias, dbGetRecordName(pdbentry));
status = S_dbLib_recExists;
} else if (dbRecordsOnceOnly) {
fprintf(stderr, ERL_ERROR ": Alias \"%s\" already defined and dbRecordsOnceOnly set.\n",
alias);
status = S_dbLib_recExists;
}
} else {
status = dbCreateAlias(pdbentry, alias);
}
dbFinishEntry(&tempEntry);
return status;
}
static void dbRecordAlias(char *name)
{
DBENTRY *pdbentry;
tempListNode *ptempListNode;
long status;
if(dbRecordNameValidate(name))
return;
if (duplicate) return;
ptempListNode = (tempListNode *)ellFirst(&tempList);
pdbentry = ptempListNode->item;
status = dbCreateAlias(pdbentry, name);
if (status) {
fprintf(stderr, "Can't create alias \"%s\" for \"%s\"\n",
name, dbGetRecordName(pdbentry));
if (createAlias(pdbentry, name) != 0) {
yyerror(NULL);
return;
}
}
@@ -1284,9 +1324,7 @@ static void dbAlias(char *name, char *alias)
alias, name);
yyerror(NULL);
}
else if (dbCreateAlias(pdbEntry, alias)) {
fprintf(stderr, "Can't create alias \"%s\" referring to \"%s\"\n",
alias, name);
else if (createAlias(pdbEntry, alias) != 0) {
yyerror(NULL);
}
dbFinishEntry(pdbEntry);
@@ -1219,7 +1219,9 @@ long dbNextRecordType(DBENTRY *pdbentry)
char * dbGetRecordTypeName(DBENTRY *pdbentry)
{
return(pdbentry->precordType->name);
dbRecordType *pdbRecordType = pdbentry->precordType;
if(!pdbRecordType) return NULL;
return(pdbRecordType->name);
}
int dbGetNRecordTypes(DBENTRY *pdbentry)
@@ -1477,6 +1479,17 @@ long dbDeleteAliases(DBENTRY *pdbentry)
return 0;
}
static void dbDeleteRecordLinks(dbRecordType *rtyp, struct dbCommon *prec)
{
short i;
for (i=0; i<rtyp->no_links; i++) {
dbFldDes *pflddes = rtyp->papFldDes[rtyp->link_ind[i]];
DBLINK *plink = (DBLINK *)(((char *)prec) + pflddes->offset);
dbFreeLinkContents(plink);
}
}
long dbDeleteRecord(DBENTRY *pdbentry)
{
dbBase *pdbbase = pdbentry->pdbbase;
@@ -1492,6 +1505,7 @@ long dbDeleteRecord(DBENTRY *pdbentry)
preclist = &precordType->recList;
ellDelete(preclist, &precnode->node);
dbPvdDelete(pdbbase, precnode);
dbDeleteRecordLinks(precordType, precnode->precord);
while (!dbFirstInfo(pdbentry)) {
dbDeleteInfo(pdbentry);
}
@@ -66,7 +66,17 @@ void devExtend(dsxt *pdsxt)
pthisDevSup->pdsxt = pdsxt;
}
}
/* Ensure that: sizeof(dbCommonPvt) + pdbRecordType->rec_size
* accounts for necessary alignment of record type struct
*/
typedef struct {
dbCommonPvt prefix;
/* ensure no padding needed... */
dbCommon suffix;
} dbCommonPvtAlignmentTest;
STATIC_ASSERT(offsetof(dbCommonPvtAlignmentTest, suffix)==sizeof(dbCommonPvt));
long dbAllocRecord(DBENTRY *pdbentry,const char *precordName)
{
dbRecordType *pdbRecordType = pdbentry->precordType;
@@ -90,8 +100,8 @@ long dbAllocRecord(DBENTRY *pdbentry,const char *precordName)
precordName, pdbRecordType->name, pdbRecordType->rec_size);
return(S_dbLib_noRecSup);
}
ppvt = dbCalloc(1, offsetof(dbCommonPvt, common) + pdbRecordType->rec_size);
precord = &ppvt->common;
ppvt = dbCalloc(1, sizeof(dbCommonPvt) + pdbRecordType->rec_size);
precord = dbPvt2Rec(ppvt);
ppvt->recnode = precnode;
precord->rdes = pdbRecordType;
precnode->precord = precord;
@@ -378,6 +378,7 @@ static int yyerror(char *str)
dbIncludePrint();
yyFailed = TRUE;
}
fprintf(stderr, "\n %d | %s\n", pinputFileNow->line_num, my_buffer);
return(0);
}
static long pvt_yy_parse(void)
@@ -9,6 +9,7 @@
#include <set>
#include <map>
#include <stdint.h>
#include <string.h>
#include <stdint.h>