From 45fd50265f34dba2cd6b27917fcc30d32a61d12e Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 16 Jan 2006 08:32:07 +0000 Subject: [PATCH] - 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 --- SCinter.c | 93 +------- conman.c | 8 +- doc/user/sicslist.htm | 56 +++++ histmem.c | 2 +- interface.h | 34 +-- interface.tex | 118 +++++----- interface.w | 2 - linux_def | 2 +- make_gen | 2 +- makefile_slinux | 4 +- obdes.c | 22 +- obdes.h | 40 ++-- ofac.c | 3 +- protocol.c | 7 +- rs232controller.c | 1 + sicslist.c | 528 ++++++++++++++++++++++++++++++++++++++++++ sicslist.h | 15 ++ sinfox.c | 26 ++- tclmotdriv.c | 9 +- tclmotdriv.h | 3 + 20 files changed, 732 insertions(+), 243 deletions(-) create mode 100644 doc/user/sicslist.htm create mode 100644 sicslist.c create mode 100644 sicslist.h diff --git a/SCinter.c b/SCinter.c index 4e08874f..bca74aac 100644 --- a/SCinter.c +++ b/SCinter.c @@ -65,6 +65,7 @@ #include "interface.h" #include "motor.h" #include "obdes.h" +#include "lld.h" /* M.Z. */ #include "definealias.h" @@ -1019,95 +1020,3 @@ int compareStringNode(void *pStr1, void **ppStr2) pCurrent = pNext; } } -/*----------------------------------------------------------------------*/ -static int handleGet(SConnection *pCon,SicsInterp *pSics, int argc, - char *argv[]){ - CommandList *obj = NULL; - pDummy pDum = NULL; - char pBueffel[512]; - char *pPtr = NULL; - - if(argc < 4){ - SCWrite(pCon,"ERROR: Insufficient number of arguments to SicsAtt get", - eError); - return 0; - } - - obj = FindCommand(pSics,argv[2]); - if(obj == NULL){ - snprintf(pBueffel,511,"ERROR: object %s not found",argv[2]); - SCWrite(pCon,pBueffel,eError); - return 0; - } - pDum = obj->pData; - if(pDum == NULL){ - snprintf(pBueffel,511,"%s has no data, is command", argv[2]); - SCWrite(pCon,pBueffel,eValue); - return 1; - } - strtolower(argv[3]); - if(strcmp(argv[3],"type") == 0){ - snprintf(pBueffel,511, "%s.type = %s", argv[2], pDum->pDescriptor->name); - SCWrite(pCon,pBueffel,eValue); - return 1; - } else { - pPtr = GetDescriptorKey(pDum->pDescriptor, argv[3]); - if(pPtr == NULL){ - snprintf(pBueffel,511,"%s.%s = Undefined", argv[0], argv[3]); - } else { - snprintf(pBueffel,511,"%s.%s = %s", argv[0], argv[3], pPtr); - } - SCWrite(pCon,pBueffel,eValue); - return 1; - } -} -/*----------------------------------------------------------------------*/ -static int handleSet(SConnection *pCon,SicsInterp *pSics, int argc, - char *argv[]){ - CommandList *obj = NULL; - pDummy pDum = NULL; - char pBueffel[512]; - char *pPtr = NULL; - - if(argc < 5){ - SCWrite(pCon,"ERROR: Insufficient number of arguments to SicsAtt set", - eError); - return 0; - } - - obj = FindCommand(pSics,argv[2]); - if(obj == NULL){ - snprintf(pBueffel,511,"ERROR: object %s not found",argv[2]); - SCWrite(pCon,pBueffel,eError); - return 0; - } - pDum = obj->pData; - if(pDum == NULL){ - snprintf(pBueffel,511,"%s has no data, is command", argv[2]); - SCWrite(pCon,pBueffel,eValue); - return 1; - } - strtolower(argv[3]); - pDum->pDescriptor->pKeys = IFSetOption(pDum->pDescriptor->pKeys, argv[3], argv[4]); - SCSendOK(pCon); - return 1; -} -/*-----------------------------------------------------------------------*/ -int SicsAtt(SConnection *pCon, SicsInterp *pSics, void *pData, - int argc, char *argv[]){ - CommandList *current = NULL; - pDummy pDum = NULL; - - if(argc < 2){ - SCWrite(pCon,"ERROR: insufficient number of argumens to SicsAtt",eError); - return 0; - } - - strtolower(argv[1]); - if(strcmp(argv[1],"get") == 0) { - return handleGet(pCon, pSics, argc, argv); - } else if(strcmp(argv[1],"set") == 0){ - return handleSet(pCon,pSics,argc, argv); - } - return 0; -} diff --git a/conman.c b/conman.c index 27822689..e2a23651 100644 --- a/conman.c +++ b/conman.c @@ -64,6 +64,7 @@ #include "token.h" #include "uubuffer.h" #include "commandlog.h" +#include "stptok.h" /* #define UUDEB 1 @@ -1317,6 +1318,8 @@ static void writeToLogFiles(SConnection *self, char *buffer) return self->eInterrupt; } + /*----------------------------------------------------------------*/ + extern char *trim(char *in); /* --------------------------------------------------------------------------*/ int SCInvoke(SConnection *self, SicsInterp *pInter, char *pCommand) { @@ -1993,9 +1996,7 @@ long SCTagContext(SConnection *self, char *tagName) { commandContext a; if(NULL==self) return -1; - /* - return SCSetContext(self,self->iCmdID,tagName); - */ + a = SCGetContext(self); strncpy(a.deviceID,tagName,SCDEVIDLEN); /* @@ -2003,6 +2004,7 @@ long SCTagContext(SConnection *self, char *tagName) last position */ LLDnodeDataTo(self->contextStack, &a); + return 1; } /* --------------------------------------------------------------------------*/ long SCAdvanceContext(SConnection *self, char *tagName) diff --git a/doc/user/sicslist.htm b/doc/user/sicslist.htm new file mode 100644 index 00000000..051e3eb2 --- /dev/null +++ b/doc/user/sicslist.htm @@ -0,0 +1,56 @@ + + +SICS Metadata + + +

SICS Metadata

+

+This section describes the list command for retrieving and + setting information about a running SICS server and the objects living in it. + Each SICS object has metadata associated with it: some of it is generated by the system such + as the object type, the interface it implements etc. Some additional metadata can be set by the + user. Most commands print their data in the form of a Tcl-list. The list is terminated with the entry ENDLIST. + This entry can be searched for by clients interested to find the end of the transmission. The general form of the + metadata is a key value pair. The following commands are implemented: +

+
list +
Prints a list of all SICS objects. +
list server +
Prints a list of all server options. +
list sicsobject +
Prints all the metadata associated with the SICS object sicsobject. +
list sicsobject key +
Prints the value of the key associated with the SICS object sicsobject. +
list setatt sicsobject key value +
Sets a user defined attribute with the name key and the value value for the SICS object sicsobject. +
list metadatakey +
List all unique entries for the specified metadata key. System supplied metadata keys are: +
+
type +
The object class +
interface +
The object interfaces implemented by SICS +
+This list may be augmented with user generated keys as defined through using the list setatt obj key value command. +An example: +
+list type
+
+will print all the objects classes available in the SICS server. +
list metadatakey value +
List all the SICS objects which match the value for the metadatakey given as parameters. For example: +
+list interface drivable
+
+will print all objects implementing the drivable interface in the SICS server. +
list objstatus obj +
Will query the current state of the SICS object obj. This makes sense for things like motors, counter etc. which +can be run asynchronously. The result can be idle, fault, busy etc. +
list match mask +
Will print the names of all SICS objects where the name + matches the wildcard given as mask. + +
+

+ + diff --git a/histmem.c b/histmem.c index 4d7c50be..26586a2c 100644 --- a/histmem.c +++ b/histmem.c @@ -1018,7 +1018,7 @@ static int checkHMEnd(pHistMem self, char *text){ if(0==strcmp("rank",pKey)) iDiscard=1; if(NULL!=strstr(pKey,"dim")) iDiscard=1; if(0==iDiscard) { - sprintf(pBuffer,"%s.%s = %s",name,pKey,pValue,sizeof(pValue)-1); + snprintf(pBuffer,511,"%s.%s = %s",name,pKey,pValue); SCWrite(pCon,pBuffer,eStatus); } pKey = StringDictGetNext(self->pOption,pValue,sizeof(pValue)-1); diff --git a/interface.h b/interface.h index b4d3c19e..326e491d 100644 --- a/interface.h +++ b/interface.h @@ -1,8 +1,8 @@ -#line 381 "interface.w" +#line 379 "interface.w" /*--------------------------------------------------------------------------- - I N T E R F A C E S + I N T E R F A C E S Any object in SICS has to adhere to the object descriptor interface (see file obdes.h). Furthermore SICS objects may choose to support other @@ -27,7 +27,7 @@ /* ----------------------- The drivable interface -----------------------*/ -#line 121 "interface.w" +#line 119 "interface.w" typedef struct { @@ -44,18 +44,18 @@ } IDrivable, *pIDrivable; pIDrivable GetDrivableInterface(void *pObject); - int GetDrivablePosition(void *pObject, SConnection *pCon, - float *fPos); + int GetDrivablePosition(void *pObject, SConnection *pCon, + float *fPos); -#line 407 "interface.w" +#line 405 "interface.w" pIDrivable CreateDrivableInterface(void); /* ------------------------ The countable interface ---------------------*/ -#line 188 "interface.w" +#line 186 "interface.w" typedef struct { int ID; @@ -72,23 +72,23 @@ pICountable GetCountableInterface(void *pObject); -#line 412 "interface.w" +#line 410 "interface.w" pICountable CreateCountableInterface(void); /* ------------------------- The CallBack Interface --------------------*/ -#line 241 "interface.w" +#line 239 "interface.w" typedef void (*KillFuncIT)(void *pData); typedef int (*SICSCallBack)(int iEvent, void *pEventData, void *pUserData, commandContext cc); -#line 417 "interface.w" +#line 415 "interface.w" -#line 263 "interface.w" +#line 261 "interface.w" typedef struct __ICallBack *pICallBack; @@ -105,15 +105,15 @@ int RemoveCallback2(pICallBack pInterface, void *pUserData); int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData, - int argc, char *argv[]); + int argc, char *argv[]); pICallBack GetCallbackInterface(void *pData); -#line 418 "interface.w" +#line 416 "interface.w" /*---------------------- The Environment Interface --------------------*/ -#line 335 "interface.w" +#line 333 "interface.w" typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode; typedef struct { @@ -123,13 +123,13 @@ int (*HandleError)(void *self); } EVInterface, *pEVInterface; -#line 420 "interface.w" +#line 418 "interface.w" -#line 361 "interface.w" +#line 359 "interface.w" pEVInterface CreateEVInterface(void); -#line 421 "interface.w" +#line 419 "interface.w" #endif diff --git a/interface.tex b/interface.tex index d6ef7978..c1331f38 100644 --- a/interface.tex +++ b/interface.tex @@ -1,13 +1,3 @@ -\newcommand{\NWtarget}[2]{#2} -\newcommand{\NWlink}[2]{#2} -\newcommand{\NWtxtMacroDefBy}{Macro defined by} -\newcommand{\NWtxtMacroRefIn}{Macro referenced in} -\newcommand{\NWtxtMacroNoRef}{Macro never referenced} -\newcommand{\NWtxtDefBy}{Defined by} -\newcommand{\NWtxtRefIn}{Referenced in} -\newcommand{\NWtxtNoRef}{Not referenced} -\newcommand{\NWtxtFileDefBy}{File defined by} -\newcommand{\NWsep}{${\diamond}$} \subsection{Object interfaces}\label{inter} In order to present themselves to the system SICS objects need to adhere to certyain interfaces. These interfaces are described in this @@ -38,24 +28,24 @@ Let's start with the objectdescriptor: \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap1} -$\langle\,$obdes\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ +$\langle$obdes {\footnotesize ?}$\rangle\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ \mbox{}\verb@/*--------------------------------------------------------------------------@\\ -\mbox{}\verb@ In SICS there is the to find out what an@\\ -\mbox{}\verb@ object is capable of at runtime. If this has been done a general@\\ -\mbox{}\verb@ way to access those capabilities is needed. In order to do all@\\ -\mbox{}\verb@ this each SICS-object is required to carry an object descriptor@\\ -\mbox{}\verb@ struct as first parameter in its class/object struct. Additionslly@\\ -\mbox{}\verb@ it is required to initialize this struct to something sensible.@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ This file defines this struct. Additionally a few functions of@\\ -\mbox{}\verb@ general use are prototyped.@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ Mark Koennecke, June, 1997@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ copyrigth: see implementation file @\\ +\mbox{}\verb@ In SICS there is the to find out what an@\\ +\mbox{}\verb@ object is capable of at runtime. If this has been done a general@\\ +\mbox{}\verb@ way to access those capabilities is needed. In order to do all@\\ +\mbox{}\verb@ this each SICS-object is required to carry an object descriptor@\\ +\mbox{}\verb@ struct as first parameter in its class/object struct. Additionslly@\\ +\mbox{}\verb@ it is required to initialize this struct to something sensible.@\\ +\mbox{}\verb@ @\\ +\mbox{}\verb@ This file defines this struct. Additionally a few functions of@\\ +\mbox{}\verb@ general use are prototyped.@\\ +\mbox{}\verb@ @\\ +\mbox{}\verb@ Mark Koennecke, June, 1997@\\ +\mbox{}\verb@ @\\ +\mbox{}\verb@ copyrigth: see implementation file @\\ \mbox{}\verb@----------------------------------------------------------------------------*/@\\ \mbox{}\verb@#ifndef SICSDESCRIPTOR@\\ \mbox{}\verb@#define SICSDESCRIPTOR@\\ @@ -66,8 +56,6 @@ $\langle\,$obdes\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ \mbox{}\verb@ char *name;@\\ \mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\ \mbox{}\verb@ void *(*GetInterface)(void *self, int iInterfaceID);@\\ -\mbox{}\verb@ char *description;@\\ -\mbox{}\verb@ char *group;@\\ \mbox{}\verb@ IPair *pKeys;@\\ \mbox{}\verb@ } ObjectDescriptor, *pObjectDescriptor;@\\ \mbox{}\verb@@\\ @@ -77,9 +65,9 @@ $\langle\,$obdes\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ \mbox{}\verb@ pObjectDescriptor FindDescriptor(void *pData);@\\ \mbox{}\verb@ @\\ \mbox{}\verb@/*============================================================================@\\ -\mbox{}\verb@ Objects which do not carry data need a dummy descriptor. Otherwise@\\ -\mbox{}\verb@ drive or scan will protection fault when trying to drive something@\\ -\mbox{}\verb@ which should not be driven. This is defined below.@\\ +\mbox{}\verb@ Objects which do not carry data need a dummy descriptor. Otherwise@\\ +\mbox{}\verb@ drive or scan will protection fault when trying to drive something@\\ +\mbox{}\verb@ which should not be driven. This is defined below.@\\ \mbox{}\verb@*/@\\ \mbox{}\verb@@\\ \mbox{}\verb@typedef struct {@\\ @@ -88,17 +76,17 @@ $\langle\,$obdes\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ \mbox{}\verb@ @\\ \mbox{}\verb@@\\ \mbox{}\verb@ pDummy CreateDummy(char *name);@\\ -\mbox{}\verb@ void KillDummy(void *pData); @\\ +\mbox{}\verb@ void KillDummy(void *pData); @\\ \mbox{}\verb@@\\ \mbox{}\verb@ int iHasType(void *pData, char *Type);@\\ \mbox{}\verb@ @\\ \mbox{}\verb@#endif @\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} -\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. +\item Macro referenced in scrap ?. \end{list} \end{minipage}\\[4ex] \end{flushleft} @@ -142,7 +130,7 @@ environment controllers fit this bill as well. \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap2} -$\langle\,$driv\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ +$\langle$driv {\footnotesize ?}$\rangle\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ @@ -161,15 +149,15 @@ $\langle\,$driv\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ \mbox{}\verb@ } IDrivable, *pIDrivable;@\\ \mbox{}\verb@@\\ \mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\ -\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\ -\mbox{}\verb@ float *fPos);@\\ +\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\ +\mbox{}\verb@ float *fPos);@\\ \mbox{}\verb@@\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} -\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. +\item Macro referenced in scrap ?. \end{list} \end{minipage}\\[4ex] \end{flushleft} @@ -222,7 +210,7 @@ This is an interface for interacting with anything which counts. \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap3} -$\langle\,$count\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ +$\langle$count {\footnotesize ?}$\rangle\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ @@ -240,12 +228,12 @@ $\langle\,$count\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ \mbox{}\verb@@\\ \mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\ \mbox{}\verb@@\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} -\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. +\item Macro referenced in scrap ?. \end{list} \end{minipage}\\[4ex] \end{flushleft} @@ -287,19 +275,19 @@ The first thing to define for such an interface is the type of the callback function: \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap4} -$\langle\,$callfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ +$\langle$callfunc {\footnotesize ?}$\rangle\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ \mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\ \mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\ \mbox{}\verb@ void *pUserData, commandContext cc);@\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} -\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. +\item Macro referenced in scrap ?. \end{list} \end{minipage}\\[4ex] \end{flushleft} @@ -321,7 +309,7 @@ interface: \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap5} -$\langle\,$cifunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ +$\langle$cifunc {\footnotesize ?}$\rangle\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ @@ -340,15 +328,15 @@ $\langle\,$cifunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ \mbox{}\verb@ int RemoveCallback2(pICallBack pInterface, void *pUserData);@\\ \mbox{}\verb@@\\ \mbox{}\verb@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,@\\ -\mbox{}\verb@ int argc, char *argv[]); @\\ +\mbox{}\verb@ int argc, char *argv[]); @\\ \mbox{}\verb@@\\ \mbox{}\verb@ pICallBack GetCallbackInterface(void *pData); @\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} -\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. +\item Macro referenced in scrap ?. \end{list} \end{minipage}\\[4ex] \end{flushleft} @@ -405,7 +393,7 @@ This interface is used by the environment monitor in order to monitor the status of a environment controller. The interface looks like this: \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap6} -$\langle\,$envir\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ +$\langle$envir {\footnotesize ?}$\rangle\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ @@ -416,12 +404,12 @@ $\langle\,$envir\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ \mbox{}\verb@ int (*IsInTolerance)(void *self);@\\ \mbox{}\verb@ int (*HandleError)(void *self);@\\ \mbox{}\verb@ } EVInterface, *pEVInterface;@\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} -\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. +\item Macro referenced in scrap ?. \end{list} \end{minipage}\\[4ex] \end{flushleft} @@ -444,17 +432,17 @@ in question. The environment interface has just one function associated with it: \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap7} -$\langle\,$envfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv$ +$\langle$envfunc {\footnotesize ?}$\rangle\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ \mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} \begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}} -\item \NWtxtMacroRefIn\ \NWlink{nuweb?}{?}. +\item Macro referenced in scrap ?. \end{list} \end{minipage}\\[4ex] \end{flushleft} @@ -462,11 +450,11 @@ $\langle\,$envfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap8} -\verb@"obdes.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$ +\verb@"obdes.h"@ {\footnotesize ? }$\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ -\mbox{}\verb@@\hbox{$\langle\,$obdes\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@$\langle$obdes {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@/*--------------------------------------------------------------------------*/@\\ \mbox{}\verb@/* Additional properties used by the ANSTO site to provide more information@\\ \mbox{}\verb@ * about each object instance, especially devices.@\\ @@ -477,19 +465,19 @@ $\langle\,$envfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv \mbox{}\verb@ char * GetDescriptorKey(pObjectDescriptor self, char *keyName);@\\ \mbox{}\verb@ char * GetDescriptorGroup(pObjectDescriptor self);@\\ \mbox{}\verb@ char * GetDescriptorDescription(pObjectDescriptor self);@\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-2ex} \end{minipage}\\[4ex] \end{flushleft} \begin{flushleft} \small \begin{minipage}{\linewidth} \label{scrap9} -\verb@"interface.h"@\nobreak\ {\footnotesize \NWtarget{nuweb?}{?} }$\equiv$ +\verb@"interface.h"@ {\footnotesize ? }$\equiv$ \vspace{-1ex} \begin{list}{}{} \item \mbox{}\verb@@\\ \mbox{}\verb@/*---------------------------------------------------------------------------@\\ -\mbox{}\verb@ I N T E R F A C E S@\\ +\mbox{}\verb@ I N T E R F A C E S@\\ \mbox{}\verb@@\\ \mbox{}\verb@ Any object in SICS has to adhere to the object descriptor interface (see@\\ \mbox{}\verb@ file obdes.h). Furthermore SICS objects may choose to support other@\\ @@ -513,23 +501,23 @@ $\langle\,$envfunc\nobreak\ {\footnotesize \NWtarget{nuweb?}{?}}$\,\rangle\equiv \mbox{}\verb@#define ENVIRINTERFACE 949@\\ \mbox{}\verb@@\\ \mbox{}\verb@/* ----------------------- The drivable interface -----------------------*/@\\ -\mbox{}\verb@@\hbox{$\langle\,$driv\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@$\langle$driv {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\\ \mbox{}\verb@ pIDrivable CreateDrivableInterface(void);@\\ \mbox{}\verb@@\\ \mbox{}\verb@/* ------------------------ The countable interface ---------------------*/@\\ -\mbox{}\verb@@\hbox{$\langle\,$count\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@$\langle$count {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@\\ \mbox{}\verb@ pICountable CreateCountableInterface(void);@\\ \mbox{}\verb@@\\ \mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\ -\mbox{}\verb@@\hbox{$\langle\,$callfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ -\mbox{}\verb@@\hbox{$\langle\,$cifunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@$\langle$callfunc {\footnotesize ?}$\rangle$\verb@@\\ +\mbox{}\verb@@$\langle$cifunc {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\ -\mbox{}\verb@@\hbox{$\langle\,$envir\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ -\mbox{}\verb@@\hbox{$\langle\,$envfunc\nobreak\ {\footnotesize \NWlink{nuweb?}{?}}$\,\rangle$}\verb@@\\ +\mbox{}\verb@@$\langle$envir {\footnotesize ?}$\rangle$\verb@@\\ +\mbox{}\verb@@$\langle$envfunc {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@#endif@\\ -\mbox{}\verb@@{\NWsep} +\mbox{}\verb@@$\diamond$ \end{list} \vspace{-2ex} \end{minipage}\\[4ex] diff --git a/interface.w b/interface.w index e8f3727d..c5dd1180 100644 --- a/interface.w +++ b/interface.w @@ -51,8 +51,6 @@ Let's start with the objectdescriptor: char *name; int (*SaveStatus)(void *self, char *name,FILE *fd); void *(*GetInterface)(void *self, int iInterfaceID); - char *description; - char *group; IPair *pKeys; } ObjectDescriptor, *pObjectDescriptor; diff --git a/linux_def b/linux_def index 4feb8a3b..95fe3c04 100644 --- a/linux_def +++ b/linux_def @@ -9,4 +9,4 @@ MFLAGS=-f makefile_linux$(DUMMY) -HDFROOT=/usr/local +HDFROOT=/afs/psi.ch/project/sinq/sl-linux \ No newline at end of file diff --git a/make_gen b/make_gen index 88ff0742..d1fa9bc2 100644 --- a/make_gen +++ b/make_gen @@ -30,7 +30,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\ hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \ mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \ - sinfox.o + sinfox.o sicslist.o MOTOROBJ = motor.o simdriv.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/makefile_slinux b/makefile_slinux index 7ead778a..493ec238 100644 --- a/makefile_slinux +++ b/makefile_slinux @@ -17,7 +17,7 @@ CC = gcc CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 -DNXXML $(NI) \ -Ipsi/hardsup -I. \ -fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY) \ - -Wall -Wno-unused -Wno-comment -Wno-switch -Werror + -Wall -Wno-unused -Wno-comment -Wno-switch BINTARGET = bin EXTRA=nintf.o @@ -26,7 +26,7 @@ SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \ LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\ -ltcl8.3 $(HDFROOT)/lib/libhdf5.a \ $(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \ - $(HDFROOT)/lib/libjpeg.a -lsz -ldl -lz -lmxml -lm -lc + $(HDFROOT)/lib/libjpeg.a -lsz -ldl -lz -lmxml -lghttp -lm -lc include make_gen diff --git a/obdes.c b/obdes.c index 92c0040d..64c16800 100644 --- a/obdes.c +++ b/obdes.c @@ -67,8 +67,6 @@ } pRes->name = strdup(name); pRes->pKeys = NULL; - pRes->description = NULL; - pRes->group = NULL; pRes->SaveStatus = DefaultSave; pRes->GetInterface = DefaultGetInterface; return pRes; @@ -78,8 +76,6 @@ { assert(self); if(self->name) free(self->name); - if(self->description) free(self->description); - if(self->group) free(self->group); if(self->pKeys) IFDeleteOptions(self->pKeys); free(self); @@ -160,11 +156,7 @@ { return; } - if(NULL != self->group) - { - free(self->group); - } - self->group = strdup(group); + IFSetOption(self->pKeys,"group",group); } /*--------------------------------------------------------------------------*/ void SetDescriptorDescription(pObjectDescriptor self, char *description) @@ -173,11 +165,7 @@ { return; } - if(NULL != self->description) - { - free(self->description); - } - self->description = strdup(description); + IFSetOption(self->pKeys,"description", description); } /*--------------------------------------------------------------------------*/ char * GetDescriptorKey(pObjectDescriptor self, char *keyName) @@ -195,14 +183,14 @@ { return NULL; } - return self->group; + return IFindOption(self->pKeys,"group"); } /*--------------------------------------------------------------------------*/ - char * GetDescriptorDescription(pObjectDescriptor self) + char *GetDescriptorDescription(pObjectDescriptor self) { if(NULL==self) { return NULL; } - return self->description; + return IFindOption(self->pKeys,"description"); } diff --git a/obdes.h b/obdes.h index 3f700d6f..d82dc49d 100644 --- a/obdes.h +++ b/obdes.h @@ -1,23 +1,23 @@ -#line 367 "interface.w" +#line 365 "interface.w" #line 29 "interface.w" /*-------------------------------------------------------------------------- - In SICS there is the to find out what an - object is capable of at runtime. If this has been done a general - way to access those capabilities is needed. In order to do all - this each SICS-object is required to carry an object descriptor - struct as first parameter in its class/object struct. Additionslly - it is required to initialize this struct to something sensible. - - This file defines this struct. Additionally a few functions of - general use are prototyped. - - Mark Koennecke, June, 1997 - - copyrigth: see implementation file + In SICS there is the to find out what an + object is capable of at runtime. If this has been done a general + way to access those capabilities is needed. In order to do all + this each SICS-object is required to carry an object descriptor + struct as first parameter in its class/object struct. Additionslly + it is required to initialize this struct to something sensible. + + This file defines this struct. Additionally a few functions of + general use are prototyped. + + Mark Koennecke, June, 1997 + + copyrigth: see implementation file ----------------------------------------------------------------------------*/ #ifndef SICSDESCRIPTOR #define SICSDESCRIPTOR @@ -28,8 +28,6 @@ char *name; int (*SaveStatus)(void *self, char *name,FILE *fd); void *(*GetInterface)(void *self, int iInterfaceID); - char *description; - char *group; IPair *pKeys; } ObjectDescriptor, *pObjectDescriptor; @@ -39,9 +37,9 @@ pObjectDescriptor FindDescriptor(void *pData); /*============================================================================ - Objects which do not carry data need a dummy descriptor. Otherwise - drive or scan will protection fault when trying to drive something - which should not be driven. This is defined below. + Objects which do not carry data need a dummy descriptor. Otherwise + drive or scan will protection fault when trying to drive something + which should not be driven. This is defined below. */ typedef struct { @@ -50,13 +48,13 @@ typedef struct { pDummy CreateDummy(char *name); - void KillDummy(void *pData); + void KillDummy(void *pData); int iHasType(void *pData, char *Type); #endif -#line 368 "interface.w" +#line 366 "interface.w" /*--------------------------------------------------------------------------*/ /* Additional properties used by the ANSTO site to provide more information diff --git a/ofac.c b/ofac.c index 00f1759c..fcebc552 100644 --- a/ofac.c +++ b/ofac.c @@ -116,6 +116,7 @@ #include "mccontrol.h" #include "protocol.h" #include "sinfox.h" +#include "sicslist.h" /*----------------------- Server options creation -------------------------*/ static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) @@ -239,7 +240,7 @@ AddCommand(pInter,"sicsdatafactory",SICSDataFactory,NULL,NULL); AddCommand(pInter,"scriptcallback",CallbackScript,NULL,NULL); AddCommand(pInter,"help",SicsHelp,KillHelp,NULL); - AddCommand(pInter,"sicsatt",SicsAtt,NULL,NULL); + AddCommand(pInter,"list",SicsList,NULL,NULL); /* commands to do with the executor. Only StopExe carries the DeleteFunction in order to avoid double deletion. All the diff --git a/protocol.c b/protocol.c index fc052127..cc790d5d 100644 --- a/protocol.c +++ b/protocol.c @@ -14,6 +14,7 @@ #include #include #include +#include "commandlog.h" #include "protocol.h" #define MAXMSG 1024 @@ -342,7 +343,7 @@ int ProtocolAction(SConnection *pCon, SicsInterp *pSics, void *pData, {"options",0,{0,0}}, {"set",1,{FUPATEXT}}, {"reset",0,{0,0}}, - NULL + {NULL} }; assert(pCon); @@ -475,9 +476,9 @@ int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut) pMsg = CreateDynString(INIT_STR_SIZE, STR_RESIZE_LENGTH); pBueffel[0] = '\0'; - sprintf(pBueffel,"con%4.4d",pCon->ident); /* field 1: connID */ + sprintf(pBueffel,"con%4.4d",(int)pCon->ident); /* field 1: connID */ DynStringConcat(pMsg,pBueffel); - sprintf(pBueffel," t%6.6d",taskID); /* field 2: taskID */ + sprintf(pBueffel," t%6.6d",(int)taskID); /* field 2: taskID */ DynStringConcat(pMsg,pBueffel); DynStringConcatChar(pMsg,' '); /* deviceID */ diff --git a/rs232controller.c b/rs232controller.c index 92934823..1f4dcac8 100644 --- a/rs232controller.c +++ b/rs232controller.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "fortify.h" #include "sics.h" #include "splitter.h" diff --git a/sicslist.c b/sicslist.c new file mode 100644 index 00000000..60bfc496 --- /dev/null +++ b/sicslist.c @@ -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 +#include +#include +#include +#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; +} diff --git a/sicslist.h b/sicslist.h new file mode 100644 index 00000000..39a385bf --- /dev/null +++ b/sicslist.h @@ -0,0 +1,15 @@ +/* + A module for displaying various bits of information about SICS + internals and objects. + + copyright: see file COPYRIGHT + + Mark Koennecke, January 2006 + */ +#ifndef SICSLIST_H_ +#define SICSLIST_H_ +#include +int SicsList(SConnection *pCon, SicsInterp *pSics, + void *pData, int argc, char *argv[]); + +#endif /*SICSLIST_H_*/ diff --git a/sinfox.c b/sinfox.c index 6330b687..75cfc21e 100644 --- a/sinfox.c +++ b/sinfox.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include /* incl. SCWrite */ @@ -100,8 +101,6 @@ pSinfox CreateSinfox(void) "::server::instrument",TCL_GLOBAL_ONLY); pNew->schemaVersion = Tcl_GetVar(tTcl, "::server::schemaVersion",TCL_GLOBAL_ONLY); - pNew->pDes->description = NULL; - pNew->pDes->group = NULL; pNew->pDes->pKeys = NULL; return pNew; } @@ -297,6 +296,7 @@ static int SinfoxGetGrp(pSinfox pSin, SicsInterp *pSics, return 1; } } + return 0; } /*------------------------------------------------------------------------*/ static int SinfoxSetKey(pSinfox pSin, SicsInterp *pSics, @@ -412,6 +412,7 @@ static int SinfoxReadKey(pSinfox pSin, SicsInterp *pSics, return 1; } } + return 0; } /*------------------------------------------------------------------------*/ @@ -503,6 +504,7 @@ static int SinfoxList(pSinfox pSin, SicsInterp* pSics, SConnection *pCon, } return 1; } + return 0; } /*------------------------------------------------------------------------*/ @@ -518,7 +520,7 @@ static int SinfoxEnumerate(pSinfox pSin, SicsInterp* pSics, IPair *pGroups = NULL; pSicsVariable pSVar = NULL; int iRet; - char pBuf[256]; + char pBuf[256], *pPtr = NULL; int checkDeviceTypes[iNumDeviceTypes]; pCurrent = pSics->pCList; @@ -632,9 +634,9 @@ static int SinfoxEnumerate(pSinfox pSin, SicsInterp* pSics, if(1==isObjectDevice(pCurrent)) { pDes = FindDescriptor(pCurrent->pData); - if(NULL != pDes->group) + if((pPtr = IFindOption(pDes->pKeys,"group")) != NULL) { - strcpy(pBuf,pDes->group); + strcpy(pBuf,pPtr); strtolower(pBuf); if(NULL==IFindOption(pGroups,pBuf)) { @@ -716,16 +718,16 @@ static int SinfoxShow(pSinfox pSin, SicsInterp* pSics, SConnection *pCon, strtolower(pBuf); addToList(tTcl,tList,"devicetype",pBuf); } - if(NULL!=pDes->group) + if((pTmp = IFindOption(pDes->pKeys,"group")) != NULL) { - strcpy(pBuf,pDes->group); + strcpy(pBuf,pTmp); strtolower(pBuf); addToList(tTcl,tList,"group",pBuf); } } - if(NULL!=pDes->description) + if((pTmp = IFindOption(pDes->pKeys,"description")) != NULL) { - strcpy(pBuf,pDes->description); + strcpy(pBuf,pTmp); strtolower(pBuf); addToList(tTcl,tList,"description",pBuf); } @@ -782,13 +784,13 @@ static int SinfoxShow(pSinfox pSin, SicsInterp* pSics, SConnection *pCon, pDes = FindDescriptor(pCurrent->pData); if(NULL != pDes) { - if(NULL == pDes->group) + if((pTmp = IFindOption(pDes->pKeys,"group")) == NULL) { strcpy(pBuf,"none"); } else { - strcpy(pBuf,pDes->group); + strcpy(pBuf,pTmp); strtolower(pBuf); } if(0==strcmp(pElt,pBuf)) @@ -961,7 +963,7 @@ int SinfoxAction(SConnection *pCon, SicsInterp *pSics, void *pData, {"reset",0,{0,0}}, {"readkey",2,{FUPATEXT,FUPATEXT}}, {"getgrp",1,{FUPATEXT}}, - NULL + {NULL} }; assert(pCon); diff --git a/tclmotdriv.c b/tclmotdriv.c index c438a257..a6dedfa0 100644 --- a/tclmotdriv.c +++ b/tclmotdriv.c @@ -107,7 +107,7 @@ static int buildStandardCommandPart(TCLDriv *pDriv, char *command, strncpy(pDriv->tclError,result,1023); return HWFault; } - sscanf(result,"%d%",&status); + sscanf(result,"%d",&status); return status; } /*-------------------------------------------------------------------------*/ @@ -182,12 +182,11 @@ static int evaluateInternalErrors(TCLDriv *pDriv, int *iCode, assert(self); pDriv = (TCLDriv *)self; - pDriv->errorCode = 0; if(!buildStandardCommandPart(pDriv,"fixit",tclCommand,1023)){ pDriv->errorCode = FUNCNOTFOUND; return HWFault; } - snprintf(num,79,"%f",fNew); + snprintf(num,79,"%d %f",pDriv->errorCode, fNew); strncat(tclCommand,num,1023-strlen(tclCommand)); status = Tcl_Eval(pServ->pSics->pTcl,tclCommand); @@ -201,7 +200,7 @@ static int evaluateInternalErrors(TCLDriv *pDriv, int *iCode, strncpy(pDriv->tclError,result,1023); return HWFault; } - sscanf(result,"%d%",&status); + sscanf(result,"%d",&status); return status; } /*--------------------------------------------------------------------------*/ @@ -262,7 +261,7 @@ static int evaluateInternalErrors(TCLDriv *pDriv, int *iCode, strncpy(pDriv->tclError,result,1023); return HWFault; } - sscanf(result,"%d%",&status); + sscanf(result,"%d",&status); return status; } /*-----------------------------------------------------------------------*/ diff --git a/tclmotdriv.h b/tclmotdriv.h index 96520e9e..aff43a6c 100644 --- a/tclmotdriv.h +++ b/tclmotdriv.h @@ -38,4 +38,7 @@ char tclError[1024]; char motName[132]; } TCLDriv; + +MotorDriver *CreateTclMotDriv(SConnection *pCon, int argc, char *argv[]); + #endif