From 0c1874bbfe7ecf389f5929750a5d3f0e79a27c68 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Tue, 4 Dec 2018 16:53:47 -0500 Subject: [PATCH 01/85] Test expansion of empty patterns with MSI This was subject to a regression in 3.15.6. See lp:1810946. --- src/ioc/dbtemplate/test/msi.plt | 8 +++++++- src/ioc/dbtemplate/test/t10-result.txt | 4 ++++ src/ioc/dbtemplate/test/t10-substitute.txt | 8 ++++++++ src/ioc/dbtemplate/test/t10-template.txt | 2 ++ src/ioc/dbtemplate/test/t11-result.txt | 4 ++++ src/ioc/dbtemplate/test/t11-substitute.txt | 10 ++++++++++ src/ioc/dbtemplate/test/t11-template.txt | 2 ++ 7 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/ioc/dbtemplate/test/t10-result.txt create mode 100644 src/ioc/dbtemplate/test/t10-substitute.txt create mode 100644 src/ioc/dbtemplate/test/t10-template.txt create mode 100644 src/ioc/dbtemplate/test/t11-result.txt create mode 100644 src/ioc/dbtemplate/test/t11-substitute.txt create mode 100644 src/ioc/dbtemplate/test/t11-template.txt diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt index 414912583..332defb13 100644 --- a/src/ioc/dbtemplate/test/msi.plt +++ b/src/ioc/dbtemplate/test/msi.plt @@ -11,7 +11,7 @@ use strict; use Test; -BEGIN {plan tests => 9} +BEGIN {plan tests => 11} # Check include/substitute command model ok(msi('-I .. ../t1-template.txt'), slurp('../t1-result.txt')); @@ -50,6 +50,12 @@ ok(msi('-I.. -D -o t8.txt ../t1-template.txt'), slurp('../t8-result.txt')); # Dependency generation, dbLoadTemplate format ok(msi('-I.. -D -ot9.txt -S ../t2-substitution.txt'), slurp('../t9-result.txt')); +# Substitution file, variable format, with 0 variable definitions +ok(msi('-I. -I.. -S ../t10-substitute.txt'), slurp('../t10-result.txt')); + +# Substitution file, pattern format, with 0 pattern definitions +ok(msi('-I. -I.. -S ../t11-substitute.txt'), slurp('../t11-result.txt')); + # Test support routines diff --git a/src/ioc/dbtemplate/test/t10-result.txt b/src/ioc/dbtemplate/test/t10-result.txt new file mode 100644 index 000000000..47b594ecb --- /dev/null +++ b/src/ioc/dbtemplate/test/t10-result.txt @@ -0,0 +1,4 @@ +# comment line +a=$(a) +# comment line +a=gbl diff --git a/src/ioc/dbtemplate/test/t10-substitute.txt b/src/ioc/dbtemplate/test/t10-substitute.txt new file mode 100644 index 000000000..aec88bb6c --- /dev/null +++ b/src/ioc/dbtemplate/test/t10-substitute.txt @@ -0,0 +1,8 @@ +file t10-template.txt { + {} +} + +global { a=gbl } +file t10-template.txt { + {} +} diff --git a/src/ioc/dbtemplate/test/t10-template.txt b/src/ioc/dbtemplate/test/t10-template.txt new file mode 100644 index 000000000..7958885a7 --- /dev/null +++ b/src/ioc/dbtemplate/test/t10-template.txt @@ -0,0 +1,2 @@ +# comment line +a=$(a) diff --git a/src/ioc/dbtemplate/test/t11-result.txt b/src/ioc/dbtemplate/test/t11-result.txt new file mode 100644 index 000000000..47b594ecb --- /dev/null +++ b/src/ioc/dbtemplate/test/t11-result.txt @@ -0,0 +1,4 @@ +# comment line +a=$(a) +# comment line +a=gbl diff --git a/src/ioc/dbtemplate/test/t11-substitute.txt b/src/ioc/dbtemplate/test/t11-substitute.txt new file mode 100644 index 000000000..94dcdbc12 --- /dev/null +++ b/src/ioc/dbtemplate/test/t11-substitute.txt @@ -0,0 +1,10 @@ +file t11-template.txt { + pattern {} + {} +} + +global { a=gbl } +file t11-template.txt { + pattern {} + {} +} diff --git a/src/ioc/dbtemplate/test/t11-template.txt b/src/ioc/dbtemplate/test/t11-template.txt new file mode 100644 index 000000000..7958885a7 --- /dev/null +++ b/src/ioc/dbtemplate/test/t11-template.txt @@ -0,0 +1,2 @@ +# comment line +a=$(a) From 801c01b9b670d5072433f66cae7c052b6119da6e Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Thu, 3 Jan 2019 14:33:46 -0500 Subject: [PATCH 02/85] Convert MSI to C++ --- src/ioc/dbtemplate/Makefile | 2 +- src/ioc/dbtemplate/{msi.c => msi.cpp} | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) rename src/ioc/dbtemplate/{msi.c => msi.cpp} (97%) diff --git a/src/ioc/dbtemplate/Makefile b/src/ioc/dbtemplate/Makefile index 2aa5a0c78..13b4f11fb 100644 --- a/src/ioc/dbtemplate/Makefile +++ b/src/ioc/dbtemplate/Makefile @@ -13,7 +13,7 @@ SRC_DIRS += $(IOCDIR)/dbtemplate PROD_HOST += msi -msi_SRCS = msi.c +msi_SRCS = msi.cpp msi_LIBS += Com HTMLS += msi.html diff --git a/src/ioc/dbtemplate/msi.c b/src/ioc/dbtemplate/msi.cpp similarity index 97% rename from src/ioc/dbtemplate/msi.c rename to src/ioc/dbtemplate/msi.cpp index 69680e17e..59d2418d8 100644 --- a/src/ioc/dbtemplate/msi.c +++ b/src/ioc/dbtemplate/msi.cpp @@ -325,7 +325,7 @@ static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *tem /*skip quote and any trailing blanks*/ while (*++p == ' ') ; if (*p != '\n' && *p != 0) goto endcmd; - copy = calloc(pend-pstart + 1, sizeof(char)); + copy = static_cast(calloc(pend-pstart + 1, sizeof(char))); strncpy(copy, pstart, pend-pstart); switch(cmdind) { @@ -386,7 +386,7 @@ static void inputConstruct(inputData **ppvt) { inputData *pinputData; - pinputData = calloc(1, sizeof(inputData)); + pinputData = static_cast(calloc(1, sizeof(inputData))); ellInit(&pinputData->inputFileList); ellInit(&pinputData->pathList); *ppvt = pinputData; @@ -531,8 +531,8 @@ static void inputOpenFile(inputData *pinputData,char *filename) else { ppathNode = (pathNode *) ellFirst(ppathList); while (ppathNode) { - fullname = calloc(strlen(filename) + strlen(ppathNode->directory) + 2, - sizeof(char)); + fullname = static_cast(calloc(strlen(filename) + strlen(ppathNode->directory) + 2, + sizeof(char))); strcpy(fullname, ppathNode->directory); strcat(fullname, "/"); strcat(fullname, filename); @@ -552,7 +552,7 @@ static void inputOpenFile(inputData *pinputData,char *filename) } STEP("File opened"); - pinputFile = calloc(1, sizeof(inputFile)); + pinputFile = static_cast(calloc(1, sizeof(inputFile))); if (ppathNode) { pinputFile->filename = fullname; @@ -654,7 +654,7 @@ struct subInfo { static char *subGetNextLine(subFile *psubFile); static tokenType subGetNextToken(subFile *psubFile); -static void subFileErrPrint(subFile *psubFile,char * message); +static void subFileErrPrint(subFile *psubFile, const char * message); static void freeSubFile(subInfo *psubInfo); static void freePattern(subInfo *psubInfo); static void catMacroReplacements(subInfo *psubInfo,const char *value); @@ -704,9 +704,9 @@ static void substituteOpen(subInfo **ppvt, char *substitutionName) FILE *fp; ENTER; - psubInfo = calloc(1, sizeof(subInfo)); + psubInfo = static_cast(calloc(1, sizeof(subInfo))); *ppvt = psubInfo; - psubFile = calloc(1, sizeof(subFile)); + psubFile = static_cast(calloc(1, sizeof(subFile))); psubInfo->psubFile = psubFile; ellInit(&psubInfo->patternList); @@ -831,7 +831,7 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename) if (psubFile->token != tokenString) break; - ppatternNode = calloc(1, sizeof(patternNode)); + ppatternNode = static_cast(calloc(1, sizeof(patternNode))); ellAdd(&psubInfo->patternList, &ppatternNode->node); ppatternNode->var = epicsStrDup(psubFile->string); } @@ -1017,7 +1017,7 @@ static char *subGetNextLine(subFile *psubFile) return &psubFile->inputBuffer[0]; } -static void subFileErrPrint(subFile *psubFile,char * message) +static void subFileErrPrint(subFile *psubFile, const char * message) { fprintf(stderr, "msi: %s\n",message); fprintf(stderr, " in substitution file '%s' at line %d:\n %s", @@ -1117,7 +1117,7 @@ static void catMacroReplacements(subInfo *psubInfo, const char *value) STEP("Enlarging buffer"); if (newsize <= psubInfo->curLength + len) newsize = psubInfo->curLength + len + 1; - newbuf = calloc(1, newsize); + newbuf = static_cast(calloc(1, newsize)); if (!newbuf) { fprintf(stderr, "calloc failed for size %lu\n", (unsigned long) newsize); From d8f18c27f49a37678faa68c8d1722c3faa858ad8 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Fri, 4 Jan 2019 09:36:20 -0500 Subject: [PATCH 03/85] Add some const keywords --- src/ioc/dbtemplate/msi.cpp | 86 +++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 59d2418d8..5e67342d4 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -56,28 +56,31 @@ int din = 0; typedef struct inputData inputData; static void inputConstruct(inputData **ppvt); -static void inputDestruct(inputData *pvt); -static void inputAddPath(inputData *pvt, char *pval); -static void inputBegin(inputData *pvt, char *fileName); -static char *inputNextLine(inputData *pvt); -static void inputNewIncludeFile(inputData *pvt, char *name); -static void inputErrPrint(inputData *pvt); +static void inputDestruct(inputData * const pvt); +static void inputAddPath(inputData * const pvt, const char * const pval); +static void inputBegin(inputData * const pvt, const char * const fileName); +static char *inputNextLine(inputData * const pvt); +static void inputNewIncludeFile(inputData * const pvt, const char * const name); +static void inputErrPrint(const inputData * const pvt); /* Module to read the substitution file */ typedef struct subInfo subInfo; -static void substituteOpen(subInfo **ppvt, char *substitutionName); -static void substituteDestruct(subInfo *pvt); -static int substituteGetNextSet(subInfo *pvt, char **filename); -static int substituteGetGlobalSet(subInfo *pvt); -static char *substituteGetReplacements(subInfo *pvt); -static char *substituteGetGlobalReplacements(subInfo *pvt); +static void substituteOpen(subInfo **ppvt, char * const substitutionName); +static void substituteDestruct(subInfo * const pvt); +static int substituteGetNextSet(subInfo * const pvt, char **filename); +static int substituteGetGlobalSet(subInfo * const pvt); +static const char *substituteGetReplacements(subInfo * const pvt); +static const char *substituteGetGlobalReplacements(subInfo * const 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); +static void usageExit(const int status); +static void abortExit(const int status); +static void addMacroReplacements(MAC_HANDLE * const macPvt, + const char * const pval); +static void makeSubstitutions(inputData * const inputPvt, + MAC_HANDLE * const macPvt, + const char * const templateName); /*Global variables */ static int opt_V = 0; @@ -180,9 +183,9 @@ int main(int argc,char **argv) isGlobal = substituteGetGlobalSet(substitutePvt); if (isGlobal) { STEP("Handling global macros"); - pval = substituteGetGlobalReplacements(substitutePvt); - if (pval) - addMacroReplacements(macPvt, pval); + const char *macStr = substituteGetGlobalReplacements(substitutePvt); + if (macStr) + addMacroReplacements(macPvt, macStr); } else if ((isFile = substituteGetNextSet(substitutePvt, &filename))) { if (templateName) @@ -193,11 +196,12 @@ int main(int argc,char **argv) } STEPS("Handling template file", filename); - while ((pval = substituteGetReplacements(substitutePvt))) { + const char *macStr; + while ((macStr = substituteGetReplacements(substitutePvt))) { if (localScope) macPushScope(macPvt); - addMacroReplacements(macPvt, pval); + addMacroReplacements(macPvt, macStr); makeSubstitutions(inputPvt, macPvt, filename); if (localScope) @@ -218,7 +222,7 @@ int main(int argc,char **argv) return opt_V & 2; } -void usageExit(int status) +void usageExit(const int status) { fprintf(stderr, "Usage: msi [options] [template]\n" @@ -236,7 +240,7 @@ void usageExit(int status) exit(status); } -void abortExit(int status) +void abortExit(const int status) { if (outFile) { fclose(stdout); @@ -245,7 +249,8 @@ void abortExit(int status) exit(status); } -static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval) +static void addMacroReplacements(MAC_HANDLE * const macPvt, + const char * const pval) { char **pairs; long status; @@ -268,7 +273,9 @@ static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval) typedef enum {cmdInclude,cmdSubstitute} cmdType; static const char *cmdNames[] = {"include","substitute"}; -static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *templateName) +static void makeSubstitutions(inputData * const inputPvt, + MAC_HANDLE * const macPvt, + const char * const templateName) { char *input; static char buffer[MAX_BUFFER_SIZE]; @@ -378,7 +385,7 @@ struct inputData { char inputBuffer[MAX_BUFFER_SIZE]; }; -static void inputOpenFile(inputData *pinputData, char *filename); +static void inputOpenFile(inputData *pinputData, const char * const filename); static void inputCloseFile(inputData *pinputData); static void inputCloseAllFiles(inputData *pinputData); @@ -392,7 +399,7 @@ static void inputConstruct(inputData **ppvt) *ppvt = pinputData; } -static void inputDestruct(inputData *pinputData) +static void inputDestruct(inputData * const pinputData) { pathNode *ppathNode; @@ -405,7 +412,7 @@ static void inputDestruct(inputData *pinputData) free(pinputData); } -static void inputAddPath(inputData *pinputData, char *path) +static void inputAddPath(inputData * const pinputData, const char * const path) { ELLLIST *ppathList = &pinputData->pathList; pathNode *ppathNode; @@ -448,7 +455,7 @@ static void inputAddPath(inputData *pinputData, char *path) EXIT; } -static void inputBegin(inputData *pinputData, char *fileName) +static void inputBegin(inputData * const pinputData, const char * const fileName) { ENTER; inputCloseAllFiles(pinputData); @@ -456,7 +463,7 @@ static void inputBegin(inputData *pinputData, char *fileName) EXIT; } -static char *inputNextLine(inputData *pinputData) +static char *inputNextLine(inputData * const pinputData) { inputFile *pinputFile; char *pline; @@ -475,14 +482,15 @@ static char *inputNextLine(inputData *pinputData) return 0; } -static void inputNewIncludeFile(inputData *pinputData, char *name) +static void inputNewIncludeFile(inputData * const pinputData, + const char * const name) { ENTER; inputOpenFile(pinputData,name); EXIT; } -static void inputErrPrint(inputData *pinputData) +static void inputErrPrint(const inputData *const pinputData) { inputFile *pinputFile; @@ -511,7 +519,7 @@ static void inputErrPrint(inputData *pinputData) EXIT; } -static void inputOpenFile(inputData *pinputData,char *filename) +static void inputOpenFile(inputData *pinputData, const char * const filename) { ELLLIST *ppathList = &pinputData->pathList; pathNode *ppathNode = 0; @@ -688,7 +696,7 @@ void freePattern(subInfo *psubInfo) EXIT; } -static void substituteDestruct(subInfo *psubInfo) +static void substituteDestruct(subInfo * const psubInfo) { ENTER; freeSubFile(psubInfo); @@ -697,7 +705,7 @@ static void substituteDestruct(subInfo *psubInfo) EXIT; } -static void substituteOpen(subInfo **ppvt, char *substitutionName) +static void substituteOpen(subInfo **ppvt, char * const substitutionName) { subInfo *psubInfo; subFile *psubFile; @@ -725,7 +733,7 @@ static void substituteOpen(subInfo **ppvt, char *substitutionName) EXIT; } -static int substituteGetGlobalSet(subInfo *psubInfo) +static int substituteGetGlobalSet(subInfo * const psubInfo) { subFile *psubFile = psubInfo->psubFile; @@ -744,7 +752,7 @@ static int substituteGetGlobalSet(subInfo *psubInfo) return 0; } -static int substituteGetNextSet(subInfo *psubInfo,char **filename) +static int substituteGetNextSet(subInfo * const psubInfo,char **filename) { subFile *psubFile = psubInfo->psubFile; patternNode *ppatternNode; @@ -846,7 +854,7 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename) return 1; } -static char *substituteGetGlobalReplacements(subInfo *psubInfo) +static const char *substituteGetGlobalReplacements(subInfo * const psubInfo) { subFile *psubFile = psubInfo->psubFile; @@ -902,7 +910,7 @@ static char *substituteGetGlobalReplacements(subInfo *psubInfo) } } -static char *substituteGetReplacements(subInfo *psubInfo) +static const char *substituteGetReplacements(subInfo * const psubInfo) { subFile *psubFile = psubInfo->psubFile; patternNode *ppatternNode; From 3e8b0028dc790912e6663a0cdd8a6536d2d46a4c Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Fri, 4 Jan 2019 13:53:07 -0500 Subject: [PATCH 04/85] Constructor for struct subInfo --- src/ioc/dbtemplate/msi.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 5e67342d4..21957768e 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -658,6 +658,8 @@ struct subInfo { size_t size; size_t curLength; char *macroReplacements; + subInfo() : psubFile(nullptr), isFile(0), filename(nullptr), isPattern(0), + size(0), curLength(0), macroReplacements(nullptr) {}; }; static char *subGetNextLine(subFile *psubFile); @@ -701,7 +703,7 @@ static void substituteDestruct(subInfo * const psubInfo) ENTER; freeSubFile(psubInfo); freePattern(psubInfo); - free(psubInfo); + delete(psubInfo); EXIT; } @@ -712,7 +714,7 @@ static void substituteOpen(subInfo **ppvt, char * const substitutionName) FILE *fp; ENTER; - psubInfo = static_cast(calloc(1, sizeof(subInfo))); + psubInfo = new subInfo; *ppvt = psubInfo; psubFile = static_cast(calloc(1, sizeof(subFile))); psubInfo->psubFile = psubFile; From 1cf3fa9ba989632bf31d38e51cc9fd80657ce541 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Fri, 4 Jan 2019 14:01:55 -0500 Subject: [PATCH 05/85] Simplify catMacroReplacements() This fixes lp:1810946 and lp:1810949. --- src/ioc/dbtemplate/msi.cpp | 55 +++++++++----------------------------- 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 21957768e..9a370e8b5 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -9,6 +9,8 @@ /* msi - macro substitutions and include */ +#include + #include #include #include @@ -655,11 +657,8 @@ struct subInfo { char *filename; int isPattern; ELLLIST patternList; - size_t size; - size_t curLength; - char *macroReplacements; - subInfo() : psubFile(nullptr), isFile(0), filename(nullptr), isPattern(0), - size(0), curLength(0), macroReplacements(nullptr) {}; + std::string macroReplacements; + subInfo() : psubFile(NULL), isFile(0), filename(NULL), isPattern(0) {}; }; static char *subGetNextLine(subFile *psubFile); @@ -861,9 +860,7 @@ static const char *substituteGetGlobalReplacements(subInfo * const psubInfo) subFile *psubFile = psubInfo->psubFile; ENTER; - if (psubInfo->macroReplacements) - psubInfo->macroReplacements[0] = 0; - psubInfo->curLength = 0; + psubInfo->macroReplacements.clear(); while (psubFile->token == tokenSeparator) subGetNextToken(psubFile); @@ -891,8 +888,8 @@ static const char *substituteGetGlobalReplacements(subInfo * const psubInfo) switch(subGetNextToken(psubFile)) { case tokenRBrace: subGetNextToken(psubFile); - EXITS(psubInfo->macroReplacements); - return psubInfo->macroReplacements; + EXITS(psubInfo->macroReplacements.c_str()); + return psubInfo->macroReplacements.c_str(); case tokenSeparator: catMacroReplacements(psubInfo, ","); @@ -918,9 +915,7 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) patternNode *ppatternNode; ENTER; - if (psubInfo->macroReplacements) - psubInfo->macroReplacements[0] = 0; - psubInfo->curLength = 0; + psubInfo->macroReplacements.clear(); while (psubFile->token == tokenSeparator) subGetNextToken(psubFile); @@ -953,8 +948,8 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) while (1) { if (psubFile->token == tokenRBrace) { subGetNextToken(psubFile); - EXITS(psubInfo->macroReplacements); - return psubInfo->macroReplacements; + EXITS(psubInfo->macroReplacements.c_str()); + return psubInfo->macroReplacements.c_str(); } if (psubFile->token != tokenString) { @@ -983,8 +978,8 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) switch(subGetNextToken(psubFile)) { case tokenRBrace: subGetNextToken(psubFile); - EXITS(psubInfo->macroReplacements); - return psubInfo->macroReplacements; + EXITS(psubInfo->macroReplacements.c_str()); + return psubInfo->macroReplacements.c_str(); case tokenSeparator: catMacroReplacements(psubInfo, ","); @@ -1117,32 +1112,8 @@ done: static void catMacroReplacements(subInfo *psubInfo, const char *value) { - size_t len = strlen(value); - ENTER; - if (psubInfo->size <= (psubInfo->curLength + len)) { - size_t newsize = psubInfo->size + MAX_BUFFER_SIZE; - char *newbuf; - - STEP("Enlarging buffer"); - if (newsize <= psubInfo->curLength + len) - newsize = psubInfo->curLength + len + 1; - newbuf = static_cast(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); - free(psubInfo->macroReplacements); - } - psubInfo->size = newsize; - psubInfo->macroReplacements = newbuf; - } - STEPS("Appending", value); - strcat(psubInfo->macroReplacements, value); - psubInfo->curLength += len; + psubInfo->macroReplacements += value; EXIT; } From db9267bbd52bbc1c47f711a2608c191c1e28e723 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Fri, 4 Jan 2019 14:48:46 -0500 Subject: [PATCH 06/85] Constructor for struct inputData --- src/ioc/dbtemplate/msi.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 9a370e8b5..7891aa53c 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -385,6 +385,7 @@ struct inputData { ELLLIST inputFileList; ELLLIST pathList; char inputBuffer[MAX_BUFFER_SIZE]; + inputData() { memset(inputBuffer, 0, sizeof(inputBuffer) * sizeof(inputBuffer[0])); }; }; static void inputOpenFile(inputData *pinputData, const char * const filename); @@ -395,7 +396,7 @@ static void inputConstruct(inputData **ppvt) { inputData *pinputData; - pinputData = static_cast(calloc(1, sizeof(inputData))); + pinputData = new inputData; ellInit(&pinputData->inputFileList); ellInit(&pinputData->pathList); *ppvt = pinputData; @@ -411,7 +412,7 @@ static void inputDestruct(inputData * const pinputData) free(ppathNode->directory); free(ppathNode); } - free(pinputData); + delete(pinputData); } static void inputAddPath(inputData * const pinputData, const char * const path) From 265d4962a494c284cdba4a445bc2bc23ba3fee1a Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Fri, 4 Jan 2019 16:42:03 -0500 Subject: [PATCH 07/85] Use std::list for inputFileList This improves type safety and readability. --- src/ioc/dbtemplate/msi.cpp | 68 +++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 7891aa53c..919894760 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -10,6 +10,7 @@ /* msi - macro substitutions and include */ #include +#include #include #include @@ -370,7 +371,6 @@ endcmd: } typedef struct inputFile { - ELLNODE node; char *filename; FILE *fp; int lineNum; @@ -382,7 +382,7 @@ typedef struct pathNode { } pathNode; struct inputData { - ELLLIST inputFileList; + std::list inputFileList; ELLLIST pathList; char inputBuffer[MAX_BUFFER_SIZE]; inputData() { memset(inputBuffer, 0, sizeof(inputBuffer) * sizeof(inputBuffer[0])); }; @@ -397,7 +397,6 @@ static void inputConstruct(inputData **ppvt) inputData *pinputData; pinputData = new inputData; - ellInit(&pinputData->inputFileList); ellInit(&pinputData->pathList); *ppvt = pinputData; } @@ -468,14 +467,15 @@ static void inputBegin(inputData * const pinputData, const char * const fileName static char *inputNextLine(inputData * const pinputData) { - inputFile *pinputFile; + std::list& inFileList = pinputData->inputFileList; char *pline; ENTER; - while ((pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList))) { - pline = fgets(pinputData->inputBuffer, MAX_BUFFER_SIZE, pinputFile->fp); + while (!inFileList.empty()) { + inputFile& inFile = inFileList.front(); + pline = fgets(pinputData->inputBuffer, MAX_BUFFER_SIZE, inFile.fp); if (pline) { - ++pinputFile->lineNum; + ++inFile.lineNum; EXITS(pline); return pline; } @@ -495,23 +495,21 @@ static void inputNewIncludeFile(inputData * const pinputData, static void inputErrPrint(const inputData *const pinputData) { - inputFile *pinputFile; - ENTER; fprintf(stderr, "input: '%s' at ", pinputData->inputBuffer); - pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList); - while (pinputFile) { - fprintf(stderr, "line %d of ", pinputFile->lineNum); + const std::list& inFileList = pinputData->inputFileList; + std::list::const_iterator inFileIt = inFileList.begin(); + while (inFileIt != inFileList.end()) { + fprintf(stderr, "line %d of ", inFileIt->lineNum); - if (pinputFile->filename) { - fprintf(stderr, " file %s\n", pinputFile->filename); + if (inFileIt->filename) { + fprintf(stderr, " file %s\n", inFileIt->filename); } else { fprintf(stderr, "stdin:\n"); } - pinputFile = (inputFile *) ellNext(&pinputFile->node); - if (pinputFile) { + if (++inFileIt != inFileList.end()) { fprintf(stderr, " included from "); } else { @@ -526,7 +524,6 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) { ELLLIST *ppathList = &pinputData->pathList; pathNode *ppathNode = 0; - inputFile *pinputFile; char *fullname = 0; FILE *fp = 0; @@ -563,20 +560,20 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) } STEP("File opened"); - pinputFile = static_cast(calloc(1, sizeof(inputFile))); + inputFile inFile = inputFile(); if (ppathNode) { - pinputFile->filename = fullname; + inFile.filename = fullname; } else if (filename) { - pinputFile->filename = epicsStrDup(filename); + inFile.filename = epicsStrDup(filename); } else { - pinputFile->filename = epicsStrDup("stdin"); + inFile.filename = epicsStrDup("stdin"); } if (opt_D) { - int hash = epicsStrHash(pinputFile->filename, 12345); + int hash = epicsStrHash(inFile.filename, 12345); int i = 0; int match = 0; @@ -589,7 +586,7 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) if (!match) { const char *wrap = numDeps ? " \\\n" : ""; - printf("%s %s", wrap, pinputFile->filename); + printf("%s %s", wrap, inFile.filename); if (numDeps < MAX_DEPS) { depHashes[numDeps++] = hash; } @@ -600,33 +597,30 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) } } - pinputFile->fp = fp; - ellInsert(&pinputData->inputFileList, 0, &pinputFile->node); + inFile.fp = fp; + pinputData->inputFileList.push_front(inFile); EXIT; } static void inputCloseFile(inputData *pinputData) { - inputFile *pinputFile; - + std::list& inFileList = pinputData->inputFileList; 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); + if(!inFileList.empty()) { + inputFile& inFile = inFileList.front(); + if (fclose(inFile.fp)) + fprintf(stderr, "msi: Can't close input file '%s'\n", inFile.filename); + free(inFile.filename); + inFileList.erase(inFileList.begin()); } EXIT; } static void inputCloseAllFiles(inputData *pinputData) { - inputFile *pinputFile; - ENTER; - while ((pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList))) { + const std::list& inFileList = pinputData->inputFileList; + while(!inFileList.empty()) { inputCloseFile(pinputData); } EXIT; From ef2a381e92d7aa6f09ffe7b6289f1999e33277d2 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sat, 5 Jan 2019 12:33:11 -0500 Subject: [PATCH 08/85] Use std::list for pathList This improves type safety and readability. --- src/ioc/dbtemplate/msi.cpp | 47 ++++++++++++-------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 919894760..ab69b0cc4 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -376,14 +376,9 @@ typedef struct inputFile { int lineNum; } inputFile; -typedef struct pathNode { - ELLNODE node; - char *directory; -} pathNode; - struct inputData { std::list inputFileList; - ELLLIST pathList; + std::list pathList; char inputBuffer[MAX_BUFFER_SIZE]; inputData() { memset(inputBuffer, 0, sizeof(inputBuffer) * sizeof(inputBuffer[0])); }; }; @@ -397,27 +392,17 @@ static void inputConstruct(inputData **ppvt) inputData *pinputData; pinputData = new inputData; - ellInit(&pinputData->pathList); *ppvt = pinputData; } static void inputDestruct(inputData * const pinputData) { - pathNode *ppathNode; - inputCloseAllFiles(pinputData); - while ((ppathNode = (pathNode *) ellFirst(&pinputData->pathList))) { - ellDelete(&pinputData->pathList, &ppathNode->node); - free(ppathNode->directory); - free(ppathNode); - } delete(pinputData); } static void inputAddPath(inputData * const pinputData, const char * const path) { - ELLLIST *ppathList = &pinputData->pathList; - pathNode *ppathNode; const char *pcolon; const char *pdir; size_t len; @@ -431,15 +416,12 @@ static void inputAddPath(inputData * const pinputData, const char * const path) emptyName = ((*pdir == sep) ? 1 : 0); if (emptyName) ++pdir; - ppathNode = (pathNode *) calloc(1, sizeof(pathNode)); - ellAdd(ppathList, &ppathNode->node); - + std::string directory; 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); + directory = std::string(pdir, len); pdir = pcolon; /*unless at end skip past first colon*/ if (pdir && *(pdir + 1) != 0) ++pdir; @@ -450,9 +432,10 @@ static void inputAddPath(inputData * const pinputData, const char * const path) } if (emptyName) { - ppathNode->directory = (char *) calloc(2, sizeof(char)); - strcpy(ppathNode->directory, "."); + directory = "."; } + + pinputData->pathList.push_back(directory); } EXIT; } @@ -522,8 +505,8 @@ static void inputErrPrint(const inputData *const pinputData) static void inputOpenFile(inputData *pinputData, const char * const filename) { - ELLLIST *ppathList = &pinputData->pathList; - pathNode *ppathNode = 0; + std::list& pathList = pinputData->pathList; + std::list::iterator pathIt = pathList.end(); char *fullname = 0; FILE *fp = 0; @@ -532,16 +515,16 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) STEP("Using stdin"); fp = stdin; } - else if ((ellCount(ppathList) == 0) || strchr(filename, '/')){ + else if (pathList.empty() || strchr(filename, '/')){ STEPS("Opening ", filename); fp = fopen(filename, "r"); } else { - ppathNode = (pathNode *) ellFirst(ppathList); - while (ppathNode) { - fullname = static_cast(calloc(strlen(filename) + strlen(ppathNode->directory) + 2, + pathIt = pathList.begin(); + while(pathIt != pathList.end()) { + fullname = static_cast(calloc(strlen(filename) + pathIt->length() + 2, sizeof(char))); - strcpy(fullname, ppathNode->directory); + strcpy(fullname, pathIt->c_str()); strcat(fullname, "/"); strcat(fullname, filename); STEPS("Trying", filename); @@ -549,7 +532,7 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) if (fp) break; free(fullname); - ppathNode = (pathNode *) ellNext(&ppathNode->node); + ++pathIt; } } @@ -562,7 +545,7 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) STEP("File opened"); inputFile inFile = inputFile(); - if (ppathNode) { + if (pathIt != pathList.end()) { inFile.filename = fullname; } else if (filename) { From e461d782f41930a367f09bd8581c1a7f17286e23 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sat, 5 Jan 2019 12:57:26 -0500 Subject: [PATCH 09/85] Simplify inputConstruct() --- src/ioc/dbtemplate/msi.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index ab69b0cc4..a48e8ff08 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -389,10 +389,7 @@ static void inputCloseAllFiles(inputData *pinputData); static void inputConstruct(inputData **ppvt) { - inputData *pinputData; - - pinputData = new inputData; - *ppvt = pinputData; + *ppvt = new inputData; } static void inputDestruct(inputData * const pinputData) From b518ebe85bc615583d46ab4f2ed0d30c9748e744 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sat, 5 Jan 2019 16:08:55 -0500 Subject: [PATCH 10/85] Convert inputFile.filename to std::string --- src/ioc/dbtemplate/msi.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index a48e8ff08..70e0f1ff6 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -371,7 +371,7 @@ endcmd: } typedef struct inputFile { - char *filename; + std::string filename; FILE *fp; int lineNum; } inputFile; @@ -482,8 +482,8 @@ static void inputErrPrint(const inputData *const pinputData) while (inFileIt != inFileList.end()) { fprintf(stderr, "line %d of ", inFileIt->lineNum); - if (inFileIt->filename) { - fprintf(stderr, " file %s\n", inFileIt->filename); + if (!inFileIt->filename.empty()) { + fprintf(stderr, " file %s\n", inFileIt->filename.c_str()); } else { fprintf(stderr, "stdin:\n"); @@ -546,14 +546,15 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) inFile.filename = fullname; } else if (filename) { - inFile.filename = epicsStrDup(filename); + inFile.filename = filename; } else { - inFile.filename = epicsStrDup("stdin"); + inFile.filename = "stdin"; } + free(fullname); if (opt_D) { - int hash = epicsStrHash(inFile.filename, 12345); + int hash = epicsStrHash(inFile.filename.c_str(), 12345); int i = 0; int match = 0; @@ -566,7 +567,7 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) if (!match) { const char *wrap = numDeps ? " \\\n" : ""; - printf("%s %s", wrap, inFile.filename); + printf("%s %s", wrap, inFile.filename.c_str()); if (numDeps < MAX_DEPS) { depHashes[numDeps++] = hash; } @@ -589,8 +590,7 @@ static void inputCloseFile(inputData *pinputData) if(!inFileList.empty()) { inputFile& inFile = inFileList.front(); if (fclose(inFile.fp)) - fprintf(stderr, "msi: Can't close input file '%s'\n", inFile.filename); - free(inFile.filename); + fprintf(stderr, "msi: Can't close input file '%s'\n", inFile.filename.c_str()); inFileList.erase(inFileList.begin()); } EXIT; From b4f4fb853dd59cd94e5d06f25ca985d220733fa0 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sat, 5 Jan 2019 16:15:40 -0500 Subject: [PATCH 11/85] Convert fullname to std::string --- src/ioc/dbtemplate/msi.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 70e0f1ff6..c52a02b7f 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -504,7 +504,7 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) { std::list& pathList = pinputData->pathList; std::list::iterator pathIt = pathList.end(); - char *fullname = 0; + std::string fullname; FILE *fp = 0; ENTER; @@ -519,16 +519,11 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) else { pathIt = pathList.begin(); while(pathIt != pathList.end()) { - fullname = static_cast(calloc(strlen(filename) + pathIt->length() + 2, - sizeof(char))); - strcpy(fullname, pathIt->c_str()); - strcat(fullname, "/"); - strcat(fullname, filename); + fullname = *pathIt + "/" + filename; STEPS("Trying", filename); - fp = fopen(fullname, "r"); + fp = fopen(fullname.c_str(), "r"); if (fp) break; - free(fullname); ++pathIt; } } @@ -551,7 +546,6 @@ static void inputOpenFile(inputData *pinputData, const char * const filename) else { inFile.filename = "stdin"; } - free(fullname); if (opt_D) { int hash = epicsStrHash(inFile.filename.c_str(), 12345); From f03f10e6643e122f455f5a30974d9b958dc8388d Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sat, 5 Jan 2019 17:28:52 -0500 Subject: [PATCH 12/85] Convert patternNode.var to std::string --- src/ioc/dbtemplate/msi.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index c52a02b7f..bafa49ff8 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -617,7 +617,7 @@ typedef struct subFile { typedef struct patternNode { ELLNODE node; - char *var; + std::string var; } patternNode; struct subInfo { @@ -659,7 +659,6 @@ void freePattern(subInfo *psubInfo) ENTER; while ((ppatternNode = (patternNode *) ellFirst(&psubInfo->patternList))) { ellDelete(&psubInfo->patternList, &ppatternNode->node); - free(ppatternNode->var); free(ppatternNode); } psubInfo->isPattern = 0; @@ -811,7 +810,7 @@ static int substituteGetNextSet(subInfo * const psubInfo,char **filename) ppatternNode = static_cast(calloc(1, sizeof(patternNode))); ellAdd(&psubInfo->patternList, &ppatternNode->node); - ppatternNode->var = epicsStrDup(psubFile->string); + ppatternNode->var = psubFile->string; } if (psubFile->token != tokenRBrace) { @@ -931,7 +930,7 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) gotFirstPattern = 1; if (ppatternNode) { - catMacroReplacements(psubInfo, ppatternNode->var); + catMacroReplacements(psubInfo, ppatternNode->var.c_str()); catMacroReplacements(psubInfo, "="); catMacroReplacements(psubInfo, psubFile->string); ppatternNode = (patternNode *) ellNext(&ppatternNode->node); From ce38caf41b488ead6bb966472b84b1e927ad9910 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sat, 5 Jan 2019 18:00:11 -0500 Subject: [PATCH 13/85] Use std::list for patternList This improves type safety and readability. --- src/ioc/dbtemplate/msi.cpp | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index bafa49ff8..66a5761b1 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -615,17 +614,12 @@ typedef struct subFile { char string[MAX_BUFFER_SIZE]; } subFile; -typedef struct patternNode { - ELLNODE node; - std::string var; -} patternNode; - struct subInfo { subFile *psubFile; int isFile; char *filename; int isPattern; - ELLLIST patternList; + std::list patternList; std::string macroReplacements; subInfo() : psubFile(NULL), isFile(0), filename(NULL), isPattern(0) {}; }; @@ -654,13 +648,8 @@ void freeSubFile(subInfo *psubInfo) void freePattern(subInfo *psubInfo) { - patternNode *ppatternNode; - ENTER; - while ((ppatternNode = (patternNode *) ellFirst(&psubInfo->patternList))) { - ellDelete(&psubInfo->patternList, &ppatternNode->node); - free(ppatternNode); - } + psubInfo->patternList.clear(); psubInfo->isPattern = 0; EXIT; } @@ -685,7 +674,6 @@ static void substituteOpen(subInfo **ppvt, char * const substitutionName) *ppvt = psubInfo; psubFile = static_cast(calloc(1, sizeof(subFile))); psubInfo->psubFile = psubFile; - ellInit(&psubInfo->patternList); fp = fopen(substitutionName, "r"); if (!fp) { @@ -724,7 +712,6 @@ static int substituteGetGlobalSet(subInfo * const psubInfo) static int substituteGetNextSet(subInfo * const psubInfo,char **filename) { subFile *psubFile = psubInfo->psubFile; - patternNode *ppatternNode; ENTER; *filename = 0; @@ -808,9 +795,7 @@ static int substituteGetNextSet(subInfo * const psubInfo,char **filename) if (psubFile->token != tokenString) break; - ppatternNode = static_cast(calloc(1, sizeof(patternNode))); - ellAdd(&psubInfo->patternList, &ppatternNode->node); - ppatternNode->var = psubFile->string; + psubInfo->patternList.push_back(psubFile->string); } if (psubFile->token != tokenRBrace) { @@ -880,7 +865,6 @@ static const char *substituteGetGlobalReplacements(subInfo * const psubInfo) static const char *substituteGetReplacements(subInfo * const psubInfo) { subFile *psubFile = psubInfo->psubFile; - patternNode *ppatternNode; ENTER; psubInfo->macroReplacements.clear(); @@ -912,7 +896,8 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) int gotFirstPattern = 0; while (subGetNextToken(psubFile) == tokenSeparator); - ppatternNode = (patternNode *) ellFirst(&psubInfo->patternList); + std::list& patternList = psubInfo->patternList; + std::list::iterator patternIt = patternList.begin(); while (1) { if (psubFile->token == tokenRBrace) { subGetNextToken(psubFile); @@ -929,11 +914,11 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) catMacroReplacements(psubInfo, ","); gotFirstPattern = 1; - if (ppatternNode) { - catMacroReplacements(psubInfo, ppatternNode->var.c_str()); + if (patternIt != patternList.end()) { + catMacroReplacements(psubInfo, patternIt->c_str()); catMacroReplacements(psubInfo, "="); catMacroReplacements(psubInfo, psubFile->string); - ppatternNode = (patternNode *) ellNext(&ppatternNode->node); + ++patternIt; } else { subFileErrPrint(psubFile, "Warning, too many values given"); From 68a1a529b26079d6c61377137de068929a8316d5 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sat, 5 Jan 2019 18:51:16 -0500 Subject: [PATCH 14/85] Convert copy to std::string --- src/ioc/dbtemplate/msi.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 66a5761b1..ba3c4aed9 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -301,7 +301,6 @@ static void makeSubstitutions(inputData * const inputPvt, if (command) { char *pstart; char *pend; - char *copy; int cmdind=-1; int i; @@ -334,16 +333,15 @@ static void makeSubstitutions(inputData * const inputPvt, /*skip quote and any trailing blanks*/ while (*++p == ' ') ; if (*p != '\n' && *p != 0) goto endcmd; - copy = static_cast(calloc(pend-pstart + 1, sizeof(char))); - strncpy(copy, pstart, pend-pstart); + std::string copy = std::string(pstart, pend); switch(cmdind) { case cmdInclude: - inputNewIncludeFile(inputPvt,copy); + inputNewIncludeFile(inputPvt, copy.c_str()); break; case cmdSubstitute: - addMacroReplacements(macPvt,copy); + addMacroReplacements(macPvt, copy.c_str()); break; default: @@ -351,7 +349,6 @@ static void makeSubstitutions(inputData * const inputPvt, inputErrPrint(inputPvt); abortExit(1); } - free(copy); expand = 0; } From 940814becfa5a1cd5abaeb98920364682442fb8d Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sat, 5 Jan 2019 20:46:37 -0500 Subject: [PATCH 15/85] Manage psubFile with new/delete --- src/ioc/dbtemplate/msi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index ba3c4aed9..4aa433c5d 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -637,7 +637,7 @@ void freeSubFile(subInfo *psubInfo) if (fclose(psubFile->fp)) fprintf(stderr, "msi: Can't close substitution file\n"); } - free(psubFile); + delete(psubFile); free(psubInfo->filename); psubInfo->psubFile = 0; EXIT; @@ -669,7 +669,7 @@ static void substituteOpen(subInfo **ppvt, char * const substitutionName) ENTER; psubInfo = new subInfo; *ppvt = psubInfo; - psubFile = static_cast(calloc(1, sizeof(subFile))); + psubFile = new subFile; psubInfo->psubFile = psubFile; fp = fopen(substitutionName, "r"); From 87f6c3dec94279b890fe04dc102ddbf3f143473a Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sun, 6 Jan 2019 00:07:23 -0500 Subject: [PATCH 16/85] Remove unneeded errlogFlush() --- src/ioc/dbtemplate/msi.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 4aa433c5d..fe18b0ea9 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -213,7 +212,6 @@ int main(int argc,char **argv) } while (isGlobal || isFile); substituteDestruct(substitutePvt); } - errlogFlush(); macDeleteHandle(macPvt); inputDestruct(inputPvt); if (opt_D) { From 84dba0d2b702091900d2f2ed2f6296f8935172b5 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Sun, 6 Jan 2019 00:20:46 -0500 Subject: [PATCH 17/85] Use bool for more clarity --- src/ioc/dbtemplate/msi.cpp | 63 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index fe18b0ea9..2c5277811 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -69,8 +69,8 @@ typedef struct subInfo subInfo; static void substituteOpen(subInfo **ppvt, char * const substitutionName); static void substituteDestruct(subInfo * const pvt); -static int substituteGetNextSet(subInfo * const pvt, char **filename); -static int substituteGetGlobalSet(subInfo * const pvt); +static bool substituteGetNextSet(subInfo * const pvt, char **filename); +static bool substituteGetGlobalSet(subInfo * const pvt); static const char *substituteGetReplacements(subInfo * const pvt); static const char *substituteGetGlobalReplacements(subInfo * const pvt); @@ -85,7 +85,7 @@ static void makeSubstitutions(inputData * const inputPvt, /*Global variables */ static int opt_V = 0; -static int opt_D = 0; +static bool opt_D = false; static char *outFile = 0; static int numDeps = 0, depHashes[MAX_DEPS]; @@ -100,7 +100,7 @@ int main(int argc,char **argv) char *substitutionName = 0; char *templateName = 0; int i; - int localScope = 1; + bool localScope = true; inputConstruct(&inputPvt); macCreateHandle(&macPvt, 0); @@ -112,7 +112,7 @@ int main(int argc,char **argv) inputAddPath(inputPvt, pval); } else if (strcmp(argv[1], "-D") == 0) { - opt_D = 1; + opt_D = true; narg = 1; /* no argument for this option */ } else if(strncmp(argv[1], "-o", 2) == 0) { @@ -129,7 +129,7 @@ int main(int argc,char **argv) narg = 1; /* no argument for this option */ } else if (strcmp(argv[1], "-g") == 0) { - localScope = 0; + localScope = false; narg = 1; /* no argument for this option */ } else if (strcmp(argv[1], "-h") == 0) { @@ -176,7 +176,7 @@ int main(int argc,char **argv) else { subInfo *substitutePvt; char *filename = 0; - int isGlobal, isFile; + bool isGlobal, isFile; STEPS("Substitutions from file", substitutionName); substituteOpen(&substitutePvt, substitutionName); @@ -397,14 +397,14 @@ static void inputAddPath(inputData * const pinputData, const char * const path) const char *pcolon; const char *pdir; size_t len; - int emptyName; + bool 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) { - emptyName = ((*pdir == sep) ? 1 : 0); + emptyName = (*pdir == sep); if (emptyName) ++pdir; std::string directory; @@ -418,7 +418,7 @@ static void inputAddPath(inputData * const pinputData, const char * const path) if (pdir && *(pdir + 1) != 0) ++pdir; } else { /*must have been trailing : */ - emptyName = 1; + emptyName = true; } } @@ -611,12 +611,13 @@ typedef struct subFile { struct subInfo { subFile *psubFile; - int isFile; + bool isFile; char *filename; - int isPattern; + bool isPattern; std::list patternList; std::string macroReplacements; - subInfo() : psubFile(NULL), isFile(0), filename(NULL), isPattern(0) {}; + subInfo() : psubFile(NULL), isFile(false), filename(NULL), + isPattern(false) {}; }; static char *subGetNextLine(subFile *psubFile); @@ -645,7 +646,7 @@ void freePattern(subInfo *psubInfo) { ENTER; psubInfo->patternList.clear(); - psubInfo->isPattern = 0; + psubInfo->isPattern = false; EXIT; } @@ -685,7 +686,7 @@ static void substituteOpen(subInfo **ppvt, char * const substitutionName) EXIT; } -static int substituteGetGlobalSet(subInfo * const psubInfo) +static bool substituteGetGlobalSet(subInfo * const psubInfo) { subFile *psubFile = psubInfo->psubFile; @@ -697,14 +698,14 @@ static int substituteGetGlobalSet(subInfo * const psubInfo) strcmp(psubFile->string, "global") == 0) { subGetNextToken(psubFile); EXITD(1); - return 1; + return true; } EXITD(0); - return 0; + return false; } -static int substituteGetNextSet(subInfo * const psubInfo,char **filename) +static bool substituteGetNextSet(subInfo * const psubInfo,char **filename) { subFile *psubFile = psubInfo->psubFile; @@ -715,7 +716,7 @@ static int substituteGetNextSet(subInfo * const psubInfo,char **filename) if (psubFile->token == tokenEOF) { EXITD(0); - return 0; + return false; } if (psubFile->token == tokenString && @@ -723,7 +724,7 @@ static int substituteGetNextSet(subInfo * const psubInfo,char **filename) size_t len; STEP("Parsed 'file'"); - psubInfo->isFile = 1; + psubInfo->isFile = true; if (subGetNextToken(psubFile) != tokenString) { subFileErrPrint(psubFile, "Parse error, expecting a filename"); abortExit(1); @@ -758,7 +759,7 @@ static int substituteGetNextSet(subInfo * const psubInfo,char **filename) if (psubFile->token == tokenLBrace) { EXITD(1); - return 1; + return true; } if (psubFile->token == tokenRBrace) { @@ -774,7 +775,7 @@ static int substituteGetNextSet(subInfo * const psubInfo,char **filename) STEP("Parsed 'pattern'"); freePattern(psubInfo); - psubInfo->isPattern = 1; + psubInfo->isPattern = true; while (subGetNextToken(psubFile) == tokenSeparator); @@ -784,7 +785,7 @@ static int substituteGetNextSet(subInfo * const psubInfo,char **filename) } STEP("Parsed '{'"); - while (1) { + while (true) { while (subGetNextToken(psubFile) == tokenSeparator); if (psubFile->token != tokenString) @@ -800,7 +801,7 @@ static int substituteGetNextSet(subInfo * const psubInfo,char **filename) subGetNextToken(psubFile); EXITD(1); - return 1; + return true; } static const char *substituteGetGlobalReplacements(subInfo * const psubInfo) @@ -814,7 +815,7 @@ static const char *substituteGetGlobalReplacements(subInfo * const psubInfo) subGetNextToken(psubFile); if (psubFile->token == tokenRBrace && psubInfo->isFile) { - psubInfo->isFile = 0; + psubInfo->isFile = false; free(psubInfo->filename); psubInfo->filename = 0; freePattern(psubInfo); @@ -832,7 +833,7 @@ static const char *substituteGetGlobalReplacements(subInfo * const psubInfo) return 0; } - while (1) { + while (true) { switch(subGetNextToken(psubFile)) { case tokenRBrace: subGetNextToken(psubFile); @@ -868,7 +869,7 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) subGetNextToken(psubFile); if (psubFile->token==tokenRBrace && psubInfo->isFile) { - psubInfo->isFile = 0; + psubInfo->isFile = false; free(psubInfo->filename); psubInfo->filename = 0; freePattern(psubInfo); @@ -888,12 +889,12 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) } if (psubInfo->isPattern) { - int gotFirstPattern = 0; + bool gotFirstPattern = false; while (subGetNextToken(psubFile) == tokenSeparator); std::list& patternList = psubInfo->patternList; std::list::iterator patternIt = patternList.begin(); - while (1) { + while (true) { if (psubFile->token == tokenRBrace) { subGetNextToken(psubFile); EXITS(psubInfo->macroReplacements.c_str()); @@ -907,7 +908,7 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) if (gotFirstPattern) catMacroReplacements(psubInfo, ","); - gotFirstPattern = 1; + gotFirstPattern = true; if (patternIt != patternList.end()) { catMacroReplacements(psubInfo, patternIt->c_str()); @@ -922,7 +923,7 @@ static const char *substituteGetReplacements(subInfo * const psubInfo) while (subGetNextToken(psubFile) == tokenSeparator); } } - else while(1) { + else while(true) { switch(subGetNextToken(psubFile)) { case tokenRBrace: subGetNextToken(psubFile); From 9a4787155cdaba3fa8c455b54aae984575a8b87f Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Mon, 7 Jan 2019 08:56:07 -0500 Subject: [PATCH 18/85] Convert substitutionName to std::string --- src/ioc/dbtemplate/msi.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 2c5277811..257b1e89e 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -67,7 +67,7 @@ static void inputErrPrint(const inputData * const pvt); /* Module to read the substitution file */ typedef struct subInfo subInfo; -static void substituteOpen(subInfo **ppvt, char * const substitutionName); +static void substituteOpen(subInfo **ppvt, const std::string& substitutionName); static void substituteDestruct(subInfo * const pvt); static bool substituteGetNextSet(subInfo * const pvt, char **filename); static bool substituteGetGlobalSet(subInfo * const pvt); @@ -97,7 +97,7 @@ int main(int argc,char **argv) MAC_HANDLE *macPvt; char *pval; int narg; - char *substitutionName = 0; + std::string substitutionName; char *templateName = 0; int i; bool localScope = true; @@ -122,7 +122,7 @@ int main(int argc,char **argv) addMacroReplacements(macPvt, pval); } else if(strncmp(argv[1], "-S", 2) == 0) { - substitutionName = epicsStrDup(pval); + substitutionName = pval; } else if (strcmp(argv[1], "-V") == 0) { opt_V = 1; @@ -169,7 +169,7 @@ int main(int argc,char **argv) if (argc == 2) templateName = epicsStrDup(argv[1]); - if (!substitutionName) { + if (substitutionName.empty()) { STEP("Single template+substitutions file"); makeSubstitutions(inputPvt, macPvt, templateName); } @@ -178,7 +178,7 @@ int main(int argc,char **argv) char *filename = 0; bool isGlobal, isFile; - STEPS("Substitutions from file", substitutionName); + STEPS("Substitutions from file", substitutionName.c_str()); substituteOpen(&substitutePvt, substitutionName); do { isGlobal = substituteGetGlobalSet(substitutePvt); @@ -218,7 +218,6 @@ int main(int argc,char **argv) printf("\n"); } free(templateName); - free(substitutionName); return opt_V & 2; } @@ -600,7 +599,7 @@ typedef enum { } tokenType; typedef struct subFile { - char *substitutionName; + std::string substitutionName; FILE *fp; int lineNum; char inputBuffer[MAX_BUFFER_SIZE]; @@ -659,7 +658,7 @@ static void substituteDestruct(subInfo * const psubInfo) EXIT; } -static void substituteOpen(subInfo **ppvt, char * const substitutionName) +static void substituteOpen(subInfo **ppvt, const std::string& substitutionName) { subInfo *psubInfo; subFile *psubFile; @@ -671,9 +670,9 @@ static void substituteOpen(subInfo **ppvt, char * const substitutionName) psubFile = new subFile; psubInfo->psubFile = psubFile; - fp = fopen(substitutionName, "r"); + fp = fopen(substitutionName.c_str(), "r"); if (!fp) { - fprintf(stderr, "msi: Can't open file '%s'\n", substitutionName); + fprintf(stderr, "msi: Can't open file '%s'\n", substitutionName.c_str()); abortExit(1); } @@ -975,7 +974,8 @@ static void subFileErrPrint(subFile *psubFile, const 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); + psubFile->substitutionName.c_str(), psubFile->lineNum, + psubFile->inputBuffer); } From 409ee26fae2f465b7455b767f228c8333ac052f0 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Mon, 7 Jan 2019 10:00:08 -0500 Subject: [PATCH 19/85] Reduce scope of some variables --- src/ioc/dbtemplate/msi.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 257b1e89e..49d8611b9 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -96,16 +96,14 @@ int main(int argc,char **argv) inputData *inputPvt; MAC_HANDLE *macPvt; char *pval; - int narg; std::string substitutionName; char *templateName = 0; - int i; bool localScope = true; inputConstruct(&inputPvt); macCreateHandle(&macPvt, 0); while ((argc > 1) && (argv[1][0] == '-')) { - narg = (strlen(argv[1]) == 2) ? 2 : 1; + int narg = (strlen(argv[1]) == 2) ? 2 : 1; pval = (narg == 1) ? (argv[1] + 2) : argv[2]; if (strncmp(argv[1], "-I", 2) == 0) { @@ -141,7 +139,7 @@ int main(int argc,char **argv) } argc -= narg; - for (i = 1; i < argc; i++) + for (int i = 1; i < argc; i++) argv[i] = argv[i + narg]; } @@ -396,14 +394,13 @@ static void inputAddPath(inputData * const pinputData, const char * const path) const char *pcolon; const char *pdir; size_t len; - bool 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) { - emptyName = (*pdir == sep); + bool emptyName = (*pdir == sep); if (emptyName) ++pdir; std::string directory; @@ -441,12 +438,11 @@ static void inputBegin(inputData * const pinputData, const char * const fileName static char *inputNextLine(inputData * const pinputData) { std::list& inFileList = pinputData->inputFileList; - char *pline; ENTER; while (!inFileList.empty()) { inputFile& inFile = inFileList.front(); - pline = fgets(pinputData->inputBuffer, MAX_BUFFER_SIZE, inFile.fp); + char *pline = fgets(pinputData->inputBuffer, MAX_BUFFER_SIZE, inFile.fp); if (pline) { ++inFile.lineNum; EXITS(pline); From a9606dbf6ef07f444c2149afd441d0b62dc0c482 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Mon, 7 Jan 2019 14:55:12 -0500 Subject: [PATCH 20/85] Add test for macro expansion in file names --- src/ioc/dbtemplate/test/msi.plt | 17 +++++++++++++++-- src/ioc/dbtemplate/test/t12-result.txt | 2 ++ src/ioc/dbtemplate/test/t12-substitute.txt | 3 +++ src/ioc/dbtemplate/test/t12-template.txt | 2 ++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/ioc/dbtemplate/test/t12-result.txt create mode 100644 src/ioc/dbtemplate/test/t12-substitute.txt create mode 100644 src/ioc/dbtemplate/test/t12-template.txt diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt index 332defb13..ca87ca1fe 100644 --- a/src/ioc/dbtemplate/test/msi.plt +++ b/src/ioc/dbtemplate/test/msi.plt @@ -11,7 +11,7 @@ use strict; use Test; -BEGIN {plan tests => 11} +BEGIN {plan tests => 12} # Check include/substitute command model ok(msi('-I .. ../t1-template.txt'), slurp('../t1-result.txt')); @@ -56,6 +56,8 @@ ok(msi('-I. -I.. -S ../t10-substitute.txt'), slurp('../t10-result.txt')); # Substitution file, pattern format, with 0 pattern definitions ok(msi('-I. -I.. -S ../t11-substitute.txt'), slurp('../t11-result.txt')); +# Macros in template-file name populated from environment variable +ok(msi('-I. -I.. -S ../t12-substitute.txt', 'TEST_NO=12,PREFIX=t'), slurp('../t12-result.txt')); # Test support routines @@ -68,10 +70,16 @@ sub slurp { } sub msi { - my ($args) = @_; + my ($args, $envstr) = @_; my $exe = ($^O eq 'MSWin32') || ($^O eq 'cygwin') ? '.exe' : ''; my $msi = "./msi-copy$exe"; my $result; + my @envs = split(/,/, $envstr); + foreach (@envs) + { + my ($var, $value) = split /=/, $_; + $ENV{$var} = $value; + } if ($args =~ m/-o / && $args !~ m/-D/) { # An empty result is expected $result = `$msi $args`; @@ -85,5 +93,10 @@ sub msi { if $result eq ''; } while ($result eq '') && (--$count > 0); } + foreach (@envs) + { + my ($var, $value) = split /=/, $_; + delete $ENV{$var}; + } return $result; } diff --git a/src/ioc/dbtemplate/test/t12-result.txt b/src/ioc/dbtemplate/test/t12-result.txt new file mode 100644 index 000000000..6cfcc57da --- /dev/null +++ b/src/ioc/dbtemplate/test/t12-result.txt @@ -0,0 +1,2 @@ +# comment line +a=foo diff --git a/src/ioc/dbtemplate/test/t12-substitute.txt b/src/ioc/dbtemplate/test/t12-substitute.txt new file mode 100644 index 000000000..7a26b6fea --- /dev/null +++ b/src/ioc/dbtemplate/test/t12-substitute.txt @@ -0,0 +1,3 @@ +file $(PREFIX)$(TEST_NO)-template.txt { + { a=foo } +} diff --git a/src/ioc/dbtemplate/test/t12-template.txt b/src/ioc/dbtemplate/test/t12-template.txt new file mode 100644 index 000000000..7958885a7 --- /dev/null +++ b/src/ioc/dbtemplate/test/t12-template.txt @@ -0,0 +1,2 @@ +# comment line +a=$(a) From 95cb81c286258e4534afc8426bba53cbdddfd787 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sun, 10 Mar 2019 16:34:51 -0700 Subject: [PATCH 21/85] generalTime short circuit current time epicsTimeGetCurrent() is called frequently. Unless more than the default provider is registered, locking and going through the timeProvider list each time is a waste. Instead, short circuit to directly call the default time current time provider unless a another has been registered. --- modules/libcom/src/osi/epicsGeneralTime.c | 16 ++++++++++++++++ modules/libcom/src/osi/os/Darwin/osdTime.cpp | 2 +- modules/libcom/src/osi/os/WIN32/osdTime.cpp | 5 +++-- modules/libcom/src/osi/os/posix/osdTime.cpp | 2 +- modules/libcom/src/osi/osiClockTime.c | 8 ++++---- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/modules/libcom/src/osi/epicsGeneralTime.c b/modules/libcom/src/osi/epicsGeneralTime.c index d08e9c6a9..dff495ef0 100644 --- a/modules/libcom/src/osi/epicsGeneralTime.c +++ b/modules/libcom/src/osi/epicsGeneralTime.c @@ -78,6 +78,11 @@ static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; static const char * const tsfmt = "%Y-%m-%d %H:%M:%S.%09f"; +/* defined in osiClockTime.c or osdTime.cpp */ +int osdTimeGetCurrent ( epicsTimeStamp *pDest ); +/* set if/when gtPvt.timeProviders contains more than the default osdTimeGetCurrent() */ +static int gtMoreThanDefault; + /* Implementation */ static void generalTime_InitOnce(void *dummy) @@ -103,6 +108,9 @@ int generalTimeGetExceptPriority(epicsTimeStamp *pDest, int *pPrio, int ignore) gtProvider *ptp; int status = S_time_noProvider; + if(!gtMoreThanDefault) + return osdTimeGetCurrent(pDest); + generalTime_Init(); IFDEBUG(2) @@ -148,6 +156,9 @@ int epicsShareAPI epicsTimeGetCurrent(epicsTimeStamp *pDest) int status = S_time_noProvider; epicsTimeStamp ts; + if(!gtMoreThanDefault) + return osdTimeGetCurrent(pDest); + generalTime_Init(); IFDEBUG(20) @@ -370,6 +381,11 @@ static void insertProvider(gtProvider *ptp, ELLLIST *plist, epicsMutexId lock) ellAdd(plist, &ptp->node); } + /* Check to see if we have more than just the OS default time source */ + if(plist==>Pvt.timeProviders && (ellCount(plist)!=1 || ptp->get.Time!=&osdTimeGetCurrent)) { + gtMoreThanDefault = 1; + } + epicsMutexUnlock(lock); } diff --git a/modules/libcom/src/osi/os/Darwin/osdTime.cpp b/modules/libcom/src/osi/os/Darwin/osdTime.cpp index 315caeb9b..09471a8e8 100644 --- a/modules/libcom/src/osi/os/Darwin/osdTime.cpp +++ b/modules/libcom/src/osi/os/Darwin/osdTime.cpp @@ -26,7 +26,7 @@ static clock_serv_t host_clock; extern "C" { -static int osdTimeGetCurrent (epicsTimeStamp *pDest) +int osdTimeGetCurrent (epicsTimeStamp *pDest) { mach_timespec_t mts; struct timespec ts; diff --git a/modules/libcom/src/osi/os/WIN32/osdTime.cpp b/modules/libcom/src/osi/os/WIN32/osdTime.cpp index 348fe7c2f..1b1a70548 100644 --- a/modules/libcom/src/osi/os/WIN32/osdTime.cpp +++ b/modules/libcom/src/osi/os/WIN32/osdTime.cpp @@ -47,7 +47,8 @@ extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ); -static int osdTimeGetCurrent ( epicsTimeStamp *pDest ); +extern "C" +int osdTimeGetCurrent ( epicsTimeStamp *pDest ); // for mingw #if !defined ( MAXLONGLONG ) @@ -116,7 +117,7 @@ static int done = timeRegister(); // // osdTimeGetCurrent () // -static int osdTimeGetCurrent ( epicsTimeStamp *pDest ) +int osdTimeGetCurrent ( epicsTimeStamp *pDest ) { assert ( pCurrentTime ); diff --git a/modules/libcom/src/osi/os/posix/osdTime.cpp b/modules/libcom/src/osi/os/posix/osdTime.cpp index 1952babd9..cc3cb1965 100644 --- a/modules/libcom/src/osi/os/posix/osdTime.cpp +++ b/modules/libcom/src/osi/os/posix/osdTime.cpp @@ -32,7 +32,7 @@ LAST_RESORT_PRIORITY, osdTimeGetCurrent) extern "C" { - static int osdTimeGetCurrent (epicsTimeStamp *pDest) + int osdTimeGetCurrent (epicsTimeStamp *pDest) { struct timeval tv; struct timezone tz; diff --git a/modules/libcom/src/osi/osiClockTime.c b/modules/libcom/src/osi/osiClockTime.c index b0f4c35eb..bf29427b2 100644 --- a/modules/libcom/src/osi/osiClockTime.c +++ b/modules/libcom/src/osi/osiClockTime.c @@ -48,7 +48,7 @@ static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; /* Forward references */ -static int ClockTimeGetCurrent(epicsTimeStamp *pDest); +int osdTimeGetCurrent(epicsTimeStamp *pDest); #if defined(vxWorks) || defined(__rtems__) static void ClockTimeSync(void *dummy); @@ -89,7 +89,7 @@ static void ClockTime_InitOnce(void *pfirst) /* Register as a time provider */ generalTimeRegisterCurrentProvider("OS Clock", LAST_RESORT_PRIORITY, - ClockTimeGetCurrent); + osdTimeGetCurrent); } void ClockTime_Init(int synchronize) @@ -125,7 +125,7 @@ void ClockTime_Init(int synchronize) else { /* No synchronization thread */ if (firstTime) - ClockTimeGetCurrent(&ClockTimePvt.startTime); + osdTimeGetCurrent(&ClockTimePvt.startTime); } } } @@ -191,7 +191,7 @@ static void ClockTimeSync(void *dummy) /* Time Provider Routine */ -static int ClockTimeGetCurrent(epicsTimeStamp *pDest) +int osdTimeGetCurrent(epicsTimeStamp *pDest) { struct timespec clockNow; From 3a5fb898d6e37edb2eb72245f9bd5e432959c98c Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 8 Apr 2019 17:50:19 -0500 Subject: [PATCH 22/85] Move rules for cvsclean and depclean to RULES_DIRS Fix FIND_TOOLS for submodules when EPICS_BASE not built Add 'make help' for newer test targets --- configure/CONFIG_BASE | 10 ++++++++-- configure/RULES_DIRS | 18 +++++++++++++----- configure/RULES_TOP | 18 +++++++----------- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/configure/CONFIG_BASE b/configure/CONFIG_BASE index 137ce0098..963b83a32 100644 --- a/configure/CONFIG_BASE +++ b/configure/CONFIG_BASE @@ -30,10 +30,11 @@ endif # BASE_TOP #--------------------------------------------------------------- # Where to find the installed build tools # Windows does not like commands with relative paths starting ../ -# but the Perl scripts in TOP/src/tools are OK +# so TOOLS must be an absolute path, although Perl scripts are OK. +# FIND_TOOL is for scripts run before the build reaches src/tools. TOOLS = $(abspath $(EPICS_BASE_HOST_BIN)) -FIND_TOOL = $(firstword $(wildcard $(TOOLS)/$(1) $(TOP)/src/tools/$(1))) +FIND_TOOL = $(firstword $(wildcard $(TOOLS)/$(1) $(EPICS_BASE)/src/tools/$(1))) #--------------------------------------------------------------- # EPICS Base build tools and tool flags @@ -54,3 +55,8 @@ INSTALL_LIBRARY = $(INSTALL) # tools for making header dependencies and variable replacement MKMF = $(PERL) $(TOOLS)/mkmf.pl REPLACEVAR = $(PERL) $(TOOLS)/replaceVAR.pl + +#--------------------------------------------------------------- +# tools for cleaning out unwanted files +CVSCLEAN = $(call FIND_TOOL,cvsclean.pl) +DEPCLEAN = $(call FIND_TOOL,depclean.pl) diff --git a/configure/RULES_DIRS b/configure/RULES_DIRS index ec156745d..01aa1fdfa 100644 --- a/configure/RULES_DIRS +++ b/configure/RULES_DIRS @@ -86,10 +86,18 @@ $(DIRS) $(dirActionTargets) $(dirArchTargets) $(dirActionArchTargets) : $(ARCHS) $(ACTIONS) $(actionArchTargets) :%: \ $(foreach dir, $(DIRS), $(dir)$(DIVIDER)%) -.PHONY : $(DIRS) all host rebuild -.PHONY : $(ARCHS) $(ACTIONS) -.PHONY : $(dirActionTargets) $(dirArchTargets) -.PHONY : $(dirActionArchTargets) -.PHONY : $(actionArchTargets) + +cvsclean: + $(PERL) $(CVSCLEAN) +depclean: + $(PERL) $(DEPCLEAN) + + +.PHONY: $(DIRS) all host rebuild +.PHONY: $(ARCHS) $(ACTIONS) +.PHONY: $(dirActionTargets) $(dirArchTargets) +.PHONY: $(dirActionArchTargets) +.PHONY: $(actionArchTargets) +.PHONY: cvsclean depclean include $(CONFIG)/RULES_COMMON diff --git a/configure/RULES_TOP b/configure/RULES_TOP index bd844e76f..e1666c9a1 100644 --- a/configure/RULES_TOP +++ b/configure/RULES_TOP @@ -11,13 +11,7 @@ include $(CONFIG)/RULES_DIRS distclean: realclean cvsclean realuninstall -CVSCLEAN = $(call FIND_TOOL,cvsclean.pl) -cvsclean: - $(PERL) $(CVSCLEAN) -DEPCLEAN = $(call FIND_TOOL,depclean.pl) -depclean: - $(PERL) $(DEPCLEAN) realuninstall: uninstallDirs $(RMDIR) $(INSTALL_LOCATION_BIN) @@ -66,7 +60,12 @@ help: @echo " Cannot be used within an O. dir" @echo " rebuild - Same as clean install" @echo " archclean - Removes O. dirs but not O.Common dir" - @echo " runtests - Run self-tests, summarize results" + @echo " depclean - Removes .d files from all O. dirs." + @echo " cvsclean - Removes backup files etc. from all dirs below" + @echo " runtests - Run self-tests, summarize results immediately" + @echo " tapfiles - Run self-tests, save to O./*.tap files" + @echo " test-results - Summarize all O./*.tap files" + @echo " clean-tests - Removes all O./*.tap files" @echo "\"Partial\" build targets supported by Makefiles:" @echo " host - Builds and installs $(EPICS_HOST_ARCH) only." @echo " inc$(DIVIDER) - Installs only header files." @@ -79,15 +78,12 @@ help: @echo " uninstall - Remove install directories created by this hostarch." @echo " realuninstall - Removes ALL install dirs" @echo " distclean - Same as realclean cvsclean realuninstall." - @echo " depclean - Removes all .d files from O. directories." - @echo " cvsclean - Removes cvs .#* files in all dirs of directory tree" @echo " help - Prints this list of valid make targets " @echo "Indiv. object targets are supported by O. level Makefile .e.g" @echo " xxxRecord.o" -.PHONY: cleandirs distclean cvsclean depclean +.PHONY: cleandirs distclean uninstall help .PHONY: realuninstall archuninstall uninstallDirs -.PHONY: uninstall help # Include /cfg/TOP_RULES* files from tops defined in RELEASE* files # From e92a9ae42698970790f3e427360b92612381c99b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 10 Apr 2019 12:13:33 -0500 Subject: [PATCH 23/85] Make submodule builds more generic Adds PARENT_MODULE to detect when building a submodule. RULES_TOP uses that to disable uninstall rules and abort instead of deleting the parent's configure/ directory. --- configure/RULES_TOP | 56 ++++++++++++++++++++++++++++----------- modules/CONFIG_SITE.local | 9 ++++--- modules/Makefile | 13 ++++++--- 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/configure/RULES_TOP b/configure/RULES_TOP index e1666c9a1..c1644bf6f 100644 --- a/configure/RULES_TOP +++ b/configure/RULES_TOP @@ -9,20 +9,30 @@ include $(CONFIG)/RULES_DIRS +# Disable most top rules when installing into a parent's tree, indicated +# by PARENT_MODULE being set in the modules/CONFIG_SITE.local file and +# INSTALL_LOCATION pointing to the the same place as in the parent. +ifeq ($(origin PARENT_MODULE),file) + ifeq ($(INSTALL_LOCATION),$($(PARENT_MODULE))) + DISABLE_TOP_RULES=YES + endif +endif + +ifndef DISABLE_TOP_RULES + # + # Rules for a regular application top directory + # + distclean: realclean cvsclean realuninstall - - realuninstall: uninstallDirs $(RMDIR) $(INSTALL_LOCATION_BIN) $(RMDIR) $(INSTALL_LOCATION_LIB) -UNINSTALL_DIRS += $(INSTALL_DBD) $(INSTALL_INCLUDE) $(INSTALL_DOC) \ - $(INSTALL_HTML) $(INSTALL_TEMPLATES) $(INSTALL_DB) $(DIRECTORY_TARGETS) +UNINSTALL_DIRS += $(INSTALL_DB) $(INSTALL_DBD) $(INSTALL_DOC) $(INSTALL_HTML) +UNINSTALL_DIRS += $(INSTALL_INCLUDE) $(INSTALL_TEMPLATES) $(DIRECTORY_TARGETS) ifneq ($(INSTALL_LOCATION),$(TOP)) -ifneq ($(INSTALL_LOCATION),$(EPICS_BASE)) -UNINSTALL_DIRS += $(INSTALL_CONFIG) -endif + UNINSTALL_DIRS += $(INSTALL_CONFIG) endif uninstallDirs: $(RMDIR) $(UNINSTALL_DIRS) @@ -36,6 +46,8 @@ uninstall$(DIVIDER)%: $(RMDIR) $(INSTALL_LOCATION_BIN)/$(archPart) $(RMDIR) $(INSTALL_LOCATION_LIB)/$(archPart) +# Remove the bin and lib directories if they have no sub-directories +# cleandirs: @$(NOP) ifeq ($(wildcard $(INSTALL_LOCATION_BIN)/*),) @@ -45,6 +57,16 @@ ifeq ($(wildcard $(INSTALL_LOCATION_LIB)/*),) $(RMDIR) $(INSTALL_LOCATION_LIB) endif +else + # + # Using a disabled rule aborts + # + + cleandirs distclean uninstall realuninstall archuninstall: + $(error Target '$@' not available in a submodule) + +endif # DISABLE_TOP_RULES + help: @echo "Usage: gnumake [options] [target] ..." @@ -72,23 +94,27 @@ help: @echo " build$(DIVIDER) - Builds and installs only." @echo " install$(DIVIDER) - Builds and installs only." @echo " clean$(DIVIDER) - Cleans binaries in O. dirs only." - @echo " uninstall$(DIVIDER) - Remove bin & lib directories for only." @echo "Targets supported by top level Makefile:" +ifndef DISABLE_TOP_RULES @echo " archuninstall - Remove bin & lib directories created by this hostarch." + @echo " uninstall$(DIVIDER) - Remove bin & lib directories for only." @echo " uninstall - Remove install directories created by this hostarch." @echo " realuninstall - Removes ALL install dirs" @echo " distclean - Same as realclean cvsclean realuninstall." +endif @echo " help - Prints this list of valid make targets " - @echo "Indiv. object targets are supported by O. level Makefile .e.g" + @echo "Object targets are supported by the O. level Makefile .e.g" @echo " xxxRecord.o" .PHONY: cleandirs distclean uninstall help .PHONY: realuninstall archuninstall uninstallDirs -# Include /cfg/TOP_RULES* files from tops defined in RELEASE* files -# -RELEASE_CFG_TOP_RULES = $(foreach top, $(RELEASE_TOPS), \ - $(wildcard $($(top))/cfg/TOP_RULES*)) -ifneq ($(RELEASE_CFG_TOP_RULES),) - include $(RELEASE_CFG_TOP_RULES) +ifndef DISABLE_TOP_RULES + # Include /cfg/TOP_RULES* files from tops defined in RELEASE* files + # + RELEASE_CFG_TOP_RULES = $(foreach top, $(RELEASE_TOPS), \ + $(wildcard $($(top))/cfg/TOP_RULES*)) + ifneq ($(RELEASE_CFG_TOP_RULES),) + include $(RELEASE_CFG_TOP_RULES) + endif endif diff --git a/modules/CONFIG_SITE.local b/modules/CONFIG_SITE.local index 760f9d691..db97a5b78 100644 --- a/modules/CONFIG_SITE.local +++ b/modules/CONFIG_SITE.local @@ -3,8 +3,11 @@ # in file LICENSE that is included with this distribution. #************************************************************************* -# When building submodules, this should always be true: -INSTALL_LOCATION = $(EPICS_BASE) +# The name our submodules know us by: +PARENT_MODULE = EPICS_BASE -# Stop submodules from installing their configuration files: +# When building submodules, this should always be true: +INSTALL_LOCATION := $($(PARENT_MODULE)) + +# Stop submodules installing their configure/ files into our area CONFIG_INSTALLS = diff --git a/modules/Makefile b/modules/Makefile index 214e914f1..9580e9ad9 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -5,6 +5,7 @@ TOP = .. include $(TOP)/configure/CONFIG +include CONFIG_SITE.local # Submodules for bundle build SUBMODULES += libcom @@ -51,8 +52,14 @@ RELEASE_LOCAL := RELEASE.$(EPICS_HOST_ARCH).local all host $(DIRS) $(ARCHS) $(ACTIONS) $(dirActionTargets) $(dirArchTargets) \ $(dirActionArchTargets) $(actionArchTargets): | $(RELEASE_LOCAL) -$(RELEASE_LOCAL): - $(ECHO) Creating $@, EPICS_BASE = $(INSTALL_LOCATION_ABS) - @echo EPICS_BASE = $(INSTALL_LOCATION_ABS)> $@ +# Convenience target +RELEASE.host: $(RELEASE_LOCAL) + +$(RELEASE_LOCAL): Makefile CONFIG_SITE.local + $(ECHO) Creating $@ with + $(ECHO) " $(PARENT_MODULE) = $(INSTALL_LOCATION_ABS)" + @echo $(PARENT_MODULE) = $(INSTALL_LOCATION_ABS)> $@ realclean: $(RM) $(wildcard RELEASE.*.local) + +.PHONY: RELEASE.host realclean From 3a0371894ba27193c69fa416e6d34fea3b1c072f Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 10 Apr 2019 13:24:09 -0500 Subject: [PATCH 24/85] Checklist tweaks for 7.0.2.2 --- documentation/ReleaseChecklist.html | 64 +++++++++++++++-------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/documentation/ReleaseChecklist.html b/documentation/ReleaseChecklist.html index cb95f7f60..1b28165be 100644 --- a/documentation/ReleaseChecklist.html +++ b/documentation/ReleaseChecklist.html @@ -53,9 +53,10 @@ made.

Short Process for Patch Releases

-

The Patch Release date and its scope are agreed upon about four weeks -ahead of time. If no blocking issues are raised, the release is made by the -release manager.

+

The Patch Release date and its scope are agreed upon a few weeks ahead of the +release. If no blocking issues are raised, the release is made by the Release +Manager on or as soon as possible after that date, following the steps below +starting at Release Approval.

Roles

@@ -72,6 +73,7 @@ release manager.

Responsible for the EPICS website
+
@@ -132,14 +134,14 @@ release manager.

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -361,48 +364,49 @@ release manager.

- + - + - + - + - + - + - +
Creating pre-release and release-candidate versions
  Release Manager Edit and commit changes to the EPICS version number file configure/CONFIG_BASE_VERSION.
  Release Manager Tag the module in Git, using these tag conventions:
    @@ -161,7 +163,7 @@ release manager.

    that are only tagged at the final release.
  Release Manager Export the tagged version into a tarfile. The make-tar.sh script generates a gzipped tarfile directly from the tag, excluding the @@ -177,27 +179,27 @@ release manager.

  Release Manager Test the tarfile by extracting its contents and building it on at least one supported platform.
  Website Manager Copy the tarfile and its signature to the Base download area of the website and add the new files to the website Base download index page.
  Website Manager Create or update a website subdirectory to hold the release documentation, and copy in selected files from the base/documentation and base/html directories of the tarfile.
  Website Manager Create or modify the webpage for the new release with links to the release documents and tar file. Pre-release and release-candidate @@ -257,10 +259,11 @@ release manager.

Release Approval + Release Approval
  Release Manager Obtain a positive Ok to release from all platform developers once a release candidate version has gone for 2 weeks without any major @@ -270,7 +273,7 @@ release manager.

Creating the final release version
  Release Manager

For each external submodule, check if the module's release version @@ -282,7 +285,7 @@ release manager.

commit.

  Release Manager Edit and commit changes to the EPICS Base version number file and the embedded module version files: @@ -294,33 +297,33 @@ release manager.

  Release Manager Tag the epics-base module in Git:
cd base-7.0
- git tag -m 'ANJ: Tagged for 7.0.2' R7.0.2 + git tag -m 'ANJ: Tagged for 7.0.2.2' R7.0.2.2
Don't push the new tag to the Launchpad repository yet.
  Release Manager Export the tagged version into a tarfile. The make-tar.sh script generates a gzipped tarfile directly from the tag, excluding the files and directories that are only used for continuous integration:
cd base-7.0
- ./.tools/make-tar.sh R7.0.2 base-7.0.2.tar.gz base-7.0.2/ + ./.tools/make-tar.sh R7.0.2.2 base-7.0.2.2.tar.gz base-7.0.2.2/
Create a GPG signature file of the tarfile as follows:
- gpg --armor --sign --detach-sig base-7.0.2.tar.gz + gpg --armor --sign --detach-sig base-7.0.2.2.tar.gz
  Release Manager Test the tar file by extracting its contents and building it on at least one supported platform. When this succeeds the new git tag can be @@ -331,7 +334,7 @@ release manager.

  Release Manager Edit and commit changes to the EPICS Base version number file and the embedded module version files: @@ -346,13 +349,13 @@ release manager.

  Release Manager Copy the tarfile and its signature to the Base download area of the website.
  Release Manager Find all Launchpad bug reports with the status Fix Committed which have been fixed in this release and mark them Fix Released. Publish and Announce it
  Website Manager Upload the tar file and its .asc signature file to the Launchpad milestone for this release version.
  Website Manager Update the website subdirectory that holds the release documentation, and copy in the files from the base/documentation directory of the tarfile.
  Website Manager Update the webpage for the new release with links to the release documents and tar file.
  Website Manager Add the new release tar file to the website Base download index page.
  Website Manager Link to the release webpage from other relevent areas of the website - update front page and sidebars.
  Website Manager Add an entry to the website News page, linking to the new version webpage.
  Release Manager Announce the release on the tech-talk mailing list.
+
From 1412abadf9d5ff4189472230d57d5921153088dc Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 10 Apr 2019 14:13:29 -0500 Subject: [PATCH 25/85] Move cvsclean and depclean to RULES_COMMON --- configure/RULES_COMMON | 12 ++++++++++++ configure/RULES_DIRS | 7 ------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/configure/RULES_COMMON b/configure/RULES_COMMON index fb8f211e4..6c3d48889 100644 --- a/configure/RULES_COMMON +++ b/configure/RULES_COMMON @@ -19,6 +19,7 @@ $(sort $(SHOW_MAKEFILES)): show-makefile.%: .PHONY: show-makefiles show-makefile.% + # These rules support printing a Makefile variable values. # Many variables are only set inside an O. build directory. # make PRINT.T_A @@ -30,6 +31,17 @@ PRINT.%: .PHONY: PRINT PRINT.% +# Clean rules for recursively deleting editor backup files +# and dependency (.d) files from CWD and below. + +cvsclean: + $(PERL) $(CVSCLEAN) +depclean: + $(PERL) $(DEPCLEAN) + +.PHONY: cvsclean depclean + + # User specific rules # -include $(HOME)/configure/RULES_USER diff --git a/configure/RULES_DIRS b/configure/RULES_DIRS index 01aa1fdfa..db68a84a5 100644 --- a/configure/RULES_DIRS +++ b/configure/RULES_DIRS @@ -87,17 +87,10 @@ $(ARCHS) $(ACTIONS) $(actionArchTargets) :%: \ $(foreach dir, $(DIRS), $(dir)$(DIVIDER)%) -cvsclean: - $(PERL) $(CVSCLEAN) -depclean: - $(PERL) $(DEPCLEAN) - - .PHONY: $(DIRS) all host rebuild .PHONY: $(ARCHS) $(ACTIONS) .PHONY: $(dirActionTargets) $(dirArchTargets) .PHONY: $(dirActionArchTargets) .PHONY: $(actionArchTargets) -.PHONY: cvsclean depclean include $(CONFIG)/RULES_COMMON From f0f7a1ef063ee24a4b92ab977e5af363c491d470 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 10 Apr 2019 16:16:12 -0500 Subject: [PATCH 26/85] Move rules from modules/Makefile to new RULES_MODULES file --- configure/RULES_MODULES | 47 +++++++++++++++++++++++++++++++++++++++++ modules/Makefile | 24 +-------------------- 2 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 configure/RULES_MODULES diff --git a/configure/RULES_MODULES b/configure/RULES_MODULES new file mode 100644 index 000000000..08ebb3e10 --- /dev/null +++ b/configure/RULES_MODULES @@ -0,0 +1,47 @@ +#************************************************************************* +# EPICS BASE is distributed subject to a Software License Agreement found +# in file LICENSE that is included with this distribution. +#************************************************************************* + +# Support modules can use these rules to build submodules too. +# +# The requirements to do so are: +# 1. Create a file CONFIG_SITE.local in the same directory as the +# Makefile, which defines these variables (the last one is empty): +# PARENT_MODULE - The name submodules call their parent +# INSTALL_LOCATION := $($(PARENT_MODULE)) +# CONFIG_INSTALLS = +# 2. The Makefile must set TOP and include $(TOP)/configure/CONFIG and +# CONFIG_SITE.local +# 3. Submodules are added to the SUBMODULES variable in the Makefile +# 4. Dependencies between submodules must be set using +# _DEPEND_DIRS = +# 5. The Makefile must end by including $(TOP)/configure/RULES_MODULES +# 6. Submodules must have a configure/RELEASE file that contains +# -include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local +# 7. Submodules must have a configure/CONFIG_SITE file that contains +# -include $(TOP)/../CONFIG_SITE.local + +# Add checked-out submodules to DIRS +DIRS += $(subst /Makefile,,$(wildcard $(addsuffix /Makefile, $(SUBMODULES)))) + +include $(CONFIG)/RULES_DIRS + +INSTALL_LOCATION_ABS := $(abspath $(INSTALL_LOCATION)) +RELEASE_LOCAL := RELEASE.$(EPICS_HOST_ARCH).local + +# Ensure that RELEASE..local exists before doing anything else +all host $(DIRS) $(ARCHS) $(ACTIONS) $(dirActionTargets) $(dirArchTargets) \ + $(dirActionArchTargets) $(actionArchTargets): | $(RELEASE_LOCAL) + +# Convenience target +RELEASE.host: $(RELEASE_LOCAL) + +$(RELEASE_LOCAL): Makefile CONFIG_SITE.local + $(ECHO) Creating $@ with + $(ECHO) " $(PARENT_MODULE) = $(INSTALL_LOCATION_ABS)" + @echo $(PARENT_MODULE) = $(INSTALL_LOCATION_ABS)> $@ +realclean: + $(RM) $(wildcard RELEASE.*.local) + +.PHONY: RELEASE.host realclean diff --git a/modules/Makefile b/modules/Makefile index 9580e9ad9..0ed2b0efe 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -40,26 +40,4 @@ example_DEPEND_DIRS = pva2pva pvaClient # Allow sites to add extra submodules -include Makefile.local -# Add only checked-out submodules to DIRS -DIRS += $(subst /Makefile,,$(wildcard $(addsuffix /Makefile, $(SUBMODULES)))) - -include $(TOP)/configure/RULES_DIRS - -INSTALL_LOCATION_ABS := $(abspath $(INSTALL_LOCATION)) -RELEASE_LOCAL := RELEASE.$(EPICS_HOST_ARCH).local - -# Ensure that RELEASE..local exists before doing anything else -all host $(DIRS) $(ARCHS) $(ACTIONS) $(dirActionTargets) $(dirArchTargets) \ - $(dirActionArchTargets) $(actionArchTargets): | $(RELEASE_LOCAL) - -# Convenience target -RELEASE.host: $(RELEASE_LOCAL) - -$(RELEASE_LOCAL): Makefile CONFIG_SITE.local - $(ECHO) Creating $@ with - $(ECHO) " $(PARENT_MODULE) = $(INSTALL_LOCATION_ABS)" - @echo $(PARENT_MODULE) = $(INSTALL_LOCATION_ABS)> $@ -realclean: - $(RM) $(wildcard RELEASE.*.local) - -.PHONY: RELEASE.host realclean +include $(TOP)/configure/RULES_MODULES From f79f2cf8fa287e7866eab3b5d62287b44db6cb5c Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 10 Apr 2019 16:44:21 -0500 Subject: [PATCH 27/85] Release Notes for commits since 7.0.2.1 --- documentation/RELEASE_NOTES.html | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 27670a17e..62a70a648 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -30,6 +30,44 @@ release.

--> +

Build System changes

+ +
    + +
  • The GNUmake build targets cvsclean and depclean are now +available from any directory; previously they were only available from +application top directories.
  • + +
  • The approach that EPICS Base uses for building submodules inside the parent +module looks useful for support modules too. The rules for building submodules +have been modified and extracted into a new RULES_MODULES file, so a +support module will be able to use them too without having to copy them into its +own modules/Makefile. There are some specific requirements that support +modules and their submodules must follow, which are described as comments in the +new base/configure/RULES_MODULES file itself.
  • + +
+ +

EPICS_BASE_VERSION Update Policy change

+ +

In the past, a build of EPICS using sources checked out from the repository +branch between official releases would have shown the version number of the +previous release, followed by a -DEV suffix, for example +7.0.2.1-DEV.

+ +

The policy that controls when the number gets updated has been changed, and +now immediately after a release has been tagged the version number will be +updated to the next patch release version, plus the -DEV suffix as +before. Thus following 7.0.2.2 the version number will show as +7.0.2.3-DEV. This does not require the next official release to be +numbered 7.0.2.3 though, it could become 7.0.3 or even +7.1.0 if the changes incorporated into it are more substantial than bug +fixes.

+ +

Drop CLOCK_MONOTONIC_RAW from posix/osdMonotonic.c

+ +

Turns out this is ~10x slower to query than CLOCK_MONOTONIC.

+

EPICS Release 7.0.2.1

From 5a55aa17d9da0ef685701147929a3148cf8bccd1 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 10 Apr 2019 16:45:35 -0500 Subject: [PATCH 28/85] Update pvData and pvDatabase modules Not updating pva2pva, the next 7.0.2.2 release should keep the previous tagged version --- modules/pvData | 2 +- modules/pvDatabase | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/pvData b/modules/pvData index 8c275cbc1..8f0111e48 160000 --- a/modules/pvData +++ b/modules/pvData @@ -1 +1 @@ -Subproject commit 8c275cbc1caca1f6175b75b6f0ffc2d4abc234db +Subproject commit 8f0111e482aa139f4311378f2b0bc831c46420b2 diff --git a/modules/pvDatabase b/modules/pvDatabase index b3f96f730..d0ddcead2 160000 --- a/modules/pvDatabase +++ b/modules/pvDatabase @@ -1 +1 @@ -Subproject commit b3f96f730fcf1b07a24125fd06b8c413a1e93b5d +Subproject commit d0ddcead2473624939230615b778bac88af9cf42 From f0e118da9169fb8d6adc1b265817a301164afb32 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 12 Apr 2019 18:13:55 -0500 Subject: [PATCH 29/85] Adjust warning message in RULES_BUILD to suggest cause --- configure/RULES_BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD index 2949ed9c2..2a78a96b1 100644 --- a/configure/RULES_BUILD +++ b/configure/RULES_BUILD @@ -553,6 +553,6 @@ include $(CONFIG)/RULES_EXPAND include $(CONFIG)/RULES_COMMON else - $(warning RULES_BUILD included more than once. \ - Use 'make show-makefiles' to work out why.) + $(warning Warning: Base configure/RULES_BUILD file included more than once. \ + Does configure/RELEASE have multiple pointers to $(EPICS_BASE)?) endif # BASE_RULES_BUILD From 8217fa86fe5e5e6bc19dad0b6e03626d1b5d3cc5 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 12 Apr 2019 18:14:57 -0500 Subject: [PATCH 30/85] Reimplement show-makefiles to display duplicates --- configure/RULES_COMMON | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/configure/RULES_COMMON b/configure/RULES_COMMON index 6c3d48889..ff428c342 100644 --- a/configure/RULES_COMMON +++ b/configure/RULES_COMMON @@ -8,16 +8,17 @@ # These rules show the set of Makefiles, config files and # rules files loaded by GNUmake. -# Protect against filenames containing colons (Windows) -SAFE_MAKEFILES = $(subst :,__colon__,$(MAKEFILE_LIST)) -SHOW_MAKEFILES = $(SAFE_MAKEFILES:%=show-makefile.%) -show-makefiles: $(SHOW_MAKEFILES) +show-makefiles:: + @echo + @echo Makefiles read: +define SHOW_MAKEFILE_template +show-makefiles:: + @echo " $(1)" +endef +$(foreach file,$(MAKEFILE_LIST), \ + $(eval $(call SHOW_MAKEFILE_template,$(file)))) -# The sort prevents warnings about duplicate targets: -$(sort $(SHOW_MAKEFILES)): show-makefile.%: - @echo " $(subst __colon__,:,$(@:show-makefile.%=%))" - -.PHONY: show-makefiles show-makefile.% +.PHONY: show-makefiles # These rules support printing a Makefile variable values. From f559c36a6f9178c99c1bd43b5c597d1cc0f953e2 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 15 Apr 2019 11:54:13 -0500 Subject: [PATCH 31/85] Update tagged modules: pvDatabase 4.4.2, pvaClient 4.5.0 --- modules/pvDatabase | 2 +- modules/pvaClient | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/pvDatabase b/modules/pvDatabase index d0ddcead2..2715f585e 160000 --- a/modules/pvDatabase +++ b/modules/pvDatabase @@ -1 +1 @@ -Subproject commit d0ddcead2473624939230615b778bac88af9cf42 +Subproject commit 2715f585e0e4bca7dae3e0ad9e25dd44278d075c diff --git a/modules/pvaClient b/modules/pvaClient index b1c101578..428adb270 160000 --- a/modules/pvaClient +++ b/modules/pvaClient @@ -1 +1 @@ -Subproject commit b1c101578bea3610f777a1f51229eb2967dc89f4 +Subproject commit 428adb270e15a820fd2dc6647c7546ce54692cb9 From ccf34ae3d0c4b287d6437bbf5371642826ff8a6d Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 17 Apr 2019 14:17:37 -0700 Subject: [PATCH 32/85] update PVD and PVA --- modules/pvAccess | 2 +- modules/pvData | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/pvAccess b/modules/pvAccess index 78410499f..5b333922d 160000 --- a/modules/pvAccess +++ b/modules/pvAccess @@ -1 +1 @@ -Subproject commit 78410499f0236f5830a0937567bbb794de7b2347 +Subproject commit 5b333922d55fbc560e41496e7f36027dce271de4 diff --git a/modules/pvData b/modules/pvData index 8f0111e48..6da871fa6 160000 --- a/modules/pvData +++ b/modules/pvData @@ -1 +1 @@ -Subproject commit 8f0111e482aa139f4311378f2b0bc831c46420b2 +Subproject commit 6da871fa6471d00b1352024297e81e98c9c90d2b From a9dbd4dd39881f270665391bc7ad5adf4c6fc3c8 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 23 Apr 2019 16:07:43 -0500 Subject: [PATCH 33/85] Update libcom and base version numbers, no -DEV --- configure/CONFIG_BASE_VERSION | 4 ++-- modules/libcom/configure/CONFIG_LIBCOM_VERSION | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index e55ee5d33..468211ef9 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -56,8 +56,8 @@ EPICS_PATCH_LEVEL = 2 # Between official releases, the EPICS_PATCH_LEVEL gets incremented # and a -DEV suffix is added (similar to the Maven -SNAPSHOT versions) -#EPICS_DEV_SNAPSHOT= -EPICS_DEV_SNAPSHOT=-DEV +EPICS_DEV_SNAPSHOT= +#EPICS_DEV_SNAPSHOT=-DEV #EPICS_DEV_SNAPSHOT=-pre1 #EPICS_DEV_SNAPSHOT=-pre1-DEV #EPICS_DEV_SNAPSHOT=-pre2 diff --git a/modules/libcom/configure/CONFIG_LIBCOM_VERSION b/modules/libcom/configure/CONFIG_LIBCOM_VERSION index 5a21198ff..baf0a06a7 100644 --- a/modules/libcom/configure/CONFIG_LIBCOM_VERSION +++ b/modules/libcom/configure/CONFIG_LIBCOM_VERSION @@ -1,4 +1,4 @@ EPICS_LIBCOM_MAJOR_VERSION = 3 EPICS_LIBCOM_MINOR_VERSION = 17 -EPICS_LIBCOM_MAINTENANCE_VERSION = 3 +EPICS_LIBCOM_MAINTENANCE_VERSION = 4 EPICS_LIBCOM_DEVELOPMENT_FLAG = 0 From 7a84a1abba5679f20c8ddfb6ca0fa77026904f95 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 23 Apr 2019 16:23:20 -0500 Subject: [PATCH 34/85] Update Base version numbers for next patch release --- configure/CONFIG_BASE_VERSION | 6 +++--- documentation/RELEASE_NOTES.html | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index 468211ef9..6f2007076 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -52,12 +52,12 @@ EPICS_MODIFICATION = 2 # EPICS_PATCH_LEVEL must be a number (win32 resource file requirement) # Not included if zero -EPICS_PATCH_LEVEL = 2 +EPICS_PATCH_LEVEL = 3 # Between official releases, the EPICS_PATCH_LEVEL gets incremented # and a -DEV suffix is added (similar to the Maven -SNAPSHOT versions) -EPICS_DEV_SNAPSHOT= -#EPICS_DEV_SNAPSHOT=-DEV +#EPICS_DEV_SNAPSHOT= +EPICS_DEV_SNAPSHOT=-DEV #EPICS_DEV_SNAPSHOT=-pre1 #EPICS_DEV_SNAPSHOT=-pre1-DEV #EPICS_DEV_SNAPSHOT=-pre2 diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 62a70a648..df783606d 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -20,7 +20,7 @@ release.

which should also be read to understand what has changed since an earlier release.

-

EPICS Release 7.0.2.2

+

EPICS Release 7.0.2.3

+

EPICS Release 7.0.2.2

+

Build System changes

    From 630663caa8dc94b777edfa1e21f02e568a221bc7 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Wed, 24 Apr 2019 18:07:23 -0400 Subject: [PATCH 35/85] Fix weird use of strncpy Note: The old code was correct. This change just gets rid of a bunch of warnings. --- src/std/rec/boRecord.c | 4 ++-- src/std/rec/stateRecord.c | 2 +- src/std/rec/stringinRecord.c | 4 ++-- src/std/rec/stringoutRecord.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/std/rec/boRecord.c b/src/std/rec/boRecord.c index 88184555e..48cc4846a 100644 --- a/src/std/rec/boRecord.c +++ b/src/std/rec/boRecord.c @@ -329,9 +329,9 @@ static long get_enum_strs(DBADDR *paddr,struct dbr_enumStrs *pes) /*SETTING no_str=0 breaks channel access clients*/ pes->no_str = 2; memset(pes->strs,'\0',sizeof(pes->strs)); - strncpy(pes->strs[0],prec->znam,sizeof(prec->znam)); + strncpy(pes->strs[0],prec->znam,sizeof(pes->strs[0])); if(*prec->znam!=0) pes->no_str=1; - strncpy(pes->strs[1],prec->onam,sizeof(prec->onam)); + strncpy(pes->strs[1],prec->onam,sizeof(pes->strs[1])); if(*prec->onam!=0) pes->no_str=2; return(0); } diff --git a/src/std/rec/stateRecord.c b/src/std/rec/stateRecord.c index a052b0728..8170de7e9 100644 --- a/src/std/rec/stateRecord.c +++ b/src/std/rec/stateRecord.c @@ -98,7 +98,7 @@ static void monitor(stateRecord *prec) monitor_mask = recGblResetAlarms(prec); if(strncmp(prec->oval,prec->val,sizeof(prec->val))) { db_post_events(prec,&(prec->val[0]),monitor_mask|DBE_VALUE|DBE_LOG); - strncpy(prec->oval,prec->val,sizeof(prec->val)); + strncpy(prec->oval,prec->val,sizeof(prec->oval)); } return; } diff --git a/src/std/rec/stringinRecord.c b/src/std/rec/stringinRecord.c index db2f626f1..aac7d4e0f 100644 --- a/src/std/rec/stringinRecord.c +++ b/src/std/rec/stringinRecord.c @@ -120,7 +120,7 @@ static long init_record(stringinRecord *prec, int pass) if( pdset->init_record ) { if((status=(*pdset->init_record)(prec))) return(status); } - strncpy(prec->oval, prec->val, sizeof(prec->val)); + strncpy(prec->oval, prec->val, sizeof(prec->oval)); return(0); } @@ -160,7 +160,7 @@ static void monitor(stringinRecord *prec) if (strncmp(prec->oval, prec->val, sizeof(prec->val))) { monitor_mask |= DBE_VALUE | DBE_LOG; - strncpy(prec->oval, prec->val, sizeof(prec->val)); + strncpy(prec->oval, prec->val, sizeof(prec->oval)); } if (prec->mpst == stringinPOST_Always) diff --git a/src/std/rec/stringoutRecord.c b/src/std/rec/stringoutRecord.c index 2bca3228c..61d88f60f 100644 --- a/src/std/rec/stringoutRecord.c +++ b/src/std/rec/stringoutRecord.c @@ -122,7 +122,7 @@ static long init_record(stringoutRecord *prec, int pass) if( pdset->init_record ) { if((status=(*pdset->init_record)(prec))) return(status); } - strncpy(prec->oval, prec->val, sizeof(prec->val)); + strncpy(prec->oval, prec->val, sizeof(prec->oval)); return(0); } @@ -188,7 +188,7 @@ static void monitor(stringoutRecord *prec) if (strncmp(prec->oval, prec->val, sizeof(prec->val))) { monitor_mask |= DBE_VALUE | DBE_LOG; - strncpy(prec->oval, prec->val, sizeof(prec->val)); + strncpy(prec->oval, prec->val, sizeof(prec->oval)); } if (prec->mpst == stringoutPOST_Always) From 8e9d75ad712d7e6464b7f5ea66cab1359812e8f6 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Wed, 24 Apr 2019 18:51:50 -0400 Subject: [PATCH 36/85] Fix potential buffer overflow in iocLogServer --- src/libCom/log/iocLogServer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libCom/log/iocLogServer.c b/src/libCom/log/iocLogServer.c index f42aa4563..67bcf1bd3 100644 --- a/src/libCom/log/iocLogServer.c +++ b/src/libCom/log/iocLogServer.c @@ -37,7 +37,7 @@ static unsigned short ioc_log_port; static long ioc_log_file_limit; -static char ioc_log_file_name[256]; +static char ioc_log_file_name[512]; static char ioc_log_file_command[256]; From e02c5c3026b8eafd7a17269558371b754f90744a Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Wed, 24 Apr 2019 22:06:29 -0400 Subject: [PATCH 37/85] iocLogServer: check return values No serious issues here just fixing some warnings. --- src/libCom/log/iocLogServer.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libCom/log/iocLogServer.c b/src/libCom/log/iocLogServer.c index 67bcf1bd3..e707185ae 100644 --- a/src/libCom/log/iocLogServer.c +++ b/src/libCom/log/iocLogServer.c @@ -866,7 +866,12 @@ static int setupSIGHUP(struct ioc_log_server *pserver) */ static void sighupHandler(int signo) { - (void) write(sighupPipe[1], "SIGHUP\n", 7); + const char msg[] = "SIGHUP\n"; + const ssize_t bytesWritten = write(sighupPipe[1], msg, sizeof(msg)); + if (bytesWritten != sizeof(msg)) { + fprintf(stderr, "iocLogServer: failed to write to SIGHUP pipe because " + "`%s'\n", strerror(errno)); + } } @@ -884,7 +889,10 @@ static void serviceSighupRequest(void *pParam) /* * Read and discard message from pipe. */ - (void) read(sighupPipe[0], buff, sizeof buff); + if (read(sighupPipe[0], buff, sizeof buff) <= 0) { + fprintf(stderr, "iocLogServer: failed to read from SIGHUP pipe because " + "`%s'\n", strerror(errno)); + }; /* * Determine new log file name. From 1f95d0db127c5cf1ea077b48be43103cf1309f8c Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Thu, 25 Apr 2019 11:00:39 -0400 Subject: [PATCH 38/85] epicsTime: rely on implicit copy constructor When a custom copy constructor is defined the assignment operator also needs to be defined explicitly. For this simple class the implicit copy ctor/assignment operator are sufficient, though. This fixes a warning emitted by GCC9. --- src/libCom/osi/epicsTime.cpp | 3 --- src/libCom/osi/epicsTime.h | 1 - 2 files changed, 4 deletions(-) diff --git a/src/libCom/osi/epicsTime.cpp b/src/libCom/osi/epicsTime.cpp index af4fae25d..ef43e0ad2 100644 --- a/src/libCom/osi/epicsTime.cpp +++ b/src/libCom/osi/epicsTime.cpp @@ -205,9 +205,6 @@ epicsTime::epicsTime (const epicsTimeStamp &ts) epicsTime::epicsTime () : secPastEpoch(0u), nSec(0u) {} -epicsTime::epicsTime (const epicsTime &t) : - secPastEpoch (t.secPastEpoch), nSec (t.nSec) {} - epicsTime epicsTime::getCurrent () { epicsTimeStamp current; diff --git a/src/libCom/osi/epicsTime.h b/src/libCom/osi/epicsTime.h index 1cb3733bc..d8b266346 100644 --- a/src/libCom/osi/epicsTime.h +++ b/src/libCom/osi/epicsTime.h @@ -81,7 +81,6 @@ public: class formatProblemWithStructTM {}; epicsTime (); - epicsTime ( const epicsTime & t ); static epicsTime getEvent ( const epicsTimeEvent & ); static epicsTime getCurrent (); From f486dba4787a5540ec3bec7ddc1995507ab35135 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 26 Apr 2019 13:53:24 -0500 Subject: [PATCH 39/85] Add some epics-controls publishing instructions, incomplete --- documentation/ReleaseChecklist.html | 67 +++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/documentation/ReleaseChecklist.html b/documentation/ReleaseChecklist.html index 1b28165be..ad305cc52 100644 --- a/documentation/ReleaseChecklist.html +++ b/documentation/ReleaseChecklist.html @@ -126,9 +126,10 @@ starting at Release Approval.

      Website Manager - Create a release milestone on Launchpad if necessary and set the - expected release date. Note that pre-release and release-candidate - versions do not appear on Launchpad, only the final release. + Create a release milestone on Launchpad. If a target release date is + known set "Date Targeted" to the expected release date. Note that + pre-release and release-candidate versions should not get Launchpad + milestones, only the final release. Creating pre-release and release-candidate versions @@ -348,27 +349,16 @@ starting at Release Approval.

    with a "-DEV" tag added (where applicable). + + + Publish to epics.anl.gov + Release Manager Copy the tarfile and its signature to the Base download area of the website. - - - Release Manager - Find all Launchpad bug reports with the status Fix Committed which - have been fixed in this release and mark them Fix Released. - - - Publish and Announce it - - - - Website Manager - Upload the tar file and its .asc signature file to the - Launchpad milestone for this release version. - Website Manager @@ -400,6 +390,47 @@ starting at Release Approval.

    Add an entry to the website News page, linking to the new version webpage. + + + Publish to epics-controls + + + + Website Manager + Upload the tar file and its .asc signature file to the + epics-controls web-server [ToDo: ssh-key, location] + + + + Website Manager + Follow instructions on + + Add a page for a new release to create a new release webpage (not + required for a patch release though, just edit the existing page). + + + + Publish to Launchpad + + + + Website Manager + Go to the Launchpad milestone for this release. Click the Create + release button and add the release date. Put a URL for the release page + in the Release notes box, and click the Create release button. Upload + the tar file and its .asc signature file to the new Launchpad + release page. + + + + Release Manager + Find all Launchpad bug reports with the status Fix Committed which + have been fixed in this release and mark them Fix Released. + + + + Make Announcement + Release Manager From 12283ce25ab443bed769e35c217beacfc0d2a062 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Tue, 30 Apr 2019 15:26:35 +0200 Subject: [PATCH 40/85] appveyor-ci: exclude some cygwin builds (broken compiler) --- .appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.appveyor.yml b/.appveyor.yml index 2652a7810..26bca0385 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -60,6 +60,10 @@ matrix: # VS Express installs don't have the 64 bit compiler - platform: x64 TOOLCHAIN: 10.0 + # Cygwin static-debug has compiler problems + - configuration: static-debug + TOOLCHAIN: cygwin + #---------------------------------# # building & testing # From 17dea964a66f0cbad12ebacecff7f186e873015e Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Tue, 30 Apr 2019 15:51:28 +0200 Subject: [PATCH 41/85] appveyor-ci: remove slack, add email and GitHub notifications --- .appveyor.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 26bca0385..bc07969fe 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -85,6 +85,9 @@ test_script: notifications: - - provider: Slack - incoming_webhook: - secure: RYOm3FIUYeZGjWKaeTVKwq+C3fzK54AKwbmAoECED45mex3lN+8HmrC845a6mg9xPUJ/ND51RopWVaKDD9/UzaM0SO195RQLKqUTIUafiuM= + - provider: Email + to: + - core-talk@aps.anl.gov + on_build_success: false + + - provider: GitHubPullRequest From ec7193d0be9934412b3e61138b1be1c71d9d83b7 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Tue, 30 Apr 2019 15:53:50 +0200 Subject: [PATCH 42/85] appveyor-ci: exclude some cygwin builds (broken compiler) appveyor-ci: remove slack, add email and GitHub notifications (cherry-picked from branch 7.0) --- appveyor.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index dbbd7a908..6c21f03a4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -60,6 +60,10 @@ matrix: # VS Express installs don't have the 64 bit compiler - platform: x64 TOOLCHAIN: 10.0 + # Cygwin static-debug has compiler problems + - configuration: static-debug + TOOLCHAIN: cygwin + #---------------------------------# # building & testing # @@ -80,6 +84,9 @@ test_script: notifications: - - provider: Slack - incoming_webhook: - secure: RYOm3FIUYeZGjWKaeTVKwq+C3fzK54AKwbmAoECED45mex3lN+8HmrC845a6mg9xPUJ/ND51RopWVaKDD9/UzaM0SO195RQLKqUTIUafiuM= + - provider: Email + to: + - core-talk@aps.anl.gov + on_build_success: false + + - provider: GitHubPullRequest From 63bf8a821971d83955f17e86110b88726559d10f Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Thu, 2 May 2019 11:39:04 +0200 Subject: [PATCH 43/85] appveyor-ci: use choco MinGW 5.3.0 to work around build problem (fixes lp:1827225) --- ci/appveyor-prepare.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/appveyor-prepare.bat b/ci/appveyor-prepare.bat index 26ca8118a..c1d0e5d9a 100644 --- a/ci/appveyor-prepare.bat +++ b/ci/appveyor-prepare.bat @@ -57,10 +57,10 @@ if "%TOOLCHAIN%"=="mingw" ( ) if "%OS%"=="64BIT" ( echo [INFO] Installing MinGW 64bit - cinst mingw || cinst mingw + cinst mingw --version="5.3.0" || cinst mingw --version="5.3.0" ) else ( echo [INFO] Installing MinGW 32bit - cinst mingw --x86 || cinst mingw --x86 + cinst mingw --x86 --version="5.3.0" || cinst mingw --x86 --version="5.3.0" ) ) From 3110322f8cb261758bcc6618dacef3e01dc76b90 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Thu, 2 May 2019 12:09:09 +0200 Subject: [PATCH 44/85] appveyor-ci: use choco MinGW 5.3.0 to work around build problem (fixes lp:1827225) --- .ci/appveyor-prepare.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/appveyor-prepare.bat b/.ci/appveyor-prepare.bat index 26ca8118a..c1d0e5d9a 100644 --- a/.ci/appveyor-prepare.bat +++ b/.ci/appveyor-prepare.bat @@ -57,10 +57,10 @@ if "%TOOLCHAIN%"=="mingw" ( ) if "%OS%"=="64BIT" ( echo [INFO] Installing MinGW 64bit - cinst mingw || cinst mingw + cinst mingw --version="5.3.0" || cinst mingw --version="5.3.0" ) else ( echo [INFO] Installing MinGW 32bit - cinst mingw --x86 || cinst mingw --x86 + cinst mingw --x86 --version="5.3.0" || cinst mingw --x86 --version="5.3.0" ) ) From 297206e247c9847f238d5ede3d01134f3c9375ce Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Fri, 3 May 2019 15:29:07 +0200 Subject: [PATCH 45/85] appveyor-ci: use pre-installed AppVeyor MinGW --- appveyor.yml | 1 + ci/appveyor-make.bat | 8 ++++---- ci/appveyor-prepare.bat | 7 ------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6c21f03a4..b6fb2f2ae 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -48,6 +48,7 @@ environment: TOOLCHAIN: 2017 - TOOLCHAIN: cygwin - TOOLCHAIN: mingw + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 # Platform: architecture platform: diff --git a/ci/appveyor-make.bat b/ci/appveyor-make.bat index a489d80ee..9cd8fe684 100644 --- a/ci/appveyor-make.bat +++ b/ci/appveyor-make.bat @@ -42,13 +42,13 @@ if "%TOOLCHAIN%"=="mingw" ( set "MAKE=mingw32-make" if "%OS%"=="64BIT" ( set "EPICS_HOST_ARCH=windows-x64-mingw" - set "INCLUDE=C:\tools\mingw64\include;%INCLUDE%" - set "PATH=C:\tools\mingw64\bin;%PATH%" + set "INCLUDE=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\include;%INCLUDE%" + set "PATH=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;%PATH%" echo [INFO] MinGW Toolchain 64bit ) else ( set "EPICS_HOST_ARCH=win32-x86-mingw" - set "INCLUDE=C:\tools\mingw32\include;%INCLUDE%" - set "PATH=C:\tools\mingw32\bin;%PATH%" + set "INCLUDE=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\include;%INCLUDE%" + set "PATH=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin;%PATH%" echo [INFO] MinGW Toolchain 32bit ) echo [INFO] Compiler Version diff --git a/ci/appveyor-prepare.bat b/ci/appveyor-prepare.bat index c1d0e5d9a..9e116354a 100644 --- a/ci/appveyor-prepare.bat +++ b/ci/appveyor-prepare.bat @@ -55,13 +55,6 @@ if "%TOOLCHAIN%"=="mingw" ( ) || ( echo [INFO] EPICS set up for optimized build ) - if "%OS%"=="64BIT" ( - echo [INFO] Installing MinGW 64bit - cinst mingw --version="5.3.0" || cinst mingw --version="5.3.0" - ) else ( - echo [INFO] Installing MinGW 32bit - cinst mingw --x86 --version="5.3.0" || cinst mingw --x86 --version="5.3.0" - ) ) echo [INFO] Installing Make 4.1 From 16ddcaeaed34b8b306cd558ce80b5c815406d313 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Fri, 3 May 2019 15:30:59 +0200 Subject: [PATCH 46/85] appveyor-ci: ANL Make install 4.1 -> 4.2.1 --- ci/appveyor-prepare.bat | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/appveyor-prepare.bat b/ci/appveyor-prepare.bat index 9e116354a..9f105ee96 100644 --- a/ci/appveyor-prepare.bat +++ b/ci/appveyor-prepare.bat @@ -57,7 +57,7 @@ if "%TOOLCHAIN%"=="mingw" ( ) ) -echo [INFO] Installing Make 4.1 -curl -fsS --retry 3 -o C:\tools\make-4.1.zip https://epics.anl.gov/download/tools/make-4.1-win64.zip +echo [INFO] Installing Make 4.2.1 from ANL web site +curl -fsS --retry 3 -o C:\tools\make-4.2.1.zip https://epics.anl.gov/download/tools/make-4.2.1-win64.zip cd \tools -"C:\Program Files\7-Zip\7z" e make-4.1.zip +"C:\Program Files\7-Zip\7z" e make-4.2.1.zip From 52cdfe0a440258307540d2d37f35e5c09bf3cba5 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Fri, 3 May 2019 15:34:01 +0200 Subject: [PATCH 47/85] appveyor-ci: use pre-installed AppVeyor MinGW --- .appveyor.yml | 1 + .ci/appveyor-make.bat | 8 ++++---- .ci/appveyor-prepare.bat | 7 ------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index bc07969fe..2cdc51128 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -48,6 +48,7 @@ environment: TOOLCHAIN: 2017 - TOOLCHAIN: cygwin - TOOLCHAIN: mingw + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 # Platform: architecture platform: diff --git a/.ci/appveyor-make.bat b/.ci/appveyor-make.bat index a489d80ee..9cd8fe684 100644 --- a/.ci/appveyor-make.bat +++ b/.ci/appveyor-make.bat @@ -42,13 +42,13 @@ if "%TOOLCHAIN%"=="mingw" ( set "MAKE=mingw32-make" if "%OS%"=="64BIT" ( set "EPICS_HOST_ARCH=windows-x64-mingw" - set "INCLUDE=C:\tools\mingw64\include;%INCLUDE%" - set "PATH=C:\tools\mingw64\bin;%PATH%" + set "INCLUDE=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\include;%INCLUDE%" + set "PATH=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;%PATH%" echo [INFO] MinGW Toolchain 64bit ) else ( set "EPICS_HOST_ARCH=win32-x86-mingw" - set "INCLUDE=C:\tools\mingw32\include;%INCLUDE%" - set "PATH=C:\tools\mingw32\bin;%PATH%" + set "INCLUDE=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\include;%INCLUDE%" + set "PATH=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin;%PATH%" echo [INFO] MinGW Toolchain 32bit ) echo [INFO] Compiler Version diff --git a/.ci/appveyor-prepare.bat b/.ci/appveyor-prepare.bat index c1d0e5d9a..9e116354a 100644 --- a/.ci/appveyor-prepare.bat +++ b/.ci/appveyor-prepare.bat @@ -55,13 +55,6 @@ if "%TOOLCHAIN%"=="mingw" ( ) || ( echo [INFO] EPICS set up for optimized build ) - if "%OS%"=="64BIT" ( - echo [INFO] Installing MinGW 64bit - cinst mingw --version="5.3.0" || cinst mingw --version="5.3.0" - ) else ( - echo [INFO] Installing MinGW 32bit - cinst mingw --x86 --version="5.3.0" || cinst mingw --x86 --version="5.3.0" - ) ) echo [INFO] Installing Make 4.1 From fe34c6f35e09a036d411af22660367153e1c7032 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Fri, 3 May 2019 15:34:37 +0200 Subject: [PATCH 48/85] appveyor-ci: ANL Make install 4.1 -> 4.2.1 --- .ci/appveyor-prepare.bat | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/appveyor-prepare.bat b/.ci/appveyor-prepare.bat index 9e116354a..9f105ee96 100644 --- a/.ci/appveyor-prepare.bat +++ b/.ci/appveyor-prepare.bat @@ -57,7 +57,7 @@ if "%TOOLCHAIN%"=="mingw" ( ) ) -echo [INFO] Installing Make 4.1 -curl -fsS --retry 3 -o C:\tools\make-4.1.zip https://epics.anl.gov/download/tools/make-4.1-win64.zip +echo [INFO] Installing Make 4.2.1 from ANL web site +curl -fsS --retry 3 -o C:\tools\make-4.2.1.zip https://epics.anl.gov/download/tools/make-4.2.1-win64.zip cd \tools -"C:\Program Files\7-Zip\7z" e make-4.1.zip +"C:\Program Files\7-Zip\7z" e make-4.2.1.zip From 2d3de1916be3a42155dda0749a52a7b4bfe804e0 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 6 May 2019 12:22:34 -0500 Subject: [PATCH 49/85] Don't clear caClientCallbackThreadId in CA's exit handler --- documentation/RELEASE_NOTES.html | 9 +++++++++ src/ca/client/ca_client_context.cpp | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index c47dc2d5b..8ed4e04bf 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -16,6 +16,15 @@ +

    Cleaning up with Multiple CA contexts in a Process

    + +

    Bruno Martins reported a problem with the CA client library at shutdown in a +process that uses multiple CA client contexts. The first context that triggers +the CA client exit handler prevents any others from being able to clean up +because it resets the ID of an internal epicsThreadPrivate variable which is +shared by all clients. This action has been removed from the client library, +which makes cleanup of clients like this possible.

    +

    Perl CA bindings fixed for macOS Mojave

    Apple removed some Perl header files from macOS Mojave that were available diff --git a/src/ca/client/ca_client_context.cpp b/src/ca/client/ca_client_context.cpp index 20a6e84c8..95cd6cb59 100644 --- a/src/ca/client/ca_client_context.cpp +++ b/src/ca/client/ca_client_context.cpp @@ -48,7 +48,6 @@ const unsigned ca_client_context :: flushBlockThreshold = 0x58000; extern "C" void cacExitHandler ( void *) { epicsThreadPrivateDelete ( caClientCallbackThreadId ); - caClientCallbackThreadId = 0; delete ca_client_context::pDefaultServiceInstallMutex; } From 25576c316ac1212dc7b3703d5d5ab36a43608050 Mon Sep 17 00:00:00 2001 From: Martin Konrad Date: Mon, 6 May 2019 14:56:45 -0400 Subject: [PATCH 50/85] Remove cacExitHandler We need to ensure the allocated resources stick around until the last instance using them doesn't need them anymore. Sharing a raw pointer by exporting it as a global variable is not compatible with cleaning up at all. For now we remove the clean-up code. Note: This fixes a segfault during IOC shutdown when using both pyDevSup and pyepics. See the discussion on https://epics.anl.gov/tech-talk/2019/msg00778.php for details. --- src/ca/client/ca_client_context.cpp | 7 ------- src/ca/client/oldAccess.h | 2 -- 2 files changed, 9 deletions(-) diff --git a/src/ca/client/ca_client_context.cpp b/src/ca/client/ca_client_context.cpp index 95cd6cb59..ce8de1ecb 100644 --- a/src/ca/client/ca_client_context.cpp +++ b/src/ca/client/ca_client_context.cpp @@ -45,19 +45,12 @@ static epicsThreadOnceId cacOnce = EPICS_THREAD_ONCE_INIT; const unsigned ca_client_context :: flushBlockThreshold = 0x58000; -extern "C" void cacExitHandler ( void *) -{ - epicsThreadPrivateDelete ( caClientCallbackThreadId ); - delete ca_client_context::pDefaultServiceInstallMutex; -} - // runs once only for each process extern "C" void cacOnceFunc ( void * ) { caClientCallbackThreadId = epicsThreadPrivateCreate (); assert ( caClientCallbackThreadId ); ca_client_context::pDefaultServiceInstallMutex = newEpicsMutex; - epicsAtExit ( cacExitHandler,0 ); } extern epicsThreadPrivateId caClientContextId; diff --git a/src/ca/client/oldAccess.h b/src/ca/client/oldAccess.h index 04f551839..daa4cc912 100644 --- a/src/ca/client/oldAccess.h +++ b/src/ca/client/oldAccess.h @@ -288,7 +288,6 @@ private: }; extern "C" void cacOnceFunc ( void * ); -extern "C" void cacExitHandler ( void *); struct ca_client_context : public cacContextNotify { @@ -428,7 +427,6 @@ private: ca_client_context & operator = ( const ca_client_context & ); friend void cacOnceFunc ( void * ); - friend void cacExitHandler ( void *); static cacService * pDefaultService; static epicsMutex * pDefaultServiceInstallMutex; static const unsigned flushBlockThreshold; From bf8ff4e5f183df675ef1e40be37e5f49718c4ca3 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 8 May 2019 19:05:58 -0700 Subject: [PATCH 51/85] !gtMoreThanDefault -> useOsdGetCurrent --- modules/libcom/src/osi/epicsGeneralTime.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/libcom/src/osi/epicsGeneralTime.c b/modules/libcom/src/osi/epicsGeneralTime.c index dff495ef0..e5dd42201 100644 --- a/modules/libcom/src/osi/epicsGeneralTime.c +++ b/modules/libcom/src/osi/epicsGeneralTime.c @@ -80,8 +80,8 @@ static const char * const tsfmt = "%Y-%m-%d %H:%M:%S.%09f"; /* defined in osiClockTime.c or osdTime.cpp */ int osdTimeGetCurrent ( epicsTimeStamp *pDest ); -/* set if/when gtPvt.timeProviders contains more than the default osdTimeGetCurrent() */ -static int gtMoreThanDefault; +/* cleared if/when gtPvt.timeProviders contains more than the default osdTimeGetCurrent() */ +static int useOsdGetCurrent = 1; /* Implementation */ @@ -108,7 +108,7 @@ int generalTimeGetExceptPriority(epicsTimeStamp *pDest, int *pPrio, int ignore) gtProvider *ptp; int status = S_time_noProvider; - if(!gtMoreThanDefault) + if(useOsdGetCurrent) return osdTimeGetCurrent(pDest); generalTime_Init(); @@ -156,7 +156,7 @@ int epicsShareAPI epicsTimeGetCurrent(epicsTimeStamp *pDest) int status = S_time_noProvider; epicsTimeStamp ts; - if(!gtMoreThanDefault) + if(useOsdGetCurrent) return osdTimeGetCurrent(pDest); generalTime_Init(); @@ -383,7 +383,7 @@ static void insertProvider(gtProvider *ptp, ELLLIST *plist, epicsMutexId lock) /* Check to see if we have more than just the OS default time source */ if(plist==>Pvt.timeProviders && (ellCount(plist)!=1 || ptp->get.Time!=&osdTimeGetCurrent)) { - gtMoreThanDefault = 1; + useOsdGetCurrent = 0; } epicsMutexUnlock(lock); From 96259b7bdc3f06f51589fbbb002a3d6fd2c52408 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Thu, 9 May 2019 17:28:36 +0200 Subject: [PATCH 52/85] doc/ca: clarify variable size array subscription --- src/ca/client/CAref.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ca/client/CAref.html b/src/ca/client/CAref.html index 81e2eb664..ef4df758e 100644 --- a/src/ca/client/CAref.html +++ b/src/ca/client/CAref.html @@ -3137,7 +3137,8 @@ indicating the current state of the channel.

    COUNT
    The element count to be read from the specified channel. A count of - zero means use the current element count from the server.
    + zero means use the current element count from the server, effectively + resulting in a variable size array subscription.
    CHID
    From 8c993405b4b4cf3bb9268ffa1b1e5731e5719810 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Thu, 9 May 2019 17:32:05 +0200 Subject: [PATCH 53/85] doc/ca: clarify variable size array subscription (cherry-picked from branch 3.15) --- modules/ca/src/client/CAref.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/ca/src/client/CAref.html b/modules/ca/src/client/CAref.html index 741716116..7b6ff143f 100644 --- a/modules/ca/src/client/CAref.html +++ b/modules/ca/src/client/CAref.html @@ -3143,7 +3143,8 @@ indicating the current state of the channel.

    COUNT
    The element count to be read from the specified channel. A count of - zero means use the current element count from the server.
    + zero means use the current element count from the server, effectively + resulting in a variable size array subscription.
    CHID
    From 86138fdd23abb1b06e5a06acc2884a2ccb6f5ba6 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 9 May 2019 11:51:26 -0500 Subject: [PATCH 54/85] Fix make-tar.sh to work on MacOS too The BSD version of tar doesn't support -a, and requires -T instead of --files-from. --- .tools/make-tar.sh | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/.tools/make-tar.sh b/.tools/make-tar.sh index 4c9c33a7b..e6bf59315 100755 --- a/.tools/make-tar.sh +++ b/.tools/make-tar.sh @@ -16,23 +16,46 @@ PREFIX="$3" if ! [ "$TOPREV" ] then cat <&2 -usage: $0 [rev] [outfile.tar.gz] [prefix/] +usage: $0 [ []] may be any git revision spec. (tag, branch, or commit id). - Output file may be .tar.gz, .tar.bz2, or any extension supported by "tar -a". - If output file name is omitted, "base-.tar.gz" will be used. - If is omitted, the default prefix is "base-/". + If provided, must end with ".tar", ".tar.gz" or ".tar.bz2". + If is omitted, "base-.tar.gz" will be used. + If provided, must end with "/". If is omitted, + the default is "base-/". EOF exit 1 fi -[ "$FINALTAR" ] || FINALTAR="base-$TOPREV.tar.gz" -[ "$PREFIX" ] || PREFIX="base-$TOPREV/" +case "$FINALTAR" in +"") + TAROPT=-z + FINALTAR="base-$TOPREV.tar.gz" + ;; +*.tar) + TAROPT="" + ;; +*.tar.gz) + TAROPT=-z + ;; +*.tar.bz2) + TAROPT=-j + ;; +*) + die "outfile must end with '.tar.gz' or '.tar.bz2'" + ;; +esac case "$PREFIX" in -*/) ;; -*) die "Prefix must end with '/'";; +"") + PREFIX="base-$TOPREV/" + ;; +*/) + ;; +*) + die "Prefix must end with '/'" + ;; esac # Check for both and R @@ -97,13 +120,11 @@ then fi # Use the filtered list to build the final tar -# The -a option chooses compression automatically based on output file name. - -tar -C "$TDIR"/tar --files-from="$TDIR"/list.2 -caf "$FINALTAR" +tar -c $TAROPT -C "$TDIR"/tar -T "$TDIR"/list.2 -f "$FINALTAR" echo "Wrote $FINALTAR" -tar -taf "$FINALTAR" > "$TDIR"/list.3 +tar -t $TAROPT -f "$FINALTAR" > "$TDIR"/list.3 # make sure we haven't picked up anything extra if ! diff -u "$TDIR"/list.2 "$TDIR"/list.3 From 71d4d3ecbd068dd5898d0522be5f20a37aadd49a Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 9 May 2019 15:03:56 -0500 Subject: [PATCH 55/85] epicsErrlogTest.c improvements Instrument testEqInt() macro with caller's source line-number. Added another epicsEvent to wait for the listeners to run. Not guaranteed to fix all issues, but should be more reliable. --- modules/libcom/test/epicsErrlogTest.c | 44 ++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/modules/libcom/test/epicsErrlogTest.c b/modules/libcom/test/epicsErrlogTest.c index 28d88f6af..2f1c42740 100644 --- a/modules/libcom/test/epicsErrlogTest.c +++ b/modules/libcom/test/epicsErrlogTest.c @@ -78,6 +78,7 @@ typedef struct { size_t checkLen; epicsEventId jammer; int jam; + epicsEventId done; } clientPvt; static void testLogPrefix(void); @@ -102,12 +103,13 @@ static const char prefixexpectedmsg[] = "A message without prefix" static char prefixmsgbuffer[1024]; -static -void testEqInt_(int lhs, int rhs, const char *LHS, const char *RHS) +static void +testEqInt_(int line, int lhs, int rhs, const char *LHS, const char *RHS) { - testOk(lhs==rhs, "%s (%d) == %s (%d)", LHS, lhs, RHS, rhs); + testOk(lhs==rhs, "%d: %s (%d) == %s (%d)", line, LHS, lhs, RHS, rhs); } -#define testEqInt(L, R) testEqInt_(L, R, #L, #R); +#define testEqInt(L, R) testEqInt_(__LINE__, L, R, #L, #R); + static void logClient(void* raw, const char* msg) { @@ -161,6 +163,7 @@ void logClient(void* raw, const char* msg) } pvt->count++; + epicsEventSignal(pvt->done); } MAIN(epicsErrlogTest) @@ -169,7 +172,7 @@ MAIN(epicsErrlogTest) char msg[256]; clientPvt pvt, pvt2; - testPlan(32); + testPlan(40); strcpy(msg, truncmsg); @@ -188,7 +191,9 @@ MAIN(epicsErrlogTest) pvt2.jam = 0; pvt.jammer = epicsEventMustCreate(epicsEventEmpty); + pvt.done = epicsEventMustCreate(epicsEventEmpty); pvt2.jammer = epicsEventMustCreate(epicsEventEmpty); + pvt2.done = epicsEventMustCreate(epicsEventEmpty); testDiag("Check listener registration"); @@ -200,6 +205,7 @@ MAIN(epicsErrlogTest) errlogPrintfNoConsole("%s", pvt.expect); errlogFlush(); + epicsEventMustWait(pvt.done); testEqInt(pvt.count, 1); errlogAddListener(&logClient, &pvt2); @@ -210,7 +216,10 @@ MAIN(epicsErrlogTest) errlogPrintfNoConsole("%s", pvt.expect); errlogFlush(); + epicsEventMustWait(pvt.done); testEqInt(pvt.count, 2); + + epicsEventMustWait(pvt2.done); testEqInt(pvt2.count, 1); /* Removes the first listener */ @@ -223,6 +232,10 @@ MAIN(epicsErrlogTest) errlogPrintfNoConsole("%s", pvt2.expect); errlogFlush(); + testOk(epicsEventWaitWithTimeout(pvt.done, 0.5) == epicsEventWaitTimeout, + "%d: Listener 1 didn't run", __LINE__); + testOk(epicsEventTryWait(pvt2.done) == epicsEventOK, + "%d: Listener 2 ran", __LINE__); testEqInt(pvt.count, 2); testEqInt(pvt2.count, 2); @@ -234,6 +247,10 @@ MAIN(epicsErrlogTest) errlogPrintfNoConsole("Something different"); errlogFlush(); + testOk(epicsEventWaitWithTimeout(pvt.done, 0.5) == epicsEventWaitTimeout, + "%d: Listener 1 didn't run", __LINE__); + testOk(epicsEventTryWait(pvt2.done) == epicsEventWaitTimeout, + "%d: Listener 2 didn't run", __LINE__); testEqInt(pvt.count, 2); testEqInt(pvt2.count, 2); @@ -248,6 +265,7 @@ MAIN(epicsErrlogTest) errlogPrintfNoConsole("%s", longmsg); errlogFlush(); + epicsEventMustWait(pvt.done); testEqInt(pvt.count, 3); pvt.expect = NULL; @@ -259,13 +277,15 @@ MAIN(epicsErrlogTest) pvt.jam = 1; errlogPrintfNoConsole("%s", longmsg); - epicsThreadSleep(0.1); + testOk(epicsEventWaitWithTimeout(pvt.done, 0.5) == epicsEventWaitTimeout, + "%d: Listener 1 didn't run", __LINE__); testEqInt(pvt.count, 3); epicsEventSignal(pvt.jammer); errlogFlush(); + epicsEventMustWait(pvt.done); testEqInt(pvt.count, 4); testDiag("Find buffer capacity (%u theoretical)",LOGBUFSIZE); @@ -303,6 +323,9 @@ MAIN(epicsErrlogTest) errlogFlush(); } + testOk(epicsEventTryWait(pvt.done) == epicsEventOK, + "%d: Listener 1 ran", __LINE__); + testDiag("Checking buffer use after partial flush"); /* Use the numbers from the largest block size above */ @@ -317,16 +340,18 @@ MAIN(epicsErrlogTest) for (i = 0; i < N; i++) { errlogPrintfNoConsole("%s", msg); } - epicsThreadSleep(0.1); /* should really be a second Event */ + testOk(epicsEventWaitWithTimeout(pvt.done, 0.5) == epicsEventWaitTimeout, + "%d: Listener 1 didn't run", __LINE__); testEqInt(pvt.count, 0); /* Extract the first 2 messages, 2*(sizeof(msgNode) + 128) bytes */ pvt.jam = -2; epicsEventSignal(pvt.jammer); - epicsThreadSleep(0.1); + epicsThreadSleep(0.5); testDiag("Drained %u messages", pvt.count); + epicsEventMustWait(pvt.done); testEqInt(pvt.count, 2); /* The buffer has space for 1 more message: sizeof(msgNode) + 256 bytes */ @@ -335,12 +360,15 @@ MAIN(epicsErrlogTest) testDiag("Overflow the buffer"); errlogPrintfNoConsole("%s", msg); + testOk(epicsEventWaitWithTimeout(pvt.done, 0.5) == epicsEventWaitTimeout, + "%d: Listener 1 didn't run", __LINE__); testEqInt(pvt.count, 2); epicsEventSignal(pvt.jammer); /* Empty */ errlogFlush(); testDiag("Logged %u messages", pvt.count); + epicsEventMustWait(pvt.done); testEqInt(pvt.count, N+1); /* Clean up */ From 655c5bed925137619d4a538f7893400b38c7c907 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 20 May 2019 15:32:57 -0700 Subject: [PATCH 56/85] osiClockTime Darwin doesn't use. Darwin/osdTime.cpp unconditionally provides osdTimeGetCurrent() and never calls ClockTime_Init(). --- modules/libcom/src/osi/osiClockTime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libcom/src/osi/osiClockTime.c b/modules/libcom/src/osi/osiClockTime.c index bf29427b2..091a95715 100644 --- a/modules/libcom/src/osi/osiClockTime.c +++ b/modules/libcom/src/osi/osiClockTime.c @@ -40,7 +40,7 @@ static struct { static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; -#if defined(CLOCK_REALTIME) && !defined(_WIN32) +#if defined(CLOCK_REALTIME) && !defined(_WIN32) && !defined(__APPLE__) /* This code is not used on systems without Posix CLOCK_REALTIME, * but the only way to detect that is from the OS headers, so the * Makefile can't exclude compiling this file on those systems. From 345cfcffa8a1dabb9c8f1e65021f840d49da7a61 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 4 Jun 2019 12:53:41 -0500 Subject: [PATCH 57/85] Fix sync filter example in dbd.pod --- src/std/filters/filters.dbd.pod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/std/filters/filters.dbd.pod b/src/std/filters/filters.dbd.pod index f1a848469..d7ab785f5 100644 --- a/src/std/filters/filters.dbd.pod +++ b/src/std/filters/filters.dbd.pod @@ -241,7 +241,7 @@ Assuming there is a system state called "blue", that is being controlled by some other facility such as a timing system, updates could be restricted to periods only when "blue" is true by using - Hal$ camonitor 'test:channel' 'test:channel.{"while":"blue"}' + Hal$ camonitor 'test:channel' 'test:channel.{"sync":{"while":"blue"}}' ... =cut From 33e099a51b653ce1ebc97a8f885a98ab3583fe38 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 7 Jun 2019 17:21:18 -0500 Subject: [PATCH 58/85] Fix VxWorks osiSockOptMcastLoop_t => char Repairs osiSockTest --- src/libCom/osi/os/vxWorks/osdSock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libCom/osi/os/vxWorks/osdSock.h b/src/libCom/osi/os/vxWorks/osdSock.h index d949b25f1..848f1d430 100644 --- a/src/libCom/osi/os/vxWorks/osdSock.h +++ b/src/libCom/osi/os/vxWorks/osdSock.h @@ -65,7 +65,7 @@ typedef int SOCKET; #define socket_ioctl(A,B,C) ioctl(A,B,(int)C) typedef int osiSockIoctl_t; typedef int osiSocklen_t; -typedef int osiSockOptMcastLoop_t; +typedef char osiSockOptMcastLoop_t; #define FD_IN_FDSET(FD) ((FD)=0) From e75a72ef76fe6ae5d396ae2a51f0d1830c9c12b9 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 7 Jun 2019 17:22:40 -0500 Subject: [PATCH 59/85] VxWorks: Mark undetected underflow parse test as ToDo --- src/libCom/test/epicsStdlibTest.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libCom/test/epicsStdlibTest.c b/src/libCom/test/epicsStdlibTest.c index a55453ad1..9a178f6bc 100644 --- a/src/libCom/test/epicsStdlibTest.c +++ b/src/libCom/test/epicsStdlibTest.c @@ -381,8 +381,14 @@ MAIN(epicsStdlibTest) testOk(epicsParseFloat("1e-40", &f, NULL) == S_stdlib_underflow, "Float '1e-40' => underflow"); +#ifdef vxWorks + testTodoBegin("Not detected on VxWorks"); +#endif testOk(epicsParseDouble("1e-330", &d, NULL) == S_stdlib_underflow, "Double '1e-330' => underflow"); +#ifdef vxWorks + testTodoEnd(); +#endif testOk(epicsScanFloat("1e30", &f) && fabs(f - 1e30) < 1e24, "Float '1e30'"); From a64cb4a87775d0ea24cf46f18c1a6da7ce25bd83 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 17 Jun 2019 17:48:41 -0700 Subject: [PATCH 60/85] update PVA modules --- modules/normativeTypes | 2 +- modules/pvAccess | 2 +- modules/pvData | 2 +- modules/pvDatabase | 2 +- modules/pva2pva | 2 +- modules/pvaClient | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/normativeTypes b/modules/normativeTypes index e803240fb..54bddc994 160000 --- a/modules/normativeTypes +++ b/modules/normativeTypes @@ -1 +1 @@ -Subproject commit e803240fbfbb06d96d94fc70e91b4cf832811b15 +Subproject commit 54bddc9942519d8f9ffd2dfb85fe4cf426cd198f diff --git a/modules/pvAccess b/modules/pvAccess index 5b333922d..a2c106378 160000 --- a/modules/pvAccess +++ b/modules/pvAccess @@ -1 +1 @@ -Subproject commit 5b333922d55fbc560e41496e7f36027dce271de4 +Subproject commit a2c106378a868b8365aa5a3315652936fa25f1d1 diff --git a/modules/pvData b/modules/pvData index 6da871fa6..c2bc77a64 160000 --- a/modules/pvData +++ b/modules/pvData @@ -1 +1 @@ -Subproject commit 6da871fa6471d00b1352024297e81e98c9c90d2b +Subproject commit c2bc77a6498dfe6f1cad1b0a28680e81764779cc diff --git a/modules/pvDatabase b/modules/pvDatabase index 2715f585e..ecdf70d85 160000 --- a/modules/pvDatabase +++ b/modules/pvDatabase @@ -1 +1 @@ -Subproject commit 2715f585e0e4bca7dae3e0ad9e25dd44278d075c +Subproject commit ecdf70d8588d5334e4958f911f3318c01011145e diff --git a/modules/pva2pva b/modules/pva2pva index 521154fd5..5170c2230 160000 --- a/modules/pva2pva +++ b/modules/pva2pva @@ -1 +1 @@ -Subproject commit 521154fd52d149ea578a73cabc1f7e4c784cf14f +Subproject commit 5170c2230de0bc984e6c4a67d03b0004ad4de0d9 diff --git a/modules/pvaClient b/modules/pvaClient index 428adb270..4c5611682 160000 --- a/modules/pvaClient +++ b/modules/pvaClient @@ -1 +1 @@ -Subproject commit 428adb270e15a820fd2dc6647c7546ce54692cb9 +Subproject commit 4c561168272ef2f4c0fa1497c9a48dd39437252a From c1ab30142abbfe3d354efdb08c07ef28fa3036e8 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 26 Jun 2019 08:59:35 -0700 Subject: [PATCH 61/85] sysconf /0 paranoia Seems unlikely, but avoid any possibility to divide by zero. --- modules/libcom/src/osi/os/posix/osdThread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libcom/src/osi/os/posix/osdThread.c b/modules/libcom/src/osi/os/posix/osdThread.c index 854441898..e3e0fe3cf 100644 --- a/modules/libcom/src/osi/os/posix/osdThread.c +++ b/modules/libcom/src/osi/os/posix/osdThread.c @@ -906,7 +906,7 @@ epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum () { double hz; hz = sysconf ( _SC_CLK_TCK ); - if(hz<0) + if(hz<=0) return 0.0; return 1.0 / hz; } From 6ce8dfec01cdfc2b3ebd9f2a506cf92312bede47 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 8 Nov 2017 10:07:55 -0600 Subject: [PATCH 62/85] libCom: timerQueueActive atomic exitFlag quiet false positive data race --- modules/libcom/src/timer/timerPrivate.h | 2 +- modules/libcom/src/timer/timerQueueActive.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/libcom/src/timer/timerPrivate.h b/modules/libcom/src/timer/timerPrivate.h index 55291309c..259afaee6 100644 --- a/modules/libcom/src/timer/timerPrivate.h +++ b/modules/libcom/src/timer/timerPrivate.h @@ -147,7 +147,7 @@ private: epicsThread thread; const double sleepQuantum; bool okToShare; - bool exitFlag; + int exitFlag; // use atomic ops bool terminateFlag; void run (); void reschedule (); diff --git a/modules/libcom/src/timer/timerQueueActive.cpp b/modules/libcom/src/timer/timerQueueActive.cpp index 5d8b72951..4db68c00c 100644 --- a/modules/libcom/src/timer/timerQueueActive.cpp +++ b/modules/libcom/src/timer/timerQueueActive.cpp @@ -15,6 +15,7 @@ #include #define epicsExportSharedSymbols +#include "epicsAtomic.h" #include "timerPrivate.h" #include "errlog.h" @@ -46,7 +47,7 @@ timerQueueActive :: _refMgr ( refMgr ), queue ( *this ), thread ( *this, "timerQueue", epicsThreadGetStackSize ( epicsThreadStackMedium ), priority ), sleepQuantum ( epicsThreadSleepQuantum() ), okToShare ( okToShareIn ), - exitFlag ( false ), terminateFlag ( false ) + exitFlag ( 0 ), terminateFlag ( false ) { } @@ -59,7 +60,7 @@ timerQueueActive::~timerQueueActive () { this->terminateFlag = true; this->rescheduleEvent.signal (); - while ( ! this->exitFlag ) { + while ( ! epics::atomic::get(this->exitFlag) ) { this->exitEvent.wait ( 1.0 ); } // in case other threads are waiting here also @@ -87,7 +88,7 @@ void timerQueueActive :: _printLastChanceExceptionMessage ( void timerQueueActive :: run () { - this->exitFlag = false; + epics::atomic::set(this->exitFlag, 0); while ( ! this->terminateFlag ) { try { double delay = this->queue.process ( epicsTime::getCurrent() ); @@ -105,7 +106,7 @@ void timerQueueActive :: run () epicsThreadSleep ( 10.0 ); } } - this->exitFlag = true; + epics::atomic::set(this->exitFlag, 1); this->exitEvent.signal (); // no access to queue after exitEvent signal } @@ -143,7 +144,7 @@ void timerQueueActive::show ( unsigned int level ) const printf ( "exit event\n" ); this->exitEvent.show ( level - 1u ); printf ( "exitFlag = %c, terminateFlag = %c\n", - this->exitFlag ? 'T' : 'F', + epics::atomic::get(this->exitFlag) ? 'T' : 'F', this->terminateFlag ? 'T' : 'F' ); } } From 89f0f1338a97d6b4db704ad5130cd2cbd36b9667 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 8 Nov 2017 10:45:39 -0600 Subject: [PATCH 63/85] ioc/db: consolidate callback state tracking combine cbCtl and callbackIsInit. use atomic ops to avoid false positive data races. --- modules/database/src/ioc/db/callback.c | 40 ++++++++++++++------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/modules/database/src/ioc/db/callback.c b/modules/database/src/ioc/db/callback.c index fe6db815b..e1f1d45a2 100644 --- a/modules/database/src/ioc/db/callback.c +++ b/modules/database/src/ioc/db/callback.c @@ -55,7 +55,7 @@ typedef struct cbQueueSet { epicsRingPointerId queue; int queueOverflow; int queueOverflows; - int shutdown; + int shutdown; // use atomic int threadsConfigured; int threadsRunning; } cbQueueSet; @@ -71,12 +71,15 @@ epicsExportAddress(int,callbackParallelThreadsDefault); /* Timer for Delayed Requests */ static epicsTimerQueueId timerQueue; -/* Shutdown handling */ -enum ctl {ctlInit, ctlRun, ctlPause, ctlExit}; -static volatile enum ctl cbCtl; -static epicsEventId startStopEvent; +enum cbState_t { + cbInit, /* before callbackInit() and after callbackCleanup() */ + cbRun, /* after callbackInit() and before callbackStop() */ + cbStop, /* after callbackStop() and before callbackCleanup() */ +}; -static int callbackIsInit; +static int cbState; // holdscbState_t, use atomic ops + +static epicsEventId startStopEvent; /* Static data */ static char *threadNamePrefix[NUM_CALLBACK_PRIORITIES] = { @@ -96,7 +99,7 @@ static int priorityValue[NUM_CALLBACK_PRIORITIES] = {0, 1, 2}; int callbackSetQueueSize(int size) { - if (callbackIsInit) { + if (epicsAtomicGetIntT(&cbState)!=cbInit) { fprintf(stderr, "Callback system already initialized\n"); return -1; } @@ -107,7 +110,7 @@ int callbackSetQueueSize(int size) int callbackQueueStatus(const int reset, callbackQueueStats *result) { int ret; - if (!callbackIsInit) return -1; + if (epicsAtomicGetIntT(&cbState)==cbInit) return -1; if (result) { int prio; result->size = callbackQueueSize; @@ -151,7 +154,7 @@ void callbackQueueShow(const int reset) int callbackParallelThreads(int count, const char *prio) { - if (callbackIsInit) { + if (epicsAtomicGetIntT(&cbState)!=cbInit) { fprintf(stderr, "Callback system already initialized\n"); return -1; } @@ -207,7 +210,7 @@ static void callbackTask(void *arg) taskwdInsert(0, NULL, NULL); epicsEventSignal(startStopEvent); - while(!mySet->shutdown) { + while(!epicsAtomicGetIntT(&mySet->shutdown)) { void *ptr; if (epicsRingPointerIsEmpty(mySet->queue)) epicsEventMustWait(mySet->semWakeUp); @@ -230,11 +233,10 @@ void callbackStop(void) { int i; - if (cbCtl == ctlExit) return; - cbCtl = ctlExit; + if (epicsAtomicCmpAndSwapIntT(&cbState, cbRun, cbStop)!=cbRun) return; for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { - callbackQueue[i].shutdown = 1; + epicsAtomicSetIntT(&callbackQueue[i].shutdown, 1); epicsEventSignal(callbackQueue[i].semWakeUp); } @@ -252,6 +254,10 @@ void callbackCleanup(void) { int i; + if(epicsAtomicCmpAndSwapIntT(&cbState, cbStop, cbInit)!=cbStop) { + fprintf(stderr, "callbackCleanup() but not stopped\n"); + } + for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { cbQueueSet *mySet = &callbackQueue[i]; @@ -261,7 +267,6 @@ void callbackCleanup(void) } epicsTimerQueueRelease(timerQueue); - callbackIsInit = 0; memset(callbackQueue, 0, sizeof(callbackQueue)); } @@ -271,15 +276,14 @@ void callbackInit(void) int j; char threadName[32]; - if (callbackIsInit) { - errlogMessage("Warning: callbackInit called again before callbackCleanup\n"); + if (epicsAtomicCmpAndSwapIntT(&cbState, cbInit, cbRun)!=cbInit) { + fprintf(stderr, "Warning: callbackInit called again before callbackCleanup\n"); return; } - callbackIsInit = 1; if(!startStopEvent) startStopEvent = epicsEventMustCreate(epicsEventEmpty); - cbCtl = ctlRun; + timerQueue = epicsTimerQueueAllocate(0, epicsThreadPriorityScanHigh); for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { From 2af0c1047067401b01be8c0ad055fb58c21c50f4 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 4 May 2018 20:27:51 -0700 Subject: [PATCH 64/85] debug epicsTimerTest --- modules/libcom/test/epicsTimerTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libcom/test/epicsTimerTest.cpp b/modules/libcom/test/epicsTimerTest.cpp index f2a510819..d820e64be 100644 --- a/modules/libcom/test/epicsTimerTest.cpp +++ b/modules/libcom/test/epicsTimerTest.cpp @@ -112,7 +112,7 @@ double delayVerify::checkError () const double actualDelay = this->expireStamp - this->beginStamp; double measuredError = actualDelay - this->expectedDelay; double percentError = 100.0 * fabs ( measuredError ) / this->expectedDelay; - if ( ! testOk1 ( percentError < messageThresh ) ) { + if ( ! testOk ( percentError < messageThresh, "%f < %f", percentError, messageThresh ) ) { testDiag ( "delay = %f s, error = %f s (%.1f %%)", this->expectedDelay, measuredError, percentError ); } From f955199805dc1987cc72f0d2691bf2a80fe796e3 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 8 Aug 2018 14:36:28 -0700 Subject: [PATCH 65/85] epicsTimerTest loosen test threshold --- modules/libcom/test/epicsTimerTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libcom/test/epicsTimerTest.cpp b/modules/libcom/test/epicsTimerTest.cpp index d820e64be..aebf3f066 100644 --- a/modules/libcom/test/epicsTimerTest.cpp +++ b/modules/libcom/test/epicsTimerTest.cpp @@ -108,7 +108,7 @@ inline double delayVerify::delay () const double delayVerify::checkError () const { - const double messageThresh = 2.0; // percent + const double messageThresh = 5.0; // percent double actualDelay = this->expireStamp - this->beginStamp; double measuredError = actualDelay - this->expectedDelay; double percentError = 100.0 * fabs ( measuredError ) / this->expectedDelay; From ceccafe82353a8b91f52d72c46981111e43752b3 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 3 Jan 2019 09:15:32 -0800 Subject: [PATCH 66/85] mbbo/mbbiDirect number of bits as precision Not really useful w/ RSRV/CA, but can be used by QSRV/PVA to provide number of bits as meta-data. --- modules/database/src/std/rec/mbbiDirectRecord.c | 12 +++++++++++- modules/database/src/std/rec/mbboDirectRecord.c | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/modules/database/src/std/rec/mbbiDirectRecord.c b/modules/database/src/std/rec/mbbiDirectRecord.c index afb59c83f..779b732d4 100644 --- a/modules/database/src/std/rec/mbbiDirectRecord.c +++ b/modules/database/src/std/rec/mbbiDirectRecord.c @@ -51,7 +51,7 @@ static long special(DBADDR *, int); #define get_array_info NULL #define put_array_info NULL #define get_units NULL -#define get_precision NULL +static long get_precision(const DBADDR *, long *); #define get_enum_str NULL #define get_enum_strs NULL #define put_enum_str NULL @@ -204,6 +204,16 @@ static long special(DBADDR *paddr, int after) } } +static long get_precision(const DBADDR *paddr,long *precision) +{ + mbbiDirectRecord *prec=(mbbiDirectRecord *)paddr->precord; + if(dbGetFieldIndex(paddr)==mbbiDirectRecordVAL) + *precision = prec->nobt; + else + recGblGetPrec(paddr,precision); + return 0; +} + static void monitor(mbbiDirectRecord *prec) { epicsUInt16 events = recGblResetAlarms(prec); diff --git a/modules/database/src/std/rec/mbboDirectRecord.c b/modules/database/src/std/rec/mbboDirectRecord.c index 9260fbda1..dcc2b3c33 100644 --- a/modules/database/src/std/rec/mbboDirectRecord.c +++ b/modules/database/src/std/rec/mbboDirectRecord.c @@ -51,7 +51,7 @@ static long special(DBADDR *, int); #define get_array_info NULL #define put_array_info NULL #define get_units NULL -#define get_precision NULL +static long get_precision(const DBADDR *, long *); #define get_enum_str NULL #define get_enum_strs NULL #define put_enum_str NULL @@ -313,6 +313,16 @@ static long special(DBADDR *paddr, int after) return 0; } +static long get_precision(const DBADDR *paddr,long *precision) +{ + mbboDirectRecord *prec=(mbboDirectRecord *)paddr->precord; + if(dbGetFieldIndex(paddr)==mbboDirectRecordVAL) + *precision = prec->nobt; + else + recGblGetPrec(paddr,precision); + return 0; +} + static void monitor(mbboDirectRecord *prec) { epicsUInt16 events = recGblResetAlarms(prec); From ede52d96b8b912498e32d621c938fe91204b2d39 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 11 Mar 2019 16:55:44 -0700 Subject: [PATCH 67/85] posix show mapping of epicsMutexId and uaddr passed to futex() On Linux w/ GLIBC+NTPL useful to establish mapping between args to futux syscall and epicsMutexId (and file+line of creation). --- modules/libcom/src/osi/os/posix/osdMutex.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/libcom/src/osi/os/posix/osdMutex.c b/modules/libcom/src/osi/os/posix/osdMutex.c index f569916a5..d1411215c 100644 --- a/modules/libcom/src/osi/os/posix/osdMutex.c +++ b/modules/libcom/src/osi/os/posix/osdMutex.c @@ -153,6 +153,10 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex) void epicsMutexOsdShow(struct epicsMutexOSD * pmutex, unsigned int level) { + /* GLIBC w/ NTPL is passing the &lock.__data.__lock as the first argument (UADDR) + * of the futex() syscall. __lock is at offset 0 of the enclosing structures. + */ + printf(" pthread_mutex_t* uaddr=%p\n", &pmutex->lock); } #else /*defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 */ From 5b09bb6e7199c5a8bbc327d602a25aaed74a3c4e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 3 Apr 2019 15:18:18 -0700 Subject: [PATCH 68/85] Set file+line for epicsMutex Makes the output of epicsMutexShowAll more useful wrt. libca. --- modules/ca/src/client/ca_client_context.cpp | 2 ++ modules/ca/src/client/repeaterSubscribeTimer.cpp | 1 + modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp | 1 + modules/libcom/src/timer/timerQueue.cpp | 1 + modules/libcom/src/timer/timerQueueActiveMgr.cpp | 1 + 5 files changed, 6 insertions(+) diff --git a/modules/ca/src/client/ca_client_context.cpp b/modules/ca/src/client/ca_client_context.cpp index 2bb3e24a8..08562612a 100644 --- a/modules/ca/src/client/ca_client_context.cpp +++ b/modules/ca/src/client/ca_client_context.cpp @@ -67,6 +67,8 @@ cacService * ca_client_context::pDefaultService = 0; epicsMutex * ca_client_context::pDefaultServiceInstallMutex; ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) : + mutex(__FILE__, __LINE__), + cbMutex(__FILE__, __LINE__), createdByThread ( epicsThreadGetIdSelf () ), ca_exception_func ( 0 ), ca_exception_arg ( 0 ), pVPrintfFunc ( errlogVprintf ), fdRegFunc ( 0 ), fdRegArg ( 0 ), diff --git a/modules/ca/src/client/repeaterSubscribeTimer.cpp b/modules/ca/src/client/repeaterSubscribeTimer.cpp index 948ccebd5..71ba5ad06 100644 --- a/modules/ca/src/client/repeaterSubscribeTimer.cpp +++ b/modules/ca/src/client/repeaterSubscribeTimer.cpp @@ -37,6 +37,7 @@ repeaterSubscribeTimer::repeaterSubscribeTimer ( epicsMutex & cbMutexIn, cacContextNotify & ctxNotifyIn ) : timer ( queueIn.createTimer () ), iiu ( iiuIn ), cbMutex ( cbMutexIn ),ctxNotify ( ctxNotifyIn ), + stateMutex(__FILE__, __LINE__), attempts ( 0 ), registered ( false ), once ( false ) { } diff --git a/modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp b/modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp index 4301612c9..ec2c16ded 100644 --- a/modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp +++ b/modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp @@ -171,6 +171,7 @@ ipAddrToAsciiEngine & ipAddrToAsciiEngine::allocate () } ipAddrToAsciiGlobal::ipAddrToAsciiGlobal () : + mutex(__FILE__, __LINE__), thread ( *this, "ipToAsciiProxy", epicsThreadGetStackSize(epicsThreadStackBig), epicsThreadPriorityLow ), diff --git a/modules/libcom/src/timer/timerQueue.cpp b/modules/libcom/src/timer/timerQueue.cpp index 5a798d4d4..8f7f98e12 100644 --- a/modules/libcom/src/timer/timerQueue.cpp +++ b/modules/libcom/src/timer/timerQueue.cpp @@ -25,6 +25,7 @@ const double timerQueue :: exceptMsgMinPeriod = 60.0 * 5.0; // seconds epicsTimerQueue::~epicsTimerQueue () {} timerQueue::timerQueue ( epicsTimerQueueNotify & notifyIn ) : + mutex(__FILE__, __LINE__), notify ( notifyIn ), pExpireTmr ( 0 ), processThread ( 0 ), diff --git a/modules/libcom/src/timer/timerQueueActiveMgr.cpp b/modules/libcom/src/timer/timerQueueActiveMgr.cpp index d6349a84c..eff2e0c53 100644 --- a/modules/libcom/src/timer/timerQueueActiveMgr.cpp +++ b/modules/libcom/src/timer/timerQueueActiveMgr.cpp @@ -20,6 +20,7 @@ #include "timerPrivate.h" timerQueueActiveMgr::timerQueueActiveMgr () + :mutex(__FILE__, __LINE__) { } From c8e5deca76f2995fe899783c46f666388101e2b3 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 29 Mar 2019 15:29:22 -0700 Subject: [PATCH 69/85] dbEvent tweak Queue size --- modules/database/src/ioc/db/dbEvent.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/database/src/ioc/db/dbEvent.c b/modules/database/src/ioc/db/dbEvent.c index 9304f99b2..77b12de8d 100644 --- a/modules/database/src/ioc/db/dbEvent.c +++ b/modules/database/src/ioc/db/dbEvent.c @@ -49,7 +49,13 @@ #include "link.h" #include "special.h" -#define EVENTSPERQUE 32 +/* Queue size based on Ethernet MTU of 1500 bytes. + * Assume <=66 bytes of ethernet+IP+TCP overhead + * and 40 byte CA messages (DBF_TIME_DOUBLE). + * + * (1500-66)/40 -> 35 + */ +#define EVENTSPERQUE 36 #define EVENTENTRIES 4 /* the number of que entries for each event */ #define EVENTQUESIZE (EVENTENTRIES * EVENTSPERQUE) #define EVENTQEMPTY ((struct evSubscrip *)NULL) From b2285bb8aa54f2e164ad4d5be55a267af38a0150 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 27 Jun 2019 12:01:42 -0500 Subject: [PATCH 70/85] Redirect msi's STDERR to /dev/null (NUL on Windows) during tests Also moves the environment variable handling code out to the only test that needs it and simplifies it; some Perl versions were giving warnings from splitting an undef value. --- src/ioc/dbtemplate/test/msi.plt | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt index ca87ca1fe..a235484a6 100644 --- a/src/ioc/dbtemplate/test/msi.plt +++ b/src/ioc/dbtemplate/test/msi.plt @@ -56,8 +56,11 @@ ok(msi('-I. -I.. -S ../t10-substitute.txt'), slurp('../t10-result.txt')); # Substitution file, pattern format, with 0 pattern definitions ok(msi('-I. -I.. -S ../t11-substitute.txt'), slurp('../t11-result.txt')); -# Macros in template-file name populated from environment variable -ok(msi('-I. -I.. -S ../t12-substitute.txt', 'TEST_NO=12,PREFIX=t'), slurp('../t12-result.txt')); +# Substitution file, environment variable macros in template filename +my %envs = (TEST_NO => 12, PREFIX => 't'); +@ENV{ keys %envs } = values %envs; +ok(msi('-I. -I.. -S ../t12-substitute.txt'), slurp('../t12-result.txt')); +delete @ENV{ keys %envs }; # Not really needed # Test support routines @@ -70,33 +73,23 @@ sub slurp { } sub msi { - my ($args, $envstr) = @_; + my ($args) = @_; my $exe = ($^O eq 'MSWin32') || ($^O eq 'cygwin') ? '.exe' : ''; + my $nul = ($^O eq 'MSWin32') ? 'NUL' : '/dev/null'; my $msi = "./msi-copy$exe"; my $result; - my @envs = split(/,/, $envstr); - foreach (@envs) - { - my ($var, $value) = split /=/, $_; - $ENV{$var} = $value; - } if ($args =~ m/-o / && $args !~ m/-D/) { # An empty result is expected - $result = `$msi $args`; + $result = `$msi $args 2>$nul`; } else { # Try up to 5 times, sometimes msi fails on Windows my $count = 5; do { - $result = `$msi $args`; + $result = `$msi $args 2>$nul`; print "# result of '$msi $args' empty, retrying\n" if $result eq ''; } while ($result eq '') && (--$count > 0); } - foreach (@envs) - { - my ($var, $value) = split /=/, $_; - delete $ENV{$var}; - } return $result; } From 78ce2dac05c60df5e2f91b390335c9f3b4b9d0a0 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 27 Jun 2019 13:28:56 -0500 Subject: [PATCH 71/85] Don't use / in Windows program paths Fixing Windows msi.t script failures... --- src/ioc/dbtemplate/test/msi.plt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt index a235484a6..420846649 100644 --- a/src/ioc/dbtemplate/test/msi.plt +++ b/src/ioc/dbtemplate/test/msi.plt @@ -76,7 +76,7 @@ sub msi { my ($args) = @_; my $exe = ($^O eq 'MSWin32') || ($^O eq 'cygwin') ? '.exe' : ''; my $nul = ($^O eq 'MSWin32') ? 'NUL' : '/dev/null'; - my $msi = "./msi-copy$exe"; + my $msi = "msi-copy$exe"; my $result; if ($args =~ m/-o / && $args !~ m/-D/) { # An empty result is expected From c9c4eea0f80a2f4810bce4801cea2b8b1a3ef450 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 27 Jun 2019 15:21:41 -0500 Subject: [PATCH 72/85] Now fix the non-windows systems --- src/ioc/dbtemplate/test/msi.plt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt index 420846649..4db5a9a41 100644 --- a/src/ioc/dbtemplate/test/msi.plt +++ b/src/ioc/dbtemplate/test/msi.plt @@ -74,9 +74,8 @@ sub slurp { sub msi { my ($args) = @_; - my $exe = ($^O eq 'MSWin32') || ($^O eq 'cygwin') ? '.exe' : ''; my $nul = ($^O eq 'MSWin32') ? 'NUL' : '/dev/null'; - my $msi = "msi-copy$exe"; + my $msi = ($^O eq 'MSWin32') ? 'msi-copy.exe' : './msi-copy'; my $result; if ($args =~ m/-o / && $args !~ m/-D/) { # An empty result is expected From c70b1a9a29a0edd25fe17ef0374635da71310076 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 6 Jul 2019 13:43:58 -0700 Subject: [PATCH 73/85] libcom: detect uclibc support for backtrace() --- .../src/osi/os/posix/osdExecinfoBackTrace.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/modules/libcom/src/osi/os/posix/osdExecinfoBackTrace.cpp b/modules/libcom/src/osi/os/posix/osdExecinfoBackTrace.cpp index ae13d28fc..8ed1bb283 100644 --- a/modules/libcom/src/osi/os/posix/osdExecinfoBackTrace.cpp +++ b/modules/libcom/src/osi/os/posix/osdExecinfoBackTrace.cpp @@ -7,12 +7,30 @@ * Author: Till Straumann , 2011, 2014 */ +// pull in libc feature test macros +#include + +// execinfo.h may not be present if uclibc is configured to omit backtrace() +#if !defined(__UCLIBC_MAJOR__) || defined(__UCLIBC_HAS_EXECINFO__) +# define HAS_EXECINFO 1 +#else +# define HAS_EXECINFO 0 +#endif + +#if HAS_EXECINFO + #include +#endif + #define epicsExportSharedSymbols #include "epicsStackTracePvt.h" int epicsBackTrace(void **buf, int buf_sz) { +#if HAS_EXECINFO return backtrace(buf, buf_sz); +#else + return -1; +#endif } From d214d81794e7ca245d22919af582d2a2bd2a1863 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sun, 7 Jul 2019 16:50:02 -0700 Subject: [PATCH 74/85] CROSS_COMPILER_RUNTEST_ARCHS for non-RTEMS --- modules/libcom/test/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/libcom/test/Makefile b/modules/libcom/test/Makefile index f2e495a90..c8680e3e6 100755 --- a/modules/libcom/test/Makefile +++ b/modules/libcom/test/Makefile @@ -255,8 +255,8 @@ TESTSPEC_RTEMS = libComTestHarness.boot; epicsRunLibComTests TESTSCRIPTS_HOST += $(TESTS:%=%.t) ifneq ($(filter $(T_A),$(CROSS_COMPILER_RUNTEST_ARCHS)),) -TESTPROD_RTEMS = $(TESTPROD_HOST) -TESTSCRIPTS_RTEMS += $(filter-out epicsUnitTestTest.t, $(TESTS:%=%.t)) +TESTPROD = $(TESTPROD_HOST) +TESTSCRIPTS += $(filter-out epicsUnitTestTest.t, $(TESTS:%=%.t)) endif From 771ad6a44264385d9282b9ca04435973e5266183 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Fri, 5 Jul 2019 12:44:05 +0100 Subject: [PATCH 75/85] msi: Flush stdout on program exit On WIN32 if the reopen()ed stdout is not closed it can occasionally result in missing lines in the output file --- src/ioc/dbtemplate/msi.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 49d8611b9..70623419a 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -215,6 +215,7 @@ int main(int argc,char **argv) if (opt_D) { printf("\n"); } + fflush(stdout); free(templateName); return opt_V & 2; } From b89494a840e62953471c7cce7b134849cf750bdd Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 17 Jul 2019 11:20:03 -0700 Subject: [PATCH 76/85] Revert "Testing msi: Add retries if necessary" This reverts commit 29c069db3dcb78e77c03bb18153eec21456585c4. # Conflicts: # src/ioc/dbtemplate/test/msi.plt --- src/ioc/dbtemplate/test/msi.plt | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt index 4db5a9a41..f0d66565e 100644 --- a/src/ioc/dbtemplate/test/msi.plt +++ b/src/ioc/dbtemplate/test/msi.plt @@ -76,19 +76,5 @@ sub msi { my ($args) = @_; my $nul = ($^O eq 'MSWin32') ? 'NUL' : '/dev/null'; my $msi = ($^O eq 'MSWin32') ? 'msi-copy.exe' : './msi-copy'; - my $result; - if ($args =~ m/-o / && $args !~ m/-D/) { - # An empty result is expected - $result = `$msi $args 2>$nul`; - } - else { - # Try up to 5 times, sometimes msi fails on Windows - my $count = 5; - do { - $result = `$msi $args 2>$nul`; - print "# result of '$msi $args' empty, retrying\n" - if $result eq ''; - } while ($result eq '') && (--$count > 0); - } - return $result; + return `$msi $args 2>$nul`; } From a6812c586928ce71d548f37e092cb3a98859ff1a Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 17 Jul 2019 16:19:37 -0500 Subject: [PATCH 77/85] Revert "More msi.plt retries for Jenkins builds on Windows" This reverts commit a69bd833fc6e29a145c7475c72bea85a32897385. --- src/ioc/dbtemplate/test/msi.plt | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt index f0d66565e..414e10961 100644 --- a/src/ioc/dbtemplate/test/msi.plt +++ b/src/ioc/dbtemplate/test/msi.plt @@ -33,16 +33,9 @@ ok(msi('-S../t6-substitute.txt ../t6-template.txt'), slurp('../t6-result.txt')); # Output option -o and verbose option -V my $out = 't7-output.txt'; -my $count = 5; # Try up to 5 times... -my $result; -do { - unlink $out; - msi("-I.. -V -o $out ../t1-template.txt"); - $result = slurp($out); - print "# msi output file empty, retrying\n" - if $result eq ''; -} while ($result eq '') && (--$count > 0); -ok($result, slurp('../t7-result.txt')); +unlink $out; +msi("-I.. -V -o $out ../t1-template.txt"); +ok(slurp($out), slurp('../t7-result.txt')); # Dependency generation, include/substitute model ok(msi('-I.. -D -o t8.txt ../t1-template.txt'), slurp('../t8-result.txt')); From 9988be090674ea5be9f7511b6609a0b8c3868f03 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 24 Jul 2019 16:44:25 -0700 Subject: [PATCH 78/85] update release notes --- documentation/RELEASE_NOTES.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index df783606d..b9f206b85 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -30,6 +30,20 @@ release.

    --> +

    epicsTimeGetCurrent() optimization

    + +

    Add a fast path to epicsTimeGetCurrent() and related calls +in the common case where only the default OS current time provider is +registered. This path does not take the global mutex guarding +the time providers list, potentially reducing lock contention.

    + +

    dbEvent tweak Queue size

    + +

    The size of the queue used by dbEvent to push monitor updates +has been slightly increased based on DBR_TIME_DOUBLE to better fill +an ethernet frame. This may result in slightly fewer, but larger +frames being sent.

    +

    EPICS Release 7.0.2.2

    Build System changes

    From afd9697290e34d28617630eb0cfdf6ac672deeaa Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 24 Jul 2019 17:45:08 -0700 Subject: [PATCH 79/85] update PVA modules --- modules/pvAccess | 2 +- modules/pvData | 2 +- modules/pva2pva | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/pvAccess b/modules/pvAccess index a2c106378..936f5d35d 160000 --- a/modules/pvAccess +++ b/modules/pvAccess @@ -1 +1 @@ -Subproject commit a2c106378a868b8365aa5a3315652936fa25f1d1 +Subproject commit 936f5d35d845a3c47a55176876a0f607a582cf09 diff --git a/modules/pvData b/modules/pvData index c2bc77a64..6ceaa6adb 160000 --- a/modules/pvData +++ b/modules/pvData @@ -1 +1 @@ -Subproject commit c2bc77a6498dfe6f1cad1b0a28680e81764779cc +Subproject commit 6ceaa6adb0b39dc3e37f064ca7e7bb5eea459d96 diff --git a/modules/pva2pva b/modules/pva2pva index 5170c2230..ce39c9320 160000 --- a/modules/pva2pva +++ b/modules/pva2pva @@ -1 +1 @@ -Subproject commit 5170c2230de0bc984e6c4a67d03b0004ad4de0d9 +Subproject commit ce39c932013e3af1d4750394ee69ba20bd13fa74 From e2881fb37e5f9963ee4dfc133a8c9ff8a35eca9c Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 24 Jul 2019 18:42:02 -0700 Subject: [PATCH 80/85] More release notes Forgot to stage... --- documentation/RELEASE_NOTES.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index b9f206b85..ef02e2bb9 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -44,6 +44,12 @@ has been slightly increased based on DBR_TIME_DOUBLE to better fill an ethernet frame. This may result in slightly fewer, but larger frames being sent.

    +

    mbbo/mbbiDirect number of bits as precision

    + +

    Report NOBT as "precision" through the dbAccess API. +This is not accessible through CA, but is planned to be used through +QSRV.

    +

    EPICS Release 7.0.2.2

    Build System changes

    From 9b5034f3072a76f7c4a53291014511be04a36f3d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 25 Jul 2019 14:35:41 -0500 Subject: [PATCH 81/85] Restore errlogFlush() call to msi.cpp --- src/ioc/dbtemplate/msi.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ioc/dbtemplate/msi.cpp b/src/ioc/dbtemplate/msi.cpp index 70623419a..462869cb3 100644 --- a/src/ioc/dbtemplate/msi.cpp +++ b/src/ioc/dbtemplate/msi.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -211,6 +212,7 @@ int main(int argc,char **argv) substituteDestruct(substitutePvt); } macDeleteHandle(macPvt); + errlogFlush(); // macLib calls errlogPrintf() inputDestruct(inputPvt); if (opt_D) { printf("\n"); From e8be04bc4391338fe6f2113ad3ac039f3af4b077 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 25 Jul 2019 18:14:12 -0500 Subject: [PATCH 82/85] Update pvDatabase submodule --- modules/pvDatabase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/pvDatabase b/modules/pvDatabase index ecdf70d85..ba832ddfd 160000 --- a/modules/pvDatabase +++ b/modules/pvDatabase @@ -1 +1 @@ -Subproject commit ecdf70d8588d5334e4958f911f3318c01011145e +Subproject commit ba832ddfd0e64ad0c596f49f37044ed55acbde56 From 1706da98cc87891d1f76e1bf4e0090f6146e2d23 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 30 Jul 2019 14:36:46 -0500 Subject: [PATCH 83/85] Update submodules to tagged versions --- modules/normativeTypes | 2 +- modules/pvDatabase | 2 +- modules/pvaClient | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/normativeTypes b/modules/normativeTypes index 54bddc994..c6168a747 160000 --- a/modules/normativeTypes +++ b/modules/normativeTypes @@ -1 +1 @@ -Subproject commit 54bddc9942519d8f9ffd2dfb85fe4cf426cd198f +Subproject commit c6168a74772a93f18facc83631c13db381ff15bb diff --git a/modules/pvDatabase b/modules/pvDatabase index ba832ddfd..70ee85778 160000 --- a/modules/pvDatabase +++ b/modules/pvDatabase @@ -1 +1 @@ -Subproject commit ba832ddfd0e64ad0c596f49f37044ed55acbde56 +Subproject commit 70ee85778268bb47397d4cf8aa07e019ccdd8392 diff --git a/modules/pvaClient b/modules/pvaClient index 4c5611682..aba40922e 160000 --- a/modules/pvaClient +++ b/modules/pvaClient @@ -1 +1 @@ -Subproject commit 4c561168272ef2f4c0fa1497c9a48dd39437252a +Subproject commit aba40922e6a96519c214c7644bfdf49a8bd0d7f6 From f550f278ade4aeeaf6cb0deea6dec0abc47150de Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 30 Jul 2019 18:09:33 -0500 Subject: [PATCH 84/85] Update version numbers in documentation to 7.0.2 --- documentation/KnownProblems.html | 8 ++++---- documentation/README.1st | 28 ++++++++++++++-------------- documentation/README.html | 2 +- documentation/RELEASE_NOTES.html | 2 +- documentation/ReleaseChecklist.html | 16 ++++++++-------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/documentation/KnownProblems.html b/documentation/KnownProblems.html index d38ad630c..787d2db4b 100644 --- a/documentation/KnownProblems.html +++ b/documentation/KnownProblems.html @@ -4,17 +4,17 @@ - Known Problems in EPICS 7.0.2 + Known Problems in EPICS 7.0.3 -

    EPICS 7.0.2: Known Problems

    +

    EPICS 7.0.3: Known Problems

    Any patch files linked below should be applied at the root of the -base-7.0.2 tree. Download them, then use the GNU Patch program as +base-7.0.3 tree. Download them, then use the GNU Patch program as follows:

    -
    % cd /path/to/base-7.0.2
    +
    % cd /path/to/base-7.0.3
     % patch -p1 < /path/to/file.patch

    The following problems were known by the developers at the time of this diff --git a/documentation/README.1st b/documentation/README.1st index f0c560fb0..177205805 100644 --- a/documentation/README.1st +++ b/documentation/README.1st @@ -1,24 +1,24 @@ Installation Instructions - EPICS Base Release 7.0.2 + EPICS Base Release 7.0.3 -------------------------------------------------------------------------- Table of Contents - * What is EPICS base? - * What is new in this release? - * Copyright - * Supported platforms - * Supported compilers - * Software requirements - * Host system storage requirements - * Documentation - * Directory Structure - * Build related components - * Building EPICS base (Unix and Win32) - * Example application and extension - * Multiple host platforms + * What is EPICS base? + * What is new in this release? + * Copyright + * Supported platforms + * Supported compilers + * Software requirements + * Host system storage requirements + * Documentation + * Directory Structure + * Build related components + * Building EPICS base (Unix and Win32) + * Example application and extension + * Multiple host platforms -------------------------------------------------------------------------- diff --git a/documentation/README.html b/documentation/README.html index ab9a1f7a4..6e15470fd 100644 --- a/documentation/README.html +++ b/documentation/README.html @@ -9,7 +9,7 @@

    Installation Instructions

    -

    EPICS Base Release 7.0.2


    +

    EPICS Base Release 7.0.3



    Table of Contents

    diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index aa2763970..103e5a957 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -20,7 +20,7 @@ release.

    which should also be read to understand what has changed since an earlier release.

    -

    EPICS Release 7.0.2.3

    +

    EPICS Release 7.0.3