diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 33f12c441..d19664ea1 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -16,6 +16,14 @@ +
Changing from numeric to named soft events introduced an incompatibility +when a numeric event 1-255 is converted from a DOUBLE, e.g. from a calc record. +The post_event() API is not marked deprecated any more. + +
Also scanpel has been modified to accept a glob pattern for
+event name filtering and to show events with no connected records as well.
Added a new OS-independent typedef for multicast socket options, and a test
diff --git a/src/ioc/db/dbScan.c b/src/ioc/db/dbScan.c
index e0c48d4c3..e9dc178a2 100644
--- a/src/ioc/db/dbScan.c
+++ b/src/ioc/db/dbScan.c
@@ -111,8 +111,8 @@ static char *priorityName[NUM_CALLBACK_PRIORITIES] = {
typedef struct event_list {
CALLBACK callback[NUM_CALLBACK_PRIORITIES];
scan_list scan_list[NUM_CALLBACK_PRIORITIES];
- struct event_list *next;
- char event_name[MAX_STRING_SIZE];
+ struct event_list *next;
+ char eventname[1]; /* actually arbitrary size */
} event_list;
static event_list * volatile pevent_list[256];
static epicsMutexId event_lock;
@@ -249,11 +249,6 @@ void scanAdd(struct dbCommon *precord)
event_list *pel;
eventname = precord->evnt;
- if (strlen(eventname) >= MAX_STRING_SIZE) {
- recGblRecordError(S_db_badField, (void *)precord,
- "scanAdd: too long EVNT value");
- return;
- }
prio = precord->prio;
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
recGblRecordError(-1, (void *)precord,
@@ -317,24 +312,17 @@ void scanDelete(struct dbCommon *precord)
recGblRecordError(-1, (void *)precord,
"scanDelete detected illegal SCAN value");
} else if (scan == menuScanEvent) {
- char* eventname;
int prio;
event_list *pel;
scan_list *psl = 0;
- eventname = precord->evnt;
prio = precord->prio;
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
recGblRecordError(-1, (void *)precord,
"scanDelete detected illegal PRIO field");
return;
}
- do /* multithreading: make sure pel is consistent */
- pel = pevent_list[0];
- while (pel != pevent_list[0]);
- for (; pel; pel=pel->next) {
- if (strcmp(pel->event_name, eventname) == 0) break;
- }
+ pel = eventNameToHandle(precord->evnt);
if (pel && (psl = &pel->scan_list[prio]))
deleteFromList(precord, psl);
} else if (scan == menuScanI_O_Intr) {
@@ -422,14 +410,12 @@ int scanpel(const char* eventname) /* print event list */
int prio;
event_list *pel;
- do /* multithreading: make sure pel is consistent */
- pel = pevent_list[0];
- while (pel != pevent_list[0]);
- for (; pel; pel = pel->next) {
- if (!eventname || strcmp(pel->event_name, eventname) == 0) {
+ for (pel = pevent_list[0]; pel; pel = pel->next) {
+ if (!eventname || epicsStrGlobMatch(pel->eventname, eventname)) {
+ printf("Event \"%s\"\n", pel->eventname);
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
if (ellCount(&pel->scan_list[prio].list) == 0) continue;
- sprintf(message, "Event \"%s\" Priority %s", pel->event_name, priorityName[prio]);
+ sprintf(message, " Priority %s", priorityName[prio]);
printList(&pel->scan_list[prio], message);
}
}
@@ -480,18 +466,51 @@ event_list *eventNameToHandle(const char *eventname)
int prio;
event_list *pel;
static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT;
+ double eventnumber = 0;
+ size_t namelength;
- if (!eventname || eventname[0] == 0)
- return NULL;
+ if (!eventname) return NULL;
+ while (isspace((unsigned char)eventname[0])) eventname++;
+ if (!eventname[0]) return NULL;
+ namelength = strlen(eventname);
+ while (isspace((unsigned char)eventname[namelength-1])) namelength--;
+
+ /* Backward compatibility with numeric events:
+ Treat any string that represents a double with an
+ integer part between 0 and 255 the same as the integer
+ because it is most probably a conversion from double
+ like from a calc record.
+ */
+ if (epicsParseDouble(eventname, &eventnumber, NULL) == 0)
+ {
+ if (eventnumber >= 0 && eventnumber < 256)
+ {
+ if (eventnumber < 1)
+ return NULL; /* 0 is no event */
+ if ((pel = pevent_list[(int)eventnumber]) != NULL)
+ return pel;
+ }
+ else
+ eventnumber = 0; /* not a numeric event between 1 and 255 */
+ }
epicsThreadOnce(&onceId, eventOnce, NULL);
epicsMutexMustLock(event_lock);
for (pel = pevent_list[0]; pel; pel=pel->next) {
- if (strcmp(pel->event_name, eventname) == 0) break;
+ if (strncmp(pel->eventname, eventname, namelength) == 0
+ && pel->eventname[namelength] == 0)
+ break;
}
if (pel == NULL) {
- pel = dbCalloc(1, sizeof(event_list));
- strcpy(pel->event_name, eventname);
+ pel = dbCalloc(1, sizeof(event_list) + namelength);
+ if (eventnumber > 0)
+ {
+ /* backward compatibility: make all numeric events look like integers */
+ sprintf(pel->eventname, "%i", (int)eventnumber);
+ pevent_list[(int)eventnumber] = pel;
+ }
+ else
+ strncpy(pel->eventname, eventname, namelength);
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]);
callbackSetPriority(prio, &pel->callback[prio]);
@@ -501,12 +520,6 @@ event_list *eventNameToHandle(const char *eventname)
}
pel->next=pevent_list[0];
pevent_list[0]=pel;
- { /* backward compatibility */
- char* p;
- long e = strtol(eventname, &p, 0);
- if (*p == 0 && e > 0 && e <= 255)
- pevent_list[e] = pel;
- }
}
epicsMutexUnlock(event_lock);
return pel;
@@ -527,13 +540,8 @@ void postEvent(event_list *pel)
/* backward compatibility */
void post_event(int event)
{
- event_list* pel;
-
if (event <= 0 || event > 255) return;
- do { /* multithreading: make sure pel is consistent */
- pel = pevent_list[event];
- } while (pel != pevent_list[event]);
- postEvent(pel);
+ postEvent(pevent_list[event]);
}
static void ioscanOnce(void *arg)
diff --git a/src/ioc/db/dbScan.h b/src/ioc/db/dbScan.h
index 28d2e133d..d3102712d 100644
--- a/src/ioc/db/dbScan.h
+++ b/src/ioc/db/dbScan.h
@@ -50,7 +50,7 @@ epicsShareFunc void scanCleanup(void);
epicsShareFunc EVENTPVT eventNameToHandle(const char* event);
epicsShareFunc void postEvent(EVENTPVT epvt);
-epicsShareFunc void post_event(int event) EPICS_DEPRECATED;
+epicsShareFunc void post_event(int event);
epicsShareFunc void scanAdd(struct dbCommon *);
epicsShareFunc void scanDelete(struct dbCommon *);
epicsShareFunc double scanPeriod(int scan);
diff --git a/src/std/rec/test/Makefile b/src/std/rec/test/Makefile
index 5322c8e92..70b6e173e 100644
--- a/src/std/rec/test/Makefile
+++ b/src/std/rec/test/Makefile
@@ -37,6 +37,15 @@ testHarness_SRCS += analogMonitorTest_registerRecordDeviceDriver.cpp
TESTFILES += $(COMMON_DIR)/analogMonitorTest.dbd ../analogMonitorTest.db
TESTS += analogMonitorTest
+TARGETS += $(COMMON_DIR)/scanEventTest.dbd
+DBDDEPENDS_FILES += scanEventTest.dbd$(DEP)
+scanEventTest_DBD += base.dbd
+TESTPROD_HOST += scanEventTest
+scanEventTest_SRCS += scanEventTest.c
+scanEventTest_SRCS += scanEventTest_registerRecordDeviceDriver.cpp
+TESTFILES += $(COMMON_DIR)/scanEventTest.dbd ../scanEventTest.db
+TESTS += scanEventTest
+
TARGETS += $(COMMON_DIR)/regressTest.dbd
DBDDEPENDS_FILES += regressTest.dbd$(DEP)
regressTest_DBD += base.dbd
diff --git a/src/std/rec/test/epicsRunRecordTests.c b/src/std/rec/test/epicsRunRecordTests.c
index 092c0a6ce..1a7133c19 100644
--- a/src/std/rec/test/epicsRunRecordTests.c
+++ b/src/std/rec/test/epicsRunRecordTests.c
@@ -14,6 +14,7 @@
int analogMonitorTest(void);
int arrayOpTest(void);
+int scanEventTest(void);
void epicsRunRecordTests(void)
{
@@ -22,6 +23,7 @@ void epicsRunRecordTests(void)
runTest(analogMonitorTest);
runTest(arrayOpTest);
+ runTest(scanEventTest);
epicsExit(0); /* Trigger test harness */
}
diff --git a/src/std/rec/test/scanEventTest.c b/src/std/rec/test/scanEventTest.c
new file mode 100644
index 000000000..77acbbeca
--- /dev/null
+++ b/src/std/rec/test/scanEventTest.c
@@ -0,0 +1,142 @@
+/*************************************************************************\
+* Copyright (c) 2018 Paul Scherrer Institut
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+ \*************************************************************************/
+
+/*
+ * Author: Dirk Zimoch