Files
sics/nxscript.c
koennecke a5c2da6acf - Switched motor to hdb
- Changes to Hipadaba
- Added project to histogram memory code
- Started regression testing code
- Added hill climbing as optimization method to optimise
2006-08-16 14:13:05 +00:00

1198 lines
31 KiB
C

/*-----------------------------------------------------------------------
N X S C R I P T
This is a class for scripting the contents of NeXus files from
SICS.
copyright: see file COPYRIGHT
Mark Koennecke, February 2003
Mark Koennecke, January 2004
------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <tcl.h>
#include <math.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include "fortify.h"
#include "sics.h"
#include "splitter.h"
#include "HistMem.h"
#include "motor.h"
#include "counter.h"
#include "sicsvar.h"
#include "danu.h"
#include "udpquieck.h"
#include "nxdict.h"
#include "nxscript.h"
#include "sicsdata.h"
extern char *trim(char *str);
/* missing in nxdict.h: */
NXstatus NXDdefget(NXdict handle, char *pKey, char *pBuffer, int iBufLen);
/*------------------------------------------------------------------------*/
char *makeFilename(SicsInterp *pSics, SConnection *pCon) {
pSicsVariable pPath = NULL, pPref = NULL, pEnd = NULL;
char *pRes = NULL;
int iLen, iNum, iYear, thousand;
char pNumText[10], pBueffel[256];
CommandList *pCom = NULL;
DIR *dir = NULL;
/* Try, get all the Variables */
pPath = FindVariable(pSics,"sicsdatapath");
pPref = FindVariable(pSics,"sicsdataprefix");
pCom = FindCommand(pSics,"sicsdatanumber");
pEnd = FindVariable(pSics,"sicsdatapostfix");
if( (!pPath) || (!pPref) || (!pCom) || (!pEnd) ){
SCWrite(pCon,
"ERROR: cannot read variables for automatic data file name creation",
eError);
SCWrite(pCon,
"ERROR: This is a VERY, VERY, VERY serious installation problem",
eError);
SCWrite(pCon,"ERROR: your data will be dumped into emergency.hdf",eError);
return NULL;
}
/* find length */
iLen = strlen(pPath->text) + 4; /* extra 4 for dir number */
iLen += strlen(pPref->text);
iLen += 10; /* for number + year */
iLen += strlen(pEnd->text);
iLen += 10; /* safety margin */
/* allocate memory */
pRes = (char *)malloc(iLen*sizeof(char));
if(!pRes){
SCWrite(pCon,"ERROR: no memory in makeFilename",eError);
return NULL;
}
memset(pRes,0,iLen);
/* increment the data file number */
iNum = IncrementDataNumber(pCom->pData,&iYear);
if(iNum < 0){
SCWrite(pCon,"ERROR: cannot increment data number!",eError);
SCWrite(pCon,"ERROR: your data will be dumped to emergency.hdf",eError);
free(pRes);
return NULL;
}
strcpy(pRes,pPath->text);
thousand = (int)floor(iNum/1000.);
snprintf(pNumText,9,"%3.3d",thousand);
strcat(pRes,pNumText);
/*
check for existence of directory and create if neccessary
*/
dir = opendir(pRes);
if(dir == NULL){
mkdir(pRes,S_IRWXU | S_IRGRP | S_IXGRP);
snprintf(pBueffel,255,"Creating dir: %s", pRes);
SCWrite(pCon,pBueffel,eWarning);
} else {
closedir(dir);
}
/*
build the rest of the filename
*/
strcat(pRes,"/");
strcat(pRes,pPref->text);
sprintf(pNumText,"%4.4d",iYear);
strcat(pRes,pNumText);
strcat(pRes,"n");
sprintf(pNumText,"%6.6d",iNum);
strcat(pRes,pNumText);
strcat(pRes,pEnd->text);
return pRes;
}
/*---------------------------------------------------------------------*/
void changeExtension(char *filename, char *newExtension){
char *pPtr = NULL;
pPtr = strrchr(filename,(int)'.');
assert(pPtr != NULL);
pPtr++;
assert(strlen(pPtr) >= strlen(newExtension));
strcpy(pPtr,newExtension);
}
/*======================== Action =======================================*/
static int handleFileOperations(SConnection *pCon, pNXScript self,
int argc, char *argv[]){
int status,i, iVal;
NXaccess access;
char buffer[512];
if(strcmp(argv[1],"close") == 0){
/*
close everything! and send a message to trigger file synchronisation
to the central server
*/
if(self->fileHandle == NULL){
SCSendOK(pCon);
return 1;
}
i = 511;
iVal = NX_CHAR;
NXgetattr(self->fileHandle,"file_name",buffer,&i,&iVal);
NXclose(&self->fileHandle);
NXDclose(self->dictHandle,NULL);
self->fileHandle = NULL;
self->dictHandle = NULL;
SendQuieck(QUIECK,buffer);
SCSendOK(pCon);
return 1;
} else if(strcmp(argv[1],"reopen") == 0){
access = NXACC_RDWR;
} else if(strcmp(argv[1],"create4") == 0){
access = NXACC_CREATE4;
unlink(argv[2]); /* kill file for overwrite */
} else if(strcmp(argv[1],"create5") == 0){
access = NXACC_CREATE5;
unlink(argv[2]); /* kill file for overwrite */
} else if(strcmp(argv[1],"createxml") == 0){
access = NXACC_CREATEXML;
} else {
return 0;
}
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments for file operation",
eError);
return -1;
}
/*
be considerate: close files left open
*/
if(self->fileHandle != NULL){
NXclose(&self->fileHandle);
self->fileHandle = NULL;
}
if(self->dictHandle != NULL){
NXDclose(self->dictHandle, NULL);
self->dictHandle = NULL;
}
/*
now initialize ourselves
*/
status = NXopen(argv[2],access,&self->fileHandle);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to open %s",argv[2]);
SCWrite(pCon,buffer,eError);
return -1;
}
status = NXDinitfromfile(argv[3],&self->dictHandle);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to open dictionary %s",argv[3]);
SCWrite(pCon,buffer,eError);
return -1;
}
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------*/
static void putMotor(SConnection *pCon, SicsInterp *pSics, pNXScript self,
int argc, char *argv[]){
int status;
pMotor brumm = NULL;
float fVal;
char buffer[132], dummy[256];
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putmotor",
eError);
return;
}
/*
find motor
*/
brumm = (pMotor)FindCommandData(pSics,argv[3],"Motor");
if(!brumm){
sprintf(buffer,"ERROR: motor %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
return;
}
/*
do position
*/
status = MotorGetSoftPosition(brumm, pCon,&fVal);
if(!status){
sprintf(buffer,"ERROR: failed to read position of %s", argv[3]);
SCWrite(pCon,buffer,eError);
return;
}
status = NXDputalias(self->fileHandle,self->dictHandle,argv[2],&fVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write %s with alias %s",
argv[3],argv[2]);
SCWrite(pCon,buffer,eError);
return;
}
/*
if alias_null is available: write zero point
*/
strcpy(buffer,argv[2]);
strcat(buffer,"_null");
if(NXDdefget(self->dictHandle,buffer,dummy,255)){
MotorGetPar(brumm,"softzero",&fVal);
status = NXDputalias(self->fileHandle,self->dictHandle,buffer, &fVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write %s zero with alias %s",
argv[3],argv[2]);
SCWrite(pCon,buffer,eError);
return;
}
}
}
/*---------------------------------------------------------------------*/
static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
int argc, char *argv[]){
pCounter cter = NULL;
float fVal;
long counts;
char buffer[256], newAlias[256], dummy[80];
int status, i, icounts;
CounterMode eMode;
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putcounter",
eError);
return;
}
memset(dummy,0,80*sizeof(char));
/*
find counter
*/
cter = (pCounter)FindCommandData(pSics,argv[3],"SingleCounter");
if(!cter){
sprintf(buffer,"ERROR: counter %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
return;
}
/*
do preset
*/
fVal = GetCounterPreset(cter);
strcpy(newAlias,argv[2]);
strcat(newAlias,"_preset");
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,&fVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write preset to %s", newAlias);
SCWrite(pCon,buffer,eError);
}
/*
do countmode
*/
eMode = GetCounterMode(cter);
strcpy(newAlias,argv[2]);
strcat(newAlias,"_mode");
if(eMode == eTimer){
strcpy(dummy,"timer");
} else {
strcpy(dummy,"monitor");
}
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,dummy);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write counter mode to %s", newAlias);
SCWrite(pCon,buffer,eError);
}
/*
do time
*/
fVal = GetCountTime(cter,pCon);
strcpy(newAlias,argv[2]);
strcat(newAlias,"_time");
if(NXDdefget(self->dictHandle,newAlias,dummy,79)){
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,&fVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write count time to %s", newAlias);
SCWrite(pCon,buffer,eError);
}
}
/*
do counter and monitors
*/
for(i = 0; i < 10; i++){
sprintf(newAlias,"%s_%2.2d",argv[2],i);
if(NXDdefget(self->dictHandle,newAlias,dummy,79)){
counts = GetMonitor(cter,i,pCon);
icounts = (int)counts;
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,
&icounts);
}
}
return;
}
/*----------------------------------------------------------------------*/
static void putSicsData(SConnection *pCon, SicsInterp *pSics,
pNXScript self, int argc, char *argv[]){
pSICSData data = NULL;
int status;
char buffer[256];
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putSicsData",
eError);
return;
}
/*
find data
*/
data = (pSICSData)FindCommandData(pSics,argv[3],"SICSData");
if(data == NULL){
snprintf(buffer,255,"ERROR: sicsdata %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
return;
}
status = NXDputalias(self->fileHandle,self->dictHandle,argv[2],data->data);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write sicsdata to %s", argv[2]);
SCWrite(pCon,buffer,eError);
}
}
/*----------------------------------------------------------------------*/
static void putAttribute(SConnection *pCon, SicsInterp *pSics,
pNXScript self, int argc, char *argv[]){
int status, type = NX_CHAR;
char buffer[256];
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to putAttribute",
eError);
return;
}
status = NXDopenalias(self->fileHandle,self->dictHandle,argv[2]);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to open alias %s", argv[2]);
SCWrite(pCon,buffer,eError);
return;
}
status = NXputattr(self->fileHandle,argv[3],(void *)argv[4],
strlen(argv[4])+1, type);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write attribute %s", argv[3]);
SCWrite(pCon,buffer,eError);
}
}
/*----------------------------------------------------------------------*/
static void updateHMDim(NXScript *self, pHistMem mem){
int iDim[MAXDIM];
int i, rank, timeLength, status;
char dummy[40], value[20];
const float *timeBin;
/*
update the dimension variables in the dictionary
*/
GetHistDim(mem,iDim,&rank);
for(i = 0; i < rank; i++){
sprintf(dummy,"dim%1.1d", i);
sprintf(value,"%d",iDim[i]);
status = NXDupdate(self->dictHandle,dummy,value);
if(status == 0) {
NXDadd(self->dictHandle,dummy,value);
}
}
timeBin = GetHistTimeBin(mem,&timeLength);
if(timeLength > 2){
sprintf(dummy,"%d",timeLength);
} else {
sprintf(dummy,"%d",1);
}
status = NXDupdate(self->dictHandle,"timedim",dummy);
if(status == 0) {
NXDadd(self->dictHandle,"timedim",dummy);
}
}
/*----------------------------------------------------------------------
The sequence of things is important in here: The code for updating
the dimensions variables also applies the time binning to the length.
Thus subsets can only be checked for after that. And then we can allocate
memory.
-------------------------------------------------------------------------*/
static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
pNXScript self,
int argc, char *argv[]){
pHistMem mem = NULL;
int status, start, length, i, subset = 0, bank = 0;
HistInt *iData = NULL;
char buffer[256];
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to puthm",
eError);
return;
}
/*
find Histogram Memory
*/
mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
if(!mem){
sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
return;
}
/*
default: everything
*/
start = 0;
length = GetHistLength(mem);
updateHMDim(self,mem);
/*
check for further arguments specifying a subset
*/
if(argc > 5){
subset = 1;
status = Tcl_GetInt(InterpGetTcl(pSics),argv[4],&start);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[4]);
SCWrite(pCon,buffer,eError);
return;
}
status = Tcl_GetInt(InterpGetTcl(pSics),argv[5],&length);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[5]);
SCWrite(pCon,buffer,eError);
return;
}
}
/*
* check for additional bank number
*/
if(argc > 6){
status = Tcl_GetInt(InterpGetTcl(pSics),argv[6],&bank);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[6]);
SCWrite(pCon,buffer,eError);
return;
}
}
/*
read HM
*/
if(subset){
iData = (HistInt *)malloc(length*sizeof(HistInt));
if(!iData){
SCWrite(pCon,"ERROR: out of memory for reading histogram memory",
eError);
return;
}
memset(iData,0,length*sizeof(HistInt));
status = GetHistogramDirect(mem,pCon,bank,start,start+length,iData,
length*sizeof(HistInt));
}else{
/*
status = GetHistogram(mem,pCon,0,start,length,iData,
length*sizeof(HistInt));
*/
iData = GetHistogramPointer(mem,pCon);
if(iData == NULL){
status = 0;
} else {
status = 1;
}
}
if(!status){
SCWrite(pCon,"ERROR: failed to read histogram memory",eError);
if(subset){
free(iData);
}
return;
}
/*
finally: write
*/
status = NXDputalias(self->fileHandle, self->dictHandle,argv[2],iData);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write histogram memory data");
SCWrite(pCon,buffer,eError);
}
if(subset){
free(iData);
}
SCSendOK(pCon);
return;
}
/*---------------------------------------------------------------------
defunct as of december 2003
*/
static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
pNXScript self,
int argc, char *argv[]){
pHistMem mem = NULL;
int status, start, length, i, noChunks, chunkDim[MAXDIM], rank;
HistInt *iData = NULL;
char buffer[256];
int subset;
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to puthmchunked",
eError);
return;
}
/*
find Histogram Memory
*/
mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
if(!mem){
sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
return;
}
/*
default: everything
*/
start = 0;
length = GetHistLength(mem);
updateHMDim(self,mem);
/*
check for an argument defining the number of chunks
*/
status = Tcl_GetInt(InterpGetTcl(pSics),argv[4],&noChunks);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[4]);
SCWrite(pCon,buffer,eError);
return;
}
/*
read HM
*/
if(subset){
iData = (HistInt *)malloc(length*sizeof(HistInt));
if(!iData){
SCWrite(pCon,"ERROR: out of memory for reading histogram memory",
eError);
return;
}
memset(iData,0,length*sizeof(HistInt));
status = GetHistogramDirect(mem,pCon,0,start,start+length,iData,
length*sizeof(HistInt));
}else{
/*
status = GetHistogram(mem,pCon,0,start,length,iData,
length*sizeof(HistInt));
*/
iData = GetHistogramPointer(mem,pCon);
if(iData == NULL){
status = 0;
} else {
status = 1;
}
}
if(!status){
SCWrite(pCon,"ERROR: failed to read histogram memory",eError);
if(subset){
free(iData);
}
return;
}
/*
finally: write
*/
status = NXDputalias(self->fileHandle, self->dictHandle,argv[2],iData);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write histogram memory data");
SCWrite(pCon,buffer,eError);
}
if(subset){
free(iData);
}
SCSendOK(pCon);
return;
}
/*-------------------------------------------------------------------*/
static void putTimeBinning(SConnection *pCon, SicsInterp *pSics,
pNXScript self,
int argc, char *argv[]){
pHistMem mem = NULL;
int i, status, timeLength;
char buffer[256], defString[512], dummy[40];
const float *timeBin;
float *timeCopy = NULL;
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to puttimebinning",
eError);
return;
}
/*
find Histogram Memory
*/
mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
if(!mem){
sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
SCWrite(pCon,buffer,eError);
return;
}
/*
build definition string
*/
status = NXDdefget(self->dictHandle,argv[2],buffer,254);
if(!status){
sprintf(buffer,"ERROR: alias %s for time binning not found",
argv[2]);
SCWrite(pCon,buffer,eError);
return;
}
timeBin = GetHistTimeBin(mem,&timeLength);
sprintf(defString,"%s -dim {%d} ",buffer,timeLength);
/*
Divide the time binning when appropriate and write
*/
if(self->timeDivisor != 1){
timeCopy = (float *)malloc(timeLength*sizeof(float));
if(timeCopy == NULL){
SCWrite(pCon,"ERROR: out of memory writing time binning",eError);
return;
}
for(i = 0; i < timeLength; i++){
timeCopy[i] = timeBin[i]/self->timeDivisor;
}
status = NXDputdef(self->fileHandle, self->dictHandle,
defString,(void *)timeCopy);
free(timeCopy);
} else {
status = NXDputdef(self->fileHandle, self->dictHandle,
defString,(void *)timeBin);
}
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write time binning");
SCWrite(pCon,buffer,eError);
}
SCSendOK(pCon);
return;
}
/*----------------------------------------------------------------------*/
static void putArray(SConnection *pCon, SicsInterp *pSics,
pNXScript self,
int argc, char *argv[]){
float *data = NULL;
int length, i, status;
char num[20];
char buffer[256], defString[512], *varData;
Tcl_Interp *tcl = NULL;
double dVal;
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to array",
eError);
return;
}
tcl = InterpGetTcl(pSics);
assert(tcl != NULL);
/*
get array length
*/
status = Tcl_GetInt(tcl,argv[4],&length);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",argv[4]);
SCWrite(pCon,buffer,eError);
return;
}
/*
allocate
*/
if(length > 0){
data = (float *)malloc(length*sizeof(float));
}
if(data == NULL){
SCWrite(pCon,"ERROR: out of memory or invalid length",eError);
return;
}
memset(data,0,length*sizeof(float));
/*
try getting data
*/
for(i = 0; i < length; i++){
sprintf(num,"%d",i);
varData = (char *)Tcl_GetVar2(tcl,argv[3],num,0);
if(varData != NULL){
status = Tcl_GetDouble(tcl,varData,&dVal);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to double",
varData);
SCWrite(pCon,buffer,eError);
}
data[i] = (float)dVal;
} else {
snprintf(buffer,254,"WARNING: failed to find array element %d", i);
SCWrite(pCon,buffer,eError);
}
}
/*
build definition string
*/
status = NXDdefget(self->dictHandle,argv[2],buffer,254);
if(!status){
sprintf(buffer,"ERROR: alias %s for array not found",
argv[2]);
SCWrite(pCon,buffer,eError);
free(data);
return;
}
snprintf(defString,511,"%s -dim {%d} ",buffer,length);
/*
write it!
*/
status = NXDputdef(self->fileHandle,self->dictHandle,defString,data);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write array");
SCWrite(pCon,buffer,eError);
}
free(data);
SCSendOK(pCon);
}
/*----------------------------------------------------------------------*/
static void putIntArray(SConnection *pCon, SicsInterp *pSics,
pNXScript self,
int argc, char *argv[]){
int *data = NULL;
int length, i, status;
char num[20];
char buffer[256], defString[512], *varData;
Tcl_Interp *tcl = NULL;
int iVal;
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to array",
eError);
return;
}
tcl = InterpGetTcl(pSics);
assert(tcl != NULL);
/*
get array length
*/
status = Tcl_GetInt(tcl,argv[4],&length);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",argv[4]);
SCWrite(pCon,buffer,eError);
return;
}
/*
allocate
*/
if(length > 0){
data = (int *)malloc(length*sizeof(int));
}
if(data == NULL){
SCWrite(pCon,"ERROR: out of memory or invalid length",eError);
return;
}
memset(data,0,length*sizeof(int));
/*
try getting data
*/
for(i = 0; i < length; i++){
sprintf(num,"%d",i);
varData = (char *)Tcl_GetVar2(tcl,argv[3],num,0);
if(varData != NULL){
status = Tcl_GetInt(tcl,varData,&iVal);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to int",
varData);
SCWrite(pCon,buffer,eError);
}
data[i] = iVal;
} else {
snprintf(buffer,254,"WARNING: failed to find array element %d", i);
SCWrite(pCon,buffer,eError);
}
}
/*
build definition string
*/
status = NXDdefget(self->dictHandle,argv[2],buffer,254);
if(!status){
sprintf(buffer,"ERROR: alias %s for array not found",
argv[2]);
SCWrite(pCon,buffer,eError);
free(data);
return;
}
snprintf(defString,511,"%s -dim {%d} ",buffer,length);
/*
write it!
*/
status = NXDputdef(self->fileHandle,self->dictHandle,defString,data);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write array");
SCWrite(pCon,buffer,eError);
}
free(data);
SCSendOK(pCon);
}
/*----------------------------------------------------------------------*/
static void putGlobal(SConnection *pCon, SicsInterp *pSics,
pNXScript self,
int argc, char *argv[]){
char value[1024];
int status;
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putglobal",
eError);
return;
}
Arg2Text(argc-3,&argv[3],value,1023);
status = NXputattr(self->fileHandle,argv[2],value,strlen(value),
NX_CHAR);
if(status != NX_OK){
SCWrite(pCon,"ERROR: failed to write attribute",eError);
}
SCSendOK(pCon);
}
/*-----------------------------------------------------------------------*/
static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
int argc, char *argv[]){
int status, iVal;
char buffer[1024], defString[1024], numBuf[25];
double dVal;
float fVal;
/*============ */
if(strcmp(argv[1],"putfloat") == 0){
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putfloat",
eError);
return 1;
}
status = Tcl_GetDouble(InterpGetTcl(pSics),argv[3],&dVal);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to float",
argv[3]);
SCWrite(pCon,buffer,eError);
return 1;
}
fVal = (float)dVal;
status = NXDputalias(self->fileHandle, self->dictHandle,
argv[2],&fVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write %f to alias %s",
fVal, argv[2]);
SCWrite(pCon,buffer,eError);
}
return 1;
} else if(strcmp(argv[1],"putint") == 0){
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to putint",
eError);
return 1;
}
status = Tcl_GetInt(InterpGetTcl(pSics),argv[3],&iVal);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to int",
argv[3]);
SCWrite(pCon,buffer,eError);
return 1;
}
status = NXDputalias(self->fileHandle, self->dictHandle,
argv[2],&iVal);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write %d to alias %s",
iVal, argv[2]);
SCWrite(pCon,buffer,eError);
}
return 1;
} else if (strcmp(argv[1],"puttext") == 0){
/*====================*/
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to puttext",
eError);
return 1;
}
Arg2Text(argc-3,&argv[3],buffer,1023);
trim(buffer);
status = NXDdefget(self->dictHandle,argv[2],defString,1023);
if(status != NX_OK){
sprintf(buffer,"ERROR: alias %s not found in puttext",
argv[2]);
SCWrite(pCon,buffer,eError);
return 1;
}
if(strlen(defString) < 900){
strcat(defString," -dim {");
sprintf(numBuf,"%d",strlen(buffer)+1);
strcat(defString,numBuf);
strcat(defString," }");
} else {
SCWrite(pCon,"ERROR: out of definition string space in puttext",
eError);
return 1;
}
status = NXDputdef(self->fileHandle,self->dictHandle,
defString,buffer);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write alias %s",
argv[2]);
SCWrite(pCon,buffer,eError);
}
return 1;
} else if(strcmp(argv[1],"putmot") == 0){
/*=========== */
putMotor(pCon,pSics,self,argc,argv);
return 1;
} else if(strcmp(argv[1],"putcounter") == 0){
/* ================*/
putCounter(pCon,pSics,self, argc,argv);
return 1;
}else if(strcmp(argv[1],"puthm") == 0){
/*=================*/
putHistogramMemory(pCon,pSics,self,argc, argv);
return 1;
}else if(strcmp(argv[1],"puttimebinning") == 0){
/*=================*/
putTimeBinning(pCon,pSics,self,argc,argv);
}else if(strcmp(argv[1],"putarray") == 0){
/*================*/
putArray(pCon,pSics,self,argc,argv);
}else if(strcmp(argv[1],"putintarray") == 0){
/*================*/
putIntArray(pCon,pSics,self,argc,argv);
}else if(strcmp(argv[1],"putglobal") == 0){
/*===============*/
putGlobal(pCon,pSics,self,argc,argv);
}else if(strcmp(argv[1],"putsicsdata") == 0){
/*===============*/
putSicsData(pCon,pSics,self,argc,argv);
}else if(strcmp(argv[1],"putattribute") == 0){
/*===============*/
putAttribute(pCon,pSics,self,argc,argv);
} else {
SCWrite(pCon,"ERROR: put command not recognised",eError);
}
return 1;
}
/*----------------------------------------------------------------------*/
static void makeLink(SConnection *pCon, SicsInterp *pSics,
pNXScript self,
int argc, char *argv[]){
int status;
char pBueffel[256];
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to makelink",
eError);
return;
}
status = NXDaliaslink(self->fileHandle, self->dictHandle,
argv[2],argv[3]);
if(status != NX_OK){
snprintf(pBueffel,255,"ERROR: linking %s against %s failed",
argv[2], argv[3]);
SCWrite(pCon,pBueffel,eError);
return;
}
SCSendOK(pCon);
}
/*----------------------------------------------------------------------*/
static void updateDictVar(SConnection *pCon, pNXScript self, int argc,
char *argv[]){
int status;
if(self->dictHandle == NULL){
SCWrite(pCon,"ERROR: cannot update variable, dictionary not open",
eError);
return;
}
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to updateDictVar",
eError);
return;
}
NXDupdate(self->dictHandle,argv[2],argv[3]);
}
/*-----------------------------------------------------------------------*/
int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pNXScript self = (pNXScript)pData;
char *pFile = NULL;
int status;
/*
preliminary checks
*/
assert(self);
if(!SCMatchRights(pCon,usUser)){
return 1;
}
if(argc < 2){
SCWrite(pCon,"ERROR: no keyword found",eError);
return 1;
}
strtolower(argv[1]);
if(strcmp(argv[1],"makefilename") == 0){
pFile = makeFilename(pSics,pCon);
if(pFile != NULL){
SCWrite(pCon,pFile,eValue);
free(pFile);
return 1;
} else {
SCWrite(pCon,"ERROR: failed to create filename",eError);
return 0;
}
} else if(strcmp(argv[1],"divisor") == 0){
if(argc < 3) {
SCWrite(pCon,"ERROR: no diviso found",eError);
return 1;
}
if(!SCMatchRights(pCon,usMugger)){
return 1;
}
self->timeDivisor = atoi(argv[2]);
return 1;
}
status = handleFileOperations(pCon,self,argc,argv);
if(status < 0){
return 0;
} else if(status == 1){
return 1;
}
/*
if we are here, we can only continue if files are open
*/
if(self->fileHandle == NULL || self->dictHandle == NULL){
SCWrite(pCon,"ERROR: cannot write, files not open",eError);
return 1;
}
if(strcmp(argv[1],"updatedictvar") == 0){
updateDictVar(pCon,self,argc,argv);
return 1;
}
if(strstr(argv[1],"put") != NULL){
handlePut(pCon,pSics,self,argc,argv);
return 1;
}
if(strcmp(argv[1],"makelink") == 0){
makeLink(pCon,pSics,self,argc,argv);
return 1;
}
return 1;
}
/*=============== make it ==============================================*/
static void KillNXScript(void *pData){
pNXScript self = (pNXScript)pData;
if(self == NULL){
return;
}
if(self->pDes){
DeleteDescriptor(self->pDes);
}
if(self->fileHandle){
NXclose(&self->fileHandle);
}
if(self->dictHandle){
NXDclose(self->dictHandle, NULL);
}
free(self);
}
/*----------------------------------------------------------------------*/
int MakeNXScript(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pNXScript self = NULL;
int status;
self = (pNXScript)malloc(sizeof(NXScript));
if(self == NULL){
SCWrite(pCon,"ERROR: no memory for NXscript creation",eError);
return 0;
}
memset(self,0,sizeof(NXScript));
self->pDes = CreateDescriptor("NXScript");
if(self->pDes == NULL){
SCWrite(pCon,"ERROR: no memory for NXscript creation",eError);
free(self);
return 0;
}
self->timeDivisor = 1;
/*
create with with a default name if none specified
*/
if(argc > 1){
status = AddCommand(pSics,argv[1],NXScriptAction,KillNXScript,self);
} else {
status = AddCommand(pSics,"nxscript",NXScriptAction,KillNXScript,self);
}
if(!status){
SCWrite(pCon,"ERROR: duplicate NXScript object not created",eError);
KillNXScript(self);
return 0;
}
return 1;
}