- Adapted indenation to new agreed upon system
- Added support for second generation scriptcontext based counter
This commit is contained in:
936
tclev.c
936
tclev.c
@@ -16,7 +16,7 @@
|
||||
#include "fortify.h"
|
||||
#include "obpar.h"
|
||||
#include "evcontroller.h"
|
||||
#include "evcontroller.i"
|
||||
#include "evcontroller.i"
|
||||
#include "evdriver.i"
|
||||
#include "tclev.h"
|
||||
#include "tclev.i"
|
||||
@@ -25,508 +25,444 @@
|
||||
The first section starts with the definition of the wrappers for all the driver
|
||||
functions.
|
||||
-----------------------------------------------------------------------------*/
|
||||
static int TclSetValue(pEVDriver self, float fNew)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
|
||||
pPriv = (pTclEv)self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel,"%s %s %f",pPriv->pSetValue, pPriv->pArray, fNew);
|
||||
iRet = Tcl_Eval(pPriv->pTcl,pBueffel);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
strncpy(pBueffel,pPriv->pTcl->result,1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl,pBueffel,&iErrCode);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int TclGetValue(pEVDriver self, float *fVal)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
double d;
|
||||
|
||||
pPriv = (pTclEv)self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel,"%s %s",pPriv->pGetValue, pPriv->pArray);
|
||||
iRet = Tcl_Eval(pPriv->pTcl,pBueffel);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
strncpy(pBueffel,pPriv->pTcl->result,1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl,pBueffel,&iErrCode);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(strstr(pPriv->pTcl->result,"pending") != NULL)
|
||||
{
|
||||
*fVal = 90.;
|
||||
return -1;
|
||||
}
|
||||
iRet = Tcl_GetDouble(pPriv->pTcl,pPriv->pTcl->result,&d);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fVal = (float)d;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int TclSend(pEVDriver self, char *pCommand,
|
||||
char *pReply, int iReplyLen)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
double d;
|
||||
|
||||
pPriv = (pTclEv)self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel,"%s %s %s",pPriv->pSend, pPriv->pArray,pCommand);
|
||||
iRet = Tcl_Eval(pPriv->pTcl,pBueffel);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
strncpy(pBueffel,pPriv->pTcl->result,1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl,pBueffel,&iErrCode);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(pReply,pPriv->pTcl->result,iReplyLen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int TclGetError(pEVDriver self, int *iCode,
|
||||
char *pReply, int iReplyLen)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
double d;
|
||||
|
||||
pPriv = (pTclEv)self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* do the iCode first */
|
||||
*iCode = pPriv->iLastError;
|
||||
|
||||
/* catch the stupid Tcl thing */
|
||||
if(pPriv->iLastError == STUPIDTCL)
|
||||
{
|
||||
sprintf(pBueffel,"Your Tcl-script returned a stupid answer:\n --> %s <--",
|
||||
pPriv->pTcl->result);
|
||||
strncpy(pReply,pBueffel,iReplyLen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel,"%s %s %d",pPriv->pGetError, pPriv->pArray,pPriv->iLastError);
|
||||
iRet = Tcl_Eval(pPriv->pTcl,pBueffel);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
strncpy(pBueffel,pPriv->pTcl->result,1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl,pPriv->pTcl->result,&iErrCode);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(pReply,pPriv->pTcl->result,iReplyLen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int TclTryFixIt(pEVDriver self, int iCode)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
double d;
|
||||
|
||||
pPriv = (pTclEv)self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
|
||||
/* catch the stupid Tcl thing */
|
||||
if(iCode == STUPIDTCL)
|
||||
{
|
||||
return DEVREDO;
|
||||
}
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel,"%s %s %d",pPriv->pTryFixIt, pPriv->pArray,iCode);
|
||||
iRet = Tcl_Eval(pPriv->pTcl,pBueffel);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
return DEVFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(strcmp(pPriv->pTcl->result,"DEVFAULT") == 0)
|
||||
{
|
||||
return DEVFAULT;
|
||||
}
|
||||
else if(strcmp(pPriv->pTcl->result,"DEVREDO") == 0)
|
||||
{
|
||||
return DEVREDO;
|
||||
}
|
||||
else if(strcmp(pPriv->pTcl->result,"DEVOK") == 0)
|
||||
{
|
||||
return DEVOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int TclInit(pEVDriver self)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
|
||||
pPriv = (pTclEv)self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel,"%s %s",pPriv->pInit, pPriv->pArray);
|
||||
iRet = Tcl_Eval(pPriv->pTcl,pBueffel);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
strncpy(pBueffel,pPriv->pTcl->result,1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl,pBueffel,&iErrCode);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int TclClose(pEVDriver self)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
|
||||
pPriv = (pTclEv)self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel,"%s %s",pPriv->pClose, pPriv->pArray);
|
||||
iRet = Tcl_Eval(pPriv->pTcl,pBueffel);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
strncpy(pBueffel,pPriv->pTcl->result,1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl,pBueffel,&iErrCode);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void KillPrivate(void *pData)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
|
||||
pPriv = (pTclEv)pData;
|
||||
assert(pPriv);
|
||||
|
||||
if(pPriv->pArray)
|
||||
{
|
||||
free(pPriv->pArray);
|
||||
}
|
||||
if(pPriv->pInit)
|
||||
{
|
||||
free(pPriv->pInit);
|
||||
}
|
||||
if(pPriv->pClose)
|
||||
{
|
||||
free(pPriv->pClose);
|
||||
}
|
||||
if(pPriv->pSetValue)
|
||||
{
|
||||
free(pPriv->pSetValue);
|
||||
}
|
||||
if(pPriv->pGetValue)
|
||||
{
|
||||
free(pPriv->pGetValue);
|
||||
}
|
||||
if(pPriv->pSend)
|
||||
{
|
||||
free(pPriv->pSend);
|
||||
}
|
||||
if(pPriv->pGetError)
|
||||
{
|
||||
free(pPriv->pGetError);
|
||||
}
|
||||
if(pPriv->pTryFixIt)
|
||||
{
|
||||
free(pPriv->pTryFixIt);
|
||||
}
|
||||
if(pPriv->pWrapper)
|
||||
{
|
||||
free(pPriv->pWrapper);
|
||||
}
|
||||
if(pPriv->pName)
|
||||
{
|
||||
free(pPriv->pName);
|
||||
}
|
||||
free(pPriv);
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
pEVDriver CreateTclDriver(int argc, char *argv[],char *pName,
|
||||
SConnection *pCon)
|
||||
{
|
||||
pEVDriver pNew = NULL;
|
||||
pTclEv pPriv = NULL;
|
||||
int iRet;
|
||||
/* the "const" saves us from a couple of warnings M.Z.*/
|
||||
const char *pPtr = NULL;
|
||||
|
||||
if(argc < 1)/* we expect a Tcl array with all data */
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pPriv = (pTclEv)malloc(sizeof(TclEv));
|
||||
if(!pPriv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(pPriv,0,sizeof(TclEv));
|
||||
|
||||
/* find the names of all the functions we need in the Tcl Array */
|
||||
pPriv->pTcl = InterpGetTcl(pServ->pSics);
|
||||
assert(pPriv->pTcl);
|
||||
pPriv->pArray = strdup(argv[0]);
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"Init",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Init script not found",eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->pInit = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"Close",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Close script not found",eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->pClose = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"SetValue",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: SetValue script not found",eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->pSetValue = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"GetValue",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: GetValue script not found",eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->pGetValue = strdup(pPtr);
|
||||
}
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"Send",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Send script not found",eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->pSend = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"GetError",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: GetError script not found",eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->pGetError = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"TryFixIt",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: TryFixIt script not found",eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->pTryFixIt = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"Wrapper",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Wrapper script not found",eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPriv->pWrapper = strdup(pPtr);
|
||||
}
|
||||
static int TclSetValue(pEVDriver self, float fNew)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
|
||||
/* well all there, do the driver */
|
||||
pNew = CreateEVDriver(argc,argv);
|
||||
if(!pNew)
|
||||
{
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* handle the name */
|
||||
pPriv->pName = strdup(pName);
|
||||
pPtr = Tcl_SetVar2(pPriv->pTcl,argv[0],"MyName",pName, TCL_GLOBAL_ONLY);
|
||||
|
||||
/* initialise driver and functions */
|
||||
pNew->pPrivate = pPriv;
|
||||
pNew->SetValue = TclSetValue;
|
||||
pNew->GetValue = TclGetValue;
|
||||
pNew->Send = TclSend;
|
||||
pNew->GetError = TclGetError;
|
||||
pNew->TryFixIt = TclTryFixIt;
|
||||
pNew->Init = TclInit;
|
||||
pNew->Close = TclClose;
|
||||
pNew->KillPrivate = KillPrivate;
|
||||
|
||||
/* driver loaded, ready steady fire! */
|
||||
return pNew;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int UpdateTclVariable(pEVDriver self, char *name, float fVal)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[132];
|
||||
const char *pPtr = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pTclEv)self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
sprintf(pBueffel,"%f",fVal);
|
||||
pPtr = Tcl_SetVar2(pPriv->pTcl,pPriv->pArray,name,
|
||||
pBueffel,TCL_GLOBAL_ONLY);
|
||||
if(pPtr == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#define MAXLEN 2048
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TclEnvironmentWrapper(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
int iRet, i;
|
||||
char pBueffel[MAXLEN+1];
|
||||
pTclEv pPriv = NULL;
|
||||
pEVControl pEv = NULL;
|
||||
|
||||
pEv = (pEVControl)pData;
|
||||
assert(pEv);
|
||||
pPriv = pEv->pDriv->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel,"%s %s",pPriv->pWrapper,pPriv->pArray);
|
||||
for(i = 1; i < argc; i++)
|
||||
{
|
||||
if((strlen(pBueffel) + strlen(argv[i])) < MAXLEN)
|
||||
{
|
||||
strcat(pBueffel," ");
|
||||
strcat(pBueffel,argv[i]);
|
||||
}
|
||||
pPriv = (pTclEv) self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel, "%s %s %f", pPriv->pSetValue, pPriv->pArray, fNew);
|
||||
iRet = Tcl_Eval(pPriv->pTcl, pBueffel);
|
||||
if (iRet != TCL_OK) {
|
||||
strncpy(pBueffel, pPriv->pTcl->result, 1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl, pBueffel, &iErrCode);
|
||||
if (iRet != TCL_OK) {
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
/* execute Tcl */
|
||||
iRet = Tcl_Eval(pPriv->pTcl,pBueffel);
|
||||
if(iRet == TCL_OK)
|
||||
{
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int TclGetValue(pEVDriver self, float *fVal)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
double d;
|
||||
|
||||
pPriv = (pTclEv) self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel, "%s %s", pPriv->pGetValue, pPriv->pArray);
|
||||
iRet = Tcl_Eval(pPriv->pTcl, pBueffel);
|
||||
if (iRet != TCL_OK) {
|
||||
strncpy(pBueffel, pPriv->pTcl->result, 1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl, pBueffel, &iErrCode);
|
||||
if (iRet != TCL_OK) {
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
} else {
|
||||
if (strstr(pPriv->pTcl->result, "pending") != NULL) {
|
||||
*fVal = 90.;
|
||||
return -1;
|
||||
}
|
||||
iRet = Tcl_GetDouble(pPriv->pTcl, pPriv->pTcl->result, &d);
|
||||
if (iRet != TCL_OK) {
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
} else {
|
||||
*fVal = (float) d;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EVControlWrapper(pCon,pSics,pData,argc,argv);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int TclSend(pEVDriver self, char *pCommand,
|
||||
char *pReply, int iReplyLen)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
double d;
|
||||
|
||||
pPriv = (pTclEv) self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel, "%s %s %s", pPriv->pSend, pPriv->pArray, pCommand);
|
||||
iRet = Tcl_Eval(pPriv->pTcl, pBueffel);
|
||||
if (iRet != TCL_OK) {
|
||||
strncpy(pBueffel, pPriv->pTcl->result, 1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl, pBueffel, &iErrCode);
|
||||
if (iRet != TCL_OK) {
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
} else {
|
||||
strncpy(pReply, pPriv->pTcl->result, iReplyLen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int TclGetError(pEVDriver self, int *iCode,
|
||||
char *pReply, int iReplyLen)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
double d;
|
||||
|
||||
pPriv = (pTclEv) self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* do the iCode first */
|
||||
*iCode = pPriv->iLastError;
|
||||
|
||||
/* catch the stupid Tcl thing */
|
||||
if (pPriv->iLastError == STUPIDTCL) {
|
||||
sprintf(pBueffel,
|
||||
"Your Tcl-script returned a stupid answer:\n --> %s <--",
|
||||
pPriv->pTcl->result);
|
||||
strncpy(pReply, pBueffel, iReplyLen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel, "%s %s %d", pPriv->pGetError, pPriv->pArray,
|
||||
pPriv->iLastError);
|
||||
iRet = Tcl_Eval(pPriv->pTcl, pBueffel);
|
||||
if (iRet != TCL_OK) {
|
||||
strncpy(pBueffel, pPriv->pTcl->result, 1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl, pPriv->pTcl->result, &iErrCode);
|
||||
if (iRet != TCL_OK) {
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
} else {
|
||||
strncpy(pReply, pPriv->pTcl->result, iReplyLen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int TclTryFixIt(pEVDriver self, int iCode)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
double d;
|
||||
|
||||
pPriv = (pTclEv) self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
|
||||
/* catch the stupid Tcl thing */
|
||||
if (iCode == STUPIDTCL) {
|
||||
return DEVREDO;
|
||||
}
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel, "%s %s %d", pPriv->pTryFixIt, pPriv->pArray, iCode);
|
||||
iRet = Tcl_Eval(pPriv->pTcl, pBueffel);
|
||||
if (iRet != TCL_OK) {
|
||||
return DEVFAULT;
|
||||
} else {
|
||||
if (strcmp(pPriv->pTcl->result, "DEVFAULT") == 0) {
|
||||
return DEVFAULT;
|
||||
} else if (strcmp(pPriv->pTcl->result, "DEVREDO") == 0) {
|
||||
return DEVREDO;
|
||||
} else if (strcmp(pPriv->pTcl->result, "DEVOK") == 0) {
|
||||
return DEVOK;
|
||||
} else {
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int TclInit(pEVDriver self)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
|
||||
pPriv = (pTclEv) self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel, "%s %s", pPriv->pInit, pPriv->pArray);
|
||||
iRet = Tcl_Eval(pPriv->pTcl, pBueffel);
|
||||
if (iRet != TCL_OK) {
|
||||
strncpy(pBueffel, pPriv->pTcl->result, 1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl, pBueffel, &iErrCode);
|
||||
if (iRet != TCL_OK) {
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int TclClose(pEVDriver self)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[1024];
|
||||
int iRet, iErrCode;
|
||||
|
||||
pPriv = (pTclEv) self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel, "%s %s", pPriv->pClose, pPriv->pArray);
|
||||
iRet = Tcl_Eval(pPriv->pTcl, pBueffel);
|
||||
if (iRet != TCL_OK) {
|
||||
strncpy(pBueffel, pPriv->pTcl->result, 1023);
|
||||
iRet = Tcl_GetInt(pPriv->pTcl, pBueffel, &iErrCode);
|
||||
if (iRet != TCL_OK) {
|
||||
pPriv->iLastError = STUPIDTCL;
|
||||
return 0;
|
||||
}
|
||||
pPriv->iLastError = iErrCode;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void KillPrivate(void *pData)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
|
||||
pPriv = (pTclEv) pData;
|
||||
assert(pPriv);
|
||||
|
||||
if (pPriv->pArray) {
|
||||
free(pPriv->pArray);
|
||||
}
|
||||
if (pPriv->pInit) {
|
||||
free(pPriv->pInit);
|
||||
}
|
||||
if (pPriv->pClose) {
|
||||
free(pPriv->pClose);
|
||||
}
|
||||
if (pPriv->pSetValue) {
|
||||
free(pPriv->pSetValue);
|
||||
}
|
||||
if (pPriv->pGetValue) {
|
||||
free(pPriv->pGetValue);
|
||||
}
|
||||
if (pPriv->pSend) {
|
||||
free(pPriv->pSend);
|
||||
}
|
||||
if (pPriv->pGetError) {
|
||||
free(pPriv->pGetError);
|
||||
}
|
||||
if (pPriv->pTryFixIt) {
|
||||
free(pPriv->pTryFixIt);
|
||||
}
|
||||
if (pPriv->pWrapper) {
|
||||
free(pPriv->pWrapper);
|
||||
}
|
||||
if (pPriv->pName) {
|
||||
free(pPriv->pName);
|
||||
}
|
||||
free(pPriv);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
pEVDriver CreateTclDriver(int argc, char *argv[], char *pName,
|
||||
SConnection * pCon)
|
||||
{
|
||||
pEVDriver pNew = NULL;
|
||||
pTclEv pPriv = NULL;
|
||||
int iRet;
|
||||
/* the "const" saves us from a couple of warnings M.Z. */
|
||||
const char *pPtr = NULL;
|
||||
|
||||
if (argc < 1) { /* we expect a Tcl array with all data */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pPriv = (pTclEv) malloc(sizeof(TclEv));
|
||||
if (!pPriv) {
|
||||
return NULL;
|
||||
}
|
||||
memset(pPriv, 0, sizeof(TclEv));
|
||||
|
||||
/* find the names of all the functions we need in the Tcl Array */
|
||||
pPriv->pTcl = InterpGetTcl(pServ->pSics);
|
||||
assert(pPriv->pTcl);
|
||||
pPriv->pArray = strdup(argv[0]);
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl, argv[0], "Init", TCL_GLOBAL_ONLY);
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "ERROR: Init script not found", eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
} else {
|
||||
pPriv->pInit = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl, argv[0], "Close", TCL_GLOBAL_ONLY);
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "ERROR: Close script not found", eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
} else {
|
||||
pPriv->pClose = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl, argv[0], "SetValue", TCL_GLOBAL_ONLY);
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "ERROR: SetValue script not found", eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
} else {
|
||||
pPriv->pSetValue = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl, argv[0], "GetValue", TCL_GLOBAL_ONLY);
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "ERROR: GetValue script not found", eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
} else {
|
||||
pPriv->pGetValue = strdup(pPtr);
|
||||
}
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl, argv[0], "Send", TCL_GLOBAL_ONLY);
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "ERROR: Send script not found", eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
} else {
|
||||
pPriv->pSend = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl, argv[0], "GetError", TCL_GLOBAL_ONLY);
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "ERROR: GetError script not found", eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
} else {
|
||||
pPriv->pGetError = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl, argv[0], "TryFixIt", TCL_GLOBAL_ONLY);
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "ERROR: TryFixIt script not found", eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
} else {
|
||||
pPriv->pTryFixIt = strdup(pPtr);
|
||||
}
|
||||
pPtr = NULL;
|
||||
pPtr = Tcl_GetVar2(pPriv->pTcl, argv[0], "Wrapper", TCL_GLOBAL_ONLY);
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "ERROR: Wrapper script not found", eError);
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
} else {
|
||||
pPriv->pWrapper = strdup(pPtr);
|
||||
}
|
||||
|
||||
/* well all there, do the driver */
|
||||
pNew = CreateEVDriver(argc, argv);
|
||||
if (!pNew) {
|
||||
KillPrivate(pPriv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* handle the name */
|
||||
pPriv->pName = strdup(pName);
|
||||
pPtr =
|
||||
Tcl_SetVar2(pPriv->pTcl, argv[0], "MyName", pName, TCL_GLOBAL_ONLY);
|
||||
|
||||
/* initialise driver and functions */
|
||||
pNew->pPrivate = pPriv;
|
||||
pNew->SetValue = TclSetValue;
|
||||
pNew->GetValue = TclGetValue;
|
||||
pNew->Send = TclSend;
|
||||
pNew->GetError = TclGetError;
|
||||
pNew->TryFixIt = TclTryFixIt;
|
||||
pNew->Init = TclInit;
|
||||
pNew->Close = TclClose;
|
||||
pNew->KillPrivate = KillPrivate;
|
||||
|
||||
/* driver loaded, ready steady fire! */
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int UpdateTclVariable(pEVDriver self, char *name, float fVal)
|
||||
{
|
||||
pTclEv pPriv = NULL;
|
||||
char pBueffel[132];
|
||||
const char *pPtr = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pTclEv) self->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
sprintf(pBueffel, "%f", fVal);
|
||||
pPtr = Tcl_SetVar2(pPriv->pTcl, pPriv->pArray, name,
|
||||
pBueffel, TCL_GLOBAL_ONLY);
|
||||
if (pPtr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define MAXLEN 2048
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TclEnvironmentWrapper(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
int iRet, i;
|
||||
char pBueffel[MAXLEN + 1];
|
||||
pTclEv pPriv = NULL;
|
||||
pEVControl pEv = NULL;
|
||||
|
||||
pEv = (pEVControl) pData;
|
||||
assert(pEv);
|
||||
pPriv = pEv->pDriv->pPrivate;
|
||||
assert(pPriv);
|
||||
|
||||
/* build command line */
|
||||
sprintf(pBueffel, "%s %s", pPriv->pWrapper, pPriv->pArray);
|
||||
for (i = 1; i < argc; i++) {
|
||||
if ((strlen(pBueffel) + strlen(argv[i])) < MAXLEN) {
|
||||
strcat(pBueffel, " ");
|
||||
strcat(pBueffel, argv[i]);
|
||||
}
|
||||
}
|
||||
/* execute Tcl */
|
||||
iRet = Tcl_Eval(pPriv->pTcl, pBueffel);
|
||||
if (iRet == TCL_OK) {
|
||||
return 1;
|
||||
} else {
|
||||
return EVControlWrapper(pCon, pSics, pData, argc, argv);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user