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
}
+