- Introducted Arg2Tcl as a replacement for some calls to Arg2Text

- Fixed a memory leak
This commit is contained in:
zolliker
2006-04-11 07:26:55 +00:00
parent e25fb68080
commit da3dfd9d76
11 changed files with 184 additions and 92 deletions

View File

@ -132,7 +132,10 @@ extern pServer pServ;
}
do
{ /* loop until an unused ident is found */
{ /* loop until an unused ident is found. This test needed only for
the case there some object has already the name con<nnn>.
In a live cycle of SICS, no connection ever can get an earlier
used name */
if (lastIdent == LONG_MAX)
{
/* This is a serious, very serious error! */
@ -1722,6 +1725,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
pCBAction pCB = NULL;
CommandList *pCom = NULL;
int iMacro;
char *script;
self = (SConnection *)pData;
if(!VerifyConnection(self))
@ -1781,17 +1785,18 @@ static void writeToLogFiles(SConnection *self, char *buffer)
return 0;
}
script = Arg2Tcl(argc-4, &argv[4], NULL, 0);
/* now we can install the callback */
pCB = (pCBAction)malloc(sizeof(CBAction));
if(!pCB)
if(!pCB || !script)
{
SCWrite(pCon,"ERROR: memory exhausted in SConnection",eError);
return 0;
}
Arg2Text(argc-4, &argv[4],pBueffel,1023);
pCB->pCon = pCon;
pCB->pSics = pSics;
pCB->pAction = strdup(pBueffel);
pCB->pAction = script;
sItem.pInterface = pInterface;
sItem.lID = RegisterCallback(pInterface, SCGetContext(pCB->pCon), iEvent, ConCallBack,
pCB, CBKill);

4
emon.c
View File

@ -85,8 +85,7 @@
/* remove all the names */
/*
iRet == LLDnodePtr2First(self->iList);
iRet = LLDnodePtr2First(self->iList);
while(iRet != 0)
{
LLDnodeDataTo(self->iList,&sEntry);
@ -97,7 +96,6 @@
}
iRet = LLDnodePtr2Next(self->iList);
}
*/
/* remove list */
LLDdelete(self->iList);

View File

@ -1214,12 +1214,11 @@ static void ErrReport(pEVControl self)
strtolower(argv[1]);
if(strcmp(argv[1],"errorscript") == 0)
{
Arg2Text(argc-2,&argv[2],pBueffel,255);
if(self->errorScript != NULL)
{
free(self->errorScript);
}
self->errorScript = strdup(pBueffel);
self->errorScript = Arg2Tcl(argc-2,&argv[2],NULL,0);
SCSendOK(pCon);
SCparChange(pCon);
return 1;
@ -1542,8 +1541,7 @@ int RemoveEVController(SConnection *pCon, char *name) {
return 0;
}
if (pNew->pDriv->SavePars) {
Arg2Text(argc-3, argv+3, pBueffel, sizeof pBueffel);
pNew->creationArgs = strdup(pBueffel);
pNew->creationArgs = Arg2Tcl(argc-3, argv+3, NULL, 0);
pNew->pDes->SaveStatus = EVSaveStatus;
} else {
pNew->creationArgs = NULL;

65
macro.c
View File

@ -174,6 +174,7 @@
return TCL_ERROR;
}
}
if (pSics->lastUnknown[pSics->iStack]) free(pSics->lastUnknown[pSics->iStack]);
pSics->lastUnknown[pSics->iStack] = strdup(comBuffer);
/* invoke */
@ -181,7 +182,6 @@
SCsetMacro(pCon,1);
iRet = pCommand->OFunc(pCon,pSinter,pCommand->pData,margc, myarg);
SCsetMacro(pCon,iMacro);
/*
lastUnkown gets deeply stacked with each SICS command exec'd.
This is not reflected in code. However, lastUnknown has already
@ -844,6 +844,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
int argc, char *argv[])
{
char pBueffel[1024];
char *pCommand;
pPubTcl self = NULL;
int iRet, length;
char *pPtr;
@ -864,45 +865,32 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
}
/* make a string */
Arg2Text(argc,argv,pBueffel,1023);
iRet = Tcl_Eval(pTcl,pBueffel);
pCommand = Arg2Tcl(argc,argv,pBueffel,sizeof(pBueffel));
if (!pCommand) {
SCWrite(pCon, "ERROR: no more memory", eError);
return 0;
}
iRet = Tcl_Eval(pTcl,pCommand);
if (pCommand != pBueffel) free(pCommand);
if(iRet == TCL_OK)
{ length = strlen(pTcl->result);
if(length < 1024){
strncpy(pBueffel,pTcl->result,1023);
SCWrite(pCon,pBueffel,eStatus);
} else {
length += 10;
pPtr = (char *)malloc(length*sizeof(char));
if(pPtr == NULL){
SCWrite(pCon,
"ERROR: out of memory in TclAction",
eError);
return 0;
}
memset(pPtr,0,length*sizeof(char));
strncpy(pPtr,pTcl->result,length-1);
SCWrite(pCon,pPtr,eStatus);
free(pPtr);
}
{
/* 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);
return 1;
}
else
{
if(Tcl_GetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY) == NULL)
{
pPtr = strdup(pTcl->result);
SCWrite(pCon,pPtr,eError);
free(pPtr);
}
else
if(Tcl_GetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY) != NULL)
{
Tcl_UnsetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY);
strncpy(pBueffel,pTcl->result,1023);
SCWrite(pCon,pBueffel,eError);
}
SCPrintf(pCon,eError,"%s",pTcl->result);
return 0;
}
return 1; /* not reached */
@ -990,16 +978,21 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
int TransactAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
char pCommand[1024], pStart[1024];
char pBuffer[1024];
char *pCommand;
int iRet;
Arg2Text(argc-1,&argv[1],pCommand,1023);
pCommand = Arg2Tcl(argc-1,&argv[1],pBuffer, sizeof(pBuffer));
if (!pCommand) {
SCWrite(pCon,"ERROR: no memory", eError);
return 0;
}
strtolower(argv[0]);
if(strcmp(argv[0],"fulltransact") == 0){
snprintf(pStart,1023,"TRANSACTIONSTART %s",pCommand);
SCWrite(pCon,pStart,eError);
SCPrintf(pCon,eError, "TRANSACTIONSTART %s",pCommand);
}
iRet = InterpExecute(pSics,pCon,pCommand);
if (pCommand != pBuffer) free(pCommand);
SCWrite(pCon,"TRANSACTIONFINISHED",eError);
return iRet;
}

View File

@ -171,7 +171,8 @@ void DeleteProtocol(void *self)
static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
commandContext comCon;
char command[1024];
char buffer[1024];
char *command;
int status;
if(argc < 3){
@ -186,11 +187,15 @@ static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
strncpy(comCon.deviceID,argv[2],SCDEVIDLEN);
memset(command,0,1024*sizeof(char));
Arg2Text(argc-2,&argv[2],command,1023);
memset(buffer,0,sizeof(buffer));
command = Arg2Tcl(argc-2,&argv[2],buffer,sizeof buffer);
if (!command) {
SCWrite(pCon,"ERROR: no more memory",eError);
return 0;
}
SCPushContext2(pCon,comCon);
status = InterpExecute(pSics,pCon,command);
if (command != buffer) free(command);
SCPopContext(pCon);
return status;
}

18
remob.c
View File

@ -534,7 +534,11 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
float fValue;
long lID;
char *endp;
char *argv0;
char *cmd;
/*
char acce[128], inte[128];
*/
int rights;
RemChannel *rc;
@ -550,16 +554,19 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
if (argc == 1) {
iRet = RemTransact(remserver, rc, pCon, argv[0], ">", NULL);
} else if (strcasecmp(argv[1],"list") == 0) {
snprintf(buf, sizeof(buf), "%s ", remob->name);
i = strlen(buf);
Arg2Text(argc-1, argv+1, buf + i, sizeof buf - i);
/*
snprintf(acce, sizeof(acce), "!%s.accesscode", remob->name);
snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name);
*/
RemTransact(remserver, rc, pCon, buf, ">", NULL);
argv0 = argv[0];
argv[0] = remob->name;
cmd = Arg2Tcl(argc, argv, buf, sizeof buf);
argv[0] = argv0;
if (cmd) {
RemTransact(remserver, rc, pCon, cmd, ">", NULL);
if (cmd != buf) free(cmd);
}
iRet=1;
} else {
pos=snprintf(buf, sizeof(buf), "%s ", remob->name);
@ -620,7 +627,6 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
float fValue;
long lID;
char *endp, *serverport, *thishostname;
char acce[128], inte[128];
struct sockaddr_in adr;
struct hostent *thishost;
Remob *p, *next;

View File

@ -411,6 +411,7 @@
char pBueffel[256];
Tcl_Interp *pTcl = NULL;
int iRet;
char *cmd;
assert(pCon);
assert(pSics);
@ -425,8 +426,13 @@
pTcl = InterpGetTcl(pSics);
assert(pTcl);
Arg2Text(argc-1,&argv[1],pBueffel,255);
iRet = Tcl_Eval(pTcl,pBueffel);
cmd = Arg2Tcl(argc-1,&argv[1],pBueffel,sizeof pBueffel);
if (!cmd) {
SCWrite(pCon,"ERROR: no more memory",eError);
return 0;
}
iRet = Tcl_Eval(pTcl,cmd);
if (cmd != pBueffel) free(cmd);
if(strlen(pTcl->result) > 1)
{
SCWrite(pCon,pTcl->result,eValue);

View File

@ -83,7 +83,7 @@
{
pCron pNew = NULL;
int iVal, iRet;
char pBueffel[512];
char *cmd;
/* only managers may do this */
if(!SCMatchRights(pCon,usMugger))
@ -108,11 +108,11 @@
}
/* concatenate the rest to the command */
Arg2Text(argc-2,&argv[2],pBueffel,511);
cmd = Arg2Tcl(argc-2,&argv[2],NULL,0);
/* create data structure and install task */
pNew = (pCron)malloc(sizeof(Cron));
if(!pNew)
if(!pNew || !cmd)
{
SCWrite(pCon,"ERROR: out of memory in sicscron",eError);
return 0;
@ -124,7 +124,7 @@
return 0;
}
pNew->iIntervall = iVal;
pNew->pCommand = strdup(pBueffel);
pNew->pCommand = cmd;
pNew->tNext = 0;
pNew->iEnd = 1;

View File

@ -11,6 +11,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "tcl.h"
#include "splitter.h"
typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
@ -116,7 +117,7 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
char pBueffel[132];
char *pChar;
CharType eWhat;
int i;
int i, n;
if(!pLine)return NULL;
@ -142,9 +143,14 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
pChar++;
while( (isEnd(*pChar) != 2) && (CheckSpecial(pChar) != eQuote))
{
pBueffel[i] = *pChar;
if (*pChar == '\\') {
pBueffel[i] = Tcl_Backslash(pChar, &n);
pChar += n;
} else {
pBueffel[i] = *pChar;
pChar++;
}
i++;
pChar++;
}
pBueffel[i] = '\0';
pChar++;
@ -226,17 +232,14 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
/* loop through arguments */
for( i = 0; i < argc; i++)
{
/* figure out what we have */
for(ii = 0; ii < strlen(argv[i]); ii++)
{
eWhat = CheckSpecial(argv[i]);
/* skip whitespace */
if(eWhat == eSpace)
/* figure out what we have */
for(ii = 0; ii < strlen(argv[i]); ii++)
{
continue;
}
eWhat = CheckSpecial(argv[i]);
/* skip whitespace */
if(eWhat != eSpace) break;
}
/* Create Token */
if(pList == NULL)
{
@ -253,13 +256,6 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
/* copy text always */
pCurrent->text = strdup(argv[i]);
/* text */
if(eWhat == eeText)
{
pCurrent->Type = eText;
break;
}
/* numbers */
if(eWhat == eNum)
{
@ -275,9 +271,11 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
pCurrent->Type = eFloat;
sscanf(argv[i],"%f",&(pCurrent->fVal));
}
break;
}
}
else
{ /* all else is text */
pCurrent->Type = eText;
}
}
return pList;
}
@ -401,6 +399,71 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
}
return 1;
}
/*--------------------------------------------------------------------------*/
char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize) {
int i, l, firstArgToQuote, quote;
char ch;
char *res, *arg;
l = 0;
firstArgToQuote = argc;
quote = 0;
for (i=0; i<argc; i++) {
arg = argv[i];
if (arg == NULL) return NULL;
ch = *arg++;
if (ch == '\0') quote=1;
while (ch != '\0') {
switch (ch) {
case '\\':
l += 2; quote = 1; break;
case '"':
l += 2; quote = 1; break;
case ' ':
case '\t':
case '\v':
case '\f':
case '\r':
case '\n':
l++; quote = 1; break;
default:
l++; break;
}
ch = *arg++;
}
if (quote == 0) {
firstArgToQuote = i+1;
l += 1;
} else {
l += 3;
}
}
if (l > buffersize) {
buffer = calloc(l,1);
if (buffer == NULL) return NULL;
}
res = buffer;
for (i=0; i<argc; i++) {
if (i >= firstArgToQuote) *res++ = '"';
arg = argv[i];
ch = *arg++;
while (ch != '\0') {
switch (ch) {
case '"': *res++ = '\\'; *res++ = '"'; break;
case '\\': *res++ = '\\'; *res++ = '\\'; break;
case '\r': *res++ = '\\'; *res++ = 'r'; break;
case '\n': *res++ = '\\'; *res++ = 'n'; break;
default: *res++ = ch; break;
}
ch = *arg++;
}
if (i >= firstArgToQuote) *res++ = '"';
*res++ = ' ';
}
if (res > buffer) res--; /* remove trailing space */
*res='\0';
return buffer;
}
/*============================================================================
Testprogram, can be activated by defining MAIN

View File

@ -73,4 +73,19 @@ typedef struct _TokenEntry {
/*!
isNumeric test if pText is a number
!*/
char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize);
/*!
Arg2Tcl converts an argc, argv[] pair into a line of
text. Args are quoted if needed, in order to be interpreted as
proper tcl command. If buffer is NULL or the result longer than
buffersize, the result is allocated by Arg2Tcl.
If the results fits the buffer, buffer is returned.
If no memory is available or any element of argv is NULL, NULL is
returned.
The result has to be freed by the caller after use be something like:
if (result != NULL && result != buffer) free(result);
!*/
#endif

View File

@ -135,7 +135,7 @@ 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);
@ -159,11 +159,14 @@ int TclIntAction(SConnection *pCon, SicsInterp *pSics, void *pData,
SCSendOK(pCon);
return 1;
} else if(strcmp(argv[1],"backup") == 0){
Arg2Text(argc-2, &argv[2],pBuffer,1023);
if(self->fd != NULL){
fprintf(self->fd,"%s\n",pBuffer);
cmd = Arg2Tcl(argc-2, &argv[2],pBuffer,1023);
if (cmd) {
if(self->fd != NULL){
fprintf(self->fd,"%s\n",pBuffer);
}
if (cmd != pBuffer) free(cmd);
SCSendOK(pCon);
}
SCSendOK(pCon);
return 1;
} else {
sprintf(pBuffer,"ERROR: keyword %s to %s not recognized",