From dc857084517289df2976a15e9607e1bf3136513d Mon Sep 17 00:00:00 2001 From: koennecke Date: Thu, 19 Dec 2013 10:24:54 +0000 Subject: [PATCH] - Added a AsconReadDoneReconnect to ascon. This handles the case better when a server hangs up diretcly after a message. - Some output was suppressed while tracing, fixed - Make ready to compile both with Ubuntu 32 and 64 or /usr/local based ON in general. Just in psi/makefile_linux the top include has to be adapted - Removed epics drivers from SICS. Still in source to be reenabled when needed - Added FindMotor - Added sput, sappend and slab to nxscript using the new sicsget module - Fix to sget to fix the "mot softzero" problem SKIPPED: psi/make_gen psi/psi.c psi/sinqhttpopt.c psi/spss7.c --- ascon.c | 5 + ascon.i | 29 +-- confvirtualmot.c | 5 +- conman.c | 14 +- counter.c | 19 +- devser.c | 2 +- devser.h | 7 + doc/manager/nxscript.htm | 19 ++ hipadaba.h | 2 +- histmemsec.c | 2 + linux_def | 2 +- make_gen | 3 +- makefile_linux | 2 +- motor.c | 10 +- motorsec.c | 32 +++- mumoconf.c | 22 --- nxdict.c | 2 +- nxscript.c | 393 ++++++++++++++++++++++++++++++++++++++- sicsget.c | 2 +- tasub.c | 18 +- test/testini.tcl | 3 +- 21 files changed, 514 insertions(+), 79 deletions(-) diff --git a/ascon.c b/ascon.c index f8d364e6..095eb536 100644 --- a/ascon.c +++ b/ascon.c @@ -765,6 +765,11 @@ AsconStatus AsconTask(Ascon * a) a->responseValid = 1; DynStringClear(a->errmsg); return AsconReady; + case AsconReadDoneReconnect: + a->responseValid = 1; + DynStringClear(a->errmsg); + AsconReconnect(a,NULL); + return AsconReady; case AsconIdle: return AsconReady; case AsconTimeout: diff --git a/ascon.i b/ascon.i index 2c510287..9cadeb95 100644 --- a/ascon.i +++ b/ascon.i @@ -25,20 +25,21 @@ * The state of the connection. */ typedef enum { - AsconNotConnected, /**< unconnected, not to be connected automatically */ - AsconConnectStart, /**< after initialisation or after AsconFailed */ - AsconConnecting, /**< after AsconConnectStart or AsconConnecting */ - AsconConnectDone, /**< after AsconConnecting */ - AsconWriteStart, /**< set by the AsconWrite function */ - AsconWriting, /**< after AsconWriteStart or AsconWriting */ - AsconWriteDone, /**< after AsconWriting */ - AsconReadStart, /**< after AsconWriteDone */ - AsconReading, /**< after AsconReadStart or AsconReading */ - AsconReadDone, /**< after AsconReading */ - AsconIdle, /**< after AsconWriteDone, AsconReadDone, AsconTimeout, AsconIdle */ - AsconFailed, /**< after any state */ - AsconTimeout, /**< after AsconReading */ - AsconMaxState /**< number of states */ + AsconNotConnected, /**< unconnected, not to be connected automatically */ + AsconConnectStart, /**< after initialisation or after AsconFailed */ + AsconConnecting, /**< after AsconConnectStart or AsconConnecting */ + AsconConnectDone, /**< after AsconConnecting */ + AsconWriteStart, /**< set by the AsconWrite function */ + AsconWriting, /**< after AsconWriteStart or AsconWriting */ + AsconWriteDone, /**< after AsconWriting */ + AsconReadStart, /**< after AsconWriteDone */ + AsconReading, /**< after AsconReadStart or AsconReading */ + AsconReadDone, /**< after AsconReading */ + AsconReadDoneReconnect, /**< after AsconReading, read success, but need to reconnect */ + AsconIdle, /**< after AsconWriteDone, AsconReadDone, AsconTimeout, AsconIdle */ + AsconFailed, /**< after any state */ + AsconTimeout, /**< after AsconReading */ + AsconMaxState /**< number of states */ } AsconState; /** \brief the task handler function prototype diff --git a/confvirtualmot.c b/confvirtualmot.c index 6215a6ad..0ac738d4 100644 --- a/confvirtualmot.c +++ b/confvirtualmot.c @@ -295,12 +295,13 @@ static int InterestCallback(int iEvent, void *pEvent, void *pUser) assert(pEvent); assert(pUser); + pEventData = (EventInfo *) pEvent; + pInfo = (RegisteredInfo *) pUser; + if (!SCisConnected(pInfo->pCon)) { return -1; } - pEventData = (EventInfo *) pEvent; - pInfo = (RegisteredInfo *) pUser; if (pInfo->lastValue != pEventData->fVal) { pInfo->lastValue = pEventData->fVal; diff --git a/conman.c b/conman.c index 198f2e75..e1f9f626 100644 --- a/conman.c +++ b/conman.c @@ -597,7 +597,17 @@ int TelnetWriteANET(int sockHandle, char *pBuffer) } return iRet; } - +/*------------------------------------------------------------------------*/ +static int mustWrite(int iOut) +{ + switch(iOut) { + case eLog: + case eLogError: + return 1; + default: + return 0; + } +} /*-------------------------------------------------------------------------*/ int SCWrite(SConnection * self, char *pBuffer, int iOut) { @@ -610,7 +620,7 @@ int SCWrite(SConnection * self, char *pBuffer, int iOut) if (pBuffer == NULL) { return 0; } - if(!SCinMacro(self)){ + if(!SCinMacro(self) || mustWrite(iOut) ){ traceCommand(ConID(self),"out:%s", pBuffer); } return self->write(self, pBuffer, iOut); diff --git a/counter.c b/counter.c index bf05593a..53b4ac80 100644 --- a/counter.c +++ b/counter.c @@ -291,16 +291,17 @@ static int CheckCountStatus(void *pData, SConnection * pCon) } } - if(self->pDriv->fTime > .0){ - rate = (float)(self->pDriv->lCounts[1])/self->pDriv->fTime; - if(rate > 10000){ - SCWrite(pCon,"WARNING: Your control monitor is running into dead time", - eWarning); - } - } + /* if(self->pDriv->fTime > .0){ */ + /* rate = (float)(self->pDriv->lCounts[1])/self->pDriv->fTime; */ + /* if(rate > 10000){ */ + /* SCWrite(pCon,"WARNING: Your control monitor is running into dead time", */ + /* eLogError); */ + /* } */ + /* } */ + /* - handle count parameters and notify listeners on progress - */ + handle count parameters and notify listeners on progress + */ sMon.fCurrent = fControl; sMon.fPreset = self->pDriv->fPreset; sMon.pName = self->name; diff --git a/devser.c b/devser.c index b16bf8fe..0525188d 100644 --- a/devser.c +++ b/devser.c @@ -228,7 +228,7 @@ void DevAsconStatistics(DevSer *self, double *avg, \ *longCount = self->maxCount; } -static int DevQueueTask(void *ds) +int DevQueueTask(void *ds) { DevSer *devser = ds; DevAction *action; diff --git a/devser.h b/devser.h index 7a927037..897c1471 100644 --- a/devser.h +++ b/devser.h @@ -215,5 +215,12 @@ double DevGetSetTimeout(DevSer *devser, double timeout, int setmode); */ int DevReconnectInterval(DevSer *devser, int interval); +/** + * Drive devser processing. Normally called as a SICS task + * @param ds The device serialiser to run + * @return 1 when continuing the task, 0 when the task is to be stopped + */ +int DevQueueTask(void *ds); + #endif diff --git a/doc/manager/nxscript.htm b/doc/manager/nxscript.htm index 2c660818..b804ceea 100644 --- a/doc/manager/nxscript.htm +++ b/doc/manager/nxscript.htm @@ -169,6 +169,25 @@ designated by targetAlias. The difference is that this converts the data to a6 bit int before writing. And SICSData objects are not supported. +
nxscript puts alias sgetstring [dim,dim] +
+ Writes any SICS data which can be fetched with sget. The input to sget is the + sgetstring. If sgetstring contains spaces, it must be quoted. The code tries to guess types + and dimensions automatically, thus alias must point to a definition string without -type, + -dim and -rank. The dimensions can be overriden with the optional dim argument which is a + komma separated list of dimensions. + +
nxscript sappend alias sgetstring point [dim,dim] +
+ Appends any SICS data which can be fetched with sget to alias. The input to sget is the + sgetstring. If sgetstring contains spaces, it must be quoted. The code tries to guess types + and dimensions automatically, thus alias must point to a definition string without -type, + -dim and -rank. It is assumed that the first dimension is NX_UNLIMITED. The dimensions can be + overriden with the optional dim argument which is a komma separated list of dimensions. This override + only allows to specify the correct dimensions of the detector, NX_UNLIMITED is prepended + automatically. Point is the count in the dataset where to append to. Usually this is the + scan point number. +

Automatic Updating of NeXus Files

diff --git a/hipadaba.h b/hipadaba.h index 29523287..09e49336 100644 --- a/hipadaba.h +++ b/hipadaba.h @@ -1,4 +1,4 @@ -/** @file + /** @file * Hipadaba is a hierarchical database of parameters. Parameters can be of * various types. What happens when a parameter is being set, updated or read * is largely determined through callbacks which can be registered on diff --git a/histmemsec.c b/histmemsec.c index 86078ec3..871231e1 100644 --- a/histmemsec.c +++ b/histmemsec.c @@ -47,6 +47,8 @@ static int initArray(pCounter self, int value) for(i = 1; i < rank->value.v.intValue; i++){ length *= dim->value.v.intArray[i]; } + /* printf("initArray called with length %d\n", length);*/ + v = MakeHdbInt(length); UpdateHipadabaPar(datalength, v, NULL); diff --git a/linux_def b/linux_def index 45815958..e312d828 100644 --- a/linux_def +++ b/linux_def @@ -10,4 +10,4 @@ MFLAGS=-f makefile_linux$(DUMMY) HDFROOT=/usr/local -TCLINC=/usr/include/tcl8.3 \ No newline at end of file +TCLINC=/usr/include/tcl \ No newline at end of file diff --git a/make_gen b/make_gen index 3f29eedb..cf100558 100644 --- a/make_gen +++ b/make_gen @@ -5,7 +5,8 @@ # Markus Zolliker March 2003 #--------------------------------------------------------------------------- -EPICSOBJ=epicsmotor.o +#EPICSOBJ=epicsmotor.o +EPICSOBJ= COBJ = Sclient.o network.o ifile.o intcli.o $(FORTIFYOBJ) SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ diff --git a/makefile_linux b/makefile_linux index 059317ff..590bf7c4 100644 --- a/makefile_linux +++ b/makefile_linux @@ -25,7 +25,7 @@ EXTRA=nintf.o SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \ psi/tecs/libtecsl.a LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\ - -ltcl8.3 -lhdf5 -lmfhdf -ldf \ + -ltcl -lNeXus -lhdf5 -lmfhdf -ldf \ -lmxml -lghttp -ljpeg -ljson -ldl -lz -lm -lc include make_gen diff --git a/motor.c b/motor.c index 8b08a43e..a0be2715 100644 --- a/motor.c +++ b/motor.c @@ -1066,23 +1066,19 @@ int MotorCreate(SConnection * pCon, SicsInterp * pSics, void *pData, SCWrite(pCon, pBueffel, eLogError); return 0; } + /* } else if (strcmp(argv[2], "epics") == 0) { if(argc > 3){ pDriver = epicsMakeMotorDriver(argv[3]); if (!pDriver) { return 0; } + } else { SCWrite(pCon,"ERROR: missing basename argument to create EPICS motor",eError); return 0; } - /* create the motor */ - pNew = MotorInit("regress", argv[1], pDriver); - if (!pNew) { - snprintf(pBueffel,sizeof(pBueffel)-1, "Failure to create motor %s", argv[1]); - SCWrite(pCon, pBueffel, eLogError); - return 0; - } + */ } else { site = getSite(); if (site != NULL) { diff --git a/motorsec.c b/motorsec.c index c17efa8f..71443aa7 100644 --- a/motorsec.c +++ b/motorsec.c @@ -121,15 +121,15 @@ static long SecMotorRun(void *sulf, SConnection * pCon, float fNew) self->stopReported = 0; self->fTarget = fNew; - v = MakeHdbFloat(fNew); SecMotorSetError(sulf,"None"); - status = SetHipadabaPar(self->pDescriptor->parNode, v, pCon); node = GetHipadabaNode(self->pDescriptor->parNode, "status"); if(node != NULL){ v = MakeHdbText(strdup("run")); UpdateHipadabaPar(node,v,pCon); ReleaseHdbValue(&v); } + v = MakeHdbFloat(fNew); + status = SetHipadabaPar(self->pDescriptor->parNode, v, pCon); return status; } @@ -255,7 +255,7 @@ static int checkPosition(pMotor self, SConnection * pCon) self->name, (int) maxretry, target - hard); node = GetHipadabaNode(self->pDescriptor->parNode, "status"); assert(node != NULL); - SecMotorSetError(self,"Aborted poistioning after many retries"); + SecMotorSetError(self,"Aborted positioning after many retries"); UpdateHipadabaPar(node, MakeHdbText("error"), pCon); return HWFault; } @@ -531,10 +531,10 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData, self->retryCount = 0; self->stopped = 0; self->posCount = 0; - child = GetHipadabaNode(self->pDescriptor->parNode, "targetposition"); - UpdateHipadabaPar(child, MakeHdbFloat(fHard), pCon); child = GetHipadabaNode(self->pDescriptor->parNode, "status"); UpdateHipadabaPar(child, MakeHdbText("run"), pCon); + child = GetHipadabaNode(self->pDescriptor->parNode, "targetposition"); + UpdateHipadabaPar(child, MakeHdbFloat(fHard), pCon); child = GetHipadabaNode(self->pDescriptor->parNode, "hardposition"); SetHipadabaPar(child, MakeHdbFloat(fHard), pCon); @@ -869,3 +869,25 @@ int SecMotorFactory(SConnection * pCon, SicsInterp * pSics, void *pData, SecMotorKill, pNew); } + +/*-------------------------------------------------------------------------- + everywhere we need to find a motor for a name quite frequently....... +----------------------------------------------------------------------------*/ +pMotor FindMotor(SicsInterp * pSics, char *name) +{ + CommandList *pC; + pMotor pMot; + + pC = FindCommand(pSics, name); + if (!pC) { + return NULL; + } + pMot = (pMotor) pC->pData; + if (!pMot) { + return NULL; + } + if (strcmp(pMot->pDescriptor->name, "Motor") != 0 ) { + return NULL; + } + return pMot; +} diff --git a/mumoconf.c b/mumoconf.c index d0f08643..cf7a5cdf 100644 --- a/mumoconf.c +++ b/mumoconf.c @@ -158,28 +158,6 @@ static int GetNextToken(psParser self) return UNKNOWN; } -/*-------------------------------------------------------------------------- - in this code we need to find a motor for a name quite frequently....... -*/ -pMotor FindMotor(SicsInterp * pSics, char *name) -{ - CommandList *pC; - pMotor pMot; - - pC = FindCommand(pSics, name); - if (!pC) { - return NULL; - } - pMot = (pMotor) pC->pData; - if (!pMot) { - return NULL; - } - if (strcmp(pMot->pDescriptor->name, "Motor") != 0) { - return NULL; - } - return pMot; -} - /*--------------------------------------------------------------------------*/ int MakeMulti(SConnection * pCon, SicsInterp * pSics, void *pData, diff --git a/nxdict.c b/nxdict.c index 05f62d44..f080d2c0 100644 --- a/nxdict.c +++ b/nxdict.c @@ -47,7 +47,7 @@ /*-------------------------------------------------------------------------- Things defined in napi.c for error reporting ---------------------------------------------------------------------------*/ -static void *NXpData = NULL; +void *NXpData = NULL; /*--------------------------------------------------------------------------*/ /* #define DEFDEBUG 1 */ /* define DEFDEBUG when you wish to print your definition strings before diff --git a/nxscript.c b/nxscript.c index 5b68d660..604d5a3c 100644 --- a/nxscript.c +++ b/nxscript.c @@ -9,6 +9,8 @@ Mark Koennecke, February 2003 Mark Koennecke, January 2004 added putHdb and putHdbSlab, Mark Koennecke, December 2008 + + added sput, sappend and slab. Mark Koennecke, November 2013 ------------------------------------------------------------------------*/ #include #include @@ -32,6 +34,9 @@ #include "nxscript.h" #include "sicsdata.h" #include "sicshipadaba.h" +#include "messagepipe.h" +#include "sicsget.h" +#include "stptok.h" extern char *trim(char *str); @@ -1397,7 +1402,381 @@ static void putGlobal(SConnection * pCon, SicsInterp * pSics, } SCSendOK(pCon); } +/*----------------------------------------------------------------------- + sget based functions + -------------------------------------------------------------------------*/ +static pMP putPipe = NULL; +static pMP appendPipe = NULL; +/*------------------------------------------------------------------------*/ +typedef struct { + hdbValue v; + char error[512]; + char defString[1024]; + int success; + int argc; + char **argv; + pNXScript nx; + int rank; + int dim[NX_MAXRANK]; + int point; +}PutMessage, *pPutMessage; +/*------------------------------------------------------------------------*/ +static int CheckNoArguments(void *message, void *userData) +{ + pPutMessage self = (pPutMessage)message; + int *noArgs = (int *)userData; + if(self->argc < *noArgs){ + snprintf(self->error, sizeof(self->error),"Not enough arguments, %d required", + *noArgs); + return MPSTOP; + } + return MPCONTINUE; +} +/*------------------------------------------------------------------------*/ +static int SGetData(void *message, void *userData) +{ + pPutMessage self = (pPutMessage)message; + int status; + + status = sget(self->argv[3],&self->v); + if(status == 0){ + snprintf(self->error, sizeof(self->error),"data for %s NOT found", + self->argv[3]); + return MPSTOP; + } + return MPCONTINUE; +} +/*-----------------------------------------------------------------------*/ +static int GetDefString(void *message, void *userData) +{ + pPutMessage self = (pPutMessage)message; + NXstatus status; + + status = NXDget(self->nx->dictHandle, self->argv[2], + self->defString,sizeof(self->defString)); + if(status != NX_OK){ + snprintf(self->error, sizeof(self->error),"alias %s NOT found", + self->argv[2]); + return MPSTOP; + } + + return MPCONTINUE; +} +/*------------------------------------------------------------------------*/ +static int SPutAddType(void *message, void *userData) +{ + pPutMessage self = (pPutMessage)message; + switch(self->v.dataType){ + case HIPINT: + case HIPINTAR: + case HIPINTVARAR: + strncat(self->defString," -type NX_INT32 ",sizeof(self->defString)); + break; + case HIPFLOAT: + case HIPFLOATAR: + case HIPFLOATVARAR: + strncat(self->defString," -type NX_FLOAT32 ",sizeof(self->defString)); + break; + case HIPTEXT: + strncat(self->defString," -type NX_CHAR ",sizeof(self->defString)); + break; + default : + snprintf(self->error, sizeof(self->error),"invalid data type %d", + self->v.dataType); + return MPSTOP; + } + return MPCONTINUE; +} +/*------------------------------------------------------------------------*/ +static int SPutDim(void *message, void *userData) +{ + pPutMessage self = (pPutMessage)message; + char dim[20], *pPtr; + int i; + + if(self->argc > 4) { + pPtr = self->argv[4]; + while((pPtr = stptok(pPtr,dim,sizeof(dim),",")) != NULL){ + self->dim[self->rank] = atoi(dim); + self->rank++; + } + } else { + self->rank = 1; + switch(self->v.dataType){ + case HIPINT: + case HIPFLOAT: + self->dim[0] = 1; + break; + case HIPINTAR: + case HIPINTVARAR: + case HIPFLOATAR: + case HIPFLOATVARAR: + self->dim[0] = self->v.arrayLength; + break; + case HIPTEXT: + self->dim[0] = strlen(self->v.v.text)+1; + break; + default: + snprintf(self->error, sizeof(self->error),"invalid data type %d", + self->v.dataType); + return MPSTOP; + } + } + snprintf(dim,sizeof(dim)," -rank %d ", self->rank); + strncat(self->defString,dim,sizeof(self->defString)); + strncat(self->defString," -dim {",sizeof(self->defString)); + for(i = 0; i < self->rank; i++){ + sprintf(dim,"%d,", self->dim[i]); + strncat(self->defString,dim,sizeof(self->defString)); + } + pPtr = strrchr(self->defString,(int)','); + *pPtr = '}'; + + return MPCONTINUE; +} +/*-----------------------------------------------------------------------*/ +static int SPutWrite(void *message, void *userData) +{ + pPutMessage self = (pPutMessage)message; + NXstatus status; + float fVal, *fData; + int i; + + switch(self->v.dataType){ + case HIPINT: + status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle, + self->defString, &self->v.v.intValue); + break; + case HIPFLOAT: + fVal = self->v.v.doubleValue; + status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle, + self->defString, &fVal); + break; + case HIPINTAR: + case HIPINTVARAR: + status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle, + self->defString, &self->v.v.intArray); + break; + case HIPFLOATAR: + case HIPFLOATVARAR: + fData = malloc(self->v.arrayLength * sizeof(float)); + if(fData == NULL){ + snprintf(self->error, sizeof(self->error),"out of memory in SPutWrire"); + return MPSTOP; + } + for(i = 0; i < self->v.arrayLength; i++){ + fData[i] = self->v.v.floatArray[i]; + } + status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle, + self->defString, &fData); + free(fData); + break; + case HIPTEXT: + status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle, + self->defString, self->v.v.text); + break; + default: + snprintf(self->error, sizeof(self->error),"invalid data type %d", + self->v.dataType); + return MPSTOP; + } + + if(status == NX_OK){ + self->success = 1; + } else { + snprintf(self->error, sizeof(self->error),"error writing %s", self->argv[2]); + } + return MPCONTINUE; +} +/*------------------------------------------------------------------------*/ +static void configurePutPipe() +{ + int *noArgs; + putPipe = MakeMP(); + + noArgs = malloc(sizeof(int)); + *noArgs = 4; + AppendMPFilter(putPipe,CheckNoArguments, noArgs,free); + AppendMPFilter(putPipe,SGetData, NULL,NULL); + AppendMPFilter(putPipe,GetDefString, NULL,NULL); + AppendMPFilter(putPipe,SPutAddType, NULL,NULL); + AppendMPFilter(putPipe,SPutDim, NULL,NULL); + AppendMPFilter(putPipe,SPutWrite, NULL,NULL); +} +/*------------------------------------------------------------------------*/ +static int SAppendDim(void *message, void *userData) +{ + pPutMessage self = (pPutMessage)message; + char dim[20], *pPtr; + int i; + + self->point = atoi(self->argv[4]); + self->rank = 1; + self->dim[0] = -1; + + if(self->argc > 5) { + pPtr = self->argv[5]; + while((pPtr = stptok(pPtr,dim,sizeof(dim),",")) != NULL){ + self->dim[self->rank] = atoi(dim); + self->rank++; + } + } else { + self->rank = 1; + switch(self->v.dataType){ + case HIPINT: + case HIPFLOAT: + break; + case HIPINTAR: + case HIPINTVARAR: + case HIPFLOATAR: + case HIPFLOATVARAR: + self->rank = 2; + self->dim[1] = self->v.arrayLength; + break; + case HIPTEXT: + self->rank = 2; + self->dim[1] = strlen(self->v.v.text)+1; + break; + default: + snprintf(self->error, sizeof(self->error),"invalid data type %d", + self->v.dataType); + return MPSTOP; + } + } + snprintf(dim,sizeof(dim)," -rank %d ", self->rank); + strncat(self->defString,dim,sizeof(self->defString)); + strncat(self->defString," -dim {",sizeof(self->defString)); + for(i = 0; i < self->rank; i++){ + sprintf(dim,"%d,", self->dim[i]); + strncat(self->defString,dim,sizeof(self->defString)); + } + pPtr = strrchr(self->defString,(int)','); + *pPtr = '}'; + + return MPCONTINUE; +} +/*-----------------------------------------------------------------------*/ +static int SAppendWrite(void *message, void *userData) +{ + pPutMessage self = (pPutMessage)message; + NXstatus status; + float fVal, *fData; + int i; + int start[NX_MAXRANK], size[NX_MAXRANK]; + + + NXopenpath(self->nx->fileHandle,"/"); + status = NXDopendef(self->nx->fileHandle, self->nx->dictHandle, + self->defString); + if(status != NX_OK){ + snprintf(self->error, sizeof(self->error),"cannot open NeXus object"); + return MPSTOP; + } + + start[0] = self->point; + size[0] = 1; + for(i = 1; i < self->rank; i++){ + start[i] = 0; + size[i] = self->dim[i]; + } + + + switch(self->v.dataType){ + case HIPINT: + status = NXputslab(self->nx->fileHandle,&self->v.v.intValue, start,size); + break; + case HIPFLOAT: + fVal = self->v.v.doubleValue; + status = NXputslab(self->nx->fileHandle,&fVal, start,size); + break; + case HIPINTAR: + case HIPINTVARAR: + status = NXputslab(self->nx->fileHandle,&self->v.v.intArray, start,size); + break; + case HIPFLOATAR: + case HIPFLOATVARAR: + fData = malloc(self->v.arrayLength * sizeof(float)); + if(fData == NULL){ + snprintf(self->error, sizeof(self->error),"out of memory in SPutWrire"); + return MPSTOP; + } + for(i = 0; i < self->v.arrayLength; i++){ + fData[i] = self->v.v.floatArray[i]; + } + status = NXputslab(self->nx->fileHandle,fData, start,size); + free(fData); + break; + case HIPTEXT: + status = NXputslab(self->nx->fileHandle,self->v.v.text, start,size); + break; + default: + snprintf(self->error, sizeof(self->error),"invalid data type %d", + self->v.dataType); + return MPSTOP; + } + + if(status == NX_OK){ + self->success = 1; + } else { + snprintf(self->error, sizeof(self->error),"error writing %s", self->argv[2]); + } + NXopenpath(self->nx->fileHandle,"/"); + return MPCONTINUE; +} +/*------------------------------------------------------------------------*/ +static void configureAppendPipe() +{ + int *noArgs; + appendPipe = MakeMP(); + + noArgs = malloc(sizeof(int)); + *noArgs = 5; + AppendMPFilter(appendPipe,CheckNoArguments, noArgs,free); + AppendMPFilter(appendPipe,SGetData, NULL,NULL); + AppendMPFilter(appendPipe,GetDefString, NULL,NULL); + AppendMPFilter(appendPipe,SPutAddType, NULL,NULL); + AppendMPFilter(appendPipe,SAppendDim, NULL,NULL); + AppendMPFilter(appendPipe,SAppendWrite, NULL,NULL); +} +/*------------------------------------------------------------------------*/ +static int handleSPut(SConnection * pCon, SicsInterp * pSics, + pNXScript self, int argc, char *argv[]) +{ + PutMessage mess; + + memset(&mess, 0, sizeof(PutMessage)); + mess.argc = argc; + mess.argv = argv; + mess.nx = self; + MPprocess(putPipe,&mess); + if(mess.success == 0){ + SCPrintf(pCon,eLogError,"ERROR: %s", mess.error); + } else { + SCSendOK(pCon); + } + ReleaseHdbValue(&mess.v); + return mess.success; +} +/*------------------------------------------------------------------------*/ +static int handleSAppend(SConnection * pCon, SicsInterp * pSics, + pNXScript self, int argc, char *argv[]) +{ + PutMessage mess; + + memset(&mess, 0, sizeof(PutMessage)); + mess.argc = argc; + mess.argv = argv; + mess.nx = self; + MPprocess(appendPipe,&mess); + if(mess.success == 0){ + SCPrintf(pCon,eLogError,"ERROR: %s", mess.error); + } else { + SCSendOK(pCon); + } + ReleaseHdbValue(&mess.v); + return mess.success; +} /*-----------------------------------------------------------------------*/ static int handlePut(SConnection * pCon, SicsInterp * pSics, pNXScript self, int argc, char *argv[]) @@ -1529,6 +1908,12 @@ static int handlePut(SConnection * pCon, SicsInterp * pSics, } else if (strcmp(argv[1], "putslab16") == 0) { /*===============*/ putSlab16(pCon, pSics, self, argc, argv); + } else if (strcmp(argv[1], "puts") == 0) { + /*===============*/ + handleSPut(pCon, pSics, self, argc, argv); + } else if (strcmp(argv[1], "sappend") == 0) { + /*===============*/ + handleSAppend(pCon, pSics, self, argc, argv); } else { SCPrintf(pCon, eLogError, "ERROR: put command %s not recognised", argv[1] ); } @@ -1646,7 +2031,7 @@ int NXScriptAction(SConnection * pCon, SicsInterp * pSics, void *pData, return 1; } - if (strstr(argv[1], "put") != NULL) { + if (strstr(argv[1], "put") != NULL || strstr(argv[1],"sappend") != NULL) { handlePut(pCon, pSics, self, argc, argv); return 1; } @@ -1711,6 +2096,12 @@ int MakeNXScript(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } self->timeDivisor = 1; + + /* + configure pipes + */ + configurePutPipe(); + configureAppendPipe(); /* create with with a default name if none specified diff --git a/sicsget.c b/sicsget.c index 252f5bad..4c1fbdb5 100644 --- a/sicsget.c +++ b/sicsget.c @@ -190,7 +190,7 @@ static int countWords(char *txt) { char number[80]; - if(txt == NULL){ + if(txt == NULL || strlen(txt) < 1){ return 0; } else { return 1 + countWords(stptok(txt,number,sizeof(number)," ")); diff --git a/tasub.c b/tasub.c index ca6ff58a..3694c347 100644 --- a/tasub.c +++ b/tasub.c @@ -378,10 +378,15 @@ static int setCrystalParameters(pmaCrystal crystal, SConnection * pCon, SCparChange(pCon); return 1; } else if (strcmp(argv[2], "ss") == 0) { - if (d > .0) { + status = (int)d; + if (status == 1) { crystal->ss = 1; - } else { + } else if(status == -1) { crystal->ss = -1; + } else { + SCPrintf(pCon,eError, + "ERROR: %f not allowed for scattering sense, only 1,-1", d); + return 0; } SCSendOK(pCon); SCparChange(pCon); @@ -560,13 +565,8 @@ static void tasListCell(SConnection * pCon, char *name, lattice direct) /*--------------------------------------------------------------------*/ static void clearReflections(ptasUB self) { - int status; - - status = LLDnodePtr2First(self->reflectionList); - while (status != 0) { - LLDnodeDelete(self->reflectionList); - status = LLDnodePtr2Next(self->reflectionList); - } + LLDdelete(self->reflectionList); + self->reflectionList = LLDcreate(sizeof(tasReflection)); self->ubValid = 0; } diff --git a/test/testini.tcl b/test/testini.tcl index 4f3fcddb..097ad774 100644 --- a/test/testini.tcl +++ b/test/testini.tcl @@ -849,10 +849,11 @@ if {$zwickroll == 1} { zwickroll::makezwickroll zwro } -set sputter 1 +set sputter 0 if {$sputter == 1} { source ../sim/sicscommon/stddrive.tcl source ../sim/amor_sics/sputter.tcl SputterInit } +