\subsection{The SICS Interpreter} \label{scinter} The SICS interpreter does the first step of command interpretation. Each SICS command is a name followed by parameters. The interpreter holds for each command a function (the object function) and a data structure. When a command is invoked the list will be searched for a fitting command and then its object function will be invoked for further processing. The object function is the object wrapper function as discussed in much detail in the Guide to Object Writers. It looks like this: \begin{verbatim} typedef int (*ObjectFunc)(pSConnection pCon, pSicsInterp pInter, void *pData, int argc, char *argv[]); \end{verbatim} {\bf pCon} is a pointer to the the connection for which the command was invoked. {\bf pInter} is the SICS interpreter in which the command was invoked. {argc, argv[]} are the command arguments similar to the classic C main() function arguments. This is an objects interface to the SICS interpreter. {\bf pData} is a pointer to a command own data structure. This data structure is deleted by the interpreter when the command is removed by calling a special removal function with the pointer as parameter. This function looks like this: \begin{verbatim} typedef void (*KillFunc)(void *pData); \end{verbatim} In order to do ist job the SICS interpreter has for each command a data structure defined below: \begin{verbatim} typedef struct __Clist { char *pName; ObjectFunc OFunc; KillFunc KFunc; void *pData; struct __Clist *pNext; struct __Clist *pPrevious; } CommandList; \end{verbatim} The fields are: \begin{description} \item[name] The command name. \item[OFunc] The object wrapper function. \item[KFunc] The object data structure removal function. \item[pData] The objects data structure. \item[pNext, pPrevious] pointers necessary to maintain the doubly linked list of commands. \end{description} The interpreter itself is described by the following data structure: \begin{verbatim} typedef struct __SINTER { CommandList *pCList; OutCode eOut; void *pTcl; char **argv; int iDeleting; }SicsInterp; \end{verbatim} The fields are: \begin{description} \item[pCList] A pointer to the command list. \item[eOut] an out code. \item[pTcl] a pointer to the Tcl macro interpreter. \item[argv] An argv[] array with command arguments. \item[iDeleting] a flag which is set when the interpreter is in the process of being removed. \end{description} Please note, that currently commands are searched for by linear scanning of the command list, doing a strcmp at each stop. This is inherently inefficient. If in some stage interpreter inefficiency is a problem this scheme should be chnaged to a hash table system or a randomized binary tree. The interpreter can be controlled with the following functions: \begin{description} \item[SicsInterp *InitInterp(void)] Makes a new interpreter. Returns him on success, else NULL \item[int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc, KillFunc pKFunc, void *pData)] Adds a new command, Returns True or False, depending on success Parameters: \begin{itemize} \item pInterp : the interpreter to add the command to. \item pName : the commands name \item pFunc : the object function to call when this command is invoked. Definition of type: see above \item pKFunc : function to call in order to delete command data. type definition: above \item pData : pointer to the command's own datastructure. Will be passed as pData with each call to Ofunc. \end{itemize} It is possible to install commands without an associated data structure. Then pData must be NULL. In such cases AddCommand provides a default data structure with a default object descriptor. \item[int RemoveCommand(SicsInterp *pInterp, char *pName)] Kills the command name from the interpreter pInterp \item[int InterpExecute(SicsInterp *self,pSConnection pCon,char *pCommand)] Executes a command in the interpreter self. Essentially converts pCommand in an argc, argv[] pair, sets various status things and invokes the object function. Takes care of status and error reporting afterwards. Parameters: \begin{itemize} \item self : interpreter to invoke command in. \item The connection pCon will be used for I/O and status reporting. \item The command to invoke is the string pCommand. \end{itemize} Returns -1 if the command can not be found. If the command is found, 1 is returned on success, 0 on failure in the command. \item[CommandList *FindCommand(SicsInterp *pInterp, char *name)] Searches the Interpreters pInterp command list for a command with name. Returns its data structure if found, NULL else \item[int WriteSicsStatus(SicsInterp *pSics,char *file)] SICS needs a way to save the status of each object into a file. This is done by invoking for each object the object descriptor function SaveStatus. This function does just that. Parameters: \begin{itemize} \item pSics : the interpreter to use. \item file : the file to write the information to. \end{itemize} Returns: 1 on success, 0 on failure. \item[int InterpWrite(SicsInterp *pSics, char *buffer)] Writes result to Tcl, used for Macro mechanism. This is an internal function and should not be used. \item[void DeleteInterp(SicsInterp *self)] Deletes the interpreter self aand clears all asoociated datastructures. self will no longer be vaild after this. \item[FindAlias] find the alias for a given data structure. This is a special function required internally. \item[FindCommandData] is a convenience wrapper around FindCommand which returns the commands data structure instead the CommandList entry fo a given command name. Returns NULL, if the command was not found. \end{description}