Add MSI 1.7 to any Base 3.14 dependency
- add test for patch being applied - fixes #20
This commit is contained in:
817
add-msi-to-314.patch
Normal file
817
add-msi-to-314.patch
Normal file
@@ -0,0 +1,817 @@
|
||||
diff -ruN ../3.14/src/dbtools/Makefile ./src/dbtools/Makefile
|
||||
--- ../3.14/src/dbtools/Makefile 2017-03-16 21:37:51.278140900 +0100
|
||||
+++ ./src/dbtools/Makefile 2020-04-06 12:40:51.723550846 +0200
|
||||
@@ -11,6 +11,11 @@
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
+PROD_HOST += msi
|
||||
+
|
||||
+msi_SRCS = msi.c
|
||||
+msi_LIBS += Com
|
||||
+
|
||||
INC += dbLoadTemplate.h
|
||||
INC += dbtoolsIocRegister.h
|
||||
|
||||
diff -ruN ../3.14/src/dbtools/msi.c ./src/dbtools/msi.c
|
||||
--- ../3.14/src/dbtools/msi.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ ./src/dbtools/msi.c 2013-05-13 19:00:43.000000000 +0200
|
||||
@@ -0,0 +1,798 @@
|
||||
+/*************************************************************************\
|
||||
+* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
+* National Laboratory.
|
||||
+* Copyright (c) 2002 The Regents of the University of California, as
|
||||
+* Operator of Los Alamos National Laboratory.
|
||||
+* This file is distributed subject to a Software License Agreement found
|
||||
+* in the file LICENSE that is included with this distribution.
|
||||
+\*************************************************************************/
|
||||
+/*msi - macro sunstitutions and include */
|
||||
+
|
||||
+/*
|
||||
+ * Modification Log:
|
||||
+ * -----------------
|
||||
+ * .01 08DEC97 mrk Original version
|
||||
+ */
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <stddef.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include <epicsVersion.h>
|
||||
+#include <dbDefs.h>
|
||||
+#include <macLib.h>
|
||||
+#include <ellLib.h>
|
||||
+#include <errlog.h>
|
||||
+
|
||||
+#define MAX_BUFFER_SIZE 4096
|
||||
+
|
||||
+#if ((EPICS_VERSION <= 3) && (EPICS_REVISION <= 13))
|
||||
+#define macEnvExpand(x) strdup(x)
|
||||
+#endif
|
||||
+
|
||||
+/*Forward references to local routines*/
|
||||
+static void usageExit(void);
|
||||
+static void addMacroReplacements(MAC_HANDLE *macPvt,char *pval);
|
||||
+static void makeSubstitutions(void *inputPvt,void *macPvt,char *templateName);
|
||||
+
|
||||
+/*Routines that read the template files */
|
||||
+static void inputConstruct(void **inputPvt);
|
||||
+static void inputDestruct(void *inputPvt);
|
||||
+static void inputAddPath(void *inputPvt, char *pval);
|
||||
+static void inputBegin(void *inputPvt,char *fileName);
|
||||
+static char *inputNextLine(void *inputPvt);
|
||||
+static void inputNewIncludeFile(void *inputPvt,char *name);
|
||||
+static void inputErrPrint(void *inputPvt);
|
||||
+
|
||||
+/*Routines that read the substitution file */
|
||||
+static void substituteDestruct(void *substitutePvt);
|
||||
+static void substituteOpen(void **substitutePvt,char *substitutionName);
|
||||
+static int substituteGetNextSet(void *substitutePvt,char **filename);
|
||||
+static char *substituteGetReplacements(void *substitutePvt);
|
||||
+
|
||||
+/*Exit status*/
|
||||
+static int exitStatus = 0;
|
||||
+
|
||||
+int opt_V = 0;
|
||||
+
|
||||
+
|
||||
+int main(int argc,char **argv)
|
||||
+{
|
||||
+ void *inputPvt;
|
||||
+ MAC_HANDLE *macPvt;
|
||||
+ char *pval;
|
||||
+ int narg;
|
||||
+ char *substitutionName=0;
|
||||
+ char *templateName=0;
|
||||
+ int i;
|
||||
+
|
||||
+ inputConstruct(&inputPvt);
|
||||
+ macCreateHandle(&macPvt,0);
|
||||
+ macSuppressWarning(macPvt,1);
|
||||
+ 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(strncmp(argv[1],"-o",2)==0) {
|
||||
+ if(freopen(pval,"w",stdout)==NULL) {
|
||||
+ fprintf(stderr,"Can't open %s for writing: %s\n", pval, strerror(errno));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ } else if(strncmp(argv[1],"-M",2)==0) {
|
||||
+ addMacroReplacements(macPvt,pval);
|
||||
+ } else if(strncmp(argv[1],"-S",2)==0) {
|
||||
+ substitutionName = calloc(strlen(pval)+1,sizeof(char));
|
||||
+ strcpy(substitutionName,pval);
|
||||
+ } else if(strncmp(argv[1],"-V",2)==0) {
|
||||
+ macSuppressWarning(macPvt,0);
|
||||
+ opt_V = 1;
|
||||
+ narg = 1; /* no argument for this option */
|
||||
+ } else {
|
||||
+ usageExit();
|
||||
+ }
|
||||
+ argc -= narg;
|
||||
+ for(i=1; i<argc; i++) argv[i] = argv[i + narg];
|
||||
+ }
|
||||
+ if(argc>2) {
|
||||
+ fprintf(stderr,"too many filename arguments\n");
|
||||
+ usageExit();
|
||||
+ }
|
||||
+ if(argc==2) {
|
||||
+ templateName = calloc(strlen(argv[1])+1,sizeof(char));
|
||||
+ strcpy(templateName,argv[1]);
|
||||
+ }
|
||||
+ if(!substitutionName) {
|
||||
+ makeSubstitutions(inputPvt,macPvt,templateName);
|
||||
+ } else {
|
||||
+ void *substitutePvt;
|
||||
+ char *filename = 0;
|
||||
+
|
||||
+ substituteOpen(&substitutePvt,substitutionName);
|
||||
+ while(substituteGetNextSet(substitutePvt,&filename)) {
|
||||
+ if(templateName) filename = templateName;
|
||||
+ if(!filename) {
|
||||
+ fprintf(stderr,"no template file\n");
|
||||
+ usageExit();
|
||||
+ }
|
||||
+ macPushScope(macPvt);
|
||||
+ while((pval = substituteGetReplacements(substitutePvt))){
|
||||
+ addMacroReplacements(macPvt,pval);
|
||||
+ makeSubstitutions(inputPvt,macPvt,filename);
|
||||
+ }
|
||||
+ macPopScope(macPvt);
|
||||
+ }
|
||||
+ substituteDestruct(substitutePvt);
|
||||
+ }
|
||||
+ errlogFlush();
|
||||
+ inputDestruct(inputPvt);
|
||||
+ free((void *)templateName);
|
||||
+ free((void *)substitutionName);
|
||||
+ return(exitStatus);
|
||||
+}
|
||||
+
|
||||
+void usageExit(void)
|
||||
+{
|
||||
+ fprintf(stderr,"usage: msi -V -opath -Ipath ... -Msub ... -Ssubfile template\n");
|
||||
+ fprintf(stderr," Specifying path will replace the default '.'\n");
|
||||
+ fprintf(stderr," stdin is used if template is not given\n");
|
||||
+ exit(1);
|
||||
+}
|
||||
+
|
||||
+static void addMacroReplacements(MAC_HANDLE *macPvt,char *pval)
|
||||
+{
|
||||
+ char **pairs;
|
||||
+ long status;
|
||||
+
|
||||
+ status = macParseDefns(macPvt,pval,&pairs);
|
||||
+ if(!status) {
|
||||
+ fprintf(stderr,"Error macParseDefns error\n");
|
||||
+ usageExit();
|
||||
+ }
|
||||
+ status = macInstallMacros(macPvt,pairs);
|
||||
+ if(!status) {
|
||||
+ fprintf(stderr,"Error macInstallMacros error\n");
|
||||
+ usageExit();
|
||||
+ }
|
||||
+ free((void *)pairs);
|
||||
+}
|
||||
+
|
||||
+typedef enum {cmdInclude,cmdSubstitute} cmdType;
|
||||
+static const char *cmdNames[] = {"include","substitute"};
|
||||
+static void makeSubstitutions(void *inputPvt,void *macPvt,char *templateName)
|
||||
+{
|
||||
+ char *input;
|
||||
+ static char buffer[MAX_BUFFER_SIZE];
|
||||
+ int n;
|
||||
+ static int unexpWarned = 0;
|
||||
+
|
||||
+ inputBegin(inputPvt,templateName);
|
||||
+ while((input = inputNextLine(inputPvt))) {
|
||||
+ int expand=1;
|
||||
+ char *p;
|
||||
+ char *command = 0;
|
||||
+
|
||||
+ p = input;
|
||||
+ /*skip whitespace at beginning of line*/
|
||||
+ while(*p && (isspace(*p))) ++p;
|
||||
+ /*Look for i or s */
|
||||
+ 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])) {
|
||||
+ cmdind = i;
|
||||
+ }
|
||||
+ }
|
||||
+ if(cmdind<0) goto endif;
|
||||
+ p = command + strlen(cmdNames[cmdind]);
|
||||
+ /*skip whitespace after command*/
|
||||
+ while(*p && (isspace(*p))) ++p;
|
||||
+ /*Next character must be quote*/
|
||||
+ if((*p==0) || (*p!='"')) goto endif;
|
||||
+ 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;
|
||||
+ }
|
||||
+ ++p;
|
||||
+ }
|
||||
+ pend = p;
|
||||
+ if(*p==0) goto endif;
|
||||
+ /*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);
|
||||
+ switch(cmdind) {
|
||||
+ case cmdInclude:
|
||||
+ inputNewIncludeFile(inputPvt,copy);
|
||||
+ break;
|
||||
+ case cmdSubstitute:
|
||||
+ addMacroReplacements(macPvt,copy);
|
||||
+ break;
|
||||
+ default:
|
||||
+ fprintf(stderr,"Logic Error: makeSubstitutions\n");
|
||||
+ inputErrPrint(inputPvt);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ free(copy);
|
||||
+ expand = 0;
|
||||
+ }
|
||||
+endif:
|
||||
+ if (expand) {
|
||||
+ n = macExpandString(macPvt,input,buffer,MAX_BUFFER_SIZE-1);
|
||||
+ fputs(buffer,stdout);
|
||||
+ if (!unexpWarned && n<0) {
|
||||
+ const char * pErrMsg = "Warning: Undefined macros present, use msi -V to list\n";
|
||||
+ if ( opt_V ) {
|
||||
+ exitStatus = 2;
|
||||
+ pErrMsg = "Error: Undefined macros present\n";
|
||||
+ }
|
||||
+ fprintf( stderr, pErrMsg );
|
||||
+ unexpWarned++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+typedef struct inputFile{
|
||||
+ ELLNODE node;
|
||||
+ char *filename;
|
||||
+ FILE *fp;
|
||||
+ int lineNum;
|
||||
+}inputFile;
|
||||
+
|
||||
+typedef struct pathNode {
|
||||
+ ELLNODE node;
|
||||
+ char *directory;
|
||||
+} pathNode;
|
||||
+
|
||||
+typedef struct inputData {
|
||||
+ ELLLIST inputFileList;
|
||||
+ ELLLIST pathList;
|
||||
+ char inputBuffer[MAX_BUFFER_SIZE];
|
||||
+}inputData;
|
||||
+
|
||||
+static void inputOpenFile(inputData *pinputData,char *filename);
|
||||
+static void inputCloseFile(inputData *pinputData);
|
||||
+static void inputCloseAllFiles(inputData *pinputData);
|
||||
+
|
||||
+static void inputConstruct(void **ppvt)
|
||||
+{
|
||||
+ inputData *pinputData;
|
||||
+
|
||||
+ pinputData = calloc(1,sizeof(inputData));
|
||||
+ ellInit(&pinputData->inputFileList);
|
||||
+ ellInit(&pinputData->pathList);
|
||||
+ *ppvt = pinputData;
|
||||
+}
|
||||
+
|
||||
+static void inputDestruct(void *pvt)
|
||||
+{
|
||||
+ inputData *pinputData = (inputData *)pvt;
|
||||
+ pathNode *ppathNode;
|
||||
+
|
||||
+ inputCloseAllFiles(pinputData);
|
||||
+ while((ppathNode = (pathNode *)ellFirst(&pinputData->pathList))) {
|
||||
+ ellDelete(&pinputData->pathList,&ppathNode->node);
|
||||
+ free((void *)ppathNode->directory);
|
||||
+ free((void *)ppathNode);
|
||||
+ }
|
||||
+ free(pvt);
|
||||
+}
|
||||
+
|
||||
+static void inputAddPath(void *pvt, char *path)
|
||||
+{
|
||||
+ inputData *pinputData = (inputData *)pvt;
|
||||
+ ELLLIST *ppathList = &pinputData->pathList;
|
||||
+ pathNode *ppathNode;
|
||||
+ const char *pcolon;
|
||||
+ const char *pdir;
|
||||
+ int len;
|
||||
+ int emptyName;
|
||||
+
|
||||
+ pdir = path;
|
||||
+ /*an empty name at beginning, middle, or end means current directory*/
|
||||
+ while(pdir && *pdir) {
|
||||
+ emptyName = ((*pdir == ':') ? 1 : 0);
|
||||
+ if(emptyName) ++pdir;
|
||||
+ ppathNode = (pathNode *)calloc(1,sizeof(pathNode));
|
||||
+ ellAdd(ppathList,&ppathNode->node);
|
||||
+ if(!emptyName) {
|
||||
+ pcolon = strchr(pdir,':');
|
||||
+ len = (pcolon ? (pcolon - pdir) : strlen(pdir));
|
||||
+ 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(emptyName) {
|
||||
+ ppathNode->directory = (char *)calloc(2,sizeof(char));
|
||||
+ strcpy(ppathNode->directory,".");
|
||||
+ }
|
||||
+ }
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void inputBegin(void *pvt,char *fileName)
|
||||
+{
|
||||
+ inputData *pinputData = (inputData *)pvt;
|
||||
+
|
||||
+ inputCloseAllFiles(pinputData);
|
||||
+ inputOpenFile(pinputData,fileName);
|
||||
+}
|
||||
+
|
||||
+static char *inputNextLine(void *pvt)
|
||||
+{
|
||||
+ inputData *pinputData = (inputData *)pvt;
|
||||
+ inputFile *pinputFile;
|
||||
+ char *pline;
|
||||
+
|
||||
+ while((pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList))) {
|
||||
+ pline = fgets(pinputData->inputBuffer,MAX_BUFFER_SIZE,pinputFile->fp);
|
||||
+ if(pline) {
|
||||
+ ++pinputFile->lineNum;
|
||||
+ return(pline);
|
||||
+ }
|
||||
+ inputCloseFile(pinputData);
|
||||
+ }
|
||||
+ return(0);
|
||||
+}
|
||||
+
|
||||
+static void inputNewIncludeFile(void *pvt,char *name)
|
||||
+{
|
||||
+ inputData *pinputData = (inputData *)pvt;
|
||||
+
|
||||
+ inputOpenFile(pinputData,name);
|
||||
+}
|
||||
+
|
||||
+static void inputErrPrint(void *pvt)
|
||||
+{
|
||||
+ inputData *pinputData = (inputData *)pvt;
|
||||
+ inputFile *pinputFile;
|
||||
+
|
||||
+ fprintf(stderr,"input: %s which is ",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");
|
||||
+ }
|
||||
+ pinputFile = (inputFile *)ellNext(&pinputFile->node);
|
||||
+ if(pinputFile) {
|
||||
+ fprintf(stderr," which is included from ");
|
||||
+ } else {
|
||||
+ fprintf(stderr,"\n");
|
||||
+ }
|
||||
+ }
|
||||
+ fprintf(stderr,"\n");
|
||||
+}
|
||||
+
|
||||
+static void inputOpenFile(inputData *pinputData,char *filename)
|
||||
+{
|
||||
+ ELLLIST *ppathList = &pinputData->pathList;
|
||||
+ pathNode *ppathNode = 0;
|
||||
+ inputFile *pinputFile;
|
||||
+ char *fullname = 0;
|
||||
+ FILE *fp = 0;
|
||||
+
|
||||
+ if(!filename) {
|
||||
+ 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,
|
||||
+ sizeof(char));
|
||||
+ strcpy(fullname,ppathNode->directory);
|
||||
+ strcat(fullname,"/");
|
||||
+ strcat(fullname,filename);
|
||||
+ fp = fopen(fullname,"r");
|
||||
+ if(fp) break;
|
||||
+ free((void *)fullname);
|
||||
+ ppathNode = (pathNode *)ellNext(&ppathNode->node);
|
||||
+ }
|
||||
+ }
|
||||
+ if(!fp) {
|
||||
+ fprintf(stderr,"Could not open %s\n",filename);
|
||||
+ inputErrPrint((void *)pinputData);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ pinputFile = calloc(1,sizeof(inputFile));
|
||||
+ if(ppathNode) {
|
||||
+ pinputFile->filename = calloc(1,strlen(fullname)+1);
|
||||
+ strcpy(pinputFile->filename,fullname);
|
||||
+ free((void *)fullname);
|
||||
+ } else if(filename) {
|
||||
+ pinputFile->filename = calloc(1,strlen(filename)+1);
|
||||
+ strcpy(pinputFile->filename,filename);
|
||||
+ } else {
|
||||
+ pinputFile->filename = calloc(1,strlen("stdin")+1);
|
||||
+ strcpy(pinputFile->filename,"stdin");
|
||||
+ }
|
||||
+ pinputFile->fp = fp;
|
||||
+ ellInsert(&pinputData->inputFileList,0,&pinputFile->node);
|
||||
+}
|
||||
+
|
||||
+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,"fclose failed: file %s\n",pinputFile->filename);
|
||||
+ free(pinputFile->filename);
|
||||
+ free(pinputFile);
|
||||
+}
|
||||
+
|
||||
+static void inputCloseAllFiles(inputData *pinputData)
|
||||
+{
|
||||
+ inputFile *pinputFile;
|
||||
+
|
||||
+ while((pinputFile=(inputFile *)ellFirst(&pinputData->inputFileList))){
|
||||
+ inputCloseFile(pinputData);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*start of code that handles substitution file*/
|
||||
+typedef enum {
|
||||
+ tokenLBrace,tokenRBrace,tokenSeparater,tokenString,tokenEOF
|
||||
+}tokenType;
|
||||
+
|
||||
+typedef struct subFile {
|
||||
+ char *substitutionName;
|
||||
+ FILE *fp;
|
||||
+ int lineNum;
|
||||
+ char inputBuffer[MAX_BUFFER_SIZE];
|
||||
+ char *pnextChar;
|
||||
+ tokenType token;
|
||||
+ char string[MAX_BUFFER_SIZE];
|
||||
+} subFile;
|
||||
+
|
||||
+typedef struct patternNode {
|
||||
+ ELLNODE node;
|
||||
+ char *var;
|
||||
+}patternNode;
|
||||
+
|
||||
+typedef struct subInfo {
|
||||
+ subFile *psubFile;
|
||||
+ int isFile;
|
||||
+ char *filename;
|
||||
+ int isPattern;
|
||||
+ ELLLIST patternList;
|
||||
+ size_t size;
|
||||
+ size_t curLength;
|
||||
+ char *macroReplacements;
|
||||
+}subInfo;
|
||||
+
|
||||
+static char *subGetNextLine(subFile *psubFile);
|
||||
+static tokenType subGetNextToken(subFile *psubFile);
|
||||
+static void subFileErrPrint(subFile *psubFile,char * message);
|
||||
+static void freeSubFile(subInfo *psubInfo);
|
||||
+static void freePattern(subInfo *psubInfo);
|
||||
+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,"fclose failed on substitution file\n");
|
||||
+ }
|
||||
+ free((void *)psubFile);
|
||||
+ free((void *)psubInfo->filename);
|
||||
+ psubInfo->psubFile = 0;
|
||||
+}
|
||||
+
|
||||
+void freePattern(subInfo *psubInfo)
|
||||
+{
|
||||
+ patternNode *ppatternNode;
|
||||
+ while((ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList))) {
|
||||
+ ellDelete(&psubInfo->patternList,&ppatternNode->node);
|
||||
+ free(ppatternNode->var);
|
||||
+ free(ppatternNode);
|
||||
+ }
|
||||
+ psubInfo->isPattern = 0;
|
||||
+}
|
||||
+
|
||||
+static void substituteDestruct(void *pvt)
|
||||
+{
|
||||
+ subInfo *psubInfo = (subInfo *)pvt;
|
||||
+
|
||||
+ freeSubFile(psubInfo);
|
||||
+ freePattern(psubInfo);
|
||||
+ free((void *)psubInfo);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void substituteOpen(void **ppvt,char *substitutionName)
|
||||
+{
|
||||
+ subInfo *psubInfo;
|
||||
+ subFile *psubFile;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ psubInfo = calloc(1,sizeof(subInfo));
|
||||
+ *ppvt = (void *)psubInfo;
|
||||
+ psubFile = calloc(1,sizeof(subFile));
|
||||
+ psubInfo->psubFile = psubFile;
|
||||
+ ellInit(&psubInfo->patternList);
|
||||
+ fp = fopen(substitutionName,"r");
|
||||
+ if(!fp) {
|
||||
+ fprintf(stderr,"Could not open %s\n",substitutionName);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ psubFile->substitutionName = substitutionName;
|
||||
+ psubFile->fp = fp;
|
||||
+ psubFile->lineNum = 0;
|
||||
+ psubFile->inputBuffer[0] = 0;
|
||||
+ psubFile->pnextChar = &psubFile->inputBuffer[0];
|
||||
+ subGetNextToken(psubFile);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static int substituteGetNextSet(void *pvt,char **filename)
|
||||
+{
|
||||
+ subInfo *psubInfo = (subInfo *)pvt;
|
||||
+ subFile *psubFile = psubInfo->psubFile;
|
||||
+ patternNode *ppatternNode;
|
||||
+
|
||||
+ *filename = 0;
|
||||
+ while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
|
||||
+ if(psubFile->token==tokenEOF) return(0);
|
||||
+ if(psubFile->token==tokenString && strcmp(psubFile->string,"file")==0) {
|
||||
+ psubInfo->isFile = 1;
|
||||
+ if(subGetNextToken(psubFile)!=tokenString) {
|
||||
+ subFileErrPrint(psubFile,"Expecting filename");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ freePattern(psubInfo);
|
||||
+ free((void *)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);
|
||||
+ }
|
||||
+ else {
|
||||
+ psubInfo->filename = macEnvExpand(psubFile->string);
|
||||
+ }
|
||||
+ while(subGetNextToken(psubFile)==tokenSeparater);
|
||||
+ if(psubFile->token!=tokenLBrace) {
|
||||
+ subFileErrPrint(psubFile,"Expecting {");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ subGetNextToken(psubFile);
|
||||
+ }
|
||||
+ *filename = psubInfo->filename;
|
||||
+ while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
|
||||
+ if(psubFile->token==tokenLBrace) return(1);
|
||||
+ if(psubFile->token==tokenRBrace) return(0);
|
||||
+ if(psubFile->token!=tokenString
|
||||
+ || strcmp(psubFile->string,"pattern")!=0) {
|
||||
+ subFileErrPrint(psubFile,"Expecting pattern");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ freePattern(psubInfo);
|
||||
+ psubInfo->isPattern = 1;
|
||||
+ while(subGetNextToken(psubFile)==tokenSeparater);
|
||||
+ if(psubFile->token!=tokenLBrace) {
|
||||
+ subFileErrPrint(psubFile,"Expecting {");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ while(1) {
|
||||
+ while(subGetNextToken(psubFile)==tokenSeparater);
|
||||
+ if(psubFile->token!=tokenString) break;
|
||||
+ ppatternNode = calloc(1,sizeof(patternNode));
|
||||
+ ellAdd(&psubInfo->patternList,&ppatternNode->node);
|
||||
+ ppatternNode->var = calloc(strlen(psubFile->string)+1,sizeof(char));
|
||||
+ strcpy(ppatternNode->var,psubFile->string);
|
||||
+ }
|
||||
+ if(psubFile->token!=tokenRBrace) {
|
||||
+ subFileErrPrint(psubFile,"Expecting }");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ subGetNextToken(psubFile);
|
||||
+ return(1);
|
||||
+}
|
||||
+
|
||||
+static char *substituteGetReplacements(void *pvt)
|
||||
+{
|
||||
+ subInfo *psubInfo = (subInfo *)pvt;
|
||||
+ subFile *psubFile = psubInfo->psubFile;
|
||||
+ patternNode *ppatternNode;
|
||||
+
|
||||
+ if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0;
|
||||
+ psubInfo->curLength = 0;
|
||||
+ while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
|
||||
+ if(psubFile->token==tokenRBrace && psubInfo->isFile) {
|
||||
+ psubInfo->isFile = 0;
|
||||
+ free((void *)psubInfo->filename);
|
||||
+ psubInfo->filename = 0;
|
||||
+ freePattern(psubInfo);
|
||||
+ subGetNextToken(psubFile);
|
||||
+ return(0);
|
||||
+ }
|
||||
+ if(psubFile->token==tokenEOF) return(0);
|
||||
+ if(psubFile->token!=tokenLBrace) return(0);
|
||||
+ if(psubInfo->isPattern) {
|
||||
+ int gotFirstPattern = 0;
|
||||
+
|
||||
+ while(subGetNextToken(psubFile)==tokenSeparater);
|
||||
+ ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList);
|
||||
+ while(1) {
|
||||
+ if(psubFile->token==tokenRBrace) {
|
||||
+ if(ppatternNode)
|
||||
+ subFileErrPrint(psubFile,"less values than patterns");
|
||||
+ subGetNextToken(psubFile);
|
||||
+ return(psubInfo->macroReplacements);
|
||||
+ }
|
||||
+ if(psubFile->token!=tokenString) {
|
||||
+ subFileErrPrint(psubFile,"Illegal token");
|
||||
+ exit(-1);
|
||||
+ }
|
||||
+ 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,"more values than patterns");
|
||||
+ }
|
||||
+ while(subGetNextToken(psubFile)==tokenSeparater);
|
||||
+ }
|
||||
+ } else while(1) {
|
||||
+ switch(subGetNextToken(psubFile)) {
|
||||
+ case tokenRBrace:
|
||||
+ subGetNextToken(psubFile);
|
||||
+ return(psubInfo->macroReplacements);
|
||||
+ case tokenSeparater:
|
||||
+ catMacroReplacements(psubInfo,",");
|
||||
+ break;
|
||||
+ case tokenString:
|
||||
+ catMacroReplacements(psubInfo,psubFile->string);
|
||||
+ break;
|
||||
+ default:
|
||||
+ subFileErrPrint(psubFile,"Illegal token");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static char *subGetNextLine(subFile *psubFile)
|
||||
+{
|
||||
+ char *pline;
|
||||
+
|
||||
+ pline = fgets(psubFile->inputBuffer,MAX_BUFFER_SIZE,psubFile->fp);
|
||||
+ ++psubFile->lineNum;
|
||||
+ while(pline && psubFile->inputBuffer[0]=='#') {
|
||||
+ pline = fgets(psubFile->inputBuffer,MAX_BUFFER_SIZE,psubFile->fp);
|
||||
+ ++psubFile->lineNum;
|
||||
+ }
|
||||
+ if(!pline) {
|
||||
+ psubFile->token = tokenEOF;
|
||||
+ psubFile->inputBuffer[0] = 0;
|
||||
+ psubFile->pnextChar = 0;
|
||||
+ return(0);
|
||||
+ }
|
||||
+ psubFile->pnextChar = &psubFile->inputBuffer[0];
|
||||
+ return(&psubFile->inputBuffer[0]);
|
||||
+}
|
||||
+
|
||||
+static void subFileErrPrint(subFile *psubFile,char * message)
|
||||
+{
|
||||
+ fprintf(stderr,"substitution file %s line %d: %s",
|
||||
+ psubFile->substitutionName,
|
||||
+ psubFile->lineNum,psubFile->inputBuffer);
|
||||
+ fprintf(stderr,"%s\n",message);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static tokenType subGetNextToken(subFile *psubFile)
|
||||
+{
|
||||
+ char *p;
|
||||
+ char *pto;
|
||||
+
|
||||
+ 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);}
|
||||
+ }
|
||||
+ while(isspace(*p)) p++;
|
||||
+ if(*p=='{') {
|
||||
+ psubFile->token = tokenLBrace;
|
||||
+ psubFile->pnextChar = ++p;
|
||||
+ return(tokenLBrace);
|
||||
+ }
|
||||
+ if(*p=='}') {
|
||||
+ psubFile->token = tokenRBrace;
|
||||
+ psubFile->pnextChar = ++p;
|
||||
+ return(tokenRBrace);
|
||||
+ }
|
||||
+ if(*p==0 || isspace(*p) || *p==',') {
|
||||
+ while(isspace(*p) || *p==',') p++;
|
||||
+ psubFile->token = tokenSeparater;
|
||||
+ psubFile->pnextChar = p;
|
||||
+ return(tokenSeparater);
|
||||
+ }
|
||||
+ /*now handle quoted strings*/
|
||||
+ if(*p=='"') {
|
||||
+ pto = &psubFile->string[0];
|
||||
+ *pto++ = *p++;
|
||||
+ while(*p!='"') {
|
||||
+ if(*p==0 || *p=='\n') {
|
||||
+ subFileErrPrint(psubFile,"Strings must be on single line\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ /*allow escape for imbeded quote*/
|
||||
+ if((*p=='\\') && *(p+1)=='"') {
|
||||
+ *pto++ = *p++;
|
||||
+ *pto++ = *p++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ *pto++ = *p++;
|
||||
+ }
|
||||
+ *pto++ = *p++;
|
||||
+ psubFile->pnextChar = p;
|
||||
+ *pto = 0;
|
||||
+ psubFile->token = tokenString;
|
||||
+ return(tokenString);
|
||||
+ }
|
||||
+ /*Now take anything up to next non String token and not space*/
|
||||
+ pto = &psubFile->string[0];
|
||||
+ while(!isspace(*p) && (strspn(p,"\",{}")==0)) *pto++ = *p++;
|
||||
+ *pto = 0;
|
||||
+ psubFile->pnextChar = p;
|
||||
+ psubFile->token = tokenString;
|
||||
+ return(tokenString);
|
||||
+}
|
||||
+
|
||||
+static void catMacroReplacements(subInfo *psubInfo,const char *value)
|
||||
+{
|
||||
+ size_t len = strlen(value);
|
||||
+
|
||||
+ if(psubInfo->size <= (psubInfo->curLength + len)) {
|
||||
+ size_t newsize = psubInfo->size + MAX_BUFFER_SIZE;
|
||||
+ char *newbuf;
|
||||
+
|
||||
+ if(newsize <= psubInfo->curLength + len)
|
||||
+ newsize = psubInfo->curLength + len + 1;
|
||||
+ newbuf = calloc(1,newsize);
|
||||
+ if(!newbuf) {
|
||||
+ fprintf(stderr,"calloc failed for size %Zu\n",newsize);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ if(psubInfo->macroReplacements) {
|
||||
+ memcpy(newbuf,psubInfo->macroReplacements,psubInfo->curLength);
|
||||
+ free(psubInfo->macroReplacements);
|
||||
+ }
|
||||
+ psubInfo->size = newsize;
|
||||
+ psubInfo->macroReplacements = newbuf;
|
||||
+ }
|
||||
+ strcat(psubInfo->macroReplacements,value);
|
||||
+ psubInfo->curLength += len;
|
||||
+}
|
||||
@@ -188,6 +188,13 @@ BUILT=$(cat "$location/built")
|
||||
[ "$do_recompile" ] || die "do_recompile flag was not set for outdated dependency"
|
||||
echo "$modules_to_compile" | grep -q "$location" || die "Outdated dependency was not set to compile"
|
||||
|
||||
# msi is automatically added to 3.14
|
||||
rm -fr $location; modules_to_compile=
|
||||
location=$CACHEDIR/base-R3.14.12.1
|
||||
rm -fr $location;
|
||||
add_dependency BASE R3.14.12.1
|
||||
[ -e $location/src/dbtools/msi.c ] || die "MSI was not added to Base 3.14"
|
||||
|
||||
rm -fr $CACHEDIR/*; modules_to_compile=
|
||||
|
||||
# missing inclusion of RELEASE.local in configure/RELEASE
|
||||
|
||||
@@ -178,9 +178,17 @@ add_dependency() {
|
||||
git clone --quiet $deptharg $recurse --branch "$TAG" $repourl $dirname-$TAG
|
||||
( cd $dirname-$TAG && git log -n1 )
|
||||
do_recompile=yes
|
||||
# fix non-base modules that do not include the .local files in configure/RELEASE
|
||||
if [ $DEP != "BASE" ]
|
||||
# add MSI to Base 3.14
|
||||
if [ $DEP == "BASE" ]
|
||||
then
|
||||
versionfile=$CACHEDIR/$dirname-$TAG/configure/CONFIG_BASE_VERSION
|
||||
if [ -e ${versionfile} ] && grep -q "BASE_3_14=YES" ${versionfile}
|
||||
then
|
||||
echo "Adding MSI 1.7 to $CACHEDIR/$dirname-$TAG"
|
||||
( cd $dirname-$TAG; patch -p0 < $curdir/add-msi-to-314.patch )
|
||||
fi
|
||||
else
|
||||
# fix non-base modules that do not include the .local files in configure/RELEASE
|
||||
release=$CACHEDIR/$dirname-$TAG/configure/RELEASE
|
||||
if [ -e $release ]
|
||||
then
|
||||
|
||||
Reference in New Issue
Block a user