diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 571a1b3a0..57baf3db1 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -16,6 +16,14 @@ +

Improvements to msi

+ +

In addition to fixing its response to discovering parsing errors in its + substitution input file (reported as Launchpad + bug #1503661) + so it now deletes the incomplete output file, the msi program has been cleaned + up a little bit internally.

+

All array records now post monitors on their array-length fields

The waveform record has been posting monitors on its NORD field since Base diff --git a/src/ioc/dbtemplate/msi.c b/src/ioc/dbtemplate/msi.c index a29bb5fc0..69680e17e 100644 --- a/src/ioc/dbtemplate/msi.c +++ b/src/ioc/dbtemplate/msi.c @@ -4,7 +4,7 @@ * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS Base is distributed subject to a Software License Agreement found -* in the file LICENSE that is included with this distribution. +* in the file LICENSE that is included with this distribution. \*************************************************************************/ /* msi - macro substitutions and include */ @@ -27,6 +27,31 @@ #define MAX_BUFFER_SIZE 4096 #define MAX_DEPS 1024 +#if 0 +/* Debug Tracing */ +int din = 0; +#define ENTER fprintf(stderr, "%*sEntering %s\n", 2*din++, "", __FUNCTION__) + +#define STEP(s) fprintf(stderr, "%*s%s: %s\n", 2*din, "", __FUNCTION__, s) +#define STEPS(s, v) fprintf(stderr, "%*s%s: %s '%s'\n", 2*din, "", __FUNCTION__, s, v) +#define STEPD(s, v) fprintf(stderr, "%*s%s: %s %d\n", 2*din, "", __FUNCTION__, s, v) + +#define EXIT fprintf(stderr, "%*s%s: Returning\n", 2*din--, "", __FUNCTION__) +#define EXITD(r) fprintf(stderr, "%*s%s: Returning %d\n", 2*din--, "", __FUNCTION__, r) +#define EXITS(r) fprintf(stderr, "%*s%s: Returning '%s'\n", 2*din--, "", __FUNCTION__, r) +#else +#define ENTER + +#define STEP(s) +#define STEPS(s, v) +#define STEPD(s, v) + +#define EXIT +#define EXITD(r) +#define EXITS(r) +#endif + + /* Module to read the template files */ typedef struct inputData inputData; @@ -68,48 +93,62 @@ int main(int argc,char **argv) MAC_HANDLE *macPvt; char *pval; int narg; - char *substitutionName=0; - char *templateName=0; + char *substitutionName = 0; + char *templateName = 0; int i; int localScope = 1; inputConstruct(&inputPvt); - macCreateHandle(&macPvt,0); - while((argc>1) && (argv[1][0] == '-')) { - narg = (strlen(argv[1])==2) ? 2 : 1; - pval = (narg==1) ? (argv[1]+2) : argv[2]; - if(strncmp(argv[1],"-I",2)==0) { - inputAddPath(inputPvt,pval); - } else if (strcmp(argv[1], "-D") == 0) { + macCreateHandle(&macPvt, 0); + while ((argc > 1) && (argv[1][0] == '-')) { + narg = (strlen(argv[1]) == 2) ? 2 : 1; + pval = (narg == 1) ? (argv[1] + 2) : argv[2]; + + if (strncmp(argv[1], "-I", 2) == 0) { + inputAddPath(inputPvt, pval); + } + else if (strcmp(argv[1], "-D") == 0) { opt_D = 1; narg = 1; /* no argument for this option */ - } else if(strncmp(argv[1],"-o",2)==0) { + } + else if(strncmp(argv[1], "-o", 2) == 0) { outFile = epicsStrDup(pval); - } else if(strncmp(argv[1],"-M",2)==0) { - addMacroReplacements(macPvt,pval); - } else if(strncmp(argv[1],"-S",2)==0) { + } + else if(strncmp(argv[1], "-M", 2) == 0) { + addMacroReplacements(macPvt, pval); + } + else if(strncmp(argv[1], "-S", 2) == 0) { substitutionName = epicsStrDup(pval); - } else if (strcmp(argv[1], "-V") == 0) { + } + else if (strcmp(argv[1], "-V") == 0) { opt_V = 1; narg = 1; /* no argument for this option */ - } else if (strcmp(argv[1], "-g") == 0) { + } + else if (strcmp(argv[1], "-g") == 0) { localScope = 0; narg = 1; /* no argument for this option */ - } else if (strcmp(argv[1], "-h") == 0) { + } + else if (strcmp(argv[1], "-h") == 0) { usageExit(0); - } else { + } + else { fprintf(stderr, "msi: Bad argument \"%s\"\n", argv[1]); usageExit(1); } + argc -= narg; - for(i=1; i2) { - fprintf(stderr,"msi: Too many arguments\n"); + macSuppressWarning(macPvt, 1); + + if (argc > 2) { + fprintf(stderr, "msi: Too many arguments\n"); usageExit(1); } + if (opt_D) { if (!outFile) { fprintf(stderr, "msi: Option -D requires -o for Makefile target\n"); @@ -122,34 +161,47 @@ int main(int argc,char **argv) outFile, strerror(errno)); exit(1); } - if(argc==2) { + + if (argc == 2) templateName = epicsStrDup(argv[1]); + + if (!substitutionName) { + STEP("Single template+substitutions file"); + makeSubstitutions(inputPvt, macPvt, templateName); } - if(!substitutionName) { - makeSubstitutions(inputPvt,macPvt,templateName); - } else { + else { subInfo *substitutePvt; char *filename = 0; int isGlobal, isFile; - substituteOpen(&substitutePvt,substitutionName); + STEPS("Substitutions from file", substitutionName); + substituteOpen(&substitutePvt, substitutionName); do { - if ((isGlobal = substituteGetGlobalSet(substitutePvt))) { + isGlobal = substituteGetGlobalSet(substitutePvt); + if (isGlobal) { + STEP("Handling global macros"); pval = substituteGetGlobalReplacements(substitutePvt); - if(pval) { - addMacroReplacements(macPvt,pval); - } - } else if ((isFile = substituteGetNextSet(substitutePvt,&filename))) { - if(templateName) filename = templateName; - if(!filename) { - fprintf(stderr,"msi: No template file\n"); + if (pval) + addMacroReplacements(macPvt, pval); + } + else if ((isFile = substituteGetNextSet(substitutePvt, &filename))) { + if (templateName) + filename = templateName; + if (!filename) { + fprintf(stderr, "msi: No template file\n"); usageExit(1); } - while((pval = substituteGetReplacements(substitutePvt))){ - if (localScope) macPushScope(macPvt); - addMacroReplacements(macPvt,pval); - makeSubstitutions(inputPvt,macPvt,filename); - if (localScope) macPopScope(macPvt); + + STEPS("Handling template file", filename); + while ((pval = substituteGetReplacements(substitutePvt))) { + if (localScope) + macPushScope(macPvt); + + addMacroReplacements(macPvt, pval); + makeSubstitutions(inputPvt, macPvt, filename); + + if (localScope) + macPopScope(macPvt); } } } while (isGlobal || isFile); @@ -198,15 +250,15 @@ static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval) char **pairs; long status; - status = macParseDefns(macPvt,pval,&pairs); - if(status==-1) { - fprintf(stderr,"msi: Error from macParseDefns\n"); + status = macParseDefns(macPvt, pval, &pairs); + if (status == -1) { + fprintf(stderr, "msi: Error from macParseDefns\n"); usageExit(1); } - if(status) { - status = macInstallMacros(macPvt,pairs); - if(!status) { - fprintf(stderr,"Error from macInstallMacros\n"); + if (status) { + status = macInstallMacros(macPvt, pairs); + if (!status) { + fprintf(stderr, "Error from macInstallMacros\n"); usageExit(1); } free(pairs); @@ -222,86 +274,98 @@ static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *tem static char buffer[MAX_BUFFER_SIZE]; int n; - inputBegin(inputPvt,templateName); - while((input = inputNextLine(inputPvt))) { + ENTER; + inputBegin(inputPvt, templateName); + while ((input = inputNextLine(inputPvt))) { int expand=1; char *p; char *command = 0; - p = input; + p = input; /*skip whitespace at beginning of line*/ - while(*p && (isspace((int) *p))) ++p; + while (*p && (isspace((int) *p))) ++p; + /*Look for i or s */ - if(*p && (*p=='i' || *p=='s')) command = p; - if(command) { + if (*p && (*p=='i' || *p=='s')) + command = p; + + if (command) { char *pstart; char *pend; char *copy; int cmdind=-1; int i; - - for(i=0; i< NELEMENTS(cmdNames); i++) { - if(strstr(command,cmdNames[i])) { + + for (i = 0; i < NELEMENTS(cmdNames); i++) { + if (strstr(command, cmdNames[i])) { cmdind = i; } } - if(cmdind<0) goto endif; + if (cmdind < 0) goto endcmd; p = command + strlen(cmdNames[cmdind]); /*skip whitespace after command*/ - while(*p && (isspace((int) *p))) ++p; + while (*p && (isspace((int) *p))) ++p; /*Next character must be quote*/ - if((*p==0) || (*p!='"')) goto endif; + if ((*p == 0) || (*p != '"')) goto endcmd; pstart = ++p; /*Look for end quote*/ - while(*p && (*p!='"')) { - /*allow escape for imbeded quote*/ - if((*p=='\\') && *(p+1)=='"') { - p += 2; continue; - } else { - if(*p=='"') break; + while (*p && (*p != '"')) { + /*allow escape for embeded quote*/ + if ((p[0] == '\\') && p[1] == '"') { + p += 2; + continue; + } + else { + if (*p == '"') break; } ++p; } pend = p; - if(*p==0) goto endif; + if (*p == 0) goto endcmd; /*skip quote and any trailing blanks*/ - while(*++p==' ') ; - if(*p != '\n' && *p !=0) goto endif; - copy = calloc(pend-pstart+1,sizeof(char)); - strncpy(copy,pstart,pend-pstart); + while (*++p == ' ') ; + if (*p != '\n' && *p != 0) goto endcmd; + copy = calloc(pend-pstart + 1, sizeof(char)); + strncpy(copy, pstart, pend-pstart); + switch(cmdind) { case cmdInclude: inputNewIncludeFile(inputPvt,copy); break; + case cmdSubstitute: addMacroReplacements(macPvt,copy); break; + default: - fprintf(stderr,"msi: Logic error in makeSubstitutions\n"); + fprintf(stderr, "msi: Logic error in makeSubstitutions\n"); inputErrPrint(inputPvt); abortExit(1); } free(copy); expand = 0; } -endif: + +endcmd: if (expand && !opt_D) { - n = macExpandString(macPvt,input,buffer,MAX_BUFFER_SIZE-1); - fputs(buffer,stdout); + STEP("Expanding to output stream"); + n = macExpandString(macPvt, input, buffer, MAX_BUFFER_SIZE - 1); + fputs(buffer, stdout); if (opt_V == 1 && n < 0) { - fprintf(stderr,"msi: Error - undefined macros present\n"); + fprintf(stderr, "msi: Error - undefined macros present\n"); opt_V++; } } } + EXIT; } -typedef struct inputFile{ +typedef struct inputFile { ELLNODE node; char *filename; FILE *fp; int lineNum; -}inputFile; +} inputFile; typedef struct pathNode { ELLNODE node; @@ -314,15 +378,15 @@ struct inputData { char inputBuffer[MAX_BUFFER_SIZE]; }; -static void inputOpenFile(inputData *pinputData,char *filename); +static void inputOpenFile(inputData *pinputData, char *filename); static void inputCloseFile(inputData *pinputData); static void inputCloseAllFiles(inputData *pinputData); static void inputConstruct(inputData **ppvt) { - inputData *pinputData; + inputData *pinputData; - pinputData = calloc(1,sizeof(inputData)); + pinputData = calloc(1, sizeof(inputData)); ellInit(&pinputData->inputFileList); ellInit(&pinputData->pathList); *ppvt = pinputData; @@ -330,11 +394,11 @@ static void inputConstruct(inputData **ppvt) static void inputDestruct(inputData *pinputData) { - pathNode *ppathNode; + pathNode *ppathNode; inputCloseAllFiles(pinputData); - while((ppathNode = (pathNode *)ellFirst(&pinputData->pathList))) { - ellDelete(&pinputData->pathList,&ppathNode->node); + while ((ppathNode = (pathNode *) ellFirst(&pinputData->pathList))) { + ellDelete(&pinputData->pathList, &ppathNode->node); free(ppathNode->directory); free(ppathNode); } @@ -351,38 +415,45 @@ static void inputAddPath(inputData *pinputData, char *path) int emptyName; const char sep = *OSI_PATH_LIST_SEPARATOR; + ENTER; pdir = path; /*an empty name at beginning, middle, or end means current directory*/ - while(pdir && *pdir) { + while (pdir && *pdir) { emptyName = ((*pdir == sep) ? 1 : 0); - if(emptyName) ++pdir; - ppathNode = (pathNode *)calloc(1,sizeof(pathNode)); - ellAdd(ppathList,&ppathNode->node); - if(!emptyName) { - pcolon = strchr(pdir,sep); + if (emptyName) ++pdir; + + ppathNode = (pathNode *) calloc(1, sizeof(pathNode)); + ellAdd(ppathList, &ppathNode->node); + + if (!emptyName) { + pcolon = strchr(pdir, sep); len = (pcolon ? (pcolon - pdir) : strlen(pdir)); - if(len>0) { - ppathNode->directory = (char *)calloc(len+1,sizeof(char)); - strncpy(ppathNode->directory,pdir,len); + if (len > 0) { + ppathNode->directory = (char *) calloc(len + 1, sizeof(char)); + strncpy(ppathNode->directory, pdir, len); pdir = pcolon; /*unless at end skip past first colon*/ - if(pdir && *(pdir+1)!=0) ++pdir; - } else { /*must have been trailing : */ - emptyName=1; + if (pdir && *(pdir + 1) != 0) ++pdir; + } + else { /*must have been trailing : */ + emptyName = 1; } } - if(emptyName) { - ppathNode->directory = (char *)calloc(2,sizeof(char)); - strcpy(ppathNode->directory,"."); + + if (emptyName) { + ppathNode->directory = (char *) calloc(2, sizeof(char)); + strcpy(ppathNode->directory, "."); } } - return; + EXIT; } static void inputBegin(inputData *pinputData, char *fileName) { + ENTER; inputCloseAllFiles(pinputData); - inputOpenFile(pinputData,fileName); + inputOpenFile(pinputData, fileName); + EXIT; } static char *inputNextLine(inputData *pinputData) @@ -390,43 +461,54 @@ static char *inputNextLine(inputData *pinputData) inputFile *pinputFile; char *pline; - while((pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList))) { - pline = fgets(pinputData->inputBuffer,MAX_BUFFER_SIZE,pinputFile->fp); - if(pline) { + ENTER; + while ((pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList))) { + pline = fgets(pinputData->inputBuffer, MAX_BUFFER_SIZE, pinputFile->fp); + if (pline) { ++pinputFile->lineNum; - return(pline); + EXITS(pline); + return pline; } inputCloseFile(pinputData); } - return(0); + EXITD(0); + return 0; } static void inputNewIncludeFile(inputData *pinputData, char *name) { + ENTER; inputOpenFile(pinputData,name); + EXIT; } static void inputErrPrint(inputData *pinputData) { inputFile *pinputFile; - fprintf(stderr,"input: '%s' at ",pinputData->inputBuffer); - pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList); - while(pinputFile) { - fprintf(stderr,"line %d of ",pinputFile->lineNum); - if(pinputFile->filename) { - fprintf(stderr," file %s\n",pinputFile->filename); - } else { - fprintf(stderr,"stdin:\n"); + ENTER; + fprintf(stderr, "input: '%s' at ", pinputData->inputBuffer); + pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList); + while (pinputFile) { + fprintf(stderr, "line %d of ", pinputFile->lineNum); + + if (pinputFile->filename) { + fprintf(stderr, " file %s\n", pinputFile->filename); } - pinputFile = (inputFile *)ellNext(&pinputFile->node); - if(pinputFile) { - fprintf(stderr," included from "); - } else { + else { + fprintf(stderr, "stdin:\n"); + } + + pinputFile = (inputFile *) ellNext(&pinputFile->node); + if (pinputFile) { + fprintf(stderr, " included from "); + } + else { fprintf(stderr,"\n"); } } fprintf(stderr,"\n"); + EXIT; } static void inputOpenFile(inputData *pinputData,char *filename) @@ -437,35 +519,48 @@ static void inputOpenFile(inputData *pinputData,char *filename) char *fullname = 0; FILE *fp = 0; - if(!filename) { + ENTER; + if (!filename) { + STEP("Using stdin"); fp = stdin; - } else if((ellCount(ppathList)==0) || strchr(filename,'/')){ - fp = fopen(filename,"r"); - } else { - ppathNode = (pathNode *)ellFirst(ppathList); - while(ppathNode) { - fullname = calloc(strlen(filename)+strlen(ppathNode->directory) +2, + } + else if ((ellCount(ppathList) == 0) || strchr(filename, '/')){ + STEPS("Opening ", filename); + fp = fopen(filename, "r"); + } + else { + ppathNode = (pathNode *) ellFirst(ppathList); + while (ppathNode) { + fullname = calloc(strlen(filename) + strlen(ppathNode->directory) + 2, sizeof(char)); - strcpy(fullname,ppathNode->directory); - strcat(fullname,"/"); - strcat(fullname,filename); - fp = fopen(fullname,"r"); - if(fp) break; + strcpy(fullname, ppathNode->directory); + strcat(fullname, "/"); + strcat(fullname, filename); + STEPS("Trying", filename); + fp = fopen(fullname, "r"); + if (fp) + break; free(fullname); - ppathNode = (pathNode *)ellNext(&ppathNode->node); + ppathNode = (pathNode *) ellNext(&ppathNode->node); } } - if(!fp) { - fprintf(stderr,"msi: Can't open file '%s'\n",filename); + + if (!fp) { + fprintf(stderr, "msi: Can't open file '%s'\n", filename); inputErrPrint(pinputData); abortExit(1); } - pinputFile = calloc(1,sizeof(inputFile)); - if(ppathNode) { + + STEP("File opened"); + pinputFile = calloc(1, sizeof(inputFile)); + + if (ppathNode) { pinputFile->filename = fullname; - } else if(filename) { + } + else if (filename) { pinputFile->filename = epicsStrDup(filename); - } else { + } + else { pinputFile->filename = epicsStrDup("stdin"); } @@ -495,35 +590,41 @@ static void inputOpenFile(inputData *pinputData,char *filename) } pinputFile->fp = fp; - ellInsert(&pinputData->inputFileList,0,&pinputFile->node); + ellInsert(&pinputData->inputFileList, 0, &pinputFile->node); + EXIT; } static void inputCloseFile(inputData *pinputData) { inputFile *pinputFile; - pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList); - if(!pinputFile) return; - ellDelete(&pinputData->inputFileList,&pinputFile->node); - if(fclose(pinputFile->fp)) - fprintf(stderr,"msi: Can't close input file '%s'\n",pinputFile->filename); - free(pinputFile->filename); - free(pinputFile); + ENTER; + pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList); + if (pinputFile) { + ellDelete(&pinputData->inputFileList, &pinputFile->node); + if (fclose(pinputFile->fp)) + fprintf(stderr, "msi: Can't close input file '%s'\n", pinputFile->filename); + free(pinputFile->filename); + free(pinputFile); + } + EXIT; } static void inputCloseAllFiles(inputData *pinputData) { inputFile *pinputFile; - while((pinputFile=(inputFile *)ellFirst(&pinputData->inputFileList))){ + ENTER; + while ((pinputFile = (inputFile *) ellFirst(&pinputData->inputFileList))) { inputCloseFile(pinputData); } + EXIT; } /*start of code that handles substitution file*/ typedef enum { - tokenLBrace,tokenRBrace,tokenSeparater,tokenString,tokenEOF -}tokenType; + tokenLBrace, tokenRBrace, tokenSeparator, tokenString, tokenEOF +} tokenType; typedef struct subFile { char *substitutionName; @@ -560,70 +661,87 @@ static void catMacroReplacements(subInfo *psubInfo,const char *value); void freeSubFile(subInfo *psubInfo) { - subFile *psubFile = psubInfo->psubFile; - if(psubFile->fp) { - if(fclose(psubFile->fp)) - fprintf(stderr,"msi: Can't close substitution file\n"); + subFile *psubFile = psubInfo->psubFile; + + ENTER; + if (psubFile->fp) { + if (fclose(psubFile->fp)) + fprintf(stderr, "msi: Can't close substitution file\n"); } free(psubFile); free(psubInfo->filename); psubInfo->psubFile = 0; + EXIT; } void freePattern(subInfo *psubInfo) { patternNode *ppatternNode; - while((ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList))) { - ellDelete(&psubInfo->patternList,&ppatternNode->node); + + ENTER; + while ((ppatternNode = (patternNode *) ellFirst(&psubInfo->patternList))) { + ellDelete(&psubInfo->patternList, &ppatternNode->node); free(ppatternNode->var); free(ppatternNode); } psubInfo->isPattern = 0; + EXIT; } static void substituteDestruct(subInfo *psubInfo) { + ENTER; freeSubFile(psubInfo); freePattern(psubInfo); free(psubInfo); - return; + EXIT; } -static void substituteOpen(subInfo **ppvt,char *substitutionName) +static void substituteOpen(subInfo **ppvt, char *substitutionName) { subInfo *psubInfo; subFile *psubFile; FILE *fp; - psubInfo = calloc(1,sizeof(subInfo)); + ENTER; + psubInfo = calloc(1, sizeof(subInfo)); *ppvt = psubInfo; - psubFile = calloc(1,sizeof(subFile)); + psubFile = calloc(1, sizeof(subFile)); psubInfo->psubFile = psubFile; ellInit(&psubInfo->patternList); - fp = fopen(substitutionName,"r"); - if(!fp) { - fprintf(stderr,"msi: Can't open file '%s'\n",substitutionName); + + fp = fopen(substitutionName, "r"); + if (!fp) { + fprintf(stderr, "msi: Can't open file '%s'\n", substitutionName); abortExit(1); } + psubFile->substitutionName = substitutionName; psubFile->fp = fp; psubFile->lineNum = 1; psubFile->inputBuffer[0] = 0; psubFile->pnextChar = &psubFile->inputBuffer[0]; subGetNextToken(psubFile); - return; + EXIT; } static int substituteGetGlobalSet(subInfo *psubInfo) { - subFile *psubFile = psubInfo->psubFile; + subFile *psubFile = psubInfo->psubFile; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenString && strcmp(psubFile->string,"global")==0) { + ENTER; + while (psubFile->token == tokenSeparator) subGetNextToken(psubFile); - return(1); + + if (psubFile->token == tokenString && + strcmp(psubFile->string, "global") == 0) { + subGetNextToken(psubFile); + EXITD(1); + return 1; } - return(0); + + EXITD(0); + return 0; } static int substituteGetNextSet(subInfo *psubInfo,char **filename) @@ -631,34 +749,59 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename) subFile *psubFile = psubInfo->psubFile; patternNode *ppatternNode; + ENTER; *filename = 0; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenEOF) return(0); - if(psubFile->token==tokenString && strcmp(psubFile->string,"file")==0) { + while (psubFile->token == tokenSeparator) + subGetNextToken(psubFile); + + if (psubFile->token == tokenEOF) { + EXITD(0); + return 0; + } + + if (psubFile->token == tokenString && + strcmp(psubFile->string, "file") == 0) { + size_t len; + + STEP("Parsed 'file'"); psubInfo->isFile = 1; - if(subGetNextToken(psubFile)!=tokenString) { - subFileErrPrint(psubFile,"Parse error, expecting filename"); + if (subGetNextToken(psubFile) != tokenString) { + subFileErrPrint(psubFile, "Parse error, expecting a filename"); abortExit(1); } + freePattern(psubInfo); free(psubInfo->filename); - if(psubFile->string[0]=='"'&&psubFile->string[strlen(psubFile->string)-1]=='"') { - psubFile->string[strlen(psubFile->string)-1]='\0'; - psubInfo->filename = macEnvExpand(psubFile->string+1); + + len = strlen(psubFile->string); + if (psubFile->string[0] == '"' && + psubFile->string[len - 1] == '"') { + psubFile->string[len - 1] = '\0'; + psubInfo->filename = macEnvExpand(psubFile->string + 1); } - else { + else psubInfo->filename = macEnvExpand(psubFile->string); - } - while(subGetNextToken(psubFile)==tokenSeparater); - if(psubFile->token!=tokenLBrace) { - subFileErrPrint(psubFile,"Parse error, expecting {"); + STEPS("Parsed filename", psubInfo->filename); + + while (subGetNextToken(psubFile) == tokenSeparator); + + if (psubFile->token != tokenLBrace) { + subFileErrPrint(psubFile, "Parse error, expecting '{'"); abortExit(1); } + STEP("Parsed '{'"); subGetNextToken(psubFile); } *filename = psubInfo->filename; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenLBrace) return(1); + + while (psubFile->token == tokenSeparator) + subGetNextToken(psubFile); + + if (psubFile->token == tokenLBrace) { + EXITD(1); + return 1; + } + if (psubFile->token == tokenRBrace) { subFileErrPrint(psubFile, "Parse error, unexpected '}'"); abortExit(1); @@ -669,58 +812,84 @@ static int substituteGetNextSet(subInfo *psubInfo,char **filename) subFileErrPrint(psubFile, "Parse error, expecting 'pattern'"); abortExit(1); } + + STEP("Parsed 'pattern'"); freePattern(psubInfo); psubInfo->isPattern = 1; - while(subGetNextToken(psubFile)==tokenSeparater); - if(psubFile->token!=tokenLBrace) { - subFileErrPrint(psubFile,"Parse error, expecting {"); + + while (subGetNextToken(psubFile) == tokenSeparator); + + if (psubFile->token != tokenLBrace) { + subFileErrPrint(psubFile, "Parse error, expecting '{'"); abortExit(1); } - while(1) { - while(subGetNextToken(psubFile)==tokenSeparater); - if(psubFile->token!=tokenString) break; - ppatternNode = calloc(1,sizeof(patternNode)); - ellAdd(&psubInfo->patternList,&ppatternNode->node); + STEP("Parsed '{'"); + + while (1) { + while (subGetNextToken(psubFile) == tokenSeparator); + + if (psubFile->token != tokenString) + break; + + ppatternNode = calloc(1, sizeof(patternNode)); + ellAdd(&psubInfo->patternList, &ppatternNode->node); ppatternNode->var = epicsStrDup(psubFile->string); } - if(psubFile->token!=tokenRBrace) { - subFileErrPrint(psubFile,"Parse error, expecting }"); + + if (psubFile->token != tokenRBrace) { + subFileErrPrint(psubFile, "Parse error, expecting '}'"); abortExit(1); } + subGetNextToken(psubFile); - return(1); + EXITD(1); + return 1; } static char *substituteGetGlobalReplacements(subInfo *psubInfo) { subFile *psubFile = psubInfo->psubFile; - if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0; + ENTER; + if (psubInfo->macroReplacements) + psubInfo->macroReplacements[0] = 0; psubInfo->curLength = 0; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenRBrace && psubInfo->isFile) { + + while (psubFile->token == tokenSeparator) + subGetNextToken(psubFile); + + if (psubFile->token == tokenRBrace && psubInfo->isFile) { psubInfo->isFile = 0; free(psubInfo->filename); psubInfo->filename = 0; freePattern(psubInfo); subGetNextToken(psubFile); - return(0); + EXITD(0); + return 0; } - if(psubFile->token==tokenEOF) return(0); - if(psubFile->token!=tokenLBrace) return(0); - while(1) { + + if (psubFile->token == tokenEOF) { + EXITD(0); + return 0; + } + if (psubFile->token != tokenLBrace) { + EXITD(0); + return 0; + } + + while (1) { switch(subGetNextToken(psubFile)) { case tokenRBrace: subGetNextToken(psubFile); - if (!psubInfo->macroReplacements) { - catMacroReplacements(psubInfo,""); - } - return(psubInfo->macroReplacements); - case tokenSeparater: - catMacroReplacements(psubInfo,","); + EXITS(psubInfo->macroReplacements); + return psubInfo->macroReplacements; + + case tokenSeparator: + catMacroReplacements(psubInfo, ","); break; + case tokenString: - catMacroReplacements(psubInfo,psubFile->string); + catMacroReplacements(psubInfo, psubFile->string); break; case tokenLBrace: @@ -738,58 +907,81 @@ static char *substituteGetReplacements(subInfo *psubInfo) subFile *psubFile = psubInfo->psubFile; patternNode *ppatternNode; - if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0; + ENTER; + if (psubInfo->macroReplacements) + psubInfo->macroReplacements[0] = 0; psubInfo->curLength = 0; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenRBrace && psubInfo->isFile) { + + while (psubFile->token == tokenSeparator) + subGetNextToken(psubFile); + + if (psubFile->token==tokenRBrace && psubInfo->isFile) { psubInfo->isFile = 0; free(psubInfo->filename); psubInfo->filename = 0; freePattern(psubInfo); subGetNextToken(psubFile); - return(0); + EXITD(0); + return 0; } - if(psubFile->token==tokenEOF) return(0); - if(psubFile->token!=tokenLBrace) return(0); - if(psubInfo->isPattern) { + + if (psubFile->token == tokenEOF) { + EXITD(0); + return 0; + } + + if (psubFile->token != tokenLBrace) { + EXITD(0); + return 0; + } + + if (psubInfo->isPattern) { int gotFirstPattern = 0; - while(subGetNextToken(psubFile)==tokenSeparater); - ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList); - while(1) { - if(psubFile->token==tokenRBrace) { + while (subGetNextToken(psubFile) == tokenSeparator); + ppatternNode = (patternNode *) ellFirst(&psubInfo->patternList); + while (1) { + if (psubFile->token == tokenRBrace) { subGetNextToken(psubFile); - return(psubInfo->macroReplacements); + EXITS(psubInfo->macroReplacements); + return psubInfo->macroReplacements; } - if(psubFile->token!=tokenString) { - subFileErrPrint(psubFile,"Parse error, illegal token"); + + if (psubFile->token != tokenString) { + subFileErrPrint(psubFile,"Parse error, expecting macro value"); abortExit(1); } - if(gotFirstPattern) catMacroReplacements(psubInfo,","); + + if (gotFirstPattern) + catMacroReplacements(psubInfo, ","); gotFirstPattern = 1; - if(ppatternNode) { - catMacroReplacements(psubInfo,ppatternNode->var); - catMacroReplacements(psubInfo,"="); - catMacroReplacements(psubInfo,psubFile->string); - ppatternNode = (patternNode *)ellNext(&ppatternNode->node); - } else { - subFileErrPrint(psubFile,"Warning, too many values given"); + + if (ppatternNode) { + catMacroReplacements(psubInfo, ppatternNode->var); + catMacroReplacements(psubInfo, "="); + catMacroReplacements(psubInfo, psubFile->string); + ppatternNode = (patternNode *) ellNext(&ppatternNode->node); } - while(subGetNextToken(psubFile)==tokenSeparater); + else { + subFileErrPrint(psubFile, "Warning, too many values given"); + } + + while (subGetNextToken(psubFile) == tokenSeparator); } - } else while(1) { + } + else while(1) { switch(subGetNextToken(psubFile)) { case tokenRBrace: subGetNextToken(psubFile); - if (!psubInfo->macroReplacements) { - catMacroReplacements(psubInfo,""); - } - return(psubInfo->macroReplacements); - case tokenSeparater: - catMacroReplacements(psubInfo,","); + EXITS(psubInfo->macroReplacements); + return psubInfo->macroReplacements; + + case tokenSeparator: + catMacroReplacements(psubInfo, ","); break; + case tokenString: - catMacroReplacements(psubInfo,psubFile->string); + catMacroReplacements(psubInfo, psubFile->string); break; case tokenLBrace: @@ -806,69 +998,84 @@ static char *subGetNextLine(subFile *psubFile) { char *pline; + ENTER; do { - pline = fgets(psubFile->inputBuffer,MAX_BUFFER_SIZE,psubFile->fp); + pline = fgets(psubFile->inputBuffer, MAX_BUFFER_SIZE, psubFile->fp); ++psubFile->lineNum; - } while(pline && psubFile->inputBuffer[0]=='#'); - if(!pline) { + } while (pline && psubFile->inputBuffer[0] == '#'); + + if (!pline) { psubFile->token = tokenEOF; psubFile->inputBuffer[0] = 0; psubFile->pnextChar = 0; - return(0); + EXITD(0); + return 0; } + psubFile->pnextChar = &psubFile->inputBuffer[0]; - return(&psubFile->inputBuffer[0]); + EXITS(&psubFile->inputBuffer[0]); + return &psubFile->inputBuffer[0]; } static void subFileErrPrint(subFile *psubFile,char * message) { - fprintf(stderr,"msi: %s\n",message); - fprintf(stderr," in substitution file '%s' at line %d:\n %s", - psubFile->substitutionName, - psubFile->lineNum,psubFile->inputBuffer); + fprintf(stderr, "msi: %s\n",message); + fprintf(stderr, " in substitution file '%s' at line %d:\n %s", + psubFile->substitutionName, psubFile->lineNum, psubFile->inputBuffer); } static tokenType subGetNextToken(subFile *psubFile) { - char *p; - char *pto; + char *p, *pto; + ENTER; p = psubFile->pnextChar; - if(!p) { psubFile->token = tokenEOF; return(tokenEOF);} - if(*p==0 || *p=='\n' || *p=='#') { - p = subGetNextLine(psubFile); - if(!p) { psubFile->token = tokenEOF; return(tokenEOF);} - else { psubFile->token = tokenSeparater; return(tokenSeparater);} + if (!p) { + STEP("Got EOF"); + psubFile->token = tokenEOF; + goto done; } - while(isspace((int) *p)) p++; - if(*p=='{') { + + if (*p == 0 || *p == '\n' || *p == '#') { + STEP("Got newline/comment"); + p = subGetNextLine(psubFile); + psubFile->token = p ? tokenSeparator : tokenEOF; + goto done; + } + + while (isspace((int) *p)) p++; + if (*p == '{') { + STEP("Got '{'"); psubFile->token = tokenLBrace; psubFile->pnextChar = ++p; - return(tokenLBrace); + goto done; } - if(*p=='}') { + if (*p == '}') { + STEP("Got '}'"); psubFile->token = tokenRBrace; psubFile->pnextChar = ++p; - return(tokenRBrace); + goto done; } - if(*p==0 || isspace((int) *p) || *p==',') { - while (isspace((int) *p) || *p==',') p++; - psubFile->token = tokenSeparater; + if (*p == 0 || isspace((int) *p) || *p == ',') { + STEP("Got space/comma"); + while (isspace((int) *p) || *p == ',') p++; + psubFile->token = tokenSeparator; psubFile->pnextChar = p; - return(tokenSeparater); + goto done; } /*now handle quoted strings*/ - if(*p=='"') { + if (*p == '"') { + STEP("Got '\"'"); pto = &psubFile->string[0]; *pto++ = *p++; - while(*p!='"') { - if(*p==0 || *p=='\n') { - subFileErrPrint(psubFile,"Strings must be on single line\n"); + while (*p != '"') { + if (*p == 0 || *p == '\n') { + subFileErrPrint(psubFile, "Strings must be on single line\n"); abortExit(1); } - /*allow escape for imbeded quote*/ - if((*p=='\\') && *(p+1)=='"') { + /*allow escape for embeded quote*/ + if ((p[0] == '\\') && p[1] == '"') { *pto++ = *p++; *pto++ = *p++; continue; @@ -879,40 +1086,53 @@ static tokenType subGetNextToken(subFile *psubFile) psubFile->pnextChar = p; *pto = 0; psubFile->token = tokenString; - return(tokenString); + goto done; } + /*Now take anything up to next non String token and not space*/ pto = &psubFile->string[0]; - while(!isspace((int) *p) && (strspn(p,"\",{}")==0)) *pto++ = *p++; + + while (!isspace((int) *p) && (strspn(p, "\",{}") == 0)) + *pto++ = *p++; *pto = 0; + STEPS("Got bareword", psubFile->string); + psubFile->pnextChar = p; psubFile->token = tokenString; - return(tokenString); + +done: + EXITD(psubFile->token); + return psubFile->token; } -static void catMacroReplacements(subInfo *psubInfo,const char *value) +static void catMacroReplacements(subInfo *psubInfo, const char *value) { - size_t len = strlen(value); + size_t len = strlen(value); - if(psubInfo->size <= (psubInfo->curLength + len)) { + ENTER; + if (psubInfo->size <= (psubInfo->curLength + len)) { size_t newsize = psubInfo->size + MAX_BUFFER_SIZE; char *newbuf; - if(newsize <= psubInfo->curLength + len) + STEP("Enlarging buffer"); + if (newsize <= psubInfo->curLength + len) newsize = psubInfo->curLength + len + 1; - newbuf = calloc(1,newsize); - if(!newbuf) { - fprintf(stderr,"calloc failed for size %lu\n", - (unsigned long) newsize); + newbuf = calloc(1, newsize); + if (!newbuf) { + fprintf(stderr, "calloc failed for size %lu\n", + (unsigned long) newsize); abortExit(1); } - if(psubInfo->macroReplacements) { - memcpy(newbuf,psubInfo->macroReplacements,psubInfo->curLength); + if (psubInfo->macroReplacements) { + memcpy(newbuf, psubInfo->macroReplacements, psubInfo->curLength); free(psubInfo->macroReplacements); } psubInfo->size = newsize; psubInfo->macroReplacements = newbuf; } - strcat(psubInfo->macroReplacements,value); + + STEPS("Appending", value); + strcat(psubInfo->macroReplacements, value); psubInfo->curLength += len; + EXIT; }