PSI sics-cvs-psi-2008-10-02
This commit is contained in:
214
macro.c
214
macro.c
@@ -2,7 +2,7 @@
|
||||
|
||||
All you need to evaluate macros with SICS
|
||||
|
||||
The implmentation for the macro stuff is complex and non intuitive.
|
||||
The implementation for the macro stuff is complex and non intuitive.
|
||||
This is the price to pay for adding the extremly powerful and
|
||||
strong Tcl-interpreter to SICS. The problem is that Tcl does not
|
||||
know anything about connections and our error handling. We have
|
||||
@@ -61,16 +61,16 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <tcl.h>
|
||||
#include "SCinter.h"
|
||||
#include "conman.h"
|
||||
#include "macro.h"
|
||||
#include <sics.h>
|
||||
#include "status.h"
|
||||
#include "obdes.h"
|
||||
#include "macro.h"
|
||||
#include "splitter.h"
|
||||
#include "ifile.h"
|
||||
#include "Dbg.h"
|
||||
#include "servlog.h"
|
||||
#include "stringdict.h"
|
||||
#include "exeman.h"
|
||||
#include "nxcopy.h"
|
||||
|
||||
#define SICSERROR "005567SICS"
|
||||
/*----------------------------------------------------------------------------
|
||||
@@ -131,7 +131,8 @@
|
||||
char *lastCommand = NULL, comBuffer[132];
|
||||
int iRet = 0,i;
|
||||
int iMacro;
|
||||
|
||||
Statistics *old;
|
||||
|
||||
/* get the datastructures */
|
||||
pSics = (struct __SicsUnknown *)pData;
|
||||
assert(pSics);
|
||||
@@ -180,7 +181,9 @@
|
||||
/* invoke */
|
||||
iMacro = SCinMacro(pCon);
|
||||
SCsetMacro(pCon,1);
|
||||
old=StatisticsBegin(pCommand->stat);
|
||||
iRet = pCommand->OFunc(pCon,pSinter,pCommand->pData,margc, myarg);
|
||||
StatisticsEnd(old);
|
||||
SCsetMacro(pCon,iMacro);
|
||||
/*
|
||||
lastUnkown gets deeply stacked with each SICS command exec'd.
|
||||
@@ -299,7 +302,8 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
/*--------------------------------------------------------------------------
|
||||
initialises a Tcl-Interpreter, installs SICS unknown mechanism and kills
|
||||
a few dangerous commands from the normal Tcl command set
|
||||
*/
|
||||
----------------------------------------------------------------------------*/
|
||||
extern int Nxinter_SafeInit(Tcl_Interp *pTcl); /* from Swig NeXus Tcl interface */
|
||||
|
||||
Tcl_Interp *MacroInit(SicsInterp *pSics)
|
||||
{
|
||||
@@ -343,6 +347,9 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
*/
|
||||
Tcl_CreateObjCommand(pInter,"exec",ProtectedExec,NULL,KillExec);
|
||||
|
||||
Nxinter_SafeInit(pInter);
|
||||
NXcopy_Init(pInter);
|
||||
|
||||
return pInter;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -431,6 +438,21 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int MacroFileEvalNew(SConnection *pCon, SicsInterp *pInter, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
void *pCom = NULL;
|
||||
pCom = FindCommandData(pInter,"exe","ExeManager");
|
||||
assert(pCom != NULL);
|
||||
|
||||
if(argc < 2){
|
||||
SCWrite(pCon,"ERROR: no batch buffer to execute specified",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
return runExeBatchBuffer(pCom,pCon,pInter,argv[1]);
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int MacroFileEval(SConnection *pCon, SicsInterp *pInter, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
@@ -459,8 +481,8 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
/* open filename */
|
||||
if( argc < 2)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: No filename specified ",eError);
|
||||
return 0;
|
||||
SCWrite(pCon,"ERROR: No filename specified ",eError);
|
||||
return 0;
|
||||
}
|
||||
fp = fopen(argv[1],"r");
|
||||
if(!fp)
|
||||
@@ -490,7 +512,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
{
|
||||
iChar = fgetc(fp);
|
||||
if(iChar == EOF)
|
||||
{
|
||||
{
|
||||
iChar = (int)'\n';
|
||||
iRun = 0;
|
||||
}
|
||||
@@ -505,11 +527,11 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
SetStatus(eEager);
|
||||
FirstWord(pCom,pBueffel);
|
||||
if(FindCommand(pInter,pBueffel) != NULL)
|
||||
{
|
||||
{
|
||||
sprintf(pBueffel,"%s:%d>> %s",pFile,iLine,pCom);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
if(pWhere != NULL)
|
||||
{
|
||||
{
|
||||
free(pWhere);
|
||||
}
|
||||
pWhere = strdup(pBueffel);
|
||||
@@ -524,16 +546,16 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
{ /* Tcl error */
|
||||
if(strlen(pTcl->result) > 2)
|
||||
{
|
||||
/*
|
||||
local copy in order to resolve a valgrind error
|
||||
*/
|
||||
strncpy(pBueffel,pTcl->result,511);
|
||||
/*
|
||||
local copy in order to resolve a valgrind error
|
||||
*/
|
||||
strncpy(pBueffel,pTcl->result,511);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
}
|
||||
pCom = Tcl_DStringValue(&command);
|
||||
SCWrite(pCon,"ERROR: in Tcl block:",eError);
|
||||
SCWrite(pCon,"ERROR: in Tcl block:",eError);
|
||||
SCWrite(pCon,pCom,eError);
|
||||
SCWrite(pCon,"ERROR: end of Tcl error block",eError);
|
||||
SCWrite(pCon,"ERROR: end of Tcl error block",eError);
|
||||
}
|
||||
else /* SICS error */
|
||||
{
|
||||
@@ -546,7 +568,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
fclose(fp);
|
||||
Tcl_DStringFree(&command);
|
||||
SCWrite(pCon,"ERROR: batch processing interrupted",eError);
|
||||
SetStatus(eEager);
|
||||
SetStatus(eEager);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -753,6 +775,127 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int GumPut(SConnection *pCon, SicsInterp *pInter, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
OutCode eOut = eWarning;
|
||||
int i = 0, iCode, iLen;
|
||||
int iMacro;
|
||||
char *ppCode;
|
||||
char *pMessage = NULL;
|
||||
commandContext cc;
|
||||
|
||||
assert(pCon);
|
||||
assert(pInter);
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
SCWrite(pCon,"Insufficient arguments to ClientPut",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handle optional I/O codes */
|
||||
if(argc > 2)
|
||||
{
|
||||
/* the last one must be the code */
|
||||
iCode = argc - 1;
|
||||
ppCode = strdup(argv[iCode]);
|
||||
strtolower(ppCode);
|
||||
while(pCode[i] != NULL)
|
||||
{
|
||||
if(strcmp(pCode[i],ppCode) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(ppCode)
|
||||
{
|
||||
free(ppCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 10;
|
||||
iCode = argc;
|
||||
}
|
||||
|
||||
switch(i)
|
||||
{
|
||||
case 0:
|
||||
eOut = eInternal;
|
||||
break;
|
||||
case 1:
|
||||
eOut = eCommand;
|
||||
break;
|
||||
case 2:
|
||||
eOut = eHWError;
|
||||
break;
|
||||
case 3:
|
||||
eOut = eInError;
|
||||
break;
|
||||
case 4:
|
||||
eOut = eStatus;
|
||||
break;
|
||||
case 5:
|
||||
eOut = eValue;
|
||||
break;
|
||||
case 6:
|
||||
eOut = eWarning;
|
||||
break;
|
||||
case 7:
|
||||
eOut = eFinish;
|
||||
break;
|
||||
case 8:
|
||||
eOut = eEvent;
|
||||
break;
|
||||
case 9:
|
||||
eOut = eWarning;
|
||||
break;
|
||||
case 10:
|
||||
eOut = eError;
|
||||
break;
|
||||
default:
|
||||
eOut = eWarning;
|
||||
iCode = argc;
|
||||
break;
|
||||
}
|
||||
|
||||
/* recombine the message */
|
||||
/* find length */
|
||||
iLen = 0;
|
||||
for(i = 1; i < iCode; i++)
|
||||
{
|
||||
iLen += strlen(argv[i]);
|
||||
}
|
||||
pMessage = (char *)malloc((iLen+100)*sizeof(char));
|
||||
if(!pMessage)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory in clientput",eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pMessage,0,(iLen+100)*sizeof(char));
|
||||
Arg2Text(iCode-1,&argv[1],pMessage,(iLen+100)*sizeof(char));
|
||||
|
||||
/* now write, thereby tunneling macro flag in order to get proper
|
||||
write to client and not into interpreter. We also make sure that the device
|
||||
is gumput
|
||||
*/
|
||||
iMacro = SCinMacro(pCon);
|
||||
SCsetMacro(pCon,0);
|
||||
cc = SCGetContext(pCon);
|
||||
strcpy(cc.deviceID,"gumput");
|
||||
SCPushContext2(pCon,cc);
|
||||
SCWrite(pCon,pMessage,eOut);
|
||||
SCPopContext(pCon);
|
||||
SCsetMacro(pCon,iMacro);
|
||||
if(pMessage)
|
||||
{
|
||||
free(pMessage);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int Broadcast(SConnection *pCon, SicsInterp *pInter, void *pData,
|
||||
int argc, char *argv[])
|
||||
@@ -865,7 +1008,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
}
|
||||
|
||||
/* make a string */
|
||||
pCommand = Arg2Tcl(argc,argv,pBueffel,sizeof(pBueffel));
|
||||
pCommand = Arg2Tcl0(argc-1,argv+1,pBueffel,sizeof(pBueffel),self->command);
|
||||
if (!pCommand) {
|
||||
SCWrite(pCon, "ERROR: no more memory", eError);
|
||||
return 0;
|
||||
@@ -874,14 +1017,9 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
if (pCommand != pBueffel) free(pCommand);
|
||||
if(iRet == TCL_OK)
|
||||
{
|
||||
/* we do not now why, but at some time it was found that
|
||||
we need a copy, and can not use pTcl->result directly
|
||||
|
||||
SCWrite(pCon,pTcl->result,eStatus);
|
||||
|
||||
let us use SCPrintf, which maked always a copy
|
||||
*/
|
||||
SCPrintf(pCon, eStatus, "%s", pTcl->result);
|
||||
if(strlen(pTcl->result) > 0){
|
||||
SCPrintf(pCon, eStatus, "%s", pTcl->result);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@@ -895,8 +1033,6 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
}
|
||||
return 1; /* not reached */
|
||||
}
|
||||
|
||||
#include "access.c"
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TclPublish(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
@@ -904,7 +1040,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
pPubTcl pNew = NULL;
|
||||
char pBueffel[132];
|
||||
int iUser, i, iRet;
|
||||
|
||||
|
||||
/* check no of args */
|
||||
if(argc < 3)
|
||||
{
|
||||
@@ -923,18 +1059,10 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* try convert last parameter to user code */
|
||||
iUser = 0;
|
||||
strtolower(argv[2]);
|
||||
while(aCode[iUser] != NULL)
|
||||
{
|
||||
if(strcmp(aCode[iUser],argv[2]) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
iUser++;
|
||||
}
|
||||
if(iUser > iCodes)
|
||||
iUser = decodeSICSPriv(argv[2]);
|
||||
if(iUser < 0)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: cannot identify %s as a valid user code",
|
||||
argv[2]);
|
||||
@@ -947,7 +1075,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
if (pNew)
|
||||
{ /* yes -> overwrite access code */
|
||||
pNew->iUser = iUser;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
/* do a job !*/
|
||||
pNew = CreatePublish(argv[1],iUser);
|
||||
|
||||
Reference in New Issue
Block a user