Merge 3.16 (after 3.16.2-rc1) into 7.0

This commit is contained in:
Andrew Johnson
2018-10-26 17:04:53 -05:00
157 changed files with 5520 additions and 1623 deletions
+11 -20
View File
@@ -2241,7 +2241,7 @@ long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec)
if(!plink->text)
continue;
if(dbParseLink(plink->text, pflddes->field_type, &link_info, 0)!=0) {
if(dbParseLink(plink->text, pflddes->field_type, &link_info)!=0) {
/* This was already parsed once when ->text was set.
* Any syntax error messages were printed at that time.
*/
@@ -2270,7 +2270,7 @@ void dbFreeLinkInfo(dbLinkInfo *pinfo)
pinfo->target = NULL;
}
long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, unsigned opts)
long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
{
char *pstr;
size_t len;
@@ -2306,7 +2306,7 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, unsigned opts)
/* Check for braces => JSON */
if (*str == '{' && str[len-1] == '}') {
if (dbJLinkParse(str, len, ftype, &pinfo->jlink, opts))
if (dbJLinkParse(str, len, ftype, &pinfo->jlink))
goto fail;
pinfo->ltype = JSON_LINK;
@@ -2353,9 +2353,13 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, unsigned opts)
else if (strcmp(pinfo->hwid, "VS")==0) pinfo->ltype = VXI_IO;
else goto fail;
if (parm && pinfo->ltype != RF_IO) {
/* move parm string to beginning of buffer */
memmove(pinfo->target, parm, len + 1);
if (pinfo->ltype != RF_IO) {
if (!parm) {
pinfo->target[0] = '\0';
} else {
/* move parm string to beginning of buffer */
memmove(pinfo->target, parm, len + 1);
}
} else if (!parm && pinfo->ltype == RF_IO) {
/* RF_IO, the string isn't needed at all */
free(pinfo->target);
@@ -2641,21 +2645,8 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
case DBF_FWDLINK: {
dbLinkInfo link_info;
DBLINK *plink = (DBLINK *)pfield;
DBENTRY infoentry;
unsigned opts = 0;
if(pdbentry->precnode && ellCount(&pdbentry->precnode->infoList)) {
dbCopyEntryContents(pdbentry, &infoentry);
if(dbFindInfo(&infoentry, "base:lsetDebug")==0 && epicsStrCaseCmp(dbGetInfoString(&infoentry), "YES")==0)
opts |= LINK_DEBUG_LSET;
if(dbFindInfo(&infoentry, "base:jlinkDebug")==0 && epicsStrCaseCmp(dbGetInfoString(&infoentry), "YES")==0)
opts |= LINK_DEBUG_JPARSE;
dbFinishEntry(&infoentry);
}
status = dbParseLink(pstring, pflddes->field_type, &link_info, opts);
status = dbParseLink(pstring, pflddes->field_type, &link_info);
if (status) break;
if (plink->type==CONSTANT && plink->value.constantStr==NULL) {
@@ -5,7 +5,7 @@
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* dbStaticPvt.h */
/*
@@ -59,13 +59,10 @@ typedef struct dbLinkInfo {
long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec);
#define LINK_DEBUG_LSET 1
#define LINK_DEBUG_JPARSE 2
/* Parse link string. no record locks needed.
* on success caller must free pinfo->target
*/
epicsShareFunc long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, unsigned opts);
epicsShareFunc long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo);
/* Check if link type allow the parsed link value pinfo
* to be assigned to the given link.
* Record containing plink must be locked.
+121 -6
View File
@@ -6,7 +6,11 @@
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* devSup.h Device Support */
/** @file devSup.h
*
* @brief Device support routines
*/
/*
* Author: Marty Kraimer
* Date: 6-1-90
@@ -21,6 +25,111 @@
/* structures defined elsewhere */
struct dbCommon;
struct devSup;
typedef struct ioscan_head *IOSCANPVT;
struct link; /* aka DBLINK */
/** Type safe version of 'struct dset'
*
* Recommended usage:
*
* In Makefile:
@code
USR_CFLAGS += -DUSE_TYPED_RSET -DUSE_TYPED_DSET
@endcode
*
* In C source file:
@code
#include <devSup.h>
#include <dbScan.h> // For IOCSCANPVT
...
#include <epicsExport.h> // defines epicsExportSharedSymbols
...
static long init_record(dbCommon *prec);
static long get_iointr_info(int detach, dbCommon *prec, IOCSCANPVT* pscan);
static long longin_read(longinRecord *prec);
const struct {
dset common;
long (*read)(longinRecord *prec);
} devLiDevName = {
{
5, // 4 from dset + 1 from longinRecord
NULL,
NULL,
&init_record,
&get_iointr_info
},
&longin_read
};
epicsExportAddress(dset, devLiDevName);
@endcode
*/
typedef struct typed_dset {
/** Number of function pointers which follow.
* The value depends on the recordtype, but must be >=4 */
long number;
/** Called from dbior() */
long (*report)(int lvl);
/** Called twice during iocInit().
* First with @a after = 0 before init_record() or array field allocation.
* Again with @a after = 1 after init_record() has finished.
*/
long (*init)(int after);
/** Called once per record instance */
long (*init_record)(struct dbCommon *prec);
/** Called when SCAN="I/O Intr" on startup, or after SCAN is changed.
*
* Caller must assign the third arguement (IOCSCANPVT*). eg.
@code
struct mpvt {
IOSCANPVT drvlist;
};
...
// init_record() routine calls
scanIoInit(&pvt->drvlist);
...
static long get_ioint_info(int detach, struct dbCommon *prec, IOCSCANPVT* pscan) {
if(prec->dpvt)
*pscan = &((mypvt*)prec->dpvt)->drvlist;
@endcode
*
* When a particular record instance can/will only used a single scan list,
* the @a detach argument can be ignored.
*
* If this is not the case, then the following should be noted.
* + get_ioint_info() is called with @a detach = 0 to fetch the scan list to
* which this record will be added.
* + get_ioint_info() is called later with @a detach = 1 to fetch the scan
* list from which this record should be removed.
* + Calls will be balanced, so a call with @a detach = 0 will be followed
* by one with @a detach = 1.
*
* @note get_ioint_info() will be called during IOC shutdown if the
* dsxt::del_record() extended callback is defined. (from 3.15.0.1)
*/
long (*get_ioint_info)(int detach, struct dbCommon *prec, IOSCANPVT* pscan);
/* Any further functions are specified by the record type. */
} typed_dset;
/** Device support extension table.
*
* Optional routines to allow run-time address modifications to be communicated
* to device support, which must register a struct dsxt by calling devExtend()
* from its init() routine.
*/
typedef struct dsxt {
/** Optional, called to offer device support a new record to control.
*
* Routine may return a non-zero error code to refuse record.
*/
long (*add_record)(struct dbCommon *precord);
/** Optional, called to remove record from device support control.
*
* Routine return a non-zero error code to refuse record removal.
*/
long (*del_record)(struct dbCommon *precord);
/* Only future Base releases may extend this table. */
} dsxt;
#ifdef __cplusplus
extern "C" {
@@ -29,6 +138,8 @@ extern "C" {
typedef long (*DEVSUPFUN)(); /* ptr to device support function*/
#endif
#ifndef USE_TYPED_DSET
typedef struct dset { /* device support entry table */
long number; /*number of support routines*/
DEVSUPFUN report; /*print report*/
@@ -38,11 +149,15 @@ typedef struct dset { /* device support entry table */
/*other functions are record dependent*/
} dset;
typedef struct dsxt { /* device support extension table */
long (*add_record)(struct dbCommon *precord);
long (*del_record)(struct dbCommon *precord);
/* Recordtypes are *not* allowed to extend this table */
} dsxt;
#else
typedef typed_dset dset;
#endif /* USE_TYPED_DSET */
/** Fetch INP or OUT link (or NULL if record type has neither).
*
* Recommended for use in device support init_record()
*/
epicsShareFunc struct link* dbGetDevLink(struct dbCommon* prec);
epicsShareExtern dsxt devSoft_DSXT; /* Allow anything table */
+33 -8
View File
@@ -6,7 +6,10 @@
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* drvSup.h Driver Support */
/** @file drvSup.h
*
* @brief Driver support routines.
*/
/*
* Author: Marty Kraimer
@@ -18,16 +21,38 @@
#include "errMdef.h"
typedef long (*DRVSUPFUN) (); /* ptr to driver support function*/
/** Driver entry table */
typedef struct typed_drvet {
/** Number of function pointers which follow. Must be >=2 */
long number;
/** Called from dbior() */
long (*report)(int lvl);
/** Called during iocInit() */
long (*init)(void);
/* Any further functions are driver-specific */
} typed_drvet;
#ifdef USE_TYPED_DRVET
typedef typed_drvet drvet;
#else
/* These interfaces may eventually get deprecated */
typedef long (*DRVSUPFUN) (); /* ptr to driver support function */
typedef struct drvet { /* driver entry table */
long number; /* number of support routines */
DRVSUPFUN report; /* print report */
DRVSUPFUN init; /* init support */
/* Any further functions are driver-specific */
} drvet;
typedef struct drvet { /* driver entry table */
long number; /*number of support routines*/
DRVSUPFUN report; /*print report*/
DRVSUPFUN init; /*init support*/
/*other functions are device dependent*/
}drvet;
#define DRVETNUMBER ( (sizeof(struct drvet) -sizeof(long))/sizeof(DRVSUPFUN) )
#endif /* USE_TYPED_DRVET */
#define S_drv_noDrvSup (M_drvSup| 1) /*SDR_DRVSUP: Driver support missing*/
#define S_drv_noDrvet (M_drvSup| 3) /*Missing driver support entry table*/