//
// tcl++.hpp
//
//---------------------------------------------------------------------------
// Copyright 1991 Karl Lehenbauer and Mark Diekhans.
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for any purpose and without fee is hereby granted, provided
// that the above copyright notice appear in all copies.  Karl Lehenbauer and
// Mark Diekhans make no representations about the suitability of this
// software for any purpose.  It is provided "as is" without express or
// implied warranty.
//---------------------------------------------------------------------------
// Based on Tcl C++ classes developed by Parag Patel.
//
// Modified by Open Systems Solutions, Inc.
// Copyright 1992 Open Systems Solutions, Inc.
//

#ifndef _TCL_PLUS_PLUS_HPP
#define _TCL_PLUS_PLUS_HPP

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#ifndef TCLEXTEND_H
#include "tclExtend.h"
#endif

class TclInterp_cl
{
    Tcl_Interp *interp;
    friend class TclTrace_cl;

private:
    char *CatVarArgs (va_list  argPtr);

public:
    TclInterp_cl();
    ~TclInterp_cl ();
    char *Result ()const {return interp->result;}
    int ErrorLine() const {return interp->errorLine;}
    Tcl_Interp * GetInterp(){return interp;}

   /*
    * Exported Tcl procedures (from standard baseline):
    */
    void AppendElement (const char *string, int noSep)
	{Tcl_AppendElement (interp, (char *) string, noSep);}

    void AppendResult (const char *p, ...);

    void AddErrorInfo (const char *message)
	{Tcl_AddErrorInfo (interp, (char *)message);}

    void CreateCommand (const char        *cmdName,
			Tcl_CmdProc       *proc, 
			ClientData         data, 
			Tcl_CmdDeleteProc *deleteProc)
    {Tcl_CreateCommand (interp, (char*) cmdName, proc, data, deleteProc);}

    int CreatePipeline (int    argc, 
			char **argv, 
			int  **pidArrayPtr,
			int   *inPipePtr, 
			int   *outPipePtr,
			int   *errFilePtr)
	{return Tcl_CreatePipeline (interp, argc, argv, pidArrayPtr, inPipePtr,
				    outPipePtr, errFilePtr);}

    Tcl_Trace CreateTrace (int               level,
			   Tcl_CmdTraceProc *proc, 
			   ClientData        data)
	{return Tcl_CreateTrace (interp, level, proc, data);}

    void DeleteCommand (const char *cmdName)
	{Tcl_DeleteCommand (interp, (char *)cmdName);}

    void  DeleteTrace (Tcl_Trace trace)
	{Tcl_DeleteTrace(interp, trace);}

    void DetachPids (int  numPids, int *pidPtr)
	{Tcl_DetachPids (numPids, pidPtr);}

    inline int 
    Eval (const char   *cmd, 
          char          flags = 0, 
          char        **termPtr = NULL)
        { return Tcl_Eval (interp, (char *) cmd, flags, termPtr); }

    int EvalFile (const char *fileName)
	{return Tcl_EvalFile (interp, (char *) fileName);}

    int ExprBoolean (const char *string, int *ptr)
	{return Tcl_ExprBoolean (interp, (char *) string, ptr);}

    int ExprDouble (const char *string, double *ptr)
	{return Tcl_ExprDouble (interp, (char *) string, ptr);}

    int ExprLong (const char *string, long *ptr)
	{return Tcl_ExprLong (interp, (char *) string, ptr);}

    int ExprString (const char *string)
	{return Tcl_ExprString (interp, (char *) string);}

    int GetBoolean (const char *string, int *boolPtr)
	{return Tcl_GetBoolean (interp, (char *) string, boolPtr);}

    int GetDouble (const char *string, double *doublePtr)
	{return Tcl_GetDouble (interp, (char *) string, doublePtr);}

    int GetInt (const char *string, int *intPtr)
	{return Tcl_GetInt (interp, (char *) string, intPtr);}

    const char * GetVar (const char *varName, int flags = 0)
	{return Tcl_GetVar (interp, (char *) varName, flags);}

    const char *GetVar2 (const char *name0, const char *name1, int flags = 0)
	{return Tcl_GetVar2 (interp, (char *) name0, (char *) name1, flags);}

    void InitMemory (){Tcl_InitMemory (interp);}
    char *ParseVar (const char  *string, char **termPtr)
       { return Tcl_ParseVar (interp, (char *) string, termPtr); }

    int RecordAndEval (const char *cmd, char flags)
        { return Tcl_RecordAndEval (interp, (char *) cmd, flags); }

    void ResetResult (){Tcl_ResetResult (interp);}
    void SetErrorCode (char *p, ...);
    void SetResult (const char *string)
    {Tcl_SetResult (interp, (char *) string, TCL_VOLATILE);}

    void SetResult (const char *string, Tcl_FreeProc *freeProc)
    {Tcl_SetResult (interp, (char *) string, freeProc);}

    const char *SetVar (const char *varName, const char *newValue, 
			int global = 0)
	{return Tcl_SetVar (interp, (char *) varName, (char *) newValue, 
			    global);}

    const char * SetVar2 (const char *name0, 
			  const char *name1, 
			  const char *newValue, 
			  int         global)
	{return Tcl_SetVar2 (interp, (char *) name0, (char *) name1, 
			     (char *) newValue, global);}

    int SplitList (const char *list, int &argcP, char **&argvP)
        { return Tcl_SplitList (interp, (char *) list, &argcP, &argvP); }

    char *TildeSubst (const char *name)
        { return Tcl_TildeSubst (interp, (char *) name);}

    int TraceVar (const char       *varName,
		  int               flags,
		  Tcl_VarTraceProc *proc,
		  ClientData        clientData)
	{return Tcl_TraceVar (interp, (char *)varName, flags, proc,
			      clientData);}

    inline int
    TraceVar2 (const char       *name0, 
               const char       *name1,
               int               flags, 
               Tcl_VarTraceProc *proc, 
               ClientData        clientData)
    {
         return Tcl_TraceVar2 (interp, (char *) name0, (char *) name1, flags,
                               proc, clientData); 
    }

    const char * UnixError ()const {return Tcl_UnixError (interp);}

    void UnsetVar (const char *varName, int global)
        { Tcl_UnsetVar (interp, (char *) varName, global); }

    void UnsetVar2 (const char *name0, const char *name1, int global)
        { Tcl_UnsetVar2 (interp, (char *) name0, (char *) name1, global); }

    void UntraceVar (const char       *varName, 
		     int               flags,
		     Tcl_VarTraceProc *proc, 
		     ClientData        clientData)
	{Tcl_UntraceVar (interp, (char *) varName, flags, proc, clientData);}


    void UntraceVar2 (const char       *name0,
		      const char       *name1,
		      int               flags, 
		      Tcl_VarTraceProc *proc, 
		      ClientData        clientData)
    {Tcl_UntraceVar2 (interp, (char *) name0, (char *) name1, flags, proc,
		      clientData);}

    int VarEval (const char *p,...);

    ClientData VarTraceInfo (const char        *varName,
			     int               flags,
			     Tcl_VarTraceProc *procPtr,
			     ClientData        prevClientData)
    {return Tcl_VarTraceInfo (interp, (char *) varName, flags, procPtr,
			      prevClientData);}

    inline ClientData
    VarTraceInfo2 (const char       *name0, 
                   const char       *name1, 
                   int               flags,
                   Tcl_VarTraceProc *procPtr,
                   ClientData        prevClientData)
    { return Tcl_VarTraceInfo2 (interp, (char *) name0, (char *) name1, 
				flags, procPtr, prevClientData);}

    //
    // Exported Tcl functions added to baseline Tcl by the Extended Tcl 
    // implementation.

    void CommandLoop (FILE *inFile, FILE *outFile, int (*evalProc)(),
		      unsigned    options)
    {Tcl_CommandLoop (interp, inFile, outFile, evalProc, options);}

    inline char *
    DeleteKeyedListField (const char  *fieldName,
                          const char  *keyedList)
    {return Tcl_DeleteKeyedListField (interp, fieldName, keyedList);}

    void ErrorAbort(int  exitCode){Tcl_ErrorAbort (interp, exitCode);}

    int
    GetKeyedListField (const char  *fieldName, const char  *keyedList,
                       char       **fieldValuePtr)
    {
        return Tcl_GetKeyedListField (interp, fieldName, keyedList,
                                      fieldValuePtr);
    }

    int GetKeyedListKeys (const char  *subfieldName, const char *keyedList,
			  int         *keyesArgcPtr,
			  char      ***keyesArgvPtr)
    {return Tcl_GetKeyedListKeys (interp, subfieldName, keyedList,
				  keyesArgcPtr,  keyesArgvPtr);}

    int GetLong (const char *string, long *longPtr)
        {return Tcl_GetLong (interp, string, longPtr); }

    int GetUnsigned (const char *string, unsigned *unsignedPtr)
	{return Tcl_GetUnsigned (interp, string, unsignedPtr);}

    char * SetKeyedListField (const char  *fieldName,
			      const char  *fieldvalue,
			      const char  *keyedList)
    {return Tcl_SetKeyedListField (interp, fieldName, fieldvalue,
                                      keyedList);}

    int ShellEnvInit (unsigned     options,
                      const char  *programName, 
                      int          argc,
                      const char **argv,
                      int          interactive,
                      const char  *defaultFile)
	{return Tcl_ShellEnvInit (interp, options, programName, argc, argv,
                                  interactive, defaultFile);}

    void Startup (int argc, const char **argv, const char *defaultFile, 
		  unsigned options) 
    {Tcl_Startup (interp, argc, argv, defaultFile, options);}

    int System (const char *command)
	{return Tcl_System (interp, (char*) command);}
};

//
// Trace class.
class TclTrace_cl
{
    Tcl_Trace trace;
    TclInterp_cl &interp;

public:
    TclTrace_cl (TclInterp_cl     &interpCl, 
                 int               level, 
                 Tcl_CmdTraceProc *proc, 
                 ClientData        data);
    ~TclTrace_cl () { Tcl_DeleteTrace (interp.GetInterp(), trace); }
};

//
// Assemble command buffer class.
class TclCmdBuf_cl
{
    Tcl_CmdBuf buf;

public:
    TclCmdBuf_cl () { buf = Tcl_CreateCmdBuf (); }
    ~TclCmdBuf_cl () { Tcl_DeleteCmdBuf (buf); }

    inline const char *
    AssembleCmd (const char *string)
        { return Tcl_AssembleCmd (buf, (char *) string); }
};

//
// Handle table class.
class TclHandleTbl_cl
{
    void_pt headerPtr;

public:
    TclHandleTbl_cl (const char *handleBase, int entrySize, int initEntries);
    ~TclHandleTbl_cl (){Tcl_HandleTblRelease (headerPtr);}

    void_pt HandleAlloc (char *handlePtr)
	{return Tcl_HandleAlloc (headerPtr, handlePtr);}

    void HandleFree (void_pt  entryPtr)
	{Tcl_HandleFree (headerPtr, entryPtr);}

    int HandleTblUseCount (int amount)
	{return Tcl_HandleTblUseCount (headerPtr, amount);}

    void_pt HandleWalk (int *walkKeyPtr)
	{return Tcl_HandleWalk (headerPtr, walkKeyPtr);}

    void_pt HandleXlate (Tcl_Interp  *interp, const  char *handle)
	{return Tcl_HandleXlate (interp, headerPtr, handle);}

    void WalkKeyToHandle(int walkKey, char *handlePtr)
	{Tcl_WalkKeyToHandle(headerPtr, walkKey, handlePtr);}
	
};

#endif // _TCL_PLUS_PLUS_HPP
 

