Merge ~info-martin-konrad/epics-base:fix-substitution-file-expansion into ~epics-core/epics-base/+git/epics-base:3.15

Proposed by Martin Konrad
Status: Merged
Merged at revision: 59cb5ba6a0f66461e1b0efea28699046d44a7a8b
Proposed branch: ~info-martin-konrad/epics-base:fix-substitution-file-expansion
Merge into: ~epics-core/epics-base/+git/epics-base:3.15
Diff against target: 531 lines (+109/-92)
9 files modified
src/ioc/dbtemplate/Makefile (+1/-1)
src/ioc/dbtemplate/msi.cpp (+71/-90)
src/ioc/dbtemplate/test/msi.plt (+7/-1)
src/ioc/dbtemplate/test/t10-result.txt (+4/-0)
src/ioc/dbtemplate/test/t10-substitute.txt (+8/-0)
src/ioc/dbtemplate/test/t10-template.txt (+2/-0)
src/ioc/dbtemplate/test/t11-result.txt (+4/-0)
src/ioc/dbtemplate/test/t11-substitute.txt (+10/-0)
src/ioc/dbtemplate/test/t11-template.txt (+2/-0)
Reviewer Review Type Date Requested Status
Andrew Johnson Pending
Review via email: mp+361500@code.launchpad.net

Description of the change

Fix https://bugs.launchpad.net/epics-base/+bug/1810946 and https://bugs.launchpad.net/epics-base/+bug/1810949.

It's way too easy to goof these kind of things up when doing manual memory management. By converting MSI to C++ I'm trying to start some improvements with regards to this. I have a bunch of other clean up changes we can look at once this issue is fixed (see https://code.launchpad.net/~info-martin-konrad/epics-base/+git/epics-base/+ref/clean-up-msi).

To post a comment you must log in.
Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Looking at the change in this MR I see a good start with a lot of work remaining. Looking at your clean-up-msi branch, I see that a lot of the remaining work is done there. If you don't want to fix the leak in the C code first, then I'd rather review all of the c++ conversion at once. The main points which make this c++ code (eg. ellLib -> std::list) are on the clean-up-msi branch.

Revision history for this message
Martin Konrad (info-martin-konrad) wrote :
Revision history for this message
Andrew Johnson (anj) wrote :

Martin, please clarify which of your two MRs should be merged, we think we're okay with fixing these bugs.

Revision history for this message
Martin Konrad (info-martin-konrad) wrote :

This one only fixes the immediate problem I ran into. https://code.launchpad.net/~info-martin-konrad/epics-base/+git/epics-base/+ref/clean-up-msi contains the same commits plus some additional clean up that should make similar problems less likely. I would recommend merging the latter.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/ioc/dbtemplate/Makefile b/src/ioc/dbtemplate/Makefile
index 2aa5a0c..13b4f11 100644
--- a/src/ioc/dbtemplate/Makefile
+++ b/src/ioc/dbtemplate/Makefile
@@ -13,7 +13,7 @@ SRC_DIRS += $(IOCDIR)/dbtemplate
1313
14PROD_HOST += msi14PROD_HOST += msi
1515
16msi_SRCS = msi.c16msi_SRCS = msi.cpp
17msi_LIBS += Com17msi_LIBS += Com
18HTMLS += msi.html18HTMLS += msi.html
1919
diff --git a/src/ioc/dbtemplate/msi.c b/src/ioc/dbtemplate/msi.cpp
20similarity index 80%20similarity index 80%
21rename from src/ioc/dbtemplate/msi.c21rename from src/ioc/dbtemplate/msi.c
22rename to src/ioc/dbtemplate/msi.cpp22rename to src/ioc/dbtemplate/msi.cpp
index 69680e1..9a370e8 100644
--- a/src/ioc/dbtemplate/msi.c
+++ b/src/ioc/dbtemplate/msi.cpp
@@ -9,6 +9,8 @@
99
10/* msi - macro substitutions and include */10/* msi - macro substitutions and include */
1111
12#include <string>
13
12#include <stdlib.h>14#include <stdlib.h>
13#include <stddef.h>15#include <stddef.h>
14#include <stdio.h>16#include <stdio.h>
@@ -56,28 +58,31 @@ int din = 0;
56typedef struct inputData inputData;58typedef struct inputData inputData;
5759
58static void inputConstruct(inputData **ppvt);60static void inputConstruct(inputData **ppvt);
59static void inputDestruct(inputData *pvt);61static void inputDestruct(inputData * const pvt);
60static void inputAddPath(inputData *pvt, char *pval);62static void inputAddPath(inputData * const pvt, const char * const pval);
61static void inputBegin(inputData *pvt, char *fileName);63static void inputBegin(inputData * const pvt, const char * const fileName);
62static char *inputNextLine(inputData *pvt);64static char *inputNextLine(inputData * const pvt);
63static void inputNewIncludeFile(inputData *pvt, char *name);65static void inputNewIncludeFile(inputData * const pvt, const char * const name);
64static void inputErrPrint(inputData *pvt);66static void inputErrPrint(const inputData * const pvt);
6567
66/* Module to read the substitution file */68/* Module to read the substitution file */
67typedef struct subInfo subInfo;69typedef struct subInfo subInfo;
6870
69static void substituteOpen(subInfo **ppvt, char *substitutionName);71static void substituteOpen(subInfo **ppvt, char * const substitutionName);
70static void substituteDestruct(subInfo *pvt);72static void substituteDestruct(subInfo * const pvt);
71static int substituteGetNextSet(subInfo *pvt, char **filename);73static int substituteGetNextSet(subInfo * const pvt, char **filename);
72static int substituteGetGlobalSet(subInfo *pvt);74static int substituteGetGlobalSet(subInfo * const pvt);
73static char *substituteGetReplacements(subInfo *pvt);75static const char *substituteGetReplacements(subInfo * const pvt);
74static char *substituteGetGlobalReplacements(subInfo *pvt);76static const char *substituteGetGlobalReplacements(subInfo * const pvt);
7577
76/* Forward references to local routines */78/* Forward references to local routines */
77static void usageExit(int status);79static void usageExit(const int status);
78static void abortExit(int status);80static void abortExit(const int status);
79static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval);81static void addMacroReplacements(MAC_HANDLE * const macPvt,
80static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *templateName);82 const char * const pval);
83static void makeSubstitutions(inputData * const inputPvt,
84 MAC_HANDLE * const macPvt,
85 const char * const templateName);
8186
82/*Global variables */87/*Global variables */
83static int opt_V = 0;88static int opt_V = 0;
@@ -180,9 +185,9 @@ int main(int argc,char **argv)
180 isGlobal = substituteGetGlobalSet(substitutePvt);185 isGlobal = substituteGetGlobalSet(substitutePvt);
181 if (isGlobal) {186 if (isGlobal) {
182 STEP("Handling global macros");187 STEP("Handling global macros");
183 pval = substituteGetGlobalReplacements(substitutePvt);188 const char *macStr = substituteGetGlobalReplacements(substitutePvt);
184 if (pval)189 if (macStr)
185 addMacroReplacements(macPvt, pval);190 addMacroReplacements(macPvt, macStr);
186 }191 }
187 else if ((isFile = substituteGetNextSet(substitutePvt, &filename))) {192 else if ((isFile = substituteGetNextSet(substitutePvt, &filename))) {
188 if (templateName)193 if (templateName)
@@ -193,11 +198,12 @@ int main(int argc,char **argv)
193 }198 }
194199
195 STEPS("Handling template file", filename);200 STEPS("Handling template file", filename);
196 while ((pval = substituteGetReplacements(substitutePvt))) {201 const char *macStr;
202 while ((macStr = substituteGetReplacements(substitutePvt))) {
197 if (localScope)203 if (localScope)
198 macPushScope(macPvt);204 macPushScope(macPvt);
199205
200 addMacroReplacements(macPvt, pval);206 addMacroReplacements(macPvt, macStr);
201 makeSubstitutions(inputPvt, macPvt, filename);207 makeSubstitutions(inputPvt, macPvt, filename);
202208
203 if (localScope)209 if (localScope)
@@ -218,7 +224,7 @@ int main(int argc,char **argv)
218 return opt_V & 2;224 return opt_V & 2;
219}225}
220226
221227
222void usageExit(int status)228void usageExit(const int status)
223{229{
224 fprintf(stderr,230 fprintf(stderr,
225 "Usage: msi [options] [template]\n"231 "Usage: msi [options] [template]\n"
@@ -236,7 +242,7 @@ void usageExit(int status)
236 exit(status);242 exit(status);
237}243}
238244
239void abortExit(int status)245void abortExit(const int status)
240{246{
241 if (outFile) {247 if (outFile) {
242 fclose(stdout);248 fclose(stdout);
@@ -245,7 +251,8 @@ void abortExit(int status)
245 exit(status);251 exit(status);
246}252}
247253
248static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval)254static void addMacroReplacements(MAC_HANDLE * const macPvt,
255 const char * const pval)
249{256{
250 char **pairs;257 char **pairs;
251 long status;258 long status;
@@ -268,7 +275,9 @@ static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval)
268typedef enum {cmdInclude,cmdSubstitute} cmdType;275typedef enum {cmdInclude,cmdSubstitute} cmdType;
269static const char *cmdNames[] = {"include","substitute"};276static const char *cmdNames[] = {"include","substitute"};
270277
271static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *templateName)278static void makeSubstitutions(inputData * const inputPvt,
279 MAC_HANDLE * const macPvt,
280 const char * const templateName)
272{281{
273 char *input;282 char *input;
274 static char buffer[MAX_BUFFER_SIZE];283 static char buffer[MAX_BUFFER_SIZE];
@@ -325,7 +334,7 @@ static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *tem
325 /*skip quote and any trailing blanks*/334 /*skip quote and any trailing blanks*/
326 while (*++p == ' ') ;335 while (*++p == ' ') ;
327 if (*p != '\n' && *p != 0) goto endcmd;336 if (*p != '\n' && *p != 0) goto endcmd;
328 copy = calloc(pend-pstart + 1, sizeof(char));337 copy = static_cast<char *>(calloc(pend-pstart + 1, sizeof(char)));
329 strncpy(copy, pstart, pend-pstart);338 strncpy(copy, pstart, pend-pstart);
330339
331 switch(cmdind) {340 switch(cmdind) {
@@ -378,7 +387,7 @@ struct inputData {
378 char inputBuffer[MAX_BUFFER_SIZE];387 char inputBuffer[MAX_BUFFER_SIZE];
379};388};
380389
381static void inputOpenFile(inputData *pinputData, char *filename);390static void inputOpenFile(inputData *pinputData, const char * const filename);
382static void inputCloseFile(inputData *pinputData);391static void inputCloseFile(inputData *pinputData);
383static void inputCloseAllFiles(inputData *pinputData);392static void inputCloseAllFiles(inputData *pinputData);
384393
@@ -386,13 +395,13 @@ static void inputConstruct(inputData **ppvt)
386{395{
387 inputData *pinputData;396 inputData *pinputData;
388397
389 pinputData = calloc(1, sizeof(inputData));398 pinputData = static_cast<inputData *>(calloc(1, sizeof(inputData)));
390 ellInit(&pinputData->inputFileList);399 ellInit(&pinputData->inputFileList);
391 ellInit(&pinputData->pathList);400 ellInit(&pinputData->pathList);
392 *ppvt = pinputData;401 *ppvt = pinputData;
393}402}
394403
395static void inputDestruct(inputData *pinputData)404static void inputDestruct(inputData * const pinputData)
396{405{
397 pathNode *ppathNode;406 pathNode *ppathNode;
398407
@@ -405,7 +414,7 @@ static void inputDestruct(inputData *pinputData)
405 free(pinputData);414 free(pinputData);
406}415}
407416
408417
409static void inputAddPath(inputData *pinputData, char *path)418static void inputAddPath(inputData * const pinputData, const char * const path)
410{419{
411 ELLLIST *ppathList = &pinputData->pathList;420 ELLLIST *ppathList = &pinputData->pathList;
412 pathNode *ppathNode;421 pathNode *ppathNode;
@@ -448,7 +457,7 @@ static void inputAddPath(inputData *pinputData, char *path)
448 EXIT;457 EXIT;
449}458}
450459
451460
452static void inputBegin(inputData *pinputData, char *fileName)461static void inputBegin(inputData * const pinputData, const char * const fileName)
453{462{
454 ENTER;463 ENTER;
455 inputCloseAllFiles(pinputData);464 inputCloseAllFiles(pinputData);
@@ -456,7 +465,7 @@ static void inputBegin(inputData *pinputData, char *fileName)
456 EXIT;465 EXIT;
457}466}
458467
459static char *inputNextLine(inputData *pinputData)468static char *inputNextLine(inputData * const pinputData)
460{469{
461 inputFile *pinputFile;470 inputFile *pinputFile;
462 char *pline;471 char *pline;
@@ -475,14 +484,15 @@ static char *inputNextLine(inputData *pinputData)
475 return 0;484 return 0;
476}485}
477486
478static void inputNewIncludeFile(inputData *pinputData, char *name)487static void inputNewIncludeFile(inputData * const pinputData,
488 const char * const name)
479{489{
480 ENTER;490 ENTER;
481 inputOpenFile(pinputData,name);491 inputOpenFile(pinputData,name);
482 EXIT;492 EXIT;
483}493}
484494
485static void inputErrPrint(inputData *pinputData)495static void inputErrPrint(const inputData *const pinputData)
486{496{
487 inputFile *pinputFile;497 inputFile *pinputFile;
488498
@@ -511,7 +521,7 @@ static void inputErrPrint(inputData *pinputData)
511 EXIT;521 EXIT;
512}522}
513523
514524
515static void inputOpenFile(inputData *pinputData,char *filename)525static void inputOpenFile(inputData *pinputData, const char * const filename)
516{526{
517 ELLLIST *ppathList = &pinputData->pathList;527 ELLLIST *ppathList = &pinputData->pathList;
518 pathNode *ppathNode = 0;528 pathNode *ppathNode = 0;
@@ -531,8 +541,8 @@ static void inputOpenFile(inputData *pinputData,char *filename)
531 else {541 else {
532 ppathNode = (pathNode *) ellFirst(ppathList);542 ppathNode = (pathNode *) ellFirst(ppathList);
533 while (ppathNode) {543 while (ppathNode) {
534 fullname = calloc(strlen(filename) + strlen(ppathNode->directory) + 2,544 fullname = static_cast<char *>(calloc(strlen(filename) + strlen(ppathNode->directory) + 2,
535 sizeof(char));545 sizeof(char)));
536 strcpy(fullname, ppathNode->directory);546 strcpy(fullname, ppathNode->directory);
537 strcat(fullname, "/");547 strcat(fullname, "/");
538 strcat(fullname, filename);548 strcat(fullname, filename);
@@ -552,7 +562,7 @@ static void inputOpenFile(inputData *pinputData,char *filename)
552 }562 }
553563
554 STEP("File opened");564 STEP("File opened");
555 pinputFile = calloc(1, sizeof(inputFile));565 pinputFile = static_cast<inputFile *>(calloc(1, sizeof(inputFile)));
556566
557 if (ppathNode) {567 if (ppathNode) {
558 pinputFile->filename = fullname;568 pinputFile->filename = fullname;
@@ -647,14 +657,13 @@ struct subInfo {
647 char *filename;657 char *filename;
648 int isPattern;658 int isPattern;
649 ELLLIST patternList;659 ELLLIST patternList;
650 size_t size;660 std::string macroReplacements;
651 size_t curLength;661 subInfo() : psubFile(NULL), isFile(0), filename(NULL), isPattern(0) {};
652 char *macroReplacements;
653};662};
654663
655static char *subGetNextLine(subFile *psubFile);664static char *subGetNextLine(subFile *psubFile);
656static tokenType subGetNextToken(subFile *psubFile);665static tokenType subGetNextToken(subFile *psubFile);
657static void subFileErrPrint(subFile *psubFile,char * message);666static void subFileErrPrint(subFile *psubFile, const char * message);
658static void freeSubFile(subInfo *psubInfo);667static void freeSubFile(subInfo *psubInfo);
659static void freePattern(subInfo *psubInfo);668static void freePattern(subInfo *psubInfo);
660static void catMacroReplacements(subInfo *psubInfo,const char *value);669static void catMacroReplacements(subInfo *psubInfo,const char *value);
@@ -688,25 +697,25 @@ void freePattern(subInfo *psubInfo)
688 EXIT;697 EXIT;
689}698}
690699
691700
692static void substituteDestruct(subInfo *psubInfo)701static void substituteDestruct(subInfo * const psubInfo)
693{702{
694 ENTER;703 ENTER;
695 freeSubFile(psubInfo);704 freeSubFile(psubInfo);
696 freePattern(psubInfo);705 freePattern(psubInfo);
697 free(psubInfo);706 delete(psubInfo);
698 EXIT;707 EXIT;
699}708}
700709
701static void substituteOpen(subInfo **ppvt, char *substitutionName)710static void substituteOpen(subInfo **ppvt, char * const substitutionName)
702{711{
703 subInfo *psubInfo;712 subInfo *psubInfo;
704 subFile *psubFile;713 subFile *psubFile;
705 FILE *fp;714 FILE *fp;
706715
707 ENTER;716 ENTER;
708 psubInfo = calloc(1, sizeof(subInfo));717 psubInfo = new subInfo;
709 *ppvt = psubInfo;718 *ppvt = psubInfo;
710 psubFile = calloc(1, sizeof(subFile));719 psubFile = static_cast<subFile *>(calloc(1, sizeof(subFile)));
711 psubInfo->psubFile = psubFile;720 psubInfo->psubFile = psubFile;
712 ellInit(&psubInfo->patternList);721 ellInit(&psubInfo->patternList);
713722
@@ -725,7 +734,7 @@ static void substituteOpen(subInfo **ppvt, char *substitutionName)
725 EXIT;734 EXIT;
726}735}
727736
728static int substituteGetGlobalSet(subInfo *psubInfo)737static int substituteGetGlobalSet(subInfo * const psubInfo)
729{738{
730 subFile *psubFile = psubInfo->psubFile;739 subFile *psubFile = psubInfo->psubFile;
731740
@@ -744,7 +753,7 @@ static int substituteGetGlobalSet(subInfo *psubInfo)
744 return 0;753 return 0;
745}754}
746755
747static int substituteGetNextSet(subInfo *psubInfo,char **filename)756static int substituteGetNextSet(subInfo * const psubInfo,char **filename)
748{757{
749 subFile *psubFile = psubInfo->psubFile;758 subFile *psubFile = psubInfo->psubFile;
750 patternNode *ppatternNode;759 patternNode *ppatternNode;
@@ -831,7 +840,7 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename)
831 if (psubFile->token != tokenString)840 if (psubFile->token != tokenString)
832 break;841 break;
833842
834 ppatternNode = calloc(1, sizeof(patternNode));843 ppatternNode = static_cast<patternNode *>(calloc(1, sizeof(patternNode)));
835 ellAdd(&psubInfo->patternList, &ppatternNode->node);844 ellAdd(&psubInfo->patternList, &ppatternNode->node);
836 ppatternNode->var = epicsStrDup(psubFile->string);845 ppatternNode->var = epicsStrDup(psubFile->string);
837 }846 }
@@ -846,14 +855,12 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename)
846 return 1;855 return 1;
847}856}
848857
849858
850static char *substituteGetGlobalReplacements(subInfo *psubInfo)859static const char *substituteGetGlobalReplacements(subInfo * const psubInfo)
851{860{
852 subFile *psubFile = psubInfo->psubFile;861 subFile *psubFile = psubInfo->psubFile;
853862
854 ENTER;863 ENTER;
855 if (psubInfo->macroReplacements)864 psubInfo->macroReplacements.clear();
856 psubInfo->macroReplacements[0] = 0;
857 psubInfo->curLength = 0;
858865
859 while (psubFile->token == tokenSeparator)866 while (psubFile->token == tokenSeparator)
860 subGetNextToken(psubFile);867 subGetNextToken(psubFile);
@@ -881,8 +888,8 @@ static char *substituteGetGlobalReplacements(subInfo *psubInfo)
881 switch(subGetNextToken(psubFile)) {888 switch(subGetNextToken(psubFile)) {
882 case tokenRBrace:889 case tokenRBrace:
883 subGetNextToken(psubFile);890 subGetNextToken(psubFile);
884 EXITS(psubInfo->macroReplacements);891 EXITS(psubInfo->macroReplacements.c_str());
885 return psubInfo->macroReplacements;892 return psubInfo->macroReplacements.c_str();
886893
887 case tokenSeparator:894 case tokenSeparator:
888 catMacroReplacements(psubInfo, ",");895 catMacroReplacements(psubInfo, ",");
@@ -902,15 +909,13 @@ static char *substituteGetGlobalReplacements(subInfo *psubInfo)
902 }909 }
903}910}
904911
905static char *substituteGetReplacements(subInfo *psubInfo)912static const char *substituteGetReplacements(subInfo * const psubInfo)
906{913{
907 subFile *psubFile = psubInfo->psubFile;914 subFile *psubFile = psubInfo->psubFile;
908 patternNode *ppatternNode;915 patternNode *ppatternNode;
909916
910 ENTER;917 ENTER;
911 if (psubInfo->macroReplacements)918 psubInfo->macroReplacements.clear();
912 psubInfo->macroReplacements[0] = 0;
913 psubInfo->curLength = 0;
914919
915 while (psubFile->token == tokenSeparator)920 while (psubFile->token == tokenSeparator)
916 subGetNextToken(psubFile);921 subGetNextToken(psubFile);
@@ -943,8 +948,8 @@ static char *substituteGetReplacements(subInfo *psubInfo)
943 while (1) {948 while (1) {
944 if (psubFile->token == tokenRBrace) {949 if (psubFile->token == tokenRBrace) {
945 subGetNextToken(psubFile);950 subGetNextToken(psubFile);
946 EXITS(psubInfo->macroReplacements);951 EXITS(psubInfo->macroReplacements.c_str());
947 return psubInfo->macroReplacements;952 return psubInfo->macroReplacements.c_str();
948 }953 }
949954
950 if (psubFile->token != tokenString) {955 if (psubFile->token != tokenString) {
@@ -973,8 +978,8 @@ static char *substituteGetReplacements(subInfo *psubInfo)
973 switch(subGetNextToken(psubFile)) {978 switch(subGetNextToken(psubFile)) {
974 case tokenRBrace:979 case tokenRBrace:
975 subGetNextToken(psubFile);980 subGetNextToken(psubFile);
976 EXITS(psubInfo->macroReplacements);981 EXITS(psubInfo->macroReplacements.c_str());
977 return psubInfo->macroReplacements;982 return psubInfo->macroReplacements.c_str();
978983
979 case tokenSeparator:984 case tokenSeparator:
980 catMacroReplacements(psubInfo, ",");985 catMacroReplacements(psubInfo, ",");
@@ -1017,7 +1022,7 @@ static char *subGetNextLine(subFile *psubFile)
1017 return &psubFile->inputBuffer[0];1022 return &psubFile->inputBuffer[0];
1018}1023}
10191024
1020static void subFileErrPrint(subFile *psubFile,char * message)1025static void subFileErrPrint(subFile *psubFile, const char * message)
1021{1026{
1022 fprintf(stderr, "msi: %s\n",message);1027 fprintf(stderr, "msi: %s\n",message);
1023 fprintf(stderr, " in substitution file '%s' at line %d:\n %s",1028 fprintf(stderr, " in substitution file '%s' at line %d:\n %s",
@@ -1107,32 +1112,8 @@ done:
11071112
1108static void catMacroReplacements(subInfo *psubInfo, const char *value)1113static void catMacroReplacements(subInfo *psubInfo, const char *value)
1109{1114{
1110 size_t len = strlen(value);
1111
1112 ENTER;1115 ENTER;
1113 if (psubInfo->size <= (psubInfo->curLength + len)) {
1114 size_t newsize = psubInfo->size + MAX_BUFFER_SIZE;
1115 char *newbuf;
1116
1117 STEP("Enlarging buffer");
1118 if (newsize <= psubInfo->curLength + len)
1119 newsize = psubInfo->curLength + len + 1;
1120 newbuf = calloc(1, newsize);
1121 if (!newbuf) {
1122 fprintf(stderr, "calloc failed for size %lu\n",
1123 (unsigned long) newsize);
1124 abortExit(1);
1125 }
1126 if (psubInfo->macroReplacements) {
1127 memcpy(newbuf, psubInfo->macroReplacements, psubInfo->curLength);
1128 free(psubInfo->macroReplacements);
1129 }
1130 psubInfo->size = newsize;
1131 psubInfo->macroReplacements = newbuf;
1132 }
1133
1134 STEPS("Appending", value);1116 STEPS("Appending", value);
1135 strcat(psubInfo->macroReplacements, value);1117 psubInfo->macroReplacements += value;
1136 psubInfo->curLength += len;
1137 EXIT;1118 EXIT;
1138}1119}
diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt
index 4149125..332defb 100644
--- a/src/ioc/dbtemplate/test/msi.plt
+++ b/src/ioc/dbtemplate/test/msi.plt
@@ -11,7 +11,7 @@
11use strict;11use strict;
12use Test;12use Test;
1313
14BEGIN {plan tests => 9}14BEGIN {plan tests => 11}
1515
16# Check include/substitute command model16# Check include/substitute command model
17ok(msi('-I .. ../t1-template.txt'), slurp('../t1-result.txt'));17ok(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'));
50# Dependency generation, dbLoadTemplate format50# Dependency generation, dbLoadTemplate format
51ok(msi('-I.. -D -ot9.txt -S ../t2-substitution.txt'), slurp('../t9-result.txt'));51ok(msi('-I.. -D -ot9.txt -S ../t2-substitution.txt'), slurp('../t9-result.txt'));
5252
53# Substitution file, variable format, with 0 variable definitions
54ok(msi('-I. -I.. -S ../t10-substitute.txt'), slurp('../t10-result.txt'));
55
56# Substitution file, pattern format, with 0 pattern definitions
57ok(msi('-I. -I.. -S ../t11-substitute.txt'), slurp('../t11-result.txt'));
58
5359
54# Test support routines60# Test support routines
5561
diff --git a/src/ioc/dbtemplate/test/t10-result.txt b/src/ioc/dbtemplate/test/t10-result.txt
56new file mode 10064462new file mode 100644
index 0000000..47b594e
--- /dev/null
+++ b/src/ioc/dbtemplate/test/t10-result.txt
@@ -0,0 +1,4 @@
1# comment line
2a=$(a)
3# comment line
4a=gbl
diff --git a/src/ioc/dbtemplate/test/t10-substitute.txt b/src/ioc/dbtemplate/test/t10-substitute.txt
0new file mode 1006445new file mode 100644
index 0000000..aec88bb
--- /dev/null
+++ b/src/ioc/dbtemplate/test/t10-substitute.txt
@@ -0,0 +1,8 @@
1file t10-template.txt {
2 {}
3}
4
5global { a=gbl }
6file t10-template.txt {
7 {}
8}
diff --git a/src/ioc/dbtemplate/test/t10-template.txt b/src/ioc/dbtemplate/test/t10-template.txt
0new file mode 1006449new file mode 100644
index 0000000..7958885
--- /dev/null
+++ b/src/ioc/dbtemplate/test/t10-template.txt
@@ -0,0 +1,2 @@
1# comment line
2a=$(a)
diff --git a/src/ioc/dbtemplate/test/t11-result.txt b/src/ioc/dbtemplate/test/t11-result.txt
0new file mode 1006443new file mode 100644
index 0000000..47b594e
--- /dev/null
+++ b/src/ioc/dbtemplate/test/t11-result.txt
@@ -0,0 +1,4 @@
1# comment line
2a=$(a)
3# comment line
4a=gbl
diff --git a/src/ioc/dbtemplate/test/t11-substitute.txt b/src/ioc/dbtemplate/test/t11-substitute.txt
0new file mode 1006445new file mode 100644
index 0000000..94dcdbc
--- /dev/null
+++ b/src/ioc/dbtemplate/test/t11-substitute.txt
@@ -0,0 +1,10 @@
1file t11-template.txt {
2 pattern {}
3 {}
4}
5
6global { a=gbl }
7file t11-template.txt {
8 pattern {}
9 {}
10}
diff --git a/src/ioc/dbtemplate/test/t11-template.txt b/src/ioc/dbtemplate/test/t11-template.txt
0new file mode 10064411new file mode 100644
index 0000000..7958885
--- /dev/null
+++ b/src/ioc/dbtemplate/test/t11-template.txt
@@ -0,0 +1,2 @@
1# comment line
2a=$(a)

Subscribers

People subscribed via source and target branches