diff --git a/SCinter.h b/SCinter.h index fd126154..33147ac8 100644 --- a/SCinter.h +++ b/SCinter.h @@ -145,7 +145,7 @@ char *FindAliases(SicsInterp * pSics, char *name); /*------------------------------------------------------------------------- FindCommandData finds a command with the name given. It tests the name in the ObjectDescriptor to be of name class. If all this succeeds a pointer - to the commands data structure is retuned. Else NULL. + to the commands data structure is returned. Else NULL. Do not test the Object Descriptor name when comclass == NULL. */ void *FindCommandData(SicsInterp * pSics, char *name, char *comclass); diff --git a/countersec.c b/countersec.c index a555eead..103d06b6 100644 --- a/countersec.c +++ b/countersec.c @@ -401,12 +401,21 @@ static int CountCmd(pSICSOBJ ccmd, SConnection * con, Hdb * cmdNode, Hdb * par[], int nPar) { float preset; + pHdb presetNode = NULL; if(nPar < 1){ - return 0; + presetNode = GetHipadabaNode(ccmd->objectNode,"preset"); + if(presetNode != NULL){ + preset = presetNode->value.v.doubleValue; + } else { + /* + This can really only happen when the counter is corrupt + */ + assert(0); + } + } else { + preset = par[0]->value.v.doubleValue; } - - preset = par[0]->value.v.doubleValue; return DoCount((pCounter)ccmd, preset, con, 1); } /*--------------------------------------------------------------------------*/ @@ -414,12 +423,21 @@ static int CountNBCmd(pSICSOBJ ccmd, SConnection * con, Hdb * cmdNode, Hdb * par[], int nPar) { float preset; + pHdb presetNode = NULL; if(nPar < 1){ - return 0; + presetNode = GetHipadabaNode(ccmd->objectNode,"preset"); + if(presetNode != NULL){ + preset = presetNode->value.v.doubleValue; + } else { + /* + This can really only happen when the counter is corrupt + */ + assert(0); + } + } else { + preset = par[0]->value.v.doubleValue; } - - preset = par[0]->value.v.doubleValue; return DoCount((pCounter)ccmd, preset, con, 0); } /*--------------------------------------------------------------------------*/ diff --git a/devexec.c b/devexec.c index 32b19835..7979d9eb 100644 --- a/devexec.c +++ b/devexec.c @@ -711,7 +711,7 @@ int SicsIdle(SConnection * pCon, SicsInterp * pSics, void *pData, int Success(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) { - int iRet, level; + int iRet, level = RUNRUN; Status eOld; pExeList self = (pExeList)pData; @@ -722,8 +722,6 @@ int Success(SConnection * pCon, SicsInterp * pSics, void *pData, if(strcmp(argv[1],"RUNDRIVE") == 0){ level = RUNDRIVE; } - } else { - level = RUNRUN; } if(level == RUNRUN) { diff --git a/exebuf.c b/exebuf.c index e5ae6c56..0ec9d5ce 100644 --- a/exebuf.c +++ b/exebuf.c @@ -91,13 +91,39 @@ static char *locateName(char *filename) } return filename; } +/*---------------------------------------------------------------------- + If this is MOUNTAINBATCH file, replace ocurrences of @nl@ with \n +------------------------------------------------------------------------*/ +static void fixMountainBatch(pExeBuf self) +{ + char *pPtr, *pData, *pNL; + pPtr = GetCharArray(self->bufferContent); + if(strstr(pPtr, "#MOUNTAINBATCH") != pPtr){ + /* + nothing to do + */ + return; + } + pData = strdup(pPtr); + DynStringClear(self->bufferContent); + pPtr = pData; + while((pNL = strstr(pPtr,"@nl@")) != NULL){ + *pNL = '\n'; + *(pNL+1) = '\0'; + DynStringConcat(self->bufferContent, pPtr); + pPtr = pNL +4; + } + DynStringConcat(self->bufferContent,pPtr); + free(pData); + +} /*-----------------------------------------------------------------------*/ int exeBufLoad(pExeBuf self, char *filename) { char line[256], *pPtr; FILE *fd = NULL; - int status, idx; + int status, idx, gtsebatch = 0; assert(self); fd = fopen(filename, "r"); @@ -128,6 +154,7 @@ int exeBufLoad(pExeBuf self, char *filename) free(self->name); } self->name = strdup(locateName(filename)); + fixMountainBatch(self); return 1; } diff --git a/histmem.c b/histmem.c index 8b31114a..4e92896c 100644 --- a/histmem.c +++ b/histmem.c @@ -1329,10 +1329,6 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData, } } else if (strcmp(argv[1], "init") == 0) { - if (GetStatus() != eEager) { - SCWrite(pCon, "ERROR: cannot initialize HM while running", eError); - return 0; - } if (SCMatchRights(pCon, usMugger)) { iRet = HistConfigure(self, pCon, pSics); if (iRet) { diff --git a/histmemsec.c b/histmemsec.c index ae1a6d82..86078ec3 100644 --- a/histmemsec.c +++ b/histmemsec.c @@ -203,7 +203,7 @@ static int SumCmd(pSICSOBJ ccmd, SConnection * pCon, { pHdb dimNode = NULL, dataNode = NULL; int xstart, xend, ystart, yend, i; - long lSum; + long lSum = 0; dimNode = GetHipadabaNode(ccmd->objectNode,"dim"); dataNode = GetHipadabaNode(ccmd->objectNode,"data"); @@ -325,6 +325,15 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData, if(pRes == NULL){ return 0; } + /* + remove count and rename countnb to it + */ + node = GetHipadabaNode(pRes->pDes->parNode,"count"); + DeleteHipadabaNode(node,NULL); + node = GetHipadabaNode(pRes->pDes->parNode,"countnb"); + strcpy(node->name,"count"); + + pRes->pCountInt->TransferData = HMCtrTransferData; node = pRes->objectNode; diff --git a/hmdata.c b/hmdata.c index 97fa5ec6..5584d910 100644 --- a/hmdata.c +++ b/hmdata.c @@ -536,7 +536,7 @@ static pNXDS hmDataToNXDataset(pHMdata self) if (isInTOFMode(self)) { result->rank++; } - result->dim = malloc(self->rank * sizeof(int)); + result->dim = malloc(self->rank * sizeof(int64_t)); if (result->dim == NULL) { free(result); return NULL; diff --git a/motorsec.c b/motorsec.c index bc2d79f5..c17efa8f 100644 --- a/motorsec.c +++ b/motorsec.c @@ -713,6 +713,7 @@ pMotor SecMotorInit(char *name) child = MakeHipadabaNode("sign", HIPFLOAT, 1); SetHdbProperty(child, "__save", "true"); + SetHdbProperty(child, "priv", "user"); AddHipadabaChild(node, child, NULL); AppendHipadabaCallback(child, MakeHipadabaCallback(SecMotorSignCallback, pM, @@ -721,6 +722,7 @@ pMotor SecMotorInit(char *name) child = MakeHipadabaNode("softzero", HIPFLOAT, 1); SetHdbProperty(child, "__save", "true"); + SetHdbProperty(child, "priv", "user"); AddHipadabaChild(node, child, NULL); AppendHipadabaCallback(child, MakeHipadabaCallback(SecMotorZeroCallback, pM, @@ -835,6 +837,8 @@ static void SecMotorKill(void *data) free(self->pDrivInt); } + RemoveHdbNodeFromParent(self->objectNode,NULL); + if (self->pCall) { DeleteCallBackInterface(self->pCall); } diff --git a/sicshdbadapter.c b/sicshdbadapter.c index a56b4d89..c7357f9a 100644 --- a/sicshdbadapter.c +++ b/sicshdbadapter.c @@ -910,10 +910,13 @@ int HdbSubSample(SConnection * pCon, SicsInterp * pSics, void *pData, { pHistMem pHM = NULL; pHdb node = NULL; - int bank = 0, length = -1, status; + int bank = 0, length = -1, status, i; HistInt *data = NULL; char *pPtr = NULL; + char error[132]; hdbValue v; + HMdata hdata; + pHdb hmnode = NULL; if (argc < 4) { SCWrite(pCon, @@ -928,23 +931,61 @@ int HdbSubSample(SConnection * pCon, SicsInterp * pSics, void *pData, pPtr++; sscanf(pPtr, "%d", &bank); } - pHM = (pHistMem) FindCommandData(pSics, argv[1], "HistMem"); node = FindHdbNode(NULL, argv[2], pCon); - if (pHM == NULL || node == NULL) { - SCWrite(pCon, "ERROR: either histogram memory or node not found!", - eError); + if (node == NULL) { + SCWrite(pCon, "ERROR: node not found!", + eError); return 0; } - if (pHM->pDriv->SubSample == NULL) { - SCWrite(pCon, "ERROR: hm does not support subsampling", eError); - return 0; - } - data = pHM->pDriv->SubSample(pHM->pDriv, pCon, bank, argv[3]); - if (data == NULL) { - SCWrite(pCon, "ERROR: sub sampling failed", eError); + /* + old HM + */ + pHM = (pHistMem) FindCommandData(pSics, argv[1], "HistMem"); + if(pHM != NULL){ + + if (pHM->pDriv->SubSample == NULL) { + SCWrite(pCon, "ERROR: hm does not support subsampling", eError); + return 0; + } + data = pHM->pDriv->SubSample(pHM->pDriv, pCon, bank, argv[3]); + if (data == NULL) { + SCWrite(pCon, "ERROR: sub sampling failed", eError); + return 0; + } + } + /* + new HM + */ + pHM = (pHistMem) FindCommandData(pSics, argv[1], "HistMemSec"); + if(pHM != NULL){ + memset(&hdata,0,sizeof(HMdata)); + hmnode = GetHipadabaNode(pHM->pDes->parNode,"dim"); + if(hmnode == NULL){ + SCWrite(pCon,"ERROR: dim node not found",eError); + return 0; + } + hdata.rank = hmnode->value.arrayLength; + for(i = 0; i < hdata.rank; i++){ + hdata.iDim[i] = hmnode->value.v.intArray[i]; + } + hmnode = GetHipadabaNode(pHM->pDes->parNode,"data"); + if(hmnode == NULL){ + SCWrite(pCon,"ERROR: data node not found",eError); + return 0; + } + hdata.localBuffer = hmnode->value.v.intArray; + data = subSample(&hdata, argv[3], error, sizeof(error)); + if(data == NULL){ + SCPrintf(pCon,eError,"ERROR: %s while processing %s with %s", + error, argv[1], argv[3]); + return 0; + } + } else { + SCPrintf(pCon,eError,"ERROR: hm %s not found", argv[1]); return 0; } + v.dataType = HIPINTVARAR; v.arrayLength = data[0]; diff --git a/sicshipadaba.c b/sicshipadaba.c index 8f2ae5ca..3ff2fe93 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -2392,6 +2392,8 @@ static int SetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData, pDynString parData = NULL; char error[512], value[132]; int i, status, priv; + pIDrivable pDriv = NULL; + pDummy data = NULL; if (argc < 3) { @@ -2415,6 +2417,25 @@ static int SetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } + /** + * special code to handle certain types of motors right + **/ + status = GetHdbProperty(targetNode,"sicsdev",value,sizeof(value)); + if(status == 1){ + data = (pDummy)FindCommandData(pSics,value,NULL); + if(data != NULL){ + pDriv = GetDrivableInterface(data); + if(pDriv != NULL){ + status = StartDevice(pServ->pExecutor,value, data->pDescriptor, + data, pCon,RUNRUN, atof(argv[2])); + if(status == 1){ + SCSendOK(pCon); + } + return status; + } + } + } + if (!cloneHdbValue(&targetNode->value, &newValue)) { SCWrite(pCon, "ERROR: out of memory cloning node", eError); @@ -3848,6 +3869,63 @@ static int AddCheck(SConnection * pCon, SicsInterp * pSics, return 1; } +/*---------------------------------------------------------------------------*/ +static hdbCallbackReturn SICSNotifyScriptCallback(pHdb node, void *userData, + pHdbMessage message) +{ + char *pPath = NULL; + int macro, status; + pHdbDataMessage mm = NULL; + SConnection *tstCon; + char script[256]; + + /* + * Deal with update messages + */ + if ((mm = GetHdbUpdateMessage(message)) == NULL) { + return hdbContinue; + } + status = GetHdbProperty(node, "updatescript", script, sizeof(script)); + if(status == 0){ + tracePar(node->name,"ERROR: did not find updatescript property"); + return hdbContinue; + } + + copyHdbValue(mm->v, &node->value); + status = Tcl_Eval(InterpGetTcl(pServ->pSics), script); + if (status != TCL_OK) { + tracePar(node->name,"ERROR: %s while evaluating updatescript %s", + Tcl_GetStringResult(InterpGetTcl(pServ->pSics)), script); + } + + return hdbContinue; +} +/*---------------------------------------------------------------------------*/ +static int AddScriptNotify(SConnection * pCon, SicsInterp * pSics, + void *pData, int argc, char *argv[]) +{ + pHdb node = NULL; + + if(argc < 3) { + SCWrite(pCon,"ERROR: Parameter missing, Usage: hscriptnotify node script", + eError); + return 0; + } + + node = FindHdbNode(NULL,argv[1],pCon); + if (node == NULL) { + SCPrintf(pCon,eLogError, "ERROR: node %s to add script update not found", + argv[1]); + return 0; + } + + SetHdbProperty(node,"updatescript",strdup(argv[2])); + AppendHipadabaCallback(node,MakeHipadabaCallback(SICSNotifyScriptCallback, + NULL,NULL)); + SCSendOK(pCon); + + return 1; +} /*======================= Factory Functions =================================*/ void killSICSHipadaba() { @@ -3891,6 +3969,7 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics, AddCommand(pSics, "hlistprop", ListSICSHdbProperty, NULL, NULL); AddCommand(pSics, "hcallnotify",CallNotify, NULL, NULL); AddCommand(pSics, "haddcheck",AddCheck, NULL, NULL); + AddCommand(pSics, "hscriptnotify",AddScriptNotify, NULL, NULL); InstallSICSPoll(pCon, pSics, pData, argc, argv); poller = (pSicsPoll) FindCommandData(pSics, "sicspoll", "SicsPoll"); diff --git a/syncedprot.c b/syncedprot.c index 3bafff40..7d6a87b2 100644 --- a/syncedprot.c +++ b/syncedprot.c @@ -9,7 +9,7 @@ * * This is a scriptcontext driver 'connecting' to its own sics server. * The argument of the send command is a sync id. - * The next script of the scriptchain is called when all actions realted to + * The next script of the scriptchain is called when all actions related to * this sync id are finished or on timeout. * * In addition the functions needed to implement other mechanisms than scriptcontext to diff --git a/test/sicsstat.tcl b/test/sicsstat.tcl index 009ec577..e90b0067 100644 --- a/test/sicsstat.tcl +++ b/test/sicsstat.tcl @@ -6,7 +6,7 @@ exe syspath ./ #--- BEGIN (commands producing errors on last restore) #--- END (commands producing errors on last restore) -lotte UNKNOWN +lotte bloerzx lotte setAccess 2 # Motor brumm brumm sign 1.000000 @@ -46,12 +46,6 @@ lieselotte SetMode Timer # Counter multi multi SetPreset 0.000000 multi SetMode Timer -sicsdatapath ./ -sicsdatapath setAccess 1 -sicsdataprefix regression -sicsdataprefix setAccess 1 -sicsdatapostfix .dat -sicsdatapostfix setAccess 1 # Motor a1 a1 sign 1.000000 a1 SoftZero 0.000000 @@ -283,7 +277,3 @@ eva ignorefault 0 eva movecount 10 eva staticoffset 0 - - - - diff --git a/test/testini.tcl b/test/testini.tcl index 3f35ee2b..a108083f 100644 --- a/test/testini.tcl +++ b/test/testini.tcl @@ -213,6 +213,12 @@ hfactory /target plain spy none hfactory /target/ta3 plain internal float hattach target a3 /target/ta3 +proc upsctest {} { + broadcast "An update script has been called" + set txt [hval /instrument/title] + broadcast "Update to $txt" +} + restore #================================================== @@ -834,7 +840,7 @@ if {$secmot == 1} { } -set zwickroll 1 +set zwickroll 0 if {$zwickroll == 1} { source ../tcl/zwickroll.tcl diff --git a/testprot.c b/testprot.c index 7707c8f7..91c9a2fc 100644 --- a/testprot.c +++ b/testprot.c @@ -108,6 +108,16 @@ static void findResponse(Ascon *a) DynStringConcat(a->errmsg,GetCharArray(a->wrBuffer)); return; } + /** + Tclescape is an escape string/character which idetifies a response as a tcl invocation. + Thus the algorithm runs: + * Find out if there is a Tcl escape + * If so: + * Is the tslcescape in the response + * If so: + * Invoke the Tcl function for the response + In all other cases the response is passed on unmodified. + **/ status = StringDictGet(dict,"tclescape",tclEscape,sizeof(tclEscape)); if(status == 1){ test = strstr(response, tclEscape);