jpayne@69: /* jpayne@69: * tclInt.h -- jpayne@69: * jpayne@69: * Declarations of things used internally by the Tcl interpreter. jpayne@69: * jpayne@69: * Copyright (c) 1987-1993 The Regents of the University of California. jpayne@69: * Copyright (c) 1993-1997 Lucent Technologies. jpayne@69: * Copyright (c) 1994-1998 Sun Microsystems, Inc. jpayne@69: * Copyright (c) 1998-1999 by Scriptics Corporation. jpayne@69: * Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved. jpayne@69: * Copyright (c) 2007 Daniel A. Steffen jpayne@69: * Copyright (c) 2006-2008 by Joe Mistachkin. All rights reserved. jpayne@69: * Copyright (c) 2008 by Miguel Sofer. All rights reserved. jpayne@69: * jpayne@69: * See the file "license.terms" for information on usage and redistribution of jpayne@69: * this file, and for a DISCLAIMER OF ALL WARRANTIES. jpayne@69: */ jpayne@69: jpayne@69: #ifndef _TCLINT jpayne@69: #define _TCLINT jpayne@69: jpayne@69: /* jpayne@69: * Some numerics configuration options. jpayne@69: */ jpayne@69: jpayne@69: #undef ACCEPT_NAN jpayne@69: jpayne@69: /* jpayne@69: * Common include files needed by most of the Tcl source files are included jpayne@69: * here, so that system-dependent personalizations for the include files only jpayne@69: * have to be made in once place. This results in a few extra includes, but jpayne@69: * greater modularity. The order of the three groups of #includes is jpayne@69: * important. For example, stdio.h is needed by tcl.h. jpayne@69: */ jpayne@69: jpayne@69: #include "tclPort.h" jpayne@69: jpayne@69: #include jpayne@69: jpayne@69: #include jpayne@69: #ifdef NO_STDLIB_H jpayne@69: # include "../compat/stdlib.h" jpayne@69: #else jpayne@69: # include jpayne@69: #endif jpayne@69: #ifdef NO_STRING_H jpayne@69: #include "../compat/string.h" jpayne@69: #else jpayne@69: #include jpayne@69: #endif jpayne@69: #if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \ jpayne@69: || defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC) jpayne@69: #include jpayne@69: #else jpayne@69: typedef int ptrdiff_t; jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * Ensure WORDS_BIGENDIAN is defined correctly: jpayne@69: * Needs to happen here in addition to configure to work with fat compiles on jpayne@69: * Darwin (where configure runs only once for multiple architectures). jpayne@69: */ jpayne@69: jpayne@69: #ifdef HAVE_SYS_TYPES_H jpayne@69: # include jpayne@69: #endif jpayne@69: #ifdef HAVE_SYS_PARAM_H jpayne@69: # include jpayne@69: #endif jpayne@69: #ifdef BYTE_ORDER jpayne@69: # ifdef BIG_ENDIAN jpayne@69: # if BYTE_ORDER == BIG_ENDIAN jpayne@69: # undef WORDS_BIGENDIAN jpayne@69: # define WORDS_BIGENDIAN 1 jpayne@69: # endif jpayne@69: # endif jpayne@69: # ifdef LITTLE_ENDIAN jpayne@69: # if BYTE_ORDER == LITTLE_ENDIAN jpayne@69: # undef WORDS_BIGENDIAN jpayne@69: # endif jpayne@69: # endif jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * Used to tag functions that are only to be visible within the module being jpayne@69: * built and not outside it (where this is supported by the linker). jpayne@69: */ jpayne@69: jpayne@69: #ifndef MODULE_SCOPE jpayne@69: # ifdef __cplusplus jpayne@69: # define MODULE_SCOPE extern "C" jpayne@69: # else jpayne@69: # define MODULE_SCOPE extern jpayne@69: # endif jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * Macros used to cast between pointers and integers (e.g. when storing an int jpayne@69: * in ClientData), on 64-bit architectures they avoid gcc warning about "cast jpayne@69: * to/from pointer from/to integer of different size". jpayne@69: */ jpayne@69: jpayne@69: #if !defined(INT2PTR) && !defined(PTR2INT) jpayne@69: # if defined(HAVE_INTPTR_T) || defined(intptr_t) jpayne@69: # define INT2PTR(p) ((void *)(intptr_t)(p)) jpayne@69: # define PTR2INT(p) ((int)(intptr_t)(p)) jpayne@69: # else jpayne@69: # define INT2PTR(p) ((void *)(p)) jpayne@69: # define PTR2INT(p) ((int)(p)) jpayne@69: # endif jpayne@69: #endif jpayne@69: #if !defined(UINT2PTR) && !defined(PTR2UINT) jpayne@69: # if defined(HAVE_UINTPTR_T) || defined(uintptr_t) jpayne@69: # define UINT2PTR(p) ((void *)(uintptr_t)(p)) jpayne@69: # define PTR2UINT(p) ((unsigned int)(uintptr_t)(p)) jpayne@69: # else jpayne@69: # define UINT2PTR(p) ((void *)(p)) jpayne@69: # define PTR2UINT(p) ((unsigned int)(p)) jpayne@69: # endif jpayne@69: #endif jpayne@69: jpayne@69: #if defined(_WIN32) && defined(_MSC_VER) jpayne@69: # define vsnprintf _vsnprintf jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * The following procedures allow namespaces to be customized to support jpayne@69: * special name resolution rules for commands/variables. jpayne@69: */ jpayne@69: jpayne@69: struct Tcl_ResolvedVarInfo; jpayne@69: jpayne@69: typedef Tcl_Var (Tcl_ResolveRuntimeVarProc)(Tcl_Interp *interp, jpayne@69: struct Tcl_ResolvedVarInfo *vinfoPtr); jpayne@69: jpayne@69: typedef void (Tcl_ResolveVarDeleteProc)(struct Tcl_ResolvedVarInfo *vinfoPtr); jpayne@69: jpayne@69: /* jpayne@69: * The following structure encapsulates the routines needed to resolve a jpayne@69: * variable reference at runtime. Any variable specific state will typically jpayne@69: * be appended to this structure. jpayne@69: */ jpayne@69: jpayne@69: typedef struct Tcl_ResolvedVarInfo { jpayne@69: Tcl_ResolveRuntimeVarProc *fetchProc; jpayne@69: Tcl_ResolveVarDeleteProc *deleteProc; jpayne@69: } Tcl_ResolvedVarInfo; jpayne@69: jpayne@69: typedef int (Tcl_ResolveCompiledVarProc)(Tcl_Interp *interp, jpayne@69: CONST84 char *name, int length, Tcl_Namespace *context, jpayne@69: Tcl_ResolvedVarInfo **rPtr); jpayne@69: jpayne@69: typedef int (Tcl_ResolveVarProc)(Tcl_Interp *interp, CONST84 char *name, jpayne@69: Tcl_Namespace *context, int flags, Tcl_Var *rPtr); jpayne@69: jpayne@69: typedef int (Tcl_ResolveCmdProc)(Tcl_Interp *interp, CONST84 char *name, jpayne@69: Tcl_Namespace *context, int flags, Tcl_Command *rPtr); jpayne@69: jpayne@69: typedef struct Tcl_ResolverInfo { jpayne@69: Tcl_ResolveCmdProc *cmdResProc; jpayne@69: /* Procedure handling command name jpayne@69: * resolution. */ jpayne@69: Tcl_ResolveVarProc *varResProc; jpayne@69: /* Procedure handling variable name resolution jpayne@69: * for variables that can only be handled at jpayne@69: * runtime. */ jpayne@69: Tcl_ResolveCompiledVarProc *compiledVarResProc; jpayne@69: /* Procedure handling variable name resolution jpayne@69: * at compile time. */ jpayne@69: } Tcl_ResolverInfo; jpayne@69: jpayne@69: /* jpayne@69: * This flag bit should not interfere with TCL_GLOBAL_ONLY, jpayne@69: * TCL_NAMESPACE_ONLY, or TCL_LEAVE_ERR_MSG; it signals that the variable jpayne@69: * lookup is performed for upvar (or similar) purposes, with slightly jpayne@69: * different rules: jpayne@69: * - Bug #696893 - variable is either proc-local or in the current jpayne@69: * namespace; never follow the second (global) resolution path jpayne@69: * - Bug #631741 - do not use special namespace or interp resolvers jpayne@69: * jpayne@69: * It should also not collide with the (deprecated) TCL_PARSE_PART1 flag jpayne@69: * (Bug #835020) jpayne@69: */ jpayne@69: jpayne@69: #define TCL_AVOID_RESOLVERS 0x40000 jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to namespaces. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: typedef struct Tcl_Ensemble Tcl_Ensemble; jpayne@69: typedef struct NamespacePathEntry NamespacePathEntry; jpayne@69: jpayne@69: /* jpayne@69: * Special hashtable for variables: this is just a Tcl_HashTable with an nsPtr jpayne@69: * field added at the end: in this way variables can find their namespace jpayne@69: * without having to copy a pointer in their struct: they can access it via jpayne@69: * their hPtr->tablePtr. jpayne@69: */ jpayne@69: jpayne@69: typedef struct TclVarHashTable { jpayne@69: Tcl_HashTable table; jpayne@69: struct Namespace *nsPtr; jpayne@69: } TclVarHashTable; jpayne@69: jpayne@69: /* jpayne@69: * This is for itcl - it likes to search our varTables directly :( jpayne@69: */ jpayne@69: jpayne@69: #define TclVarHashFindVar(tablePtr, key) \ jpayne@69: TclVarHashCreateVar((tablePtr), (key), NULL) jpayne@69: jpayne@69: /* jpayne@69: * Define this to reduce the amount of space that the average namespace jpayne@69: * consumes by only allocating the table of child namespaces when necessary. jpayne@69: * Defining it breaks compatibility for Tcl extensions (e.g., itcl) which jpayne@69: * reach directly into the Namespace structure. jpayne@69: */ jpayne@69: jpayne@69: #undef BREAK_NAMESPACE_COMPAT jpayne@69: jpayne@69: /* jpayne@69: * The structure below defines a namespace. jpayne@69: * Note: the first five fields must match exactly the fields in a jpayne@69: * Tcl_Namespace structure (see tcl.h). If you change one, be sure to change jpayne@69: * the other. jpayne@69: */ jpayne@69: jpayne@69: typedef struct Namespace { jpayne@69: char *name; /* The namespace's simple (unqualified) name. jpayne@69: * This contains no ::'s. The name of the jpayne@69: * global namespace is "" although "::" is an jpayne@69: * synonym. */ jpayne@69: char *fullName; /* The namespace's fully qualified name. This jpayne@69: * starts with ::. */ jpayne@69: ClientData clientData; /* An arbitrary value associated with this jpayne@69: * namespace. */ jpayne@69: Tcl_NamespaceDeleteProc *deleteProc; jpayne@69: /* Procedure invoked when deleting the jpayne@69: * namespace to, e.g., free clientData. */ jpayne@69: struct Namespace *parentPtr;/* Points to the namespace that contains this jpayne@69: * one. NULL if this is the global jpayne@69: * namespace. */ jpayne@69: #ifndef BREAK_NAMESPACE_COMPAT jpayne@69: Tcl_HashTable childTable; /* Contains any child namespaces. Indexed by jpayne@69: * strings; values have type (Namespace *). */ jpayne@69: #else jpayne@69: Tcl_HashTable *childTablePtr; jpayne@69: /* Contains any child namespaces. Indexed by jpayne@69: * strings; values have type (Namespace *). If jpayne@69: * NULL, there are no children. */ jpayne@69: #endif jpayne@69: long nsId; /* Unique id for the namespace. */ jpayne@69: Tcl_Interp *interp; /* The interpreter containing this jpayne@69: * namespace. */ jpayne@69: int flags; /* OR-ed combination of the namespace status jpayne@69: * flags NS_DYING and NS_DEAD listed below. */ jpayne@69: int activationCount; /* Number of "activations" or active call jpayne@69: * frames for this namespace that are on the jpayne@69: * Tcl call stack. The namespace won't be jpayne@69: * freed until activationCount becomes zero. */ jpayne@69: int refCount; /* Count of references by namespaceName jpayne@69: * objects. The namespace can't be freed until jpayne@69: * refCount becomes zero. */ jpayne@69: Tcl_HashTable cmdTable; /* Contains all the commands currently jpayne@69: * registered in the namespace. Indexed by jpayne@69: * strings; values have type (Command *). jpayne@69: * Commands imported by Tcl_Import have jpayne@69: * Command structures that point (via an jpayne@69: * ImportedCmdRef structure) to the Command jpayne@69: * structure in the source namespace's command jpayne@69: * table. */ jpayne@69: TclVarHashTable varTable; /* Contains all the (global) variables jpayne@69: * currently in this namespace. Indexed by jpayne@69: * strings; values have type (Var *). */ jpayne@69: char **exportArrayPtr; /* Points to an array of string patterns jpayne@69: * specifying which commands are exported. A jpayne@69: * pattern may include "string match" style jpayne@69: * wildcard characters to specify multiple jpayne@69: * commands; however, no namespace qualifiers jpayne@69: * are allowed. NULL if no export patterns are jpayne@69: * registered. */ jpayne@69: int numExportPatterns; /* Number of export patterns currently jpayne@69: * registered using "namespace export". */ jpayne@69: int maxExportPatterns; /* Mumber of export patterns for which space jpayne@69: * is currently allocated. */ jpayne@69: int cmdRefEpoch; /* Incremented if a newly added command jpayne@69: * shadows a command for which this namespace jpayne@69: * has already cached a Command* pointer; this jpayne@69: * causes all its cached Command* pointers to jpayne@69: * be invalidated. */ jpayne@69: int resolverEpoch; /* Incremented whenever (a) the name jpayne@69: * resolution rules change for this namespace jpayne@69: * or (b) a newly added command shadows a jpayne@69: * command that is compiled to bytecodes. This jpayne@69: * invalidates all byte codes compiled in the jpayne@69: * namespace, causing the code to be jpayne@69: * recompiled under the new rules.*/ jpayne@69: Tcl_ResolveCmdProc *cmdResProc; jpayne@69: /* If non-null, this procedure overrides the jpayne@69: * usual command resolution mechanism in Tcl. jpayne@69: * This procedure is invoked within jpayne@69: * Tcl_FindCommand to resolve all command jpayne@69: * references within the namespace. */ jpayne@69: Tcl_ResolveVarProc *varResProc; jpayne@69: /* If non-null, this procedure overrides the jpayne@69: * usual variable resolution mechanism in Tcl. jpayne@69: * This procedure is invoked within jpayne@69: * Tcl_FindNamespaceVar to resolve all jpayne@69: * variable references within the namespace at jpayne@69: * runtime. */ jpayne@69: Tcl_ResolveCompiledVarProc *compiledVarResProc; jpayne@69: /* If non-null, this procedure overrides the jpayne@69: * usual variable resolution mechanism in Tcl. jpayne@69: * This procedure is invoked within jpayne@69: * LookupCompiledLocal to resolve variable jpayne@69: * references within the namespace at compile jpayne@69: * time. */ jpayne@69: int exportLookupEpoch; /* Incremented whenever a command is added to jpayne@69: * a namespace, removed from a namespace or jpayne@69: * the exports of a namespace are changed. jpayne@69: * Allows TIP#112-driven command lists to be jpayne@69: * validated efficiently. */ jpayne@69: Tcl_Ensemble *ensembles; /* List of structures that contain the details jpayne@69: * of the ensembles that are implemented on jpayne@69: * top of this namespace. */ jpayne@69: Tcl_Obj *unknownHandlerPtr; /* A script fragment to be used when command jpayne@69: * resolution in this namespace fails. TIP jpayne@69: * 181. */ jpayne@69: int commandPathLength; /* The length of the explicit path. */ jpayne@69: NamespacePathEntry *commandPathArray; jpayne@69: /* The explicit path of the namespace as an jpayne@69: * array. */ jpayne@69: NamespacePathEntry *commandPathSourceList; jpayne@69: /* Linked list of path entries that point to jpayne@69: * this namespace. */ jpayne@69: Tcl_NamespaceDeleteProc *earlyDeleteProc; jpayne@69: /* Just like the deleteProc field (and called jpayne@69: * with the same clientData) but called at the jpayne@69: * start of the deletion process, so there is jpayne@69: * a chance for code to do stuff inside the jpayne@69: * namespace before deletion completes. */ jpayne@69: } Namespace; jpayne@69: jpayne@69: /* jpayne@69: * An entry on a namespace's command resolution path. jpayne@69: */ jpayne@69: jpayne@69: struct NamespacePathEntry { jpayne@69: Namespace *nsPtr; /* What does this path entry point to? If it jpayne@69: * is NULL, this path entry points is jpayne@69: * redundant and should be skipped. */ jpayne@69: Namespace *creatorNsPtr; /* Where does this path entry point from? This jpayne@69: * allows for efficient invalidation of jpayne@69: * references when the path entry's target jpayne@69: * updates its current list of defined jpayne@69: * commands. */ jpayne@69: NamespacePathEntry *prevPtr, *nextPtr; jpayne@69: /* Linked list pointers or NULL at either end jpayne@69: * of the list that hangs off Namespace's jpayne@69: * commandPathSourceList field. */ jpayne@69: }; jpayne@69: jpayne@69: /* jpayne@69: * Flags used to represent the status of a namespace: jpayne@69: * jpayne@69: * NS_DYING - 1 means Tcl_DeleteNamespace has been called to delete the jpayne@69: * namespace but there are still active call frames on the Tcl jpayne@69: * stack that refer to the namespace. When the last call frame jpayne@69: * referring to it has been popped, it's variables and command jpayne@69: * will be destroyed and it will be marked "dead" (NS_DEAD). The jpayne@69: * namespace can no longer be looked up by name. jpayne@69: * NS_DEAD - 1 means Tcl_DeleteNamespace has been called to delete the jpayne@69: * namespace and no call frames still refer to it. Its variables jpayne@69: * and command have already been destroyed. This bit allows the jpayne@69: * namespace resolution code to recognize that the namespace is jpayne@69: * "deleted". When the last namespaceName object in any byte code jpayne@69: * unit that refers to the namespace has been freed (i.e., when jpayne@69: * the namespace's refCount is 0), the namespace's storage will jpayne@69: * be freed. jpayne@69: * NS_KILLED - 1 means that TclTeardownNamespace has already been called on jpayne@69: * this namespace and it should not be called again [Bug 1355942] jpayne@69: * NS_SUPPRESS_COMPILATION - jpayne@69: * Marks the commands in this namespace for not being compiled, jpayne@69: * forcing them to be looked up every time. jpayne@69: */ jpayne@69: jpayne@69: #define NS_DYING 0x01 jpayne@69: #define NS_DEAD 0x02 jpayne@69: #define NS_KILLED 0x04 jpayne@69: #define NS_SUPPRESS_COMPILATION 0x08 jpayne@69: jpayne@69: /* jpayne@69: * Flags passed to TclGetNamespaceForQualName: jpayne@69: * jpayne@69: * TCL_GLOBAL_ONLY - (see tcl.h) Look only in the global ns. jpayne@69: * TCL_NAMESPACE_ONLY - (see tcl.h) Look only in the context ns. jpayne@69: * TCL_CREATE_NS_IF_UNKNOWN - Create unknown namespaces. jpayne@69: * TCL_FIND_ONLY_NS - The name sought is a namespace name. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_CREATE_NS_IF_UNKNOWN 0x800 jpayne@69: #define TCL_FIND_ONLY_NS 0x1000 jpayne@69: jpayne@69: /* jpayne@69: * The client data for an ensemble command. This consists of the table of jpayne@69: * commands that are actually exported by the namespace, and an epoch counter jpayne@69: * that, combined with the exportLookupEpoch field of the namespace structure, jpayne@69: * defines whether the table contains valid data or will need to be recomputed jpayne@69: * next time the ensemble command is called. jpayne@69: */ jpayne@69: jpayne@69: typedef struct EnsembleConfig { jpayne@69: Namespace *nsPtr; /* The namespace backing this ensemble up. */ jpayne@69: Tcl_Command token; /* The token for the command that provides jpayne@69: * ensemble support for the namespace, or NULL jpayne@69: * if the command has been deleted (or never jpayne@69: * existed; the global namespace never has an jpayne@69: * ensemble command.) */ jpayne@69: int epoch; /* The epoch at which this ensemble's table of jpayne@69: * exported commands is valid. */ jpayne@69: char **subcommandArrayPtr; /* Array of ensemble subcommand names. At all jpayne@69: * consistent points, this will have the same jpayne@69: * number of entries as there are entries in jpayne@69: * the subcommandTable hash. */ jpayne@69: Tcl_HashTable subcommandTable; jpayne@69: /* Hash table of ensemble subcommand names, jpayne@69: * which are its keys so this also provides jpayne@69: * the storage management for those subcommand jpayne@69: * names. The contents of the entry values are jpayne@69: * object version the prefix lists to use when jpayne@69: * substituting for the command/subcommand to jpayne@69: * build the ensemble implementation command. jpayne@69: * Has to be stored here as well as in jpayne@69: * subcommandDict because that field is NULL jpayne@69: * when we are deriving the ensemble from the jpayne@69: * namespace exports list. FUTURE WORK: use jpayne@69: * object hash table here. */ jpayne@69: struct EnsembleConfig *next;/* The next ensemble in the linked list of jpayne@69: * ensembles associated with a namespace. If jpayne@69: * this field points to this ensemble, the jpayne@69: * structure has already been unlinked from jpayne@69: * all lists, and cannot be found by scanning jpayne@69: * the list from the namespace's ensemble jpayne@69: * field. */ jpayne@69: int flags; /* ORed combo of TCL_ENSEMBLE_PREFIX, jpayne@69: * ENSEMBLE_DEAD and ENSEMBLE_COMPILE. */ jpayne@69: jpayne@69: /* OBJECT FIELDS FOR ENSEMBLE CONFIGURATION */ jpayne@69: jpayne@69: Tcl_Obj *subcommandDict; /* Dictionary providing mapping from jpayne@69: * subcommands to their implementing command jpayne@69: * prefixes, or NULL if we are to build the jpayne@69: * map automatically from the namespace jpayne@69: * exports. */ jpayne@69: Tcl_Obj *subcmdList; /* List of commands that this ensemble jpayne@69: * actually provides, and whose implementation jpayne@69: * will be built using the subcommandDict (if jpayne@69: * present and defined) and by simple mapping jpayne@69: * to the namespace otherwise. If NULL, jpayne@69: * indicates that we are using the (dynamic) jpayne@69: * list of currently exported commands. */ jpayne@69: Tcl_Obj *unknownHandler; /* Script prefix used to handle the case when jpayne@69: * no match is found (according to the rule jpayne@69: * defined by flag bit TCL_ENSEMBLE_PREFIX) or jpayne@69: * NULL to use the default error-generating jpayne@69: * behaviour. The script execution gets all jpayne@69: * the arguments to the ensemble command jpayne@69: * (including objv[0]) and will have the jpayne@69: * results passed directly back to the caller jpayne@69: * (including the error code) unless the code jpayne@69: * is TCL_CONTINUE in which case the jpayne@69: * subcommand will be reparsed by the ensemble jpayne@69: * core, presumably because the ensemble jpayne@69: * itself has been updated. */ jpayne@69: Tcl_Obj *parameterList; /* List of ensemble parameter names. */ jpayne@69: int numParameters; /* Cached number of parameters. This is either jpayne@69: * 0 (if the parameterList field is NULL) or jpayne@69: * the length of the list in the parameterList jpayne@69: * field. */ jpayne@69: } EnsembleConfig; jpayne@69: jpayne@69: /* jpayne@69: * Various bits for the EnsembleConfig.flags field. jpayne@69: */ jpayne@69: jpayne@69: #define ENSEMBLE_DEAD 0x1 /* Flag value to say that the ensemble is dead jpayne@69: * and on its way out. */ jpayne@69: #define ENSEMBLE_COMPILE 0x4 /* Flag to enable bytecode compilation of an jpayne@69: * ensemble. */ jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to variables. These are used primarily in tclVar.c jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * The following structure defines a variable trace, which is used to invoke a jpayne@69: * specific C procedure whenever certain operations are performed on a jpayne@69: * variable. jpayne@69: */ jpayne@69: jpayne@69: typedef struct VarTrace { jpayne@69: Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given by jpayne@69: * flags are performed on variable. */ jpayne@69: ClientData clientData; /* Argument to pass to proc. */ jpayne@69: int flags; /* What events the trace procedure is jpayne@69: * interested in: OR-ed combination of jpayne@69: * TCL_TRACE_READS, TCL_TRACE_WRITES, jpayne@69: * TCL_TRACE_UNSETS and TCL_TRACE_ARRAY. */ jpayne@69: struct VarTrace *nextPtr; /* Next in list of traces associated with a jpayne@69: * particular variable. */ jpayne@69: } VarTrace; jpayne@69: jpayne@69: /* jpayne@69: * The following structure defines a command trace, which is used to invoke a jpayne@69: * specific C procedure whenever certain operations are performed on a jpayne@69: * command. jpayne@69: */ jpayne@69: jpayne@69: typedef struct CommandTrace { jpayne@69: Tcl_CommandTraceProc *traceProc; jpayne@69: /* Procedure to call when operations given by jpayne@69: * flags are performed on command. */ jpayne@69: ClientData clientData; /* Argument to pass to proc. */ jpayne@69: int flags; /* What events the trace procedure is jpayne@69: * interested in: OR-ed combination of jpayne@69: * TCL_TRACE_RENAME, TCL_TRACE_DELETE. */ jpayne@69: struct CommandTrace *nextPtr; jpayne@69: /* Next in list of traces associated with a jpayne@69: * particular command. */ jpayne@69: int refCount; /* Used to ensure this structure is not jpayne@69: * deleted too early. Keeps track of how many jpayne@69: * pieces of code have a pointer to this jpayne@69: * structure. */ jpayne@69: } CommandTrace; jpayne@69: jpayne@69: /* jpayne@69: * When a command trace is active (i.e. its associated procedure is executing) jpayne@69: * one of the following structures is linked into a list associated with the jpayne@69: * command's interpreter. The information in the structure is needed in order jpayne@69: * for Tcl to behave reasonably if traces are deleted while traces are active. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ActiveCommandTrace { jpayne@69: struct Command *cmdPtr; /* Command that's being traced. */ jpayne@69: struct ActiveCommandTrace *nextPtr; jpayne@69: /* Next in list of all active command traces jpayne@69: * for the interpreter, or NULL if no more. */ jpayne@69: CommandTrace *nextTracePtr; /* Next trace to check after current trace jpayne@69: * procedure returns; if this trace gets jpayne@69: * deleted, must update pointer to avoid using jpayne@69: * free'd memory. */ jpayne@69: int reverseScan; /* Boolean set true when traces are scanning jpayne@69: * in reverse order. */ jpayne@69: } ActiveCommandTrace; jpayne@69: jpayne@69: /* jpayne@69: * When a variable trace is active (i.e. its associated procedure is jpayne@69: * executing) one of the following structures is linked into a list associated jpayne@69: * with the variable's interpreter. The information in the structure is needed jpayne@69: * in order for Tcl to behave reasonably if traces are deleted while traces jpayne@69: * are active. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ActiveVarTrace { jpayne@69: struct Var *varPtr; /* Variable that's being traced. */ jpayne@69: struct ActiveVarTrace *nextPtr; jpayne@69: /* Next in list of all active variable traces jpayne@69: * for the interpreter, or NULL if no more. */ jpayne@69: VarTrace *nextTracePtr; /* Next trace to check after current trace jpayne@69: * procedure returns; if this trace gets jpayne@69: * deleted, must update pointer to avoid using jpayne@69: * free'd memory. */ jpayne@69: } ActiveVarTrace; jpayne@69: jpayne@69: /* jpayne@69: * The structure below defines a variable, which associates a string name with jpayne@69: * a Tcl_Obj value. These structures are kept in procedure call frames (for jpayne@69: * local variables recognized by the compiler) or in the heap (for global jpayne@69: * variables and any variable not known to the compiler). For each Var jpayne@69: * structure in the heap, a hash table entry holds the variable name and a jpayne@69: * pointer to the Var structure. jpayne@69: */ jpayne@69: jpayne@69: typedef struct Var { jpayne@69: int flags; /* Miscellaneous bits of information about jpayne@69: * variable. See below for definitions. */ jpayne@69: union { jpayne@69: Tcl_Obj *objPtr; /* The variable's object value. Used for jpayne@69: * scalar variables and array elements. */ jpayne@69: TclVarHashTable *tablePtr;/* For array variables, this points to jpayne@69: * information about the hash table used to jpayne@69: * implement the associative array. Points to jpayne@69: * ckalloc-ed data. */ jpayne@69: struct Var *linkPtr; /* If this is a global variable being referred jpayne@69: * to in a procedure, or a variable created by jpayne@69: * "upvar", this field points to the jpayne@69: * referenced variable's Var struct. */ jpayne@69: } value; jpayne@69: } Var; jpayne@69: jpayne@69: typedef struct VarInHash { jpayne@69: Var var; jpayne@69: int refCount; /* Counts number of active uses of this jpayne@69: * variable: 1 for the entry in the hash jpayne@69: * table, 1 for each additional variable whose jpayne@69: * linkPtr points here, 1 for each nested jpayne@69: * trace active on variable, and 1 if the jpayne@69: * variable is a namespace variable. This jpayne@69: * record can't be deleted until refCount jpayne@69: * becomes 0. */ jpayne@69: Tcl_HashEntry entry; /* The hash table entry that refers to this jpayne@69: * variable. This is used to find the name of jpayne@69: * the variable and to delete it from its jpayne@69: * hashtable if it is no longer needed. It jpayne@69: * also holds the variable's name. */ jpayne@69: } VarInHash; jpayne@69: jpayne@69: /* jpayne@69: * Flag bits for variables. The first two (VAR_ARRAY and VAR_LINK) are jpayne@69: * mutually exclusive and give the "type" of the variable. If none is set, jpayne@69: * this is a scalar variable. jpayne@69: * jpayne@69: * VAR_ARRAY - 1 means this is an array variable rather than jpayne@69: * a scalar variable or link. The "tablePtr" jpayne@69: * field points to the array's hashtable for its jpayne@69: * elements. jpayne@69: * VAR_LINK - 1 means this Var structure contains a pointer jpayne@69: * to another Var structure that either has the jpayne@69: * real value or is itself another VAR_LINK jpayne@69: * pointer. Variables like this come about jpayne@69: * through "upvar" and "global" commands, or jpayne@69: * through references to variables in enclosing jpayne@69: * namespaces. jpayne@69: * jpayne@69: * Flags that indicate the type and status of storage; none is set for jpayne@69: * compiled local variables (Var structs). jpayne@69: * jpayne@69: * VAR_IN_HASHTABLE - 1 means this variable is in a hashtable and jpayne@69: * the Var structure is malloced. 0 if it is a jpayne@69: * local variable that was assigned a slot in a jpayne@69: * procedure frame by the compiler so the Var jpayne@69: * storage is part of the call frame. jpayne@69: * VAR_DEAD_HASH 1 means that this var's entry in the hashtable jpayne@69: * has already been deleted. jpayne@69: * VAR_ARRAY_ELEMENT - 1 means that this variable is an array jpayne@69: * element, so it is not legal for it to be an jpayne@69: * array itself (the VAR_ARRAY flag had better jpayne@69: * not be set). jpayne@69: * VAR_NAMESPACE_VAR - 1 means that this variable was declared as a jpayne@69: * namespace variable. This flag ensures it jpayne@69: * persists until its namespace is destroyed or jpayne@69: * until the variable is unset; it will persist jpayne@69: * even if it has not been initialized and is jpayne@69: * marked undefined. The variable's refCount is jpayne@69: * incremented to reflect the "reference" from jpayne@69: * its namespace. jpayne@69: * jpayne@69: * Flag values relating to the variable's trace and search status. jpayne@69: * jpayne@69: * VAR_TRACED_READ jpayne@69: * VAR_TRACED_WRITE jpayne@69: * VAR_TRACED_UNSET jpayne@69: * VAR_TRACED_ARRAY jpayne@69: * VAR_TRACE_ACTIVE - 1 means that trace processing is currently jpayne@69: * underway for a read or write access, so new jpayne@69: * read or write accesses should not cause trace jpayne@69: * procedures to be called and the variable can't jpayne@69: * be deleted. jpayne@69: * VAR_SEARCH_ACTIVE jpayne@69: * jpayne@69: * The following additional flags are used with the CompiledLocal type defined jpayne@69: * below: jpayne@69: * jpayne@69: * VAR_ARGUMENT - 1 means that this variable holds a procedure jpayne@69: * argument. jpayne@69: * VAR_TEMPORARY - 1 if the local variable is an anonymous jpayne@69: * temporary variable. Temporaries have a NULL jpayne@69: * name. jpayne@69: * VAR_RESOLVED - 1 if name resolution has been done for this jpayne@69: * variable. jpayne@69: * VAR_IS_ARGS 1 if this variable is the last argument and is jpayne@69: * named "args". jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * FLAGS RENUMBERED: everything breaks already, make things simpler. jpayne@69: * jpayne@69: * IMPORTANT: skip the values 0x10, 0x20, 0x40, 0x800 corresponding to jpayne@69: * TCL_TRACE_(READS/WRITES/UNSETS/ARRAY): makes code simpler in tclTrace.c jpayne@69: * jpayne@69: * Keep the flag values for VAR_ARGUMENT and VAR_TEMPORARY so that old values jpayne@69: * in precompiled scripts keep working. jpayne@69: */ jpayne@69: jpayne@69: /* Type of value (0 is scalar) */ jpayne@69: #define VAR_ARRAY 0x1 jpayne@69: #define VAR_LINK 0x2 jpayne@69: jpayne@69: /* Type of storage (0 is compiled local) */ jpayne@69: #define VAR_IN_HASHTABLE 0x4 jpayne@69: #define VAR_DEAD_HASH 0x8 jpayne@69: #define VAR_ARRAY_ELEMENT 0x1000 jpayne@69: #define VAR_NAMESPACE_VAR 0x80 /* KEEP OLD VALUE for Itcl */ jpayne@69: jpayne@69: #define VAR_ALL_HASH \ jpayne@69: (VAR_IN_HASHTABLE|VAR_DEAD_HASH|VAR_NAMESPACE_VAR|VAR_ARRAY_ELEMENT) jpayne@69: jpayne@69: /* Trace and search state. */ jpayne@69: jpayne@69: #define VAR_TRACED_READ 0x10 /* TCL_TRACE_READS */ jpayne@69: #define VAR_TRACED_WRITE 0x20 /* TCL_TRACE_WRITES */ jpayne@69: #define VAR_TRACED_UNSET 0x40 /* TCL_TRACE_UNSETS */ jpayne@69: #define VAR_TRACED_ARRAY 0x800 /* TCL_TRACE_ARRAY */ jpayne@69: #define VAR_TRACE_ACTIVE 0x2000 jpayne@69: #define VAR_SEARCH_ACTIVE 0x4000 jpayne@69: #define VAR_ALL_TRACES \ jpayne@69: (VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_ARRAY|VAR_TRACED_UNSET) jpayne@69: jpayne@69: /* Special handling on initialisation (only CompiledLocal). */ jpayne@69: #define VAR_ARGUMENT 0x100 /* KEEP OLD VALUE! See tclProc.c */ jpayne@69: #define VAR_TEMPORARY 0x200 /* KEEP OLD VALUE! See tclProc.c */ jpayne@69: #define VAR_IS_ARGS 0x400 jpayne@69: #define VAR_RESOLVED 0x8000 jpayne@69: jpayne@69: /* jpayne@69: * Macros to ensure that various flag bits are set properly for variables. jpayne@69: * The ANSI C "prototypes" for these macros are: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclSetVarScalar(Var *varPtr); jpayne@69: * MODULE_SCOPE void TclSetVarArray(Var *varPtr); jpayne@69: * MODULE_SCOPE void TclSetVarLink(Var *varPtr); jpayne@69: * MODULE_SCOPE void TclSetVarArrayElement(Var *varPtr); jpayne@69: * MODULE_SCOPE void TclSetVarUndefined(Var *varPtr); jpayne@69: * MODULE_SCOPE void TclClearVarUndefined(Var *varPtr); jpayne@69: */ jpayne@69: jpayne@69: #define TclSetVarScalar(varPtr) \ jpayne@69: (varPtr)->flags &= ~(VAR_ARRAY|VAR_LINK) jpayne@69: jpayne@69: #define TclSetVarArray(varPtr) \ jpayne@69: (varPtr)->flags = ((varPtr)->flags & ~VAR_LINK) | VAR_ARRAY jpayne@69: jpayne@69: #define TclSetVarLink(varPtr) \ jpayne@69: (varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_LINK jpayne@69: jpayne@69: #define TclSetVarArrayElement(varPtr) \ jpayne@69: (varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_ARRAY_ELEMENT jpayne@69: jpayne@69: #define TclSetVarUndefined(varPtr) \ jpayne@69: (varPtr)->flags &= ~(VAR_ARRAY|VAR_LINK);\ jpayne@69: (varPtr)->value.objPtr = NULL jpayne@69: jpayne@69: #define TclClearVarUndefined(varPtr) jpayne@69: jpayne@69: #define TclSetVarTraceActive(varPtr) \ jpayne@69: (varPtr)->flags |= VAR_TRACE_ACTIVE jpayne@69: jpayne@69: #define TclClearVarTraceActive(varPtr) \ jpayne@69: (varPtr)->flags &= ~VAR_TRACE_ACTIVE jpayne@69: jpayne@69: #define TclSetVarNamespaceVar(varPtr) \ jpayne@69: if (!TclIsVarNamespaceVar(varPtr)) {\ jpayne@69: (varPtr)->flags |= VAR_NAMESPACE_VAR;\ jpayne@69: if (TclIsVarInHash(varPtr)) {\ jpayne@69: ((VarInHash *)(varPtr))->refCount++;\ jpayne@69: }\ jpayne@69: } jpayne@69: jpayne@69: #define TclClearVarNamespaceVar(varPtr) \ jpayne@69: if (TclIsVarNamespaceVar(varPtr)) {\ jpayne@69: (varPtr)->flags &= ~VAR_NAMESPACE_VAR;\ jpayne@69: if (TclIsVarInHash(varPtr)) {\ jpayne@69: ((VarInHash *)(varPtr))->refCount--;\ jpayne@69: }\ jpayne@69: } jpayne@69: jpayne@69: /* jpayne@69: * Macros to read various flag bits of variables. jpayne@69: * The ANSI C "prototypes" for these macros are: jpayne@69: * jpayne@69: * MODULE_SCOPE int TclIsVarScalar(Var *varPtr); jpayne@69: * MODULE_SCOPE int TclIsVarLink(Var *varPtr); jpayne@69: * MODULE_SCOPE int TclIsVarArray(Var *varPtr); jpayne@69: * MODULE_SCOPE int TclIsVarUndefined(Var *varPtr); jpayne@69: * MODULE_SCOPE int TclIsVarArrayElement(Var *varPtr); jpayne@69: * MODULE_SCOPE int TclIsVarTemporary(Var *varPtr); jpayne@69: * MODULE_SCOPE int TclIsVarArgument(Var *varPtr); jpayne@69: * MODULE_SCOPE int TclIsVarResolved(Var *varPtr); jpayne@69: */ jpayne@69: jpayne@69: #define TclIsVarScalar(varPtr) \ jpayne@69: !((varPtr)->flags & (VAR_ARRAY|VAR_LINK)) jpayne@69: jpayne@69: #define TclIsVarLink(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_LINK) jpayne@69: jpayne@69: #define TclIsVarArray(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_ARRAY) jpayne@69: jpayne@69: #define TclIsVarUndefined(varPtr) \ jpayne@69: ((varPtr)->value.objPtr == NULL) jpayne@69: jpayne@69: #define TclIsVarArrayElement(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_ARRAY_ELEMENT) jpayne@69: jpayne@69: #define TclIsVarNamespaceVar(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_NAMESPACE_VAR) jpayne@69: jpayne@69: #define TclIsVarTemporary(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_TEMPORARY) jpayne@69: jpayne@69: #define TclIsVarArgument(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_ARGUMENT) jpayne@69: jpayne@69: #define TclIsVarResolved(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_RESOLVED) jpayne@69: jpayne@69: #define TclIsVarTraceActive(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_TRACE_ACTIVE) jpayne@69: jpayne@69: #define TclIsVarTraced(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_ALL_TRACES) jpayne@69: jpayne@69: #define TclIsVarInHash(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_IN_HASHTABLE) jpayne@69: jpayne@69: #define TclIsVarDeadHash(varPtr) \ jpayne@69: ((varPtr)->flags & VAR_DEAD_HASH) jpayne@69: jpayne@69: #define TclGetVarNsPtr(varPtr) \ jpayne@69: (TclIsVarInHash(varPtr) \ jpayne@69: ? ((TclVarHashTable *) ((((VarInHash *) (varPtr))->entry.tablePtr)))->nsPtr \ jpayne@69: : NULL) jpayne@69: jpayne@69: #define VarHashRefCount(varPtr) \ jpayne@69: ((VarInHash *) (varPtr))->refCount jpayne@69: jpayne@69: /* jpayne@69: * Macros for direct variable access by TEBC. jpayne@69: */ jpayne@69: jpayne@69: #define TclIsVarDirectReadable(varPtr) \ jpayne@69: ( !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ)) \ jpayne@69: && (varPtr)->value.objPtr) jpayne@69: jpayne@69: #define TclIsVarDirectWritable(varPtr) \ jpayne@69: !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_WRITE|VAR_DEAD_HASH)) jpayne@69: jpayne@69: #define TclIsVarDirectUnsettable(varPtr) \ jpayne@69: !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_UNSET|VAR_DEAD_HASH)) jpayne@69: jpayne@69: #define TclIsVarDirectModifyable(varPtr) \ jpayne@69: ( !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ|VAR_TRACED_WRITE)) \ jpayne@69: && (varPtr)->value.objPtr) jpayne@69: jpayne@69: #define TclIsVarDirectReadable2(varPtr, arrayPtr) \ jpayne@69: (TclIsVarDirectReadable(varPtr) &&\ jpayne@69: (!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_READ))) jpayne@69: jpayne@69: #define TclIsVarDirectWritable2(varPtr, arrayPtr) \ jpayne@69: (TclIsVarDirectWritable(varPtr) &&\ jpayne@69: (!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_WRITE))) jpayne@69: jpayne@69: #define TclIsVarDirectModifyable2(varPtr, arrayPtr) \ jpayne@69: (TclIsVarDirectModifyable(varPtr) &&\ jpayne@69: (!(arrayPtr) || !((arrayPtr)->flags & (VAR_TRACED_READ|VAR_TRACED_WRITE)))) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to procedures. These are used primarily in jpayne@69: * tclProc.c, tclCompile.c, and tclExecute.c. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) jpayne@69: # define TCLFLEXARRAY jpayne@69: #elif defined(__GNUC__) && (__GNUC__ > 2) jpayne@69: # define TCLFLEXARRAY 0 jpayne@69: #else jpayne@69: # define TCLFLEXARRAY 1 jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * Forward declaration to prevent an error when the forward reference to jpayne@69: * Command is encountered in the Proc and ImportRef types declared below. jpayne@69: */ jpayne@69: jpayne@69: struct Command; jpayne@69: jpayne@69: /* jpayne@69: * The variable-length structure below describes a local variable of a jpayne@69: * procedure that was recognized by the compiler. These variables have a name, jpayne@69: * an element in the array of compiler-assigned local variables in the jpayne@69: * procedure's call frame, and various other items of information. If the jpayne@69: * local variable is a formal argument, it may also have a default value. The jpayne@69: * compiler can't recognize local variables whose names are expressions (these jpayne@69: * names are only known at runtime when the expressions are evaluated) or jpayne@69: * local variables that are created as a result of an "upvar" or "uplevel" jpayne@69: * command. These other local variables are kept separately in a hash table in jpayne@69: * the call frame. jpayne@69: */ jpayne@69: jpayne@69: typedef struct CompiledLocal { jpayne@69: struct CompiledLocal *nextPtr; jpayne@69: /* Next compiler-recognized local variable for jpayne@69: * this procedure, or NULL if this is the last jpayne@69: * local. */ jpayne@69: int nameLength; /* The number of bytes in local variable's name. jpayne@69: * Among others used to speed up var lookups. */ jpayne@69: int frameIndex; /* Index in the array of compiler-assigned jpayne@69: * variables in the procedure call frame. */ jpayne@69: int flags; /* Flag bits for the local variable. Same as jpayne@69: * the flags for the Var structure above, jpayne@69: * although only VAR_ARGUMENT, VAR_TEMPORARY, jpayne@69: * and VAR_RESOLVED make sense. */ jpayne@69: Tcl_Obj *defValuePtr; /* Pointer to the default value of an jpayne@69: * argument, if any. NULL if not an argument jpayne@69: * or, if an argument, no default value. */ jpayne@69: Tcl_ResolvedVarInfo *resolveInfo; jpayne@69: /* Customized variable resolution info jpayne@69: * supplied by the Tcl_ResolveCompiledVarProc jpayne@69: * associated with a namespace. Each variable jpayne@69: * is marked by a unique ClientData tag during jpayne@69: * compilation, and that same tag is used to jpayne@69: * find the variable at runtime. */ jpayne@69: char name[TCLFLEXARRAY]; /* Name of the local variable starts here. If jpayne@69: * the name is NULL, this will just be '\0'. jpayne@69: * The actual size of this field will be large jpayne@69: * enough to hold the name. MUST BE THE LAST jpayne@69: * FIELD IN THE STRUCTURE! */ jpayne@69: } CompiledLocal; jpayne@69: jpayne@69: /* jpayne@69: * The structure below defines a command procedure, which consists of a jpayne@69: * collection of Tcl commands plus information about arguments and other local jpayne@69: * variables recognized at compile time. jpayne@69: */ jpayne@69: jpayne@69: typedef struct Proc { jpayne@69: struct Interp *iPtr; /* Interpreter for which this command is jpayne@69: * defined. */ jpayne@69: int refCount; /* Reference count: 1 if still present in jpayne@69: * command table plus 1 for each call to the jpayne@69: * procedure that is currently active. This jpayne@69: * structure can be freed when refCount jpayne@69: * becomes zero. */ jpayne@69: struct Command *cmdPtr; /* Points to the Command structure for this jpayne@69: * procedure. This is used to get the jpayne@69: * namespace in which to execute the jpayne@69: * procedure. */ jpayne@69: Tcl_Obj *bodyPtr; /* Points to the ByteCode object for jpayne@69: * procedure's body command. */ jpayne@69: int numArgs; /* Number of formal parameters. */ jpayne@69: int numCompiledLocals; /* Count of local variables recognized by the jpayne@69: * compiler including arguments and jpayne@69: * temporaries. */ jpayne@69: CompiledLocal *firstLocalPtr; jpayne@69: /* Pointer to first of the procedure's jpayne@69: * compiler-allocated local variables, or NULL jpayne@69: * if none. The first numArgs entries in this jpayne@69: * list describe the procedure's formal jpayne@69: * arguments. */ jpayne@69: CompiledLocal *lastLocalPtr;/* Pointer to the last allocated local jpayne@69: * variable or NULL if none. This has frame jpayne@69: * index (numCompiledLocals-1). */ jpayne@69: } Proc; jpayne@69: jpayne@69: /* jpayne@69: * The type of functions called to process errors found during the execution jpayne@69: * of a procedure (or lambda term or ...). jpayne@69: */ jpayne@69: jpayne@69: typedef void (ProcErrorProc)(Tcl_Interp *interp, Tcl_Obj *procNameObj); jpayne@69: jpayne@69: /* jpayne@69: * The structure below defines a command trace. This is used to allow Tcl jpayne@69: * clients to find out whenever a command is about to be executed. jpayne@69: */ jpayne@69: jpayne@69: typedef struct Trace { jpayne@69: int level; /* Only trace commands at nesting level less jpayne@69: * than or equal to this. */ jpayne@69: Tcl_CmdObjTraceProc *proc; /* Procedure to call to trace command. */ jpayne@69: ClientData clientData; /* Arbitrary value to pass to proc. */ jpayne@69: struct Trace *nextPtr; /* Next in list of traces for this interp. */ jpayne@69: int flags; /* Flags governing the trace - see jpayne@69: * Tcl_CreateObjTrace for details. */ jpayne@69: Tcl_CmdObjTraceDeleteProc *delProc; jpayne@69: /* Procedure to call when trace is deleted. */ jpayne@69: } Trace; jpayne@69: jpayne@69: /* jpayne@69: * When an interpreter trace is active (i.e. its associated procedure is jpayne@69: * executing), one of the following structures is linked into a list jpayne@69: * associated with the interpreter. The information in the structure is needed jpayne@69: * in order for Tcl to behave reasonably if traces are deleted while traces jpayne@69: * are active. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ActiveInterpTrace { jpayne@69: struct ActiveInterpTrace *nextPtr; jpayne@69: /* Next in list of all active command traces jpayne@69: * for the interpreter, or NULL if no more. */ jpayne@69: Trace *nextTracePtr; /* Next trace to check after current trace jpayne@69: * procedure returns; if this trace gets jpayne@69: * deleted, must update pointer to avoid using jpayne@69: * free'd memory. */ jpayne@69: int reverseScan; /* Boolean set true when traces are scanning jpayne@69: * in reverse order. */ jpayne@69: } ActiveInterpTrace; jpayne@69: jpayne@69: /* jpayne@69: * Flag values designating types of execution traces. See tclTrace.c for jpayne@69: * related flag values. jpayne@69: * jpayne@69: * TCL_TRACE_ENTER_EXEC - triggers enter/enterstep traces. jpayne@69: * - passed to Tcl_CreateObjTrace to set up jpayne@69: * "enterstep" traces. jpayne@69: * TCL_TRACE_LEAVE_EXEC - triggers leave/leavestep traces. jpayne@69: * - passed to Tcl_CreateObjTrace to set up jpayne@69: * "leavestep" traces. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_TRACE_ENTER_EXEC 1 jpayne@69: #define TCL_TRACE_LEAVE_EXEC 2 jpayne@69: jpayne@69: /* jpayne@69: * The structure below defines an entry in the assocData hash table which is jpayne@69: * associated with an interpreter. The entry contains a pointer to a function jpayne@69: * to call when the interpreter is deleted, and a pointer to a user-defined jpayne@69: * piece of data. jpayne@69: */ jpayne@69: jpayne@69: typedef struct AssocData { jpayne@69: Tcl_InterpDeleteProc *proc; /* Proc to call when deleting. */ jpayne@69: ClientData clientData; /* Value to pass to proc. */ jpayne@69: } AssocData; jpayne@69: jpayne@69: /* jpayne@69: * The structure below defines a call frame. A call frame defines a naming jpayne@69: * context for a procedure call: its local naming scope (for local variables) jpayne@69: * and its global naming scope (a namespace, perhaps the global :: namespace). jpayne@69: * A call frame can also define the naming context for a namespace eval or jpayne@69: * namespace inscope command: the namespace in which the command's code should jpayne@69: * execute. The Tcl_CallFrame structures exist only while procedures or jpayne@69: * namespace eval/inscope's are being executed, and provide a kind of Tcl call jpayne@69: * stack. jpayne@69: * jpayne@69: * WARNING!! The structure definition must be kept consistent with the jpayne@69: * Tcl_CallFrame structure in tcl.h. If you change one, change the other. jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * Will be grown to contain: pointers to the varnames (allocated at the end), jpayne@69: * plus the init values for each variable (suitable to be memcopied on init) jpayne@69: */ jpayne@69: jpayne@69: typedef struct LocalCache { jpayne@69: int refCount; jpayne@69: int numVars; jpayne@69: Tcl_Obj *varName0; jpayne@69: } LocalCache; jpayne@69: jpayne@69: #define localName(framePtr, i) \ jpayne@69: ((&((framePtr)->localCachePtr->varName0))[(i)]) jpayne@69: jpayne@69: MODULE_SCOPE void TclFreeLocalCache(Tcl_Interp *interp, jpayne@69: LocalCache *localCachePtr); jpayne@69: jpayne@69: typedef struct CallFrame { jpayne@69: Namespace *nsPtr; /* Points to the namespace used to resolve jpayne@69: * commands and global variables. */ jpayne@69: int isProcCallFrame; /* If 0, the frame was pushed to execute a jpayne@69: * namespace command and var references are jpayne@69: * treated as references to namespace vars; jpayne@69: * varTablePtr and compiledLocals are ignored. jpayne@69: * If FRAME_IS_PROC is set, the frame was jpayne@69: * pushed to execute a Tcl procedure and may jpayne@69: * have local vars. */ jpayne@69: int objc; /* This and objv below describe the arguments jpayne@69: * for this procedure call. */ jpayne@69: Tcl_Obj *const *objv; /* Array of argument objects. */ jpayne@69: struct CallFrame *callerPtr; jpayne@69: /* Value of interp->framePtr when this jpayne@69: * procedure was invoked (i.e. next higher in jpayne@69: * stack of all active procedures). */ jpayne@69: struct CallFrame *callerVarPtr; jpayne@69: /* Value of interp->varFramePtr when this jpayne@69: * procedure was invoked (i.e. determines jpayne@69: * variable scoping within caller). Same as jpayne@69: * callerPtr unless an "uplevel" command or jpayne@69: * something equivalent was active in the jpayne@69: * caller). */ jpayne@69: int level; /* Level of this procedure, for "uplevel" jpayne@69: * purposes (i.e. corresponds to nesting of jpayne@69: * callerVarPtr's, not callerPtr's). 1 for jpayne@69: * outermost procedure, 0 for top-level. */ jpayne@69: Proc *procPtr; /* Points to the structure defining the called jpayne@69: * procedure. Used to get information such as jpayne@69: * the number of compiled local variables jpayne@69: * (local variables assigned entries ["slots"] jpayne@69: * in the compiledLocals array below). */ jpayne@69: TclVarHashTable *varTablePtr; jpayne@69: /* Hash table containing local variables not jpayne@69: * recognized by the compiler, or created at jpayne@69: * execution time through, e.g., upvar. jpayne@69: * Initially NULL and created if needed. */ jpayne@69: int numCompiledLocals; /* Count of local variables recognized by the jpayne@69: * compiler including arguments. */ jpayne@69: Var *compiledLocals; /* Points to the array of local variables jpayne@69: * recognized by the compiler. The compiler jpayne@69: * emits code that refers to these variables jpayne@69: * using an index into this array. */ jpayne@69: ClientData clientData; /* Pointer to some context that is used by jpayne@69: * object systems. The meaning of the contents jpayne@69: * of this field is defined by the code that jpayne@69: * sets it, and it should only ever be set by jpayne@69: * the code that is pushing the frame. In that jpayne@69: * case, the code that sets it should also jpayne@69: * have some means of discovering what the jpayne@69: * meaning of the value is, which we do not jpayne@69: * specify. */ jpayne@69: LocalCache *localCachePtr; jpayne@69: Tcl_Obj *tailcallPtr; jpayne@69: /* NULL if no tailcall is scheduled */ jpayne@69: } CallFrame; jpayne@69: jpayne@69: #define FRAME_IS_PROC 0x1 jpayne@69: #define FRAME_IS_LAMBDA 0x2 jpayne@69: #define FRAME_IS_METHOD 0x4 /* The frame is a method body, and the frame's jpayne@69: * clientData field contains a CallContext jpayne@69: * reference. Part of TIP#257. */ jpayne@69: #define FRAME_IS_OO_DEFINE 0x8 /* The frame is part of the inside workings of jpayne@69: * the [oo::define] command; the clientData jpayne@69: * field contains an Object reference that has jpayne@69: * been confirmed to refer to a class. Part of jpayne@69: * TIP#257. */ jpayne@69: jpayne@69: /* jpayne@69: * TIP #280 jpayne@69: * The structure below defines a command frame. A command frame provides jpayne@69: * location information for all commands executing a tcl script (source, eval, jpayne@69: * uplevel, procedure bodies, ...). The runtime structure essentially contains jpayne@69: * the stack trace as it would be if the currently executing command were to jpayne@69: * throw an error. jpayne@69: * jpayne@69: * For commands where it makes sense it refers to the associated CallFrame as jpayne@69: * well. jpayne@69: * jpayne@69: * The structures are chained in a single list, with the top of the stack jpayne@69: * anchored in the Interp structure. jpayne@69: * jpayne@69: * Instances can be allocated on the C stack, or the heap, the former making jpayne@69: * cleanup a bit simpler. jpayne@69: */ jpayne@69: jpayne@69: typedef struct CmdFrame { jpayne@69: /* jpayne@69: * General data. Always available. jpayne@69: */ jpayne@69: jpayne@69: int type; /* Values see below. */ jpayne@69: int level; /* Number of frames in stack, prevent O(n) jpayne@69: * scan of list. */ jpayne@69: int *line; /* Lines the words of the command start on. */ jpayne@69: int nline; jpayne@69: CallFrame *framePtr; /* Procedure activation record, may be jpayne@69: * NULL. */ jpayne@69: struct CmdFrame *nextPtr; /* Link to calling frame. */ jpayne@69: /* jpayne@69: * Data needed for Eval vs TEBC jpayne@69: * jpayne@69: * EXECUTION CONTEXTS and usage of CmdFrame jpayne@69: * jpayne@69: * Field TEBC EvalEx jpayne@69: * ======= ==== ====== jpayne@69: * level yes yes jpayne@69: * type BC/PREBC SRC/EVAL jpayne@69: * line0 yes yes jpayne@69: * framePtr yes yes jpayne@69: * ======= ==== ====== jpayne@69: * jpayne@69: * ======= ==== ========= union data jpayne@69: * line1 - yes jpayne@69: * line3 - yes jpayne@69: * path - yes jpayne@69: * ------- ---- ------ jpayne@69: * codePtr yes - jpayne@69: * pc yes - jpayne@69: * ======= ==== ====== jpayne@69: * jpayne@69: * ======= ==== ========= union cmd jpayne@69: * str.cmd yes yes jpayne@69: * str.len yes yes jpayne@69: * ------- ---- ------ jpayne@69: */ jpayne@69: jpayne@69: union { jpayne@69: struct { jpayne@69: Tcl_Obj *path; /* Path of the sourced file the command is jpayne@69: * in. */ jpayne@69: } eval; jpayne@69: struct { jpayne@69: const void *codePtr;/* Byte code currently executed... */ jpayne@69: const char *pc; /* ... and instruction pointer. */ jpayne@69: } tebc; jpayne@69: } data; jpayne@69: Tcl_Obj *cmdObj; jpayne@69: const char *cmd; /* The executed command, if possible... */ jpayne@69: int len; /* ... and its length. */ jpayne@69: const struct CFWordBC *litarg; jpayne@69: /* Link to set of literal arguments which have jpayne@69: * ben pushed on the lineLABCPtr stack by jpayne@69: * TclArgumentBCEnter(). These will be removed jpayne@69: * by TclArgumentBCRelease. */ jpayne@69: } CmdFrame; jpayne@69: jpayne@69: typedef struct CFWord { jpayne@69: CmdFrame *framePtr; /* CmdFrame to access. */ jpayne@69: int word; /* Index of the word in the command. */ jpayne@69: int refCount; /* Number of times the word is on the jpayne@69: * stack. */ jpayne@69: } CFWord; jpayne@69: jpayne@69: typedef struct CFWordBC { jpayne@69: CmdFrame *framePtr; /* CmdFrame to access. */ jpayne@69: int pc; /* Instruction pointer of a command in jpayne@69: * ExtCmdLoc.loc[.] */ jpayne@69: int word; /* Index of word in jpayne@69: * ExtCmdLoc.loc[cmd]->line[.] */ jpayne@69: struct CFWordBC *prevPtr; /* Previous entry in stack for same Tcl_Obj. */ jpayne@69: struct CFWordBC *nextPtr; /* Next entry for same command call. See jpayne@69: * CmdFrame litarg field for the list start. */ jpayne@69: Tcl_Obj *obj; /* Back reference to hashtable key */ jpayne@69: } CFWordBC; jpayne@69: jpayne@69: /* jpayne@69: * Structure to record the locations of invisible continuation lines in jpayne@69: * literal scripts, as character offset from the beginning of the script. Both jpayne@69: * compiler and direct evaluator use this information to adjust their line jpayne@69: * counters when tracking through the script, because when it is invoked the jpayne@69: * continuation line marker as a whole has been removed already, meaning that jpayne@69: * the \n which was part of it is gone as well, breaking regular line jpayne@69: * tracking. jpayne@69: * jpayne@69: * These structures are allocated and filled by both the function jpayne@69: * TclSubstTokens() in the file "tclParse.c" and its caller TclEvalEx() in the jpayne@69: * file "tclBasic.c", and stored in the thread-global hashtable "lineCLPtr" in jpayne@69: * file "tclObj.c". They are used by the functions TclSetByteCodeFromAny() and jpayne@69: * TclCompileScript(), both found in the file "tclCompile.c". Their memory is jpayne@69: * released by the function TclFreeObj(), in the file "tclObj.c", and also by jpayne@69: * the function TclThreadFinalizeObjects(), in the same file. jpayne@69: */ jpayne@69: jpayne@69: #define CLL_END (-1) jpayne@69: jpayne@69: typedef struct ContLineLoc { jpayne@69: int num; /* Number of entries in loc, not counting the jpayne@69: * final -1 marker entry. */ jpayne@69: int loc[TCLFLEXARRAY];/* Table of locations, as character offsets. jpayne@69: * The table is allocated as part of the jpayne@69: * structure, extending behind the nominal end jpayne@69: * of the structure. An entry containing the jpayne@69: * value -1 is put after the last location, as jpayne@69: * end-marker/sentinel. */ jpayne@69: } ContLineLoc; jpayne@69: jpayne@69: /* jpayne@69: * The following macros define the allowed values for the type field of the jpayne@69: * CmdFrame structure above. Some of the values occur only in the extended jpayne@69: * location data referenced via the 'baseLocPtr'. jpayne@69: * jpayne@69: * TCL_LOCATION_EVAL : Frame is for a script evaluated by EvalEx. jpayne@69: * TCL_LOCATION_BC : Frame is for bytecode. jpayne@69: * TCL_LOCATION_PREBC : Frame is for precompiled bytecode. jpayne@69: * TCL_LOCATION_SOURCE : Frame is for a script evaluated by EvalEx, from a jpayne@69: * sourced file. jpayne@69: * TCL_LOCATION_PROC : Frame is for bytecode of a procedure. jpayne@69: * jpayne@69: * A TCL_LOCATION_BC type in a frame can be overridden by _SOURCE and _PROC jpayne@69: * types, per the context of the byte code in execution. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_LOCATION_EVAL (0) /* Location in a dynamic eval script. */ jpayne@69: #define TCL_LOCATION_BC (2) /* Location in byte code. */ jpayne@69: #define TCL_LOCATION_PREBC (3) /* Location in precompiled byte code, no jpayne@69: * location. */ jpayne@69: #define TCL_LOCATION_SOURCE (4) /* Location in a file. */ jpayne@69: #define TCL_LOCATION_PROC (5) /* Location in a dynamic proc. */ jpayne@69: #define TCL_LOCATION_LAST (6) /* Number of values in the enum. */ jpayne@69: jpayne@69: /* jpayne@69: * Structure passed to describe procedure-like "procedures" that are not jpayne@69: * procedures (e.g. a lambda) so that their details can be reported correctly jpayne@69: * by [info frame]. Contains a sub-structure for each extra field. jpayne@69: */ jpayne@69: jpayne@69: typedef Tcl_Obj * (GetFrameInfoValueProc)(ClientData clientData); jpayne@69: typedef struct { jpayne@69: const char *name; /* Name of this field. */ jpayne@69: GetFrameInfoValueProc *proc; /* Function to generate a Tcl_Obj* from the jpayne@69: * clientData, or just use the clientData jpayne@69: * directly (after casting) if NULL. */ jpayne@69: ClientData clientData; /* Context for above function, or Tcl_Obj* if jpayne@69: * proc field is NULL. */ jpayne@69: } ExtraFrameInfoField; jpayne@69: typedef struct { jpayne@69: int length; /* Length of array. */ jpayne@69: ExtraFrameInfoField fields[2]; jpayne@69: /* Really as long as necessary, but this is jpayne@69: * long enough for nearly anything. */ jpayne@69: } ExtraFrameInfo; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures and procedures related to TclHandles, which are a very jpayne@69: * lightweight method of preserving enough information to determine if an jpayne@69: * arbitrary malloc'd block has been deleted. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: typedef void **TclHandle; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Experimental flag value passed to Tcl_GetRegExpFromObj. Intended for use jpayne@69: * only by Expect. It will probably go away in a later release. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TCL_REG_BOSONLY 002000 /* Prepend \A to pattern so it only matches at jpayne@69: * the beginning of the string. */ jpayne@69: jpayne@69: /* jpayne@69: * These are a thin layer over TclpThreadKeyDataGet and TclpThreadKeyDataSet jpayne@69: * when threads are used, or an emulation if there are no threads. These are jpayne@69: * really internal and Tcl clients should use Tcl_GetThreadData. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE void * TclThreadDataKeyGet(Tcl_ThreadDataKey *keyPtr); jpayne@69: MODULE_SCOPE void TclThreadDataKeySet(Tcl_ThreadDataKey *keyPtr, jpayne@69: void *data); jpayne@69: jpayne@69: /* jpayne@69: * This is a convenience macro used to initialize a thread local storage ptr. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_TSD_INIT(keyPtr) \ jpayne@69: (ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData)) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to bytecode compilation and execution. These are jpayne@69: * used primarily in tclCompile.c, tclExecute.c, and tclBasic.c. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * Forward declaration to prevent errors when the forward references to jpayne@69: * Tcl_Parse and CompileEnv are encountered in the procedure type CompileProc jpayne@69: * declared below. jpayne@69: */ jpayne@69: jpayne@69: struct CompileEnv; jpayne@69: jpayne@69: /* jpayne@69: * The type of procedures called by the Tcl bytecode compiler to compile jpayne@69: * commands. Pointers to these procedures are kept in the Command structure jpayne@69: * describing each command. The integer value returned by a CompileProc must jpayne@69: * be one of the following: jpayne@69: * jpayne@69: * TCL_OK Compilation completed normally. jpayne@69: * TCL_ERROR Compilation could not be completed. This can be just a jpayne@69: * judgment by the CompileProc that the command is too jpayne@69: * complex to compile effectively, or it can indicate jpayne@69: * that in the current state of the interp, the command jpayne@69: * would raise an error. The bytecode compiler will not jpayne@69: * do any error reporting at compiler time. Error jpayne@69: * reporting is deferred until the actual runtime, jpayne@69: * because by then changes in the interp state may allow jpayne@69: * the command to be successfully evaluated. jpayne@69: * TCL_OUT_LINE_COMPILE A source-compatible alias for TCL_ERROR, kept for the jpayne@69: * sake of old code only. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_OUT_LINE_COMPILE TCL_ERROR jpayne@69: jpayne@69: typedef int (CompileProc)(Tcl_Interp *interp, Tcl_Parse *parsePtr, jpayne@69: struct Command *cmdPtr, struct CompileEnv *compEnvPtr); jpayne@69: jpayne@69: /* jpayne@69: * The type of procedure called from the compilation hook point in jpayne@69: * SetByteCodeFromAny. jpayne@69: */ jpayne@69: jpayne@69: typedef int (CompileHookProc)(Tcl_Interp *interp, jpayne@69: struct CompileEnv *compEnvPtr, ClientData clientData); jpayne@69: jpayne@69: /* jpayne@69: * The data structure for a (linked list of) execution stacks. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ExecStack { jpayne@69: struct ExecStack *prevPtr; jpayne@69: struct ExecStack *nextPtr; jpayne@69: Tcl_Obj **markerPtr; jpayne@69: Tcl_Obj **endPtr; jpayne@69: Tcl_Obj **tosPtr; jpayne@69: Tcl_Obj *stackWords[TCLFLEXARRAY]; jpayne@69: } ExecStack; jpayne@69: jpayne@69: /* jpayne@69: * The data structure defining the execution environment for ByteCode's. jpayne@69: * There is one ExecEnv structure per Tcl interpreter. It holds the evaluation jpayne@69: * stack that holds command operands and results. The stack grows towards jpayne@69: * increasing addresses. The member stackPtr points to the stackItems of the jpayne@69: * currently active execution stack. jpayne@69: */ jpayne@69: jpayne@69: typedef struct CorContext { jpayne@69: struct CallFrame *framePtr; jpayne@69: struct CallFrame *varFramePtr; jpayne@69: struct CmdFrame *cmdFramePtr; /* See Interp.cmdFramePtr */ jpayne@69: Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ jpayne@69: } CorContext; jpayne@69: jpayne@69: typedef struct CoroutineData { jpayne@69: struct Command *cmdPtr; /* The command handle for the coroutine. */ jpayne@69: struct ExecEnv *eePtr; /* The special execution environment (stacks, jpayne@69: * etc.) for the coroutine. */ jpayne@69: struct ExecEnv *callerEEPtr;/* The execution environment for the caller of jpayne@69: * the coroutine, which might be the jpayne@69: * interpreter global environment or another jpayne@69: * coroutine. */ jpayne@69: CorContext caller; jpayne@69: CorContext running; jpayne@69: Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */ jpayne@69: void *stackLevel; jpayne@69: int auxNumLevels; /* While the coroutine is running the jpayne@69: * numLevels of the create/resume command is jpayne@69: * stored here; for suspended coroutines it jpayne@69: * holds the nesting numLevels at yield. */ jpayne@69: int nargs; /* Number of args required for resuming this jpayne@69: * coroutine; -2 means "0 or 1" (default), -1 jpayne@69: * means "any" */ jpayne@69: } CoroutineData; jpayne@69: jpayne@69: typedef struct ExecEnv { jpayne@69: ExecStack *execStackPtr; /* Points to the first item in the evaluation jpayne@69: * stack on the heap. */ jpayne@69: Tcl_Obj *constants[2]; /* Pointers to constant "0" and "1" objs. */ jpayne@69: struct Tcl_Interp *interp; jpayne@69: struct NRE_callback *callbackPtr; jpayne@69: /* Top callback in NRE's stack. */ jpayne@69: struct CoroutineData *corPtr; jpayne@69: int rewind; jpayne@69: } ExecEnv; jpayne@69: jpayne@69: #define COR_IS_SUSPENDED(corPtr) \ jpayne@69: ((corPtr)->stackLevel == NULL) jpayne@69: jpayne@69: /* jpayne@69: * The definitions for the LiteralTable and LiteralEntry structures. Each jpayne@69: * interpreter contains a LiteralTable. It is used to reduce the storage jpayne@69: * needed for all the Tcl objects that hold the literals of scripts compiled jpayne@69: * by the interpreter. A literal's object is shared by all the ByteCodes that jpayne@69: * refer to the literal. Each distinct literal has one LiteralEntry entry in jpayne@69: * the LiteralTable. A literal table is a specialized hash table that is jpayne@69: * indexed by the literal's string representation, which may contain null jpayne@69: * characters. jpayne@69: * jpayne@69: * Note that we reduce the space needed for literals by sharing literal jpayne@69: * objects both within a ByteCode (each ByteCode contains a local jpayne@69: * LiteralTable) and across all an interpreter's ByteCodes (with the jpayne@69: * interpreter's global LiteralTable). jpayne@69: */ jpayne@69: jpayne@69: typedef struct LiteralEntry { jpayne@69: struct LiteralEntry *nextPtr; jpayne@69: /* Points to next entry in this hash bucket or jpayne@69: * NULL if end of chain. */ jpayne@69: Tcl_Obj *objPtr; /* Points to Tcl object that holds the jpayne@69: * literal's bytes and length. */ jpayne@69: int refCount; /* If in an interpreter's global literal jpayne@69: * table, the number of ByteCode structures jpayne@69: * that share the literal object; the literal jpayne@69: * entry can be freed when refCount drops to jpayne@69: * 0. If in a local literal table, -1. */ jpayne@69: Namespace *nsPtr; /* Namespace in which this literal is used. We jpayne@69: * try to avoid sharing literal non-FQ command jpayne@69: * names among different namespaces to reduce jpayne@69: * shimmering. */ jpayne@69: } LiteralEntry; jpayne@69: jpayne@69: typedef struct LiteralTable { jpayne@69: LiteralEntry **buckets; /* Pointer to bucket array. Each element jpayne@69: * points to first entry in bucket's hash jpayne@69: * chain, or NULL. */ jpayne@69: LiteralEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; jpayne@69: /* Bucket array used for small tables to avoid jpayne@69: * mallocs and frees. */ jpayne@69: int numBuckets; /* Total number of buckets allocated at jpayne@69: * **buckets. */ jpayne@69: int numEntries; /* Total number of entries present in jpayne@69: * table. */ jpayne@69: int rebuildSize; /* Enlarge table when numEntries gets to be jpayne@69: * this large. */ jpayne@69: int mask; /* Mask value used in hashing function. */ jpayne@69: } LiteralTable; jpayne@69: jpayne@69: /* jpayne@69: * The following structure defines for each Tcl interpreter various jpayne@69: * statistics-related information about the bytecode compiler and jpayne@69: * interpreter's operation in that interpreter. jpayne@69: */ jpayne@69: jpayne@69: #ifdef TCL_COMPILE_STATS jpayne@69: typedef struct ByteCodeStats { jpayne@69: long numExecutions; /* Number of ByteCodes executed. */ jpayne@69: long numCompilations; /* Number of ByteCodes created. */ jpayne@69: long numByteCodesFreed; /* Number of ByteCodes destroyed. */ jpayne@69: long instructionCount[256]; /* Number of times each instruction was jpayne@69: * executed. */ jpayne@69: jpayne@69: double totalSrcBytes; /* Total source bytes ever compiled. */ jpayne@69: double totalByteCodeBytes; /* Total bytes for all ByteCodes. */ jpayne@69: double currentSrcBytes; /* Src bytes for all current ByteCodes. */ jpayne@69: double currentByteCodeBytes;/* Code bytes in all current ByteCodes. */ jpayne@69: jpayne@69: long srcCount[32]; /* Source size distribution: # of srcs of jpayne@69: * size [2**(n-1)..2**n), n in [0..32). */ jpayne@69: long byteCodeCount[32]; /* ByteCode size distribution. */ jpayne@69: long lifetimeCount[32]; /* ByteCode lifetime distribution (ms). */ jpayne@69: jpayne@69: double currentInstBytes; /* Instruction bytes-current ByteCodes. */ jpayne@69: double currentLitBytes; /* Current literal bytes. */ jpayne@69: double currentExceptBytes; /* Current exception table bytes. */ jpayne@69: double currentAuxBytes; /* Current auxiliary information bytes. */ jpayne@69: double currentCmdMapBytes; /* Current src<->code map bytes. */ jpayne@69: jpayne@69: long numLiteralsCreated; /* Total literal objects ever compiled. */ jpayne@69: double totalLitStringBytes; /* Total string bytes in all literals. */ jpayne@69: double currentLitStringBytes; jpayne@69: /* String bytes in current literals. */ jpayne@69: long literalCount[32]; /* Distribution of literal string sizes. */ jpayne@69: } ByteCodeStats; jpayne@69: #endif /* TCL_COMPILE_STATS */ jpayne@69: jpayne@69: /* jpayne@69: * Structure used in implementation of those core ensembles which are jpayne@69: * partially compiled. Used as an array of these, with a terminating field jpayne@69: * whose 'name' is NULL. jpayne@69: */ jpayne@69: jpayne@69: typedef struct { jpayne@69: const char *name; /* The name of the subcommand. */ jpayne@69: Tcl_ObjCmdProc *proc; /* The implementation of the subcommand. */ jpayne@69: CompileProc *compileProc; /* The compiler for the subcommand. */ jpayne@69: Tcl_ObjCmdProc *nreProc; /* NRE implementation of this command. */ jpayne@69: ClientData clientData; /* Any clientData to give the command. */ jpayne@69: int unsafe; /* Whether this command is to be hidden by jpayne@69: * default in a safe interpreter. */ jpayne@69: } EnsembleImplMap; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to commands. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * An imported command is created in an namespace when it imports a "real" jpayne@69: * command from another namespace. An imported command has a Command structure jpayne@69: * that points (via its ClientData value) to the "real" Command structure in jpayne@69: * the source namespace's command table. The real command records all the jpayne@69: * imported commands that refer to it in a list of ImportRef structures so jpayne@69: * that they can be deleted when the real command is deleted. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ImportRef { jpayne@69: struct Command *importedCmdPtr; jpayne@69: /* Points to the imported command created in jpayne@69: * an importing namespace; this command jpayne@69: * redirects its invocations to the "real" jpayne@69: * command. */ jpayne@69: struct ImportRef *nextPtr; /* Next element on the linked list of imported jpayne@69: * commands that refer to the "real" command. jpayne@69: * The real command deletes these imported jpayne@69: * commands on this list when it is jpayne@69: * deleted. */ jpayne@69: } ImportRef; jpayne@69: jpayne@69: /* jpayne@69: * Data structure used as the ClientData of imported commands: commands jpayne@69: * created in an namespace when it imports a "real" command from another jpayne@69: * namespace. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ImportedCmdData { jpayne@69: struct Command *realCmdPtr; /* "Real" command that this imported command jpayne@69: * refers to. */ jpayne@69: struct Command *selfPtr; /* Pointer to this imported command. Needed jpayne@69: * only when deleting it in order to remove it jpayne@69: * from the real command's linked list of jpayne@69: * imported commands that refer to it. */ jpayne@69: } ImportedCmdData; jpayne@69: jpayne@69: /* jpayne@69: * A Command structure exists for each command in a namespace. The Tcl_Command jpayne@69: * opaque type actually refers to these structures. jpayne@69: */ jpayne@69: jpayne@69: typedef struct Command { jpayne@69: Tcl_HashEntry *hPtr; /* Pointer to the hash table entry that refers jpayne@69: * to this command. The hash table is either a jpayne@69: * namespace's command table or an jpayne@69: * interpreter's hidden command table. This jpayne@69: * pointer is used to get a command's name jpayne@69: * from its Tcl_Command handle. NULL means jpayne@69: * that the hash table entry has been removed jpayne@69: * already (this can happen if deleteProc jpayne@69: * causes the command to be deleted or jpayne@69: * recreated). */ jpayne@69: Namespace *nsPtr; /* Points to the namespace containing this jpayne@69: * command. */ jpayne@69: int refCount; /* 1 if in command hashtable plus 1 for each jpayne@69: * reference from a CmdName Tcl object jpayne@69: * representing a command's name in a ByteCode jpayne@69: * instruction sequence. This structure can be jpayne@69: * freed when refCount becomes zero. */ jpayne@69: int cmdEpoch; /* Incremented to invalidate any references jpayne@69: * that point to this command when it is jpayne@69: * renamed, deleted, hidden, or exposed. */ jpayne@69: CompileProc *compileProc; /* Procedure called to compile command. NULL jpayne@69: * if no compile proc exists for command. */ jpayne@69: Tcl_ObjCmdProc *objProc; /* Object-based command procedure. */ jpayne@69: ClientData objClientData; /* Arbitrary value passed to object proc. */ jpayne@69: Tcl_CmdProc *proc; /* String-based command procedure. */ jpayne@69: ClientData clientData; /* Arbitrary value passed to string proc. */ jpayne@69: Tcl_CmdDeleteProc *deleteProc; jpayne@69: /* Procedure invoked when deleting command to, jpayne@69: * e.g., free all client data. */ jpayne@69: ClientData deleteData; /* Arbitrary value passed to deleteProc. */ jpayne@69: int flags; /* Miscellaneous bits of information about jpayne@69: * command. See below for definitions. */ jpayne@69: ImportRef *importRefPtr; /* List of each imported Command created in jpayne@69: * another namespace when this command is jpayne@69: * imported. These imported commands redirect jpayne@69: * invocations back to this command. The list jpayne@69: * is used to remove all those imported jpayne@69: * commands when deleting this "real" jpayne@69: * command. */ jpayne@69: CommandTrace *tracePtr; /* First in list of all traces set for this jpayne@69: * command. */ jpayne@69: Tcl_ObjCmdProc *nreProc; /* NRE implementation of this command. */ jpayne@69: } Command; jpayne@69: jpayne@69: /* jpayne@69: * Flag bits for commands. jpayne@69: * jpayne@69: * CMD_IS_DELETED - Means that the command is in the process of jpayne@69: * being deleted (its deleteProc is currently jpayne@69: * executing). Other attempts to delete the jpayne@69: * command should be ignored. jpayne@69: * CMD_TRACE_ACTIVE - 1 means that trace processing is currently jpayne@69: * underway for a rename/delete change. See the jpayne@69: * two flags below for which is currently being jpayne@69: * processed. jpayne@69: * CMD_HAS_EXEC_TRACES - 1 means that this command has at least one jpayne@69: * execution trace (as opposed to simple jpayne@69: * delete/rename traces) in its tracePtr list. jpayne@69: * CMD_COMPILES_EXPANDED - 1 means that this command has a compiler that jpayne@69: * can handle expansion (provided it is not the jpayne@69: * first word). jpayne@69: * TCL_TRACE_RENAME - A rename trace is in progress. Further jpayne@69: * recursive renames will not be traced. jpayne@69: * TCL_TRACE_DELETE - A delete trace is in progress. Further jpayne@69: * recursive deletes will not be traced. jpayne@69: * (these last two flags are defined in tcl.h) jpayne@69: */ jpayne@69: jpayne@69: #define CMD_IS_DELETED 0x01 jpayne@69: #define CMD_TRACE_ACTIVE 0x02 jpayne@69: #define CMD_HAS_EXEC_TRACES 0x04 jpayne@69: #define CMD_COMPILES_EXPANDED 0x08 jpayne@69: #define CMD_REDEF_IN_PROGRESS 0x10 jpayne@69: #define CMD_VIA_RESOLVER 0x20 jpayne@69: #define CMD_DEAD 0x40 jpayne@69: jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to name resolution procedures. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * The interpreter keeps a linked list of name resolution schemes. The scheme jpayne@69: * for a namespace is consulted first, followed by the list of schemes in an jpayne@69: * interpreter, followed by the default name resolution in Tcl. Schemes are jpayne@69: * added/removed from the interpreter's list by calling Tcl_AddInterpResolver jpayne@69: * and Tcl_RemoveInterpResolver. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ResolverScheme { jpayne@69: char *name; /* Name identifying this scheme. */ jpayne@69: Tcl_ResolveCmdProc *cmdResProc; jpayne@69: /* Procedure handling command name jpayne@69: * resolution. */ jpayne@69: Tcl_ResolveVarProc *varResProc; jpayne@69: /* Procedure handling variable name resolution jpayne@69: * for variables that can only be handled at jpayne@69: * runtime. */ jpayne@69: Tcl_ResolveCompiledVarProc *compiledVarResProc; jpayne@69: /* Procedure handling variable name resolution jpayne@69: * at compile time. */ jpayne@69: jpayne@69: struct ResolverScheme *nextPtr; jpayne@69: /* Pointer to next record in linked list. */ jpayne@69: } ResolverScheme; jpayne@69: jpayne@69: /* jpayne@69: * Forward declaration of the TIP#143 limit handler structure. jpayne@69: */ jpayne@69: jpayne@69: typedef struct LimitHandler LimitHandler; jpayne@69: jpayne@69: /* jpayne@69: * TIP #268. jpayne@69: * Values for the selection mode, i.e the package require preferences. jpayne@69: */ jpayne@69: jpayne@69: enum PkgPreferOptions { jpayne@69: PKG_PREFER_LATEST, PKG_PREFER_STABLE jpayne@69: }; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * This structure shadows the first few fields of the memory cache for the jpayne@69: * allocator defined in tclThreadAlloc.c; it has to be kept in sync with the jpayne@69: * definition there. jpayne@69: * Some macros require knowledge of some fields in the struct in order to jpayne@69: * avoid hitting the TSD unnecessarily. In order to facilitate this, a pointer jpayne@69: * to the relevant fields is kept in the allocCache field in struct Interp. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: typedef struct AllocCache { jpayne@69: struct Cache *nextPtr; /* Linked list of cache entries. */ jpayne@69: Tcl_ThreadId owner; /* Which thread's cache is this? */ jpayne@69: Tcl_Obj *firstObjPtr; /* List of free objects for thread. */ jpayne@69: int numObjects; /* Number of objects for thread. */ jpayne@69: } AllocCache; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * This structure defines an interpreter, which is a collection of commands jpayne@69: * plus other state information related to interpreting commands, such as jpayne@69: * variable storage. Primary responsibility for this data structure is in jpayne@69: * tclBasic.c, but almost every Tcl source file uses something in here. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: typedef struct Interp { jpayne@69: /* jpayne@69: * Note: the first three fields must match exactly the fields in a jpayne@69: * Tcl_Interp struct (see tcl.h). If you change one, be sure to change the jpayne@69: * other. jpayne@69: * jpayne@69: * The interpreter's result is held in both the string and the jpayne@69: * objResultPtr fields. These fields hold, respectively, the result's jpayne@69: * string or object value. The interpreter's result is always in the jpayne@69: * result field if that is non-empty, otherwise it is in objResultPtr. jpayne@69: * The two fields are kept consistent unless some C code sets jpayne@69: * interp->result directly. Programs should not access result and jpayne@69: * objResultPtr directly; instead, they should always get and set the jpayne@69: * result using procedures such as Tcl_SetObjResult, Tcl_GetObjResult, and jpayne@69: * Tcl_GetStringResult. See the SetResult man page for details. jpayne@69: */ jpayne@69: jpayne@69: char *result; /* If the last command returned a string jpayne@69: * result, this points to it. Should not be jpayne@69: * accessed directly; see comment above. */ jpayne@69: Tcl_FreeProc *freeProc; /* Zero means a string result is statically jpayne@69: * allocated. TCL_DYNAMIC means string result jpayne@69: * was allocated with ckalloc and should be jpayne@69: * freed with ckfree. Other values give jpayne@69: * address of procedure to invoke to free the jpayne@69: * string result. Tcl_Eval must free it before jpayne@69: * executing next command. */ jpayne@69: int errorLine; /* When TCL_ERROR is returned, this gives the jpayne@69: * line number in the command where the error jpayne@69: * occurred (1 means first line). */ jpayne@69: const struct TclStubs *stubTable; jpayne@69: /* Pointer to the exported Tcl stub table. On jpayne@69: * previous versions of Tcl this is a pointer jpayne@69: * to the objResultPtr or a pointer to a jpayne@69: * buckets array in a hash table. We therefore jpayne@69: * have to do some careful checking before we jpayne@69: * can use this. */ jpayne@69: jpayne@69: TclHandle handle; /* Handle used to keep track of when this jpayne@69: * interp is deleted. */ jpayne@69: jpayne@69: Namespace *globalNsPtr; /* The interpreter's global namespace. */ jpayne@69: Tcl_HashTable *hiddenCmdTablePtr; jpayne@69: /* Hash table used by tclBasic.c to keep track jpayne@69: * of hidden commands on a per-interp jpayne@69: * basis. */ jpayne@69: ClientData interpInfo; /* Information used by tclInterp.c to keep jpayne@69: * track of parent/child interps on a jpayne@69: * per-interp basis. */ jpayne@69: union { jpayne@69: void (*optimizer)(void *envPtr); jpayne@69: Tcl_HashTable unused2; /* No longer used (was mathFuncTable). The jpayne@69: * unused space in interp was repurposed for jpayne@69: * pluggable bytecode optimizers. The core jpayne@69: * contains one optimizer, which can be jpayne@69: * selectively overridden by extensions. */ jpayne@69: } extra; jpayne@69: jpayne@69: /* jpayne@69: * Information related to procedures and variables. See tclProc.c and jpayne@69: * tclVar.c for usage. jpayne@69: */ jpayne@69: jpayne@69: int numLevels; /* Keeps track of how many nested calls to jpayne@69: * Tcl_Eval are in progress for this jpayne@69: * interpreter. It's used to delay deletion of jpayne@69: * the table until all Tcl_Eval invocations jpayne@69: * are completed. */ jpayne@69: int maxNestingDepth; /* If numLevels exceeds this value then Tcl jpayne@69: * assumes that infinite recursion has jpayne@69: * occurred and it generates an error. */ jpayne@69: CallFrame *framePtr; /* Points to top-most in stack of all nested jpayne@69: * procedure invocations. */ jpayne@69: CallFrame *varFramePtr; /* Points to the call frame whose variables jpayne@69: * are currently in use (same as framePtr jpayne@69: * unless an "uplevel" command is jpayne@69: * executing). */ jpayne@69: ActiveVarTrace *activeVarTracePtr; jpayne@69: /* First in list of active traces for interp, jpayne@69: * or NULL if no active traces. */ jpayne@69: int returnCode; /* [return -code] parameter. */ jpayne@69: CallFrame *rootFramePtr; /* Global frame pointer for this jpayne@69: * interpreter. */ jpayne@69: Namespace *lookupNsPtr; /* Namespace to use ONLY on the next jpayne@69: * TCL_EVAL_INVOKE call to Tcl_EvalObjv. */ jpayne@69: jpayne@69: /* jpayne@69: * Information used by Tcl_AppendResult to keep track of partial results. jpayne@69: * See Tcl_AppendResult code for details. jpayne@69: */ jpayne@69: jpayne@69: char *appendResult; /* Storage space for results generated by jpayne@69: * Tcl_AppendResult. Ckalloc-ed. NULL means jpayne@69: * not yet allocated. */ jpayne@69: int appendAvl; /* Total amount of space available at jpayne@69: * partialResult. */ jpayne@69: int appendUsed; /* Number of non-null bytes currently stored jpayne@69: * at partialResult. */ jpayne@69: jpayne@69: /* jpayne@69: * Information about packages. Used only in tclPkg.c. jpayne@69: */ jpayne@69: jpayne@69: Tcl_HashTable packageTable; /* Describes all of the packages loaded in or jpayne@69: * available to this interpreter. Keys are jpayne@69: * package names, values are (Package *) jpayne@69: * pointers. */ jpayne@69: char *packageUnknown; /* Command to invoke during "package require" jpayne@69: * commands for packages that aren't described jpayne@69: * in packageTable. Ckalloc'ed, may be jpayne@69: * NULL. */ jpayne@69: /* jpayne@69: * Miscellaneous information: jpayne@69: */ jpayne@69: jpayne@69: int cmdCount; /* Total number of times a command procedure jpayne@69: * has been called for this interpreter. */ jpayne@69: int evalFlags; /* Flags to control next call to Tcl_Eval. jpayne@69: * Normally zero, but may be set before jpayne@69: * calling Tcl_Eval. See below for valid jpayne@69: * values. */ jpayne@69: int unused1; /* No longer used (was termOffset) */ jpayne@69: LiteralTable literalTable; /* Contains LiteralEntry's describing all Tcl jpayne@69: * objects holding literals of scripts jpayne@69: * compiled by the interpreter. Indexed by the jpayne@69: * string representations of literals. Used to jpayne@69: * avoid creating duplicate objects. */ jpayne@69: int compileEpoch; /* Holds the current "compilation epoch" for jpayne@69: * this interpreter. This is incremented to jpayne@69: * invalidate existing ByteCodes when, e.g., a jpayne@69: * command with a compile procedure is jpayne@69: * redefined. */ jpayne@69: Proc *compiledProcPtr; /* If a procedure is being compiled, a pointer jpayne@69: * to its Proc structure; otherwise, this is jpayne@69: * NULL. Set by ObjInterpProc in tclProc.c and jpayne@69: * used by tclCompile.c to process local jpayne@69: * variables appropriately. */ jpayne@69: ResolverScheme *resolverPtr; jpayne@69: /* Linked list of name resolution schemes jpayne@69: * added to this interpreter. Schemes are jpayne@69: * added and removed by calling jpayne@69: * Tcl_AddInterpResolvers and jpayne@69: * Tcl_RemoveInterpResolver respectively. */ jpayne@69: Tcl_Obj *scriptFile; /* NULL means there is no nested source jpayne@69: * command active; otherwise this points to jpayne@69: * pathPtr of the file being sourced. */ jpayne@69: int flags; /* Various flag bits. See below. */ jpayne@69: long randSeed; /* Seed used for rand() function. */ jpayne@69: Trace *tracePtr; /* List of traces for this interpreter. */ jpayne@69: Tcl_HashTable *assocData; /* Hash table for associating data with this jpayne@69: * interpreter. Cleaned up when this jpayne@69: * interpreter is deleted. */ jpayne@69: struct ExecEnv *execEnvPtr; /* Execution environment for Tcl bytecode jpayne@69: * execution. Contains a pointer to the Tcl jpayne@69: * evaluation stack. */ jpayne@69: Tcl_Obj *emptyObjPtr; /* Points to an object holding an empty jpayne@69: * string. Returned by Tcl_ObjSetVar2 when jpayne@69: * variable traces change a variable in a jpayne@69: * gross way. */ jpayne@69: char resultSpace[TCL_RESULT_SIZE+1]; jpayne@69: /* Static space holding small results. */ jpayne@69: Tcl_Obj *objResultPtr; /* If the last command returned an object jpayne@69: * result, this points to it. Should not be jpayne@69: * accessed directly; see comment above. */ jpayne@69: Tcl_ThreadId threadId; /* ID of thread that owns the interpreter. */ jpayne@69: jpayne@69: ActiveCommandTrace *activeCmdTracePtr; jpayne@69: /* First in list of active command traces for jpayne@69: * interp, or NULL if no active traces. */ jpayne@69: ActiveInterpTrace *activeInterpTracePtr; jpayne@69: /* First in list of active traces for interp, jpayne@69: * or NULL if no active traces. */ jpayne@69: jpayne@69: int tracesForbiddingInline; /* Count of traces (in the list headed by jpayne@69: * tracePtr) that forbid inline bytecode jpayne@69: * compilation. */ jpayne@69: jpayne@69: /* jpayne@69: * Fields used to manage extensible return options (TIP 90). jpayne@69: */ jpayne@69: jpayne@69: Tcl_Obj *returnOpts; /* A dictionary holding the options to the jpayne@69: * last [return] command. */ jpayne@69: jpayne@69: Tcl_Obj *errorInfo; /* errorInfo value (now as a Tcl_Obj). */ jpayne@69: Tcl_Obj *eiVar; /* cached ref to ::errorInfo variable. */ jpayne@69: Tcl_Obj *errorCode; /* errorCode value (now as a Tcl_Obj). */ jpayne@69: Tcl_Obj *ecVar; /* cached ref to ::errorInfo variable. */ jpayne@69: int returnLevel; /* [return -level] parameter. */ jpayne@69: jpayne@69: /* jpayne@69: * Resource limiting framework support (TIP#143). jpayne@69: */ jpayne@69: jpayne@69: struct { jpayne@69: int active; /* Flag values defining which limits have been jpayne@69: * set. */ jpayne@69: int granularityTicker; /* Counter used to determine how often to jpayne@69: * check the limits. */ jpayne@69: int exceeded; /* Which limits have been exceeded, described jpayne@69: * as flag values the same as the 'active' jpayne@69: * field. */ jpayne@69: jpayne@69: int cmdCount; /* Limit for how many commands to execute in jpayne@69: * the interpreter. */ jpayne@69: LimitHandler *cmdHandlers; jpayne@69: /* Handlers to execute when the limit is jpayne@69: * reached. */ jpayne@69: int cmdGranularity; /* Mod factor used to determine how often to jpayne@69: * evaluate the limit check. */ jpayne@69: jpayne@69: Tcl_Time time; /* Time limit for execution within the jpayne@69: * interpreter. */ jpayne@69: LimitHandler *timeHandlers; jpayne@69: /* Handlers to execute when the limit is jpayne@69: * reached. */ jpayne@69: int timeGranularity; /* Mod factor used to determine how often to jpayne@69: * evaluate the limit check. */ jpayne@69: Tcl_TimerToken timeEvent; jpayne@69: /* Handle for a timer callback that will occur jpayne@69: * when the time-limit is exceeded. */ jpayne@69: jpayne@69: Tcl_HashTable callbacks;/* Mapping from (interp,type) pair to data jpayne@69: * used to install a limit handler callback to jpayne@69: * run in _this_ interp when the limit is jpayne@69: * exceeded. */ jpayne@69: } limit; jpayne@69: jpayne@69: /* jpayne@69: * Information for improved default error generation from ensembles jpayne@69: * (TIP#112). jpayne@69: */ jpayne@69: jpayne@69: struct { jpayne@69: Tcl_Obj *const *sourceObjs; jpayne@69: /* What arguments were actually input into the jpayne@69: * *root* ensemble command? (Nested ensembles jpayne@69: * don't rewrite this.) NULL if we're not jpayne@69: * processing an ensemble. */ jpayne@69: int numRemovedObjs; /* How many arguments have been stripped off jpayne@69: * because of ensemble processing. */ jpayne@69: int numInsertedObjs; /* How many of the current arguments were jpayne@69: * inserted by an ensemble. */ jpayne@69: } ensembleRewrite; jpayne@69: jpayne@69: /* jpayne@69: * TIP #219: Global info for the I/O system. jpayne@69: */ jpayne@69: jpayne@69: Tcl_Obj *chanMsg; /* Error message set by channel drivers, for jpayne@69: * the propagation of arbitrary Tcl errors. jpayne@69: * This information, if present (chanMsg not jpayne@69: * NULL), takes precedence over a POSIX error jpayne@69: * code returned by a channel operation. */ jpayne@69: jpayne@69: /* jpayne@69: * Source code origin information (TIP #280). jpayne@69: */ jpayne@69: jpayne@69: CmdFrame *cmdFramePtr; /* Points to the command frame containing the jpayne@69: * location information for the current jpayne@69: * command. */ jpayne@69: const CmdFrame *invokeCmdFramePtr; jpayne@69: /* Points to the command frame which is the jpayne@69: * invoking context of the bytecode compiler. jpayne@69: * NULL when the byte code compiler is not jpayne@69: * active. */ jpayne@69: int invokeWord; /* Index of the word in the command which jpayne@69: * is getting compiled. */ jpayne@69: Tcl_HashTable *linePBodyPtr;/* This table remembers for each statically jpayne@69: * defined procedure the location information jpayne@69: * for its body. It is keyed by the address of jpayne@69: * the Proc structure for a procedure. The jpayne@69: * values are "struct CmdFrame*". */ jpayne@69: Tcl_HashTable *lineBCPtr; /* This table remembers for each ByteCode jpayne@69: * object the location information for its jpayne@69: * body. It is keyed by the address of the jpayne@69: * Proc structure for a procedure. The values jpayne@69: * are "struct ExtCmdLoc*". (See jpayne@69: * tclCompile.h) */ jpayne@69: Tcl_HashTable *lineLABCPtr; jpayne@69: Tcl_HashTable *lineLAPtr; /* This table remembers for each argument of a jpayne@69: * command on the execution stack the index of jpayne@69: * the argument in the command, and the jpayne@69: * location data of the command. It is keyed jpayne@69: * by the address of the Tcl_Obj containing jpayne@69: * the argument. The values are "struct jpayne@69: * CFWord*" (See tclBasic.c). This allows jpayne@69: * commands like uplevel, eval, etc. to find jpayne@69: * location information for their arguments, jpayne@69: * if they are a proper literal argument to an jpayne@69: * invoking command. Alt view: An index to the jpayne@69: * CmdFrame stack keyed by command argument jpayne@69: * holders. */ jpayne@69: ContLineLoc *scriptCLLocPtr;/* This table points to the location data for jpayne@69: * invisible continuation lines in the script, jpayne@69: * if any. This pointer is set by the function jpayne@69: * TclEvalObjEx() in file "tclBasic.c", and jpayne@69: * used by function ...() in the same file. jpayne@69: * It does for the eval/direct path of script jpayne@69: * execution what CompileEnv.clLoc does for jpayne@69: * the bytecode compiler. jpayne@69: */ jpayne@69: /* jpayne@69: * TIP #268. The currently active selection mode, i.e. the package require jpayne@69: * preferences. jpayne@69: */ jpayne@69: jpayne@69: int packagePrefer; /* Current package selection mode. */ jpayne@69: jpayne@69: /* jpayne@69: * Hashtables for variable traces and searches. jpayne@69: */ jpayne@69: jpayne@69: Tcl_HashTable varTraces; /* Hashtable holding the start of a variable's jpayne@69: * active trace list; varPtr is the key. */ jpayne@69: Tcl_HashTable varSearches; /* Hashtable holding the start of a variable's jpayne@69: * active searches list; varPtr is the key. */ jpayne@69: /* jpayne@69: * The thread-specific data ekeko: cache pointers or values that jpayne@69: * (a) do not change during the thread's lifetime jpayne@69: * (b) require access to TSD to determine at runtime jpayne@69: * (c) are accessed very often (e.g., at each command call) jpayne@69: * jpayne@69: * Note that these are the same for all interps in the same thread. They jpayne@69: * just have to be initialised for the thread's parent interp, children jpayne@69: * inherit the value. jpayne@69: * jpayne@69: * They are used by the macros defined below. jpayne@69: */ jpayne@69: jpayne@69: AllocCache *allocCache; jpayne@69: void *pendingObjDataPtr; /* Pointer to the Cache and PendingObjData jpayne@69: * structs for this interp's thread; see jpayne@69: * tclObj.c and tclThreadAlloc.c */ jpayne@69: int *asyncReadyPtr; /* Pointer to the asyncReady indicator for jpayne@69: * this interp's thread; see tclAsync.c */ jpayne@69: /* jpayne@69: * The pointer to the object system root ekeko. c.f. TIP #257. jpayne@69: */ jpayne@69: void *objectFoundation; /* Pointer to the Foundation structure of the jpayne@69: * object system, which contains things like jpayne@69: * references to key namespaces. See jpayne@69: * tclOOInt.h and tclOO.c for real definition jpayne@69: * and setup. */ jpayne@69: jpayne@69: struct NRE_callback *deferredCallbacks; jpayne@69: /* Callbacks that are set previous to a call jpayne@69: * to some Eval function but that actually jpayne@69: * belong to the command that is about to be jpayne@69: * called - i.e., they should be run *before* jpayne@69: * any tailcall is invoked. */ jpayne@69: jpayne@69: /* jpayne@69: * TIP #285, Script cancellation support. jpayne@69: */ jpayne@69: jpayne@69: Tcl_AsyncHandler asyncCancel; jpayne@69: /* Async handler token for Tcl_CancelEval. */ jpayne@69: Tcl_Obj *asyncCancelMsg; /* Error message set by async cancel handler jpayne@69: * for the propagation of arbitrary Tcl jpayne@69: * errors. This information, if present jpayne@69: * (asyncCancelMsg not NULL), takes precedence jpayne@69: * over the default error messages returned by jpayne@69: * a script cancellation operation. */ jpayne@69: jpayne@69: /* jpayne@69: * TIP #348 IMPLEMENTATION - Substituted error stack jpayne@69: */ jpayne@69: Tcl_Obj *errorStack; /* [info errorstack] value (as a Tcl_Obj). */ jpayne@69: Tcl_Obj *upLiteral; /* "UP" literal for [info errorstack] */ jpayne@69: Tcl_Obj *callLiteral; /* "CALL" literal for [info errorstack] */ jpayne@69: Tcl_Obj *innerLiteral; /* "INNER" literal for [info errorstack] */ jpayne@69: Tcl_Obj *innerContext; /* cached list for fast reallocation */ jpayne@69: int resetErrorStack; /* controls cleaning up of ::errorStack */ jpayne@69: jpayne@69: #ifdef TCL_COMPILE_STATS jpayne@69: /* jpayne@69: * Statistical information about the bytecode compiler and interpreter's jpayne@69: * operation. This should be the last field of Interp. jpayne@69: */ jpayne@69: jpayne@69: ByteCodeStats stats; /* Holds compilation and execution statistics jpayne@69: * for this interpreter. */ jpayne@69: #endif /* TCL_COMPILE_STATS */ jpayne@69: } Interp; jpayne@69: jpayne@69: /* jpayne@69: * Macros that use the TSD-ekeko. jpayne@69: */ jpayne@69: jpayne@69: #define TclAsyncReady(iPtr) \ jpayne@69: *((iPtr)->asyncReadyPtr) jpayne@69: jpayne@69: /* jpayne@69: * Macros for script cancellation support (TIP #285). jpayne@69: */ jpayne@69: jpayne@69: #define TclCanceled(iPtr) \ jpayne@69: (((iPtr)->flags & CANCELED) || ((iPtr)->flags & TCL_CANCEL_UNWIND)) jpayne@69: jpayne@69: #define TclSetCancelFlags(iPtr, cancelFlags) \ jpayne@69: (iPtr)->flags |= CANCELED; \ jpayne@69: if ((cancelFlags) & TCL_CANCEL_UNWIND) { \ jpayne@69: (iPtr)->flags |= TCL_CANCEL_UNWIND; \ jpayne@69: } jpayne@69: jpayne@69: #define TclUnsetCancelFlags(iPtr) \ jpayne@69: (iPtr)->flags &= (~(CANCELED | TCL_CANCEL_UNWIND)) jpayne@69: jpayne@69: /* jpayne@69: * Macros for splicing into and out of doubly linked lists. They assume jpayne@69: * existence of struct items 'prevPtr' and 'nextPtr'. jpayne@69: * jpayne@69: * a = element to add or remove. jpayne@69: * b = list head. jpayne@69: * jpayne@69: * TclSpliceIn adds to the head of the list. jpayne@69: */ jpayne@69: jpayne@69: #define TclSpliceIn(a,b) \ jpayne@69: (a)->nextPtr = (b); \ jpayne@69: if ((b) != NULL) { \ jpayne@69: (b)->prevPtr = (a); \ jpayne@69: } \ jpayne@69: (a)->prevPtr = NULL, (b) = (a); jpayne@69: jpayne@69: #define TclSpliceOut(a,b) \ jpayne@69: if ((a)->prevPtr != NULL) { \ jpayne@69: (a)->prevPtr->nextPtr = (a)->nextPtr; \ jpayne@69: } else { \ jpayne@69: (b) = (a)->nextPtr; \ jpayne@69: } \ jpayne@69: if ((a)->nextPtr != NULL) { \ jpayne@69: (a)->nextPtr->prevPtr = (a)->prevPtr; \ jpayne@69: } jpayne@69: jpayne@69: /* jpayne@69: * EvalFlag bits for Interp structures: jpayne@69: * jpayne@69: * TCL_ALLOW_EXCEPTIONS 1 means it's OK for the script to terminate with a jpayne@69: * code other than TCL_OK or TCL_ERROR; 0 means codes jpayne@69: * other than these should be turned into errors. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_ALLOW_EXCEPTIONS 0x04 jpayne@69: #define TCL_EVAL_FILE 0x02 jpayne@69: #define TCL_EVAL_SOURCE_IN_FRAME 0x10 jpayne@69: #define TCL_EVAL_NORESOLVE 0x20 jpayne@69: #define TCL_EVAL_DISCARD_RESULT 0x40 jpayne@69: jpayne@69: /* jpayne@69: * Flag bits for Interp structures: jpayne@69: * jpayne@69: * DELETED: Non-zero means the interpreter has been deleted: jpayne@69: * don't process any more commands for it, and destroy jpayne@69: * the structure as soon as all nested invocations of jpayne@69: * Tcl_Eval are done. jpayne@69: * ERR_ALREADY_LOGGED: Non-zero means information has already been logged in jpayne@69: * iPtr->errorInfo for the current Tcl_Eval instance, so jpayne@69: * Tcl_Eval needn't log it (used to implement the "error jpayne@69: * message log" command). jpayne@69: * DONT_COMPILE_CMDS_INLINE: Non-zero means that the bytecode compiler should jpayne@69: * not compile any commands into an inline sequence of jpayne@69: * instructions. This is set 1, for example, when command jpayne@69: * traces are requested. jpayne@69: * RAND_SEED_INITIALIZED: Non-zero means that the randSeed value of the interp jpayne@69: * has not be initialized. This is set 1 when we first jpayne@69: * use the rand() or srand() functions. jpayne@69: * SAFE_INTERP: Non zero means that the current interp is a safe jpayne@69: * interp (i.e. it has only the safe commands installed, jpayne@69: * less privilege than a regular interp). jpayne@69: * INTERP_DEBUG_FRAME: Used for switching on various extra interpreter jpayne@69: * debug/info mechanisms (e.g. info frame eval/uplevel jpayne@69: * tracing) which are performance intensive. jpayne@69: * INTERP_TRACE_IN_PROGRESS: Non-zero means that an interp trace is currently jpayne@69: * active; so no further trace callbacks should be jpayne@69: * invoked. jpayne@69: * INTERP_ALTERNATE_WRONG_ARGS: Used for listing second and subsequent forms jpayne@69: * of the wrong-num-args string in Tcl_WrongNumArgs. jpayne@69: * Makes it append instead of replacing and uses jpayne@69: * different intermediate text. jpayne@69: * CANCELED: Non-zero means that the script in progress should be jpayne@69: * canceled as soon as possible. This can be checked by jpayne@69: * extensions (and the core itself) by calling jpayne@69: * Tcl_Canceled and checking if TCL_ERROR is returned. jpayne@69: * This is a one-shot flag that is reset immediately upon jpayne@69: * being detected; however, if the TCL_CANCEL_UNWIND flag jpayne@69: * is set Tcl_Canceled will continue to report that the jpayne@69: * script in progress has been canceled thereby allowing jpayne@69: * the evaluation stack for the interp to be fully jpayne@69: * unwound. jpayne@69: * jpayne@69: * WARNING: For the sake of some extensions that have made use of former jpayne@69: * internal values, do not re-use the flag values 2 (formerly ERR_IN_PROGRESS) jpayne@69: * or 8 (formerly ERROR_CODE_SET). jpayne@69: */ jpayne@69: jpayne@69: #define DELETED 1 jpayne@69: #define ERR_ALREADY_LOGGED 4 jpayne@69: #define INTERP_DEBUG_FRAME 0x10 jpayne@69: #define DONT_COMPILE_CMDS_INLINE 0x20 jpayne@69: #define RAND_SEED_INITIALIZED 0x40 jpayne@69: #define SAFE_INTERP 0x80 jpayne@69: #define INTERP_TRACE_IN_PROGRESS 0x200 jpayne@69: #define INTERP_ALTERNATE_WRONG_ARGS 0x400 jpayne@69: #define ERR_LEGACY_COPY 0x800 jpayne@69: #define CANCELED 0x1000 jpayne@69: jpayne@69: /* jpayne@69: * Maximum number of levels of nesting permitted in Tcl commands (used to jpayne@69: * catch infinite recursion). jpayne@69: */ jpayne@69: jpayne@69: #define MAX_NESTING_DEPTH 1000 jpayne@69: jpayne@69: /* jpayne@69: * The macro below is used to modify a "char" value (e.g. by casting it to an jpayne@69: * unsigned character) so that it can be used safely with macros such as jpayne@69: * isspace. jpayne@69: */ jpayne@69: jpayne@69: #define UCHAR(c) ((unsigned char) (c)) jpayne@69: jpayne@69: /* jpayne@69: * This macro is used to properly align the memory allocated by Tcl, giving jpayne@69: * the same alignment as the native malloc. jpayne@69: */ jpayne@69: jpayne@69: #if defined(__APPLE__) jpayne@69: #define TCL_ALLOCALIGN 16 jpayne@69: #else jpayne@69: #define TCL_ALLOCALIGN (2*sizeof(void *)) jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * This macro is used to determine the offset needed to safely allocate any jpayne@69: * data structure in memory. Given a starting offset or size, it "rounds up" jpayne@69: * or "aligns" the offset to the next 8-byte boundary so that any data jpayne@69: * structure can be placed at the resulting offset without fear of an jpayne@69: * alignment error. jpayne@69: * jpayne@69: * WARNING!! DO NOT USE THIS MACRO TO ALIGN POINTERS: it will produce the jpayne@69: * wrong result on platforms that allocate addresses that are divisible by 4 jpayne@69: * or 2. Only use it for offsets or sizes. jpayne@69: * jpayne@69: * This macro is only used by tclCompile.c in the core (Bug 926445). It jpayne@69: * however not be made file static, as extensions that touch bytecodes jpayne@69: * (notably tbcload) require it. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_ALIGN(x) (((int)(x) + 7) & ~7) jpayne@69: jpayne@69: /* jpayne@69: * The following enum values are used to specify the runtime platform setting jpayne@69: * of the tclPlatform variable. jpayne@69: */ jpayne@69: jpayne@69: typedef enum { jpayne@69: TCL_PLATFORM_UNIX = 0, /* Any Unix-like OS. */ jpayne@69: TCL_PLATFORM_WINDOWS = 2 /* Any Microsoft Windows OS. */ jpayne@69: } TclPlatformType; jpayne@69: jpayne@69: /* jpayne@69: * The following enum values are used to indicate the translation of a Tcl jpayne@69: * channel. Declared here so that each platform can define jpayne@69: * TCL_PLATFORM_TRANSLATION to the native translation on that platform. jpayne@69: */ jpayne@69: jpayne@69: typedef enum TclEolTranslation { jpayne@69: TCL_TRANSLATE_AUTO, /* Eol == \r, \n and \r\n. */ jpayne@69: TCL_TRANSLATE_CR, /* Eol == \r. */ jpayne@69: TCL_TRANSLATE_LF, /* Eol == \n. */ jpayne@69: TCL_TRANSLATE_CRLF /* Eol == \r\n. */ jpayne@69: } TclEolTranslation; jpayne@69: jpayne@69: /* jpayne@69: * Flags for TclInvoke: jpayne@69: * jpayne@69: * TCL_INVOKE_HIDDEN Invoke a hidden command; if not set, invokes jpayne@69: * an exposed command. jpayne@69: * TCL_INVOKE_NO_UNKNOWN If set, "unknown" is not invoked if the jpayne@69: * command to be invoked is not found. Only has jpayne@69: * an effect if invoking an exposed command, jpayne@69: * i.e. if TCL_INVOKE_HIDDEN is not also set. jpayne@69: * TCL_INVOKE_NO_TRACEBACK Does not record traceback information if the jpayne@69: * invoked command returns an error. Used if the jpayne@69: * caller plans on recording its own traceback jpayne@69: * information. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_INVOKE_HIDDEN (1<<0) jpayne@69: #define TCL_INVOKE_NO_UNKNOWN (1<<1) jpayne@69: #define TCL_INVOKE_NO_TRACEBACK (1<<2) jpayne@69: jpayne@69: /* jpayne@69: * The structure used as the internal representation of Tcl list objects. This jpayne@69: * struct is grown (reallocated and copied) as necessary to hold all the jpayne@69: * list's element pointers. The struct might contain more slots than currently jpayne@69: * used to hold all element pointers. This is done to make append operations jpayne@69: * faster. jpayne@69: */ jpayne@69: jpayne@69: typedef struct List { jpayne@69: int refCount; jpayne@69: int maxElemCount; /* Total number of element array slots. */ jpayne@69: int elemCount; /* Current number of list elements. */ jpayne@69: int canonicalFlag; /* Set if the string representation was jpayne@69: * derived from the list representation. May jpayne@69: * be ignored if there is no string rep at jpayne@69: * all.*/ jpayne@69: Tcl_Obj *elements; /* First list element; the struct is grown to jpayne@69: * accommodate all elements. */ jpayne@69: } List; jpayne@69: jpayne@69: #define LIST_MAX \ jpayne@69: (1 + (int)(((size_t)UINT_MAX - sizeof(List))/sizeof(Tcl_Obj *))) jpayne@69: #define LIST_SIZE(numElems) \ jpayne@69: (unsigned)(sizeof(List) + (((numElems) - 1) * sizeof(Tcl_Obj *))) jpayne@69: jpayne@69: /* jpayne@69: * Macro used to get the elements of a list object. jpayne@69: */ jpayne@69: jpayne@69: #define ListRepPtr(listPtr) \ jpayne@69: ((List *) (listPtr)->internalRep.twoPtrValue.ptr1) jpayne@69: jpayne@69: /* Not used any more */ jpayne@69: #define ListSetIntRep(objPtr, listRepPtr) \ jpayne@69: (objPtr)->internalRep.twoPtrValue.ptr1 = (void *)(listRepPtr), \ jpayne@69: (objPtr)->internalRep.twoPtrValue.ptr2 = NULL, \ jpayne@69: (listRepPtr)->refCount++, \ jpayne@69: (objPtr)->typePtr = &tclListType jpayne@69: jpayne@69: #define ListObjGetElements(listPtr, objc, objv) \ jpayne@69: ((objv) = &(ListRepPtr(listPtr)->elements), \ jpayne@69: (objc) = ListRepPtr(listPtr)->elemCount) jpayne@69: jpayne@69: #define ListObjLength(listPtr, len) \ jpayne@69: ((len) = ListRepPtr(listPtr)->elemCount) jpayne@69: jpayne@69: #define ListObjIsCanonical(listPtr) \ jpayne@69: (((listPtr)->bytes == NULL) || ListRepPtr(listPtr)->canonicalFlag) jpayne@69: jpayne@69: #define TclListObjGetElements(interp, listPtr, objcPtr, objvPtr) \ jpayne@69: (((listPtr)->typePtr == &tclListType) \ jpayne@69: ? ((ListObjGetElements((listPtr), *(objcPtr), *(objvPtr))), TCL_OK)\ jpayne@69: : Tcl_ListObjGetElements((interp), (listPtr), (objcPtr), (objvPtr))) jpayne@69: jpayne@69: #define TclListObjLength(interp, listPtr, lenPtr) \ jpayne@69: (((listPtr)->typePtr == &tclListType) \ jpayne@69: ? ((ListObjLength((listPtr), *(lenPtr))), TCL_OK)\ jpayne@69: : Tcl_ListObjLength((interp), (listPtr), (lenPtr))) jpayne@69: jpayne@69: #define TclListObjIsCanonical(listPtr) \ jpayne@69: (((listPtr)->typePtr == &tclListType) ? ListObjIsCanonical((listPtr)) : 0) jpayne@69: jpayne@69: /* jpayne@69: * Modes for collecting (or not) in the implementations of TclNRForeachCmd, jpayne@69: * TclNRLmapCmd and their compilations. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_EACH_KEEP_NONE 0 /* Discard iteration result like [foreach] */ jpayne@69: #define TCL_EACH_COLLECT 1 /* Collect iteration result like [lmap] */ jpayne@69: jpayne@69: /* jpayne@69: * Macros providing a faster path to integers: Tcl_GetLongFromObj, jpayne@69: * Tcl_GetIntFromObj and TclGetIntForIndex. jpayne@69: * jpayne@69: * WARNING: these macros eval their args more than once. jpayne@69: */ jpayne@69: jpayne@69: #define TclGetLongFromObj(interp, objPtr, longPtr) \ jpayne@69: (((objPtr)->typePtr == &tclIntType) \ jpayne@69: ? ((*(longPtr) = (objPtr)->internalRep.longValue), TCL_OK) \ jpayne@69: : Tcl_GetLongFromObj((interp), (objPtr), (longPtr))) jpayne@69: jpayne@69: #if (LONG_MAX == INT_MAX) jpayne@69: #define TclGetIntFromObj(interp, objPtr, intPtr) \ jpayne@69: (((objPtr)->typePtr == &tclIntType) \ jpayne@69: ? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \ jpayne@69: : Tcl_GetIntFromObj((interp), (objPtr), (intPtr))) jpayne@69: #define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \ jpayne@69: (((objPtr)->typePtr == &tclIntType) \ jpayne@69: ? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \ jpayne@69: : TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr))) jpayne@69: #else jpayne@69: #define TclGetIntFromObj(interp, objPtr, intPtr) \ jpayne@69: (((objPtr)->typePtr == &tclIntType \ jpayne@69: && (objPtr)->internalRep.longValue >= -(Tcl_WideInt)(UINT_MAX) \ jpayne@69: && (objPtr)->internalRep.longValue <= (Tcl_WideInt)(UINT_MAX)) \ jpayne@69: ? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \ jpayne@69: : Tcl_GetIntFromObj((interp), (objPtr), (intPtr))) jpayne@69: #define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \ jpayne@69: (((objPtr)->typePtr == &tclIntType \ jpayne@69: && (objPtr)->internalRep.longValue >= INT_MIN \ jpayne@69: && (objPtr)->internalRep.longValue <= INT_MAX) \ jpayne@69: ? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \ jpayne@69: : TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr))) jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * Macro used to save a function call for common uses of jpayne@69: * Tcl_GetWideIntFromObj(). The ANSI C "prototype" is: jpayne@69: * jpayne@69: * MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, jpayne@69: * Tcl_WideInt *wideIntPtr); jpayne@69: */ jpayne@69: jpayne@69: #ifdef TCL_WIDE_INT_IS_LONG jpayne@69: #define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \ jpayne@69: (((objPtr)->typePtr == &tclIntType) \ jpayne@69: ? (*(wideIntPtr) = (Tcl_WideInt) \ jpayne@69: ((objPtr)->internalRep.longValue), TCL_OK) : \ jpayne@69: Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) jpayne@69: #else /* !TCL_WIDE_INT_IS_LONG */ jpayne@69: #define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \ jpayne@69: (((objPtr)->typePtr == &tclWideIntType) \ jpayne@69: ? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) : \ jpayne@69: ((objPtr)->typePtr == &tclIntType) \ jpayne@69: ? (*(wideIntPtr) = (Tcl_WideInt) \ jpayne@69: ((objPtr)->internalRep.longValue), TCL_OK) : \ jpayne@69: Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) jpayne@69: #endif /* TCL_WIDE_INT_IS_LONG */ jpayne@69: jpayne@69: /* jpayne@69: * Flag values for TclTraceDictPath(). jpayne@69: * jpayne@69: * DICT_PATH_READ indicates that all entries on the path must exist but no jpayne@69: * updates will be needed. jpayne@69: * jpayne@69: * DICT_PATH_UPDATE indicates that we are going to be doing an update at the jpayne@69: * tip of the path, so duplication of shared objects should be done along the jpayne@69: * way. jpayne@69: * jpayne@69: * DICT_PATH_EXISTS indicates that we are performing an existence test and a jpayne@69: * lookup failure should therefore not be an error. If (and only if) this flag jpayne@69: * is set, TclTraceDictPath() will return the special value jpayne@69: * DICT_PATH_NON_EXISTENT if the path is not traceable. jpayne@69: * jpayne@69: * DICT_PATH_CREATE (which also requires the DICT_PATH_UPDATE bit to be set) jpayne@69: * indicates that we are to create non-existent dictionaries on the path. jpayne@69: */ jpayne@69: jpayne@69: #define DICT_PATH_READ 0 jpayne@69: #define DICT_PATH_UPDATE 1 jpayne@69: #define DICT_PATH_EXISTS 2 jpayne@69: #define DICT_PATH_CREATE 5 jpayne@69: jpayne@69: #define DICT_PATH_NON_EXISTENT ((Tcl_Obj *) (void *) 1) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to the filesystem internals jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * The version_2 filesystem is private to Tcl. As and when these changes have jpayne@69: * been thoroughly tested and investigated a new public filesystem interface jpayne@69: * will be released. The aim is more versatile virtual filesystem interfaces, jpayne@69: * more efficiency in 'path' manipulation and usage, and cleaner filesystem jpayne@69: * code internally. jpayne@69: */ jpayne@69: jpayne@69: #define TCL_FILESYSTEM_VERSION_2 ((Tcl_FSVersion) 0x2) jpayne@69: typedef ClientData (TclFSGetCwdProc2)(ClientData clientData); jpayne@69: typedef int (Tcl_FSLoadFileProc2) (Tcl_Interp *interp, Tcl_Obj *pathPtr, jpayne@69: Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); jpayne@69: jpayne@69: /* jpayne@69: * The following types are used for getting and storing platform-specific file jpayne@69: * attributes in tclFCmd.c and the various platform-versions of that file. jpayne@69: * This is done to have as much common code as possible in the file attributes jpayne@69: * code. For more information about the callbacks, see TclFileAttrsCmd in jpayne@69: * tclFCmd.c. jpayne@69: */ jpayne@69: jpayne@69: typedef int (TclGetFileAttrProc)(Tcl_Interp *interp, int objIndex, jpayne@69: Tcl_Obj *fileName, Tcl_Obj **attrObjPtrPtr); jpayne@69: typedef int (TclSetFileAttrProc)(Tcl_Interp *interp, int objIndex, jpayne@69: Tcl_Obj *fileName, Tcl_Obj *attrObjPtr); jpayne@69: jpayne@69: typedef struct TclFileAttrProcs { jpayne@69: TclGetFileAttrProc *getProc;/* The procedure for getting attrs. */ jpayne@69: TclSetFileAttrProc *setProc;/* The procedure for setting attrs. */ jpayne@69: } TclFileAttrProcs; jpayne@69: jpayne@69: /* jpayne@69: * Opaque handle used in pipeline routines to encapsulate platform-dependent jpayne@69: * state. jpayne@69: */ jpayne@69: jpayne@69: typedef struct TclFile_ *TclFile; jpayne@69: jpayne@69: /* jpayne@69: * The "globParameters" argument of the function TclGlob is an or'ed jpayne@69: * combination of the following values: jpayne@69: */ jpayne@69: jpayne@69: #define TCL_GLOBMODE_NO_COMPLAIN 1 jpayne@69: #define TCL_GLOBMODE_JOIN 2 jpayne@69: #define TCL_GLOBMODE_DIR 4 jpayne@69: #define TCL_GLOBMODE_TAILS 8 jpayne@69: jpayne@69: typedef enum Tcl_PathPart { jpayne@69: TCL_PATH_DIRNAME, jpayne@69: TCL_PATH_TAIL, jpayne@69: TCL_PATH_EXTENSION, jpayne@69: TCL_PATH_ROOT jpayne@69: } Tcl_PathPart; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to obsolete filesystem hooks jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: typedef int (TclStatProc_)(const char *path, struct stat *buf); jpayne@69: typedef int (TclAccessProc_)(const char *path, int mode); jpayne@69: typedef Tcl_Channel (TclOpenFileChannelProc_)(Tcl_Interp *interp, jpayne@69: const char *fileName, const char *modeString, int permissions); jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures related to procedures jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: typedef Tcl_CmdProc *TclCmdProcType; jpayne@69: typedef Tcl_ObjCmdProc *TclObjCmdProcType; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Data structures for process-global values. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, int *lengthPtr, jpayne@69: Tcl_Encoding *encodingPtr); jpayne@69: jpayne@69: /* jpayne@69: * A ProcessGlobalValue struct exists for each internal value in Tcl that is jpayne@69: * to be shared among several threads. Each thread sees a (Tcl_Obj) copy of jpayne@69: * the value, and the gobal value is kept as a counted string, with epoch and jpayne@69: * mutex control. Each ProcessGlobalValue struct should be a static variable in jpayne@69: * some file. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ProcessGlobalValue { jpayne@69: int epoch; /* Epoch counter to detect changes in the jpayne@69: * global value. */ jpayne@69: int numBytes; /* Length of the global string. */ jpayne@69: char *value; /* The global string value. */ jpayne@69: Tcl_Encoding encoding; /* system encoding when global string was jpayne@69: * initialized. */ jpayne@69: TclInitProcessGlobalValueProc *proc; jpayne@69: /* A procedure to initialize the global string jpayne@69: * copy when a "get" request comes in before jpayne@69: * any "set" request has been received. */ jpayne@69: Tcl_Mutex mutex; /* Enforce orderly access from multiple jpayne@69: * threads. */ jpayne@69: Tcl_ThreadDataKey key; /* Key for per-thread data holding the jpayne@69: * (Tcl_Obj) copy for each thread. */ jpayne@69: } ProcessGlobalValue; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------------- jpayne@69: * Flags for TclParseNumber jpayne@69: *---------------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TCL_PARSE_DECIMAL_ONLY 1 jpayne@69: /* Leading zero doesn't denote octal or jpayne@69: * hex. */ jpayne@69: #define TCL_PARSE_OCTAL_ONLY 2 jpayne@69: /* Parse octal even without prefix. */ jpayne@69: #define TCL_PARSE_HEXADECIMAL_ONLY 4 jpayne@69: /* Parse hexadecimal even without prefix. */ jpayne@69: #define TCL_PARSE_INTEGER_ONLY 8 jpayne@69: /* Disable floating point parsing. */ jpayne@69: #define TCL_PARSE_SCAN_PREFIXES 16 jpayne@69: /* Use [scan] rules dealing with 0? jpayne@69: * prefixes. */ jpayne@69: #define TCL_PARSE_NO_WHITESPACE 32 jpayne@69: /* Reject leading/trailing whitespace. */ jpayne@69: #define TCL_PARSE_BINARY_ONLY 64 jpayne@69: /* Parse binary even without prefix. */ jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------------- jpayne@69: * Type values TclGetNumberFromObj jpayne@69: *---------------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TCL_NUMBER_LONG 1 jpayne@69: #define TCL_NUMBER_WIDE 2 jpayne@69: #define TCL_NUMBER_BIG 3 jpayne@69: #define TCL_NUMBER_DOUBLE 4 jpayne@69: #define TCL_NUMBER_NAN 5 jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Variables shared among Tcl modules but not used by the outside world. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE char *tclNativeExecutableName; jpayne@69: MODULE_SCOPE int tclFindExecutableSearchDone; jpayne@69: MODULE_SCOPE char *tclMemDumpFileName; jpayne@69: MODULE_SCOPE TclPlatformType tclPlatform; jpayne@69: MODULE_SCOPE Tcl_NotifierProcs tclNotifierHooks; jpayne@69: jpayne@69: MODULE_SCOPE Tcl_Encoding tclIdentityEncoding; jpayne@69: jpayne@69: /* jpayne@69: * TIP #233 (Virtualized Time) jpayne@69: * Data for the time hooks, if any. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE Tcl_GetTimeProc *tclGetTimeProcPtr; jpayne@69: MODULE_SCOPE Tcl_ScaleTimeProc *tclScaleTimeProcPtr; jpayne@69: MODULE_SCOPE ClientData tclTimeClientData; jpayne@69: jpayne@69: /* jpayne@69: * Variables denoting the Tcl object types defined in the core. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE const Tcl_ObjType tclBignumType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclBooleanType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclByteArrayType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclByteCodeType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclDoubleType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclEndOffsetType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclIntType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclListType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclDictType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclProcBodyType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclStringType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclArraySearchType; jpayne@69: MODULE_SCOPE const Tcl_ObjType tclEnsembleCmdType; jpayne@69: #ifndef TCL_WIDE_INT_IS_LONG jpayne@69: MODULE_SCOPE const Tcl_ObjType tclWideIntType; jpayne@69: #endif jpayne@69: MODULE_SCOPE const Tcl_ObjType tclRegexpType; jpayne@69: MODULE_SCOPE Tcl_ObjType tclCmdNameType; jpayne@69: jpayne@69: /* jpayne@69: * Variables denoting the hash key types defined in the core. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE const Tcl_HashKeyType tclArrayHashKeyType; jpayne@69: MODULE_SCOPE const Tcl_HashKeyType tclOneWordHashKeyType; jpayne@69: MODULE_SCOPE const Tcl_HashKeyType tclStringHashKeyType; jpayne@69: MODULE_SCOPE const Tcl_HashKeyType tclObjHashKeyType; jpayne@69: jpayne@69: /* jpayne@69: * The head of the list of free Tcl objects, and the total number of Tcl jpayne@69: * objects ever allocated and freed. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE Tcl_Obj * tclFreeObjList; jpayne@69: jpayne@69: #ifdef TCL_COMPILE_STATS jpayne@69: MODULE_SCOPE long tclObjsAlloced; jpayne@69: MODULE_SCOPE long tclObjsFreed; jpayne@69: #define TCL_MAX_SHARED_OBJ_STATS 5 jpayne@69: MODULE_SCOPE long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS]; jpayne@69: #endif /* TCL_COMPILE_STATS */ jpayne@69: jpayne@69: /* jpayne@69: * Pointer to a heap-allocated string of length zero that the Tcl core uses as jpayne@69: * the value of an empty string representation for an object. This value is jpayne@69: * shared by all new objects allocated by Tcl_NewObj. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE char * tclEmptyStringRep; jpayne@69: MODULE_SCOPE char tclEmptyString; jpayne@69: jpayne@69: enum CheckEmptyStringResult { jpayne@69: TCL_EMPTYSTRING_UNKNOWN = -1, TCL_EMPTYSTRING_NO, TCL_EMPTYSTRING_YES jpayne@69: }; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Procedures shared among Tcl modules but not used by the outside world, jpayne@69: * introduced by/for NRE. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRApplyObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNREvalObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRCatchObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRExprObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRForObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRForeachCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRIfObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRLmapCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRPackageObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRSourceObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRSubstObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRSwitchObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRTryObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRUplevelObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRWhileObjCmd; jpayne@69: jpayne@69: MODULE_SCOPE Tcl_NRPostProc TclNRForIterCallback; jpayne@69: MODULE_SCOPE Tcl_NRPostProc TclNRCoroutineActivateCallback; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRTailcallObjCmd; jpayne@69: MODULE_SCOPE Tcl_NRPostProc TclNRTailcallEval; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke; jpayne@69: MODULE_SCOPE Tcl_NRPostProc TclNRReleaseValues; jpayne@69: jpayne@69: MODULE_SCOPE void TclSetTailcall(Tcl_Interp *interp, Tcl_Obj *tailcallPtr); jpayne@69: MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp); jpayne@69: jpayne@69: /* These two can be considered for the public api */ jpayne@69: MODULE_SCOPE void TclMarkTailcall(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE void TclSkipTailcall(Tcl_Interp *interp); jpayne@69: jpayne@69: /* jpayne@69: * This structure holds the data for the various iteration callbacks used to jpayne@69: * NRE the 'for' and 'while' commands. We need a separate structure because we jpayne@69: * have more than the 4 client data entries we can provide directly thorugh jpayne@69: * the callback API. It is the 'word' information which puts us over the jpayne@69: * limit. It is needed because the loop body is argument 4 of 'for' and jpayne@69: * argument 2 of 'while'. Not providing the correct index confuses the #280 jpayne@69: * code. We TclSmallAlloc/Free this. jpayne@69: */ jpayne@69: jpayne@69: typedef struct ForIterData { jpayne@69: Tcl_Obj *cond; /* Loop condition expression. */ jpayne@69: Tcl_Obj *body; /* Loop body. */ jpayne@69: Tcl_Obj *next; /* Loop step script, NULL for 'while'. */ jpayne@69: const char *msg; /* Error message part. */ jpayne@69: int word; /* Index of the body script in the command */ jpayne@69: } ForIterData; jpayne@69: jpayne@69: /* TIP #357 - Structure doing the bookkeeping of handles for Tcl_LoadFile jpayne@69: * and Tcl_FindSymbol. This structure corresponds to an opaque jpayne@69: * typedef in tcl.h */ jpayne@69: jpayne@69: typedef void* TclFindSymbolProc(Tcl_Interp* interp, Tcl_LoadHandle loadHandle, jpayne@69: const char* symbol); jpayne@69: struct Tcl_LoadHandle_ { jpayne@69: ClientData clientData; /* Client data is the load handle in the jpayne@69: * native filesystem if a module was loaded jpayne@69: * there, or an opaque pointer to a structure jpayne@69: * for further bookkeeping on load-from-VFS jpayne@69: * and load-from-memory */ jpayne@69: TclFindSymbolProc* findSymbolProcPtr; jpayne@69: /* Procedure that resolves symbols in a jpayne@69: * loaded module */ jpayne@69: Tcl_FSUnloadFileProc* unloadFileProcPtr; jpayne@69: /* Procedure that unloads a loaded module */ jpayne@69: }; jpayne@69: jpayne@69: /* Flags for conversion of doubles to digit strings */ jpayne@69: jpayne@69: #define TCL_DD_SHORTEST 0x4 jpayne@69: /* Use the shortest possible string */ jpayne@69: #define TCL_DD_STEELE 0x5 jpayne@69: /* Use the original Steele&White algorithm */ jpayne@69: #define TCL_DD_E_FORMAT 0x2 jpayne@69: /* Use a fixed-length string of digits, jpayne@69: * suitable for E format*/ jpayne@69: #define TCL_DD_F_FORMAT 0x3 jpayne@69: /* Use a fixed number of digits after the jpayne@69: * decimal point, suitable for F format */ jpayne@69: jpayne@69: #define TCL_DD_SHORTEN_FLAG 0x4 jpayne@69: /* Allow return of a shorter digit string jpayne@69: * if it converts losslessly */ jpayne@69: #define TCL_DD_NO_QUICK 0x8 jpayne@69: /* Debug flag: forbid quick FP conversion */ jpayne@69: jpayne@69: #define TCL_DD_CONVERSION_TYPE_MASK 0x3 jpayne@69: /* Mask to isolate the conversion type */ jpayne@69: #define TCL_DD_STEELE0 0x1 jpayne@69: /* 'Steele&White' after masking */ jpayne@69: #define TCL_DD_SHORTEST0 0x0 jpayne@69: /* 'Shortest possible' after masking */ jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Procedures shared among Tcl modules but not used by the outside world: jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, jpayne@69: const unsigned char *bytes, int len); jpayne@69: MODULE_SCOPE int TclNREvalCmd(Tcl_Interp *interp, Tcl_Obj *objPtr, jpayne@69: int flags); jpayne@69: MODULE_SCOPE void TclAdvanceContinuations(int *line, int **next, jpayne@69: int loc); jpayne@69: MODULE_SCOPE void TclAdvanceLines(int *line, const char *start, jpayne@69: const char *end); jpayne@69: MODULE_SCOPE void TclArgumentEnter(Tcl_Interp *interp, jpayne@69: Tcl_Obj *objv[], int objc, CmdFrame *cf); jpayne@69: MODULE_SCOPE void TclArgumentRelease(Tcl_Interp *interp, jpayne@69: Tcl_Obj *objv[], int objc); jpayne@69: MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp, jpayne@69: Tcl_Obj *objv[], int objc, jpayne@69: void *codePtr, CmdFrame *cfPtr, int cmd, int pc); jpayne@69: MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp, jpayne@69: CmdFrame *cfPtr); jpayne@69: MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj, jpayne@69: CmdFrame **cfPtrPtr, int *wordPtr); jpayne@69: MODULE_SCOPE double TclBignumToDouble(const mp_int *bignum); jpayne@69: MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string, jpayne@69: int strLen, const unsigned char *pattern, jpayne@69: int ptnLen, int flags); jpayne@69: MODULE_SCOPE double TclCeil(const mp_int *a); jpayne@69: MODULE_SCOPE void TclChannelPreserve(Tcl_Channel chan); jpayne@69: MODULE_SCOPE void TclChannelRelease(Tcl_Channel chan); jpayne@69: MODULE_SCOPE int TclCheckArrayTraces(Tcl_Interp *interp, Var *varPtr, jpayne@69: Var *arrayPtr, Tcl_Obj *name, int index); jpayne@69: MODULE_SCOPE int TclCheckBadOctal(Tcl_Interp *interp, jpayne@69: const char *value); jpayne@69: MODULE_SCOPE int TclCheckEmptyString(Tcl_Obj *objPtr); jpayne@69: MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp, jpayne@69: Tcl_Channel chan); jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd; jpayne@69: MODULE_SCOPE Tcl_NRPostProc TclClearRootEnsemble; jpayne@69: MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num, jpayne@69: int *loc); jpayne@69: MODULE_SCOPE void TclContinuationsEnterDerived(Tcl_Obj *objPtr, jpayne@69: int start, int *clNext); jpayne@69: MODULE_SCOPE ContLineLoc *TclContinuationsGet(Tcl_Obj *objPtr); jpayne@69: MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr, jpayne@69: Tcl_Obj *originObjPtr); jpayne@69: MODULE_SCOPE int TclConvertElement(const char *src, int length, jpayne@69: char *dst, int flags); jpayne@69: MODULE_SCOPE Tcl_Command TclCreateObjCommandInNs ( jpayne@69: Tcl_Interp *interp, jpayne@69: const char *cmdName, jpayne@69: Tcl_Namespace *nsPtr, jpayne@69: Tcl_ObjCmdProc *proc, jpayne@69: ClientData clientData, jpayne@69: Tcl_CmdDeleteProc *deleteProc); jpayne@69: MODULE_SCOPE Tcl_Command TclCreateEnsembleInNs( jpayne@69: Tcl_Interp *interp, jpayne@69: const char *name, jpayne@69: Tcl_Namespace *nameNamespacePtr, jpayne@69: Tcl_Namespace *ensembleNamespacePtr, jpayne@69: int flags); jpayne@69: MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); jpayne@69: MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, jpayne@69: const char *dict, int dictLength, jpayne@69: const char **elementPtr, const char **nextPtr, jpayne@69: int *sizePtr, int *literalPtr); jpayne@69: /* TIP #280 - Modified token based evulation, with line information. */ jpayne@69: MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, jpayne@69: int numBytes, int flags, int line, jpayne@69: int *clNextOuter, const char *outerScript); jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclFileDeleteCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclFileLinkCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclFileMakeDirsCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclFileReadLinkCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclFileRenameCmd; jpayne@69: MODULE_SCOPE Tcl_ObjCmdProc TclFileTemporaryCmd; jpayne@69: MODULE_SCOPE void TclCreateLateExitHandler(Tcl_ExitProc *proc, jpayne@69: ClientData clientData); jpayne@69: MODULE_SCOPE void TclDeleteLateExitHandler(Tcl_ExitProc *proc, jpayne@69: ClientData clientData); jpayne@69: MODULE_SCOPE char * TclDStringAppendObj(Tcl_DString *dsPtr, jpayne@69: Tcl_Obj *objPtr); jpayne@69: MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr, jpayne@69: Tcl_DString *toAppendPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclDStringToObj(Tcl_DString *dsPtr); jpayne@69: MODULE_SCOPE Tcl_Obj *const * TclFetchEnsembleRoot(Tcl_Interp *interp, jpayne@69: Tcl_Obj *const *objv, int objc, int *objcPtr); jpayne@69: MODULE_SCOPE Tcl_Obj *const *TclEnsembleGetRewriteValues(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE Tcl_Namespace *TclEnsureNamespace(Tcl_Interp *interp, jpayne@69: Tcl_Namespace *namespacePtr); jpayne@69: jpayne@69: MODULE_SCOPE void TclFinalizeAllocSubsystem(void); jpayne@69: MODULE_SCOPE void TclFinalizeAsync(void); jpayne@69: MODULE_SCOPE void TclFinalizeDoubleConversion(void); jpayne@69: MODULE_SCOPE void TclFinalizeEncodingSubsystem(void); jpayne@69: MODULE_SCOPE void TclFinalizeEnvironment(void); jpayne@69: MODULE_SCOPE void TclFinalizeEvaluation(void); jpayne@69: MODULE_SCOPE void TclFinalizeExecution(void); jpayne@69: MODULE_SCOPE void TclFinalizeIOSubsystem(void); jpayne@69: MODULE_SCOPE void TclFinalizeFilesystem(void); jpayne@69: MODULE_SCOPE void TclResetFilesystem(void); jpayne@69: MODULE_SCOPE void TclFinalizeLoad(void); jpayne@69: MODULE_SCOPE void TclFinalizeLock(void); jpayne@69: MODULE_SCOPE void TclFinalizeMemorySubsystem(void); jpayne@69: MODULE_SCOPE void TclFinalizeNotifier(void); jpayne@69: MODULE_SCOPE void TclFinalizeObjects(void); jpayne@69: MODULE_SCOPE void TclFinalizePreserve(void); jpayne@69: MODULE_SCOPE void TclFinalizeSynchronization(void); jpayne@69: MODULE_SCOPE void TclFinalizeThreadAlloc(void); jpayne@69: MODULE_SCOPE void TclFinalizeThreadAllocThread(void); jpayne@69: MODULE_SCOPE void TclFinalizeThreadData(int quick); jpayne@69: MODULE_SCOPE void TclFinalizeThreadObjects(void); jpayne@69: MODULE_SCOPE double TclFloor(const mp_int *a); jpayne@69: MODULE_SCOPE void TclFormatNaN(double value, char *buffer); jpayne@69: MODULE_SCOPE int TclFSFileAttrIndex(Tcl_Obj *pathPtr, jpayne@69: const char *attributeName, int *indexPtr); jpayne@69: MODULE_SCOPE Tcl_Command TclNRCreateCommandInNs ( jpayne@69: Tcl_Interp *interp, jpayne@69: const char *cmdName, jpayne@69: Tcl_Namespace *nsPtr, jpayne@69: Tcl_ObjCmdProc *proc, jpayne@69: Tcl_ObjCmdProc *nreProc, jpayne@69: ClientData clientData, jpayne@69: Tcl_CmdDeleteProc *deleteProc); jpayne@69: jpayne@69: MODULE_SCOPE int TclNREvalFile(Tcl_Interp *interp, Tcl_Obj *pathPtr, jpayne@69: const char *encodingName); jpayne@69: MODULE_SCOPE void TclFSUnloadTempFile(Tcl_LoadHandle loadHandle); jpayne@69: MODULE_SCOPE int * TclGetAsyncReadyPtr(void); jpayne@69: MODULE_SCOPE Tcl_Obj * TclGetBgErrorHandler(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp, jpayne@69: Tcl_Obj *objPtr, Tcl_Channel *chanPtr, jpayne@69: int *modePtr, int flags); jpayne@69: MODULE_SCOPE CmdFrame * TclGetCmdFrameForProcedure(Proc *procPtr); jpayne@69: MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, jpayne@69: Tcl_Obj *value, int *code); jpayne@69: MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp, jpayne@69: Tcl_Obj *objPtr, ClientData *clientDataPtr, jpayne@69: int *typePtr); jpayne@69: MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp, jpayne@69: const char *modeString, int *seekFlagPtr, jpayne@69: int *binaryPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE char * TclGetStringStorage(Tcl_Obj *objPtr, jpayne@69: unsigned int *sizePtr); jpayne@69: MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, jpayne@69: Tcl_Obj *unquotedPrefix, int globFlags, jpayne@69: Tcl_GlobTypeData *types); jpayne@69: MODULE_SCOPE int TclIncrObj(Tcl_Interp *interp, Tcl_Obj *valuePtr, jpayne@69: Tcl_Obj *incrPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclIncrObjVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, jpayne@69: Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, int flags); jpayne@69: MODULE_SCOPE int TclInfoExistsCmd(ClientData dummy, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclInfoCoroutineCmd(ClientData dummy, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Obj * TclInfoFrame(Tcl_Interp *interp, CmdFrame *framePtr); jpayne@69: MODULE_SCOPE int TclInfoGlobalsCmd(ClientData dummy, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclInfoLocalsCmd(ClientData dummy, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclInfoVarsCmd(ClientData dummy, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE void TclInitAlloc(void); jpayne@69: MODULE_SCOPE void TclInitDbCkalloc(void); jpayne@69: MODULE_SCOPE void TclInitDoubleConversion(void); jpayne@69: MODULE_SCOPE void TclInitEmbeddedConfigurationInformation( jpayne@69: Tcl_Interp *interp); jpayne@69: MODULE_SCOPE void TclInitEncodingSubsystem(void); jpayne@69: MODULE_SCOPE void TclInitIOSubsystem(void); jpayne@69: MODULE_SCOPE void TclInitLimitSupport(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE void TclInitNamespaceSubsystem(void); jpayne@69: MODULE_SCOPE void TclInitNotifier(void); jpayne@69: MODULE_SCOPE void TclInitObjSubsystem(void); jpayne@69: MODULE_SCOPE const char *TclInitSubsystems(void); jpayne@69: MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclIsBareword(int byte); jpayne@69: MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[], jpayne@69: int forceRelative); jpayne@69: MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); jpayne@69: MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, jpayne@69: Tcl_Obj *listPtr, Tcl_Obj *argPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, jpayne@69: int indexCount, Tcl_Obj *const indexArray[]); jpayne@69: /* TIP #280 */ jpayne@69: MODULE_SCOPE void TclListLines(Tcl_Obj *listObj, int line, int n, jpayne@69: int *lines, Tcl_Obj *const *elems); jpayne@69: MODULE_SCOPE Tcl_Obj * TclListObjCopy(Tcl_Interp *interp, Tcl_Obj *listPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclLsetList(Tcl_Interp *interp, Tcl_Obj *listPtr, jpayne@69: Tcl_Obj *indexPtr, Tcl_Obj *valuePtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclLsetFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, jpayne@69: int indexCount, Tcl_Obj *const indexArray[], jpayne@69: Tcl_Obj *valuePtr); jpayne@69: MODULE_SCOPE Tcl_Command TclMakeEnsemble(Tcl_Interp *interp, const char *name, jpayne@69: const EnsembleImplMap map[]); jpayne@69: MODULE_SCOPE int TclMaxListLength(const char *bytes, int numBytes, jpayne@69: const char **endPtr); jpayne@69: MODULE_SCOPE int TclMergeReturnOptions(Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[], Tcl_Obj **optionsPtrPtr, jpayne@69: int *codePtr, int *levelPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options); jpayne@69: MODULE_SCOPE int TclNokia770Doubles(void); jpayne@69: MODULE_SCOPE void TclNsDecrRefCount(Namespace *nsPtr); jpayne@69: MODULE_SCOPE void TclNsDecrRefCount(Namespace *nsPtr); jpayne@69: MODULE_SCOPE int TclNamespaceDeleted(Namespace *nsPtr); jpayne@69: MODULE_SCOPE void TclObjVarErrMsg(Tcl_Interp *interp, Tcl_Obj *part1Ptr, jpayne@69: Tcl_Obj *part2Ptr, const char *operation, jpayne@69: const char *reason, int index); jpayne@69: MODULE_SCOPE int TclObjInvokeNamespace(Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[], jpayne@69: Tcl_Namespace *nsPtr, int flags); jpayne@69: MODULE_SCOPE int TclObjUnsetVar2(Tcl_Interp *interp, jpayne@69: Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags); jpayne@69: MODULE_SCOPE int TclParseBackslash(const char *src, jpayne@69: int numBytes, int *readPtr, char *dst); jpayne@69: MODULE_SCOPE int TclParseNumber(Tcl_Interp *interp, Tcl_Obj *objPtr, jpayne@69: const char *expected, const char *bytes, jpayne@69: int numBytes, const char **endPtrPtr, int flags); jpayne@69: MODULE_SCOPE void TclParseInit(Tcl_Interp *interp, const char *string, jpayne@69: int numBytes, Tcl_Parse *parsePtr); jpayne@69: MODULE_SCOPE int TclParseAllWhiteSpace(const char *src, int numBytes); jpayne@69: MODULE_SCOPE int TclProcessReturn(Tcl_Interp *interp, jpayne@69: int code, int level, Tcl_Obj *returnOpts); jpayne@69: MODULE_SCOPE int TclpObjLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); jpayne@69: MODULE_SCOPE Tcl_Obj * TclpTempFileName(void); jpayne@69: MODULE_SCOPE Tcl_Obj * TclpTempFileNameForLibrary(Tcl_Interp *interp, Tcl_Obj* pathPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclNewFSPathObj(Tcl_Obj *dirPtr, const char *addStrRep, jpayne@69: int len); jpayne@69: MODULE_SCOPE int TclpDeleteFile(const void *path); jpayne@69: MODULE_SCOPE void TclpFinalizeCondition(Tcl_Condition *condPtr); jpayne@69: MODULE_SCOPE void TclpFinalizeMutex(Tcl_Mutex *mutexPtr); jpayne@69: MODULE_SCOPE void TclpFinalizePipes(void); jpayne@69: MODULE_SCOPE void TclpFinalizeSockets(void); jpayne@69: MODULE_SCOPE int TclCreateSocketAddress(Tcl_Interp *interp, jpayne@69: struct addrinfo **addrlist, jpayne@69: const char *host, int port, int willBind, jpayne@69: const char **errorMsgPtr); jpayne@69: MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr, jpayne@69: Tcl_ThreadCreateProc *proc, ClientData clientData, jpayne@69: int stackSize, int flags); jpayne@69: MODULE_SCOPE int TclpFindVariable(const char *name, int *lengthPtr); jpayne@69: MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, jpayne@69: int *lengthPtr, Tcl_Encoding *encodingPtr); jpayne@69: MODULE_SCOPE void TclpInitLock(void); jpayne@69: MODULE_SCOPE void TclpInitPlatform(void); jpayne@69: MODULE_SCOPE void TclpInitUnlock(void); jpayne@69: MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void); jpayne@69: MODULE_SCOPE void TclpGlobalLock(void); jpayne@69: MODULE_SCOPE void TclpGlobalUnlock(void); jpayne@69: MODULE_SCOPE int TclpMatchFiles(Tcl_Interp *interp, char *separators, jpayne@69: Tcl_DString *dirPtr, char *pattern, char *tail); jpayne@69: MODULE_SCOPE int TclpObjNormalizePath(Tcl_Interp *interp, jpayne@69: Tcl_Obj *pathPtr, int nextCheckpoint); jpayne@69: MODULE_SCOPE void TclpNativeJoinPath(Tcl_Obj *prefix, const char *joining); jpayne@69: MODULE_SCOPE Tcl_Obj * TclpNativeSplitPath(Tcl_Obj *pathPtr, int *lenPtr); jpayne@69: MODULE_SCOPE Tcl_PathType TclpGetNativePathType(Tcl_Obj *pathPtr, jpayne@69: int *driveNameLengthPtr, Tcl_Obj **driveNameRef); jpayne@69: MODULE_SCOPE int TclCrossFilesystemCopy(Tcl_Interp *interp, jpayne@69: Tcl_Obj *source, Tcl_Obj *target); jpayne@69: MODULE_SCOPE int TclpMatchInDirectory(Tcl_Interp *interp, jpayne@69: Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, jpayne@69: const char *pattern, Tcl_GlobTypeData *types); jpayne@69: MODULE_SCOPE ClientData TclpGetNativeCwd(ClientData clientData); jpayne@69: MODULE_SCOPE Tcl_FSDupInternalRepProc TclNativeDupInternalRep; jpayne@69: MODULE_SCOPE Tcl_Obj * TclpObjLink(Tcl_Obj *pathPtr, Tcl_Obj *toPtr, jpayne@69: int linkType); jpayne@69: MODULE_SCOPE int TclpObjChdir(Tcl_Obj *pathPtr); jpayne@69: MODULE_SCOPE Tcl_Channel TclpOpenTemporaryFile(Tcl_Obj *dirObj, jpayne@69: Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, jpayne@69: Tcl_Obj *resultingNameObj); jpayne@69: MODULE_SCOPE Tcl_Obj * TclPathPart(Tcl_Interp *interp, Tcl_Obj *pathPtr, jpayne@69: Tcl_PathPart portion); jpayne@69: MODULE_SCOPE char * TclpReadlink(const char *fileName, jpayne@69: Tcl_DString *linkPtr); jpayne@69: MODULE_SCOPE void TclpSetVariables(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE void * TclThreadStorageKeyGet(Tcl_ThreadDataKey *keyPtr); jpayne@69: MODULE_SCOPE void TclThreadStorageKeySet(Tcl_ThreadDataKey *keyPtr, jpayne@69: void *data); jpayne@69: MODULE_SCOPE void TclpThreadExit(int status); jpayne@69: MODULE_SCOPE void TclRememberCondition(Tcl_Condition *mutex); jpayne@69: MODULE_SCOPE void TclRememberJoinableThread(Tcl_ThreadId id); jpayne@69: MODULE_SCOPE void TclRememberMutex(Tcl_Mutex *mutex); jpayne@69: MODULE_SCOPE void TclRemoveScriptLimitCallbacks(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclReToGlob(Tcl_Interp *interp, const char *reStr, jpayne@69: int reStrLen, Tcl_DString *dsPtr, int *flagsPtr, jpayne@69: int *quantifiersFoundPtr); jpayne@69: MODULE_SCOPE unsigned int TclScanElement(const char *string, int length, jpayne@69: char *flagPtr); jpayne@69: MODULE_SCOPE void TclSetBgErrorHandler(Tcl_Interp *interp, jpayne@69: Tcl_Obj *cmdPrefix); jpayne@69: MODULE_SCOPE void TclSetBignumInternalRep(Tcl_Obj *objPtr, jpayne@69: mp_int *bignumValue); jpayne@69: MODULE_SCOPE int TclSetBooleanFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); jpayne@69: MODULE_SCOPE void TclSetCmdNameObj(Tcl_Interp *interp, Tcl_Obj *objPtr, jpayne@69: Command *cmdPtr); jpayne@69: MODULE_SCOPE void TclSetDuplicateObj(Tcl_Obj *dupPtr, Tcl_Obj *objPtr); jpayne@69: MODULE_SCOPE void TclSetProcessGlobalValue(ProcessGlobalValue *pgvPtr, jpayne@69: Tcl_Obj *newValue, Tcl_Encoding encoding); jpayne@69: MODULE_SCOPE void TclSignalExitThread(Tcl_ThreadId id, int result); jpayne@69: MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp, jpayne@69: Tcl_Obj *const *objv, int objc, int subIdx, jpayne@69: Tcl_Obj *bad, Tcl_Obj *fix); jpayne@69: MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr, jpayne@69: int numBytes); jpayne@69: jpayne@69: typedef int (*memCmpFn_t)(const void*, const void*, size_t); jpayne@69: MODULE_SCOPE int TclStringCmp (Tcl_Obj *value1Ptr, Tcl_Obj *value2Ptr, jpayne@69: int checkEq, int nocase, int reqlength); jpayne@69: MODULE_SCOPE int TclStringCmpOpts (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], jpayne@69: int *nocase, int *reqlength); jpayne@69: MODULE_SCOPE int TclStringMatch(const char *str, int strLen, jpayne@69: const char *pattern, int ptnLen, int flags); jpayne@69: MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj, jpayne@69: Tcl_Obj *patternObj, int flags); jpayne@69: MODULE_SCOPE Tcl_Obj * TclStringReverse(Tcl_Obj *objPtr); jpayne@69: MODULE_SCOPE void TclSubstCompile(Tcl_Interp *interp, const char *bytes, jpayne@69: int numBytes, int flags, int line, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclSubstOptions(Tcl_Interp *interp, int numOpts, jpayne@69: Tcl_Obj *const opts[], int *flagPtr); jpayne@69: MODULE_SCOPE void TclSubstParse(Tcl_Interp *interp, const char *bytes, jpayne@69: int numBytes, int flags, Tcl_Parse *parsePtr, jpayne@69: Tcl_InterpState *statePtr); jpayne@69: MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, jpayne@69: int count, int *tokensLeftPtr, int line, jpayne@69: int *clNextOuter, const char *outerScript); jpayne@69: MODULE_SCOPE int TclTrim(const char *bytes, int numBytes, jpayne@69: const char *trim, int numTrim, int *trimRight); jpayne@69: MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes, jpayne@69: const char *trim, int numTrim); jpayne@69: MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes, jpayne@69: const char *trim, int numTrim); jpayne@69: MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct); jpayne@69: MODULE_SCOPE int TclUtfToUCS4(const char *, int *); jpayne@69: MODULE_SCOPE int TclUCS4ToUtf(int, char *); jpayne@69: MODULE_SCOPE int TclUCS4ToLower(int ch); jpayne@69: #if TCL_UTF_MAX == 4 jpayne@69: MODULE_SCOPE int TclGetUCS4(Tcl_Obj *, int); jpayne@69: MODULE_SCOPE int TclUniCharToUCS4(const Tcl_UniChar *, int *); jpayne@69: #else jpayne@69: # define TclGetUCS4 Tcl_GetUniChar jpayne@69: # define TclUniCharToUCS4(src, ptr) (*ptr = *(src),1) jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * Bytes F0-F4 are start-bytes for 4-byte sequences. jpayne@69: * Byte 0xED can be the start-byte of an upper surrogate. In that case, jpayne@69: * TclUtfToUCS4() might read the lower surrogate following it too. jpayne@69: */ jpayne@69: # define TclUCS4Complete(src, length) (((unsigned)(UCHAR(*(src)) - 0xF0) < 5) \ jpayne@69: ? ((length) >= 4) : (UCHAR(*(src)) == 0xED) ? ((length) >= 6) : Tcl_UtfCharComplete((src), (length))) jpayne@69: MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData); jpayne@69: MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr); jpayne@69: MODULE_SCOPE int TclpDlopen(Tcl_Interp *interp, Tcl_Obj *pathPtr, jpayne@69: Tcl_LoadHandle *loadHandle, jpayne@69: Tcl_FSUnloadFileProc **unloadProcPtr, int flags); jpayne@69: MODULE_SCOPE int TclpUtime(Tcl_Obj *pathPtr, struct utimbuf *tval); jpayne@69: #ifdef TCL_LOAD_FROM_MEMORY jpayne@69: MODULE_SCOPE void * TclpLoadMemoryGetBuffer(Tcl_Interp *interp, int size); jpayne@69: MODULE_SCOPE int TclpLoadMemory(Tcl_Interp *interp, void *buffer, jpayne@69: int size, int codeSize, Tcl_LoadHandle *loadHandle, jpayne@69: Tcl_FSUnloadFileProc **unloadProcPtr, int flags); jpayne@69: #endif jpayne@69: MODULE_SCOPE void TclInitThreadStorage(void); jpayne@69: MODULE_SCOPE void TclFinalizeThreadDataThread(void); jpayne@69: MODULE_SCOPE void TclFinalizeThreadStorage(void); jpayne@69: jpayne@69: /* TclWideMUInt -- wide integer used for measurement calculations: */ jpayne@69: #if (!defined(_WIN32) || !defined(_MSC_VER) || (_MSC_VER >= 1400)) jpayne@69: # define TclWideMUInt Tcl_WideUInt jpayne@69: #else jpayne@69: /* older MSVS may not allow conversions between unsigned __int64 and double) */ jpayne@69: # define TclWideMUInt Tcl_WideInt jpayne@69: #endif jpayne@69: #ifdef TCL_WIDE_CLICKS jpayne@69: MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void); jpayne@69: MODULE_SCOPE double TclpWideClicksToNanoseconds(Tcl_WideInt clicks); jpayne@69: MODULE_SCOPE double TclpWideClickInMicrosec(void); jpayne@69: #else jpayne@69: # ifdef _WIN32 jpayne@69: # define TCL_WIDE_CLICKS 1 jpayne@69: MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void); jpayne@69: MODULE_SCOPE double TclpWideClickInMicrosec(void); jpayne@69: # define TclpWideClicksToNanoseconds(clicks) \ jpayne@69: ((double)(clicks) * TclpWideClickInMicrosec() * 1000) jpayne@69: # endif jpayne@69: #endif jpayne@69: MODULE_SCOPE Tcl_WideInt TclpGetMicroseconds(void); jpayne@69: jpayne@69: MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE void * TclpThreadCreateKey(void); jpayne@69: MODULE_SCOPE void TclpThreadDeleteKey(void *keyPtr); jpayne@69: MODULE_SCOPE void TclpThreadSetGlobalTSD(void *tsdKeyPtr, void *ptr); jpayne@69: MODULE_SCOPE void * TclpThreadGetGlobalTSD(void *tsdKeyPtr); jpayne@69: jpayne@69: MODULE_SCOPE void TclErrorStackResetIf(Tcl_Interp *interp, const char *msg, int length); jpayne@69: jpayne@69: /* jpayne@69: * Many parsing tasks need a common definition of whitespace. jpayne@69: * Use this routine and macro to achieve that and place jpayne@69: * optimization (fragile on changes) in one place. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE int TclIsSpaceProc(int byte); jpayne@69: # define TclIsSpaceProcM(byte) \ jpayne@69: (((byte) > 0x20) ? 0 : TclIsSpaceProc(byte)) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Command procedures in the generic core: jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE int Tcl_AfterObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_AppendObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ApplyObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitArrayCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE Tcl_Command TclInitBinaryCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int Tcl_BreakObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_CaseObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_CatchObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_CdObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitChanCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclChanCreateObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclChanPostEventObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclChanPopObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclChanPushObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE void TclClockInit(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclClockOldscanObjCmd( jpayne@69: ClientData clientData, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_CloseObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ConcatObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ContinueObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_TimerToken TclCreateAbsoluteTimerHandler( jpayne@69: Tcl_Time *timePtr, Tcl_TimerProc *proc, jpayne@69: ClientData clientData); jpayne@69: MODULE_SCOPE int TclDefaultBgErrorHandlerObjCmd( jpayne@69: ClientData clientData, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitDictCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclDictWithFinish(Tcl_Interp *interp, Var *varPtr, jpayne@69: Var *arrayPtr, Tcl_Obj *part1Ptr, jpayne@69: Tcl_Obj *part2Ptr, int index, int pathc, jpayne@69: Tcl_Obj *const pathv[], Tcl_Obj *keysPtr); jpayne@69: MODULE_SCOPE Tcl_Obj * TclDictWithInit(Tcl_Interp *interp, Tcl_Obj *dictPtr, jpayne@69: int pathc, Tcl_Obj *const pathv[]); jpayne@69: MODULE_SCOPE int Tcl_DisassembleObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: jpayne@69: /* Assemble command function */ jpayne@69: MODULE_SCOPE int Tcl_AssembleObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclNRAssembleObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitEncodingCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclMakeEncodingCommandSafe(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int Tcl_EofObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ErrorObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_EvalObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ExecObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ExitObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ExprObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_FblockedObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_FconfigureObjCmd( jpayne@69: ClientData clientData, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_FcopyObjCmd(ClientData dummy, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitFileCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclMakeFileCommandSafe(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int Tcl_FileEventObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_FlushObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ForObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ForeachObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_FormatObjCmd(ClientData dummy, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_GetsObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_GlobalObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_GlobObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_IfObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_IncrObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitInfoCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int Tcl_InterpObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int argc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_JoinObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LappendObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LassignObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LindexObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LinsertObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LlengthObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ListObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LmapObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LoadObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LrangeObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LrepeatObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LreplaceObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LreverseObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LsearchObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LsetObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_LsortObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitNamespaceCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int TclNamespaceEnsembleCmd(ClientData dummy, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_OpenObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_PackageObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_PidObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitPrefixCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int Tcl_PutsObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_PwdObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ReadObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_RegexpObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_RegsubObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_RenameObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_RepresentationCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ReturnObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ScanObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_SeekObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_SetObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_SplitObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_SocketObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_SourceObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE Tcl_Command TclInitStringCmd(Tcl_Interp *interp); jpayne@69: MODULE_SCOPE int Tcl_SubstObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_SwitchObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_TellObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_ThrowObjCmd(ClientData dummy, Tcl_Interp *interp, jpayne@69: int objc, Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_TimeObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_TimeRateObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_TraceObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_TryObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_UnloadObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_UnsetObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_UpdateObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_UplevelObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_UpvarObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_VariableObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_VwaitObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int Tcl_WhileObjCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Compilation procedures for commands in the generic core: jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE int TclCompileAppendCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileArrayExistsCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileArraySetCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileArrayUnsetCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBreakCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileCatchCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileClockClicksCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileClockReadingCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileConcatCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileContinueCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictAppendCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictCreateCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictExistsCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictForCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictGetCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictIncrCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictLappendCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictMapCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictMergeCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictSetCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictUnsetCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictUpdateCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileDictWithCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileEnsemble(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileErrorCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileExprCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileForCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileForeachCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileFormatCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileGlobalCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileIfCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileInfoCommandsCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileInfoCoroutineCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileInfoExistsCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileInfoLevelCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileInfoObjectClassCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileInfoObjectIsACmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileInfoObjectNamespaceCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileIncrCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLappendCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLassignCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLindexCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLinsertCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileListCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLlengthCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLmapCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLrangeCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLreplaceCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLsetCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileNamespaceCodeCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileNamespaceCurrentCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileNamespaceOriginCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileNamespaceQualifiersCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileNamespaceTailCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileNamespaceUpvarCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileNamespaceWhichCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileNoOp(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileObjectNextCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileObjectNextToCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileObjectSelfCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileRegexpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileRegsubCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileReturnCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileSetCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringCatCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringCmpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringEqualCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringFirstCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringIndexCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringIsCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringLastCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringLenCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringMapCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringMatchCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringRangeCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringReplaceCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringToLowerCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringToTitleCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringToUpperCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringTrimCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringTrimLCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStringTrimRCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileSubstCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileSwitchCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileTailcallCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileThrowCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileTryCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileUnsetCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileUpvarCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileVariableCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileWhileCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileYieldCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileYieldToCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic0ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic1ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic2ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic3ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic0Or1ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic1Or2ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic2Or3ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic0To2ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasic1To3ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasicMin0ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasicMin1ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileBasicMin2ArgCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: jpayne@69: MODULE_SCOPE int TclInvertOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileInvertOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclNotOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileNotOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclAddOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileAddOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclMulOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileMulOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclAndOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileAndOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclOrOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileOrOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclXorOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileXorOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclPowOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompilePowOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclLshiftOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileLshiftOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclRshiftOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileRshiftOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclModOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileModOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclNeqOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileNeqOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclStrneqOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileStrneqOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclInOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileInOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclNiOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileNiOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclMinusOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileMinusOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclDivOpCmd(ClientData clientData, jpayne@69: Tcl_Interp *interp, int objc, jpayne@69: Tcl_Obj *const objv[]); jpayne@69: MODULE_SCOPE int TclCompileDivOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLessOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileLeqOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileGreaterOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileGeqOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileEqOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: MODULE_SCOPE int TclCompileStreqOpCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: jpayne@69: MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp, jpayne@69: Tcl_Parse *parsePtr, Command *cmdPtr, jpayne@69: struct CompileEnv *envPtr); jpayne@69: jpayne@69: /* jpayne@69: * Functions defined in generic/tclVar.c and currently exported only for use jpayne@69: * by the bytecode compiler and engine. Some of these could later be placed in jpayne@69: * the public interface. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE Var * TclObjLookupVarEx(Tcl_Interp * interp, jpayne@69: Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags, jpayne@69: const char *msg, const int createPart1, jpayne@69: const int createPart2, Var **arrayPtrPtr); jpayne@69: MODULE_SCOPE Var * TclLookupArrayElement(Tcl_Interp *interp, jpayne@69: Tcl_Obj *arrayNamePtr, Tcl_Obj *elNamePtr, jpayne@69: const int flags, const char *msg, jpayne@69: const int createPart1, const int createPart2, jpayne@69: Var *arrayPtr, int index); jpayne@69: MODULE_SCOPE Tcl_Obj * TclPtrGetVarIdx(Tcl_Interp *interp, jpayne@69: Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, jpayne@69: Tcl_Obj *part2Ptr, const int flags, int index); jpayne@69: MODULE_SCOPE Tcl_Obj * TclPtrSetVarIdx(Tcl_Interp *interp, jpayne@69: Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, jpayne@69: Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, jpayne@69: const int flags, int index); jpayne@69: MODULE_SCOPE Tcl_Obj * TclPtrIncrObjVarIdx(Tcl_Interp *interp, jpayne@69: Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, jpayne@69: Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, jpayne@69: const int flags, int index); jpayne@69: MODULE_SCOPE int TclPtrObjMakeUpvarIdx(Tcl_Interp *interp, jpayne@69: Var *otherPtr, Tcl_Obj *myNamePtr, int myFlags, jpayne@69: int index); jpayne@69: MODULE_SCOPE int TclPtrUnsetVarIdx(Tcl_Interp *interp, Var *varPtr, jpayne@69: Var *arrayPtr, Tcl_Obj *part1Ptr, jpayne@69: Tcl_Obj *part2Ptr, const int flags, jpayne@69: int index); jpayne@69: MODULE_SCOPE void TclInvalidateNsPath(Namespace *nsPtr); jpayne@69: MODULE_SCOPE void TclFindArrayPtrElements(Var *arrayPtr, jpayne@69: Tcl_HashTable *tablePtr); jpayne@69: jpayne@69: /* jpayne@69: * The new extended interface to the variable traces. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE int TclObjCallVarTraces(Interp *iPtr, Var *arrayPtr, jpayne@69: Var *varPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, jpayne@69: int flags, int leaveErrMsg, int index); jpayne@69: jpayne@69: /* jpayne@69: * So tclObj.c and tclDictObj.c can share these implementations. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE int TclCompareObjKeys(void *keyPtr, Tcl_HashEntry *hPtr); jpayne@69: MODULE_SCOPE void TclFreeObjEntry(Tcl_HashEntry *hPtr); jpayne@69: MODULE_SCOPE unsigned TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr); jpayne@69: jpayne@69: MODULE_SCOPE int TclFullFinalizationRequested(void); jpayne@69: jpayne@69: /* jpayne@69: * Utility routines for encoding index values as integers. Used by both jpayne@69: * some of the command compilers and by [lsort] and [lsearch]. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE int TclIndexEncode(Tcl_Interp *interp, Tcl_Obj *objPtr, jpayne@69: int before, int after, int *indexPtr); jpayne@69: MODULE_SCOPE int TclIndexDecode(int encoded, int endValue); jpayne@69: jpayne@69: MODULE_SCOPE void TclBN_s_mp_reverse(unsigned char *s, size_t len); jpayne@69: jpayne@69: /* Constants used in index value encoding routines. */ jpayne@69: #define TCL_INDEX_END (-2) jpayne@69: #define TCL_INDEX_BEFORE (-1) jpayne@69: #define TCL_INDEX_START (0) jpayne@69: #define TCL_INDEX_AFTER (INT_MAX) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macros used by the Tcl core to create and release Tcl objects. jpayne@69: * TclNewObj(objPtr) creates a new object denoting an empty string. jpayne@69: * TclDecrRefCount(objPtr) decrements the object's reference count, and frees jpayne@69: * the object if its reference count is zero. These macros are inline versions jpayne@69: * of Tcl_NewObj() and Tcl_DecrRefCount(). Notice that the names differ in not jpayne@69: * having a "_" after the "Tcl". Notice also that these macros reference their jpayne@69: * argument more than once, so you should avoid calling them with an jpayne@69: * expression that is expensive to compute or has side effects. The ANSI C jpayne@69: * "prototypes" for these macros are: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclNewObj(Tcl_Obj *objPtr); jpayne@69: * MODULE_SCOPE void TclDecrRefCount(Tcl_Obj *objPtr); jpayne@69: * jpayne@69: * These macros are defined in terms of two macros that depend on memory jpayne@69: * allocator in use: TclAllocObjStorage, TclFreeObjStorage. They are defined jpayne@69: * below. jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * DTrace object allocation probe macros. jpayne@69: */ jpayne@69: jpayne@69: #ifdef USE_DTRACE jpayne@69: #ifndef _TCLDTRACE_H jpayne@69: #include "tclDTrace.h" jpayne@69: #endif jpayne@69: #define TCL_DTRACE_OBJ_CREATE(objPtr) TCL_OBJ_CREATE(objPtr) jpayne@69: #define TCL_DTRACE_OBJ_FREE(objPtr) TCL_OBJ_FREE(objPtr) jpayne@69: #else /* USE_DTRACE */ jpayne@69: #define TCL_DTRACE_OBJ_CREATE(objPtr) {} jpayne@69: #define TCL_DTRACE_OBJ_FREE(objPtr) {} jpayne@69: #endif /* USE_DTRACE */ jpayne@69: jpayne@69: #ifdef TCL_COMPILE_STATS jpayne@69: # define TclIncrObjsAllocated() \ jpayne@69: tclObjsAlloced++ jpayne@69: # define TclIncrObjsFreed() \ jpayne@69: tclObjsFreed++ jpayne@69: #else jpayne@69: # define TclIncrObjsAllocated() jpayne@69: # define TclIncrObjsFreed() jpayne@69: #endif /* TCL_COMPILE_STATS */ jpayne@69: jpayne@69: # define TclAllocObjStorage(objPtr) \ jpayne@69: TclAllocObjStorageEx(NULL, (objPtr)) jpayne@69: jpayne@69: # define TclFreeObjStorage(objPtr) \ jpayne@69: TclFreeObjStorageEx(NULL, (objPtr)) jpayne@69: jpayne@69: #ifndef TCL_MEM_DEBUG jpayne@69: # define TclNewObj(objPtr) \ jpayne@69: TclIncrObjsAllocated(); \ jpayne@69: TclAllocObjStorage(objPtr); \ jpayne@69: (objPtr)->refCount = 0; \ jpayne@69: (objPtr)->bytes = tclEmptyStringRep; \ jpayne@69: (objPtr)->length = 0; \ jpayne@69: (objPtr)->typePtr = NULL; \ jpayne@69: TCL_DTRACE_OBJ_CREATE(objPtr) jpayne@69: jpayne@69: /* jpayne@69: * Invalidate the string rep first so we can use the bytes value for our jpayne@69: * pointer chain, and signal an obj deletion (as opposed to shimmering) with jpayne@69: * 'length == -1'. jpayne@69: * Use empty 'if ; else' to handle use in unbraced outer if/else conditions. jpayne@69: */ jpayne@69: jpayne@69: # define TclDecrRefCount(objPtr) \ jpayne@69: if ((objPtr)->refCount-- > 1) ; else { \ jpayne@69: if (!(objPtr)->typePtr || !(objPtr)->typePtr->freeIntRepProc) { \ jpayne@69: TCL_DTRACE_OBJ_FREE(objPtr); \ jpayne@69: if ((objPtr)->bytes \ jpayne@69: && ((objPtr)->bytes != tclEmptyStringRep)) { \ jpayne@69: ckfree((char *) (objPtr)->bytes); \ jpayne@69: } \ jpayne@69: (objPtr)->length = -1; \ jpayne@69: TclFreeObjStorage(objPtr); \ jpayne@69: TclIncrObjsFreed(); \ jpayne@69: } else { \ jpayne@69: TclFreeObj(objPtr); \ jpayne@69: } \ jpayne@69: } jpayne@69: jpayne@69: #if defined(PURIFY) jpayne@69: jpayne@69: /* jpayne@69: * The PURIFY mode is like the regular mode, but instead of doing block jpayne@69: * Tcl_Obj allocation and keeping a freed list for efficiency, it always jpayne@69: * allocates and frees a single Tcl_Obj so that tools like Purify can better jpayne@69: * track memory leaks. jpayne@69: */ jpayne@69: jpayne@69: # define TclAllocObjStorageEx(interp, objPtr) \ jpayne@69: (objPtr) = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj)) jpayne@69: jpayne@69: # define TclFreeObjStorageEx(interp, objPtr) \ jpayne@69: ckfree((char *) (objPtr)) jpayne@69: jpayne@69: #undef USE_THREAD_ALLOC jpayne@69: #undef USE_TCLALLOC jpayne@69: #elif defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) jpayne@69: jpayne@69: /* jpayne@69: * The TCL_THREADS mode is like the regular mode but allocates Tcl_Obj's from jpayne@69: * per-thread caches. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE Tcl_Obj * TclThreadAllocObj(void); jpayne@69: MODULE_SCOPE void TclThreadFreeObj(Tcl_Obj *); jpayne@69: MODULE_SCOPE Tcl_Mutex *TclpNewAllocMutex(void); jpayne@69: MODULE_SCOPE void TclFreeAllocCache(void *); jpayne@69: MODULE_SCOPE void * TclpGetAllocCache(void); jpayne@69: MODULE_SCOPE void TclpSetAllocCache(void *); jpayne@69: MODULE_SCOPE void TclpFreeAllocMutex(Tcl_Mutex *mutex); jpayne@69: MODULE_SCOPE void TclpFreeAllocCache(void *); jpayne@69: jpayne@69: /* jpayne@69: * These macros need to be kept in sync with the code of TclThreadAllocObj() jpayne@69: * and TclThreadFreeObj(). jpayne@69: * jpayne@69: * Note that the optimiser should resolve the case (interp==NULL) at compile jpayne@69: * time. jpayne@69: */ jpayne@69: jpayne@69: # define ALLOC_NOBJHIGH 1200 jpayne@69: jpayne@69: # define TclAllocObjStorageEx(interp, objPtr) \ jpayne@69: do { \ jpayne@69: AllocCache *cachePtr; \ jpayne@69: if (((interp) == NULL) || \ jpayne@69: ((cachePtr = ((Interp *)(interp))->allocCache), \ jpayne@69: (cachePtr->numObjects == 0))) { \ jpayne@69: (objPtr) = TclThreadAllocObj(); \ jpayne@69: } else { \ jpayne@69: (objPtr) = cachePtr->firstObjPtr; \ jpayne@69: cachePtr->firstObjPtr = (Tcl_Obj *)(objPtr)->internalRep.twoPtrValue.ptr1; \ jpayne@69: --cachePtr->numObjects; \ jpayne@69: } \ jpayne@69: } while (0) jpayne@69: jpayne@69: # define TclFreeObjStorageEx(interp, objPtr) \ jpayne@69: do { \ jpayne@69: AllocCache *cachePtr; \ jpayne@69: if (((interp) == NULL) || \ jpayne@69: ((cachePtr = ((Interp *)(interp))->allocCache), \ jpayne@69: ((cachePtr->numObjects == 0) || \ jpayne@69: (cachePtr->numObjects >= ALLOC_NOBJHIGH)))) { \ jpayne@69: TclThreadFreeObj(objPtr); \ jpayne@69: } else { \ jpayne@69: (objPtr)->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; \ jpayne@69: cachePtr->firstObjPtr = objPtr; \ jpayne@69: ++cachePtr->numObjects; \ jpayne@69: } \ jpayne@69: } while (0) jpayne@69: jpayne@69: #else /* not PURIFY or USE_THREAD_ALLOC */ jpayne@69: jpayne@69: #if defined(USE_TCLALLOC) && USE_TCLALLOC jpayne@69: MODULE_SCOPE void TclFinalizeAllocSubsystem(); jpayne@69: MODULE_SCOPE void TclInitAlloc(); jpayne@69: #else jpayne@69: # define USE_TCLALLOC 0 jpayne@69: #endif jpayne@69: jpayne@69: #ifdef TCL_THREADS jpayne@69: /* declared in tclObj.c */ jpayne@69: MODULE_SCOPE Tcl_Mutex tclObjMutex; jpayne@69: #endif jpayne@69: jpayne@69: # define TclAllocObjStorageEx(interp, objPtr) \ jpayne@69: do { \ jpayne@69: Tcl_MutexLock(&tclObjMutex); \ jpayne@69: if (tclFreeObjList == NULL) { \ jpayne@69: TclAllocateFreeObjects(); \ jpayne@69: } \ jpayne@69: (objPtr) = tclFreeObjList; \ jpayne@69: tclFreeObjList = (Tcl_Obj *) \ jpayne@69: tclFreeObjList->internalRep.twoPtrValue.ptr1; \ jpayne@69: Tcl_MutexUnlock(&tclObjMutex); \ jpayne@69: } while (0) jpayne@69: jpayne@69: # define TclFreeObjStorageEx(interp, objPtr) \ jpayne@69: do { \ jpayne@69: Tcl_MutexLock(&tclObjMutex); \ jpayne@69: (objPtr)->internalRep.twoPtrValue.ptr1 = (void *) tclFreeObjList; \ jpayne@69: tclFreeObjList = (objPtr); \ jpayne@69: Tcl_MutexUnlock(&tclObjMutex); \ jpayne@69: } while (0) jpayne@69: #endif jpayne@69: jpayne@69: #else /* TCL_MEM_DEBUG */ jpayne@69: MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, jpayne@69: int line); jpayne@69: jpayne@69: # define TclDbNewObj(objPtr, file, line) \ jpayne@69: do { \ jpayne@69: TclIncrObjsAllocated(); \ jpayne@69: (objPtr) = (Tcl_Obj *) \ jpayne@69: Tcl_DbCkalloc(sizeof(Tcl_Obj), (file), (line)); \ jpayne@69: TclDbInitNewObj((objPtr), (file), (line)); \ jpayne@69: TCL_DTRACE_OBJ_CREATE(objPtr); \ jpayne@69: } while (0) jpayne@69: jpayne@69: # define TclNewObj(objPtr) \ jpayne@69: TclDbNewObj(objPtr, __FILE__, __LINE__); jpayne@69: jpayne@69: # define TclDecrRefCount(objPtr) \ jpayne@69: Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) jpayne@69: jpayne@69: # define TclNewListObjDirect(objc, objv) \ jpayne@69: TclDbNewListObjDirect(objc, objv, __FILE__, __LINE__) jpayne@69: jpayne@69: #undef USE_THREAD_ALLOC jpayne@69: #endif /* TCL_MEM_DEBUG */ jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro used by the Tcl core to set a Tcl_Obj's string representation to a jpayne@69: * copy of the "len" bytes starting at "bytePtr". This code works even if the jpayne@69: * byte array contains NULLs as long as the length is correct. Because "len" jpayne@69: * is referenced multiple times, it should be as simple an expression as jpayne@69: * possible. The ANSI C "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclInitStringRep(Tcl_Obj *objPtr, char *bytePtr, int len); jpayne@69: * jpayne@69: * This macro should only be called on an unshared objPtr where jpayne@69: * objPtr->typePtr->freeIntRepProc == NULL jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclInitStringRep(objPtr, bytePtr, len) \ jpayne@69: if ((len) == 0) { \ jpayne@69: (objPtr)->bytes = tclEmptyStringRep; \ jpayne@69: (objPtr)->length = 0; \ jpayne@69: } else { \ jpayne@69: (objPtr)->bytes = (char *) ckalloc((unsigned int)(len) + 1U); \ jpayne@69: memcpy((objPtr)->bytes, (bytePtr), (len)); \ jpayne@69: (objPtr)->bytes[len] = '\0'; \ jpayne@69: (objPtr)->length = (len); \ jpayne@69: } jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro used by the Tcl core to get the string representation's byte array jpayne@69: * pointer from a Tcl_Obj. This is an inline version of Tcl_GetString(). The jpayne@69: * macro's expression result is the string rep's byte pointer which might be jpayne@69: * NULL. The bytes referenced by this pointer must not be modified by the jpayne@69: * caller. The ANSI C "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE char * TclGetString(Tcl_Obj *objPtr); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclGetString(objPtr) \ jpayne@69: ((objPtr)->bytes? (objPtr)->bytes : Tcl_GetString((objPtr))) jpayne@69: jpayne@69: #define TclGetStringFromObj(objPtr, lenPtr) \ jpayne@69: ((objPtr)->bytes \ jpayne@69: ? (*(lenPtr) = (objPtr)->length, (objPtr)->bytes) \ jpayne@69: : Tcl_GetStringFromObj((objPtr), (lenPtr))) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro used by the Tcl core to clean out an object's internal jpayne@69: * representation. Does not actually reset the rep's bytes. The ANSI C jpayne@69: * "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclFreeIntRep(Tcl_Obj *objPtr); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclFreeIntRep(objPtr) \ jpayne@69: if ((objPtr)->typePtr != NULL) { \ jpayne@69: if ((objPtr)->typePtr->freeIntRepProc != NULL) { \ jpayne@69: (objPtr)->typePtr->freeIntRepProc(objPtr); \ jpayne@69: } \ jpayne@69: (objPtr)->typePtr = NULL; \ jpayne@69: } jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro used by the Tcl core to clean out an object's string representation. jpayne@69: * The ANSI C "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclInvalidateStringRep(Tcl_Obj *objPtr); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclInvalidateStringRep(objPtr) \ jpayne@69: do { \ jpayne@69: Tcl_Obj *_isobjPtr = (Tcl_Obj *)(objPtr); \ jpayne@69: if (_isobjPtr->bytes != NULL) { \ jpayne@69: if (_isobjPtr->bytes != tclEmptyStringRep) { \ jpayne@69: ckfree((char *)_isobjPtr->bytes); \ jpayne@69: } \ jpayne@69: _isobjPtr->bytes = NULL; \ jpayne@69: } \ jpayne@69: } while (0) jpayne@69: jpayne@69: #define TclHasStringRep(objPtr) \ jpayne@69: ((objPtr)->bytes != NULL) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macros used by the Tcl core to grow Tcl_Token arrays. They use the same jpayne@69: * growth algorithm as used in tclStringObj.c for growing strings. The ANSI C jpayne@69: * "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclGrowTokenArray(Tcl_Token *tokenPtr, int used, jpayne@69: * int available, int append, jpayne@69: * Tcl_Token *staticPtr); jpayne@69: * MODULE_SCOPE void TclGrowParseTokenArray(Tcl_Parse *parsePtr, jpayne@69: * int append); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: /* General tuning for minimum growth in Tcl growth algorithms */ jpayne@69: #ifndef TCL_MIN_GROWTH jpayne@69: # ifdef TCL_GROWTH_MIN_ALLOC jpayne@69: /* Support for any legacy tuners */ jpayne@69: # define TCL_MIN_GROWTH TCL_GROWTH_MIN_ALLOC jpayne@69: # else jpayne@69: # define TCL_MIN_GROWTH 1024 jpayne@69: # endif jpayne@69: #endif jpayne@69: jpayne@69: /* Token growth tuning, default to the general value. */ jpayne@69: #ifndef TCL_MIN_TOKEN_GROWTH jpayne@69: #define TCL_MIN_TOKEN_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_Token) jpayne@69: #endif jpayne@69: jpayne@69: #define TCL_MAX_TOKENS (int)(UINT_MAX / sizeof(Tcl_Token)) jpayne@69: #define TclGrowTokenArray(tokenPtr, used, available, append, staticPtr) \ jpayne@69: do { \ jpayne@69: int _needed = (used) + (append); \ jpayne@69: if (_needed > TCL_MAX_TOKENS) { \ jpayne@69: Tcl_Panic("max # of tokens for a Tcl parse (%d) exceeded", \ jpayne@69: TCL_MAX_TOKENS); \ jpayne@69: } \ jpayne@69: if (_needed > (available)) { \ jpayne@69: int allocated = 2 * _needed; \ jpayne@69: Tcl_Token *oldPtr = (tokenPtr); \ jpayne@69: Tcl_Token *newPtr; \ jpayne@69: if (oldPtr == (staticPtr)) { \ jpayne@69: oldPtr = NULL; \ jpayne@69: } \ jpayne@69: if (allocated > TCL_MAX_TOKENS) { \ jpayne@69: allocated = TCL_MAX_TOKENS; \ jpayne@69: } \ jpayne@69: newPtr = (Tcl_Token *) attemptckrealloc((char *) oldPtr, \ jpayne@69: (unsigned int) (allocated * sizeof(Tcl_Token))); \ jpayne@69: if (newPtr == NULL) { \ jpayne@69: allocated = _needed + (append) + TCL_MIN_TOKEN_GROWTH; \ jpayne@69: if (allocated > TCL_MAX_TOKENS) { \ jpayne@69: allocated = TCL_MAX_TOKENS; \ jpayne@69: } \ jpayne@69: newPtr = (Tcl_Token *) ckrealloc((char *) oldPtr, \ jpayne@69: (unsigned int) (allocated * sizeof(Tcl_Token))); \ jpayne@69: } \ jpayne@69: (available) = allocated; \ jpayne@69: if (oldPtr == NULL) { \ jpayne@69: memcpy(newPtr, staticPtr, \ jpayne@69: (size_t) ((used) * sizeof(Tcl_Token))); \ jpayne@69: } \ jpayne@69: (tokenPtr) = newPtr; \ jpayne@69: } \ jpayne@69: } while (0) jpayne@69: jpayne@69: #define TclGrowParseTokenArray(parsePtr, append) \ jpayne@69: TclGrowTokenArray((parsePtr)->tokenPtr, (parsePtr)->numTokens, \ jpayne@69: (parsePtr)->tokensAvailable, (append), \ jpayne@69: (parsePtr)->staticTokens) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro used by the Tcl core get a unicode char from a utf string. It checks jpayne@69: * to see if we have a one-byte utf char before calling the real jpayne@69: * Tcl_UtfToUniChar, as this will save a lot of time for primarily ASCII jpayne@69: * string handling. The macro's expression result is 1 for the 1-byte case or jpayne@69: * the result of Tcl_UtfToUniChar. The ANSI C "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE int TclUtfToUniChar(const char *string, Tcl_UniChar *ch); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclUtfToUniChar(str, chPtr) \ jpayne@69: (((UCHAR(*(str))) < 0x80) ? \ jpayne@69: ((*(chPtr) = UCHAR(*(str))), 1) \ jpayne@69: : Tcl_UtfToUniChar(str, chPtr)) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro counterpart of the Tcl_NumUtfChars() function. To be used in speed- jpayne@69: * -sensitive points where it pays to avoid a function call in the common case jpayne@69: * of counting along a string of all one-byte characters. The ANSI C jpayne@69: * "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclNumUtfChars(int numChars, const char *bytes, jpayne@69: * int numBytes); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclNumUtfChars(numChars, bytes, numBytes) \ jpayne@69: do { \ jpayne@69: int _count, _i = (numBytes); \ jpayne@69: unsigned char *_str = (unsigned char *) (bytes); \ jpayne@69: while (_i && (*_str < 0xC0)) { _i--; _str++; } \ jpayne@69: _count = (numBytes) - _i; \ jpayne@69: if (_i) { \ jpayne@69: _count += Tcl_NumUtfChars((bytes) + _count, _i); \ jpayne@69: } \ jpayne@69: (numChars) = _count; \ jpayne@69: } while (0); jpayne@69: jpayne@69: #define TclUtfPrev(src, start) \ jpayne@69: (((src) < (start)+2) ? (start) : \ jpayne@69: (UCHAR(*((src) - 1))) < 0x80 ? (src)-1 : \ jpayne@69: Tcl_UtfPrev(src, start)) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro that encapsulates the logic that determines when it is safe to jpayne@69: * interpret a string as a byte array directly. In summary, the object must be jpayne@69: * a byte array and must not have a string representation (as the operations jpayne@69: * that it is used in are defined on strings, not byte arrays). Theoretically jpayne@69: * it is possible to also be efficient in the case where the object's bytes jpayne@69: * field is filled by generation from the byte array (c.f. list canonicality) jpayne@69: * but we don't do that at the moment since this is purely about efficiency. jpayne@69: * The ANSI C "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE int TclIsPureByteArray(Tcl_Obj *objPtr); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclIsPureByteArray(objPtr) \ jpayne@69: (((objPtr)->typePtr==&tclByteArrayType) && ((objPtr)->bytes==NULL)) jpayne@69: #define TclIsPureDict(objPtr) \ jpayne@69: (((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclDictType)) jpayne@69: jpayne@69: #define TclIsPureList(objPtr) \ jpayne@69: (((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclListType)) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro used by the Tcl core to compare Unicode strings. On big-endian jpayne@69: * systems we can use the more efficient memcmp, but this would not be jpayne@69: * lexically correct on little-endian systems. The ANSI C "prototype" for jpayne@69: * this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE int TclUniCharNcmp(const Tcl_UniChar *cs, jpayne@69: * const Tcl_UniChar *ct, unsigned long n); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #if defined(WORDS_BIGENDIAN) && (TCL_UTF_MAX != 4) jpayne@69: # define TclUniCharNcmp(cs,ct,n) memcmp((cs),(ct),(n)*sizeof(Tcl_UniChar)) jpayne@69: #else /* !WORDS_BIGENDIAN */ jpayne@69: # define TclUniCharNcmp Tcl_UniCharNcmp jpayne@69: #endif /* WORDS_BIGENDIAN */ jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro used by the Tcl core to increment a namespace's export epoch jpayne@69: * counter. The ANSI C "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclInvalidateNsCmdLookup(Namespace *nsPtr); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclInvalidateNsCmdLookup(nsPtr) \ jpayne@69: if ((nsPtr)->numExportPatterns) { \ jpayne@69: (nsPtr)->exportLookupEpoch++; \ jpayne@69: } \ jpayne@69: if ((nsPtr)->commandPathLength) { \ jpayne@69: (nsPtr)->cmdRefEpoch++; \ jpayne@69: } jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------------- jpayne@69: * jpayne@69: * Core procedure added to libtommath for bignum manipulation. jpayne@69: * jpayne@69: *---------------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE Tcl_PackageInitProc TclTommath_Init; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------------- jpayne@69: * jpayne@69: * External (platform specific) initialization routine, these declarations jpayne@69: * explicitly don't use EXTERN since this code does not get compiled into the jpayne@69: * library: jpayne@69: * jpayne@69: *---------------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE Tcl_PackageInitProc TclplatformtestInit; jpayne@69: MODULE_SCOPE Tcl_PackageInitProc TclObjTest_Init; jpayne@69: MODULE_SCOPE Tcl_PackageInitProc TclThread_Init; jpayne@69: MODULE_SCOPE Tcl_PackageInitProc Procbodytest_Init; jpayne@69: MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macro used by the Tcl core to check whether a pattern has any characters jpayne@69: * special to [string match]. The ANSI C "prototype" for this macro is: jpayne@69: * jpayne@69: * MODULE_SCOPE int TclMatchIsTrivial(const char *pattern); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclMatchIsTrivial(pattern) \ jpayne@69: (strpbrk((pattern), "*[?\\") == NULL) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macros used by the Tcl core to set a Tcl_Obj's numeric representation jpayne@69: * avoiding the corresponding function calls in time critical parts of the jpayne@69: * core. They should only be called on unshared objects. The ANSI C jpayne@69: * "prototypes" for these macros are: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclSetIntObj(Tcl_Obj *objPtr, int intValue); jpayne@69: * MODULE_SCOPE void TclSetLongObj(Tcl_Obj *objPtr, long longValue); jpayne@69: * MODULE_SCOPE void TclSetBooleanObj(Tcl_Obj *objPtr, int intValue); jpayne@69: * MODULE_SCOPE void TclSetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt w); jpayne@69: * MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d); jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclSetLongObj(objPtr, i) \ jpayne@69: do { \ jpayne@69: TclInvalidateStringRep(objPtr); \ jpayne@69: TclFreeIntRep(objPtr); \ jpayne@69: (objPtr)->internalRep.longValue = (long)(i); \ jpayne@69: (objPtr)->typePtr = &tclIntType; \ jpayne@69: } while (0) jpayne@69: jpayne@69: #define TclSetIntObj(objPtr, l) \ jpayne@69: TclSetLongObj(objPtr, l) jpayne@69: jpayne@69: /* jpayne@69: * NOTE: There is to be no such thing as a "pure" boolean. Boolean values set jpayne@69: * programmatically go straight to being "int" Tcl_Obj's, with value 0 or 1. jpayne@69: * The only "boolean" Tcl_Obj's shall be those holding the cached boolean jpayne@69: * value of strings like: "yes", "no", "true", "false", "on", "off". jpayne@69: */ jpayne@69: jpayne@69: #define TclSetBooleanObj(objPtr, b) \ jpayne@69: TclSetLongObj(objPtr, (b)!=0); jpayne@69: jpayne@69: #ifndef TCL_WIDE_INT_IS_LONG jpayne@69: #define TclSetWideIntObj(objPtr, w) \ jpayne@69: do { \ jpayne@69: TclInvalidateStringRep(objPtr); \ jpayne@69: TclFreeIntRep(objPtr); \ jpayne@69: (objPtr)->internalRep.wideValue = (Tcl_WideInt)(w); \ jpayne@69: (objPtr)->typePtr = &tclWideIntType; \ jpayne@69: } while (0) jpayne@69: #endif jpayne@69: jpayne@69: #define TclSetDoubleObj(objPtr, d) \ jpayne@69: do { \ jpayne@69: TclInvalidateStringRep(objPtr); \ jpayne@69: TclFreeIntRep(objPtr); \ jpayne@69: (objPtr)->internalRep.doubleValue = (double)(d); \ jpayne@69: (objPtr)->typePtr = &tclDoubleType; \ jpayne@69: } while (0) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macros used by the Tcl core to create and initialise objects of standard jpayne@69: * types, avoiding the corresponding function calls in time critical parts of jpayne@69: * the core. The ANSI C "prototypes" for these macros are: jpayne@69: * jpayne@69: * MODULE_SCOPE void TclNewIntObj(Tcl_Obj *objPtr, int i); jpayne@69: * MODULE_SCOPE void TclNewLongObj(Tcl_Obj *objPtr, long l); jpayne@69: * MODULE_SCOPE void TclNewBooleanObj(Tcl_Obj *objPtr, int b); jpayne@69: * MODULE_SCOPE void TclNewWideObj(Tcl_Obj *objPtr, Tcl_WideInt w); jpayne@69: * MODULE_SCOPE void TclNewDoubleObj(Tcl_Obj *objPtr, double d); jpayne@69: * MODULE_SCOPE void TclNewStringObj(Tcl_Obj *objPtr, char *s, int len); jpayne@69: * MODULE_SCOPE void TclNewLiteralStringObj(Tcl_Obj*objPtr, char*sLiteral); jpayne@69: * jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #ifndef TCL_MEM_DEBUG jpayne@69: #define TclNewLongObj(objPtr, i) \ jpayne@69: do { \ jpayne@69: TclIncrObjsAllocated(); \ jpayne@69: TclAllocObjStorage(objPtr); \ jpayne@69: (objPtr)->refCount = 0; \ jpayne@69: (objPtr)->bytes = NULL; \ jpayne@69: (objPtr)->internalRep.longValue = (long)(i); \ jpayne@69: (objPtr)->typePtr = &tclIntType; \ jpayne@69: TCL_DTRACE_OBJ_CREATE(objPtr); \ jpayne@69: } while (0) jpayne@69: jpayne@69: #define TclNewIntObj(objPtr, l) \ jpayne@69: TclNewLongObj(objPtr, l) jpayne@69: jpayne@69: /* jpayne@69: * NOTE: There is to be no such thing as a "pure" boolean. jpayne@69: * See comment above TclSetBooleanObj macro above. jpayne@69: */ jpayne@69: #define TclNewBooleanObj(objPtr, b) \ jpayne@69: TclNewLongObj((objPtr), (b)!=0) jpayne@69: jpayne@69: #define TclNewDoubleObj(objPtr, d) \ jpayne@69: do { \ jpayne@69: TclIncrObjsAllocated(); \ jpayne@69: TclAllocObjStorage(objPtr); \ jpayne@69: (objPtr)->refCount = 0; \ jpayne@69: (objPtr)->bytes = NULL; \ jpayne@69: (objPtr)->internalRep.doubleValue = (double)(d); \ jpayne@69: (objPtr)->typePtr = &tclDoubleType; \ jpayne@69: TCL_DTRACE_OBJ_CREATE(objPtr); \ jpayne@69: } while (0) jpayne@69: jpayne@69: #define TclNewStringObj(objPtr, s, len) \ jpayne@69: do { \ jpayne@69: TclIncrObjsAllocated(); \ jpayne@69: TclAllocObjStorage(objPtr); \ jpayne@69: (objPtr)->refCount = 0; \ jpayne@69: TclInitStringRep((objPtr), (s), (len)); \ jpayne@69: (objPtr)->typePtr = NULL; \ jpayne@69: TCL_DTRACE_OBJ_CREATE(objPtr); \ jpayne@69: } while (0) jpayne@69: jpayne@69: #else /* TCL_MEM_DEBUG */ jpayne@69: #define TclNewIntObj(objPtr, i) \ jpayne@69: (objPtr) = Tcl_NewIntObj(i) jpayne@69: jpayne@69: #define TclNewLongObj(objPtr, l) \ jpayne@69: (objPtr) = Tcl_NewLongObj(l) jpayne@69: jpayne@69: #define TclNewBooleanObj(objPtr, b) \ jpayne@69: (objPtr) = Tcl_NewBooleanObj(b) jpayne@69: jpayne@69: #define TclNewDoubleObj(objPtr, d) \ jpayne@69: (objPtr) = Tcl_NewDoubleObj(d) jpayne@69: jpayne@69: #define TclNewStringObj(objPtr, s, len) \ jpayne@69: (objPtr) = Tcl_NewStringObj((s), (len)) jpayne@69: #endif /* TCL_MEM_DEBUG */ jpayne@69: jpayne@69: /* jpayne@69: * The sLiteral argument *must* be a string literal; the incantation with jpayne@69: * sizeof(sLiteral "") will fail to compile otherwise. jpayne@69: */ jpayne@69: #define TclNewLiteralStringObj(objPtr, sLiteral) \ jpayne@69: TclNewStringObj((objPtr), (sLiteral), (int) (sizeof(sLiteral "") - 1)) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Convenience macros for DStrings. jpayne@69: * The ANSI C "prototypes" for these macros are: jpayne@69: * jpayne@69: * MODULE_SCOPE char * TclDStringAppendLiteral(Tcl_DString *dsPtr, jpayne@69: * const char *sLiteral); jpayne@69: * MODULE_SCOPE void TclDStringClear(Tcl_DString *dsPtr); jpayne@69: */ jpayne@69: jpayne@69: #define TclDStringAppendLiteral(dsPtr, sLiteral) \ jpayne@69: Tcl_DStringAppend((dsPtr), (sLiteral), (int) (sizeof(sLiteral "") - 1)) jpayne@69: #define TclDStringClear(dsPtr) \ jpayne@69: Tcl_DStringSetLength((dsPtr), 0) jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Macros used by the Tcl core to test for some special double values. jpayne@69: * The ANSI C "prototypes" for these macros are: jpayne@69: * jpayne@69: * MODULE_SCOPE int TclIsInfinite(double d); jpayne@69: * MODULE_SCOPE int TclIsNaN(double d); jpayne@69: */ jpayne@69: jpayne@69: #ifdef _MSC_VER jpayne@69: # define TclIsInfinite(d) (!(_finite((d)))) jpayne@69: # define TclIsNaN(d) (_isnan((d))) jpayne@69: #else jpayne@69: # define TclIsInfinite(d) ((d) > DBL_MAX || (d) < -DBL_MAX) jpayne@69: # ifdef NO_ISNAN jpayne@69: # define TclIsNaN(d) ((d) != (d)) jpayne@69: # else jpayne@69: # define TclIsNaN(d) (isnan(d)) jpayne@69: # endif jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * ---------------------------------------------------------------------- jpayne@69: * Macro to use to find the offset of a field in a structure. Computes number jpayne@69: * of bytes from beginning of structure to a given field. jpayne@69: */ jpayne@69: jpayne@69: #ifdef offsetof jpayne@69: #define TclOffset(type, field) ((int) offsetof(type, field)) jpayne@69: #else jpayne@69: #define TclOffset(type, field) ((int) ((char *) &((type *) 0)->field)) jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Inline version of Tcl_GetCurrentNamespace and Tcl_GetGlobalNamespace. jpayne@69: */ jpayne@69: jpayne@69: #define TclGetCurrentNamespace(interp) \ jpayne@69: (Tcl_Namespace *) ((Interp *)(interp))->varFramePtr->nsPtr jpayne@69: jpayne@69: #define TclGetGlobalNamespace(interp) \ jpayne@69: (Tcl_Namespace *) ((Interp *)(interp))->globalNsPtr jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Inline version of TclCleanupCommand; still need the function as it is in jpayne@69: * the internal stubs, but the core can use the macro instead. jpayne@69: */ jpayne@69: jpayne@69: #define TclCleanupCommandMacro(cmdPtr) \ jpayne@69: if ((cmdPtr)->refCount-- <= 1) { \ jpayne@69: ckfree((char *) (cmdPtr));\ jpayne@69: } jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Inline versions of Tcl_LimitReady() and Tcl_LimitExceeded to limit number jpayne@69: * of calls out of the critical path. Note that this code isn't particularly jpayne@69: * readable; the non-inline version (in tclInterp.c) is much easier to jpayne@69: * understand. Note also that these macros takes different args (iPtr->limit) jpayne@69: * to the non-inline version. jpayne@69: */ jpayne@69: jpayne@69: #define TclLimitExceeded(limit) ((limit).exceeded != 0) jpayne@69: jpayne@69: #define TclLimitReady(limit) \ jpayne@69: (((limit).active == 0) ? 0 : \ jpayne@69: (++(limit).granularityTicker, \ jpayne@69: ((((limit).active & TCL_LIMIT_COMMANDS) && \ jpayne@69: (((limit).cmdGranularity == 1) || \ jpayne@69: ((limit).granularityTicker % (limit).cmdGranularity == 0))) \ jpayne@69: ? 1 : \ jpayne@69: (((limit).active & TCL_LIMIT_TIME) && \ jpayne@69: (((limit).timeGranularity == 1) || \ jpayne@69: ((limit).granularityTicker % (limit).timeGranularity == 0)))\ jpayne@69: ? 1 : 0))) jpayne@69: jpayne@69: /* jpayne@69: * Compile-time assertions: these produce a compile time error if the jpayne@69: * expression is not known to be true at compile time. If the assertion is jpayne@69: * known to be false, the compiler (or optimizer?) will error out with jpayne@69: * "division by zero". If the assertion cannot be evaluated at compile time, jpayne@69: * the compiler will error out with "non-static initializer". jpayne@69: * jpayne@69: * Adapted with permission from jpayne@69: * http://www.pixelbeat.org/programming/gcc/static_assert.html jpayne@69: */ jpayne@69: jpayne@69: #define TCL_CT_ASSERT(e) \ jpayne@69: {enum { ct_assert_value = 1/(!!(e)) };} jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Allocator for small structs (<=sizeof(Tcl_Obj)) using the Tcl_Obj pool. jpayne@69: * Only checked at compile time. jpayne@69: * jpayne@69: * ONLY USE FOR CONSTANT nBytes. jpayne@69: * jpayne@69: * DO NOT LET THEM CROSS THREAD BOUNDARIES jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define TclSmallAlloc(nbytes, memPtr) \ jpayne@69: TclSmallAllocEx(NULL, (nbytes), (memPtr)) jpayne@69: jpayne@69: #define TclSmallFree(memPtr) \ jpayne@69: TclSmallFreeEx(NULL, (memPtr)) jpayne@69: jpayne@69: #ifndef TCL_MEM_DEBUG jpayne@69: #define TclSmallAllocEx(interp, nbytes, memPtr) \ jpayne@69: do { \ jpayne@69: Tcl_Obj *_objPtr; \ jpayne@69: TCL_CT_ASSERT((nbytes)<=sizeof(Tcl_Obj)); \ jpayne@69: TclIncrObjsAllocated(); \ jpayne@69: TclAllocObjStorageEx((interp), (_objPtr)); \ jpayne@69: memPtr = (ClientData) (_objPtr); \ jpayne@69: } while (0) jpayne@69: jpayne@69: #define TclSmallFreeEx(interp, memPtr) \ jpayne@69: do { \ jpayne@69: TclFreeObjStorageEx((interp), (Tcl_Obj *) (memPtr)); \ jpayne@69: TclIncrObjsFreed(); \ jpayne@69: } while (0) jpayne@69: jpayne@69: #else /* TCL_MEM_DEBUG */ jpayne@69: #define TclSmallAllocEx(interp, nbytes, memPtr) \ jpayne@69: do { \ jpayne@69: Tcl_Obj *_objPtr; \ jpayne@69: TCL_CT_ASSERT((nbytes)<=sizeof(Tcl_Obj)); \ jpayne@69: TclNewObj(_objPtr); \ jpayne@69: memPtr = (ClientData) _objPtr; \ jpayne@69: } while (0) jpayne@69: jpayne@69: #define TclSmallFreeEx(interp, memPtr) \ jpayne@69: do { \ jpayne@69: Tcl_Obj *_objPtr = (Tcl_Obj *) memPtr; \ jpayne@69: _objPtr->bytes = NULL; \ jpayne@69: _objPtr->typePtr = NULL; \ jpayne@69: _objPtr->refCount = 1; \ jpayne@69: TclDecrRefCount(_objPtr); \ jpayne@69: } while (0) jpayne@69: #endif /* TCL_MEM_DEBUG */ jpayne@69: jpayne@69: /* jpayne@69: * Support for Clang Static Analyzer jpayne@69: */ jpayne@69: jpayne@69: #if defined(PURIFY) && defined(__clang__) jpayne@69: #if __has_feature(attribute_analyzer_noreturn) && \ jpayne@69: !defined(Tcl_Panic) && defined(Tcl_Panic_TCL_DECLARED) jpayne@69: void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn)); jpayne@69: #endif jpayne@69: #if !defined(CLANG_ASSERT) jpayne@69: #include jpayne@69: #define CLANG_ASSERT(x) assert(x) jpayne@69: #endif jpayne@69: #elif !defined(CLANG_ASSERT) jpayne@69: #define CLANG_ASSERT(x) jpayne@69: #endif /* PURIFY && __clang__ */ jpayne@69: jpayne@69: /* jpayne@69: *---------------------------------------------------------------- jpayne@69: * Parameters, structs and macros for the non-recursive engine (NRE) jpayne@69: *---------------------------------------------------------------- jpayne@69: */ jpayne@69: jpayne@69: #define NRE_USE_SMALL_ALLOC 1 /* Only turn off for debugging purposes. */ jpayne@69: #ifndef NRE_ENABLE_ASSERTS jpayne@69: #define NRE_ENABLE_ASSERTS 0 jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * This is the main data struct for representing NR commands. It is designed jpayne@69: * to fit in sizeof(Tcl_Obj) in order to exploit the fastest memory allocator jpayne@69: * available. jpayne@69: */ jpayne@69: jpayne@69: typedef struct NRE_callback { jpayne@69: Tcl_NRPostProc *procPtr; jpayne@69: ClientData data[4]; jpayne@69: struct NRE_callback *nextPtr; jpayne@69: } NRE_callback; jpayne@69: jpayne@69: #define TOP_CB(iPtr) (((Interp *)(iPtr))->execEnvPtr->callbackPtr) jpayne@69: jpayne@69: /* jpayne@69: * Inline version of Tcl_NRAddCallback. jpayne@69: */ jpayne@69: jpayne@69: #define TclNRAddCallback(interp,postProcPtr,data0,data1,data2,data3) \ jpayne@69: do { \ jpayne@69: NRE_callback *_callbackPtr; \ jpayne@69: TCLNR_ALLOC((interp), (_callbackPtr)); \ jpayne@69: _callbackPtr->procPtr = (postProcPtr); \ jpayne@69: _callbackPtr->data[0] = (ClientData)(data0); \ jpayne@69: _callbackPtr->data[1] = (ClientData)(data1); \ jpayne@69: _callbackPtr->data[2] = (ClientData)(data2); \ jpayne@69: _callbackPtr->data[3] = (ClientData)(data3); \ jpayne@69: _callbackPtr->nextPtr = TOP_CB(interp); \ jpayne@69: TOP_CB(interp) = _callbackPtr; \ jpayne@69: } while (0) jpayne@69: jpayne@69: #if NRE_USE_SMALL_ALLOC jpayne@69: #define TCLNR_ALLOC(interp, ptr) \ jpayne@69: TclSmallAllocEx(interp, sizeof(NRE_callback), (ptr)) jpayne@69: #define TCLNR_FREE(interp, ptr) TclSmallFreeEx((interp), (ptr)) jpayne@69: #else jpayne@69: #define TCLNR_ALLOC(interp, ptr) \ jpayne@69: ((ptr) = ((void *)ckalloc(sizeof(NRE_callback)))) jpayne@69: #define TCLNR_FREE(interp, ptr) ckfree((char *) (ptr)) jpayne@69: #endif jpayne@69: jpayne@69: #if NRE_ENABLE_ASSERTS jpayne@69: #define NRE_ASSERT(expr) assert((expr)) jpayne@69: #else jpayne@69: #define NRE_ASSERT(expr) jpayne@69: #endif jpayne@69: jpayne@69: #include "tclIntDecls.h" jpayne@69: #include "tclIntPlatDecls.h" jpayne@69: #include "tclTomMathDecls.h" jpayne@69: jpayne@69: #if !defined(USE_TCL_STUBS) && !defined(TCL_MEM_DEBUG) jpayne@69: #define Tcl_AttemptAlloc(size) TclpAlloc(size) jpayne@69: #define Tcl_AttemptRealloc(ptr, size) TclpRealloc((ptr), (size)) jpayne@69: #define Tcl_Free(ptr) TclpFree(ptr) jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * Other externals. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE size_t TclEnvEpoch; /* Epoch of the tcl environment jpayne@69: * (if changed with tcl-env). */ jpayne@69: jpayne@69: #endif /* _TCLINT */ jpayne@69: jpayne@69: /* jpayne@69: * Local Variables: jpayne@69: * mode: c jpayne@69: * c-basic-offset: 4 jpayne@69: * fill-column: 78 jpayne@69: * End: jpayne@69: */