/*--------------------------------------------------------------------------

	The SICS needs an interpreter. This is it.
	
	Mark Koennecke, November 1996
	
	copyright: see implementation file
	
---------------------------------------------------------------------------*/
#ifndef SICSINTERPRETER
#define SICSINTERPRETER
#include "Scommon.h" 
/* M.Z. */
#include "definealias.i"

typedef struct __SConnection *pSConnection;
typedef struct __SINTER      *pSicsInterp;


typedef int (*ObjectFunc)(pSConnection pCon, pSicsInterp pInter, void
                          *pData, int argc, char *argv[]);

typedef void (*KillFunc)(void *pData);

typedef struct __Clist {
                          char       *pName;
                          ObjectFunc OFunc;
                          KillFunc   KFunc;
                          void *pData;
                          struct __Clist *pNext;
                          struct __Clist *pPrevious;
                        }  CommandList;

typedef struct __SINTER
             {
               CommandList *pCList;
               OutCode eOut;
               void  *pTcl;
               int iDeleting;
               AliasList AList; /* M.Z. */
             }SicsInterp;
             
/*-------------------------------------------------------------------------*/
  SicsInterp *InitInterp(void);
  /* makes a new interpreter. Returns him on success, else NULL
  */
/*------------------------------------------------------------------------*/  
  int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc, 
                 KillFunc pKFunc, void *pData);
  /* adds a new command, Returns True or False, depending on success
     Parameters:
              pInterp : the interpreter to add the command to.
              pName   : the commands name
              pFunc   : the object function to call when this command is
                        invoked. Definition of type: see above
              pKFunc  : function to call in order to delete command data.
                        type definition: above
              pData   : pointer to the command's own datastructure. Will be 
                        passed as pData with each call to Ofunc.                    
  */ 
/*-------------------------------------------------------------------------*/  
  int RemoveCommand(SicsInterp *pInterp, char *pName);
  /* kills the  command name from the interpreter pInterp 
  */ 
/*-------------------------------------------------------------------------*/  
  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:
    self : interpreter to invoke command in.
    The connection pCon will be used for I/O and status reporting.
    The command to invoke is the string pCommand.
    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.
----------------------------------------------------------------------------*/
  
  CommandList *FindCommand(SicsInterp *pInterp, char *name);
  /*
     Searches the Interpreters pInterp command list for a command
     with name. Returns ist datastructure if found, NULL else
  */
/*-------------------------------------------------------------------------*/
  int WriteSicsStatus(SicsInterp *pSics,char *file, int iMot);
  /*
      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:
                  pSics : the interpreter to use.
                  file  : the file to write the information to.
                  iMot  : flag if motor position shall be saved or not
      Returns: 1 on success, 0 on failure. 
---------------------------------------------------------------------------*/                 
  int InterpWrite(SicsInterp *pSics, char *buffer);
  /*
     writes result to Tcl, used for Macro mechanism.
     This is an internal function and should not be used.
----------------------------------------------------------------------------*/
  
  void DeleteInterp(SicsInterp *self);
  /* 
     deletes the interpreter self aand clears all asoociated datastructures.
     self will no longer be valid after this.
---------------------------------------------------------------------------  */
  void strtolower(char *pText);
  /*
    strtolower converts a string to lowercase
---------------------------------------------------------------------------  */
  void argtolower(int argc, char *argv[]);
  /*
    converts an argc, argv[] pair to lowercase
  */  

/*--------------------------------------------------------------------------
  FindAlias tries to find an alias to the datastructure given as second
  parameter. Returns the command name on success, else NULL. Be warned, this
  is very special
  */
  
  char *FindAlias(SicsInterp *pSics, void *pData);
      
/*-------------------------------------------------------------------------
  FindCommandData finds a command with the name given. It tests the name in the
  ObjectDescriptor to be of name class. If all this succeeds a pointer
  to the commands data structure is retuned. Else NULL
*/
  void *FindCommandData(SicsInterp *pSics, char *name, char *comclass);    

/*------------------------------------------------------------------------
  FindDrivable tries to find Drivable object by the name given. Returns a
  pointer to the drivable interface in the case of success, NULL in
  case of failure. In order to save me fixing header files the pointer must
  be cast to the drivable interface pointer.
  ------------------------------------------------------------------------*/

void *FindDrivable(SicsInterp *pics, char *name);
#endif

