1996-09-27 06:29:02 -04:00
|
|
|
/*
|
|
|
|
* tclInt.h --
|
|
|
|
*
|
|
|
|
* Declarations of things used internally by the Tcl interpreter.
|
|
|
|
*
|
|
|
|
* Copyright (c) 1987-1993 The Regents of the University of California.
|
1998-04-10 06:59:06 -04:00
|
|
|
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
|
|
|
|
* Copyright (c) 1993-1997 Lucent Technologies.
|
1996-09-27 06:29:02 -04:00
|
|
|
*
|
|
|
|
* See the file "license.terms" for information on usage and redistribution
|
|
|
|
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
|
|
*
|
1998-09-30 07:11:02 -04:00
|
|
|
* SCCS: @(#) tclInt.h 1.16 98/08/10 15:44:18
|
1996-09-27 06:29:02 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _TCLINT
|
|
|
|
#define _TCLINT
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Common include files needed by most of the Tcl source files are
|
|
|
|
* included here, so that system-dependent personalizations for the
|
|
|
|
* include files only have to be made in once place. This results
|
|
|
|
* in a few extra includes, but greater modularity. The order of
|
|
|
|
* the three groups of #includes is important. For example, stdio.h
|
|
|
|
* is needed by tcl.h, and the _ANSI_ARGS_ declaration in tcl.h is
|
|
|
|
* needed by stdlib.h in some configurations.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#ifndef _TCL
|
|
|
|
#include "tcl.h"
|
|
|
|
#endif
|
|
|
|
#ifndef _REGEXP
|
|
|
|
#include "tclRegexp.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#ifdef NO_LIMITS_H
|
1999-09-05 07:16:41 -04:00
|
|
|
# ifdef SCM_CODE
|
1998-04-30 07:04:33 -04:00
|
|
|
# include "compat/limits.h"
|
|
|
|
# else
|
|
|
|
# include "../compat/limits.h"
|
|
|
|
# endif
|
1996-09-27 06:29:02 -04:00
|
|
|
#else
|
|
|
|
# include <limits.h>
|
|
|
|
#endif
|
|
|
|
#ifdef NO_STDLIB_H
|
1999-09-05 07:16:41 -04:00
|
|
|
# ifdef SCM_CODE
|
1998-04-30 07:04:33 -04:00
|
|
|
# include "compat/stdlib.h"
|
|
|
|
# else
|
|
|
|
# include "../compat/stdlib.h"
|
|
|
|
# endif
|
1996-09-27 06:29:02 -04:00
|
|
|
#else
|
|
|
|
# include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
#ifdef NO_STRING_H
|
1999-09-05 07:16:41 -04:00
|
|
|
# ifdef SCM_CODE
|
1998-04-30 07:04:33 -04:00
|
|
|
# include "compat/string.h"
|
|
|
|
# else
|
|
|
|
# include "../compat/string.h"
|
|
|
|
# endif
|
1996-09-27 06:29:02 -04:00
|
|
|
#else
|
|
|
|
#include <string.h>
|
|
|
|
#endif
|
1998-09-30 07:11:02 -04:00
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
#if defined(__STDC__) || defined(HAS_STDARG)
|
|
|
|
# include <stdarg.h>
|
|
|
|
#else
|
|
|
|
# include <varargs.h>
|
|
|
|
#endif
|
|
|
|
|
1998-09-30 07:11:02 -04:00
|
|
|
#ifdef BUILD_tcl
|
|
|
|
# undef TCL_STORAGE_CLASS
|
|
|
|
# define TCL_STORAGE_CLASS DLLEXPORT
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The following procedures allow namespaces to be customized to
|
|
|
|
* support special name resolution rules for commands/variables.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct Tcl_ResolvedVarInfo;
|
|
|
|
|
|
|
|
typedef Tcl_Var (Tcl_ResolveRuntimeVarProc) _ANSI_ARGS_((
|
|
|
|
Tcl_Interp* interp, struct Tcl_ResolvedVarInfo *vinfoPtr));
|
|
|
|
|
|
|
|
typedef void (Tcl_ResolveVarDeleteProc) _ANSI_ARGS_((
|
|
|
|
struct Tcl_ResolvedVarInfo *vinfoPtr));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The following structure encapsulates the routines needed to resolve a
|
|
|
|
* variable reference at runtime. Any variable specific state will typically
|
|
|
|
* be appended to this structure.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct Tcl_ResolvedVarInfo {
|
|
|
|
Tcl_ResolveRuntimeVarProc *fetchProc;
|
|
|
|
Tcl_ResolveVarDeleteProc *deleteProc;
|
|
|
|
} Tcl_ResolvedVarInfo;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef int (Tcl_ResolveCompiledVarProc) _ANSI_ARGS_((
|
|
|
|
Tcl_Interp* interp, char* name, int length,
|
|
|
|
Tcl_Namespace *context, Tcl_ResolvedVarInfo **rPtr));
|
|
|
|
|
|
|
|
typedef int (Tcl_ResolveVarProc) _ANSI_ARGS_((
|
|
|
|
Tcl_Interp* interp, char* name, Tcl_Namespace *context,
|
|
|
|
int flags, Tcl_Var *rPtr));
|
|
|
|
|
|
|
|
typedef int (Tcl_ResolveCmdProc) _ANSI_ARGS_((Tcl_Interp* interp,
|
|
|
|
char* name, Tcl_Namespace *context, int flags,
|
|
|
|
Tcl_Command *rPtr));
|
|
|
|
|
|
|
|
typedef struct Tcl_ResolverInfo {
|
|
|
|
Tcl_ResolveCmdProc *cmdResProc; /* Procedure handling command name
|
|
|
|
* resolution. */
|
|
|
|
Tcl_ResolveVarProc *varResProc; /* Procedure handling variable name
|
|
|
|
* resolution for variables that
|
|
|
|
* can only be handled at runtime. */
|
|
|
|
Tcl_ResolveCompiledVarProc *compiledVarResProc;
|
|
|
|
/* Procedure handling variable name
|
|
|
|
* resolution at compile time. */
|
|
|
|
} Tcl_ResolverInfo;
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
* Data structures related to namespaces.
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The structure below defines a namespace.
|
|
|
|
* Note: the first five fields must match exactly the fields in a
|
|
|
|
* Tcl_Namespace structure (see tcl.h). If you change one, be sure to
|
|
|
|
* change the other.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct Namespace {
|
|
|
|
char *name; /* The namespace's simple (unqualified)
|
|
|
|
* name. This contains no ::'s. The name of
|
|
|
|
* the global namespace is "" although "::"
|
|
|
|
* is an synonym. */
|
|
|
|
char *fullName; /* The namespace's fully qualified name.
|
|
|
|
* This starts with ::. */
|
|
|
|
ClientData clientData; /* An arbitrary value associated with this
|
|
|
|
* namespace. */
|
|
|
|
Tcl_NamespaceDeleteProc *deleteProc;
|
|
|
|
/* Procedure invoked when deleting the
|
|
|
|
* namespace to, e.g., free clientData. */
|
|
|
|
struct Namespace *parentPtr; /* Points to the namespace that contains
|
|
|
|
* this one. NULL if this is the global
|
|
|
|
* namespace. */
|
|
|
|
Tcl_HashTable childTable; /* Contains any child namespaces. Indexed
|
|
|
|
* by strings; values have type
|
|
|
|
* (Namespace *). */
|
|
|
|
long nsId; /* Unique id for the namespace. */
|
|
|
|
Tcl_Interp *interp; /* The interpreter containing this
|
|
|
|
* namespace. */
|
|
|
|
int flags; /* OR-ed combination of the namespace
|
|
|
|
* status flags NS_DYING and NS_DEAD
|
|
|
|
* listed below. */
|
|
|
|
int activationCount; /* Number of "activations" or active call
|
|
|
|
* frames for this namespace that are on
|
|
|
|
* the Tcl call stack. The namespace won't
|
|
|
|
* be freed until activationCount becomes
|
|
|
|
* zero. */
|
|
|
|
int refCount; /* Count of references by namespaceName *
|
|
|
|
* objects. The namespace can't be freed
|
|
|
|
* until refCount becomes zero. */
|
|
|
|
Tcl_HashTable cmdTable; /* Contains all the commands currently
|
|
|
|
* registered in the namespace. Indexed by
|
|
|
|
* strings; values have type (Command *).
|
|
|
|
* Commands imported by Tcl_Import have
|
|
|
|
* Command structures that point (via an
|
|
|
|
* ImportedCmdRef structure) to the
|
|
|
|
* Command structure in the source
|
|
|
|
* namespace's command table. */
|
|
|
|
Tcl_HashTable varTable; /* Contains all the (global) variables
|
|
|
|
* currently in this namespace. Indexed
|
|
|
|
* by strings; values have type (Var *). */
|
|
|
|
char **exportArrayPtr; /* Points to an array of string patterns
|
|
|
|
* specifying which commands are exported.
|
|
|
|
* A pattern may include "string match"
|
|
|
|
* style wildcard characters to specify
|
|
|
|
* multiple commands; however, no namespace
|
|
|
|
* qualifiers are allowed. NULL if no
|
|
|
|
* export patterns are registered. */
|
|
|
|
int numExportPatterns; /* Number of export patterns currently
|
|
|
|
* registered using "namespace export". */
|
|
|
|
int maxExportPatterns; /* Mumber of export patterns for which
|
|
|
|
* space is currently allocated. */
|
|
|
|
int cmdRefEpoch; /* Incremented if a newly added command
|
|
|
|
* shadows a command for which this
|
|
|
|
* namespace has already cached a Command *
|
|
|
|
* pointer; this causes all its cached
|
|
|
|
* Command* pointers to be invalidated. */
|
1998-09-30 07:11:02 -04:00
|
|
|
int resolverEpoch; /* Incremented whenever the name resolution
|
|
|
|
* rules change for this namespace; this
|
|
|
|
* invalidates all byte codes compiled in
|
|
|
|
* the namespace, causing the code to be
|
|
|
|
* recompiled under the new rules. */
|
|
|
|
Tcl_ResolveCmdProc *cmdResProc;
|
|
|
|
/* If non-null, this procedure overrides
|
|
|
|
* the usual command resolution mechanism
|
|
|
|
* in Tcl. This procedure is invoked
|
|
|
|
* within Tcl_FindCommand to resolve all
|
|
|
|
* command references within the namespace. */
|
|
|
|
Tcl_ResolveVarProc *varResProc;
|
|
|
|
/* If non-null, this procedure overrides
|
|
|
|
* the usual variable resolution mechanism
|
|
|
|
* in Tcl. This procedure is invoked
|
|
|
|
* within Tcl_FindNamespaceVar to resolve all
|
|
|
|
* variable references within the namespace
|
|
|
|
* at runtime. */
|
|
|
|
Tcl_ResolveCompiledVarProc *compiledVarResProc;
|
|
|
|
/* If non-null, this procedure overrides
|
|
|
|
* the usual variable resolution mechanism
|
|
|
|
* in Tcl. This procedure is invoked
|
|
|
|
* within LookupCompiledLocal to resolve
|
|
|
|
* variable references within the namespace
|
|
|
|
* at compile time. */
|
1998-04-10 06:59:06 -04:00
|
|
|
} Namespace;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Flags used to represent the status of a namespace:
|
|
|
|
*
|
|
|
|
* NS_DYING - 1 means Tcl_DeleteNamespace has been called to delete the
|
|
|
|
* namespace but there are still active call frames on the Tcl
|
|
|
|
* stack that refer to the namespace. When the last call frame
|
|
|
|
* referring to it has been popped, it's variables and command
|
|
|
|
* will be destroyed and it will be marked "dead" (NS_DEAD).
|
|
|
|
* The namespace can no longer be looked up by name.
|
|
|
|
* NS_DEAD - 1 means Tcl_DeleteNamespace has been called to delete the
|
|
|
|
* namespace and no call frames still refer to it. Its
|
|
|
|
* variables and command have already been destroyed. This bit
|
|
|
|
* allows the namespace resolution code to recognize that the
|
|
|
|
* namespace is "deleted". When the last namespaceName object
|
|
|
|
* in any byte code code unit that refers to the namespace has
|
|
|
|
* been freed (i.e., when the namespace's refCount is 0), the
|
|
|
|
* namespace's storage will be freed.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define NS_DYING 0x01
|
|
|
|
#define NS_DEAD 0x02
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Flag passed to TclGetNamespaceForQualName to have it create all namespace
|
|
|
|
* components of a namespace-qualified name that cannot be found. The new
|
|
|
|
* namespaces are created within their specified parent. Note that this
|
|
|
|
* flag's value must not conflict with the values of the flags
|
|
|
|
* TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, and FIND_ONLY_NS (defined in
|
|
|
|
* tclNamesp.c).
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define CREATE_NS_IF_UNKNOWN 0x800
|
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
* Data structures related to variables. These are used primarily
|
|
|
|
* in tclVar.c
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The following structure defines a variable trace, which is used to
|
|
|
|
* invoke a specific C procedure whenever certain operations are performed
|
|
|
|
* on a variable.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct VarTrace {
|
|
|
|
Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given
|
|
|
|
* by flags are performed on variable. */
|
|
|
|
ClientData clientData; /* Argument to pass to proc. */
|
|
|
|
int flags; /* What events the trace procedure is
|
|
|
|
* interested in: OR-ed combination of
|
|
|
|
* TCL_TRACE_READS, TCL_TRACE_WRITES, and
|
|
|
|
* TCL_TRACE_UNSETS. */
|
|
|
|
struct VarTrace *nextPtr; /* Next in list of traces associated with
|
|
|
|
* a particular variable. */
|
|
|
|
} VarTrace;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When a variable trace is active (i.e. its associated procedure is
|
|
|
|
* executing), one of the following structures is linked into a list
|
|
|
|
* associated with the variable's interpreter. The information in
|
|
|
|
* the structure is needed in order for Tcl to behave reasonably
|
|
|
|
* if traces are deleted while traces are active.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct ActiveVarTrace {
|
|
|
|
struct Var *varPtr; /* Variable that's being traced. */
|
|
|
|
struct ActiveVarTrace *nextPtr;
|
|
|
|
/* Next in list of all active variable
|
|
|
|
* traces for the interpreter, or NULL
|
|
|
|
* if no more. */
|
|
|
|
VarTrace *nextTracePtr; /* Next trace to check after current
|
|
|
|
* trace procedure returns; if this
|
|
|
|
* trace gets deleted, must update pointer
|
|
|
|
* to avoid using free'd memory. */
|
|
|
|
} ActiveVarTrace;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The following structure describes an enumerative search in progress on
|
|
|
|
* an array variable; this are invoked with options to the "array"
|
|
|
|
* command.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct ArraySearch {
|
|
|
|
int id; /* Integer id used to distinguish among
|
|
|
|
* multiple concurrent searches for the
|
|
|
|
* same array. */
|
|
|
|
struct Var *varPtr; /* Pointer to array variable that's being
|
|
|
|
* searched. */
|
|
|
|
Tcl_HashSearch search; /* Info kept by the hash module about
|
|
|
|
* progress through the array. */
|
|
|
|
Tcl_HashEntry *nextEntry; /* Non-null means this is the next element
|
1998-04-10 06:59:06 -04:00
|
|
|
* to be enumerated (it's leftover from
|
1996-09-27 06:29:02 -04:00
|
|
|
* the Tcl_FirstHashEntry call or from
|
|
|
|
* an "array anymore" command). NULL
|
|
|
|
* means must call Tcl_NextHashEntry
|
|
|
|
* to get value to return. */
|
|
|
|
struct ArraySearch *nextPtr;/* Next in list of all active searches
|
|
|
|
* for this variable, or NULL if this is
|
|
|
|
* the last one. */
|
|
|
|
} ArraySearch;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The structure below defines a variable, which associates a string name
|
1998-04-10 06:59:06 -04:00
|
|
|
* with a Tcl_Obj value. These structures are kept in procedure call frames
|
|
|
|
* (for local variables recognized by the compiler) or in the heap (for
|
|
|
|
* global variables and any variable not known to the compiler). For each
|
|
|
|
* Var structure in the heap, a hash table entry holds the variable name and
|
|
|
|
* a pointer to the Var structure.
|
1996-09-27 06:29:02 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct Var {
|
|
|
|
union {
|
1998-04-10 06:59:06 -04:00
|
|
|
Tcl_Obj *objPtr; /* The variable's object value. Used for
|
|
|
|
* scalar variables and array elements. */
|
1996-09-27 06:29:02 -04:00
|
|
|
Tcl_HashTable *tablePtr;/* For array variables, this points to
|
|
|
|
* information about the hash table used
|
|
|
|
* to implement the associative array.
|
|
|
|
* Points to malloc-ed data. */
|
1998-04-10 06:59:06 -04:00
|
|
|
struct Var *linkPtr; /* If this is a global variable being
|
1996-09-27 06:29:02 -04:00
|
|
|
* referred to in a procedure, or a variable
|
|
|
|
* created by "upvar", this field points to
|
1998-04-10 06:59:06 -04:00
|
|
|
* the referenced variable's Var struct. */
|
1996-09-27 06:29:02 -04:00
|
|
|
} value;
|
1998-04-10 06:59:06 -04:00
|
|
|
char *name; /* NULL if the variable is in a hashtable,
|
|
|
|
* otherwise points to the variable's
|
|
|
|
* name. It is used, e.g., by TclLookupVar
|
|
|
|
* and "info locals". The storage for the
|
|
|
|
* characters of the name is not owned by
|
|
|
|
* the Var and must not be freed when
|
|
|
|
* freeing the Var. */
|
|
|
|
Namespace *nsPtr; /* Points to the namespace that contains
|
|
|
|
* this variable or NULL if the variable is
|
|
|
|
* a local variable in a Tcl procedure. */
|
|
|
|
Tcl_HashEntry *hPtr; /* If variable is in a hashtable, either the
|
|
|
|
* hash table entry that refers to this
|
|
|
|
* variable or NULL if the variable has been
|
|
|
|
* detached from its hash table (e.g. an
|
|
|
|
* array is deleted, but some of its
|
|
|
|
* elements are still referred to in
|
|
|
|
* upvars). NULL if the variable is not in a
|
|
|
|
* hashtable. This is used to delete an
|
|
|
|
* variable from its hashtable if it is no
|
|
|
|
* longer needed. */
|
1996-09-27 06:29:02 -04:00
|
|
|
int refCount; /* Counts number of active uses of this
|
1998-04-10 06:59:06 -04:00
|
|
|
* variable, not including its entry in the
|
|
|
|
* call frame or the hash table: 1 for each
|
|
|
|
* additional variable whose linkPtr points
|
|
|
|
* here, 1 for each nested trace active on
|
|
|
|
* variable, and 1 if the variable is a
|
|
|
|
* namespace variable. This record can't be
|
|
|
|
* deleted until refCount becomes 0. */
|
1996-09-27 06:29:02 -04:00
|
|
|
VarTrace *tracePtr; /* First in list of all traces set for this
|
|
|
|
* variable. */
|
|
|
|
ArraySearch *searchPtr; /* First in list of all searches active
|
|
|
|
* for this variable, or NULL if none. */
|
|
|
|
int flags; /* Miscellaneous bits of information about
|
1998-04-10 06:59:06 -04:00
|
|
|
* variable. See below for definitions. */
|
1996-09-27 06:29:02 -04:00
|
|
|
} Var;
|
|
|
|
|
|
|
|
/*
|
1998-04-10 06:59:06 -04:00
|
|
|
* Flag bits for variables. The first three (VAR_SCALAR, VAR_ARRAY, and
|
|
|
|
* VAR_LINK) are mutually exclusive and give the "type" of the variable.
|
|
|
|
* VAR_UNDEFINED is independent of the variable's type.
|
1996-09-27 06:29:02 -04:00
|
|
|
*
|
1998-04-10 06:59:06 -04:00
|
|
|
* VAR_SCALAR - 1 means this is a scalar variable and not
|
|
|
|
* an array or link. The "objPtr" field points
|
|
|
|
* to the variable's value, a Tcl object.
|
|
|
|
* VAR_ARRAY - 1 means this is an array variable rather
|
|
|
|
* than a scalar variable or link. The
|
|
|
|
* "tablePtr" field points to the array's
|
|
|
|
* hashtable for its elements.
|
|
|
|
* VAR_LINK - 1 means this Var structure contains a
|
|
|
|
* pointer to another Var structure that
|
|
|
|
* either has the real value or is itself
|
|
|
|
* another VAR_LINK pointer. Variables like
|
|
|
|
* this come about through "upvar" and "global"
|
|
|
|
* commands, or through references to variables
|
|
|
|
* in enclosing namespaces.
|
|
|
|
* VAR_UNDEFINED - 1 means that the variable is in the process
|
|
|
|
* of being deleted. An undefined variable
|
|
|
|
* logically does not exist and survives only
|
|
|
|
* while it has a trace, or if it is a global
|
|
|
|
* variable currently being used by some
|
|
|
|
* procedure.
|
|
|
|
* VAR_IN_HASHTABLE - 1 means this variable is in a hashtable and
|
|
|
|
* the Var structure is malloced. 0 if it is
|
|
|
|
* a local variable that was assigned a slot
|
|
|
|
* in a procedure frame by the compiler so the
|
|
|
|
* Var storage is part of the call frame.
|
1996-09-27 06:29:02 -04:00
|
|
|
* VAR_TRACE_ACTIVE - 1 means that trace processing is currently
|
|
|
|
* underway for a read or write access, so
|
|
|
|
* new read or write accesses should not cause
|
|
|
|
* trace procedures to be called and the
|
|
|
|
* variable can't be deleted.
|
1998-04-10 06:59:06 -04:00
|
|
|
* VAR_ARRAY_ELEMENT - 1 means that this variable is an array
|
|
|
|
* element, so it is not legal for it to be
|
|
|
|
* an array itself (the VAR_ARRAY flag had
|
|
|
|
* better not be set).
|
|
|
|
* VAR_NAMESPACE_VAR - 1 means that this variable was declared
|
|
|
|
* as a namespace variable. This flag ensures
|
|
|
|
* it persists until its namespace is
|
|
|
|
* destroyed or until the variable is unset;
|
|
|
|
* it will persist even if it has not been
|
|
|
|
* initialized and is marked undefined.
|
|
|
|
* The variable's refCount is incremented to
|
|
|
|
* reflect the "reference" from its namespace.
|
1998-09-30 07:11:02 -04:00
|
|
|
*
|
|
|
|
* The following additional flags are used with the CompiledLocal type
|
|
|
|
* defined below:
|
|
|
|
*
|
|
|
|
* VAR_ARGUMENT - 1 means that this variable holds a procedure
|
|
|
|
* argument.
|
|
|
|
* VAR_TEMPORARY - 1 if the local variable is an anonymous
|
|
|
|
* temporary variable. Temporaries have a NULL
|
|
|
|
* name.
|
|
|
|
* VAR_RESOLVED - 1 if name resolution has been done for this
|
|
|
|
* variable.
|
1996-09-27 06:29:02 -04:00
|
|
|
*/
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
#define VAR_SCALAR 0x1
|
|
|
|
#define VAR_ARRAY 0x2
|
|
|
|
#define VAR_LINK 0x4
|
|
|
|
#define VAR_UNDEFINED 0x8
|
|
|
|
#define VAR_IN_HASHTABLE 0x10
|
|
|
|
#define VAR_TRACE_ACTIVE 0x20
|
|
|
|
#define VAR_ARRAY_ELEMENT 0x40
|
|
|
|
#define VAR_NAMESPACE_VAR 0x80
|
|
|
|
|
1998-09-30 07:11:02 -04:00
|
|
|
#define VAR_ARGUMENT 0x100
|
|
|
|
#define VAR_TEMPORARY 0x200
|
|
|
|
#define VAR_RESOLVED 0x400
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
/*
|
|
|
|
* Macros to ensure that various flag bits are set properly for variables.
|
|
|
|
* The ANSI C "prototypes" for these macros are:
|
|
|
|
*
|
|
|
|
* EXTERN void TclSetVarScalar _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN void TclSetVarArray _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN void TclSetVarLink _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN void TclSetVarArrayElement _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN void TclSetVarUndefined _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN void TclClearVarUndefined _ANSI_ARGS_((Var *varPtr));
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define TclSetVarScalar(varPtr) \
|
|
|
|
(varPtr)->flags = ((varPtr)->flags & ~(VAR_ARRAY|VAR_LINK)) | VAR_SCALAR
|
|
|
|
|
|
|
|
#define TclSetVarArray(varPtr) \
|
|
|
|
(varPtr)->flags = ((varPtr)->flags & ~(VAR_SCALAR|VAR_LINK)) | VAR_ARRAY
|
|
|
|
|
|
|
|
#define TclSetVarLink(varPtr) \
|
|
|
|
(varPtr)->flags = ((varPtr)->flags & ~(VAR_SCALAR|VAR_ARRAY)) | VAR_LINK
|
|
|
|
|
|
|
|
#define TclSetVarArrayElement(varPtr) \
|
|
|
|
(varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_ARRAY_ELEMENT
|
|
|
|
|
|
|
|
#define TclSetVarUndefined(varPtr) \
|
|
|
|
(varPtr)->flags |= VAR_UNDEFINED
|
|
|
|
|
|
|
|
#define TclClearVarUndefined(varPtr) \
|
|
|
|
(varPtr)->flags &= ~VAR_UNDEFINED
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Macros to read various flag bits of variables.
|
|
|
|
* The ANSI C "prototypes" for these macros are:
|
|
|
|
*
|
|
|
|
* EXTERN int TclIsVarScalar _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN int TclIsVarLink _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN int TclIsVarArray _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN int TclIsVarUndefined _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN int TclIsVarArrayElement _ANSI_ARGS_((Var *varPtr));
|
1998-09-30 07:11:02 -04:00
|
|
|
* EXTERN int TclIsVarTemporary _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN int TclIsVarArgument _ANSI_ARGS_((Var *varPtr));
|
|
|
|
* EXTERN int TclIsVarResolved _ANSI_ARGS_((Var *varPtr));
|
1998-04-10 06:59:06 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#define TclIsVarScalar(varPtr) \
|
|
|
|
((varPtr)->flags & VAR_SCALAR)
|
|
|
|
|
|
|
|
#define TclIsVarLink(varPtr) \
|
|
|
|
((varPtr)->flags & VAR_LINK)
|
|
|
|
|
|
|
|
#define TclIsVarArray(varPtr) \
|
|
|
|
((varPtr)->flags & VAR_ARRAY)
|
|
|
|
|
|
|
|
#define TclIsVarUndefined(varPtr) \
|
|
|
|
((varPtr)->flags & VAR_UNDEFINED)
|
|
|
|
|
|
|
|
#define TclIsVarArrayElement(varPtr) \
|
|
|
|
((varPtr)->flags & VAR_ARRAY_ELEMENT)
|
1996-09-27 06:29:02 -04:00
|
|
|
|
1998-09-30 07:11:02 -04:00
|
|
|
#define TclIsVarTemporary(varPtr) \
|
|
|
|
((varPtr)->flags & VAR_TEMPORARY)
|
|
|
|
|
|
|
|
#define TclIsVarArgument(varPtr) \
|
|
|
|
((varPtr)->flags & VAR_ARGUMENT)
|
|
|
|
|
|
|
|
#define TclIsVarResolved(varPtr) \
|
|
|
|
((varPtr)->flags & VAR_RESOLVED)
|
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
1998-04-10 06:59:06 -04:00
|
|
|
* Data structures related to procedures. These are used primarily
|
|
|
|
* in tclProc.c, tclCompile.c, and tclExecute.c.
|
1996-09-27 06:29:02 -04:00
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
1998-04-10 06:59:06 -04:00
|
|
|
* Forward declaration to prevent an error when the forward reference to
|
|
|
|
* Command is encountered in the Proc and ImportRef types declared below.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct Command;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The variable-length structure below describes a local variable of a
|
|
|
|
* procedure that was recognized by the compiler. These variables have a
|
|
|
|
* name, an element in the array of compiler-assigned local variables in the
|
|
|
|
* procedure's call frame, and various other items of information. If the
|
|
|
|
* local variable is a formal argument, it may also have a default value.
|
|
|
|
* The compiler can't recognize local variables whose names are
|
|
|
|
* expressions (these names are only known at runtime when the expressions
|
|
|
|
* are evaluated) or local variables that are created as a result of an
|
|
|
|
* "upvar" or "uplevel" command. These other local variables are kept
|
|
|
|
* separately in a hash table in the call frame.
|
1996-09-27 06:29:02 -04:00
|
|
|
*/
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
typedef struct CompiledLocal {
|
|
|
|
struct CompiledLocal *nextPtr;
|
|
|
|
/* Next compiler-recognized local variable
|
|
|
|
* for this procedure, or NULL if this is
|
|
|
|
* the last local. */
|
|
|
|
int nameLength; /* The number of characters in local
|
|
|
|
* variable's name. Used to speed up
|
|
|
|
* variable lookups. */
|
|
|
|
int frameIndex; /* Index in the array of compiler-assigned
|
|
|
|
* variables in the procedure call frame. */
|
|
|
|
int flags; /* Flag bits for the local variable. Same as
|
|
|
|
* the flags for the Var structure above,
|
1998-09-30 07:11:02 -04:00
|
|
|
* although only VAR_SCALAR, VAR_ARRAY,
|
|
|
|
* VAR_LINK, VAR_ARGUMENT, VAR_TEMPORARY, and
|
|
|
|
* VAR_RESOLVED make sense. */
|
1998-04-10 06:59:06 -04:00
|
|
|
Tcl_Obj *defValuePtr; /* Pointer to the default value of an
|
|
|
|
* argument, if any. NULL if not an argument
|
|
|
|
* or, if an argument, no default value. */
|
1998-09-30 07:11:02 -04:00
|
|
|
Tcl_ResolvedVarInfo *resolveInfo;
|
|
|
|
/* Customized variable resolution info
|
|
|
|
* supplied by the Tcl_ResolveCompiledVarProc
|
|
|
|
* associated with a namespace. Each variable
|
|
|
|
* is marked by a unique ClientData tag
|
|
|
|
* during compilation, and that same tag
|
|
|
|
* is used to find the variable at runtime. */
|
1998-04-10 06:59:06 -04:00
|
|
|
char name[4]; /* Name of the local variable starts here.
|
|
|
|
* If the name is NULL, this will just be
|
|
|
|
* '\0'. The actual size of this field will
|
|
|
|
* be large enough to hold the name. MUST
|
|
|
|
* BE THE LAST FIELD IN THE STRUCTURE! */
|
|
|
|
} CompiledLocal;
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
|
|
/*
|
1998-04-10 06:59:06 -04:00
|
|
|
* The structure below defines a command procedure, which consists of a
|
|
|
|
* collection of Tcl commands plus information about arguments and other
|
|
|
|
* local variables recognized at compile time.
|
1996-09-27 06:29:02 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct Proc {
|
1998-04-10 06:59:06 -04:00
|
|
|
struct Interp *iPtr; /* Interpreter for which this command
|
|
|
|
* is defined. */
|
|
|
|
int refCount; /* Reference count: 1 if still present
|
|
|
|
* in command table plus 1 for each call
|
|
|
|
* to the procedure that is currently
|
|
|
|
* active. This structure can be freed
|
|
|
|
* when refCount becomes zero. */
|
|
|
|
struct Command *cmdPtr; /* Points to the Command structure for
|
|
|
|
* this procedure. This is used to get
|
|
|
|
* the namespace in which to execute
|
|
|
|
* the procedure. */
|
|
|
|
Tcl_Obj *bodyPtr; /* Points to the ByteCode object for
|
|
|
|
* procedure's body command. */
|
|
|
|
int numArgs; /* Number of formal parameters. */
|
|
|
|
int numCompiledLocals; /* Count of local variables recognized by
|
|
|
|
* the compiler including arguments and
|
|
|
|
* temporaries. */
|
|
|
|
CompiledLocal *firstLocalPtr; /* Pointer to first of the procedure's
|
|
|
|
* compiler-allocated local variables, or
|
|
|
|
* NULL if none. The first numArgs entries
|
|
|
|
* in this list describe the procedure's
|
|
|
|
* formal arguments. */
|
|
|
|
CompiledLocal *lastLocalPtr; /* Pointer to the last allocated local
|
|
|
|
* variable or NULL if none. This has
|
|
|
|
* frame index (numCompiledLocals-1). */
|
1996-09-27 06:29:02 -04:00
|
|
|
} Proc;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The structure below defines a command trace. This is used to allow Tcl
|
|
|
|
* clients to find out whenever a command is about to be executed.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct Trace {
|
|
|
|
int level; /* Only trace commands at nesting level
|
|
|
|
* less than or equal to this. */
|
|
|
|
Tcl_CmdTraceProc *proc; /* Procedure to call to trace command. */
|
|
|
|
ClientData clientData; /* Arbitrary value to pass to proc. */
|
|
|
|
struct Trace *nextPtr; /* Next in list of traces for this interp. */
|
|
|
|
} Trace;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The structure below defines an entry in the assocData hash table which
|
|
|
|
* is associated with an interpreter. The entry contains a pointer to a
|
|
|
|
* function to call when the interpreter is deleted, and a pointer to
|
|
|
|
* a user-defined piece of data.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct AssocData {
|
|
|
|
Tcl_InterpDeleteProc *proc; /* Proc to call when deleting. */
|
|
|
|
ClientData clientData; /* Value to pass to proc. */
|
|
|
|
} AssocData;
|
|
|
|
|
|
|
|
/*
|
1998-04-10 06:59:06 -04:00
|
|
|
* The structure below defines a call frame. A call frame defines a naming
|
|
|
|
* context for a procedure call: its local naming scope (for local
|
|
|
|
* variables) and its global naming scope (a namespace, perhaps the global
|
|
|
|
* :: namespace). A call frame can also define the naming context for a
|
|
|
|
* namespace eval or namespace inscope command: the namespace in which the
|
|
|
|
* command's code should execute. The Tcl_CallFrame structures exist only
|
|
|
|
* while procedures or namespace eval/inscope's are being executed, and
|
|
|
|
* provide a kind of Tcl call stack.
|
|
|
|
*
|
|
|
|
* WARNING!! The structure definition must be kept consistent with the
|
|
|
|
* Tcl_CallFrame structure in tcl.h. If you change one, change the other.
|
1996-09-27 06:29:02 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct CallFrame {
|
1998-04-10 06:59:06 -04:00
|
|
|
Namespace *nsPtr; /* Points to the namespace used to resolve
|
|
|
|
* commands and global variables. */
|
|
|
|
int isProcCallFrame; /* If nonzero, the frame was pushed to
|
|
|
|
* execute a Tcl procedure and may have
|
|
|
|
* local vars. If 0, the frame was pushed
|
|
|
|
* to execute a namespace command and var
|
|
|
|
* references are treated as references to
|
|
|
|
* namespace vars; varTablePtr and
|
|
|
|
* compiledLocals are ignored. */
|
|
|
|
int objc; /* This and objv below describe the
|
|
|
|
* arguments for this procedure call. */
|
|
|
|
Tcl_Obj *CONST *objv; /* Array of argument objects. */
|
1996-09-27 06:29:02 -04:00
|
|
|
struct CallFrame *callerPtr;
|
|
|
|
/* Value of interp->framePtr when this
|
1998-04-10 06:59:06 -04:00
|
|
|
* procedure was invoked (i.e. next higher
|
|
|
|
* in stack of all active procedures). */
|
1996-09-27 06:29:02 -04:00
|
|
|
struct CallFrame *callerVarPtr;
|
|
|
|
/* Value of interp->varFramePtr when this
|
|
|
|
* procedure was invoked (i.e. determines
|
1998-04-10 06:59:06 -04:00
|
|
|
* variable scoping within caller). Same
|
1996-09-27 06:29:02 -04:00
|
|
|
* as callerPtr unless an "uplevel" command
|
|
|
|
* or something equivalent was active in
|
|
|
|
* the caller). */
|
1998-04-10 06:59:06 -04:00
|
|
|
int level; /* Level of this procedure, for "uplevel"
|
|
|
|
* purposes (i.e. corresponds to nesting of
|
|
|
|
* callerVarPtr's, not callerPtr's). 1 for
|
|
|
|
* outermost procedure, 0 for top-level. */
|
|
|
|
Proc *procPtr; /* Points to the structure defining the
|
|
|
|
* called procedure. Used to get information
|
|
|
|
* such as the number of compiled local
|
|
|
|
* variables (local variables assigned
|
|
|
|
* entries ["slots"] in the compiledLocals
|
|
|
|
* array below). */
|
|
|
|
Tcl_HashTable *varTablePtr; /* Hash table containing local variables not
|
|
|
|
* recognized by the compiler, or created at
|
|
|
|
* execution time through, e.g., upvar.
|
|
|
|
* Initially NULL and created if needed. */
|
|
|
|
int numCompiledLocals; /* Count of local variables recognized by
|
|
|
|
* the compiler including arguments. */
|
|
|
|
Var* compiledLocals; /* Points to the array of local variables
|
|
|
|
* recognized by the compiler. The compiler
|
|
|
|
* emits code that refers to these variables
|
|
|
|
* using an index into this array. */
|
1996-09-27 06:29:02 -04:00
|
|
|
} CallFrame;
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
* Data structures related to history. These are used primarily
|
|
|
|
* in tclHistory.c
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
/*
|
|
|
|
* The structure below defines one history event (a previously-executed
|
|
|
|
* command that can be re-executed in whole or in part).
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char *command; /* String containing previously-executed
|
|
|
|
* command. */
|
|
|
|
int bytesAvl; /* Total # of bytes available at *event (not
|
|
|
|
* all are necessarily in use now). */
|
|
|
|
} HistoryEvent;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The structure below defines a pending revision to the most recent
|
|
|
|
* history event. Changes are linked together into a list and applied
|
|
|
|
* during the next call to Tcl_RecordHistory. See the comments at the
|
|
|
|
* beginning of tclHistory.c for information on revisions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct HistoryRev {
|
|
|
|
int firstIndex; /* Index of the first byte to replace in
|
|
|
|
* current history event. */
|
|
|
|
int lastIndex; /* Index of last byte to replace in
|
|
|
|
* current history event. */
|
|
|
|
int newSize; /* Number of bytes in newBytes. */
|
|
|
|
char *newBytes; /* Replacement for the range given by
|
|
|
|
* firstIndex and lastIndex (malloced). */
|
|
|
|
struct HistoryRev *nextPtr; /* Next in chain of revisions to apply, or
|
|
|
|
* NULL for end of list. */
|
|
|
|
} HistoryRev;
|
|
|
|
|
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
* Data structures related to expressions. These are used only in
|
|
|
|
* tclExpr.c.
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The data structure below defines a math function (e.g. sin or hypot)
|
|
|
|
* for use in Tcl expressions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define MAX_MATH_ARGS 5
|
|
|
|
typedef struct MathFunc {
|
1998-04-10 06:59:06 -04:00
|
|
|
int builtinFuncIndex; /* If this is a builtin math function, its
|
|
|
|
* index in the array of builtin functions.
|
|
|
|
* (tclCompilation.h lists these indices.)
|
|
|
|
* The value is -1 if this is a new function
|
|
|
|
* defined by Tcl_CreateMathFunc. The value
|
|
|
|
* is also -1 if a builtin function is
|
|
|
|
* replaced by a Tcl_CreateMathFunc call. */
|
1996-09-27 06:29:02 -04:00
|
|
|
int numArgs; /* Number of arguments for function. */
|
|
|
|
Tcl_ValueType argTypes[MAX_MATH_ARGS];
|
|
|
|
/* Acceptable types for each argument. */
|
1998-04-10 06:59:06 -04:00
|
|
|
Tcl_MathProc *proc; /* Procedure that implements this function.
|
|
|
|
* NULL if isBuiltinFunc is 1. */
|
|
|
|
ClientData clientData; /* Additional argument to pass to the
|
|
|
|
* function when invoking it. NULL if
|
|
|
|
* isBuiltinFunc is 1. */
|
1996-09-27 06:29:02 -04:00
|
|
|
} MathFunc;
|
|
|
|
|
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
1998-04-10 06:59:06 -04:00
|
|
|
* Data structures related to bytecode compilation and execution.
|
|
|
|
* These are used primarily in tclCompile.c, tclExecute.c, and
|
|
|
|
* tclBasic.c.
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Forward declaration to prevent an error when the forward reference to
|
|
|
|
* CompileEnv is encountered in the procedure type CompileProc declared
|
|
|
|
* below.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct CompileEnv;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The type of procedures called by the Tcl bytecode compiler to compile
|
|
|
|
* commands. Pointers to these procedures are kept in the Command structure
|
|
|
|
* describing each command. When a CompileProc returns, the interpreter's
|
|
|
|
* result is set to error information, if any. In addition, the CompileProc
|
|
|
|
* returns an integer value, which is one of the following:
|
|
|
|
*
|
|
|
|
* TCL_OK Compilation completed normally.
|
|
|
|
* TCL_ERROR Compilation failed because of an error;
|
|
|
|
* the interpreter's result describes what went wrong.
|
|
|
|
* TCL_OUT_LINE_COMPILE Compilation failed because, e.g., the command is
|
|
|
|
* too complex for effective inline compilation. The
|
|
|
|
* CompileProc believes the command is legal but
|
|
|
|
* should be compiled "out of line" by emitting code
|
|
|
|
* to invoke its command procedure at runtime.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define TCL_OUT_LINE_COMPILE (TCL_CONTINUE + 1)
|
|
|
|
|
|
|
|
typedef int (CompileProc) _ANSI_ARGS_((Tcl_Interp *interp, char *string,
|
|
|
|
char *lastChar, int compileFlags, struct CompileEnv *compEnvPtr));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The data structure defining the execution environment for ByteCode's.
|
|
|
|
* There is one ExecEnv structure per Tcl interpreter. It holds the
|
|
|
|
* evaluation stack that holds command operands and results. The stack grows
|
|
|
|
* towards increasing addresses. The "stackTop" member is cached by
|
|
|
|
* TclExecuteByteCode in a local variable: it must be set before calling
|
|
|
|
* TclExecuteByteCode and will be restored by TclExecuteByteCode before it
|
|
|
|
* returns.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef union StackItem {
|
|
|
|
Tcl_Obj *o; /* Stack item as a pointer to a Tcl_Obj. */
|
|
|
|
int i; /* Stack item as an integer. */
|
|
|
|
VOID *p; /* Stack item as an arbitrary pointer. */
|
|
|
|
} StackItem;
|
|
|
|
|
|
|
|
typedef struct ExecEnv {
|
|
|
|
StackItem *stackPtr; /* Points to the first item in the
|
|
|
|
* evaluation stack on the heap. */
|
|
|
|
int stackTop; /* Index of current top of stack; -1 when
|
|
|
|
* the stack is empty. */
|
|
|
|
int stackEnd; /* Index of last usable item in stack. */
|
|
|
|
} ExecEnv;
|
|
|
|
|
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
* Data structures related to commands.
|
1996-09-27 06:29:02 -04:00
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
/*
|
|
|
|
* An imported command is created in an namespace when it imports a "real"
|
|
|
|
* command from another namespace. An imported command has a Command
|
|
|
|
* structure that points (via its ClientData value) to the "real" Command
|
|
|
|
* structure in the source namespace's command table. The real command
|
|
|
|
* records all the imported commands that refer to it in a list of ImportRef
|
|
|
|
* structures so that they can be deleted when the real command is deleted. */
|
|
|
|
|
|
|
|
typedef struct ImportRef {
|
|
|
|
struct Command *importedCmdPtr;
|
|
|
|
/* Points to the imported command created in
|
|
|
|
* an importing namespace; this command
|
|
|
|
* redirects its invocations to the "real"
|
|
|
|
* command. */
|
|
|
|
struct ImportRef *nextPtr; /* Next element on the linked list of
|
|
|
|
* imported commands that refer to the
|
|
|
|
* "real" command. The real command deletes
|
|
|
|
* these imported commands on this list when
|
|
|
|
* it is deleted. */
|
|
|
|
} ImportRef;
|
|
|
|
|
1998-09-30 07:11:02 -04:00
|
|
|
/*
|
|
|
|
* Data structure used as the ClientData of imported commands: commands
|
|
|
|
* created in an namespace when it imports a "real" command from another
|
|
|
|
* namespace.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct ImportedCmdData {
|
|
|
|
struct Command *realCmdPtr; /* "Real" command that this imported command
|
|
|
|
* refers to. */
|
|
|
|
struct Command *selfPtr; /* Pointer to this imported command. Needed
|
|
|
|
* only when deleting it in order to remove
|
|
|
|
* it from the real command's linked list of
|
|
|
|
* imported commands that refer to it. */
|
|
|
|
} ImportedCmdData;
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
/*
|
|
|
|
* A Command structure exists for each command in a namespace. The
|
|
|
|
* Tcl_Command opaque type actually refers to these structures.
|
|
|
|
*/
|
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
typedef struct Command {
|
1998-04-10 06:59:06 -04:00
|
|
|
Tcl_HashEntry *hPtr; /* Pointer to the hash table entry that
|
|
|
|
* refers to this command. The hash table is
|
|
|
|
* either a namespace's command table or an
|
|
|
|
* interpreter's hidden command table. This
|
|
|
|
* pointer is used to get a command's name
|
|
|
|
* from its Tcl_Command handle. NULL means
|
|
|
|
* that the hash table entry has been
|
|
|
|
* removed already (this can happen if
|
|
|
|
* deleteProc causes the command to be
|
1996-09-27 06:29:02 -04:00
|
|
|
* deleted or recreated). */
|
1998-04-10 06:59:06 -04:00
|
|
|
Namespace *nsPtr; /* Points to the namespace containing this
|
1996-09-27 06:29:02 -04:00
|
|
|
* command. */
|
1998-04-10 06:59:06 -04:00
|
|
|
int refCount; /* 1 if in command hashtable plus 1 for each
|
|
|
|
* reference from a CmdName Tcl object
|
|
|
|
* representing a command's name in a
|
|
|
|
* ByteCode instruction sequence. This
|
|
|
|
* structure can be freed when refCount
|
|
|
|
* becomes zero. */
|
|
|
|
int cmdEpoch; /* Incremented to invalidate any references
|
|
|
|
* that point to this command when it is
|
|
|
|
* renamed, deleted, hidden, or exposed. */
|
|
|
|
CompileProc *compileProc; /* Procedure called to compile command. NULL
|
|
|
|
* if no compile proc exists for command. */
|
|
|
|
Tcl_ObjCmdProc *objProc; /* Object-based command procedure. */
|
|
|
|
ClientData objClientData; /* Arbitrary value passed to object proc. */
|
|
|
|
Tcl_CmdProc *proc; /* String-based command procedure. */
|
|
|
|
ClientData clientData; /* Arbitrary value passed to string proc. */
|
|
|
|
Tcl_CmdDeleteProc *deleteProc;
|
|
|
|
/* Procedure invoked when deleting command
|
|
|
|
* to, e.g., free all client data. */
|
|
|
|
ClientData deleteData; /* Arbitrary value passed to deleteProc. */
|
1996-09-27 06:29:02 -04:00
|
|
|
int deleted; /* Means that the command is in the process
|
|
|
|
* of being deleted (its deleteProc is
|
1998-04-10 06:59:06 -04:00
|
|
|
* currently executing). Other attempts to
|
|
|
|
* delete the command should be ignored. */
|
|
|
|
ImportRef *importRefPtr; /* List of each imported Command created in
|
|
|
|
* another namespace when this command is
|
|
|
|
* imported. These imported commands
|
|
|
|
* redirect invocations back to this
|
|
|
|
* command. The list is used to remove all
|
|
|
|
* those imported commands when deleting
|
|
|
|
* this "real" command. */
|
1996-09-27 06:29:02 -04:00
|
|
|
} Command;
|
|
|
|
|
1998-09-30 07:11:02 -04:00
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
* Data structures related to name resolution procedures.
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The interpreter keeps a linked list of name resolution schemes.
|
|
|
|
* The scheme for a namespace is consulted first, followed by the
|
|
|
|
* list of schemes in an interpreter, followed by the default
|
|
|
|
* name resolution in Tcl. Schemes are added/removed from the
|
|
|
|
* interpreter's list by calling Tcl_AddInterpResolver and
|
|
|
|
* Tcl_RemoveInterpResolver.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct ResolverScheme {
|
|
|
|
char *name; /* Name identifying this scheme. */
|
|
|
|
Tcl_ResolveCmdProc *cmdResProc;
|
|
|
|
/* Procedure handling command name
|
|
|
|
* resolution. */
|
|
|
|
Tcl_ResolveVarProc *varResProc;
|
|
|
|
/* Procedure handling variable name
|
|
|
|
* resolution for variables that
|
|
|
|
* can only be handled at runtime. */
|
|
|
|
Tcl_ResolveCompiledVarProc *compiledVarResProc;
|
|
|
|
/* Procedure handling variable name
|
|
|
|
* resolution at compile time. */
|
|
|
|
|
|
|
|
struct ResolverScheme *nextPtr;
|
|
|
|
/* Pointer to next record in linked list. */
|
|
|
|
} ResolverScheme;
|
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
/*
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
* This structure defines an interpreter, which is a collection of
|
|
|
|
* commands plus other state information related to interpreting
|
1998-04-10 06:59:06 -04:00
|
|
|
* commands, such as variable storage. Primary responsibility for
|
1996-09-27 06:29:02 -04:00
|
|
|
* this data structure is in tclBasic.c, but almost every Tcl
|
|
|
|
* source file uses something in here.
|
|
|
|
*----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct Interp {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note: the first three fields must match exactly the fields in
|
|
|
|
* a Tcl_Interp struct (see tcl.h). If you change one, be sure to
|
|
|
|
* change the other.
|
1998-04-10 06:59:06 -04:00
|
|
|
*
|
|
|
|
* The interpreter's result is held in both the string and the
|
|
|
|
* objResultPtr fields. These fields hold, respectively, the result's
|
|
|
|
* string or object value. The interpreter's result is always in the
|
|
|
|
* result field if that is non-empty, otherwise it is in objResultPtr.
|
|
|
|
* The two fields are kept consistent unless some C code sets
|
|
|
|
* interp->result directly. Programs should not access result and
|
|
|
|
* objResultPtr directly; instead, they should always get and set the
|
|
|
|
* result using procedures such as Tcl_SetObjResult, Tcl_GetObjResult,
|
|
|
|
* and Tcl_GetStringResult. See the SetResult man page for details.
|
1996-09-27 06:29:02 -04:00
|
|
|
*/
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
char *result; /* If the last command returned a string
|
|
|
|
* result, this points to it. Should not be
|
|
|
|
* accessed directly; see comment above. */
|
|
|
|
Tcl_FreeProc *freeProc; /* Zero means a string result is statically
|
|
|
|
* allocated. TCL_DYNAMIC means string
|
|
|
|
* result was allocated with ckalloc and
|
|
|
|
* should be freed with ckfree. Other values
|
|
|
|
* give address of procedure to invoke to
|
|
|
|
* free the string result. Tcl_Eval must
|
|
|
|
* free it before executing next command. */
|
1996-09-27 06:29:02 -04:00
|
|
|
int errorLine; /* When TCL_ERROR is returned, this gives
|
1998-04-10 06:59:06 -04:00
|
|
|
* the line number in the command where the
|
|
|
|
* error occurred (1 means first line). */
|
|