181 lines
4.5 KiB
C
181 lines
4.5 KiB
C
/* -------------------------------------------------------------------------
|
|
This class allows for the implementation off SICS internal interfaces
|
|
through Tcl scripts. Additionally, helper functions for supporting such
|
|
scripts are provided.
|
|
|
|
This is the first implementation which only supports saving additional
|
|
data into status files. This is the object decriptor interface.
|
|
|
|
copyright: see file COPYRIGHT
|
|
|
|
Mark Koennecke, May 2003
|
|
------------------------------------------------------------------------*/
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <tcl.h>
|
|
#include "fortify.h"
|
|
#include "splitter.h"
|
|
#include "tclintimpl.h"
|
|
/*================== our data structure ===================================*/
|
|
typedef struct {
|
|
pObjectDescriptor pDes;
|
|
pIDrivable pDriv;
|
|
char *saveScript;
|
|
FILE *fd;
|
|
} tclInt, *pTclInt;
|
|
/*======================= interface functions ============================*/
|
|
static int TclSaveStatus(void *pData, char *name, FILE *fd){
|
|
pTclInt self = NULL;
|
|
char pBuffer[1024];
|
|
|
|
self = (pTclInt)pData;
|
|
assert(self);
|
|
|
|
if(self->saveScript == NULL){
|
|
return 1;
|
|
}
|
|
|
|
if(strlen(self->saveScript) + strlen(name) + 2 >= 1023){
|
|
fprintf(fd,"#ERROR: arguments to long for save scripting");
|
|
return 1;
|
|
}
|
|
strcpy(pBuffer,self->saveScript);
|
|
strcat(pBuffer," ");
|
|
strcat(pBuffer,name);
|
|
self->fd = fd;
|
|
|
|
Tcl_Eval(InterpGetTcl(pServ->pSics),pBuffer);
|
|
self->fd = NULL;
|
|
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
static void *TclGetInterface(void *pData, int id){
|
|
pTclInt self = NULL;
|
|
self = (pTclInt)pData;
|
|
if(self == NULL){
|
|
return NULL;
|
|
}
|
|
|
|
if(id == DRIVEID){
|
|
return self->pDriv;
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
/*======================== data structure creation and deletion ==========*/
|
|
static pTclInt MakeTclIntData(void){
|
|
pTclInt pNew = NULL;
|
|
|
|
pNew = (pTclInt)malloc(sizeof(tclInt));
|
|
if(pNew == NULL){
|
|
return NULL;
|
|
}
|
|
memset(pNew,0,sizeof(tclInt));
|
|
pNew->pDes = CreateDescriptor("SICS Interfaces in Tcl");
|
|
pNew->pDes->SaveStatus = TclSaveStatus;
|
|
pNew->pDes->GetInterface = TclGetInterface;
|
|
pNew->pDriv = CreateDrivableInterface();
|
|
if(!pNew->pDes || !pNew->pDriv){
|
|
free(pNew);
|
|
return NULL;
|
|
}
|
|
return pNew;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static void KillTclInt(void *pData){
|
|
pTclInt self = NULL;
|
|
|
|
self = (pTclInt)pData;
|
|
if(self == NULL){
|
|
return;
|
|
}
|
|
|
|
if(self->pDes != NULL){
|
|
DeleteDescriptor(self->pDes);
|
|
}
|
|
if(self->saveScript != NULL){
|
|
free(self->saveScript);
|
|
}
|
|
if(self->pDriv){
|
|
free(self->pDriv);
|
|
}
|
|
free(self);
|
|
}
|
|
/*=============== interpreter interface + helper functions =============*/
|
|
int MakeTclInt(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]){
|
|
pTclInt pNew = NULL;
|
|
char pBuffer[132];
|
|
int iRet;
|
|
|
|
if(argc < 2) {
|
|
SCWrite(pCon,"ERROR: I need a name argument for the script interface",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
pNew = MakeTclIntData();
|
|
if(pNew == NULL){
|
|
SCWrite(pCon,"ERROR: no memory to create SICS script interface",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
iRet = AddCommand(pSics,argv[1],TclIntAction,KillTclInt,(void *)pNew);
|
|
if(!iRet){
|
|
sprintf(pBuffer,"ERROR: duplicate command %s not created",argv[1]);
|
|
SCWrite(pCon,pBuffer,eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
int TclIntAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]){
|
|
pTclInt self = NULL;
|
|
char pBuffer[1024];
|
|
char *cmd;
|
|
|
|
self = (pTclInt)pData;
|
|
assert(self);
|
|
if(argc < 2){
|
|
sprintf(pBuffer,"ERROR: %s expects at least one argument!", argv[0]);
|
|
SCWrite(pCon,pBuffer,eError);
|
|
return 0;
|
|
}
|
|
|
|
strtolower(argv[1]);
|
|
if(strcmp(argv[1],"savescript") == 0){
|
|
if(argc < 3){
|
|
SCWrite(pCon,"ERROR: missing argument to savescript",eError);
|
|
return 0;
|
|
}
|
|
if(self->saveScript != NULL){
|
|
free(self->saveScript);
|
|
self->saveScript = NULL;
|
|
}
|
|
self->saveScript = strdup(argv[2]);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if(strcmp(argv[1],"backup") == 0){
|
|
cmd = Arg2Tcl(argc-2, &argv[2],pBuffer,1023);
|
|
if (cmd) {
|
|
if(self->fd != NULL){
|
|
fprintf(self->fd,"%s\n",cmd);
|
|
}
|
|
if (cmd != pBuffer) free(cmd);
|
|
SCSendOK(pCon);
|
|
}
|
|
return 1;
|
|
} else {
|
|
sprintf(pBuffer,"ERROR: keyword %s to %s not recognized",
|
|
argv[1],argv[0]);
|
|
SCWrite(pCon,pBuffer,eError);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|