From a447ed8bd03d0271f9c20409772587d1e4f08ac9 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 16 Jul 2018 15:49:10 -0500 Subject: [PATCH 1/4] Merged Dirk Zimoch's info_fields branch into 3.16 Used --squash to drop noisy history. Modified the dbli output format slightly. --- documentation/RELEASE_NOTES.html | 8 ++++++++ src/ioc/db/dbIocRegister.c | 7 +++++++ src/ioc/db/dbTest.c | 23 +++++++++++++++++++++++ src/ioc/db/dbTest.h | 2 ++ src/ioc/db/test/dbStaticTest.db | 2 +- src/ioc/dbStatic/dbStaticLib.c | 26 ++++++++++++++++++++++++++ src/ioc/dbStatic/dbStaticLib.h | 2 ++ 7 files changed, 69 insertions(+), 1 deletion(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index e00ccb08c..e82180c74 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -19,6 +19,14 @@ --> +

Finding info fields

+ +

A new iocsh command dbli lists the info fields defined in the +database, and can take a glob pattern to limit output to specific info names. +The newly added dbStaticLib function dbNextMatchingInfo() iterates +through the info fields defined in the current record, and is used to implement +the new command.

+

Output from dbpr command enhanced

The "DataBase Print Record" command dbpr now generates slightly diff --git a/src/ioc/db/dbIocRegister.c b/src/ioc/db/dbIocRegister.c index 07c9836c2..4d0b88cd9 100644 --- a/src/ioc/db/dbIocRegister.c +++ b/src/ioc/db/dbIocRegister.c @@ -152,6 +152,12 @@ static const iocshArg * const dbnrArgs[1] = {&dbnrArg0}; static const iocshFuncDef dbnrFuncDef = {"dbnr",1,dbnrArgs}; static void dbnrCallFunc(const iocshArgBuf *args) { dbnr(args[0].ival);} +/* dbli */ +static const iocshArg dbliArg0 = { "pattern",iocshArgString}; +static const iocshArg * const dbliArgs[1] = {&dbliArg0}; +static const iocshFuncDef dbliFuncDef = {"dbli",1,dbliArgs}; +static void dbliCallFunc(const iocshArgBuf *args) { dbli(args[0].sval);} + /* dbla */ static const iocshArg dblaArg0 = { "pattern",iocshArgString}; static const iocshArg * const dblaArgs[1] = {&dblaArg0}; @@ -415,6 +421,7 @@ void dbIocRegister(void) iocshRegister(&dblFuncDef,dblCallFunc); iocshRegister(&dbnrFuncDef,dbnrCallFunc); iocshRegister(&dblaFuncDef,dblaCallFunc); + iocshRegister(&dbliFuncDef,dbliCallFunc); iocshRegister(&dbgrepFuncDef,dbgrepCallFunc); iocshRegister(&dbgfFuncDef,dbgfCallFunc); iocshRegister(&dbpfFuncDef,dbpfCallFunc); diff --git a/src/ioc/db/dbTest.c b/src/ioc/db/dbTest.c index cb9963ef3..0daafc436 100644 --- a/src/ioc/db/dbTest.c +++ b/src/ioc/db/dbTest.c @@ -258,7 +258,30 @@ long dbla(const char *pmask) dbFinishEntry(pdbentry); return 0; } + +long dbli(const char *pattern) +{ + DBENTRY dbentry; + void* ptr; + if (!pdbbase) { + printf("No database loaded\n"); + return 0; + } + + dbInitEntry(pdbbase, &dbentry); + while (dbNextMatchingInfo(&dbentry, pattern) == 0) + { + printf("%s info(%s, \"%s\"", dbGetRecordName(&dbentry), + dbGetInfoName(&dbentry), dbGetInfoString(&dbentry)); + if ((ptr = dbGetInfoPointer(&dbentry)) != NULL) + printf(", %p", ptr); + printf(")\n"); + } + dbFinishEntry(&dbentry); + return 0; +} + long dbgrep(const char *pmask) { DBENTRY dbentry; diff --git a/src/ioc/db/dbTest.h b/src/ioc/db/dbTest.h index 6d457b59e..a4d90e2ad 100644 --- a/src/ioc/db/dbTest.h +++ b/src/ioc/db/dbTest.h @@ -25,6 +25,8 @@ epicsShareFunc long dbl( epicsShareFunc long dbnr(int verbose); /* list aliases */ epicsShareFunc long dbla(const char *pmask); +/* list infos */ +epicsShareFunc long dbli(const char *patern); /*list records with mask*/ epicsShareFunc long dbgrep(const char *pmask); /*get field value*/ diff --git a/src/ioc/db/test/dbStaticTest.db b/src/ioc/db/test/dbStaticTest.db index c35ff9a91..63036727f 100644 --- a/src/ioc/db/test/dbStaticTest.db +++ b/src/ioc/db/test/dbStaticTest.db @@ -1,7 +1,7 @@ record(x, "testrec") { - info("A", "B") alias("testalias") + info("A", "B") } alias("testrec", "testalias2") diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c index 4135d7f3a..a43b49e51 100644 --- a/src/ioc/dbStatic/dbStaticLib.c +++ b/src/ioc/dbStatic/dbStaticLib.c @@ -2716,6 +2716,32 @@ long dbNextInfo(DBENTRY *pdbentry) return (pinfo ? 0 : S_dbLib_infoNotFound); } +long dbNextMatchingInfo(DBENTRY *pdbentry, const char *pattern) +{ + long status; + + if (!pdbentry->precordType) + { + status = dbFirstRecordType(pdbentry); + goto first; + } + while(1) { + status = dbNextInfo(pdbentry); + while (status) { + status = dbNextRecord(pdbentry); + while (status) { + status = dbNextRecordType(pdbentry); +first: + if (status) return status; + status = dbFirstRecord(pdbentry); + } + status = dbFirstInfo(pdbentry); + } + if (!pattern || !*pattern) return 0; + if (epicsStrGlobMatch(dbGetInfoName(pdbentry), pattern)) return 0; + } +} + long dbFindInfo(DBENTRY *pdbentry,const char *name) { dbRecordNode *precnode = pdbentry->precnode; diff --git a/src/ioc/dbStatic/dbStaticLib.h b/src/ioc/dbStatic/dbStaticLib.h index b2f4a02ae..92b32d94c 100644 --- a/src/ioc/dbStatic/dbStaticLib.h +++ b/src/ioc/dbStatic/dbStaticLib.h @@ -188,6 +188,8 @@ epicsShareFunc long dbFirstInfo(DBENTRY *pdbentry); epicsShareFunc long dbNextInfo(DBENTRY *pdbentry); epicsShareFunc long dbFindInfo(DBENTRY *pdbentry, const char *name); +epicsShareFunc long dbNextMatchingInfo(DBENTRY *pdbentry, + const char *pattern); epicsShareFunc long dbDeleteInfo(DBENTRY *pdbentry); epicsShareFunc const char * dbGetInfoName(DBENTRY *pdbentry); epicsShareFunc const char * dbGetInfoString(DBENTRY *pdbentry); From fe4b5d7d72bfc3dc691dd24d720a514f1659fbe1 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 19 Jul 2018 01:08:12 -0500 Subject: [PATCH 2/4] Fix for lp: #1743795 LIFO Mode --- src/std/rec/compressRecord.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/std/rec/compressRecord.c b/src/std/rec/compressRecord.c index 4b4de5f15..3cad58b80 100644 --- a/src/std/rec/compressRecord.c +++ b/src/std/rec/compressRecord.c @@ -120,13 +120,13 @@ static void put_value(compressRecord *prec, double *psource, int n) nuse = nsam; while (n--) { - /* for LIFO, decrement before */ + /* for LIFO, pre-decrement modulo nsam */ if (!fifo) - offset = (offset - 1) % nsam; + offset = (offset + nsam - 1) % nsam; prec->bptr[offset] = *psource++; - /* for FIFO, increment after */ + /* for FIFO, post-increment modulo nsam */ if (fifo) offset = (offset + 1) % nsam; } From 27431facb83fbc70381dc4c77d734884a6c62efa Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 19 Jul 2018 01:09:40 -0500 Subject: [PATCH 3/4] Fix for lp: #1743795 FIFO Mode --- src/std/rec/compressRecord.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/std/rec/compressRecord.c b/src/std/rec/compressRecord.c index 3cad58b80..b123dcf09 100644 --- a/src/std/rec/compressRecord.c +++ b/src/std/rec/compressRecord.c @@ -424,15 +424,15 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) compressRecord *prec = (compressRecord *) paddr->precord; epicsUInt32 off = prec->off; epicsUInt32 nuse = prec->nuse; - epicsUInt32 nsam = prec->nsam; - *no_elements = nuse; if (prec->balg == bufferingALG_FIFO) { - *offset = (off - nuse) % nsam; - } else { - *offset = off; + epicsUInt32 nsam = prec->nsam; + + off = (off + nsam - nuse) % nsam; } + *no_elements = nuse; + *offset = off; return 0; } From 1ffd30c6d4784a8337f8623a277e074552d27da6 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sat, 4 Aug 2018 12:58:30 -0500 Subject: [PATCH 4/4] Add dbLinkFieldName() API to dbLink.h for error messages Returns a pointer to the field name of the plink field. Was previously an internal routine with a different name. --- src/ioc/db/dbLink.c | 4 ++-- src/ioc/db/dbLink.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ioc/db/dbLink.c b/src/ioc/db/dbLink.c index c90dcb3df..f87a3eb09 100644 --- a/src/ioc/db/dbLink.c +++ b/src/ioc/db/dbLink.c @@ -49,7 +49,7 @@ #include "special.h" /* How to identify links in error messages */ -static const char * link_field_name(const struct link *plink) +const char * dbLinkFieldName(const struct link *plink) { const struct dbCommon *precord = plink->precord; const dbRecordType *pdbRecordType = precord->rdes; @@ -136,7 +136,7 @@ void dbInitLink(struct link *plink, short dbfType) errlogPrintf("Forward-link uses Channel Access " "without pointing to PROC field\n" " %s.%s => %s\n", - precord->name, link_field_name(plink), + precord->name, dbLinkFieldName(plink), plink->value.pv_link.pvname); } } diff --git a/src/ioc/db/dbLink.h b/src/ioc/db/dbLink.h index ad4ac2f45..1fa80411a 100644 --- a/src/ioc/db/dbLink.h +++ b/src/ioc/db/dbLink.h @@ -81,6 +81,8 @@ typedef struct lset { #define dbGetSevr(link, sevr) \ dbGetAlarm(link, NULL, sevr) +epicsShareFunc const char * dbLinkFieldName(const struct link *plink); + epicsShareFunc void dbInitLink(struct link *plink, short dbfType); epicsShareFunc void dbAddLink(struct dbLocker *locker, struct link *plink, short dbfType, DBADDR *ptarget);