- Added SicsList
- Removed group and description attributes from ObjectDescriptor SKIPPED: psi/dornier2.c psi/libpsi.a psi/make_gen psi/makefile_linux psi/pimotor.c psi/pipiezo.c psi/psi.c psi/serial.c psi/sinqhttp.c psi/sinqhttp.h psi/tcpdornier.c psi/velodornier.c
This commit is contained in:
528
sicslist.c
Normal file
528
sicslist.c
Normal file
@ -0,0 +1,528 @@
|
||||
/*
|
||||
A module for displaying various bits of information about SICS
|
||||
internals and objects.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, January 2006
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <tcl.h>
|
||||
#include "sicslist.h"
|
||||
#include "lld.h"
|
||||
#include "lld_str.h"
|
||||
/*------------------------------------------------------------------*/
|
||||
static void listAllObjects(SConnection *pCon, SicsInterp *pSics){
|
||||
CommandList *pCom = NULL;
|
||||
Tcl_DString lst;
|
||||
|
||||
Tcl_DStringInit(&lst);
|
||||
|
||||
pCom = pSics->pCList;
|
||||
while(pCom != NULL){
|
||||
Tcl_DStringAppendElement(&lst,pCom->pName);
|
||||
pCom = pCom->pNext;
|
||||
}
|
||||
Tcl_DStringAppendElement(&lst,"ENDLIST");
|
||||
SCWrite(pCon,Tcl_DStringValue(&lst), eValue);
|
||||
Tcl_DStringFree(&lst);
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static void listAllObjectData(SConnection *pCon, char *name, pDummy data){
|
||||
Tcl_DString lst;
|
||||
char buffer[256];
|
||||
IPair *prop = NULL;
|
||||
|
||||
Tcl_DStringInit(&lst);
|
||||
if(data == NULL){
|
||||
snprintf(buffer,255,"%s = command", name);
|
||||
Tcl_DStringAppendElement(&lst,buffer);
|
||||
} else {
|
||||
snprintf(buffer,255,"%s=obj", name);
|
||||
Tcl_DStringAppendElement(&lst,buffer);
|
||||
snprintf(buffer,255,"type=%s",data->pDescriptor->name);
|
||||
Tcl_DStringAppendElement(&lst,buffer);
|
||||
if(data->pDescriptor->GetInterface(data,DRIVEID) != NULL){
|
||||
snprintf(buffer,255,"drivable=true");
|
||||
} else {
|
||||
snprintf(buffer,255,"drivable=false");
|
||||
}
|
||||
Tcl_DStringAppendElement(&lst,buffer);
|
||||
if(data->pDescriptor->GetInterface(data,COUNTID) != NULL){
|
||||
snprintf(buffer,255,"countable=true");
|
||||
} else {
|
||||
snprintf(buffer,255,"countable=false");
|
||||
}
|
||||
Tcl_DStringAppendElement(&lst,buffer);
|
||||
if(data->pDescriptor->GetInterface(data,CALLBACKINTERFACE) != NULL){
|
||||
snprintf(buffer,255,"callback=true");
|
||||
} else {
|
||||
snprintf(buffer,255,"callback=false");
|
||||
}
|
||||
Tcl_DStringAppendElement(&lst,buffer);
|
||||
if(data->pDescriptor->GetInterface(data,ENVIRINTERFACE) != NULL){
|
||||
snprintf(buffer,255,"environment=true");
|
||||
} else {
|
||||
snprintf(buffer,255,"environment=false");
|
||||
}
|
||||
Tcl_DStringAppendElement(&lst,buffer);
|
||||
prop = data->pDescriptor->pKeys;
|
||||
while(prop != NULL){
|
||||
snprintf(buffer,255,"%s=%s",prop->name,prop->value);
|
||||
Tcl_DStringAppendElement(&lst,buffer);
|
||||
prop = prop->pNext;
|
||||
}
|
||||
}
|
||||
Tcl_DStringAppendElement(&lst,"ENDLIST");
|
||||
SCWrite(pCon,Tcl_DStringValue(&lst),eValue);
|
||||
Tcl_DStringFree(&lst);
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static int getObjectData(pDummy obj, char *key, char buffer[512]){
|
||||
char *ptr = NULL;
|
||||
void *iPtr = NULL;
|
||||
int status = 0;
|
||||
|
||||
/*
|
||||
* first check attributes
|
||||
*/
|
||||
ptr = IFindOption(obj->pDescriptor->pKeys,key);
|
||||
if(ptr != NULL){
|
||||
snprintf(buffer,511,"%s",ptr);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* check indirect attributes
|
||||
*/
|
||||
strtolower(key);
|
||||
if(strcmp(key,"type") == 0){
|
||||
snprintf(buffer,511,"%s",obj->pDescriptor->name);
|
||||
return 1;
|
||||
} else if(strcmp(key,"drivable") == 0){
|
||||
iPtr = obj->pDescriptor->GetInterface(obj,DRIVEID);
|
||||
if(iPtr != NULL){
|
||||
status = 1;
|
||||
snprintf(buffer,511,"true");
|
||||
} else {
|
||||
status = 0;
|
||||
snprintf(buffer,511,"false");
|
||||
}
|
||||
} else if(strcmp(key,"countable") == 0){
|
||||
iPtr = obj->pDescriptor->GetInterface(obj,COUNTID);
|
||||
if(iPtr != NULL){
|
||||
status = 1;
|
||||
snprintf(buffer,511,"true");
|
||||
} else {
|
||||
status = 0;
|
||||
snprintf(buffer,511,"false");
|
||||
}
|
||||
} else if(strcmp(key,"callback") == 0){
|
||||
iPtr = obj->pDescriptor->GetInterface(obj,CALLBACKINTERFACE);
|
||||
if(iPtr != NULL){
|
||||
status = 1;
|
||||
snprintf(buffer,511,"true");
|
||||
} else {
|
||||
status = 0;
|
||||
snprintf(buffer,511,"false");
|
||||
}
|
||||
} else if(strcmp(key,"environment") == 0){
|
||||
iPtr = obj->pDescriptor->GetInterface(obj,ENVIRINTERFACE);
|
||||
if(iPtr != NULL){
|
||||
status = 1;
|
||||
snprintf(buffer,511,"true");
|
||||
} else {
|
||||
status = 0;
|
||||
snprintf(buffer,511,"false");
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
static int printObjectData(SConnection *pCon, pDummy obj, char *key){
|
||||
char value[512];
|
||||
char buffer[1024];
|
||||
int status;
|
||||
|
||||
status = getObjectData(obj,key,value);
|
||||
if(status >= 0){
|
||||
snprintf(buffer,1023,"%s=%s",key,value);
|
||||
} else {
|
||||
snprintf(buffer,1023,"%s=UNDEFINED",key);
|
||||
}
|
||||
SCWrite(pCon,buffer,eValue);
|
||||
if(status < 0){
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------
|
||||
* this function implements a set on top of a list. This means that
|
||||
* the list is first searched for the occurence of name. name is only
|
||||
* added when it does not exist in list
|
||||
* ----------------------------------------------------------------*/
|
||||
static void addItemToList(int list, char *name){
|
||||
int status;
|
||||
char *pPtr = NULL;
|
||||
|
||||
status = LLDnodePtr2First(list);
|
||||
while(status != 0){
|
||||
pPtr = (char *)LLDnodePtr(list);
|
||||
if(pPtr != NULL){
|
||||
if(strcmp(pPtr,name) == 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
status = LLDnodePtr2Next(list);
|
||||
}
|
||||
LLDstringAppend(list,name);
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
static void listToString(int list,Tcl_DString *txt){
|
||||
int status;
|
||||
char *pPtr = NULL;
|
||||
|
||||
status = LLDnodePtr2First(list);
|
||||
while(status != 0){
|
||||
pPtr = (char *)LLDnodePtr(list);
|
||||
if(pPtr != NULL){
|
||||
Tcl_DStringAppendElement(txt,pPtr);
|
||||
}
|
||||
status = LLDnodePtr2Next(list);
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
static void printKeyTypes(SicsInterp *pSics, SConnection *pCon,
|
||||
char *key){
|
||||
CommandList *pCom = NULL;
|
||||
int list;
|
||||
int status;
|
||||
char value[512];
|
||||
Tcl_DString result;
|
||||
|
||||
if(strcmp(key,"interface") == 0){
|
||||
SCWrite(pCon,"drivable countable callback environment",eValue);
|
||||
return;
|
||||
}
|
||||
|
||||
list = LLDstringCreate();
|
||||
Tcl_DStringInit(&result);
|
||||
pCom = pSics->pCList;
|
||||
while(pCom != NULL){
|
||||
status = getObjectData((pDummy)pCom->pData,key,value);
|
||||
if(status >= 0){
|
||||
addItemToList(list,value);
|
||||
}
|
||||
pCom = pCom->pNext;
|
||||
}
|
||||
LLDstringAppend(list,"ENDLIST");
|
||||
|
||||
listToString(list,&result);
|
||||
SCWrite(pCon,Tcl_DStringValue(&result),eValue);
|
||||
Tcl_DStringFree(&result);
|
||||
LLDstringDelete(list);
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
static void printObjectsMatchingKeyVal(SicsInterp *pSics,
|
||||
SConnection *pCon,char *key, char *value){
|
||||
CommandList *pCom = NULL;
|
||||
Tcl_DString result;
|
||||
int status;
|
||||
char buffer[512];
|
||||
|
||||
Tcl_DStringInit(&result);
|
||||
pCom = pSics->pCList;
|
||||
strtolower(value);
|
||||
while(pCom != NULL){
|
||||
if(strcmp(key,"interface") == 0){
|
||||
status = getObjectData((pDummy)pCom->pData,value,
|
||||
buffer);
|
||||
} else {
|
||||
status = getObjectData((pDummy)pCom->pData,key,
|
||||
buffer);
|
||||
if(status == 1){
|
||||
strtolower(buffer);
|
||||
if(strcmp(buffer,value) == 0){
|
||||
status = 1;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(status == 1){
|
||||
Tcl_DStringAppendElement(&result,pCom->pName);
|
||||
}
|
||||
pCom = pCom->pNext;
|
||||
}
|
||||
Tcl_DStringAppendElement(&result,"ENDLIST");
|
||||
SCWrite(pCon,Tcl_DStringValue(&result),eValue);
|
||||
Tcl_DStringFree(&result);
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
static int setAttribute(SConnection *pCon, SicsInterp *pSics,
|
||||
char *obj, char *key, char *value){
|
||||
CommandList *pCom = NULL;
|
||||
pDummy pDum = NULL;
|
||||
|
||||
if(!SCMatchRights(pCon,usMugger)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
strtolower(key);
|
||||
if(strcmp(key,"type") == 0 || strcmp(key,"interface") == 0){
|
||||
SCWrite(pCon,"ERROR: this key is forbidden",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCom = FindCommand(pSics, obj);
|
||||
if(pCom == NULL){
|
||||
SCWrite(pCon,"ERROR: object not found",eError);
|
||||
return 0;
|
||||
}
|
||||
pDum = (pDummy)pCom->pData;
|
||||
|
||||
if(pDum != NULL){
|
||||
if(IFindOption(pDum->pDescriptor->pKeys,key) == NULL){
|
||||
pDum->pDescriptor->pKeys = IFAddOption(pDum->pDescriptor->pKeys,
|
||||
key,value);
|
||||
} else {
|
||||
IFSetOption(pDum->pDescriptor->pKeys,key,value);
|
||||
}
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
static int printObjStatus(SConnection *pCon, SicsInterp *pSics,
|
||||
char *name){
|
||||
CommandList *pCom = NULL;
|
||||
pDummy pDum = NULL;
|
||||
pIDrivable pDriv = NULL;
|
||||
pICountable pCount = NULL;
|
||||
pEVInterface pEV = NULL;
|
||||
int status = -1, evStatus = -1;
|
||||
char buffer[256];
|
||||
|
||||
pCom = FindCommand(pSics,name);
|
||||
if(pCom == NULL){
|
||||
SCWrite(pCon,"ERROR: object not found",eError);
|
||||
return 0;
|
||||
}
|
||||
pDum = (pDummy)pCom->pData;
|
||||
if(pDum != NULL){
|
||||
pDriv = GetDrivableInterface(pDum);
|
||||
if(pDriv != NULL){
|
||||
status = pDriv->CheckStatus(pDum,pCon);
|
||||
}
|
||||
pCount = GetCountableInterface(pDum);
|
||||
if(pCount != NULL){
|
||||
status = pCount->CheckCountStatus(pDum,pCon);
|
||||
}
|
||||
pEV = pDum->pDescriptor->GetInterface(pDum,ENVIRINTERFACE);
|
||||
if(pEV != NULL){
|
||||
evStatus = pEV->IsInTolerance(pDum);
|
||||
}
|
||||
}
|
||||
switch(status){
|
||||
case HWBusy:
|
||||
snprintf(buffer,255,"%s = running",pCom->pName);
|
||||
break;
|
||||
case HWIdle:
|
||||
case OKOK:
|
||||
if(evStatus < 0){
|
||||
snprintf(buffer,255,"%s = idle",pCom->pName);
|
||||
} else if(evStatus == 1){
|
||||
snprintf(buffer,255,"%s = intolerance",pCom->pName);
|
||||
} else {
|
||||
snprintf(buffer,255,"%s = outoftolerance",pCom->pName);
|
||||
}
|
||||
break;
|
||||
case HWFault:
|
||||
case HWPosFault:
|
||||
snprintf(buffer,255,"%s = faulty",pCom->pName);
|
||||
break;
|
||||
case HWPause:
|
||||
snprintf(buffer,255,"%s = paused",pCom->pName);
|
||||
break;
|
||||
case HWNoBeam:
|
||||
snprintf(buffer,255,"%s = nobeam",pCom->pName);
|
||||
break;
|
||||
default:
|
||||
snprintf(buffer,255,"%s = nostatus",pCom->pName);
|
||||
break;
|
||||
}
|
||||
SCWrite(pCon,buffer,eValue);
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
static int printServer(SConnection *pCon){
|
||||
Tcl_DString txt;
|
||||
IPair *current = NULL;
|
||||
char buffer[512];
|
||||
|
||||
Tcl_DStringInit(&txt);
|
||||
current = pSICSOptions;
|
||||
while(current != NULL){
|
||||
snprintf(buffer,511,"%s=%s",current->name,current->value);
|
||||
Tcl_DStringAppendElement(&txt,buffer);
|
||||
current = current->pNext;
|
||||
}
|
||||
Tcl_DStringAppendElement(&txt,"ENDLIST");
|
||||
SCWrite(pCon,Tcl_DStringValue(&txt),eValue);
|
||||
Tcl_DStringFree(&txt);
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static int printObjectPar(SConnection *pCon,SicsInterp *pSics, char *obj){
|
||||
CommandList *pCom = NULL;
|
||||
FILE *fd = NULL;
|
||||
char *buffer = NULL, tmpfile[80];
|
||||
pDummy pDum = NULL;
|
||||
long length;
|
||||
struct stat statbuf;
|
||||
|
||||
snprintf(tmpfile,80,"SICS%6.6d.dat",getpid());
|
||||
pCom = FindCommand(pSics, obj);
|
||||
if(pCom == NULL){
|
||||
SCWrite(pCon,"ERROR: object to list not found",eError);
|
||||
return 0;
|
||||
}
|
||||
fd = fopen(tmpfile,"w");
|
||||
if(fd == NULL){
|
||||
SCWrite(pCon,"ERROR: failed to open tmpfile",eError);
|
||||
return 0;
|
||||
}
|
||||
pDum = (pDummy)pCom->pData;
|
||||
if(pDum != NULL){
|
||||
pDum->pDescriptor->SaveStatus(pDum, obj, fd);
|
||||
fclose(fd);
|
||||
stat(tmpfile, &statbuf);
|
||||
length = statbuf.st_size;
|
||||
fd = fopen(tmpfile,"r");
|
||||
if(fd == NULL){
|
||||
SCWrite(pCon,"ERROR: failed to open tmpfile",eError);
|
||||
return 0;
|
||||
}
|
||||
buffer = (char *)malloc(length*sizeof(char));
|
||||
if(buffer == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in list par",eError);
|
||||
fclose(fd);
|
||||
unlink(tmpfile);
|
||||
return 0;
|
||||
}
|
||||
memset(buffer,0,length*sizeof(char));
|
||||
fread(buffer,length,1,fd);
|
||||
fclose(fd);
|
||||
SCWrite(pCon,buffer,eValue);
|
||||
free(buffer);
|
||||
unlink(tmpfile);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
extern int match(const char *mask, const char *name); /* from wwildcard.c */
|
||||
|
||||
static void printMatch(SConnection *pCon, SicsInterp *pSics,
|
||||
char *mask){
|
||||
CommandList *current = NULL;
|
||||
Tcl_DString txt;
|
||||
|
||||
Tcl_DStringInit(&txt);
|
||||
current = pSics->pCList;
|
||||
while(current != NULL){
|
||||
if(!match(mask,current->pName)){
|
||||
Tcl_DStringAppendElement(&txt, current->pName);
|
||||
}
|
||||
current = current->pNext;
|
||||
}
|
||||
Tcl_DStringAppendElement(&txt,"ENDLIST");
|
||||
SCWrite(pCon,Tcl_DStringValue(&txt), eValue);
|
||||
Tcl_DStringFree(&txt);
|
||||
}
|
||||
|
||||
/*==================================================================*/
|
||||
int SicsList(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
CommandList *pCom = NULL;
|
||||
|
||||
if(argc < 2){
|
||||
listAllObjects(pCon,pSics);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(strcmp(argv[1],"objstatus") == 0){
|
||||
if(argc < 3){
|
||||
SCWrite(pCon,"ERROR: Insufficient number of arguments to status",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
return printObjStatus(pCon,pSics,argv[2]);
|
||||
}
|
||||
|
||||
if(strcmp(argv[1],"server") == 0){
|
||||
printServer(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(strcmp(argv[1],"par") == 0){
|
||||
if(argc > 2) {
|
||||
return printObjectPar(pCon,pSics, argv[2]);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: not enough arguments to list par",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(strcmp(argv[1],"match") == 0){
|
||||
if(argc > 2) {
|
||||
printMatch(pCon,pSics, argv[2]);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: not enough arguments to list match",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* object properties
|
||||
*/
|
||||
pCom = FindCommand(pSics,argv[1]);
|
||||
if(pCom != NULL){
|
||||
if(argc < 3){
|
||||
listAllObjectData(pCon,argv[1],(pDummy)pCom->pData);
|
||||
return 1;
|
||||
} else {
|
||||
return printObjectData(pCon,(pDummy)pCom->pData, argv[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* attribute setting and status
|
||||
*/
|
||||
if(strcmp(argv[1],"setatt") == 0){
|
||||
if(argc < 5){
|
||||
SCWrite(pCon,"ERROR: Insufficient number of arguments to setatt",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
return setAttribute(pCon, pSics, argv[2],argv[3], argv[4]);
|
||||
}
|
||||
|
||||
/*
|
||||
* classes and class membership
|
||||
*/
|
||||
if(argc < 3){
|
||||
printKeyTypes(pSics, pCon,argv[1]);
|
||||
return 1;
|
||||
} else {
|
||||
printObjectsMatchingKeyVal(pSics,pCon,argv[1],argv[2]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user