/** * Implementation file for the exe buffer buffer handling system. * * copyright: see file COPYRIGHT * * More information in exe.tex * * Mark Koennecke, November 2004 */ #include #include #include #include "lld_str.h" #include "fortify.h" #include "sics.h" #include "exebuf.h" #include "dynstring.h" #include "exebuf.i" #include "status.h" /*-----------------------------------------------------------------------*/ pExeBuf exeBufCreate(char *name){ pExeBuf pNew = NULL; pNew = (pExeBuf)malloc(sizeof(ExeBuf)); if(pNew == NULL){ return NULL; } memset(pNew,0,sizeof(ExeBuf)); pNew->name = strdup(name); pNew->bufferContent = CreateDynString(1024,1024); if(!pNew->bufferContent){ return NULL; } return pNew; } /*----------------------------------------------------------------------*/ void exeBufKill(void *data){ exeBufDelete((pExeBuf)data); } /*-----------------------------------------------------------------------*/ void exeBufDelete(pExeBuf self){ if(self == NULL){ return; } if(self->name != NULL){ free(self->name); self->name = NULL; } if(self->bufferContent != NULL){ DeleteDynString(self->bufferContent); self->bufferContent = NULL; } free(self); } /*----------------------------------------------------------------------*/ int exeBufAppend(pExeBuf self, char *line){ int status; assert(self); status = DynStringConcat(self->bufferContent,line); if(strrchr(line,(int)'\n') == NULL){ DynStringConcatChar(self->bufferContent,'\n'); } return status; } /*-----------------------------------------------------------------------*/ static char *locateName(char *filename){ char *pPtr; int i; pPtr = filename + strlen(filename) -1; for(i = strlen(filename) -1; i > 0; i--,pPtr--){ if(*pPtr == '/'){ pPtr++; return pPtr; } } return filename; } /*-----------------------------------------------------------------------*/ int exeBufLoad(pExeBuf self, char *filename){ char line[256]; FILE *fd = NULL; int status; assert(self); fd = fopen(filename,"r"); if(fd == NULL){ return 0; } while(fgets(line,255,fd) != NULL){ status = exeBufAppend(self,line); if(status != 1){ fclose(fd); return 0; } } fclose(fd); if(self->name != NULL){ free(self->name); } self->name = strdup(locateName(filename)); return 1; } /*----------------------------------------------------------------------*/ int exeBufSave(pExeBuf self, char *filename){ FILE *fd = NULL; fd = fopen(filename,"w"); if(fd == NULL){ return 0; } fputs(GetCharArray(self->bufferContent),fd); fclose(fd); self->name = strdup(locateName(filename)); return 1; } /*================ process batch buffer ==============================*/ static pDynString findBlockEnd(pExeBuf self){ pDynString command = NULL; char *buffer = NULL; int i; assert(self); command = CreateDynString(80,80); if(command == NULL){ return NULL; } buffer = GetCharArray(self->bufferContent); if(self->end != -1){ self->start = self->end + 1; } for(i = self->start; i < strlen(buffer); i++){ DynStringConcatChar(command,buffer[i]); if(buffer[i] == '\n'){ self->lineno++; if(Tcl_CommandComplete(GetCharArray(command))){ self->end = i; return command; } } } DeleteDynString(command); return NULL; } /*---------------------------------------------------------------------*/ int exeBufProcess(pExeBuf self, SicsInterp *pSics, SConnection *pCon, pICallBack pCall, int echo){ pDynString command = NULL; Tcl_Interp *pTcl = NULL; int status; static int weWantLogging = 1; char *cmd; char cmdName[128]; char *ende; int l; assert(self); assert(pSics); self->start = 0; self->end = -1; self->lineno = 0; pTcl = InterpGetTcl(pSics); if(pCall != NULL){ InvokeCallBack(pCall,BATCHSTART,self->name); } if (echo) { SCsetMacro(pCon,0); } while((command = findBlockEnd(self)) != NULL){ if(pCall != NULL){ InvokeCallBack(pCall,BATCHAREA,NULL); } cmd = GetCharArray(command); if (echo) { /* find first word */ while (*cmd == ' ') { cmd++; } ende = cmd; while (*ende > ' ') { ende++; } l = ende - cmd; if (l < sizeof cmdName) { strncpy(cmdName, cmd, l); cmdName[l] = '\0'; if (FindCommand(pSics, cmdName) != NULL) { /* print only SICS commands */ SCPrintf(pCon, eValue, "%s:%d>> %s",self->name,self->lineno,cmd); } } } status = Tcl_Eval(pTcl,cmd); if(status != TCL_OK){ if(pCon->sicsError == 0){ /* Tcl Error */ if(strlen(pTcl->result) >= 2){ SCWrite(pCon,pTcl->result,eError); } SCWrite(pCon,"ERROR: Tcl error in block:",eError); SCWrite(pCon,GetCharArray(command),eError); SCWrite(pCon,"ERROR: end of Tcl error block",eError); } else { /* SICS error: has already been reported */ pCon->sicsError = 0; } } DeleteDynString(command); if(SCGetInterrupt(pCon) >= eAbortBatch){ SCWrite(pCon,"ERROR: batch processing interrupted",eError); SetStatus(eEager); return 0; } else { SCSetInterrupt(pCon,eContinue); } } if(pCall != NULL){ InvokeCallBack(pCall,BATCHEND,self->name); } return 1; } /*---------------------------------------------------------------------*/ int exeBufProcessErrList(pExeBuf self, SicsInterp *pSics, SConnection *pCon, int errList){ pDynString command = NULL; Tcl_Interp *pTcl = NULL; int status; static int weWantLogging = 1; char *cmd; char cmdName[128]; char *error; char msg[132]; char *ende; int l; assert(self); assert(pSics); self->start = 0; self->end = -1; self->lineno = 0; pTcl = InterpGetTcl(pSics); while((command = findBlockEnd(self)) != NULL){ cmd = GetCharArray(command); status = Tcl_Eval(pTcl,cmd); if(status != TCL_OK){ LLDstringAppend(errList,cmd); error = (char *)Tcl_GetStringResult(pTcl); snprintf(msg, sizeof msg, "#ERR: %s\n", error); LLDstringAppend(errList,msg); } DeleteDynString(command); if(SCGetInterrupt(pCon) >= eAbortBatch){ SCWrite(pCon,"ERROR: batch processing interrupted",eError); SetStatus(eEager); return 0; } else { SCSetInterrupt(pCon,eContinue); } } return 1; } /*------------------------------------------------------------------------*/ void exeBufRange(pExeBuf self, int *start, int *end, int *lineno){ assert(self); *start = self->start; *end = self->end; *lineno = self->lineno; } /*------------------------------------------------------------------------*/ pDynString exeBufText(pExeBuf self, int start, int end){ pDynString result = NULL; char *pPtr; int i; assert(self); result = CreateDynString(256,132); if(result == NULL){ return NULL; } pPtr = GetCharArray(self->bufferContent); if(end >= strlen(pPtr)){ end = strlen(pPtr) -1; } for(i = start; i < end; i++){ DynStringConcatChar(result,pPtr[i]); } return result; } /*-----------------------------------------------------------------------*/ char *exeBufName(pExeBuf self){ assert(self); return self->name; }