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
+