Files
sics/tclintimpl.c
koennecke 8cc5474334 - After a bug at TRICS I replaced all occurrences of strcpy, strcat, sprintf
by length limited versions wherever appropriate.


SKIPPED:
	psi/el755driv.c
	psi/faverage.c
	psi/frame.c
	psi/lmd200.c
	psi/polterwrite.c
	psi/psi.c
	psi/sanswave.c
	psi/sinqhmdriv.c
	psi/termprot.c
2009-12-04 12:58:31 +00:00

202 lines
4.9 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) {
snprintf(pBuffer,sizeof(pBuffer)-1, "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;
float val;
self = (pTclInt) pData;
assert(self);
if (argc < 2) {
if (self->pDriv->GetValue != NULL) {
val = self->pDriv->GetValue(self, pCon);
snprintf(pBuffer, 1024, "%s = %f", argv[0], val);
SCWrite(pCon, pBuffer, eValue);
return 1;
} else {
snprintf(pBuffer,sizeof(pBuffer)-1, "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 {
snprintf(pBuffer,sizeof(pBuffer)-1, "ERROR: keyword %s to %s not recognized",
argv[1], argv[0]);
SCWrite(pCon, pBuffer, eError);
return 0;
}
return 1;
}