PSI sics-cvs-psi-2006

This commit is contained in:
2006-05-08 02:00:00 +00:00
committed by Douglas Clowes
parent ae77364de2
commit 6e926b813f
388 changed files with 445529 additions and 14109 deletions

324
SCinter.c
View File

@@ -2,11 +2,9 @@
Implementation file for the SICS-interpreter.
Mark Koennecke, November 1996
Made ListObjects moe intelligent: list objects according to interface etc.
Made ListObjects more intelligent: list objects according to interface etc.
Mark Koennecke, December 2003
Copyright:
@@ -33,7 +31,7 @@
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
@@ -42,6 +40,16 @@
M. Zolliker, Sept 2000, introduced formal aliases, modifications marked M.Z
Mark Koennecke, August 2001, modified SicsWriteStatus to write motor
positions on demand.
Made ListObjects moe intelligent: list objects according to interface etc.
Mark Koennecke, December 2003
Extended 'dir' command (function ListObjects) to list via typename from
object descriptor. For completeness, added function PrintAllTypes.
Paul Hathaway, May 2004
Modified printXXX functions to fix duplicate write of last buffer line.
Paul Hathaway, May 2004
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
@@ -57,13 +65,19 @@
#include "interface.h"
#include "motor.h"
#include "obdes.h"
#include "lld.h"
/* M.Z. */
#include "definealias.h"
/* pvh */
#include "lld_str.h"
static void printList(SConnection *pCon, int listID);
static void freeList(int listID);
#define MAXLEN 256
#define MAXPAR 100
#define MAXBUF 128
/*--------------------------------------------------------------------------*/
SicsInterp *InitInterp(void)
@@ -77,6 +91,7 @@
SICSLogWrite("Error allocating memory for Interpreter",eInternal);
return NULL;
}
memset(pInter,0,sizeof(SicsInterp));
pInter->pCList = NULL;
pInter->AList.pFirst = NULL; /* M.Z. */
pInter->pTcl = (void *)MacroInit(pInter);
@@ -90,10 +105,11 @@
return pInter;
}
/*------------------------------------------------------------------------*/
int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
KillFunc pKFunc, void *pData)
int AddCommandWithFlag(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
KillFunc pKFunc, void *pData, int startupOnly)
{
CommandList *pNew = NULL;
CommandList *p, *tail;
char pBueffel[512];
assert(pName);
@@ -133,19 +149,42 @@
pNew->OFunc = pFunc;
pNew->KFunc = pKFunc;
pNew->pData = pData;
pNew->pNext = pInterp->pCList;
pNew->pNext = NULL;
pNew->startupOnly = startupOnly;
if(pInterp->pCList)
/* find end of list */
tail = NULL;
p = pInterp->pCList;
while(p != NULL)
{
pInterp->pCList->pPrevious = pNew;
tail = p;
p = p->pNext;
}
pNew->pPrevious = NULL;
if (tail==NULL) { /* first entry */
pInterp->pCList = pNew;
} else { /* insert at tail */
tail->pNext = pNew;
}
pNew->pPrevious = tail;
/* update headpointer */
pInterp->pCList = pNew;
return 1;
}
/*------------------------------------------------------------------------*/
int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
KillFunc pKFunc, void *pData)
{
return AddCommandWithFlag(pInterp, pName, pFunc, pKFunc, pData, 0);
}
/*------------------------------------------------------------------------*/
int AddIniCmd(char *pName, ObjectFunc pFunc)
{
return AddCommandWithFlag(pServ->pSics, pName, pFunc, NULL, NULL, 1);
}
/*------------------------------------------------------------------------*/
int AddCmd(char *pName, ObjectFunc pFunc)
{
return AddCommandWithFlag(pServ->pSics, pName, pFunc, NULL, NULL, 0);
}
/*------------------------------------------------------------------------*/
int RemoveCommand(SicsInterp *pInterp, char *pName)
{
@@ -201,7 +240,7 @@
#define MAXCOM 50
extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
extern char *SkipSpace(char *pPtr);
/*------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
{
int iCount = 0;
@@ -212,6 +251,7 @@ extern char *SkipSpace(char *pPtr);
char pBrk[] = {" \r\n\0"};
char *pPtr;
char **argv = NULL;
commandContext comCon;
assert(self);
@@ -226,24 +266,28 @@ extern char *SkipSpace(char *pPtr);
}
else
{
printf("Executing -> %s <- from dummy socket\n", pText);
sprintf(pBueffel, "Executing -> %s <- from dummy socket\n", pText);
SICSLogWrite(pBueffel,eCommand);
}
/* convert to argc, argv */
argc = 0;
argv = NULL;
Text2Arg(pText,&argc,&argv);
/* the first one must be the target object. If not given an empty
command string was given which will be silently ignored */
if(argc < 1)
{
return 1;
iRet = 1;
goto deleteArgv;
}
if(argv[0] == NULL)
{
SCWrite(pCon,"ERROR: failed to parse command",eError);
return -1;
SCWrite(pCon,"ERROR: failed to parse command",eError);
iRet = -1;
goto deleteArgv;
}
/* find it */
@@ -253,8 +297,8 @@ extern char *SkipSpace(char *pPtr);
sprintf(pBueffel,"ERROR: Object -> %s <- NOT found",
argv[0]);
SCWrite(pCon,pBueffel,eError);
return -1;
iRet = -1;
goto deleteArgv;
}
@@ -262,19 +306,28 @@ extern char *SkipSpace(char *pPtr);
self->eOut = eStatus;
Tcl_ResetResult((Tcl_Interp *)self->pTcl);
MacroPush(pCon);
pCon->conStatus = 0;
iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv);
/* If a task is registered with the dev exec then conStatus is HWBusy*/
if (pCon->conStatus != HWBusy) {
comCon = SCGetContext(pCon);
if (0 != strcmp("contextdo",comCon.deviceID))
SCWrite(pCon,"",eFinish);
}
MacroPop();
/* delete argv */
for(i = 0; i < argc; i++)
{
if(argv[i] != NULL)
{
free(argv[i]);
}
deleteArgv:
if (argv) {
/* delete argv */
for(i = 0; i < argc; i++)
{
if(argv[i] != NULL)
{
free(argv[i]);
}
}
free(argv);
}
free(argv);
return iRet;
}
/*------------------------------------------------------------------------*/
@@ -318,23 +371,24 @@ extern char *SkipSpace(char *pPtr);
float fVal;
pIDrivable pDriv = NULL;
void *pTest = NULL;
char tmpfile[PATH_MAX];
int l;
assert(self);
assert(file);
/* open file */
fd = fopen(file,"w");
if(!fd)
{
/* make sure that status file is always valid M.Z. Apr 2005 */
/* create a temporary file first */
l=strlen(file);
if (l >= sizeof tmpfile - 2) {
return 0;
}
/* remove it, as I found garbage from previous runs in the
status file
*/
fclose(fd);
remove(file);
strcpy(tmpfile, file);
tmpfile[l]='.';
tmpfile[l+1]='\0';
remove(tmpfile); /* remove already existing file */
fd = fopen(file,"w");
fd = fopen(tmpfile,"w");
if(!fd)
{
return 0;
@@ -380,6 +434,10 @@ extern char *SkipSpace(char *pPtr);
fprintf(fd,"Success \n");
}
fclose(fd);
/* rename temporary to final file (this is an atomic action) */
if (0 > rename(tmpfile, file)) {
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
@@ -420,7 +478,15 @@ extern char *SkipSpace(char *pPtr);
pTcl = (Tcl_Interp *)self->pTcl;
if(pTcl)
{
/*
uncommented: the current versions of Tcl (8.3,4) dump core with a
memory problem deep in the Tcl library. This causes a core dump on
each SICS restart and breaks the use of external tools.
Tcl_DeleteInterp(pTcl);
call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05
*/
KillSicsUnknown();
}
free(self);
@@ -456,6 +522,7 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
iNum = 0;
pBueffel[0]='\0';
}
pCurrent = pCurrent->pNext;
}
@@ -467,6 +534,80 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
SCWrite(pCon,pBueffel,eStatus);
}
}
/*------------------------------------------------------------------------*/
/* compareStringNode wraps strcmp for use in findNode(LLD module) calls */
int compareStringNode(const void *pStr1, const void *ppStr2)
{
return strcmp((char *)pStr1,*(char **)ppStr2);
}
/*------------------------------------------------------------------------
printAllTypes prints the list of types of objects instantiated on the
CommandList.
iFiltered=0 gives all objects including interpreter command objects
iFiltered=1 gives types where object name is not the same as its type
-------------------------------------------------------------------------*/
static void printAllTypes(SicsInterp *pSics, SConnection *pCon, int iFiltered)
{
CommandList *pCurrent = NULL;
char pBueffel[256];
char pName_lc[256];
char pType_lc[256];
char *pType;
Dummy *pTest;
int typeListID;
assert(pSics);
assert(pCon);
pBueffel[0] = '\0';
typeListID = LLDstringCreate();
if(-1==typeListID)
{
strcpy(pBueffel,"ERROR: Cannot generate list of object types\r\n");
SCWrite(pCon,pBueffel,eStatus);
return;
}
pCurrent = pSics->pCList;
while(pCurrent)
{
if(NULL != pCurrent->pData)
{
pTest = (pDummy)pCurrent->pData;
if(NULL != pTest->pDescriptor)
{
pType = pTest->pDescriptor->name;
strcpy(pType_lc,pType);
strtolower(pType_lc);
LLDnodePtr2First(typeListID);
/* int LLDnodeFind( int List, CompFunPtr Compare, void * DataPtr ); */
/* */
/* Find *DataPtr in the List using the *Compare function. */
/* Returns the return value of *Compare. */
/* 0 == equal == found. */
/* non-zero == not found. Current node is set to found node. */
/* Returns 2 for an empty list. */
/* NB: First checked node is current node, then search to end of list*/
if(0!=LLDnodeFind(typeListID,compareStringNode,(void *)pType))
{ /* empty list or 'typename' not found */
strcpy(pName_lc, pCurrent->pName);
strtolower(pName_lc);
if((0==iFiltered)||((1==iFiltered)&&(0!=strcmp(pType_lc,pName_lc))))
{ /*ie Add if unfiltered or pass filter(name!=typename) */
LLDstringAdd(typeListID,pType);
}
}
}
}
pCurrent = pCurrent->pNext;
}
printList(pCon,typeListID);
freeList(typeListID);
}
/*-----------------------------------------------------------------------
printInterface prints only those objects which implement an interface
as specified bi the id given
@@ -508,6 +649,7 @@ static void printInterface(SicsInterp *pSics, SConnection *pCon, int id)
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
iNum = 0;
pBueffel[0]='\0';
}
}
}
@@ -559,6 +701,7 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
strcat(pBueffel,pCurrent->pName);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
pBueffel[0]='\0';
iNum = 0;
}
}
@@ -571,24 +714,26 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
SCWrite(pCon,pBueffel,eStatus);
}
/*-----------------------------------------------------------------------
printType prints only those objects which match the type given
printType prints only those objects whose descriptor match the type given
-------------------------------------------------------------------------*/
static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
static void printType(SicsInterp *pSics, SConnection *pCon, char *typeName)
{
CommandList *pCurrent;
Tcl_DString txt;
char pBueffel[256];
int iNum = 0;
assert(pSics);
assert(pCon);
Tcl_DStringInit(&txt);
pBueffel[0] = '\0';
pCurrent = pSics->pCList;
while(pCurrent)
{
if(pCurrent->pData != NULL)
{
if(iHasType(pCurrent->pData,type))
if(iHasType(pCurrent->pData,typeName))
{
if(iNum == 0)
{
@@ -606,7 +751,8 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
strcat(pBueffel," ");
strcat(pBueffel,pCurrent->pName);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
Tcl_DStringAppend(&txt,pBueffel,-1);
pBueffel[0]='\0';
iNum = 0;
}
}
@@ -616,13 +762,15 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
/* write final entries */
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,Tcl_DStringValue(&txt),eStatus);
Tcl_DStringFree(&txt);
}
/*--------------------------------------------------------------------------*/
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
char pType[256];
int i;
if(argc < 2)
{
@@ -644,6 +792,13 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printType(pSics,pCon,"Motor");
return 1;
}
/* Start Mod by Paul Hathaway May 2004 */
if(0 == strcmp(argv[1],"types"))
{
printAllTypes(pSics,pCon,1);
return 1;
}
/* End Mod by Paul Hathaway May 2004*/
/*
@@ -677,7 +832,7 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printInterface(pSics,pCon,ENVIRINTERFACE);
return 1;
}
SCWrite(pCon,"ERROR: interface description nor recognized",eError);
SCWrite(pCon,"ERROR: interface description not recognized",eError);
return 0;
}
/*
@@ -688,6 +843,33 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printMatch(pSics,pCon,argv[2]);
return 1;
}
/* Start Mod by Paul Hathaway May 2004 */
/*
* type-based dir
*/
if(0 == strcmp(argv[1],"type"))
{
if(0==strcmp(argv[2],"*"))
{
printAllTypes(pSics,pCon,0);
return 1;
}
strcpy(pType,argv[2]);
/* Cater for multi-word types eg 'Environment Monitor' */
if(argc > 3)
{
for(i=3;i<argc;i++)
{
strcat(pType," ");
strcat(pType,argv[i]);
}
}
printType(pSics,pCon,pType);
return 1;
}
/* End Mod by Paul Hathaway May 2004*/
return 1;
}
/*---------------------------------------------------------------------------*/
@@ -791,3 +973,51 @@ void *FindDrivable(SicsInterp *pSics, char *name){
return NULL;
}
/*------------------------------------------------------------------------*/
/* printList: Print contents of an LLDstring list
* Envisaged to be used by other extensions/refactoring utilising dynamic
* linked list module. May extend toallow different output formats
* (eg multi/single column) via switches
*/
static void printList(SConnection *pCon, int listID)
{
char pBueffel[MAXBUF];
int retCode;
if(0!=LLDnodePtr2First(listID))
{
do
{
retCode = LLDstringData(listID,NULL);
if ((MAXBUF-3) > retCode) {
retCode = LLDstringData(listID,pBueffel);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
}
} while(0!=LLDnodePtr2Next(listID));
}
}
/*------------------------------------------------------------------------*/
static void freeList(int listID)
{
do {
LLDstringDelete(listID);
} while(0!=LLDnodePtr2First(listID));
LLDdelete(listID);
}
/*------------------------------------------------------------------------*/
void RemoveStartupCommands(void)
{
CommandList *pCurrent, *pNext;
pCurrent = pServ->pSics->pCList;
while(pCurrent)
{
pNext = pCurrent->pNext;
if (pCurrent->startupOnly) {
RemoveCommand(pServ->pSics, pCurrent->pName);
}
pCurrent = pNext;
}
}