Date: Fri, 20 Jul 2018 23:10:34 -0500
Subject: [PATCH 24/55] Fix for lp: #1730727
Post monitors on all array-length record fields (often NORD)
when their values get changed.
---
documentation/RELEASE_NOTES.html | 8 +++++++
src/std/dev/devAaiSoft.c | 9 ++++++--
src/std/dev/devSASoft.c | 5 ++++-
src/std/dev/devWfSoft.c | 7 ++++++-
src/std/rec/aaiRecord.c | 36 +++++++++++++++++++++-----------
src/std/rec/aaoRecord.c | 11 ++++++----
src/std/rec/compressRecord.c | 8 +++++--
src/std/rec/subArrayRecord.c | 18 +++++++++-------
src/std/rec/waveformRecord.c | 26 ++++++++++++-----------
9 files changed, 86 insertions(+), 42 deletions(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 59cd4ce18..8e902238b 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -16,6 +16,14 @@
+All array records now post monitors on their array-length fields
+
+The waveform record has been posting monitors on its NORD field since Base
+3.15.0.1; we finally got around to doing the equivalent in all the other
+built-in record types, which even required modifying device support in some
+cases. This fixes
+Launchpad bug #1730727.
+
HOWTO: Converting Wiki Record Reference to POD
Some documentation has been added to the dbdToHtml.pl script
diff --git a/src/std/dev/devAaiSoft.c b/src/std/dev/devAaiSoft.c
index 586483c92..4aa1f4cc3 100644
--- a/src/std/dev/devAaiSoft.c
+++ b/src/std/dev/devAaiSoft.c
@@ -4,7 +4,7 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is 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.
\*************************************************************************/
/*
@@ -71,13 +71,18 @@ static long init_record(aaiRecord *prec)
static long read_aai(aaiRecord *prec)
{
+ epicsUInt32 nord = prec->nord;
long nRequest = prec->nelm;
dbGetLink(prec->simm == menuYesNoYES ? &prec->siol : &prec->inp,
prec->ftvl, prec->bptr, 0, &nRequest);
+
if (nRequest > 0) {
prec->nord = nRequest;
- prec->udf=FALSE;
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
+
+ prec->udf = FALSE;
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
dbGetTimeStamp(&prec->inp, &prec->time);
diff --git a/src/std/dev/devSASoft.c b/src/std/dev/devSASoft.c
index 6c0c876f0..5f5d8189f 100644
--- a/src/std/dev/devSASoft.c
+++ b/src/std/dev/devSASoft.c
@@ -4,7 +4,7 @@
* Copyright (c) 2002 Lawrence Berkeley Laboratory,The Control Systems
* Group, Systems Engineering Department
* EPICS BASE is 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.
\*************************************************************************/
/*
@@ -67,6 +67,7 @@ static long init_record(subArrayRecord *prec)
static long read_sa(subArrayRecord *prec)
{
long nRequest = prec->indx + prec->nelm;
+ epicsUInt32 nord = prec->nord;
long ecount;
if (nRequest > prec->malm)
@@ -89,6 +90,8 @@ static long read_sa(subArrayRecord *prec)
ecount = 0;
prec->nord = ecount;
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
if (nRequest > 0 &&
prec->tsel.type == CONSTANT &&
diff --git a/src/std/dev/devWfSoft.c b/src/std/dev/devWfSoft.c
index f1754f78e..0d58c5f52 100644
--- a/src/std/dev/devWfSoft.c
+++ b/src/std/dev/devWfSoft.c
@@ -4,7 +4,7 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is 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.
\*************************************************************************/
/*
@@ -67,11 +67,16 @@ static long init_record(waveformRecord *prec)
static long read_wf(waveformRecord *prec)
{
+ epicsUInt32 nord = prec->nord;
long nRequest = prec->nelm;
dbGetLink(&prec->inp, prec->ftvl, prec->bptr, 0, &nRequest);
+
if (nRequest > 0) {
prec->nord = nRequest;
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
+
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
dbGetTimeStamp(&prec->inp, &prec->time);
diff --git a/src/std/rec/aaiRecord.c b/src/std/rec/aaiRecord.c
index 5b370fe4c..088777b30 100644
--- a/src/std/rec/aaiRecord.c
+++ b/src/std/rec/aaiRecord.c
@@ -2,7 +2,7 @@
* Copyright (c) 2002 Southeastern Universities Research Association, as
* Operator of Thomas Jefferson National Accelerator Facility.
* EPICS BASE is 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.
\*************************************************************************/
/* recAai.c */
@@ -11,7 +11,7 @@
* Original Author: Dave Barker
*
* C E B A F
- *
+ *
* Continuous Electron Beam Accelerator Facility
* Newport News, Virginia, USA.
*
@@ -139,12 +139,12 @@ static long init_record(aaiRecord *prec, int pass)
}
return 0;
}
-
+
/* SIML must be a CONSTANT or a PV_LINK or a DB_LINK */
if (prec->siml.type == CONSTANT) {
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
}
-
+
/* must have read_aai function defined */
if (pdset->number < 5 || pdset->read_aai == NULL) {
recGblRecordError(S_dev_missingSup, prec, "aai: init_record");
@@ -204,10 +204,14 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
static long put_array_info(DBADDR *paddr, long nNew)
{
aaiRecord *prec = (aaiRecord *)paddr->precord;
+ epicsUInt32 nord = prec->nord;
prec->nord = nNew;
if (prec->nord > prec->nelm)
prec->nord = prec->nelm;
+
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
return 0;
}
@@ -220,7 +224,7 @@ static long get_units(DBADDR *paddr, char *units)
switch (dbGetFieldIndex(paddr)) {
case indexof(VAL):
if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
- break;
+ break;
case indexof(HOPR):
case indexof(LOPR):
strncpy(units,prec->egu,DB_UNITS_SIZE);
@@ -314,12 +318,11 @@ static void monitor(aaiRecord *prec)
static long readValue(aaiRecord *prec)
{
- long status;
struct aaidset *pdset = (struct aaidset *)prec->dset;
+ long status;
if (prec->pact == TRUE){
- status = pdset->read_aai(prec);
- return status;
+ return pdset->read_aai(prec);
}
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
@@ -327,10 +330,16 @@ static long readValue(aaiRecord *prec)
return status;
if (prec->simm == menuYesNoNO){
- return pdset->read_aai(prec);
+ epicsUInt32 nord = prec->nord;
+
+ status = pdset->read_aai(prec);
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
+ return status;
}
-
+
if (prec->simm == menuYesNoYES){
+ epicsUInt32 nord = prec->nord;
/* Device suport is responsible for buffer
which might be read-only so we may not be
allowed to call dbGetLink on it.
@@ -339,10 +348,13 @@ static long readValue(aaiRecord *prec)
Thus call device now.
*/
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
- return pdset->read_aai(prec);
+
+ status = pdset->read_aai(prec);
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
+ return status;
}
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
return -1;
}
-
diff --git a/src/std/rec/aaoRecord.c b/src/std/rec/aaoRecord.c
index 565fd2886..d2d652b5e 100644
--- a/src/std/rec/aaoRecord.c
+++ b/src/std/rec/aaoRecord.c
@@ -2,7 +2,7 @@
* Copyright (c) 2002 Southeastern Universities Research Association, as
* Operator of Thomas Jefferson National Accelerator Facility.
* EPICS BASE is 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.
\*************************************************************************/
/* recAao.c */
@@ -11,7 +11,7 @@
* Original Author: Dave Barker
*
* C E B A F
- *
+ *
* Continuous Electron Beam Accelerator Facility
* Newport News, Virginia, USA.
*
@@ -204,10 +204,14 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
static long put_array_info(DBADDR *paddr, long nNew)
{
aaoRecord *prec = (aaoRecord *)paddr->precord;
+ epicsUInt32 nord = prec->nord;
prec->nord = nNew;
if (prec->nord > prec->nelm)
prec->nord = prec->nelm;
+
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
return 0;
}
@@ -220,7 +224,7 @@ static long get_units(DBADDR *paddr, char *units)
switch (dbGetFieldIndex(paddr)) {
case indexof(VAL):
if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
- break;
+ break;
case indexof(HOPR):
case indexof(LOPR):
strncpy(units,prec->egu,DB_UNITS_SIZE);
@@ -343,4 +347,3 @@ static long writeValue(aaoRecord *prec)
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
return -1;
}
-
diff --git a/src/std/rec/compressRecord.c b/src/std/rec/compressRecord.c
index fd99412e5..244f6f399 100644
--- a/src/std/rec/compressRecord.c
+++ b/src/std/rec/compressRecord.c
@@ -4,12 +4,12 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is 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.
\*************************************************************************/
/*
* Original Author: Bob Dalesio
- * Date: 7-14-89
+ * Date: 7-14-89
*/
#include
@@ -405,11 +405,15 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
static long put_array_info(DBADDR *paddr, long nNew)
{
compressRecord *prec = (compressRecord *) paddr->precord;
+ epicsUInt32 nuse = prec->nuse;
prec->off = (prec->off + nNew) % prec->nsam;
prec->nuse += nNew;
if (prec->nuse > prec->nsam)
prec->nuse = prec->nsam;
+
+ if (nuse != prec->nuse)
+ db_post_events(prec, &prec->nuse, DBE_VALUE | DBE_LOG);
return 0;
}
diff --git a/src/std/rec/subArrayRecord.c b/src/std/rec/subArrayRecord.c
index 197750b81..e480e9184 100644
--- a/src/std/rec/subArrayRecord.c
+++ b/src/std/rec/subArrayRecord.c
@@ -2,17 +2,17 @@
* Copyright (c) 2002 Lawrence Berkeley Laboratory,The Control Systems
* Group, Systems Engineering Department
* EPICS BASE is 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.
\*************************************************************************/
-/* recSubArray.c - Record Support Routines for SubArray records
+/* recSubArray.c - Record Support Routines for SubArray records
*
*
* Author: Carl Lionberger
* Date: 090293
*
* NOTES:
- * Derived from waveform record.
+ * Derived from waveform record.
* Modification Log:
* -----------------
*/
@@ -124,7 +124,7 @@ static long init_record(subArrayRecord *prec, int pass)
}
if (pdset->init_record)
- return (*pdset->init_record)(prec);
+ return pdset->init_record(prec);
return 0;
}
@@ -191,11 +191,14 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
static long put_array_info(DBADDR *paddr, long nNew)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
+ epicsUInt32 nord = prec->nord;
- if (nNew > prec->malm)
- nNew = prec->malm;
prec->nord = nNew;
+ if (prec->nord > prec->malm)
+ prec->nord = prec->malm;
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
return 0;
}
@@ -208,7 +211,7 @@ static long get_units(DBADDR *paddr, char *units)
switch (dbGetFieldIndex(paddr)) {
case indexof(VAL):
if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
- break;
+ break;
case indexof(HOPR):
case indexof(LOPR):
strncpy(units,prec->egu,DB_UNITS_SIZE);
@@ -318,4 +321,3 @@ static long readValue(subArrayRecord *prec)
return status;
}
-
diff --git a/src/std/rec/waveformRecord.c b/src/std/rec/waveformRecord.c
index ab00a39fd..c65d07964 100644
--- a/src/std/rec/waveformRecord.c
+++ b/src/std/rec/waveformRecord.c
@@ -4,7 +4,7 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is 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.
\*************************************************************************/
/* recWaveform.c - Record Support Routines for Waveform records */
@@ -184,12 +184,14 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
static long put_array_info(DBADDR *paddr, long nNew)
{
waveformRecord *prec = (waveformRecord *) paddr->precord;
+ epicsUInt32 nord = prec->nord;
prec->nord = nNew;
if (prec->nord > prec->nelm)
prec->nord = prec->nelm;
- db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
return 0;
}
@@ -202,7 +204,7 @@ static long get_units(DBADDR *paddr, char *units)
switch (dbGetFieldIndex(paddr)) {
case indexof(VAL):
if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
- break;
+ break;
case indexof(HOPR):
case indexof(LOPR):
strncpy(units,prec->egu,DB_UNITS_SIZE);
@@ -305,36 +307,37 @@ static void monitor(waveformRecord *prec)
static long readValue(waveformRecord *prec)
{
- long status;
struct wfdset *pdset = (struct wfdset *) prec->dset;
+ long status;
if (prec->pact == TRUE){
- return (*pdset->read_wf)(prec);
+ return pdset->read_wf(prec);
}
- status = dbGetLink(&(prec->siml), DBR_ENUM, &(prec->simm),0,0);
+ status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
if (status)
return status;
if (prec->simm == menuYesNoNO){
epicsUInt32 nord = prec->nord;
- status = (*pdset->read_wf)(prec);
+ status = pdset->read_wf(prec);
if (nord != prec->nord)
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
return status;
}
if (prec->simm == menuYesNoYES){
+ epicsUInt32 nord = prec->nord;
long nRequest = prec->nelm;
- status = dbGetLink(&(prec->siol), prec->ftvl, prec->bptr, 0, &nRequest);
- /* nord set only for db links: needed for old db_access */
+ status = dbGetLink(&prec->siol, prec->ftvl, prec->bptr, 0, &nRequest);
if (prec->siol.type != CONSTANT) {
prec->nord = nRequest;
- db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
+ if (nord != prec->nord)
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
if (status == 0)
- prec->udf=FALSE;
+ prec->udf = FALSE;
}
} else {
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
@@ -344,4 +347,3 @@ static long readValue(waveformRecord *prec)
return status;
}
-
From 45be2306bdf6d09fdc4c2af6ac0ad2e2d8f74d4a Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Sat, 21 Jul 2018 01:04:05 -0500
Subject: [PATCH 25/55] Add missing includes for db_post_events()
---
src/std/dev/devAaiSoft.c | 1 +
src/std/dev/devSASoft.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/std/dev/devAaiSoft.c b/src/std/dev/devAaiSoft.c
index 4aa1f4cc3..7a8ca9832 100644
--- a/src/std/dev/devAaiSoft.c
+++ b/src/std/dev/devAaiSoft.c
@@ -22,6 +22,7 @@
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
+#include "dbEvent.h"
#include "recGbl.h"
#include "devSup.h"
#include "cantProceed.h"
diff --git a/src/std/dev/devSASoft.c b/src/std/dev/devSASoft.c
index 5f5d8189f..a49b1bc49 100644
--- a/src/std/dev/devSASoft.c
+++ b/src/std/dev/devSASoft.c
@@ -19,6 +19,7 @@
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
+#include "dbEvent.h"
#include "recGbl.h"
#include "devSup.h"
#include "subArrayRecord.h"
From c09b6e2f1b34ea1925e8ff2678811b40bc23f5ca Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Sat, 21 Jul 2018 01:47:33 -0500
Subject: [PATCH 26/55] libCom: Add and use a -o option to e_flex
Note that like the -S option the filename must follow immediately in
the same command-line argument with no space.
---
configure/RULES_BUILD | 6 ++----
src/libCom/flex/flex.c | 11 +++++++++--
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD
index cec33eca7..1c38eef4c 100644
--- a/configure/RULES_BUILD
+++ b/configure/RULES_BUILD
@@ -256,15 +256,13 @@ YACCOPT ?= $($*_YACCOPT)
$(MV) $*.tab.c $*.c
$(if $(findstring -d, $(YACCOPT)),$(MV) $*.tab.h $*.h,)
-# must be a seperate rule since when not using '-d' the
+# must be a separate rule since when not using '-d' the
# prefix for .h will be different then .c
%.h : %.c %.y
%.c: %.l
- @$(RM) $*.yy.c
- $(LEX) $(LEXOPT) -t $< > $*.yy.c
@$(RM) $@
- $(MV) $*.yy.c $@
+ $(LEX) $(LEXOPT) -o$@ $<
#---------------------------------------------------------------
# Libraries, shared/DLL and stubs
diff --git a/src/libCom/flex/flex.c b/src/libCom/flex/flex.c
index 196f4e4cc..8d0400c2b 100644
--- a/src/libCom/flex/flex.c
+++ b/src/libCom/flex/flex.c
@@ -4,7 +4,7 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is 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.
\*************************************************************************/
/* flex - tool to generate fast lexical analyzers */
@@ -14,7 +14,7 @@
*
* This code is derived from software contributed to Berkeley by
* Vern Paxson.
- *
+ *
* The United States Government has rights in this work pursuant
* to contract no. DE-AC03-76SF00098 between the United States
* Department of Energy and the University of California.
@@ -495,6 +495,13 @@ void flexinit(int argc, char **argv)
/* stupid do-nothing deprecated option */
break;
+ case 'o':
+ if ( i != 1 )
+ flexerror( "-o flag must be given separately" );
+
+ outfile = arg + i + 1;
+ goto get_next_arg;
+
case 'p':
performance_report = true;
break;
From 67e2b74758982fd46be5529e28fcb93fd7eb59ad Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 25 Jul 2018 00:31:48 -0500
Subject: [PATCH 27/55] Fix for lp: #1503661
Delete output file if parse errors found in substitution file
---
src/ioc/dbtemplate/msi.c | 67 +++++++++++++++++++++++++++-------------
1 file changed, 45 insertions(+), 22 deletions(-)
diff --git a/src/ioc/dbtemplate/msi.c b/src/ioc/dbtemplate/msi.c
index 5a5023163..a29bb5fc0 100644
--- a/src/ioc/dbtemplate/msi.c
+++ b/src/ioc/dbtemplate/msi.c
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#define MAX_BUFFER_SIZE 4096
#define MAX_DEPS 1024
@@ -49,6 +50,7 @@ static char *substituteGetGlobalReplacements(subInfo *pvt);
/* Forward references to local routines */
static void usageExit(int status);
+static void abortExit(int status);
static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval);
static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *templateName);
@@ -182,7 +184,16 @@ void usageExit(int status)
exit(status);
}
-static void addMacroReplacements(MAC_HANDLE *macPvt,char *pval)
+void abortExit(int status)
+{
+ if (outFile) {
+ fclose(stdout);
+ unlink(outFile);
+ }
+ exit(status);
+}
+
+static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval)
{
char **pairs;
long status;
@@ -268,7 +279,7 @@ static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *tem
default:
fprintf(stderr,"msi: Logic error in makeSubstitutions\n");
inputErrPrint(inputPvt);
- exit(1);
+ abortExit(1);
}
free(copy);
expand = 0;
@@ -447,7 +458,7 @@ static void inputOpenFile(inputData *pinputData,char *filename)
if(!fp) {
fprintf(stderr,"msi: Can't open file '%s'\n",filename);
inputErrPrint(pinputData);
- exit(1);
+ abortExit(1);
}
pinputFile = calloc(1,sizeof(inputFile));
if(ppathNode) {
@@ -592,7 +603,7 @@ static void substituteOpen(subInfo **ppvt,char *substitutionName)
fp = fopen(substitutionName,"r");
if(!fp) {
fprintf(stderr,"msi: Can't open file '%s'\n",substitutionName);
- exit(1);
+ abortExit(1);
}
psubFile->substitutionName = substitutionName;
psubFile->fp = fp;
@@ -627,7 +638,7 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename)
psubInfo->isFile = 1;
if(subGetNextToken(psubFile)!=tokenString) {
subFileErrPrint(psubFile,"Parse error, expecting filename");
- exit(1);
+ abortExit(1);
}
freePattern(psubInfo);
free(psubInfo->filename);
@@ -641,25 +652,29 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename)
while(subGetNextToken(psubFile)==tokenSeparater);
if(psubFile->token!=tokenLBrace) {
subFileErrPrint(psubFile,"Parse error, expecting {");
- exit(1);
+ abortExit(1);
}
subGetNextToken(psubFile);
}
*filename = psubInfo->filename;
while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
if(psubFile->token==tokenLBrace) return(1);
- if(psubFile->token==tokenRBrace) return(1);
- if(psubFile->token!=tokenString
- || strcmp(psubFile->string,"pattern")!=0) {
- subFileErrPrint(psubFile,"Parse error, expecting pattern");
- exit(1);
+ if (psubFile->token == tokenRBrace) {
+ subFileErrPrint(psubFile, "Parse error, unexpected '}'");
+ abortExit(1);
+ }
+
+ if (psubFile->token != tokenString ||
+ strcmp(psubFile->string, "pattern") != 0) {
+ subFileErrPrint(psubFile, "Parse error, expecting 'pattern'");
+ abortExit(1);
}
freePattern(psubInfo);
psubInfo->isPattern = 1;
while(subGetNextToken(psubFile)==tokenSeparater);
if(psubFile->token!=tokenLBrace) {
subFileErrPrint(psubFile,"Parse error, expecting {");
- exit(1);
+ abortExit(1);
}
while(1) {
while(subGetNextToken(psubFile)==tokenSeparater);
@@ -670,7 +685,7 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename)
}
if(psubFile->token!=tokenRBrace) {
subFileErrPrint(psubFile,"Parse error, expecting }");
- exit(1);
+ abortExit(1);
}
subGetNextToken(psubFile);
return(1);
@@ -707,9 +722,13 @@ static char *substituteGetGlobalReplacements(subInfo *psubInfo)
case tokenString:
catMacroReplacements(psubInfo,psubFile->string);
break;
- default:
- subFileErrPrint(psubFile,"Parse error, illegal token");
- exit(1);
+
+ case tokenLBrace:
+ subFileErrPrint(psubFile, "Parse error, unexpected '{'");
+ abortExit(1);
+ case tokenEOF:
+ subFileErrPrint(psubFile, "Parse error, incomplete file?");
+ abortExit(1);
}
}
}
@@ -744,7 +763,7 @@ static char *substituteGetReplacements(subInfo *psubInfo)
}
if(psubFile->token!=tokenString) {
subFileErrPrint(psubFile,"Parse error, illegal token");
- exit(-1);
+ abortExit(1);
}
if(gotFirstPattern) catMacroReplacements(psubInfo,",");
gotFirstPattern = 1;
@@ -772,9 +791,13 @@ static char *substituteGetReplacements(subInfo *psubInfo)
case tokenString:
catMacroReplacements(psubInfo,psubFile->string);
break;
- default:
- subFileErrPrint(psubFile,"Parse error, illegal token");
- exit(1);
+
+ case tokenLBrace:
+ subFileErrPrint(psubFile, "Parse error, unexpected '{'");
+ abortExit(1);
+ case tokenEOF:
+ subFileErrPrint(psubFile, "Parse error, incomplete file?");
+ abortExit(1);
}
}
}
@@ -842,7 +865,7 @@ static tokenType subGetNextToken(subFile *psubFile)
while(*p!='"') {
if(*p==0 || *p=='\n') {
subFileErrPrint(psubFile,"Strings must be on single line\n");
- exit(1);
+ abortExit(1);
}
/*allow escape for imbeded quote*/
if((*p=='\\') && *(p+1)=='"') {
@@ -881,7 +904,7 @@ static void catMacroReplacements(subInfo *psubInfo,const char *value)
if(!newbuf) {
fprintf(stderr,"calloc failed for size %lu\n",
(unsigned long) newsize);
- exit(1);
+ abortExit(1);
}
if(psubInfo->macroReplacements) {
memcpy(newbuf,psubInfo->macroReplacements,psubInfo->curLength);
From fe7260e263da2e7df0e0d463a51ecd9b738ae78d Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 25 Jul 2018 00:47:18 -0500
Subject: [PATCH 28/55] msi: Source code reformatting, typo fixes, unify
messages
Added lots of debug tracing macros.
Release notes.
---
documentation/RELEASE_NOTES.html | 8 +
src/ioc/dbtemplate/msi.c | 784 ++++++++++++++++++++-----------
2 files changed, 510 insertions(+), 282 deletions(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 571a1b3a0..57baf3db1 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -16,6 +16,14 @@
+Improvements to msi
+
+In addition to fixing its response to discovering parsing errors in its
+ substitution input file (reported as Launchpad
+ bug #1503661)
+ so it now deletes the incomplete output file, the msi program has been cleaned
+ up a little bit internally.
+
All array records now post monitors on their array-length fields
The waveform record has been posting monitors on its NORD field since Base
diff --git a/src/ioc/dbtemplate/msi.c b/src/ioc/dbtemplate/msi.c
index a29bb5fc0..69680e17e 100644
--- a/src/ioc/dbtemplate/msi.c
+++ b/src/ioc/dbtemplate/msi.c
@@ -4,7 +4,7 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS Base is distributed subject to a Software License Agreement found
-* in the file LICENSE that is included with this distribution.
+* in the file LICENSE that is included with this distribution.
\*************************************************************************/
/* msi - macro substitutions and include */
@@ -27,6 +27,31 @@
#define MAX_BUFFER_SIZE 4096
#define MAX_DEPS 1024
+#if 0
+/* Debug Tracing */
+int din = 0;
+#define ENTER fprintf(stderr, "%*sEntering %s\n", 2*din++, "", __FUNCTION__)
+
+#define STEP(s) fprintf(stderr, "%*s%s: %s\n", 2*din, "", __FUNCTION__, s)
+#define STEPS(s, v) fprintf(stderr, "%*s%s: %s '%s'\n", 2*din, "", __FUNCTION__, s, v)
+#define STEPD(s, v) fprintf(stderr, "%*s%s: %s %d\n", 2*din, "", __FUNCTION__, s, v)
+
+#define EXIT fprintf(stderr, "%*s%s: Returning\n", 2*din--, "", __FUNCTION__)
+#define EXITD(r) fprintf(stderr, "%*s%s: Returning %d\n", 2*din--, "", __FUNCTION__, r)
+#define EXITS(r) fprintf(stderr, "%*s%s: Returning '%s'\n", 2*din--, "", __FUNCTION__, r)
+#else
+#define ENTER
+
+#define STEP(s)
+#define STEPS(s, v)
+#define STEPD(s, v)
+
+#define EXIT
+#define EXITD(r)
+#define EXITS(r)
+#endif
+
+
/* Module to read the template files */
typedef struct inputData inputData;
@@ -68,48 +93,62 @@ int main(int argc,char **argv)
MAC_HANDLE *macPvt;
char *pval;
int narg;
- char *substitutionName=0;
- char *templateName=0;
+ char *substitutionName = 0;
+ char *templateName = 0;
int i;
int localScope = 1;
inputConstruct(&inputPvt);
- macCreateHandle(&macPvt,0);
- while((argc>1) && (argv[1][0] == '-')) {
- narg = (strlen(argv[1])==2) ? 2 : 1;
- pval = (narg==1) ? (argv[1]+2) : argv[2];
- if(strncmp(argv[1],"-I",2)==0) {
- inputAddPath(inputPvt,pval);
- } else if (strcmp(argv[1], "-D") == 0) {
+ macCreateHandle(&macPvt, 0);
+ while ((argc > 1) && (argv[1][0] == '-')) {
+ narg = (strlen(argv[1]) == 2) ? 2 : 1;
+ pval = (narg == 1) ? (argv[1] + 2) : argv[2];
+
+ if (strncmp(argv[1], "-I", 2) == 0) {
+ inputAddPath(inputPvt, pval);
+ }
+ else if (strcmp(argv[1], "-D") == 0) {
opt_D = 1;
narg = 1; /* no argument for this option */
- } else if(strncmp(argv[1],"-o",2)==0) {
+ }
+ else if(strncmp(argv[1], "-o", 2) == 0) {
outFile = epicsStrDup(pval);
- } else if(strncmp(argv[1],"-M",2)==0) {
- addMacroReplacements(macPvt,pval);
- } else if(strncmp(argv[1],"-S",2)==0) {
+ }
+ else if(strncmp(argv[1], "-M", 2) == 0) {
+ addMacroReplacements(macPvt, pval);
+ }
+ else if(strncmp(argv[1], "-S", 2) == 0) {
substitutionName = epicsStrDup(pval);
- } else if (strcmp(argv[1], "-V") == 0) {
+ }
+ else if (strcmp(argv[1], "-V") == 0) {
opt_V = 1;
narg = 1; /* no argument for this option */
- } else if (strcmp(argv[1], "-g") == 0) {
+ }
+ else if (strcmp(argv[1], "-g") == 0) {
localScope = 0;
narg = 1; /* no argument for this option */
- } else if (strcmp(argv[1], "-h") == 0) {
+ }
+ else if (strcmp(argv[1], "-h") == 0) {
usageExit(0);
- } else {
+ }
+ else {
fprintf(stderr, "msi: Bad argument \"%s\"\n", argv[1]);
usageExit(1);
}
+
argc -= narg;
- for(i=1; i2) {
- fprintf(stderr,"msi: Too many arguments\n");
+ macSuppressWarning(macPvt, 1);
+
+ if (argc > 2) {
+ fprintf(stderr, "msi: Too many arguments\n");
usageExit(1);
}
+
if (opt_D) {
if (!outFile) {
fprintf(stderr, "msi: Option -D requires -o for Makefile target\n");
@@ -122,34 +161,47 @@ int main(int argc,char **argv)
outFile, strerror(errno));
exit(1);
}
- if(argc==2) {
+
+ if (argc == 2)
templateName = epicsStrDup(argv[1]);
+
+ if (!substitutionName) {
+ STEP("Single template+substitutions file");
+ makeSubstitutions(inputPvt, macPvt, templateName);
}
- if(!substitutionName) {
- makeSubstitutions(inputPvt,macPvt,templateName);
- } else {
+ else {
subInfo *substitutePvt;
char *filename = 0;
int isGlobal, isFile;
- substituteOpen(&substitutePvt,substitutionName);
+ STEPS("Substitutions from file", substitutionName);
+ substituteOpen(&substitutePvt, substitutionName);
do {
- if ((isGlobal = substituteGetGlobalSet(substitutePvt))) {
+ isGlobal = substituteGetGlobalSet(substitutePvt);
+ if (isGlobal) {
+ STEP("Handling global macros");
pval = substituteGetGlobalReplacements(substitutePvt);
- if(pval) {
- addMacroReplacements(macPvt,pval);
- }
- } else if ((isFile = substituteGetNextSet(substitutePvt,&filename))) {
- if(templateName) filename = templateName;
- if(!filename) {
- fprintf(stderr,"msi: No template file\n");
+ if (pval)
+ addMacroReplacements(macPvt, pval);
+ }
+ else if ((isFile = substituteGetNextSet(substitutePvt, &filename))) {
+ if (templateName)
+ filename = templateName;
+ if (!filename) {
+ fprintf(stderr, "msi: No template file\n");
usageExit(1);
}
- while((pval = substituteGetReplacements(substitutePvt))){
- if (localScope) macPushScope(macPvt);
- addMacroReplacements(macPvt,pval);
- makeSubstitutions(inputPvt,macPvt,filename);
- if (localScope) macPopScope(macPvt);
+
+ STEPS("Handling template file", filename);
+ while ((pval = substituteGetReplacements(substitutePvt))) {
+ if (localScope)
+ macPushScope(macPvt);
+
+ addMacroReplacements(macPvt, pval);
+ makeSubstitutions(inputPvt, macPvt, filename);
+
+ if (localScope)
+ macPopScope(macPvt);
}
}
} while (isGlobal || isFile);
@@ -198,15 +250,15 @@ static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval)
char **pairs;
long status;
- status = macParseDefns(macPvt,pval,&pairs);
- if(status==-1) {
- fprintf(stderr,"msi: Error from macParseDefns\n");
+ status = macParseDefns(macPvt, pval, &pairs);
+ if (status == -1) {
+ fprintf(stderr, "msi: Error from macParseDefns\n");
usageExit(1);
}
- if(status) {
- status = macInstallMacros(macPvt,pairs);
- if(!status) {
- fprintf(stderr,"Error from macInstallMacros\n");
+ if (status) {
+ status = macInstallMacros(macPvt, pairs);
+ if (!status) {
+ fprintf(stderr, "Error from macInstallMacros\n");
usageExit(1);
}
free(pairs);
@@ -222,86 +274,98 @@ static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *tem
static char buffer[MAX_BUFFER_SIZE];
int n;
- inputBegin(inputPvt,templateName);
- while((input = inputNextLine(inputPvt))) {
+ ENTER;
+ inputBegin(inputPvt, templateName);
+ while ((input = inputNextLine(inputPvt))) {
int expand=1;
char *p;
char *command = 0;
- p = input;
+ p = input;
/*skip whitespace at beginning of line*/
- while(*p && (isspace((int) *p))) ++p;
+ while (*p && (isspace((int) *p))) ++p;
+
/*Look for i or s */
- if(*p && (*p=='i' || *p=='s')) command = p;
- if(command) {
+ if (*p && (*p=='i' || *p=='s'))
+ command = p;
+
+ if (command) {
char *pstart;
char *pend;
char *copy;
int cmdind=-1;
int i;
-
- for(i=0; i< NELEMENTS(cmdNames); i++) {
- if(strstr(command,cmdNames[i])) {
+
+ for (i = 0; i < NELEMENTS(cmdNames); i++) {
+ if (strstr(command, cmdNames[i])) {
cmdind = i;
}
}
- if(cmdind<0) goto endif;
+ if (cmdind < 0) goto endcmd;
p = command + strlen(cmdNames[cmdind]);
/*skip whitespace after command*/
- while(*p && (isspace((int) *p))) ++p;
+ while (*p && (isspace((int) *p))) ++p;
/*Next character must be quote*/
- if((*p==0) || (*p!='"')) goto endif;
+ if ((*p == 0) || (*p != '"')) goto endcmd;
pstart = ++p;
/*Look for end quote*/
- while(*p && (*p!='"')) {
- /*allow escape for imbeded quote*/
- if((*p=='\\') && *(p+1)=='"') {
- p += 2; continue;
- } else {
- if(*p=='"') break;
+ while (*p && (*p != '"')) {
+ /*allow escape for embeded quote*/
+ if ((p[0] == '\\') && p[1] == '"') {
+ p += 2;
+ continue;
+ }
+ else {
+ if (*p == '"') break;
}
++p;
}
pend = p;
- if(*p==0) goto endif;
+ if (*p == 0) goto endcmd;
/*skip quote and any trailing blanks*/
- while(*++p==' ') ;
- if(*p != '\n' && *p !=0) goto endif;
- copy = calloc(pend-pstart+1,sizeof(char));
- strncpy(copy,pstart,pend-pstart);
+ while (*++p == ' ') ;
+ if (*p != '\n' && *p != 0) goto endcmd;
+ copy = calloc(pend-pstart + 1, sizeof(char));
+ strncpy(copy, pstart, pend-pstart);
+
switch(cmdind) {
case cmdInclude:
inputNewIncludeFile(inputPvt,copy);
break;
+
case cmdSubstitute:
addMacroReplacements(macPvt,copy);
break;
+
default:
- fprintf(stderr,"msi: Logic error in makeSubstitutions\n");
+ fprintf(stderr, "msi: Logic error in makeSubstitutions\n");
inputErrPrint(inputPvt);
abortExit(1);
}
free(copy);
expand = 0;
}
-endif:
+
+endcmd:
if (expand && !opt_D) {
- n = macExpandString(macPvt,input,buffer,MAX_BUFFER_SIZE-1);
- fputs(buffer,stdout);
+ STEP("Expanding to output stream");
+ n = macExpandString(macPvt, input, buffer, MAX_BUFFER_SIZE - 1);
+ fputs(buffer, stdout);
if (opt_V == 1 && n < 0) {
- fprintf(stderr,"msi: Error - undefined macros present\n");
+ fprintf(stderr, "msi: Error - undefined macros present\n");
opt_V++;
}
}
}
+ EXIT;
}
-typedef struct inputFile{
+typedef struct inputFile {
ELLNODE node;
char *filename;
FILE *fp;
int lineNum;
-}inputFile;
+} inputFile;
typedef struct pathNode {
ELLNODE node;
@@ -314,15 +378,15 @@ struct inputData {
char inputBuffer[MAX_BUFFER_SIZE];
};
-static void inputOpenFile(inputData *pinputData,char *filename);
+static void inputOpenFile(inputData *pinputData, char *filename);
static void inputCloseFile(inputData *pinputData);
static void inputCloseAllFiles(inputData *pinputData);
static void inputConstruct(inputData **ppvt)
{
- inputData *pinputData;
+ inputData *pinputData;
- pinputData = calloc(1,sizeof(inputData));
+ pinputData = calloc(1, sizeof(inputData));
ellInit(&pinputData->inputFileList);
ellInit(&pinputData->pathList);
*ppvt = pinputData;
@@ -330,11 +394,11 @@ static void inputConstruct(inputData **ppvt)
static void inputDestruct(inputData *pinputData)
{
- pathNode *ppathNode;
+ pathNode *ppathNode;
inputCloseAllFiles(pinputData);
- while((ppathNode = (pathNode *)ellFirst(&pinputData->pathList))) {
- ellDelete(&pinputData->pathList,&ppathNode->node);
+ while ((ppathNode = (pathNode *) ellFirst(&pinputData->pathList))) {
+ ellDelete(&pinputData->pathList, &ppathNode->node);
free(ppathNode->directory);
free(ppathNode);
}
@@ -351,38 +415,45 @@ static void inputAddPath(inputData *pinputData, char *path)
int emptyName;
const char sep = *OSI_PATH_LIST_SEPARATOR;
+ ENTER;
pdir = path;
/*an empty name at beginning, middle, or end means current directory*/
- while(pdir && *pdir) {
+ while (pdir && *pdir) {
emptyName = ((*pdir == sep) ? 1 : 0);
- if(emptyName) ++pdir;
- ppathNode = (pathNode *)calloc(1,sizeof(pathNode));
- ellAdd(ppathList,&ppathNode->node);
- if(!emptyName) {
- pcolon = strchr(pdir,sep);
+ if (emptyName) ++pdir;
+
+ ppathNode = (pathNode *) calloc(1, sizeof(pathNode));
+ ellAdd(ppathList, &ppathNode->node);
+
+ if (!emptyName) {
+ pcolon = strchr(pdir, sep);
len = (pcolon ? (pcolon - pdir) : strlen(pdir));
- if(len>0) {
- ppathNode->directory = (char *)calloc(len+1,sizeof(char));
- strncpy(ppathNode->directory,pdir,len);
+ if (len > 0) {
+ ppathNode->directory = (char *) calloc(len + 1, sizeof(char));
+ strncpy(ppathNode->directory, pdir, len);
pdir = pcolon;
/*unless at end skip past first colon*/
- if(pdir && *(pdir+1)!=0) ++pdir;
- } else { /*must have been trailing : */
- emptyName=1;
+ if (pdir && *(pdir + 1) != 0) ++pdir;
+ }
+ else { /*must have been trailing : */
+ emptyName = 1;
}
}
- if(emptyName) {
- ppathNode->directory = (char *)calloc(2,sizeof(char));
- strcpy(ppathNode->directory,".");
+
+ if (emptyName) {
+ ppathNode->directory = (char *) calloc(2, sizeof(char));
+ strcpy(ppathNode->directory, ".");
}
}
- return;
+ EXIT;
}
static void inputBegin(inputData *pinputData, char *fileName)
{
+ ENTER;
inputCloseAllFiles(pinputData);
- inputOpenFile(pinputData,fileName);
+ inputOpenFile(pinputData, fileName);
+ EXIT;
}
static char *inputNextLine(inputData *pinputData)
@@ -390,43 +461,54 @@ static char *inputNextLine(inputData *pinputData)
inputFile *pinputFile;
char *pline;
- while((pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList))) {
- pline = fgets(pinputData->inputBuffer,MAX_BUFFER_SIZE,pinputFile->fp);
- if(pline) {
+ ENTER;
+ while ((pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList))) {
+ pline = fgets(pinputData->inputBuffer, MAX_BUFFER_SIZE, pinputFile->fp);
+ if (pline) {
++pinputFile->lineNum;
- return(pline);
+ EXITS(pline);
+ return pline;
}
inputCloseFile(pinputData);
}
- return(0);
+ EXITD(0);
+ return 0;
}
static void inputNewIncludeFile(inputData *pinputData, char *name)
{
+ ENTER;
inputOpenFile(pinputData,name);
+ EXIT;
}
static void inputErrPrint(inputData *pinputData)
{
inputFile *pinputFile;
- fprintf(stderr,"input: '%s' at ",pinputData->inputBuffer);
- pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList);
- while(pinputFile) {
- fprintf(stderr,"line %d of ",pinputFile->lineNum);
- if(pinputFile->filename) {
- fprintf(stderr," file %s\n",pinputFile->filename);
- } else {
- fprintf(stderr,"stdin:\n");
+ ENTER;
+ fprintf(stderr, "input: '%s' at ", pinputData->inputBuffer);
+ pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList);
+ while (pinputFile) {
+ fprintf(stderr, "line %d of ", pinputFile->lineNum);
+
+ if (pinputFile->filename) {
+ fprintf(stderr, " file %s\n", pinputFile->filename);
}
- pinputFile = (inputFile *)ellNext(&pinputFile->node);
- if(pinputFile) {
- fprintf(stderr," included from ");
- } else {
+ else {
+ fprintf(stderr, "stdin:\n");
+ }
+
+ pinputFile = (inputFile *) ellNext(&pinputFile->node);
+ if (pinputFile) {
+ fprintf(stderr, " included from ");
+ }
+ else {
fprintf(stderr,"\n");
}
}
fprintf(stderr,"\n");
+ EXIT;
}
static void inputOpenFile(inputData *pinputData,char *filename)
@@ -437,35 +519,48 @@ static void inputOpenFile(inputData *pinputData,char *filename)
char *fullname = 0;
FILE *fp = 0;
- if(!filename) {
+ ENTER;
+ if (!filename) {
+ STEP("Using stdin");
fp = stdin;
- } else if((ellCount(ppathList)==0) || strchr(filename,'/')){
- fp = fopen(filename,"r");
- } else {
- ppathNode = (pathNode *)ellFirst(ppathList);
- while(ppathNode) {
- fullname = calloc(strlen(filename)+strlen(ppathNode->directory) +2,
+ }
+ else if ((ellCount(ppathList) == 0) || strchr(filename, '/')){
+ STEPS("Opening ", filename);
+ fp = fopen(filename, "r");
+ }
+ else {
+ ppathNode = (pathNode *) ellFirst(ppathList);
+ while (ppathNode) {
+ fullname = calloc(strlen(filename) + strlen(ppathNode->directory) + 2,
sizeof(char));
- strcpy(fullname,ppathNode->directory);
- strcat(fullname,"/");
- strcat(fullname,filename);
- fp = fopen(fullname,"r");
- if(fp) break;
+ strcpy(fullname, ppathNode->directory);
+ strcat(fullname, "/");
+ strcat(fullname, filename);
+ STEPS("Trying", filename);
+ fp = fopen(fullname, "r");
+ if (fp)
+ break;
free(fullname);
- ppathNode = (pathNode *)ellNext(&ppathNode->node);
+ ppathNode = (pathNode *) ellNext(&ppathNode->node);
}
}
- if(!fp) {
- fprintf(stderr,"msi: Can't open file '%s'\n",filename);
+
+ if (!fp) {
+ fprintf(stderr, "msi: Can't open file '%s'\n", filename);
inputErrPrint(pinputData);
abortExit(1);
}
- pinputFile = calloc(1,sizeof(inputFile));
- if(ppathNode) {
+
+ STEP("File opened");
+ pinputFile = calloc(1, sizeof(inputFile));
+
+ if (ppathNode) {
pinputFile->filename = fullname;
- } else if(filename) {
+ }
+ else if (filename) {
pinputFile->filename = epicsStrDup(filename);
- } else {
+ }
+ else {
pinputFile->filename = epicsStrDup("stdin");
}
@@ -495,35 +590,41 @@ static void inputOpenFile(inputData *pinputData,char *filename)
}
pinputFile->fp = fp;
- ellInsert(&pinputData->inputFileList,0,&pinputFile->node);
+ ellInsert(&pinputData->inputFileList, 0, &pinputFile->node);
+ EXIT;
}
static void inputCloseFile(inputData *pinputData)
{
inputFile *pinputFile;
- pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList);
- if(!pinputFile) return;
- ellDelete(&pinputData->inputFileList,&pinputFile->node);
- if(fclose(pinputFile->fp))
- fprintf(stderr,"msi: Can't close input file '%s'\n",pinputFile->filename);
- free(pinputFile->filename);
- free(pinputFile);
+ ENTER;
+ pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList);
+ if (pinputFile) {
+ ellDelete(&pinputData->inputFileList, &pinputFile->node);
+ if (fclose(pinputFile->fp))
+ fprintf(stderr, "msi: Can't close input file '%s'\n", pinputFile->filename);
+ free(pinputFile->filename);
+ free(pinputFile);
+ }
+ EXIT;
}
static void inputCloseAllFiles(inputData *pinputData)
{
inputFile *pinputFile;
- while((pinputFile=(inputFile *)ellFirst(&pinputData->inputFileList))){
+ ENTER;
+ while ((pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList))) {
inputCloseFile(pinputData);
}
+ EXIT;
}
/*start of code that handles substitution file*/
typedef enum {
- tokenLBrace,tokenRBrace,tokenSeparater,tokenString,tokenEOF
-}tokenType;
+ tokenLBrace, tokenRBrace, tokenSeparator, tokenString, tokenEOF
+} tokenType;
typedef struct subFile {
char *substitutionName;
@@ -560,70 +661,87 @@ static void catMacroReplacements(subInfo *psubInfo,const char *value);
void freeSubFile(subInfo *psubInfo)
{
- subFile *psubFile = psubInfo->psubFile;
- if(psubFile->fp) {
- if(fclose(psubFile->fp))
- fprintf(stderr,"msi: Can't close substitution file\n");
+ subFile *psubFile = psubInfo->psubFile;
+
+ ENTER;
+ if (psubFile->fp) {
+ if (fclose(psubFile->fp))
+ fprintf(stderr, "msi: Can't close substitution file\n");
}
free(psubFile);
free(psubInfo->filename);
psubInfo->psubFile = 0;
+ EXIT;
}
void freePattern(subInfo *psubInfo)
{
patternNode *ppatternNode;
- while((ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList))) {
- ellDelete(&psubInfo->patternList,&ppatternNode->node);
+
+ ENTER;
+ while ((ppatternNode = (patternNode *) ellFirst(&psubInfo->patternList))) {
+ ellDelete(&psubInfo->patternList, &ppatternNode->node);
free(ppatternNode->var);
free(ppatternNode);
}
psubInfo->isPattern = 0;
+ EXIT;
}
static void substituteDestruct(subInfo *psubInfo)
{
+ ENTER;
freeSubFile(psubInfo);
freePattern(psubInfo);
free(psubInfo);
- return;
+ EXIT;
}
-static void substituteOpen(subInfo **ppvt,char *substitutionName)
+static void substituteOpen(subInfo **ppvt, char *substitutionName)
{
subInfo *psubInfo;
subFile *psubFile;
FILE *fp;
- psubInfo = calloc(1,sizeof(subInfo));
+ ENTER;
+ psubInfo = calloc(1, sizeof(subInfo));
*ppvt = psubInfo;
- psubFile = calloc(1,sizeof(subFile));
+ psubFile = calloc(1, sizeof(subFile));
psubInfo->psubFile = psubFile;
ellInit(&psubInfo->patternList);
- fp = fopen(substitutionName,"r");
- if(!fp) {
- fprintf(stderr,"msi: Can't open file '%s'\n",substitutionName);
+
+ fp = fopen(substitutionName, "r");
+ if (!fp) {
+ fprintf(stderr, "msi: Can't open file '%s'\n", substitutionName);
abortExit(1);
}
+
psubFile->substitutionName = substitutionName;
psubFile->fp = fp;
psubFile->lineNum = 1;
psubFile->inputBuffer[0] = 0;
psubFile->pnextChar = &psubFile->inputBuffer[0];
subGetNextToken(psubFile);
- return;
+ EXIT;
}
static int substituteGetGlobalSet(subInfo *psubInfo)
{
- subFile *psubFile = psubInfo->psubFile;
+ subFile *psubFile = psubInfo->psubFile;
- while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
- if(psubFile->token==tokenString && strcmp(psubFile->string,"global")==0) {
+ ENTER;
+ while (psubFile->token == tokenSeparator)
subGetNextToken(psubFile);
- return(1);
+
+ if (psubFile->token == tokenString &&
+ strcmp(psubFile->string, "global") == 0) {
+ subGetNextToken(psubFile);
+ EXITD(1);
+ return 1;
}
- return(0);
+
+ EXITD(0);
+ return 0;
}
static int substituteGetNextSet(subInfo *psubInfo,char **filename)
@@ -631,34 +749,59 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename)
subFile *psubFile = psubInfo->psubFile;
patternNode *ppatternNode;
+ ENTER;
*filename = 0;
- while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
- if(psubFile->token==tokenEOF) return(0);
- if(psubFile->token==tokenString && strcmp(psubFile->string,"file")==0) {
+ while (psubFile->token == tokenSeparator)
+ subGetNextToken(psubFile);
+
+ if (psubFile->token == tokenEOF) {
+ EXITD(0);
+ return 0;
+ }
+
+ if (psubFile->token == tokenString &&
+ strcmp(psubFile->string, "file") == 0) {
+ size_t len;
+
+ STEP("Parsed 'file'");
psubInfo->isFile = 1;
- if(subGetNextToken(psubFile)!=tokenString) {
- subFileErrPrint(psubFile,"Parse error, expecting filename");
+ if (subGetNextToken(psubFile) != tokenString) {
+ subFileErrPrint(psubFile, "Parse error, expecting a filename");
abortExit(1);
}
+
freePattern(psubInfo);
free(psubInfo->filename);
- if(psubFile->string[0]=='"'&&psubFile->string[strlen(psubFile->string)-1]=='"') {
- psubFile->string[strlen(psubFile->string)-1]='\0';
- psubInfo->filename = macEnvExpand(psubFile->string+1);
+
+ len = strlen(psubFile->string);
+ if (psubFile->string[0] == '"' &&
+ psubFile->string[len - 1] == '"') {
+ psubFile->string[len - 1] = '\0';
+ psubInfo->filename = macEnvExpand(psubFile->string + 1);
}
- else {
+ else
psubInfo->filename = macEnvExpand(psubFile->string);
- }
- while(subGetNextToken(psubFile)==tokenSeparater);
- if(psubFile->token!=tokenLBrace) {
- subFileErrPrint(psubFile,"Parse error, expecting {");
+ STEPS("Parsed filename", psubInfo->filename);
+
+ while (subGetNextToken(psubFile) == tokenSeparator);
+
+ if (psubFile->token != tokenLBrace) {
+ subFileErrPrint(psubFile, "Parse error, expecting '{'");
abortExit(1);
}
+ STEP("Parsed '{'");
subGetNextToken(psubFile);
}
*filename = psubInfo->filename;
- while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
- if(psubFile->token==tokenLBrace) return(1);
+
+ while (psubFile->token == tokenSeparator)
+ subGetNextToken(psubFile);
+
+ if (psubFile->token == tokenLBrace) {
+ EXITD(1);
+ return 1;
+ }
+
if (psubFile->token == tokenRBrace) {
subFileErrPrint(psubFile, "Parse error, unexpected '}'");
abortExit(1);
@@ -669,58 +812,84 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename)
subFileErrPrint(psubFile, "Parse error, expecting 'pattern'");
abortExit(1);
}
+
+ STEP("Parsed 'pattern'");
freePattern(psubInfo);
psubInfo->isPattern = 1;
- while(subGetNextToken(psubFile)==tokenSeparater);
- if(psubFile->token!=tokenLBrace) {
- subFileErrPrint(psubFile,"Parse error, expecting {");
+
+ while (subGetNextToken(psubFile) == tokenSeparator);
+
+ if (psubFile->token != tokenLBrace) {
+ subFileErrPrint(psubFile, "Parse error, expecting '{'");
abortExit(1);
}
- while(1) {
- while(subGetNextToken(psubFile)==tokenSeparater);
- if(psubFile->token!=tokenString) break;
- ppatternNode = calloc(1,sizeof(patternNode));
- ellAdd(&psubInfo->patternList,&ppatternNode->node);
+ STEP("Parsed '{'");
+
+ while (1) {
+ while (subGetNextToken(psubFile) == tokenSeparator);
+
+ if (psubFile->token != tokenString)
+ break;
+
+ ppatternNode = calloc(1, sizeof(patternNode));
+ ellAdd(&psubInfo->patternList, &ppatternNode->node);
ppatternNode->var = epicsStrDup(psubFile->string);
}
- if(psubFile->token!=tokenRBrace) {
- subFileErrPrint(psubFile,"Parse error, expecting }");
+
+ if (psubFile->token != tokenRBrace) {
+ subFileErrPrint(psubFile, "Parse error, expecting '}'");
abortExit(1);
}
+
subGetNextToken(psubFile);
- return(1);
+ EXITD(1);
+ return 1;
}
static char *substituteGetGlobalReplacements(subInfo *psubInfo)
{
subFile *psubFile = psubInfo->psubFile;
- if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0;
+ ENTER;
+ if (psubInfo->macroReplacements)
+ psubInfo->macroReplacements[0] = 0;
psubInfo->curLength = 0;
- while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
- if(psubFile->token==tokenRBrace && psubInfo->isFile) {
+
+ while (psubFile->token == tokenSeparator)
+ subGetNextToken(psubFile);
+
+ if (psubFile->token == tokenRBrace && psubInfo->isFile) {
psubInfo->isFile = 0;
free(psubInfo->filename);
psubInfo->filename = 0;
freePattern(psubInfo);
subGetNextToken(psubFile);
- return(0);
+ EXITD(0);
+ return 0;
}
- if(psubFile->token==tokenEOF) return(0);
- if(psubFile->token!=tokenLBrace) return(0);
- while(1) {
+
+ if (psubFile->token == tokenEOF) {
+ EXITD(0);
+ return 0;
+ }
+ if (psubFile->token != tokenLBrace) {
+ EXITD(0);
+ return 0;
+ }
+
+ while (1) {
switch(subGetNextToken(psubFile)) {
case tokenRBrace:
subGetNextToken(psubFile);
- if (!psubInfo->macroReplacements) {
- catMacroReplacements(psubInfo,"");
- }
- return(psubInfo->macroReplacements);
- case tokenSeparater:
- catMacroReplacements(psubInfo,",");
+ EXITS(psubInfo->macroReplacements);
+ return psubInfo->macroReplacements;
+
+ case tokenSeparator:
+ catMacroReplacements(psubInfo, ",");
break;
+
case tokenString:
- catMacroReplacements(psubInfo,psubFile->string);
+ catMacroReplacements(psubInfo, psubFile->string);
break;
case tokenLBrace:
@@ -738,58 +907,81 @@ static char *substituteGetReplacements(subInfo *psubInfo)
subFile *psubFile = psubInfo->psubFile;
patternNode *ppatternNode;
- if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0;
+ ENTER;
+ if (psubInfo->macroReplacements)
+ psubInfo->macroReplacements[0] = 0;
psubInfo->curLength = 0;
- while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
- if(psubFile->token==tokenRBrace && psubInfo->isFile) {
+
+ while (psubFile->token == tokenSeparator)
+ subGetNextToken(psubFile);
+
+ if (psubFile->token==tokenRBrace && psubInfo->isFile) {
psubInfo->isFile = 0;
free(psubInfo->filename);
psubInfo->filename = 0;
freePattern(psubInfo);
subGetNextToken(psubFile);
- return(0);
+ EXITD(0);
+ return 0;
}
- if(psubFile->token==tokenEOF) return(0);
- if(psubFile->token!=tokenLBrace) return(0);
- if(psubInfo->isPattern) {
+
+ if (psubFile->token == tokenEOF) {
+ EXITD(0);
+ return 0;
+ }
+
+ if (psubFile->token != tokenLBrace) {
+ EXITD(0);
+ return 0;
+ }
+
+ if (psubInfo->isPattern) {
int gotFirstPattern = 0;
- while(subGetNextToken(psubFile)==tokenSeparater);
- ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList);
- while(1) {
- if(psubFile->token==tokenRBrace) {
+ while (subGetNextToken(psubFile) == tokenSeparator);
+ ppatternNode = (patternNode *) ellFirst(&psubInfo->patternList);
+ while (1) {
+ if (psubFile->token == tokenRBrace) {
subGetNextToken(psubFile);
- return(psubInfo->macroReplacements);
+ EXITS(psubInfo->macroReplacements);
+ return psubInfo->macroReplacements;
}
- if(psubFile->token!=tokenString) {
- subFileErrPrint(psubFile,"Parse error, illegal token");
+
+ if (psubFile->token != tokenString) {
+ subFileErrPrint(psubFile,"Parse error, expecting macro value");
abortExit(1);
}
- if(gotFirstPattern) catMacroReplacements(psubInfo,",");
+
+ if (gotFirstPattern)
+ catMacroReplacements(psubInfo, ",");
gotFirstPattern = 1;
- if(ppatternNode) {
- catMacroReplacements(psubInfo,ppatternNode->var);
- catMacroReplacements(psubInfo,"=");
- catMacroReplacements(psubInfo,psubFile->string);
- ppatternNode = (patternNode *)ellNext(&ppatternNode->node);
- } else {
- subFileErrPrint(psubFile,"Warning, too many values given");
+
+ if (ppatternNode) {
+ catMacroReplacements(psubInfo, ppatternNode->var);
+ catMacroReplacements(psubInfo, "=");
+ catMacroReplacements(psubInfo, psubFile->string);
+ ppatternNode = (patternNode *) ellNext(&ppatternNode->node);
}
- while(subGetNextToken(psubFile)==tokenSeparater);
+ else {
+ subFileErrPrint(psubFile, "Warning, too many values given");
+ }
+
+ while (subGetNextToken(psubFile) == tokenSeparator);
}
- } else while(1) {
+ }
+ else while(1) {
switch(subGetNextToken(psubFile)) {
case tokenRBrace:
subGetNextToken(psubFile);
- if (!psubInfo->macroReplacements) {
- catMacroReplacements(psubInfo,"");
- }
- return(psubInfo->macroReplacements);
- case tokenSeparater:
- catMacroReplacements(psubInfo,",");
+ EXITS(psubInfo->macroReplacements);
+ return psubInfo->macroReplacements;
+
+ case tokenSeparator:
+ catMacroReplacements(psubInfo, ",");
break;
+
case tokenString:
- catMacroReplacements(psubInfo,psubFile->string);
+ catMacroReplacements(psubInfo, psubFile->string);
break;
case tokenLBrace:
@@ -806,69 +998,84 @@ static char *subGetNextLine(subFile *psubFile)
{
char *pline;
+ ENTER;
do {
- pline = fgets(psubFile->inputBuffer,MAX_BUFFER_SIZE,psubFile->fp);
+ pline = fgets(psubFile->inputBuffer, MAX_BUFFER_SIZE, psubFile->fp);
++psubFile->lineNum;
- } while(pline && psubFile->inputBuffer[0]=='#');
- if(!pline) {
+ } while (pline && psubFile->inputBuffer[0] == '#');
+
+ if (!pline) {
psubFile->token = tokenEOF;
psubFile->inputBuffer[0] = 0;
psubFile->pnextChar = 0;
- return(0);
+ EXITD(0);
+ return 0;
}
+
psubFile->pnextChar = &psubFile->inputBuffer[0];
- return(&psubFile->inputBuffer[0]);
+ EXITS(&psubFile->inputBuffer[0]);
+ return &psubFile->inputBuffer[0];
}
static void subFileErrPrint(subFile *psubFile,char * message)
{
- fprintf(stderr,"msi: %s\n",message);
- fprintf(stderr," in substitution file '%s' at line %d:\n %s",
- psubFile->substitutionName,
- psubFile->lineNum,psubFile->inputBuffer);
+ fprintf(stderr, "msi: %s\n",message);
+ fprintf(stderr, " in substitution file '%s' at line %d:\n %s",
+ psubFile->substitutionName, psubFile->lineNum, psubFile->inputBuffer);
}
static tokenType subGetNextToken(subFile *psubFile)
{
- char *p;
- char *pto;
+ char *p, *pto;
+ ENTER;
p = psubFile->pnextChar;
- if(!p) { psubFile->token = tokenEOF; return(tokenEOF);}
- if(*p==0 || *p=='\n' || *p=='#') {
- p = subGetNextLine(psubFile);
- if(!p) { psubFile->token = tokenEOF; return(tokenEOF);}
- else { psubFile->token = tokenSeparater; return(tokenSeparater);}
+ if (!p) {
+ STEP("Got EOF");
+ psubFile->token = tokenEOF;
+ goto done;
}
- while(isspace((int) *p)) p++;
- if(*p=='{') {
+
+ if (*p == 0 || *p == '\n' || *p == '#') {
+ STEP("Got newline/comment");
+ p = subGetNextLine(psubFile);
+ psubFile->token = p ? tokenSeparator : tokenEOF;
+ goto done;
+ }
+
+ while (isspace((int) *p)) p++;
+ if (*p == '{') {
+ STEP("Got '{'");
psubFile->token = tokenLBrace;
psubFile->pnextChar = ++p;
- return(tokenLBrace);
+ goto done;
}
- if(*p=='}') {
+ if (*p == '}') {
+ STEP("Got '}'");
psubFile->token = tokenRBrace;
psubFile->pnextChar = ++p;
- return(tokenRBrace);
+ goto done;
}
- if(*p==0 || isspace((int) *p) || *p==',') {
- while (isspace((int) *p) || *p==',') p++;
- psubFile->token = tokenSeparater;
+ if (*p == 0 || isspace((int) *p) || *p == ',') {
+ STEP("Got space/comma");
+ while (isspace((int) *p) || *p == ',') p++;
+ psubFile->token = tokenSeparator;
psubFile->pnextChar = p;
- return(tokenSeparater);
+ goto done;
}
/*now handle quoted strings*/
- if(*p=='"') {
+ if (*p == '"') {
+ STEP("Got '\"'");
pto = &psubFile->string[0];
*pto++ = *p++;
- while(*p!='"') {
- if(*p==0 || *p=='\n') {
- subFileErrPrint(psubFile,"Strings must be on single line\n");
+ while (*p != '"') {
+ if (*p == 0 || *p == '\n') {
+ subFileErrPrint(psubFile, "Strings must be on single line\n");
abortExit(1);
}
- /*allow escape for imbeded quote*/
- if((*p=='\\') && *(p+1)=='"') {
+ /*allow escape for embeded quote*/
+ if ((p[0] == '\\') && p[1] == '"') {
*pto++ = *p++;
*pto++ = *p++;
continue;
@@ -879,40 +1086,53 @@ static tokenType subGetNextToken(subFile *psubFile)
psubFile->pnextChar = p;
*pto = 0;
psubFile->token = tokenString;
- return(tokenString);
+ goto done;
}
+
/*Now take anything up to next non String token and not space*/
pto = &psubFile->string[0];
- while(!isspace((int) *p) && (strspn(p,"\",{}")==0)) *pto++ = *p++;
+
+ while (!isspace((int) *p) && (strspn(p, "\",{}") == 0))
+ *pto++ = *p++;
*pto = 0;
+ STEPS("Got bareword", psubFile->string);
+
psubFile->pnextChar = p;
psubFile->token = tokenString;
- return(tokenString);
+
+done:
+ EXITD(psubFile->token);
+ return psubFile->token;
}
-static void catMacroReplacements(subInfo *psubInfo,const char *value)
+static void catMacroReplacements(subInfo *psubInfo, const char *value)
{
- size_t len = strlen(value);
+ size_t len = strlen(value);
- if(psubInfo->size <= (psubInfo->curLength + len)) {
+ ENTER;
+ if (psubInfo->size <= (psubInfo->curLength + len)) {
size_t newsize = psubInfo->size + MAX_BUFFER_SIZE;
char *newbuf;
- if(newsize <= psubInfo->curLength + len)
+ STEP("Enlarging buffer");
+ if (newsize <= psubInfo->curLength + len)
newsize = psubInfo->curLength + len + 1;
- newbuf = calloc(1,newsize);
- if(!newbuf) {
- fprintf(stderr,"calloc failed for size %lu\n",
- (unsigned long) newsize);
+ newbuf = calloc(1, newsize);
+ if (!newbuf) {
+ fprintf(stderr, "calloc failed for size %lu\n",
+ (unsigned long) newsize);
abortExit(1);
}
- if(psubInfo->macroReplacements) {
- memcpy(newbuf,psubInfo->macroReplacements,psubInfo->curLength);
+ if (psubInfo->macroReplacements) {
+ memcpy(newbuf, psubInfo->macroReplacements, psubInfo->curLength);
free(psubInfo->macroReplacements);
}
psubInfo->size = newsize;
psubInfo->macroReplacements = newbuf;
}
- strcat(psubInfo->macroReplacements,value);
+
+ STEPS("Appending", value);
+ strcat(psubInfo->macroReplacements, value);
psubInfo->curLength += len;
+ EXIT;
}
From fb31dd784b7dc1d21c61af167caca8da52f39d87 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Tue, 31 Jul 2018 16:30:11 -0500
Subject: [PATCH 29/55] recGbl: Prevent record alarm severities > INVALID_ALARM
---
documentation/RELEASE_NOTES.html | 9 +++++++++
src/db/recGbl.c | 4 ++++
2 files changed, 13 insertions(+)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index b327e2430..fb5238bd1 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -16,6 +16,15 @@ Base-3.15 series or to EPICS 7.
+Prevent illegal alarm severities
+
+A check has been added to recGblResetAlarms() that prevents records
+from getting an alarm severity higher than INVALID_ALARM. It is still possible
+for a field like HSV to get set to a value that is not a legal alarm severity,
+but the core IOC code should never copy such a value into a record's SEVR or
+ACKS fields. With this fix the record's alarm severity will be limited to
+INVALID_ALARM.
+
Fixes for Launchpad bugs
The following launchpad bugs have fixes included:
diff --git a/src/db/recGbl.c b/src/db/recGbl.c
index 6d45e7333..01b2fa544 100644
--- a/src/db/recGbl.c
+++ b/src/db/recGbl.c
@@ -19,6 +19,7 @@
#include
#include "dbDefs.h"
+#include "alarm.h"
#include "epicsMath.h"
#include "epicsTime.h"
#include "epicsPrint.h"
@@ -222,6 +223,9 @@ unsigned short epicsShareAPI recGblResetAlarms(void *precord)
epicsEnum16 val_mask = 0;
epicsEnum16 stat_mask = 0;
+ if (new_sevr > INVALID_ALARM)
+ new_sevr = INVALID_ALARM;
+
pdbc->stat = new_stat;
pdbc->sevr = new_sevr;
pdbc->nsta = 0;
From 1dc1b25aaa61bb986cb0d27711e1b21bb46603a8 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Tue, 31 Jul 2018 17:58:38 -0500
Subject: [PATCH 30/55] caget.pl: Add missing acks and ackt metadata to display
output
---
src/cap5/caget.pl | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/cap5/caget.pl b/src/cap5/caget.pl
index 9d3df35b4..0ee407ad9 100644
--- a/src/cap5/caget.pl
+++ b/src/cap5/caget.pl
@@ -140,6 +140,10 @@ sub display {
printf " Lo ctrl limit: %g\n", $data->{lower_ctrl_limit};
printf " Hi ctrl limit: %g\n", $data->{upper_ctrl_limit};
}
+ if (exists $data->{ackt}) {
+ printf " Ack transients: %s\n", $data->{ackt} ? 'YES' : 'NO';
+ printf " Ack severity: %s\n", $data->{acks};
+ }
} else {
my $value = format_number($data, $type);
if ($opt_t) {
From 2548a372672367b2662dac5a484b634acb8b7f65 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 8 Aug 2018 16:53:32 -0500
Subject: [PATCH 31/55] Update/clean up EpicsHostArch.pl
---
src/tools/EpicsHostArch.pl | 76 +++++++++++++++++++++-----------------
1 file changed, 42 insertions(+), 34 deletions(-)
diff --git a/src/tools/EpicsHostArch.pl b/src/tools/EpicsHostArch.pl
index 5f5dad453..e8e49bc5e 100644
--- a/src/tools/EpicsHostArch.pl
+++ b/src/tools/EpicsHostArch.pl
@@ -1,47 +1,55 @@
-eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
- if $running_under_some_shell; # EpicsHostArch.pl
+#!/usr/bin/env perl
#*************************************************************************
-# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
+# Copyright (c) 2018 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
-# Copyright (c) 2002 The Regents of the University of California, as
-# Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
-# Returns the Epics host architecture suitable
-# for assigning to the EPICS_HOST_ARCH variable
+# Returns an architecture name for EPICS_HOST_ARCH that should be
+# appropriate for the CPU that this version of Perl was built for.
+# Any arguments to the program will be appended with separator '-'
+# to allow flags like -gnu -debug and/or -static to be added.
+
+# Before Base has been built, use a command like this:
+# bash$ export EPICS_HOST_ARCH=`perl src/tools/EpicsHostArch.pl`
+#
+# If Base is already built, use
+# tcsh% setenv EPICS_HOST_ARCH `perl base/lib/perl/EpicsHostArch.pl`
+
+# If your architecture is not recognized by this script, please send
+# the output from running 'perl --version' to the EPICS tech-talk
+# mailing list to have it added.
+
+use strict;
use Config;
use POSIX;
-$suffix="";
-$suffix="-".$ARGV[0] if ($ARGV[0] ne "");
+print join('-', HostArch(), @ARGV), "\n";
-$EpicsHostArch = GetEpicsHostArch();
-print "$EpicsHostArch$suffix\n";
+sub HostArch {
+ my $arch = $Config{archname};
+ for ($arch) {
+ return 'linux-x86_64' if m/^x86_64-linux/;
+ return 'linux-x86' if m/^i[3-6]86-linux/;
+ return 'linux-arm' if m/^arm-linux/;
+ return 'windows-x64' if m/^MSWin32-x64/;
+ return 'win32-x86' if m/^MSWin32-x86/;
+ return "cygwin-x86_64" if m/^x86_64-cygwin/;
+ return "cygwin-x86" if m/^i[3-6]86-cygwin/;
+ return 'solaris-sparc' if m/^sun4-solaris/;
+ return 'solaris-x86' if m/^i86pc-solaris/;
-sub GetEpicsHostArch { # no args
- $arch=$Config{'archname'};
- if ($arch =~ /sun4-solaris/) { return "solaris-sparc";
- } elsif ($arch =~ m/i86pc-solaris/) { return "solaris-x86";
- } elsif ($arch =~ m/i[3-6]86-linux/){ return "linux-x86";
- } elsif ($arch =~ m/x86_64-linux/) { return "linux-x86_64";
- } elsif ($arch =~ m/arm-linux/) { return "linux-arm";
- } elsif ($arch =~ m/MSWin32-x86/) { return "win32-x86";
- } elsif ($arch =~ m/MSWin32-x64/) { return "windows-x64";
- } elsif ($arch =~ m/cygwin/) {
- my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname();
- if ($cpu =~ m/x86_64/) { return "cygwin-x86_64"; }
- return "cygwin-x86";
- } elsif ($arch =~ m/darwin/) {
- my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname();
- if ($cpu =~ m/Power Macintosh/) { return "darwin-ppc"; }
- elsif ($cpu =~ m/i386/) { return "darwin-x86"; }
- elsif ($cpu =~ m/x86_64/) { return "darwin-x86"; }
- else { return "unsupported"; }
- } else { return "unsupported"; }
+ my ($kernel, $hostname, $release, $version, $cpu) = uname;
+ if (m/^darwin/) {
+ for ($cpu) {
+ return 'darwin-x86' if m/^(i386|x86_64)/;
+ return 'darwin-ppc' if m/Power Macintosh/;
+ }
+ die "$0: macOS CPU type '$cpu' not recognized\n";
+ }
+
+ die "$0: Architecture '$arch' not recognized\n";
+ }
}
-
-#EOF EpicsHostArch.pl
-
From 8ffea9de2700d41fe526f0e151a0ad30f1787510 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Fri, 10 Aug 2018 14:12:19 -0500
Subject: [PATCH 32/55] Remove macLib warning indicators
Only add ',undefined' tags to macLib output when we aren't
suppressing warnings, e.g. using msi's -V flag.
---
documentation/RELEASE_NOTES.html | 19 +++++++--
src/ioc/dbtemplate/msi.html | 8 ++--
src/ioc/dbtemplate/test/msi.plt | 6 +--
src/ioc/dbtemplate/test/t1-result.txt | 2 +-
src/ioc/dbtemplate/test/t2-result.txt | 12 +++---
src/ioc/dbtemplate/test/t3-result.txt | 56 +++++++++++++--------------
src/ioc/dbtemplate/test/t4-result.txt | 12 +++---
src/ioc/dbtemplate/test/t5-result.txt | 8 ++--
src/ioc/dbtemplate/test/t6-result.txt | 8 ++--
src/ioc/dbtemplate/test/t7-result.txt | 21 ++++++++++
src/libCom/macLib/macCore.c | 9 ++++-
src/libCom/test/macLibTest.c | 8 +++-
12 files changed, 105 insertions(+), 64 deletions(-)
create mode 100644 src/ioc/dbtemplate/test/t7-result.txt
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 57baf3db1..9c6c43a90 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -16,13 +16,24 @@
+Warning indicators in msi (and macLib) output
+
+The libCom macro expansion library has been modified so that when the
+SUPPRESS_WARNINGS flag is set it will no longer include any ,undefined
+or ,recursive indicators in its output when undefined or recursive
+macros are encountered. These indicators were harmless when the output was fed
+into an IOC along with a definition for the macro, but when the msi
+tool was used to generate other kinds of files they caused problems. If the
+msi -V flag is used the markers will still be present in the output
+whenever the appropriate condition is seen.
+
Improvements to msi
In addition to fixing its response to discovering parsing errors in its
- substitution input file (reported as Launchpad
- bug #1503661)
- so it now deletes the incomplete output file, the msi program has been cleaned
- up a little bit internally.
+substitution input file (reported as Launchpad
+bug #1503661)
+so it now deletes the incomplete output file, the msi program has been cleaned
+up a little bit internally.
All array records now post monitors on their array-length fields
diff --git a/src/ioc/dbtemplate/msi.html b/src/ioc/dbtemplate/msi.html
index ff4341ead..b5929fc79 100644
--- a/src/ioc/dbtemplate/msi.html
+++ b/src/ioc/dbtemplate/msi.html
@@ -34,10 +34,10 @@ be written to stdout unless the -o option is given.