From 8215244a282a616e31591d2bf6dc3a5d1ed9ca07 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 13 Mar 2015 10:06:23 -0500 Subject: [PATCH 1/5] Fix Windows time discontinuity report --- src/libCom/osi/os/WIN32/osdTime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libCom/osi/os/WIN32/osdTime.cpp b/src/libCom/osi/os/WIN32/osdTime.cpp index fc35c7789..eb2c7ad9d 100644 --- a/src/libCom/osi/os/WIN32/osdTime.cpp +++ b/src/libCom/osi/os/WIN32/osdTime.cpp @@ -366,7 +366,7 @@ void currentTime::getCurrentTime ( epicsTimeStamp & dest ) LONGLONG epicsTimeCurrent = this->epicsTimeLast + offset; if ( this->epicsTimeLast > epicsTimeCurrent ) { double diff = static_cast < double > - ( this->epicsTimeLast - epicsTimeCurrent ); + ( this->epicsTimeLast - epicsTimeCurrent ) / EPICS_TIME_TICKS_PER_SEC; errlogPrintf ( "currentTime::getCurrentTime(): %f sec " "time discontinuity detected\n", From f6373093a54cf25ccebf5b29cf926d76dc2c57f1 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 13 Mar 2015 10:56:03 -0500 Subject: [PATCH 2/5] Fix Windows linkage warning in alarmString.h --- src/dbStatic/alarm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dbStatic/alarm.h b/src/dbStatic/alarm.h index 6aaab449d..814da49f3 100644 --- a/src/dbStatic/alarm.h +++ b/src/dbStatic/alarm.h @@ -43,7 +43,7 @@ typedef enum { #define INVALID_ALARM epicsSevInvalid #define lastEpicsAlarmSev epicsSevInvalid -epicsShareExtern const char *epicsAlarmSeverityStrings [ALARM_NSEV]; +extern const char *epicsAlarmSeverityStrings [ALARM_NSEV]; /* ALARM STATUS - must match menuAlarmStat.dbd */ @@ -98,7 +98,7 @@ typedef enum { #define WRITE_ACCESS_ALARM epicsAlarmWriteAccess #define lastEpicsAlarmCond epicsAlarmWriteAccess -epicsShareExtern const char *epicsAlarmConditionStrings [ALARM_NSTATUS]; +extern const char *epicsAlarmConditionStrings [ALARM_NSTATUS]; #ifdef __cplusplus } From 5ffda58351c631d27e2656dd0ca05c0d7b5ef4aa Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 13 Mar 2015 11:08:05 -0500 Subject: [PATCH 3/5] ca: Fix missing guard argument --- src/ca/oldAccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ca/oldAccess.h b/src/ca/oldAccess.h index 5684b83c3..40f0aee7c 100644 --- a/src/ca/oldAccess.h +++ b/src/ca/oldAccess.h @@ -591,7 +591,7 @@ void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO ( } else { // dont reverse the lock hierarchy - epicsGuardRelease < epicsMutex > guardRelease (); + epicsGuardRelease < epicsMutex > guardRelease ( guard ); { // // we will definately stall out here if all of the From 1fd91f52e2882c94eaadc9b20c165b54ee72f693 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 18 Mar 2015 16:34:07 -0500 Subject: [PATCH 4/5] dbStatic: Add field type lookup routines --- src/ioc/dbStatic/dbLexRoutines.c | 11 +++----- src/ioc/dbStatic/dbStaticLib.c | 44 ++++++++++++++++++++------------ src/ioc/dbStatic/dbStaticLib.h | 3 +++ 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/ioc/dbStatic/dbLexRoutines.c b/src/ioc/dbStatic/dbLexRoutines.c index 6c3d94561..39124289e 100644 --- a/src/ioc/dbStatic/dbLexRoutines.c +++ b/src/ioc/dbStatic/dbLexRoutines.c @@ -486,13 +486,10 @@ static void dbRecordtypeFieldHead(char *name,char *type) allocTemp(pdbFldDes); pdbFldDes->name = epicsStrDup(name); pdbFldDes->as_level = ASL1; - for(i=0; ifield_type = pamapdbfType[i].value; - return; - } - } - yyerrorAbort("Illegal Field Type"); + i = dbFindFieldType(type); + if (i < 0) + yyerrorAbort("Illegal Field Type"); + pdbFldDes->field_type = i; } static void dbRecordtypeFieldItem(char *name,char *value) diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c index 18221af0b..dfbf3ab14 100644 --- a/src/ioc/dbStatic/dbStaticLib.c +++ b/src/ioc/dbStatic/dbStaticLib.c @@ -928,15 +928,8 @@ long dbWriteRecordTypeFP( int j; pdbFldDes = pdbRecordType->papFldDes[i]; - fprintf(fp,"\tfield(%s,",pdbFldDes->name); - for(j=0; jfield_type) break; - } - if(j>=DBF_NTYPES) - fprintf(stderr,"\t field_type: %d\n", - pdbFldDes->field_type); - else - fprintf(fp,"%s) {\n",pamapdbfType[j].strvalue); + fprintf(fp,"\tfield(%s,%s) {\n",pdbFldDes->name, + dbGetFieldTypeString(pdbFldDes->field_type)); if(pdbFldDes->prompt) fprintf(fp,"\t\tprompt(\"%s\")\n",pdbFldDes->prompt); if(pdbFldDes->initial) @@ -2755,6 +2748,30 @@ brkTable * dbFindBrkTable(dbBase *pdbbase,const char *name) return((brkTable *)pgph->userPvt); } +const char * dbGetFieldTypeString(int dbfType) +{ + int i; + + for (i=0; i < DBF_NTYPES; i++) { + if (pamapdbfType[i].value == dbfType) { + return pamapdbfType[i].strvalue; + } + } + return "BAD_DBF_TYPE"; +} + +int dbFindFieldType(const char *type) +{ + int i; + + for (i = 0; i < DBF_NTYPES; i++) { + if (strcmp(type, pamapdbfType[i].strvalue) == 0) { + return pamapdbfType[i].value; + } + } + return -1; +} + dbMenu * dbFindMenu(dbBase *pdbbase,const char *name) { GPHENTRY *pgph; @@ -3143,13 +3160,8 @@ void dbDumpField( } } printf("\n"); - for(j=0; jfield_type) break; - } - if(j>=DBF_NTYPES) - printf("\t field_type: %d\n", pdbFldDes->field_type); - else - printf("\t field_type: %s\n", pamapdbfType[j].strvalue); + printf("\t field_type: %s\n", + dbGetFieldTypeString(pdbFldDes->field_type)); printf("\tprocess_passive: %u\n",pdbFldDes->process_passive); printf("\t property: %u\n",pdbFldDes->prop); printf("\t base: %d\n",pdbFldDes->base); diff --git a/src/ioc/dbStatic/dbStaticLib.h b/src/ioc/dbStatic/dbStaticLib.h index a1752319f..93f7f27d2 100644 --- a/src/ioc/dbStatic/dbStaticLib.h +++ b/src/ioc/dbStatic/dbStaticLib.h @@ -190,6 +190,9 @@ epicsShareFunc long dbPutInfo(DBENTRY *pdbentry, epicsShareFunc brkTable * dbFindBrkTable(DBBASE *pdbbase, const char *name); +epicsShareFunc const char * dbGetFieldTypeString(int dbfType); +epicsShareFunc int dbFindFieldType(const char *type); + epicsShareFunc dbMenu * dbFindMenu(DBBASE *pdbbase, const char *name); epicsShareFunc char ** dbGetMenuChoices(DBENTRY *pdbentry); From eaef9aabdf15771da0637e9f409b6bd7ab848e34 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 18 Mar 2015 16:48:07 -0500 Subject: [PATCH 5/5] Fix export type of .LINK$ fields, add tests --- src/ioc/db/dbChannel.c | 18 +++++++----------- src/ioc/db/dbChannel.h | 3 +-- src/ioc/db/db_access.c | 5 +++-- src/ioc/db/test/dbChannelTest.c | 17 ++++++++++++++--- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/ioc/db/dbChannel.c b/src/ioc/db/dbChannel.c index ae8181cbb..6c57040df 100644 --- a/src/ioc/db/dbChannel.c +++ b/src/ioc/db/dbChannel.c @@ -38,9 +38,6 @@ #include "recSup.h" #include "special.h" -/* The following is defined in db_convert.h */ -extern unsigned short dbDBRnewToDBRold[DBR_ENUM+1]; - typedef struct parseContext { dbChannel *chan; chFilter *filter; @@ -618,7 +615,7 @@ long dbChannelOpen(dbChannel *chan) /* Set up type probe */ probe.type = dbfl_type_val; probe.ctx = dbfl_context_read; - probe.field_type = dbChannelFieldType(chan); + probe.field_type = dbChannelExportType(chan); probe.no_elements = dbChannelElements(chan); probe.field_size = dbChannelFieldSize(chan); p = probe; @@ -660,7 +657,6 @@ long dbChannelOpen(dbChannel *chan) chan->final_no_elements = probe.no_elements; chan->final_field_size = probe.field_size; chan->final_type = probe.field_type; - chan->final_dbr_type = dbDBRnewToDBRold[mapDBFToDBR[probe.field_type]]; return 0; } @@ -709,9 +705,9 @@ void dbChannelShow(dbChannel *chan, int level, const unsigned short indent) int post = ellCount(&chan->post_chain); printf("%*schannel name: %s\n", indent, "", chan->name); - /* FIXME: show field_type as text */ - printf("%*s field_type=%d (%dB), %ld element%s, %d filter%s", indent, "", - chan->addr.field_type, chan->addr.field_size, elems, elems == 1 ? "" : "s", + printf("%*s field_type=%s (%d bytes), dbr_type=%s, %ld element%s, %d filter%s", indent, "", + dbGetFieldTypeString(chan->addr.field_type), chan->addr.field_size, + dbGetFieldTypeString(chan->addr.dbr_field_type), elems, elems == 1 ? "" : "s", count, count == 1 ? "" : "s"); if (count) printf(" (%d pre eventq, %d post eventq)\n", pre, post); @@ -720,9 +716,9 @@ void dbChannelShow(dbChannel *chan, int level, const unsigned short indent) if (level > 0) dbChannelFilterShow(chan, level - 1, indent + 2); if (count) { - /* FIXME: show field_type as text */ - printf("%*s final field_type=%d (%dB), %ld element%s\n", indent, "", - chan->final_type, chan->final_field_size, felems, felems == 1 ? "" : "s"); + printf("%*s final field_type=%s (%dB), %ld element%s\n", indent, "", + dbGetFieldTypeString(chan->final_type), chan->final_field_size, + felems, felems == 1 ? "" : "s"); } } diff --git a/src/ioc/db/dbChannel.h b/src/ioc/db/dbChannel.h index 9f21887db..2d7dc6727 100644 --- a/src/ioc/db/dbChannel.h +++ b/src/ioc/db/dbChannel.h @@ -56,7 +56,6 @@ typedef struct dbChannel { long final_no_elements; /* final number of elements (arrays) */ short final_field_size; /* final size of element */ short final_type; /* final type of database field */ - short final_dbr_type; /* final field type as seen by database request */ ELLLIST filters; /* list of filters as created from JSON */ ELLLIST pre_chain; /* list of filters to be called pre-event-queue */ ELLLIST post_chain; /* list of filters to be called post-event-queue */ @@ -186,7 +185,7 @@ epicsShareFunc long dbChannelOpen(dbChannel *chan); #define dbChannelFinalFieldType(pChan) ((pChan)->final_type) /* evaluates to short */ -#define dbChannelFinalExportType(pChan) ((pChan)->final_dbr_type) +#define dbChannelFinalExportType(pChan) ((pChan)->final_type) /* evaluates to short */ #define dbChannelFinalFieldSize(pChan) ((pChan)->final_field_size) diff --git a/src/ioc/db/db_access.c b/src/ioc/db/db_access.c index 30bbbbec4..c399fdb88 100644 --- a/src/ioc/db/db_access.c +++ b/src/ioc/db/db_access.c @@ -119,13 +119,14 @@ struct dbChannel * dbChannel_create(const char *pname) return NULL; } - chan->addr.dbr_field_type = dbDBRnewToDBRold[ftype]; - if (dbChannelOpen(chan)) { dbChannelDelete(chan); return NULL; } + /* Convert final_type to CA's type mapping */ + chan->final_type = dbDBRnewToDBRold[chan->final_type]; + return chan; } diff --git a/src/ioc/db/test/dbChannelTest.c b/src/ioc/db/test/dbChannelTest.c index 75d3185aa..a509e74c9 100644 --- a/src/ioc/db/test/dbChannelTest.c +++ b/src/ioc/db/test/dbChannelTest.c @@ -156,7 +156,7 @@ MAIN(testDbChannel) /* dbChannelTest is an API routine... */ { dbChannel *pch; - testPlan(66); + testPlan(76); if (dbReadDatabase(&pdbbase, "dbTestIoc.dbd", "." OSI_PATH_LIST_SEPARATOR ".." OSI_PATH_LIST_SEPARATOR @@ -173,6 +173,7 @@ MAIN(testDbChannel) /* dbChannelTest is an API routine... */ r = e = 0; /* dbChannelTest() checks record and field names */ testOk1(!dbChannelTest("x.NAME")); + testOk1(!dbChannelTest("x.INP")); testOk1(!dbChannelTest("x.VAL")); testOk1(!dbChannelTest("x.")); testOk1(!dbChannelTest("x")); @@ -188,12 +189,22 @@ MAIN(testDbChannel) /* dbChannelTest is an API routine... */ testOk1(!!(pch = dbChannelCreate("x.{}"))); if (pch) dbChannelDelete(pch); testOk1(!!(pch = dbChannelCreate("x.VAL{}"))); + testOk1(pch && dbChannelElements(pch) == 1); if (pch) dbChannelDelete(pch); testOk1(!!(pch = dbChannelCreate("x.NAME$"))); - testOk1(pch && pch->addr.no_elements > 1); + testOk1(pch && dbChannelFieldType(pch) == DBF_CHAR); + testOk1(pch && dbChannelExportType(pch) == DBR_CHAR); + testOk1(pch && dbChannelElements(pch) == PVNAME_STRINGSZ); + if (pch) dbChannelDelete(pch); + testOk1(!!(pch = dbChannelCreate("x.INP$"))); + testOk1(pch && dbChannelFieldType(pch) == DBF_INLINK); + testOk1(pch && dbChannelExportType(pch) == DBR_CHAR); + testOk1(pch && dbChannelElements(pch) > PVNAME_STRINGSZ); if (pch) dbChannelDelete(pch); testOk1(!!(pch = dbChannelCreate("x.NAME${}"))); - testOk1(pch && pch->addr.no_elements > 1); + testOk1(pch && dbChannelFieldType(pch) == DBF_CHAR); + testOk1(pch && dbChannelExportType(pch) == DBR_CHAR); + testOk1(pch && dbChannelElements(pch) == PVNAME_STRINGSZ); if (pch) dbChannelDelete(pch); /* dbChannelCreate() rejects bad PVs */