Files
sics/sicslist.c
Ferdi Franceschini 10d29d597c Cleaned up ANSTO code to merge with sinqdev.sics
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c
Conflicts:
	.gitignore
	SICSmain.c
	asynnet.c
	confvirtualmot.c
	counter.c
	devexec.c
	drive.c
	event.h
	exebuf.c
	exeman.c
	histmem.c
	interface.h
	motor.c
	motorlist.c
	motorsec.c
	multicounter.c
	napi.c
	napi.h
	napi4.c
	network.c
	nwatch.c
	nxscript.c
	nxxml.c
	nxxml.h
	ofac.c
	reflist.c
	scan.c
	sicshipadaba.c
	sicsobj.c
	site_ansto/docs/Copyright.txt
	site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl
	site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl
	statusfile.c
	tasdrive.c
	tasub.c
	tasub.h
	tasublib.c
	tasublib.h
2015-04-23 20:49:26 +10:00

585 lines
15 KiB
C

/*
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_DStringAppend(&lst, pCom->pName, -1);
pCom = pCom->pNext;
Tcl_DStringAppend(&lst, ",", -1);
}
Tcl_DStringAppend(&lst, "ENDLIST", -1);
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_DStringAppend(&lst, buffer, -1);
} else {
snprintf(buffer, 255, "%s=obj, ", name);
Tcl_DStringAppend(&lst, buffer, -1);
snprintf(buffer, 255, "type=%s, ", data->pDescriptor->name);
Tcl_DStringAppend(&lst, buffer, -1);
if (data->pDescriptor->GetInterface(data, DRIVEID) != NULL) {
snprintf(buffer, 255, "drivable=true, ");
} else {
snprintf(buffer, 255, "drivable=false, ");
}
Tcl_DStringAppend(&lst, buffer, -1);
if (data->pDescriptor->GetInterface(data, COUNTID) != NULL) {
snprintf(buffer, 255, "countable=true, ");
} else {
snprintf(buffer, 255, "countable=false, ");
}
Tcl_DStringAppend(&lst, buffer, -1);
if (data->pDescriptor->GetInterface(data, CALLBACKINTERFACE) != NULL) {
snprintf(buffer, 255, "callback=true, ");
} else {
snprintf(buffer, 255, "callback=false, ");
}
Tcl_DStringAppend(&lst, buffer, -1);
if (data->pDescriptor->GetInterface(data, ENVIRINTERFACE) != NULL) {
snprintf(buffer, 255, "environment=true, ");
} else {
snprintf(buffer, 255, "environment=false, ");
}
Tcl_DStringAppend(&lst, buffer, -1);
prop = data->pDescriptor->pKeys;
while (prop != NULL) {
snprintf(buffer, 255, "%s=%s, ", prop->name, prop->value);
Tcl_DStringAppend(&lst, buffer, -1);
prop = prop->pNext;
}
}
Tcl_DStringAppend(&lst, "ENDLIST", -1);
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;
}
}
static int existsObjectData(SConnection * pCon, pDummy obj, char *key)
{
char *ptr = NULL;
ptr = IFindOption(obj->pDescriptor->pKeys, key);
if (ptr != NULL)
SCPrintf(pCon, eValue, "%s", "true");
else
SCPrintf(pCon, eValue, "%s", "false");
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_DStringAppend(txt, pPtr, -1);
Tcl_DStringAppend(txt, ",", -1);
}
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_DStringAppend(&result, pCom->pName, -1);
Tcl_DStringAppend(&result, ",", -1);
}
pCom = pCom->pNext;
}
Tcl_DStringAppend(&result, "ENDLIST", -1);
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_DStringAppend(&txt, buffer, -1);
current = current->pNext;
}
Tcl_DStringAppend(&txt, "ENDLIST", -1);
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 = malloc(length + 1);
if (buffer == NULL) {
SCWrite(pCon, "ERROR: out of memory in list par", eError);
fclose(fd);
unlink(tmpfile);
return 0;
}
memset(buffer, 0, length + 1);
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_DStringAppend(&txt, current->pName, -1);
Tcl_DStringAppend(&txt, ",", -1);
}
current = current->pNext;
}
Tcl_DStringAppend(&txt, "ENDLIST", -1);
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;
}
}
if (strcmp(argv[1], "exists") == 0) {
if (argc < 4) {
SCWrite(pCon, "ERROR: not enough arguments", eError);
return 0;
} else {
pCom = FindCommand(pSics, argv[2]);
if (pCom == NULL) {
SCWrite(pCon, "ERROR: Object doesn't exist", eError);
return 0;
} else
return existsObjectData(pCon, (pDummy) pCom->pData, argv[3]);
}
}
/*
* 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;
}