os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclObj.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* 
     2  * tclObj.c --
     3  *
     4  *	This file contains Tcl object-related procedures that are used by
     5  * 	many Tcl commands.
     6  *
     7  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
     8  * Copyright (c) 1999 by Scriptics Corporation.
     9  * Copyright (c) 2001 by ActiveState Corporation.
    10  * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.  
    11  *
    12  * See the file "license.terms" for information on usage and redistribution
    13  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14  *
    15  * RCS: @(#) $Id: tclObj.c,v 1.42.2.14 2005/11/29 14:02:04 dkf Exp $
    16  */
    17 
    18 #include "tclInt.h"
    19 #include "tclCompile.h"
    20 #include "tclPort.h"
    21 #if defined(__SYMBIAN32__) 
    22 #include "tclSymbianGlobals.h"
    23 #endif 
    24 
    25 /*
    26  * Table of all object types.
    27  */
    28 #if !defined(__SYMBIAN32__) || !defined(__WINSCW__)
    29 static Tcl_HashTable typeTable;
    30 static int typeTableInitialized = 0;    /* 0 means not yet initialized. */
    31 #endif
    32 TCL_DECLARE_MUTEX(tableMutex)
    33 
    34 /*
    35  * Head of the list of free Tcl_Obj structs we maintain.
    36  */
    37 
    38 Tcl_Obj *tclFreeObjList = NULL;
    39 
    40 /*
    41  * The object allocator is single threaded.  This mutex is referenced
    42  * by the TclNewObj macro, however, so must be visible.
    43  */
    44 
    45 #ifdef TCL_THREADS
    46 Tcl_Mutex tclObjMutex;
    47 #endif
    48 
    49 /*
    50  * Pointer to a heap-allocated string of length zero that the Tcl core uses
    51  * as the value of an empty string representation for an object. This value
    52  * is shared by all new objects allocated by Tcl_NewObj.
    53  */
    54 
    55 char tclEmptyString = '\0';
    56 char *tclEmptyStringRep = &tclEmptyString;
    57 
    58 /*
    59  * Prototypes for procedures defined later in this file:
    60  */
    61 
    62 static int		SetBooleanFromAny _ANSI_ARGS_((Tcl_Interp *interp,
    63 			    Tcl_Obj *objPtr));
    64 static int		SetDoubleFromAny _ANSI_ARGS_((Tcl_Interp *interp,
    65 			    Tcl_Obj *objPtr));
    66 static int		SetIntFromAny _ANSI_ARGS_((Tcl_Interp *interp,
    67 			    Tcl_Obj *objPtr));
    68 static int		SetIntOrWideFromAny _ANSI_ARGS_((Tcl_Interp* interp,
    69 							 Tcl_Obj *objPtr));
    70 static void		UpdateStringOfBoolean _ANSI_ARGS_((Tcl_Obj *objPtr));
    71 static void		UpdateStringOfDouble _ANSI_ARGS_((Tcl_Obj *objPtr));
    72 static void		UpdateStringOfInt _ANSI_ARGS_((Tcl_Obj *objPtr));
    73 static int		SetWideIntFromAny _ANSI_ARGS_((Tcl_Interp *interp,
    74 			    Tcl_Obj *objPtr));
    75 
    76 #ifndef TCL_WIDE_INT_IS_LONG
    77 static void		UpdateStringOfWideInt _ANSI_ARGS_((Tcl_Obj *objPtr));
    78 #endif
    79 
    80 /*
    81  * Prototypes for the array hash key methods.
    82  */
    83 
    84 static Tcl_HashEntry *	AllocObjEntry _ANSI_ARGS_((
    85 			    Tcl_HashTable *tablePtr, VOID *keyPtr));
    86 static int		CompareObjKeys _ANSI_ARGS_((
    87 			    VOID *keyPtr, Tcl_HashEntry *hPtr));
    88 static void		FreeObjEntry _ANSI_ARGS_((
    89 			    Tcl_HashEntry *hPtr));
    90 static unsigned int	HashObjKey _ANSI_ARGS_((
    91 			    Tcl_HashTable *tablePtr,
    92 			    VOID *keyPtr));
    93 
    94 /*
    95  * Prototypes for the CommandName object type.
    96  */
    97 
    98 static void		DupCmdNameInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr,
    99 			    Tcl_Obj *copyPtr));
   100 static void		FreeCmdNameInternalRep _ANSI_ARGS_((
   101     			    Tcl_Obj *objPtr));
   102 static int		SetCmdNameFromAny _ANSI_ARGS_((Tcl_Interp *interp,
   103 			    Tcl_Obj *objPtr));
   104 
   105 
   106 /*
   107  * The structures below defines the Tcl object types defined in this file by
   108  * means of procedures that can be invoked by generic object code. See also
   109  * tclStringObj.c, tclListObj.c, tclByteCode.c for other type manager
   110  * implementations.
   111  */
   112 
   113 Tcl_ObjType tclBooleanType = {
   114     "boolean",				/* name */
   115     (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
   116     (Tcl_DupInternalRepProc *) NULL,	/* dupIntRepProc */
   117     UpdateStringOfBoolean,		/* updateStringProc */
   118     SetBooleanFromAny			/* setFromAnyProc */
   119 };
   120 
   121 Tcl_ObjType tclDoubleType = {
   122     "double",				/* name */
   123     (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
   124     (Tcl_DupInternalRepProc *) NULL,	/* dupIntRepProc */
   125     UpdateStringOfDouble,		/* updateStringProc */
   126     SetDoubleFromAny			/* setFromAnyProc */
   127 };
   128 
   129 Tcl_ObjType tclIntType = {
   130     "int",				/* name */
   131     (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
   132     (Tcl_DupInternalRepProc *) NULL,	/* dupIntRepProc */
   133     UpdateStringOfInt,			/* updateStringProc */
   134     SetIntFromAny			/* setFromAnyProc */
   135 };
   136 
   137 Tcl_ObjType tclWideIntType = {
   138     "wideInt",				/* name */
   139     (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
   140     (Tcl_DupInternalRepProc *) NULL,	/* dupIntRepProc */
   141 #ifdef TCL_WIDE_INT_IS_LONG
   142     UpdateStringOfInt,			/* updateStringProc */
   143 #else /* !TCL_WIDE_INT_IS_LONG */
   144     UpdateStringOfWideInt,		/* updateStringProc */
   145 #endif
   146     SetWideIntFromAny			/* setFromAnyProc */
   147 };
   148 
   149 /*
   150  * The structure below defines the Tcl obj hash key type.
   151  */
   152 Tcl_HashKeyType tclObjHashKeyType = {
   153     TCL_HASH_KEY_TYPE_VERSION,		/* version */
   154     0,					/* flags */
   155     HashObjKey,				/* hashKeyProc */
   156     CompareObjKeys,			/* compareKeysProc */
   157     AllocObjEntry,			/* allocEntryProc */
   158     FreeObjEntry			/* freeEntryProc */
   159 };
   160 
   161 /*
   162  * The structure below defines the command name Tcl object type by means of
   163  * procedures that can be invoked by generic object code. Objects of this
   164  * type cache the Command pointer that results from looking up command names
   165  * in the command hashtable. Such objects appear as the zeroth ("command
   166  * name") argument in a Tcl command.
   167  *
   168  * NOTE: the ResolvedCmdName that gets cached is stored in the
   169  * twoPtrValue.ptr1 field, and the twoPtrValue.ptr2 field is unused.
   170  * You might think you could use the simpler otherValuePtr field to
   171  * store the single ResolvedCmdName pointer, but DO NOT DO THIS.  It
   172  * seems that some extensions use the second internal pointer field
   173  * of the twoPtrValue field for their own purposes.
   174  */
   175 
   176 static Tcl_ObjType tclCmdNameType = {
   177     "cmdName",				/* name */
   178     FreeCmdNameInternalRep,		/* freeIntRepProc */
   179     DupCmdNameInternalRep,		/* dupIntRepProc */
   180     (Tcl_UpdateStringProc *) NULL,	/* updateStringProc */
   181     SetCmdNameFromAny			/* setFromAnyProc */
   182 };
   183 
   184 
   185 /*
   186  * Structure containing a cached pointer to a command that is the result
   187  * of resolving the command's name in some namespace. It is the internal
   188  * representation for a cmdName object. It contains the pointer along
   189  * with some information that is used to check the pointer's validity.
   190  */
   191 
   192 typedef struct ResolvedCmdName {
   193     Command *cmdPtr;		/* A cached Command pointer. */
   194     Namespace *refNsPtr;	/* Points to the namespace containing the
   195 				 * reference (not the namespace that
   196 				 * contains the referenced command). */
   197     long refNsId;		/* refNsPtr's unique namespace id. Used to
   198 				 * verify that refNsPtr is still valid
   199 				 * (e.g., it's possible that the cmd's
   200 				 * containing namespace was deleted and a
   201 				 * new one created at the same address). */
   202     int refNsCmdEpoch;		/* Value of the referencing namespace's
   203 				 * cmdRefEpoch when the pointer was cached.
   204 				 * Before using the cached pointer, we check
   205 				 * if the namespace's epoch was incremented;
   206 				 * if so, this cached pointer is invalid. */
   207     int cmdEpoch;		/* Value of the command's cmdEpoch when this
   208 				 * pointer was cached. Before using the
   209 				 * cached pointer, we check if the cmd's
   210 				 * epoch was incremented; if so, the cmd was
   211 				 * renamed, deleted, hidden, or exposed, and
   212 				 * so the pointer is invalid. */
   213     int refCount;		/* Reference count: 1 for each cmdName
   214 				 * object that has a pointer to this
   215 				 * ResolvedCmdName structure as its internal
   216 				 * rep. This structure can be freed when
   217 				 * refCount becomes zero. */
   218 } ResolvedCmdName;
   219 
   220 
   221 /*
   222  *-------------------------------------------------------------------------
   223  *
   224  * TclInitObjectSubsystem --
   225  *
   226  *	This procedure is invoked to perform once-only initialization of
   227  *	the type table. It also registers the object types defined in 
   228  *	this file.
   229  *
   230  * Results:
   231  *	None.
   232  *
   233  * Side effects:
   234  *	Initializes the table of defined object types "typeTable" with
   235  *	builtin object types defined in this file.  
   236  *
   237  *-------------------------------------------------------------------------
   238  */
   239 
   240 void
   241 TclInitObjSubsystem()
   242 {
   243     Tcl_MutexLock(&tableMutex);
   244     typeTableInitialized = 1;
   245     Tcl_InitHashTable(&typeTable, TCL_STRING_KEYS);
   246     Tcl_MutexUnlock(&tableMutex);
   247 
   248     Tcl_RegisterObjType(&tclBooleanType);
   249     Tcl_RegisterObjType(&tclByteArrayType);
   250     Tcl_RegisterObjType(&tclDoubleType);
   251     Tcl_RegisterObjType(&tclEndOffsetType);
   252     Tcl_RegisterObjType(&tclIntType);
   253     Tcl_RegisterObjType(&tclWideIntType);
   254     Tcl_RegisterObjType(&tclStringType);
   255     Tcl_RegisterObjType(&tclListType);
   256     Tcl_RegisterObjType(&tclByteCodeType);
   257     Tcl_RegisterObjType(&tclProcBodyType);
   258     Tcl_RegisterObjType(&tclArraySearchType);
   259     Tcl_RegisterObjType(&tclIndexType);
   260     Tcl_RegisterObjType(&tclNsNameType);
   261     Tcl_RegisterObjType(&tclCmdNameType);
   262 
   263 #ifdef TCL_COMPILE_STATS
   264     Tcl_MutexLock(&tclObjMutex);
   265     tclObjsAlloced = 0;
   266     tclObjsFreed = 0;
   267     {
   268 	int i;
   269 	for (i = 0;  i < TCL_MAX_SHARED_OBJ_STATS;  i++) {
   270 	    tclObjsShared[i] = 0;
   271 	}
   272     }
   273     Tcl_MutexUnlock(&tclObjMutex);
   274 #endif
   275 }
   276 
   277 /*
   278  *----------------------------------------------------------------------
   279  *
   280  * TclFinalizeObjects --
   281  *
   282  *	This procedure is called by Tcl_Finalize to clean up all
   283  *	registered Tcl_ObjType's and to reset the tclFreeObjList.
   284  *
   285  * Results:
   286  *	None.
   287  *
   288  * Side effects:
   289  *	None.
   290  *
   291  *----------------------------------------------------------------------
   292  */
   293 
   294 void
   295 TclFinalizeObjects()
   296 {
   297     Tcl_MutexLock(&tableMutex);
   298     if (typeTableInitialized) {
   299         Tcl_DeleteHashTable(&typeTable);
   300         typeTableInitialized = 0;
   301     }
   302     Tcl_MutexUnlock(&tableMutex);
   303 
   304     /* 
   305      * All we do here is reset the head pointer of the linked list of
   306      * free Tcl_Obj's to NULL;  the memory finalization will take care
   307      * of releasing memory for us.
   308      */
   309     Tcl_MutexLock(&tclObjMutex);
   310     tclFreeObjList = NULL;
   311     Tcl_MutexUnlock(&tclObjMutex);
   312 }
   313 
   314 /*
   315  *--------------------------------------------------------------
   316  *
   317  * Tcl_RegisterObjType --
   318  *
   319  *	This procedure is called to register a new Tcl object type
   320  *	in the table of all object types supported by Tcl.
   321  *
   322  * Results:
   323  *	None.
   324  *
   325  * Side effects:
   326  *	The type is registered in the Tcl type table. If there was already
   327  *	a type with the same name as in typePtr, it is replaced with the
   328  *	new type.
   329  *
   330  *--------------------------------------------------------------
   331  */
   332 
   333 EXPORT_C void
   334 Tcl_RegisterObjType(typePtr)
   335     Tcl_ObjType *typePtr;	/* Information about object type;
   336 				 * storage must be statically
   337 				 * allocated (must live forever). */
   338 {
   339     int new;
   340     Tcl_MutexLock(&tableMutex);
   341     Tcl_SetHashValue(
   342 	    Tcl_CreateHashEntry(&typeTable, typePtr->name, &new), typePtr);
   343     Tcl_MutexUnlock(&tableMutex);
   344 }
   345 
   346 /*
   347  *----------------------------------------------------------------------
   348  *
   349  * Tcl_AppendAllObjTypes --
   350  *
   351  *	This procedure appends onto the argument object the name of each
   352  *	object type as a list element. This includes the builtin object
   353  *	types (e.g. int, list) as well as those added using
   354  *	Tcl_NewObj. These names can be used, for example, with
   355  *	Tcl_GetObjType to get pointers to the corresponding Tcl_ObjType
   356  *	structures.
   357  *
   358  * Results:
   359  *	The return value is normally TCL_OK; in this case the object
   360  *	referenced by objPtr has each type name appended to it. If an
   361  *	error occurs, TCL_ERROR is returned and the interpreter's result
   362  *	holds an error message.
   363  *
   364  * Side effects:
   365  *	If necessary, the object referenced by objPtr is converted into
   366  *	a list object.
   367  *
   368  *----------------------------------------------------------------------
   369  */
   370 
   371 EXPORT_C int
   372 Tcl_AppendAllObjTypes(interp, objPtr)
   373     Tcl_Interp *interp;		/* Interpreter used for error reporting. */
   374     Tcl_Obj *objPtr;		/* Points to the Tcl object onto which the
   375 				 * name of each registered type is appended
   376 				 * as a list element. */
   377 {
   378     register Tcl_HashEntry *hPtr;
   379     Tcl_HashSearch search;
   380     int objc;
   381     Tcl_Obj **objv;
   382 
   383     /*
   384      * Get the test for a valid list out of the way first.
   385      */
   386 
   387     if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
   388 	return TCL_ERROR;
   389     }
   390 
   391     /*
   392      * Type names are NUL-terminated, not counted strings.
   393      * This code relies on that.
   394      */
   395 
   396     Tcl_MutexLock(&tableMutex);
   397     for (hPtr = Tcl_FirstHashEntry(&typeTable, &search);
   398 	    hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
   399 	Tcl_ListObjAppendElement(NULL, objPtr,
   400 	        Tcl_NewStringObj(Tcl_GetHashKey(&typeTable, hPtr), -1));
   401     }
   402     Tcl_MutexUnlock(&tableMutex);
   403     return TCL_OK;
   404 }
   405 
   406 /*
   407  *----------------------------------------------------------------------
   408  *
   409  * Tcl_GetObjType --
   410  *
   411  *	This procedure looks up an object type by name.
   412  *
   413  * Results:
   414  *	If an object type with name matching "typeName" is found, a pointer
   415  *	to its Tcl_ObjType structure is returned; otherwise, NULL is
   416  *	returned.
   417  *
   418  * Side effects:
   419  *	None.
   420  *
   421  *----------------------------------------------------------------------
   422  */
   423 
   424 EXPORT_C Tcl_ObjType *
   425 Tcl_GetObjType(typeName)
   426     CONST char *typeName;	/* Name of Tcl object type to look up. */
   427 {
   428     register Tcl_HashEntry *hPtr;
   429     Tcl_ObjType *typePtr = NULL;
   430 
   431     Tcl_MutexLock(&tableMutex);
   432     hPtr = Tcl_FindHashEntry(&typeTable, typeName);
   433     if (hPtr != (Tcl_HashEntry *) NULL) {
   434         typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);
   435     }
   436     Tcl_MutexUnlock(&tableMutex);
   437     return typePtr;
   438 }
   439 
   440 /*
   441  *----------------------------------------------------------------------
   442  *
   443  * Tcl_ConvertToType --
   444  *
   445  *	Convert the Tcl object "objPtr" to have type "typePtr" if possible.
   446  *
   447  * Results:
   448  *	The return value is TCL_OK on success and TCL_ERROR on failure. If
   449  *	TCL_ERROR is returned, then the interpreter's result contains an
   450  *	error message unless "interp" is NULL. Passing a NULL "interp"
   451  *	allows this procedure to be used as a test whether the conversion
   452  *	could be done (and in fact was done).
   453  *
   454  * Side effects:
   455  *	Any internal representation for the old type is freed.
   456  *
   457  *----------------------------------------------------------------------
   458  */
   459 
   460 EXPORT_C int
   461 Tcl_ConvertToType(interp, objPtr, typePtr)
   462     Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
   463     Tcl_Obj *objPtr;		/* The object to convert. */
   464     Tcl_ObjType *typePtr;	/* The target type. */
   465 {
   466     if (objPtr->typePtr == typePtr) {
   467 	return TCL_OK;
   468     }
   469 
   470     /*
   471      * Use the target type's Tcl_SetFromAnyProc to set "objPtr"s internal
   472      * form as appropriate for the target type. This frees the old internal
   473      * representation.
   474      */
   475 
   476     return typePtr->setFromAnyProc(interp, objPtr);
   477 }
   478 
   479 /*
   480  *----------------------------------------------------------------------
   481  *
   482  * Tcl_NewObj --
   483  *
   484  *	This procedure is normally called when not debugging: i.e., when
   485  *	TCL_MEM_DEBUG is not defined. It creates new Tcl objects that denote
   486  *	the empty string. These objects have a NULL object type and NULL
   487  *	string representation byte pointer. Type managers call this routine
   488  *	to allocate new objects that they further initialize.
   489  *
   490  *	When TCL_MEM_DEBUG is defined, this procedure just returns the
   491  *	result of calling the debugging version Tcl_DbNewObj.
   492  *
   493  * Results:
   494  *	The result is a newly allocated object that represents the empty
   495  *	string. The new object's typePtr is set NULL and its ref count
   496  *	is set to 0.
   497  *
   498  * Side effects:
   499  *	If compiling with TCL_COMPILE_STATS, this procedure increments
   500  *	the global count of allocated objects (tclObjsAlloced).
   501  *
   502  *----------------------------------------------------------------------
   503  */
   504 
   505 #ifdef TCL_MEM_DEBUG
   506 #undef Tcl_NewObj
   507 
   508 EXPORT_C Tcl_Obj *
   509 Tcl_NewObj()
   510 {
   511     return Tcl_DbNewObj("unknown", 0);
   512 }
   513 
   514 #else /* if not TCL_MEM_DEBUG */
   515 
   516 EXPORT_C Tcl_Obj *
   517 Tcl_NewObj()
   518 {
   519     register Tcl_Obj *objPtr;
   520 
   521     /*
   522      * Use the macro defined in tclInt.h - it will use the
   523      * correct allocator.
   524      */
   525 
   526     TclNewObj(objPtr);
   527     return objPtr;
   528 }
   529 #endif /* TCL_MEM_DEBUG */
   530 
   531 /*
   532  *----------------------------------------------------------------------
   533  *
   534  * Tcl_DbNewObj --
   535  *
   536  *	This procedure is normally called when debugging: i.e., when
   537  *	TCL_MEM_DEBUG is defined. It creates new Tcl objects that denote the
   538  *	empty string. It is the same as the Tcl_NewObj procedure above
   539  *	except that it calls Tcl_DbCkalloc directly with the file name and
   540  *	line number from its caller. This simplifies debugging since then
   541  *	the [memory active] command will report the correct file name and line
   542  *	number when reporting objects that haven't been freed.
   543  *
   544  *	When TCL_MEM_DEBUG is not defined, this procedure just returns the
   545  *	result of calling Tcl_NewObj.
   546  *
   547  * Results:
   548  *	The result is a newly allocated that represents the empty string.
   549  *	The new object's typePtr is set NULL and its ref count is set to 0.
   550  *
   551  * Side effects:
   552  *	If compiling with TCL_COMPILE_STATS, this procedure increments
   553  *	the global count of allocated objects (tclObjsAlloced).
   554  *
   555  *----------------------------------------------------------------------
   556  */
   557 
   558 #ifdef TCL_MEM_DEBUG
   559 
   560 EXPORT_C Tcl_Obj *
   561 Tcl_DbNewObj(file, line)
   562     register CONST char *file;	/* The name of the source file calling this
   563 				 * procedure; used for debugging. */
   564     register int line;		/* Line number in the source file; used
   565 				 * for debugging. */
   566 {
   567     register Tcl_Obj *objPtr;
   568 
   569     /*
   570      * Use the macro defined in tclInt.h - it will use the
   571      * correct allocator.
   572      */
   573 
   574     TclDbNewObj(objPtr, file, line);
   575     return objPtr;
   576 }
   577 #else /* if not TCL_MEM_DEBUG */
   578 
   579 EXPORT_C Tcl_Obj *
   580 Tcl_DbNewObj(file, line)
   581     CONST char *file;		/* The name of the source file calling this
   582 				 * procedure; used for debugging. */
   583     int line;			/* Line number in the source file; used
   584 				 * for debugging. */
   585 {
   586     return Tcl_NewObj();
   587 }
   588 #endif /* TCL_MEM_DEBUG */
   589 
   590 /*
   591  *----------------------------------------------------------------------
   592  *
   593  * TclAllocateFreeObjects --
   594  *
   595  *	Procedure to allocate a number of free Tcl_Objs. This is done using
   596  *	a single ckalloc to reduce the overhead for Tcl_Obj allocation.
   597  *
   598  *	Assumes mutex is held.
   599  *
   600  * Results:
   601  *	None.
   602  *
   603  * Side effects:
   604  *	tclFreeObjList, the head of the list of free Tcl_Objs, is set to the
   605  *	first of a number of free Tcl_Obj's linked together by their
   606  *	internalRep.otherValuePtrs.
   607  *
   608  *----------------------------------------------------------------------
   609  */
   610 
   611 #define OBJS_TO_ALLOC_EACH_TIME 100
   612 
   613 void
   614 TclAllocateFreeObjects()
   615 {
   616     size_t bytesToAlloc = (OBJS_TO_ALLOC_EACH_TIME * sizeof(Tcl_Obj));
   617     char *basePtr;
   618     register Tcl_Obj *prevPtr, *objPtr;
   619     register int i;
   620 
   621     /*
   622      * This has been noted by Purify to be a potential leak.  The problem is
   623      * that Tcl, when not TCL_MEM_DEBUG compiled, keeps around all allocated
   624      * Tcl_Obj's, pointed to by tclFreeObjList, when freed instead of
   625      * actually freeing the memory.  TclFinalizeObjects() does not ckfree()
   626      * this memory, but leaves it to Tcl's memory subsystem finalziation to
   627      * release it.  Purify apparently can't figure that out, and fires a
   628      * false alarm.
   629      */
   630 
   631     basePtr = (char *) ckalloc(bytesToAlloc);
   632     memset(basePtr, 0, bytesToAlloc);
   633 
   634     prevPtr = NULL;
   635     objPtr = (Tcl_Obj *) basePtr;
   636     for (i = 0; i < OBJS_TO_ALLOC_EACH_TIME; i++) {
   637 	objPtr->internalRep.otherValuePtr = (VOID *) prevPtr;
   638 	prevPtr = objPtr;
   639 	objPtr++;
   640     }
   641     tclFreeObjList = prevPtr;
   642 }
   643 #undef OBJS_TO_ALLOC_EACH_TIME
   644 
   645 /*
   646  *----------------------------------------------------------------------
   647  *
   648  * TclFreeObj --
   649  *
   650  *	This procedure frees the memory associated with the argument
   651  *	object. It is called by the tcl.h macro Tcl_DecrRefCount when an
   652  *	object's ref count is zero. It is only "public" since it must
   653  *	be callable by that macro wherever the macro is used. It should not
   654  *	be directly called by clients.
   655  *
   656  * Results:
   657  *	None.
   658  *
   659  * Side effects:
   660  *	Deallocates the storage for the object's Tcl_Obj structure
   661  *	after deallocating the string representation and calling the
   662  *	type-specific Tcl_FreeInternalRepProc to deallocate the object's
   663  *	internal representation. If compiling with TCL_COMPILE_STATS,
   664  *	this procedure increments the global count of freed objects
   665  *	(tclObjsFreed).
   666  *
   667  *----------------------------------------------------------------------
   668  */
   669 
   670 EXPORT_C void
   671 TclFreeObj(objPtr)
   672     register Tcl_Obj *objPtr;	/* The object to be freed. */
   673 {
   674     register Tcl_ObjType *typePtr = objPtr->typePtr;
   675     
   676 #ifdef TCL_MEM_DEBUG
   677     if ((objPtr)->refCount < -1) {
   678 	panic("Reference count for %lx was negative", objPtr);
   679     }
   680 #endif /* TCL_MEM_DEBUG */
   681 
   682     if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
   683 	typePtr->freeIntRepProc(objPtr);
   684     }
   685     Tcl_InvalidateStringRep(objPtr);
   686 
   687     /*
   688      * If debugging Tcl's memory usage, deallocate the object using ckfree.
   689      * Otherwise, deallocate it by adding it onto the list of free
   690      * Tcl_Obj structs we maintain.
   691      */
   692 
   693 #if defined(TCL_MEM_DEBUG) || defined(PURIFY)
   694     Tcl_MutexLock(&tclObjMutex);
   695     ckfree((char *) objPtr);
   696     Tcl_MutexUnlock(&tclObjMutex);
   697 #elif defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) 
   698     TclThreadFreeObj(objPtr); 
   699 #else 
   700     Tcl_MutexLock(&tclObjMutex);
   701     objPtr->internalRep.otherValuePtr = (VOID *) tclFreeObjList;
   702     tclFreeObjList = objPtr;
   703     Tcl_MutexUnlock(&tclObjMutex);
   704 #endif /* TCL_MEM_DEBUG */
   705 
   706 #ifdef TCL_COMPILE_STATS
   707     tclObjsFreed++;
   708 #endif /* TCL_COMPILE_STATS */
   709 }
   710 
   711 /*
   712  *----------------------------------------------------------------------
   713  *
   714  * Tcl_DuplicateObj --
   715  *
   716  *	Create and return a new object that is a duplicate of the argument
   717  *	object.
   718  *
   719  * Results:
   720  *	The return value is a pointer to a newly created Tcl_Obj. This
   721  *	object has reference count 0 and the same type, if any, as the
   722  *	source object objPtr. Also:
   723  *	  1) If the source object has a valid string rep, we copy it;
   724  *	     otherwise, the duplicate's string rep is set NULL to mark
   725  *	     it invalid.
   726  *	  2) If the source object has an internal representation (i.e. its
   727  *	     typePtr is non-NULL), the new object's internal rep is set to
   728  *	     a copy; otherwise the new internal rep is marked invalid.
   729  *
   730  * Side effects:
   731  *      What constitutes "copying" the internal representation depends on
   732  *	the type. For example, if the argument object is a list,
   733  *	the element objects it points to will not actually be copied but
   734  *	will be shared with the duplicate list. That is, the ref counts of
   735  *	the element objects will be incremented.
   736  *
   737  *----------------------------------------------------------------------
   738  */
   739 
   740 EXPORT_C Tcl_Obj *
   741 Tcl_DuplicateObj(objPtr)
   742     register Tcl_Obj *objPtr;		/* The object to duplicate. */
   743 {
   744     register Tcl_ObjType *typePtr = objPtr->typePtr;
   745     register Tcl_Obj *dupPtr;
   746 
   747     TclNewObj(dupPtr);
   748 
   749     if (objPtr->bytes == NULL) {
   750 	dupPtr->bytes = NULL;
   751     } else if (objPtr->bytes != tclEmptyStringRep) {
   752 	TclInitStringRep(dupPtr, objPtr->bytes, objPtr->length);
   753     }
   754     
   755     if (typePtr != NULL) {
   756 	if (typePtr->dupIntRepProc == NULL) {
   757 	    dupPtr->internalRep = objPtr->internalRep;
   758 	    dupPtr->typePtr = typePtr;
   759 	} else {
   760 	    (*typePtr->dupIntRepProc)(objPtr, dupPtr);
   761 	}
   762     }
   763     return dupPtr;
   764 }
   765 
   766 /*
   767  *----------------------------------------------------------------------
   768  *
   769  * Tcl_GetString --
   770  *
   771  *	Returns the string representation byte array pointer for an object.
   772  *
   773  * Results:
   774  *	Returns a pointer to the string representation of objPtr. The byte
   775  *	array referenced by the returned pointer must not be modified by the
   776  *	caller. Furthermore, the caller must copy the bytes if they need to
   777  *	retain them since the object's string rep can change as a result of
   778  *	other operations.
   779  *
   780  * Side effects:
   781  *	May call the object's updateStringProc to update the string
   782  *	representation from the internal representation.
   783  *
   784  *----------------------------------------------------------------------
   785  */
   786 
   787 EXPORT_C char *
   788 Tcl_GetString(objPtr)
   789     register Tcl_Obj *objPtr;	/* Object whose string rep byte pointer
   790 				 * should be returned. */
   791 {
   792     if (objPtr->bytes != NULL) {
   793 	return objPtr->bytes;
   794     }
   795 
   796     if (objPtr->typePtr->updateStringProc == NULL) {
   797 	panic("UpdateStringProc should not be invoked for type %s",
   798 		objPtr->typePtr->name);
   799     }
   800     (*objPtr->typePtr->updateStringProc)(objPtr);
   801     return objPtr->bytes;
   802 }
   803 
   804 /*
   805  *----------------------------------------------------------------------
   806  *
   807  * Tcl_GetStringFromObj --
   808  *
   809  *	Returns the string representation's byte array pointer and length
   810  *	for an object.
   811  *
   812  * Results:
   813  *	Returns a pointer to the string representation of objPtr. If
   814  *	lengthPtr isn't NULL, the length of the string representation is
   815  *	stored at *lengthPtr. The byte array referenced by the returned
   816  *	pointer must not be modified by the caller. Furthermore, the
   817  *	caller must copy the bytes if they need to retain them since the
   818  *	object's string rep can change as a result of other operations.
   819  *
   820  * Side effects:
   821  *	May call the object's updateStringProc to update the string
   822  *	representation from the internal representation.
   823  *
   824  *----------------------------------------------------------------------
   825  */
   826 
   827 EXPORT_C char *
   828 Tcl_GetStringFromObj(objPtr, lengthPtr)
   829     register Tcl_Obj *objPtr;	/* Object whose string rep byte pointer should
   830 				 * be returned. */
   831     register int *lengthPtr;	/* If non-NULL, the location where the string
   832 				 * rep's byte array length should * be stored.
   833 				 * If NULL, no length is stored. */
   834 {
   835     if (objPtr->bytes == NULL) {
   836 	if (objPtr->typePtr->updateStringProc == NULL) {
   837 	    panic("UpdateStringProc should not be invoked for type %s",
   838 		    objPtr->typePtr->name);
   839 	}
   840 	(*objPtr->typePtr->updateStringProc)(objPtr);
   841     }
   842 
   843     if (lengthPtr != NULL) {
   844 	*lengthPtr = objPtr->length;
   845     }
   846     return objPtr->bytes;
   847 }
   848 
   849 /*
   850  *----------------------------------------------------------------------
   851  *
   852  * Tcl_InvalidateStringRep --
   853  *
   854  *	This procedure is called to invalidate an object's string
   855  *	representation. 
   856  *
   857  * Results:
   858  *	None.
   859  *
   860  * Side effects:
   861  *	Deallocates the storage for any old string representation, then
   862  *	sets the string representation NULL to mark it invalid.
   863  *
   864  *----------------------------------------------------------------------
   865  */
   866 
   867 EXPORT_C void
   868 Tcl_InvalidateStringRep(objPtr)
   869      register Tcl_Obj *objPtr;	/* Object whose string rep byte pointer
   870 				 * should be freed. */
   871 {
   872     if (objPtr->bytes != NULL) {
   873 	if (objPtr->bytes != tclEmptyStringRep) {
   874 	    ckfree((char *) objPtr->bytes);
   875 	}
   876 	objPtr->bytes = NULL;
   877     }
   878 }
   879 
   880 /*
   881  *----------------------------------------------------------------------
   882  *
   883  * Tcl_NewBooleanObj --
   884  *
   885  *	This procedure is normally called when not debugging: i.e., when
   886  *	TCL_MEM_DEBUG is not defined. It creates a new Tcl_Obj and
   887  *	initializes it from the argument boolean value. A nonzero
   888  *	"boolValue" is coerced to 1.
   889  *
   890  *	When TCL_MEM_DEBUG is defined, this procedure just returns the
   891  *	result of calling the debugging version Tcl_DbNewBooleanObj.
   892  *
   893  * Results:
   894  *	The newly created object is returned. This object will have an
   895  *	invalid string representation. The returned object has ref count 0.
   896  *
   897  * Side effects:
   898  *	None.
   899  *
   900  *----------------------------------------------------------------------
   901  */
   902 
   903 #ifdef TCL_MEM_DEBUG
   904 #undef Tcl_NewBooleanObj
   905 
   906 EXPORT_C Tcl_Obj *
   907 Tcl_NewBooleanObj(boolValue)
   908     register int boolValue;	/* Boolean used to initialize new object. */
   909 {
   910     return Tcl_DbNewBooleanObj(boolValue, "unknown", 0);
   911 }
   912 
   913 #else /* if not TCL_MEM_DEBUG */
   914 
   915 EXPORT_C Tcl_Obj *
   916 Tcl_NewBooleanObj(boolValue)
   917     register int boolValue;	/* Boolean used to initialize new object. */
   918 {
   919     register Tcl_Obj *objPtr;
   920 
   921     TclNewObj(objPtr);
   922     objPtr->bytes = NULL;
   923     
   924     objPtr->internalRep.longValue = (boolValue? 1 : 0);
   925     objPtr->typePtr = &tclBooleanType;
   926     return objPtr;
   927 }
   928 #endif /* TCL_MEM_DEBUG */
   929 
   930 /*
   931  *----------------------------------------------------------------------
   932  *
   933  * Tcl_DbNewBooleanObj --
   934  *
   935  *	This procedure is normally called when debugging: i.e., when
   936  *	TCL_MEM_DEBUG is defined. It creates new boolean objects. It is the
   937  *	same as the Tcl_NewBooleanObj procedure above except that it calls
   938  *	Tcl_DbCkalloc directly with the file name and line number from its
   939  *	caller. This simplifies debugging since then the [memory active]
   940  *	command	will report the correct file name and line number when
   941  *	reporting objects that haven't been freed.
   942  *
   943  *	When TCL_MEM_DEBUG is not defined, this procedure just returns the
   944  *	result of calling Tcl_NewBooleanObj.
   945  *
   946  * Results:
   947  *	The newly created object is returned. This object will have an
   948  *	invalid string representation. The returned object has ref count 0.
   949  *
   950  * Side effects:
   951  *	None.
   952  *
   953  *----------------------------------------------------------------------
   954  */
   955 
   956 #ifdef TCL_MEM_DEBUG
   957 
   958 EXPORT_C Tcl_Obj *
   959 Tcl_DbNewBooleanObj(boolValue, file, line)
   960     register int boolValue;	/* Boolean used to initialize new object. */
   961     CONST char *file;		/* The name of the source file calling this
   962 				 * procedure; used for debugging. */
   963     int line;			/* Line number in the source file; used
   964 				 * for debugging. */
   965 {
   966     register Tcl_Obj *objPtr;
   967 
   968     TclDbNewObj(objPtr, file, line);
   969     objPtr->bytes = NULL;
   970     
   971     objPtr->internalRep.longValue = (boolValue? 1 : 0);
   972     objPtr->typePtr = &tclBooleanType;
   973     return objPtr;
   974 }
   975 
   976 #else /* if not TCL_MEM_DEBUG */
   977 
   978 EXPORT_C Tcl_Obj *
   979 Tcl_DbNewBooleanObj(boolValue, file, line)
   980     register int boolValue;	/* Boolean used to initialize new object. */
   981     CONST char *file;		/* The name of the source file calling this
   982 				 * procedure; used for debugging. */
   983     int line;			/* Line number in the source file; used
   984 				 * for debugging. */
   985 {
   986     return Tcl_NewBooleanObj(boolValue);
   987 }
   988 #endif /* TCL_MEM_DEBUG */
   989 
   990 /*
   991  *----------------------------------------------------------------------
   992  *
   993  * Tcl_SetBooleanObj --
   994  *
   995  *	Modify an object to be a boolean object and to have the specified
   996  *	boolean value. A nonzero "boolValue" is coerced to 1.
   997  *
   998  * Results:
   999  *	None.
  1000  *
  1001  * Side effects:
  1002  *	The object's old string rep, if any, is freed. Also, any old
  1003  *	internal rep is freed.
  1004  *
  1005  *----------------------------------------------------------------------
  1006  */
  1007 
  1008 EXPORT_C void
  1009 Tcl_SetBooleanObj(objPtr, boolValue)
  1010     register Tcl_Obj *objPtr;	/* Object whose internal rep to init. */
  1011     register int boolValue;	/* Boolean used to set object's value. */
  1012 {
  1013     register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  1014 
  1015     if (Tcl_IsShared(objPtr)) {
  1016 	panic("Tcl_SetBooleanObj called with shared object");
  1017     }
  1018     
  1019     if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
  1020 	oldTypePtr->freeIntRepProc(objPtr);
  1021     }
  1022     
  1023     objPtr->internalRep.longValue = (boolValue? 1 : 0);
  1024     objPtr->typePtr = &tclBooleanType;
  1025     Tcl_InvalidateStringRep(objPtr);
  1026 }
  1027 
  1028 /*
  1029  *----------------------------------------------------------------------
  1030  *
  1031  * Tcl_GetBooleanFromObj --
  1032  *
  1033  *	Attempt to return a boolean from the Tcl object "objPtr". If the
  1034  *	object is not already a boolean, an attempt will be made to convert
  1035  *	it to one.
  1036  *
  1037  * Results:
  1038  *	The return value is a standard Tcl object result. If an error occurs
  1039  *	during conversion, an error message is left in the interpreter's
  1040  *	result unless "interp" is NULL.
  1041  *
  1042  * Side effects:
  1043  *	If the object is not already a boolean, the conversion will free
  1044  *	any old internal representation. 
  1045  *
  1046  *----------------------------------------------------------------------
  1047  */
  1048 
  1049 EXPORT_C int
  1050 Tcl_GetBooleanFromObj(interp, objPtr, boolPtr)
  1051     Tcl_Interp *interp; 	/* Used for error reporting if not NULL. */
  1052     register Tcl_Obj *objPtr;	/* The object from which to get boolean. */
  1053     register int *boolPtr;	/* Place to store resulting boolean. */
  1054 {
  1055     register int result;
  1056 
  1057     if (objPtr->typePtr == &tclBooleanType) {
  1058 	result = TCL_OK;
  1059     } else {
  1060 	result = SetBooleanFromAny(interp, objPtr);
  1061     }
  1062 
  1063     if (result == TCL_OK) {
  1064 	*boolPtr = (int) objPtr->internalRep.longValue;
  1065     }
  1066     return result;
  1067 }
  1068 
  1069 /*
  1070  *----------------------------------------------------------------------
  1071  *
  1072  * SetBooleanFromAny --
  1073  *
  1074  *	Attempt to generate a boolean internal form for the Tcl object
  1075  *	"objPtr".
  1076  *
  1077  * Results:
  1078  *	The return value is a standard Tcl result. If an error occurs during
  1079  *	conversion, an error message is left in the interpreter's result
  1080  *	unless "interp" is NULL.
  1081  *
  1082  * Side effects:
  1083  *	If no error occurs, an integer 1 or 0 is stored as "objPtr"s
  1084  *	internal representation and the type of "objPtr" is set to boolean.
  1085  *
  1086  *----------------------------------------------------------------------
  1087  */
  1088 
  1089 static int
  1090 SetBooleanFromAny(interp, objPtr)
  1091     Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
  1092     register Tcl_Obj *objPtr;	/* The object to convert. */
  1093 {
  1094     Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  1095     char *string, *end;
  1096     register char c;
  1097     char lowerCase[10];
  1098     int newBool, length;
  1099     register int i;
  1100 
  1101     /*
  1102      * Get the string representation. Make it up-to-date if necessary.
  1103      */
  1104     
  1105     string = Tcl_GetStringFromObj(objPtr, &length);
  1106 
  1107     /*
  1108      * Use the obvious shortcuts for numerical values; if objPtr is not
  1109      * of numerical type, parse its string rep.
  1110      */
  1111 	
  1112     if (objPtr->typePtr == &tclIntType) {
  1113 	newBool = (objPtr->internalRep.longValue != 0);
  1114     } else if (objPtr->typePtr == &tclDoubleType) {
  1115 	newBool = (objPtr->internalRep.doubleValue != 0.0);
  1116     } else if (objPtr->typePtr == &tclWideIntType) {
  1117 	newBool = (objPtr->internalRep.wideValue != 0);
  1118     } else {
  1119 	/*
  1120 	 * Copy the string converting its characters to lower case.
  1121 	 */
  1122 	
  1123 	for (i = 0;  (i < 9) && (i < length);  i++) {
  1124 	    c = string[i];
  1125 	    /*
  1126 	     * Weed out international characters so we can safely operate
  1127 	     * on single bytes.
  1128 	     */
  1129 	    
  1130 	    if (c & 0x80) {
  1131 		goto badBoolean;
  1132 	    }
  1133 	    if (Tcl_UniCharIsUpper(UCHAR(c))) {
  1134 		c = (char) Tcl_UniCharToLower(UCHAR(c));
  1135 	    }
  1136 	    lowerCase[i] = c;
  1137 	}
  1138 	lowerCase[i] = 0;
  1139 	
  1140 	/*
  1141 	 * Parse the string as a boolean. We use an implementation here that
  1142 	 * doesn't report errors in interp if interp is NULL.
  1143 	 */
  1144 	
  1145 	c = lowerCase[0];
  1146 	if ((c == '0') && (lowerCase[1] == '\0')) {
  1147 	    newBool = 0;
  1148 	} else if ((c == '1') && (lowerCase[1] == '\0')) {
  1149 	    newBool = 1;
  1150 	} else if ((c == 'y') && (strncmp(lowerCase, "yes", (size_t) length) == 0)) {
  1151 	    newBool = 1;
  1152 	} else if ((c == 'n') && (strncmp(lowerCase, "no", (size_t) length) == 0)) {
  1153 	    newBool = 0;
  1154 	} else if ((c == 't') && (strncmp(lowerCase, "true", (size_t) length) == 0)) {
  1155 	    newBool = 1;
  1156 	} else if ((c == 'f') && (strncmp(lowerCase, "false", (size_t) length) == 0)) {
  1157 	    newBool = 0;
  1158 	} else if ((c == 'o') && (length >= 2)) {
  1159 	    if (strncmp(lowerCase, "on", (size_t) length) == 0) {
  1160 		newBool = 1;
  1161 	    } else if (strncmp(lowerCase, "off", (size_t) length) == 0) {
  1162 		newBool = 0;
  1163 	    } else {
  1164 		goto badBoolean;
  1165 	    }
  1166 	} else {
  1167 	    double dbl;
  1168 	    /*
  1169 	     * Boolean values can be extracted from ints or doubles.  Note
  1170 	     * that we don't use strtoul or strtoull here because we don't
  1171 	     * care about what the value is, just whether it is equal to
  1172 	     * zero or not.
  1173 	     */
  1174 #ifdef TCL_WIDE_INT_IS_LONG
  1175 	    newBool = strtol(string, &end, 0);
  1176 	    if (end != string) {
  1177 		/*
  1178 		 * Make sure the string has no garbage after the end of
  1179 		 * the int.
  1180 		 */
  1181 		while ((end < (string+length))
  1182 		       && isspace(UCHAR(*end))) { /* INTL: ISO only */
  1183 		    end++;
  1184 		}
  1185 		if (end == (string+length)) {
  1186 		    newBool = (newBool != 0);
  1187 		    goto goodBoolean;
  1188 		}
  1189 	    }
  1190 #else /* !TCL_WIDE_INT_IS_LONG */
  1191 	    Tcl_WideInt wide = strtoll(string, &end, 0);
  1192 	    if (end != string) {
  1193 		/*
  1194 		 * Make sure the string has no garbage after the end of
  1195 		 * the wide int.
  1196 		 */
  1197 		while ((end < (string+length))
  1198 		       && isspace(UCHAR(*end))) { /* INTL: ISO only */
  1199 		    end++;
  1200 		}
  1201 		if (end == (string+length)) {
  1202 		    newBool = (wide != Tcl_LongAsWide(0));
  1203 		    goto goodBoolean;
  1204 		}
  1205 	    }
  1206 #endif /* TCL_WIDE_INT_IS_LONG */
  1207 	    /*
  1208 	     * Still might be a string containing the characters representing an
  1209 	     * int or double that wasn't handled above. This would be a string
  1210 	     * like "27" or "1.0" that is non-zero and not "1". Such a string
  1211 	     * would result in the boolean value true. We try converting to
  1212 	     * double. If that succeeds and the resulting double is non-zero, we
  1213 	     * have a "true". Note that numbers can't have embedded NULLs.
  1214 	     */
  1215 	    
  1216 	    dbl = strtod(string, &end);
  1217 	    if (end == string) {
  1218 		goto badBoolean;
  1219 	    }
  1220 	    
  1221 	    /*
  1222 	     * Make sure the string has no garbage after the end of the double.
  1223 	     */
  1224 	    
  1225 	    while ((end < (string+length))
  1226 		   && isspace(UCHAR(*end))) { /* INTL: ISO only */
  1227 		end++;
  1228 	    }
  1229 	    if (end != (string+length)) {
  1230 		goto badBoolean;
  1231 	    }
  1232 	    newBool = (dbl != 0.0);
  1233 	}
  1234     }
  1235 
  1236     /*
  1237      * Free the old internalRep before setting the new one. We do this as
  1238      * late as possible to allow the conversion code, in particular
  1239      * Tcl_GetStringFromObj, to use that old internalRep.
  1240      */
  1241 
  1242     goodBoolean:
  1243     if ((oldTypePtr != NULL) &&	(oldTypePtr->freeIntRepProc != NULL)) {
  1244 	oldTypePtr->freeIntRepProc(objPtr);
  1245     }
  1246 
  1247     objPtr->internalRep.longValue = newBool;
  1248     objPtr->typePtr = &tclBooleanType;
  1249     return TCL_OK;
  1250 
  1251     badBoolean:
  1252     if (interp != NULL) {
  1253 	/*
  1254 	 * Must copy string before resetting the result in case a caller
  1255 	 * is trying to convert the interpreter's result to a boolean.
  1256 	 */
  1257 	
  1258 	char buf[100];
  1259 	sprintf(buf, "expected boolean value but got \"%.50s\"", string);
  1260 	Tcl_ResetResult(interp);
  1261 	Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
  1262     }
  1263     return TCL_ERROR;
  1264 }
  1265 
  1266 /*
  1267  *----------------------------------------------------------------------
  1268  *
  1269  * UpdateStringOfBoolean --
  1270  *
  1271  *	Update the string representation for a boolean object.
  1272  *	Note: This procedure does not free an existing old string rep
  1273  *	so storage will be lost if this has not already been done. 
  1274  *
  1275  * Results:
  1276  *	None.
  1277  *
  1278  * Side effects:
  1279  *	The object's string is set to a valid string that results from
  1280  *	the boolean-to-string conversion.
  1281  *
  1282  *----------------------------------------------------------------------
  1283  */
  1284 
  1285 static void
  1286 UpdateStringOfBoolean(objPtr)
  1287     register Tcl_Obj *objPtr;	/* Int object whose string rep to update. */
  1288 {
  1289     char *s = ckalloc((unsigned) 2);
  1290     
  1291     s[0] = (char) (objPtr->internalRep.longValue? '1' : '0');
  1292     s[1] = '\0';
  1293     objPtr->bytes = s;
  1294     objPtr->length = 1;
  1295 }
  1296 
  1297 /*
  1298  *----------------------------------------------------------------------
  1299  *
  1300  * Tcl_NewDoubleObj --
  1301  *
  1302  *	This procedure is normally called when not debugging: i.e., when
  1303  *	TCL_MEM_DEBUG is not defined. It creates a new double object and
  1304  *	initializes it from the argument double value.
  1305  *
  1306  *	When TCL_MEM_DEBUG is defined, this procedure just returns the
  1307  *	result of calling the debugging version Tcl_DbNewDoubleObj.
  1308  *
  1309  * Results:
  1310  *	The newly created object is returned. This object will have an
  1311  *	invalid string representation. The returned object has ref count 0.
  1312  *
  1313  * Side effects:
  1314  *	None.
  1315  *
  1316  *----------------------------------------------------------------------
  1317  */
  1318 
  1319 #ifdef TCL_MEM_DEBUG
  1320 #undef Tcl_NewDoubleObj
  1321 
  1322 EXPORT_C Tcl_Obj *
  1323 Tcl_NewDoubleObj(dblValue)
  1324     register double dblValue;	/* Double used to initialize the object. */
  1325 {
  1326     return Tcl_DbNewDoubleObj(dblValue, "unknown", 0);
  1327 }
  1328 
  1329 #else /* if not TCL_MEM_DEBUG */
  1330 
  1331 EXPORT_C Tcl_Obj *
  1332 Tcl_NewDoubleObj(dblValue)
  1333     register double dblValue;	/* Double used to initialize the object. */
  1334 {
  1335     register Tcl_Obj *objPtr;
  1336 
  1337     TclNewObj(objPtr);
  1338     objPtr->bytes = NULL;
  1339     
  1340     objPtr->internalRep.doubleValue = dblValue;
  1341     objPtr->typePtr = &tclDoubleType;
  1342     return objPtr;
  1343 }
  1344 #endif /* if TCL_MEM_DEBUG */
  1345 
  1346 /*
  1347  *----------------------------------------------------------------------
  1348  *
  1349  * Tcl_DbNewDoubleObj --
  1350  *
  1351  *	This procedure is normally called when debugging: i.e., when
  1352  *	TCL_MEM_DEBUG is defined. It creates new double objects. It is the
  1353  *	same as the Tcl_NewDoubleObj procedure above except that it calls
  1354  *	Tcl_DbCkalloc directly with the file name and line number from its
  1355  *	caller. This simplifies debugging since then the [memory active]
  1356  *	command	will report the correct file name and line number when
  1357  *	reporting objects that haven't been freed.
  1358  *
  1359  *	When TCL_MEM_DEBUG is not defined, this procedure just returns the
  1360  *	result of calling Tcl_NewDoubleObj.
  1361  *
  1362  * Results:
  1363  *	The newly created object is returned. This object will have an
  1364  *	invalid string representation. The returned object has ref count 0.
  1365  *
  1366  * Side effects:
  1367  *	None.
  1368  *
  1369  *----------------------------------------------------------------------
  1370  */
  1371 
  1372 #ifdef TCL_MEM_DEBUG
  1373 
  1374 EXPORT_C Tcl_Obj *
  1375 Tcl_DbNewDoubleObj(dblValue, file, line)
  1376     register double dblValue;	/* Double used to initialize the object. */
  1377     CONST char *file;		/* The name of the source file calling this
  1378 				 * procedure; used for debugging. */
  1379     int line;			/* Line number in the source file; used
  1380 				 * for debugging. */
  1381 {
  1382     register Tcl_Obj *objPtr;
  1383 
  1384     TclDbNewObj(objPtr, file, line);
  1385     objPtr->bytes = NULL;
  1386     
  1387     objPtr->internalRep.doubleValue = dblValue;
  1388     objPtr->typePtr = &tclDoubleType;
  1389     return objPtr;
  1390 }
  1391 
  1392 #else /* if not TCL_MEM_DEBUG */
  1393 
  1394 EXPORT_C Tcl_Obj *
  1395 Tcl_DbNewDoubleObj(dblValue, file, line)
  1396     register double dblValue;	/* Double used to initialize the object. */
  1397     CONST char *file;		/* The name of the source file calling this
  1398 				 * procedure; used for debugging. */
  1399     int line;			/* Line number in the source file; used
  1400 				 * for debugging. */
  1401 {
  1402     return Tcl_NewDoubleObj(dblValue);
  1403 }
  1404 #endif /* TCL_MEM_DEBUG */
  1405 
  1406 /*
  1407  *----------------------------------------------------------------------
  1408  *
  1409  * Tcl_SetDoubleObj --
  1410  *
  1411  *	Modify an object to be a double object and to have the specified
  1412  *	double value.
  1413  *
  1414  * Results:
  1415  *	None.
  1416  *
  1417  * Side effects:
  1418  *	The object's old string rep, if any, is freed. Also, any old
  1419  *	internal rep is freed.
  1420  *
  1421  *----------------------------------------------------------------------
  1422  */
  1423 
  1424 EXPORT_C void
  1425 Tcl_SetDoubleObj(objPtr, dblValue)
  1426     register Tcl_Obj *objPtr;	/* Object whose internal rep to init. */
  1427     register double dblValue;	/* Double used to set the object's value. */
  1428 {
  1429     register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  1430 
  1431     if (Tcl_IsShared(objPtr)) {
  1432 	panic("Tcl_SetDoubleObj called with shared object");
  1433     }
  1434 
  1435     if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
  1436 	oldTypePtr->freeIntRepProc(objPtr);
  1437     }
  1438     
  1439     objPtr->internalRep.doubleValue = dblValue;
  1440     objPtr->typePtr = &tclDoubleType;
  1441     Tcl_InvalidateStringRep(objPtr);
  1442 }
  1443 
  1444 /*
  1445  *----------------------------------------------------------------------
  1446  *
  1447  * Tcl_GetDoubleFromObj --
  1448  *
  1449  *	Attempt to return a double from the Tcl object "objPtr". If the
  1450  *	object is not already a double, an attempt will be made to convert
  1451  *	it to one.
  1452  *
  1453  * Results:
  1454  *	The return value is a standard Tcl object result. If an error occurs
  1455  *	during conversion, an error message is left in the interpreter's
  1456  *	result unless "interp" is NULL.
  1457  *
  1458  * Side effects:
  1459  *	If the object is not already a double, the conversion will free
  1460  *	any old internal representation.
  1461  *
  1462  *----------------------------------------------------------------------
  1463  */
  1464 
  1465 EXPORT_C int
  1466 Tcl_GetDoubleFromObj(interp, objPtr, dblPtr)
  1467     Tcl_Interp *interp; 	/* Used for error reporting if not NULL. */
  1468     register Tcl_Obj *objPtr;	/* The object from which to get a double. */
  1469     register double *dblPtr;	/* Place to store resulting double. */
  1470 {
  1471     register int result;
  1472     
  1473     if (objPtr->typePtr == &tclDoubleType) {
  1474 	*dblPtr = objPtr->internalRep.doubleValue;
  1475 	return TCL_OK;
  1476     }
  1477 
  1478     result = SetDoubleFromAny(interp, objPtr);
  1479     if (result == TCL_OK) {
  1480 	*dblPtr = objPtr->internalRep.doubleValue;
  1481     }
  1482     return result;
  1483 }
  1484 
  1485 /*
  1486  *----------------------------------------------------------------------
  1487  *
  1488  * SetDoubleFromAny --
  1489  *
  1490  *	Attempt to generate an double-precision floating point internal form
  1491  *	for the Tcl object "objPtr".
  1492  *
  1493  * Results:
  1494  *	The return value is a standard Tcl object result. If an error occurs
  1495  *	during conversion, an error message is left in the interpreter's
  1496  *	result unless "interp" is NULL.
  1497  *
  1498  * Side effects:
  1499  *	If no error occurs, a double is stored as "objPtr"s internal
  1500  *	representation.
  1501  *
  1502  *----------------------------------------------------------------------
  1503  */
  1504 
  1505 static int
  1506 SetDoubleFromAny(interp, objPtr)
  1507     Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
  1508     register Tcl_Obj *objPtr;	/* The object to convert. */
  1509 {
  1510     Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  1511     char *string, *end;
  1512     double newDouble;
  1513     int length;
  1514 
  1515     /*
  1516      * Get the string representation. Make it up-to-date if necessary.
  1517      */
  1518 
  1519     string = Tcl_GetStringFromObj(objPtr, &length);
  1520 
  1521     /*
  1522      * Now parse "objPtr"s string as an double. Numbers can't have embedded
  1523      * NULLs. We use an implementation here that doesn't report errors in
  1524      * interp if interp is NULL.
  1525      */
  1526 
  1527     errno = 0;
  1528     newDouble = strtod(string, &end);
  1529     if (end == string) {
  1530 	badDouble:
  1531 	if (interp != NULL) {
  1532 	    /*
  1533 	     * Must copy string before resetting the result in case a caller
  1534 	     * is trying to convert the interpreter's result to an int.
  1535 	     */
  1536 	    
  1537 	    char buf[100];
  1538 	    sprintf(buf, "expected floating-point number but got \"%.50s\"",
  1539 	            string);
  1540 	    Tcl_ResetResult(interp);
  1541 	    Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
  1542 	}
  1543 	return TCL_ERROR;
  1544     }
  1545     if (errno != 0) {
  1546 	if (interp != NULL) {
  1547 	    TclExprFloatError(interp, newDouble);
  1548 	}
  1549 	return TCL_ERROR;
  1550     }
  1551 
  1552     /*
  1553      * Make sure that the string has no garbage after the end of the double.
  1554      */
  1555     
  1556     while ((end < (string+length))
  1557 	    && isspace(UCHAR(*end))) { /* INTL: ISO space. */
  1558 	end++;
  1559     }
  1560     if (end != (string+length)) {
  1561 	goto badDouble;
  1562     }
  1563     
  1564     /*
  1565      * The conversion to double succeeded. Free the old internalRep before
  1566      * setting the new one. We do this as late as possible to allow the
  1567      * conversion code, in particular Tcl_GetStringFromObj, to use that old
  1568      * internalRep.
  1569      */
  1570     
  1571     if ((oldTypePtr != NULL) &&	(oldTypePtr->freeIntRepProc != NULL)) {
  1572 	oldTypePtr->freeIntRepProc(objPtr);
  1573     }
  1574 
  1575     objPtr->internalRep.doubleValue = newDouble;
  1576     objPtr->typePtr = &tclDoubleType;
  1577     return TCL_OK;
  1578 }
  1579 
  1580 /*
  1581  *----------------------------------------------------------------------
  1582  *
  1583  * UpdateStringOfDouble --
  1584  *
  1585  *	Update the string representation for a double-precision floating
  1586  *	point object. This must obey the current tcl_precision value for
  1587  *	double-to-string conversions. Note: This procedure does not free an
  1588  *	existing old string rep so storage will be lost if this has not
  1589  *	already been done.
  1590  *
  1591  * Results:
  1592  *	None.
  1593  *
  1594  * Side effects:
  1595  *	The object's string is set to a valid string that results from
  1596  *	the double-to-string conversion.
  1597  *
  1598  *----------------------------------------------------------------------
  1599  */
  1600 
  1601 static void
  1602 UpdateStringOfDouble(objPtr)
  1603     register Tcl_Obj *objPtr;	/* Double obj with string rep to update. */
  1604 {
  1605     char buffer[TCL_DOUBLE_SPACE];
  1606     register int len;
  1607     
  1608     Tcl_PrintDouble((Tcl_Interp *) NULL, objPtr->internalRep.doubleValue,
  1609 	    buffer);
  1610     len = strlen(buffer);
  1611     
  1612     objPtr->bytes = (char *) ckalloc((unsigned) len + 1);
  1613     strcpy(objPtr->bytes, buffer);
  1614     objPtr->length = len;
  1615 }
  1616 
  1617 /*
  1618  *----------------------------------------------------------------------
  1619  *
  1620  * Tcl_NewIntObj --
  1621  *
  1622  *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
  1623  *	Tcl_NewIntObj to create a new integer object end up calling the
  1624  *	debugging procedure Tcl_DbNewLongObj instead.
  1625  *
  1626  *	Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,
  1627  *	calls to Tcl_NewIntObj result in a call to one of the two
  1628  *	Tcl_NewIntObj implementations below. We provide two implementations
  1629  *	so that the Tcl core can be compiled to do memory debugging of the 
  1630  *	core even if a client does not request it for itself.
  1631  *
  1632  *	Integer and long integer objects share the same "integer" type
  1633  *	implementation. We store all integers as longs and Tcl_GetIntFromObj
  1634  *	checks whether the current value of the long can be represented by
  1635  *	an int.
  1636  *
  1637  * Results:
  1638  *	The newly created object is returned. This object will have an
  1639  *	invalid string representation. The returned object has ref count 0.
  1640  *
  1641  * Side effects:
  1642  *	None.
  1643  *
  1644  *----------------------------------------------------------------------
  1645  */
  1646 
  1647 #ifdef TCL_MEM_DEBUG
  1648 #undef Tcl_NewIntObj
  1649 
  1650 EXPORT_C Tcl_Obj *
  1651 Tcl_NewIntObj(intValue)
  1652     register int intValue;	/* Int used to initialize the new object. */
  1653 {
  1654     return Tcl_DbNewLongObj((long)intValue, "unknown", 0);
  1655 }
  1656 
  1657 #else /* if not TCL_MEM_DEBUG */
  1658 
  1659 EXPORT_C Tcl_Obj *
  1660 Tcl_NewIntObj(intValue)
  1661     register int intValue;	/* Int used to initialize the new object. */
  1662 {
  1663     register Tcl_Obj *objPtr;
  1664 
  1665     TclNewObj(objPtr);
  1666     objPtr->bytes = NULL;
  1667     
  1668     objPtr->internalRep.longValue = (long)intValue;
  1669     objPtr->typePtr = &tclIntType;
  1670     return objPtr;
  1671 }
  1672 #endif /* if TCL_MEM_DEBUG */
  1673 
  1674 /*
  1675  *----------------------------------------------------------------------
  1676  *
  1677  * Tcl_SetIntObj --
  1678  *
  1679  *	Modify an object to be an integer and to have the specified integer
  1680  *	value.
  1681  *
  1682  * Results:
  1683  *	None.
  1684  *
  1685  * Side effects:
  1686  *	The object's old string rep, if any, is freed. Also, any old
  1687  *	internal rep is freed. 
  1688  *
  1689  *----------------------------------------------------------------------
  1690  */
  1691 
  1692 EXPORT_C void
  1693 Tcl_SetIntObj(objPtr, intValue)
  1694     register Tcl_Obj *objPtr;	/* Object whose internal rep to init. */
  1695     register int intValue;	/* Integer used to set object's value. */
  1696 {
  1697     register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  1698 
  1699     if (Tcl_IsShared(objPtr)) {
  1700 	panic("Tcl_SetIntObj called with shared object");
  1701     }
  1702     
  1703     if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
  1704 	oldTypePtr->freeIntRepProc(objPtr);
  1705     }
  1706     
  1707     objPtr->internalRep.longValue = (long) intValue;
  1708     objPtr->typePtr = &tclIntType;
  1709     Tcl_InvalidateStringRep(objPtr);
  1710 }
  1711 
  1712 /*
  1713  *----------------------------------------------------------------------
  1714  *
  1715  * Tcl_GetIntFromObj --
  1716  *
  1717  *	Attempt to return an int from the Tcl object "objPtr". If the object
  1718  *	is not already an int, an attempt will be made to convert it to one.
  1719  *
  1720  *	Integer and long integer objects share the same "integer" type
  1721  *	implementation. We store all integers as longs and Tcl_GetIntFromObj
  1722  *	checks whether the current value of the long can be represented by
  1723  *	an int.
  1724  *
  1725  * Results:
  1726  *	The return value is a standard Tcl object result. If an error occurs
  1727  *	during conversion or if the long integer held by the object
  1728  *	can not be represented by an int, an error message is left in
  1729  *	the interpreter's result unless "interp" is NULL.
  1730  *
  1731  * Side effects:
  1732  *	If the object is not already an int, the conversion will free
  1733  *	any old internal representation.
  1734  *
  1735  *----------------------------------------------------------------------
  1736  */
  1737 
  1738 EXPORT_C int
  1739 Tcl_GetIntFromObj(interp, objPtr, intPtr)
  1740     Tcl_Interp *interp; 	/* Used for error reporting if not NULL. */
  1741     register Tcl_Obj *objPtr;	/* The object from which to get a int. */
  1742     register int *intPtr;	/* Place to store resulting int. */
  1743 {
  1744     int result;
  1745     Tcl_WideInt w = 0;
  1746 
  1747     /*
  1748      * If the object isn't already an integer of any width, try to
  1749      * convert it to one.
  1750      */
  1751 
  1752     if (objPtr->typePtr != &tclIntType && objPtr->typePtr != &tclWideIntType) {
  1753 	result = SetIntOrWideFromAny(interp, objPtr);
  1754 	if (result != TCL_OK) {
  1755 	    return result;
  1756 	}
  1757     }
  1758 
  1759     /*
  1760      * Object should now be either int or wide. Get its value.
  1761      */
  1762 
  1763 #ifndef TCL_WIDE_INT_IS_LONG
  1764     if (objPtr->typePtr == &tclWideIntType) {
  1765 	w = objPtr->internalRep.wideValue;
  1766     } else
  1767 #endif
  1768     {
  1769 	w = Tcl_LongAsWide(objPtr->internalRep.longValue);
  1770     }
  1771 
  1772     if ((LLONG_MAX > UINT_MAX)
  1773 	    && ((w > UINT_MAX) || (w < -(Tcl_WideInt)UINT_MAX))) {
  1774 	if (interp != NULL) {
  1775 	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
  1776 		"integer value too large to represent as non-long integer",
  1777 		-1));
  1778 	}
  1779 	return TCL_ERROR;
  1780     }
  1781     *intPtr = (int)w;
  1782     return TCL_OK;
  1783 }
  1784 
  1785 /*
  1786  *----------------------------------------------------------------------
  1787  *
  1788  * SetIntFromAny --
  1789  *
  1790  *	Attempts to force the internal representation for a Tcl object
  1791  *	to tclIntType, specifically.
  1792  *
  1793  * Results:
  1794  *	The return value is a standard object Tcl result.  If an
  1795  *	error occurs during conversion, an error message is left in
  1796  *	the interpreter's result unless "interp" is NULL.
  1797  *
  1798  *----------------------------------------------------------------------
  1799  */
  1800 
  1801 static int
  1802 SetIntFromAny( Tcl_Interp* interp, 
  1803 				/* Tcl interpreter */
  1804 	       Tcl_Obj* objPtr )
  1805 				/* Pointer to the object to convert */
  1806 {
  1807     int result;
  1808 
  1809     result = SetIntOrWideFromAny( interp, objPtr );
  1810     if ( result != TCL_OK ) {
  1811 	return result;
  1812     }
  1813     if ( objPtr->typePtr != &tclIntType ) {
  1814 	if ( interp != NULL ) {
  1815 	    char *s = "integer value too large to represent";
  1816 	    Tcl_ResetResult(interp);
  1817 	    Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
  1818 	    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *) NULL);
  1819 	}
  1820 	return TCL_ERROR;
  1821     }
  1822     return TCL_OK;
  1823 }
  1824 
  1825 /*
  1826  *----------------------------------------------------------------------
  1827  *
  1828  * SetIntOrWideFromAny --
  1829  *
  1830  *	Attempt to generate an integer internal form for the Tcl object
  1831  *	"objPtr".
  1832  *
  1833  * Results:
  1834  *	The return value is a standard object Tcl result. If an error occurs
  1835  *	during conversion, an error message is left in the interpreter's
  1836  *	result unless "interp" is NULL.
  1837  *
  1838  * Side effects:
  1839  *	If no error occurs, an int is stored as "objPtr"s internal
  1840  *	representation. 
  1841  *
  1842  *----------------------------------------------------------------------
  1843  */
  1844 
  1845 static int
  1846 SetIntOrWideFromAny(interp, objPtr)
  1847     Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
  1848     register Tcl_Obj *objPtr;	/* The object to convert. */
  1849 {
  1850     Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  1851     char *string, *end;
  1852     int length;
  1853     register char *p;
  1854     unsigned long newLong;
  1855     int isNegative = 0;
  1856     int isWide = 0;
  1857 
  1858     /*
  1859      * Get the string representation. Make it up-to-date if necessary.
  1860      */
  1861 
  1862     p = string = Tcl_GetStringFromObj(objPtr, &length);
  1863 
  1864     /*
  1865      * Now parse "objPtr"s string as an int. We use an implementation here
  1866      * that doesn't report errors in interp if interp is NULL. Note: use
  1867      * strtoul instead of strtol for integer conversions to allow full-size
  1868      * unsigned numbers, but don't depend on strtoul to handle sign
  1869      * characters; it won't in some implementations.
  1870      */
  1871 
  1872     errno = 0;
  1873     for ( ;  isspace(UCHAR(*p));  p++) { /* INTL: ISO space. */
  1874 	/* Empty loop body. */
  1875     }
  1876     if (*p == '-') {
  1877 	p++;
  1878 	isNegative = 1;
  1879     } else if (*p == '+') {
  1880 	p++;
  1881     }
  1882     if (!isdigit(UCHAR(*p))) {
  1883 	badInteger:
  1884 	if (interp != NULL) {
  1885 	    /*
  1886 	     * Must copy string before resetting the result in case a caller
  1887 	     * is trying to convert the interpreter's result to an int.
  1888 	     */
  1889 	    
  1890 	    char buf[100];
  1891 	    sprintf(buf, "expected integer but got \"%.50s\"", string);
  1892 	    Tcl_ResetResult(interp);
  1893 	    Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
  1894 	    TclCheckBadOctal(interp, string);
  1895 	}
  1896 	return TCL_ERROR;
  1897     }
  1898     newLong = strtoul(p, &end, 0);
  1899     if (end == p) {
  1900 	goto badInteger;
  1901     }
  1902     if (errno == ERANGE) {
  1903 	if (interp != NULL) {
  1904 	    char *s = "integer value too large to represent";
  1905 	    Tcl_ResetResult(interp);
  1906 	    Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
  1907 	    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *) NULL);
  1908 	}
  1909 	return TCL_ERROR;
  1910     }
  1911 
  1912     /*
  1913      * Make sure that the string has no garbage after the end of the int.
  1914      */
  1915     
  1916     while ((end < (string+length))
  1917 	    && isspace(UCHAR(*end))) { /* INTL: ISO space. */
  1918 	end++;
  1919     }
  1920     if (end != (string+length)) {
  1921 	goto badInteger;
  1922     }
  1923 
  1924     /*
  1925      * If the resulting integer will exceed the range of a long,
  1926      * put it into a wide instead.  (Tcl Bug #868489)
  1927      */
  1928 
  1929 #ifndef TCL_WIDE_INT_IS_LONG
  1930     if ((isNegative && newLong > (unsigned long) (LONG_MAX) + 1)
  1931 	    || (!isNegative && newLong > LONG_MAX)) {
  1932 	isWide = 1;
  1933     }
  1934 #endif
  1935 
  1936     /*
  1937      * The conversion to int succeeded. Free the old internalRep before
  1938      * setting the new one. We do this as late as possible to allow the
  1939      * conversion code, in particular Tcl_GetStringFromObj, to use that old
  1940      * internalRep.
  1941      */
  1942 
  1943     if ((oldTypePtr != NULL) &&	(oldTypePtr->freeIntRepProc != NULL)) {
  1944 	oldTypePtr->freeIntRepProc(objPtr);
  1945     }
  1946 
  1947     if (isWide) {
  1948 	objPtr->internalRep.wideValue =
  1949 		(isNegative ? -(Tcl_WideInt)newLong : (Tcl_WideInt)newLong);
  1950 	objPtr->typePtr = &tclWideIntType;
  1951     } else {
  1952 	objPtr->internalRep.longValue =
  1953 		(isNegative ? -(long)newLong : (long)newLong);
  1954 	objPtr->typePtr = &tclIntType;
  1955     }
  1956     return TCL_OK;
  1957 }
  1958 
  1959 /*
  1960  *----------------------------------------------------------------------
  1961  *
  1962  * UpdateStringOfInt --
  1963  *
  1964  *	Update the string representation for an integer object.
  1965  *	Note: This procedure does not free an existing old string rep
  1966  *	so storage will be lost if this has not already been done. 
  1967  *
  1968  * Results:
  1969  *	None.
  1970  *
  1971  * Side effects:
  1972  *	The object's string is set to a valid string that results from
  1973  *	the int-to-string conversion.
  1974  *
  1975  *----------------------------------------------------------------------
  1976  */
  1977 
  1978 static void
  1979 UpdateStringOfInt(objPtr)
  1980     register Tcl_Obj *objPtr;	/* Int object whose string rep to update. */
  1981 {
  1982     char buffer[TCL_INTEGER_SPACE];
  1983     register int len;
  1984     
  1985     len = TclFormatInt(buffer, objPtr->internalRep.longValue);
  1986     
  1987     objPtr->bytes = ckalloc((unsigned) len + 1);
  1988     strcpy(objPtr->bytes, buffer);
  1989     objPtr->length = len;
  1990 }
  1991 
  1992 /*
  1993  *----------------------------------------------------------------------
  1994  *
  1995  * Tcl_NewLongObj --
  1996  *
  1997  *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
  1998  *	Tcl_NewLongObj to create a new long integer object end up calling
  1999  *	the debugging procedure Tcl_DbNewLongObj instead.
  2000  *
  2001  *	Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,
  2002  *	calls to Tcl_NewLongObj result in a call to one of the two
  2003  *	Tcl_NewLongObj implementations below. We provide two implementations
  2004  *	so that the Tcl core can be compiled to do memory debugging of the 
  2005  *	core even if a client does not request it for itself.
  2006  *
  2007  *	Integer and long integer objects share the same "integer" type
  2008  *	implementation. We store all integers as longs and Tcl_GetIntFromObj
  2009  *	checks whether the current value of the long can be represented by
  2010  *	an int.
  2011  *
  2012  * Results:
  2013  *	The newly created object is returned. This object will have an
  2014  *	invalid string representation. The returned object has ref count 0.
  2015  *
  2016  * Side effects:
  2017  *	None.
  2018  *
  2019  *----------------------------------------------------------------------
  2020  */
  2021 
  2022 #ifdef TCL_MEM_DEBUG
  2023 #undef Tcl_NewLongObj
  2024 
  2025 EXPORT_C Tcl_Obj *
  2026 Tcl_NewLongObj(longValue)
  2027     register long longValue;	/* Long integer used to initialize the
  2028 				 * new object. */
  2029 {
  2030     return Tcl_DbNewLongObj(longValue, "unknown", 0);
  2031 }
  2032 
  2033 #else /* if not TCL_MEM_DEBUG */
  2034 
  2035 EXPORT_C Tcl_Obj *
  2036 Tcl_NewLongObj(longValue)
  2037     register long longValue;	/* Long integer used to initialize the
  2038 				 * new object. */
  2039 {
  2040     register Tcl_Obj *objPtr;
  2041 
  2042     TclNewObj(objPtr);
  2043     objPtr->bytes = NULL;
  2044     
  2045     objPtr->internalRep.longValue = longValue;
  2046     objPtr->typePtr = &tclIntType;
  2047     return objPtr;
  2048 }
  2049 #endif /* if TCL_MEM_DEBUG */
  2050 
  2051 /*
  2052  *----------------------------------------------------------------------
  2053  *
  2054  * Tcl_DbNewLongObj --
  2055  *
  2056  *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
  2057  *	Tcl_NewIntObj and Tcl_NewLongObj to create new integer or
  2058  *	long integer objects end up calling the debugging procedure
  2059  *	Tcl_DbNewLongObj instead. We provide two implementations of
  2060  *	Tcl_DbNewLongObj so that whether the Tcl core is compiled to do
  2061  *	memory debugging of the core is independent of whether a client
  2062  *	requests debugging for itself.
  2063  *
  2064  *	When the core is compiled with TCL_MEM_DEBUG defined,
  2065  *	Tcl_DbNewLongObj calls Tcl_DbCkalloc directly with the file name and
  2066  *	line number from its caller. This simplifies debugging since then
  2067  *	the [memory active] command will report the caller's file name and
  2068  *	line number when reporting objects that haven't been freed.
  2069  *
  2070  *	Otherwise, when the core is compiled without TCL_MEM_DEBUG defined,
  2071  *	this procedure just returns the result of calling Tcl_NewLongObj.
  2072  *
  2073  * Results:
  2074  *	The newly created long integer object is returned. This object
  2075  *	will have an invalid string representation. The returned object has
  2076  *	ref count 0.
  2077  *
  2078  * Side effects:
  2079  *	Allocates memory.
  2080  *
  2081  *----------------------------------------------------------------------
  2082  */
  2083 
  2084 #ifdef TCL_MEM_DEBUG
  2085 
  2086 EXPORT_C Tcl_Obj *
  2087 Tcl_DbNewLongObj(longValue, file, line)
  2088     register long longValue;	/* Long integer used to initialize the
  2089 				 * new object. */
  2090     CONST char *file;		/* The name of the source file calling this
  2091 				 * procedure; used for debugging. */
  2092     int line;			/* Line number in the source file; used
  2093 				 * for debugging. */
  2094 {
  2095     register Tcl_Obj *objPtr;
  2096 
  2097     TclDbNewObj(objPtr, file, line);
  2098     objPtr->bytes = NULL;
  2099     
  2100     objPtr->internalRep.longValue = longValue;
  2101     objPtr->typePtr = &tclIntType;
  2102     return objPtr;
  2103 }
  2104 
  2105 #else /* if not TCL_MEM_DEBUG */
  2106 
  2107 EXPORT_C Tcl_Obj *
  2108 Tcl_DbNewLongObj(longValue, file, line)
  2109     register long longValue;	/* Long integer used to initialize the
  2110 				 * new object. */
  2111     CONST char *file;		/* The name of the source file calling this
  2112 				 * procedure; used for debugging. */
  2113     int line;			/* Line number in the source file; used
  2114 				 * for debugging. */
  2115 {
  2116     return Tcl_NewLongObj(longValue);
  2117 }
  2118 #endif /* TCL_MEM_DEBUG */
  2119 
  2120 /*
  2121  *----------------------------------------------------------------------
  2122  *
  2123  * Tcl_SetLongObj --
  2124  *
  2125  *	Modify an object to be an integer object and to have the specified
  2126  *	long integer value.
  2127  *
  2128  * Results:
  2129  *	None.
  2130  *
  2131  * Side effects:
  2132  *	The object's old string rep, if any, is freed. Also, any old
  2133  *	internal rep is freed. 
  2134  *
  2135  *----------------------------------------------------------------------
  2136  */
  2137 
  2138 EXPORT_C void
  2139 Tcl_SetLongObj(objPtr, longValue)
  2140     register Tcl_Obj *objPtr;	/* Object whose internal rep to init. */
  2141     register long longValue;	/* Long integer used to initialize the
  2142 				 * object's value. */
  2143 {
  2144     register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  2145 
  2146     if (Tcl_IsShared(objPtr)) {
  2147 	panic("Tcl_SetLongObj called with shared object");
  2148     }
  2149 
  2150     if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
  2151 	oldTypePtr->freeIntRepProc(objPtr);
  2152     }
  2153     
  2154     objPtr->internalRep.longValue = longValue;
  2155     objPtr->typePtr = &tclIntType;
  2156     Tcl_InvalidateStringRep(objPtr);
  2157 }
  2158 
  2159 /*
  2160  *----------------------------------------------------------------------
  2161  *
  2162  * Tcl_GetLongFromObj --
  2163  *
  2164  *	Attempt to return an long integer from the Tcl object "objPtr". If
  2165  *	the object is not already an int object, an attempt will be made to
  2166  *	convert it to one.
  2167  *
  2168  * Results:
  2169  *	The return value is a standard Tcl object result. If an error occurs
  2170  *	during conversion, an error message is left in the interpreter's
  2171  *	result unless "interp" is NULL.
  2172  *
  2173  * Side effects:
  2174  *	If the object is not already an int object, the conversion will free
  2175  *	any old internal representation.
  2176  *
  2177  *----------------------------------------------------------------------
  2178  */
  2179 
  2180 EXPORT_C int
  2181 Tcl_GetLongFromObj(interp, objPtr, longPtr)
  2182     Tcl_Interp *interp; 	/* Used for error reporting if not NULL. */
  2183     register Tcl_Obj *objPtr;	/* The object from which to get a long. */
  2184     register long *longPtr;	/* Place to store resulting long. */
  2185 {
  2186     register int result;
  2187     
  2188     if (objPtr->typePtr != &tclIntType && objPtr->typePtr != &tclWideIntType) {
  2189 	result = SetIntOrWideFromAny(interp, objPtr);
  2190 	if (result != TCL_OK) {
  2191 	    return result;
  2192 	}
  2193     }
  2194 
  2195 #ifndef TCL_WIDE_INT_IS_LONG
  2196     if (objPtr->typePtr == &tclWideIntType) {
  2197 	/*
  2198 	 * If the object is already a wide integer, don't convert it.
  2199 	 * This code allows for any integer in the range -ULONG_MAX to
  2200 	 * ULONG_MAX to be converted to a long, ignoring overflow.
  2201 	 * The rule preserves existing semantics for conversion of
  2202 	 * integers on input, but avoids inadvertent demotion of
  2203 	 * wide integers to 32-bit ones in the internal rep.
  2204 	 */
  2205 
  2206 	Tcl_WideInt w = objPtr->internalRep.wideValue;
  2207 	if (w >= -(Tcl_WideInt)(ULONG_MAX) && w <= (Tcl_WideInt)(ULONG_MAX)) {
  2208 	    *longPtr = Tcl_WideAsLong(w);
  2209 	    return TCL_OK;
  2210 	} else {
  2211 	    if (interp != NULL) {
  2212 		Tcl_ResetResult(interp);
  2213 		Tcl_AppendToObj(Tcl_GetObjResult(interp),
  2214 			"integer value too large to represent", -1);
  2215 	    }
  2216 	    return TCL_ERROR;
  2217 	}
  2218     }
  2219 #endif
  2220 
  2221     *longPtr = objPtr->internalRep.longValue;
  2222     return TCL_OK;
  2223 }
  2224 
  2225 /*
  2226  *----------------------------------------------------------------------
  2227  *
  2228  * SetWideIntFromAny --
  2229  *
  2230  *	Attempt to generate an integer internal form for the Tcl object
  2231  *	"objPtr".
  2232  *
  2233  * Results:
  2234  *	The return value is a standard object Tcl result. If an error occurs
  2235  *	during conversion, an error message is left in the interpreter's
  2236  *	result unless "interp" is NULL.
  2237  *
  2238  * Side effects:
  2239  *	If no error occurs, an int is stored as "objPtr"s internal
  2240  *	representation. 
  2241  *
  2242  *----------------------------------------------------------------------
  2243  */
  2244 
  2245 static int
  2246 SetWideIntFromAny(interp, objPtr)
  2247     Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
  2248     register Tcl_Obj *objPtr;	/* The object to convert. */
  2249 {
  2250 #ifndef TCL_WIDE_INT_IS_LONG
  2251     Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  2252     char *string, *end;
  2253     int length;
  2254     register char *p;
  2255     Tcl_WideInt newWide;
  2256 
  2257     /*
  2258      * Get the string representation. Make it up-to-date if necessary.
  2259      */
  2260 
  2261     p = string = Tcl_GetStringFromObj(objPtr, &length);
  2262 
  2263     /*
  2264      * Now parse "objPtr"s string as an int. We use an implementation here
  2265      * that doesn't report errors in interp if interp is NULL. Note: use
  2266      * strtoull instead of strtoll for integer conversions to allow full-size
  2267      * unsigned numbers, but don't depend on strtoull to handle sign
  2268      * characters; it won't in some implementations.
  2269      */
  2270 
  2271     errno = 0;
  2272 #ifdef TCL_STRTOUL_SIGN_CHECK
  2273     for ( ;  isspace(UCHAR(*p));  p++) { /* INTL: ISO space. */
  2274 	/* Empty loop body. */
  2275     }
  2276     if (*p == '-') {
  2277 	p++;
  2278 	newWide = -((Tcl_WideInt)strtoull(p, &end, 0));
  2279     } else if (*p == '+') {
  2280 	p++;
  2281 	newWide = strtoull(p, &end, 0);
  2282     } else
  2283 #else
  2284 	newWide = strtoull(p, &end, 0);
  2285 #endif
  2286     if (end == p) {
  2287 	badInteger:
  2288 	if (interp != NULL) {
  2289 	    /*
  2290 	     * Must copy string before resetting the result in case a caller
  2291 	     * is trying to convert the interpreter's result to an int.
  2292 	     */
  2293 	    
  2294 	    char buf[100];
  2295 	    sprintf(buf, "expected integer but got \"%.50s\"", string);
  2296 	    Tcl_ResetResult(interp);
  2297 	    Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
  2298 	    TclCheckBadOctal(interp, string);
  2299 	}
  2300 	return TCL_ERROR;
  2301     }
  2302     if (errno == ERANGE) {
  2303 	if (interp != NULL) {
  2304 	    char *s = "integer value too large to represent";
  2305 	    Tcl_ResetResult(interp);
  2306 	    Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
  2307 	    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *) NULL);
  2308 	}
  2309 	return TCL_ERROR;
  2310     }
  2311 
  2312     /*
  2313      * Make sure that the string has no garbage after the end of the int.
  2314      */
  2315     
  2316     while ((end < (string+length))
  2317 	    && isspace(UCHAR(*end))) { /* INTL: ISO space. */
  2318 	end++;
  2319     }
  2320     if (end != (string+length)) {
  2321 	goto badInteger;
  2322     }
  2323 
  2324     /*
  2325      * The conversion to int succeeded. Free the old internalRep before
  2326      * setting the new one. We do this as late as possible to allow the
  2327      * conversion code, in particular Tcl_GetStringFromObj, to use that old
  2328      * internalRep.
  2329      */
  2330 
  2331     if ((oldTypePtr != NULL) &&	(oldTypePtr->freeIntRepProc != NULL)) {
  2332 	oldTypePtr->freeIntRepProc(objPtr);
  2333     }
  2334     
  2335     objPtr->internalRep.wideValue = newWide;
  2336 #else 
  2337     if (TCL_ERROR == SetIntFromAny(interp, objPtr)) {
  2338 	return TCL_ERROR;
  2339     }
  2340 #endif
  2341     objPtr->typePtr = &tclWideIntType;
  2342     return TCL_OK;
  2343 }
  2344 
  2345 /*
  2346  *----------------------------------------------------------------------
  2347  *
  2348  * UpdateStringOfWideInt --
  2349  *
  2350  *	Update the string representation for a wide integer object.
  2351  *	Note: This procedure does not free an existing old string rep
  2352  *	so storage will be lost if this has not already been done. 
  2353  *
  2354  * Results:
  2355  *	None.
  2356  *
  2357  * Side effects:
  2358  *	The object's string is set to a valid string that results from
  2359  *	the wideInt-to-string conversion.
  2360  *
  2361  *----------------------------------------------------------------------
  2362  */
  2363 
  2364 #ifndef TCL_WIDE_INT_IS_LONG
  2365 static void
  2366 UpdateStringOfWideInt(objPtr)
  2367     register Tcl_Obj *objPtr;	/* Int object whose string rep to update. */
  2368 {
  2369     char buffer[TCL_INTEGER_SPACE+2];
  2370     register unsigned len;
  2371     register Tcl_WideInt wideVal = objPtr->internalRep.wideValue;
  2372 
  2373     /*
  2374      * Note that sprintf will generate a compiler warning under
  2375      * Mingw claiming %I64 is an unknown format specifier.
  2376      * Just ignore this warning. We can't use %L as the format
  2377      * specifier since that gets printed as a 32 bit value.
  2378      */
  2379     sprintf(buffer, "%" TCL_LL_MODIFIER "d", wideVal);
  2380     len = strlen(buffer);
  2381     objPtr->bytes = ckalloc((unsigned) len + 1);
  2382     memcpy(objPtr->bytes, buffer, len + 1);
  2383     objPtr->length = len;
  2384 }
  2385 #endif /* TCL_WIDE_INT_IS_LONG */
  2386 
  2387 /*
  2388  *----------------------------------------------------------------------
  2389  *
  2390  * Tcl_NewWideIntObj --
  2391  *
  2392  *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
  2393  *	Tcl_NewWideIntObj to create a new 64-bit integer object end up calling
  2394  *	the debugging procedure Tcl_DbNewWideIntObj instead.
  2395  *
  2396  *	Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,
  2397  *	calls to Tcl_NewWideIntObj result in a call to one of the two
  2398  *	Tcl_NewWideIntObj implementations below. We provide two implementations
  2399  *	so that the Tcl core can be compiled to do memory debugging of the 
  2400  *	core even if a client does not request it for itself.
  2401  *
  2402  * Results:
  2403  *	The newly created object is returned. This object will have an
  2404  *	invalid string representation. The returned object has ref count 0.
  2405  *
  2406  * Side effects:
  2407  *	None.
  2408  *
  2409  *----------------------------------------------------------------------
  2410  */
  2411 
  2412 #ifdef TCL_MEM_DEBUG
  2413 #undef Tcl_NewWideIntObj
  2414 
  2415 EXPORT_C Tcl_Obj *
  2416 Tcl_NewWideIntObj(wideValue)
  2417     register Tcl_WideInt wideValue;	/* Wide integer used to initialize
  2418 					 * the new object. */
  2419 {
  2420     return Tcl_DbNewWideIntObj(wideValue, "unknown", 0);
  2421 }
  2422 
  2423 #else /* if not TCL_MEM_DEBUG */
  2424 
  2425 EXPORT_C Tcl_Obj *
  2426 Tcl_NewWideIntObj(wideValue)
  2427     register Tcl_WideInt wideValue;	/* Wide integer used to initialize
  2428 					 * the new object. */
  2429 {
  2430     register Tcl_Obj *objPtr;
  2431 
  2432     TclNewObj(objPtr);
  2433     objPtr->bytes = NULL;
  2434     
  2435     objPtr->internalRep.wideValue = wideValue;
  2436     objPtr->typePtr = &tclWideIntType;
  2437     return objPtr;
  2438 }
  2439 #endif /* if TCL_MEM_DEBUG */
  2440 
  2441 /*
  2442  *----------------------------------------------------------------------
  2443  *
  2444  * Tcl_DbNewWideIntObj --
  2445  *
  2446  *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
  2447  *	Tcl_NewWideIntObj to create new wide integer end up calling
  2448  *	the debugging procedure Tcl_DbNewWideIntObj instead. We
  2449  *	provide two implementations of Tcl_DbNewWideIntObj so that
  2450  *	whether the Tcl core is compiled to do memory debugging of the
  2451  *	core is independent of whether a client requests debugging for
  2452  *	itself.
  2453  *
  2454  *	When the core is compiled with TCL_MEM_DEBUG defined,
  2455  *	Tcl_DbNewWideIntObj calls Tcl_DbCkalloc directly with the file
  2456  *	name and line number from its caller. This simplifies
  2457  *	debugging since then the checkmem command will report the
  2458  *	caller's file name and line number when reporting objects that
  2459  *	haven't been freed.
  2460  *
  2461  *	Otherwise, when the core is compiled without TCL_MEM_DEBUG defined,
  2462  *	this procedure just returns the result of calling Tcl_NewWideIntObj.
  2463  *
  2464  * Results:
  2465  *	The newly created wide integer object is returned. This object
  2466  *	will have an invalid string representation. The returned object has
  2467  *	ref count 0.
  2468  *
  2469  * Side effects:
  2470  *	Allocates memory.
  2471  *
  2472  *----------------------------------------------------------------------
  2473  */
  2474 
  2475 #ifdef TCL_MEM_DEBUG
  2476 
  2477 EXPORT_C Tcl_Obj *
  2478 Tcl_DbNewWideIntObj(wideValue, file, line)
  2479     register Tcl_WideInt wideValue;	/* Wide integer used to initialize
  2480 					 * the new object. */
  2481     CONST char *file;			/* The name of the source file
  2482 					 * calling this procedure; used for
  2483 					 * debugging. */
  2484     int line;				/* Line number in the source file;
  2485 					 * used for debugging. */
  2486 {
  2487     register Tcl_Obj *objPtr;
  2488 
  2489     TclDbNewObj(objPtr, file, line);
  2490     objPtr->bytes = NULL;
  2491     
  2492     objPtr->internalRep.wideValue = wideValue;
  2493     objPtr->typePtr = &tclWideIntType;
  2494     return objPtr;
  2495 }
  2496 
  2497 #else /* if not TCL_MEM_DEBUG */
  2498 
  2499 EXPORT_C Tcl_Obj *
  2500 Tcl_DbNewWideIntObj(wideValue, file, line)
  2501     register Tcl_WideInt wideValue;	/* Long integer used to initialize
  2502 					 * the new object. */
  2503     CONST char *file;			/* The name of the source file
  2504 					 * calling this procedure; used for
  2505 					 * debugging. */
  2506     int line;				/* Line number in the source file;
  2507 					 * used for debugging. */
  2508 {
  2509     return Tcl_NewWideIntObj(wideValue);
  2510 }
  2511 #endif /* TCL_MEM_DEBUG */
  2512 
  2513 /*
  2514  *----------------------------------------------------------------------
  2515  *
  2516  * Tcl_SetWideIntObj --
  2517  *
  2518  *	Modify an object to be a wide integer object and to have the
  2519  *	specified wide integer value.
  2520  *
  2521  * Results:
  2522  *	None.
  2523  *
  2524  * Side effects:
  2525  *	The object's old string rep, if any, is freed. Also, any old
  2526  *	internal rep is freed. 
  2527  *
  2528  *----------------------------------------------------------------------
  2529  */
  2530 
  2531 EXPORT_C void
  2532 Tcl_SetWideIntObj(objPtr, wideValue)
  2533     register Tcl_Obj *objPtr;		/* Object w. internal rep to init. */
  2534     register Tcl_WideInt wideValue;	/* Wide integer used to initialize
  2535 					 * the object's value. */
  2536 {
  2537     register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  2538 
  2539     if (Tcl_IsShared(objPtr)) {
  2540 	panic("Tcl_SetWideIntObj called with shared object");
  2541     }
  2542 
  2543     if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
  2544 	oldTypePtr->freeIntRepProc(objPtr);
  2545     }
  2546     
  2547     objPtr->internalRep.wideValue = wideValue;
  2548     objPtr->typePtr = &tclWideIntType;
  2549     Tcl_InvalidateStringRep(objPtr);
  2550 }
  2551 
  2552 /*
  2553  *----------------------------------------------------------------------
  2554  *
  2555  * Tcl_GetWideIntFromObj --
  2556  *
  2557  *	Attempt to return a wide integer from the Tcl object "objPtr". If
  2558  *	the object is not already a wide int object, an attempt will be made
  2559  *	to convert it to one.
  2560  *
  2561  * Results:
  2562  *	The return value is a standard Tcl object result. If an error occurs
  2563  *	during conversion, an error message is left in the interpreter's
  2564  *	result unless "interp" is NULL.
  2565  *
  2566  * Side effects:
  2567  *	If the object is not already an int object, the conversion will free
  2568  *	any old internal representation.
  2569  *
  2570  *----------------------------------------------------------------------
  2571  */
  2572 
  2573 EXPORT_C int
  2574 Tcl_GetWideIntFromObj(interp, objPtr, wideIntPtr)
  2575     Tcl_Interp *interp; 	/* Used for error reporting if not NULL. */
  2576     register Tcl_Obj *objPtr;	/* Object from which to get a wide int. */
  2577     register Tcl_WideInt *wideIntPtr; /* Place to store resulting long. */
  2578 {
  2579     register int result;
  2580 
  2581     if (objPtr->typePtr == &tclWideIntType) {
  2582     gotWide:
  2583 	*wideIntPtr = objPtr->internalRep.wideValue;
  2584 	return TCL_OK;
  2585     }
  2586     if (objPtr->typePtr == &tclIntType) {
  2587 	/*
  2588 	 * This cast is safe; all valid ints/longs are wides.
  2589 	 */
  2590 
  2591 	objPtr->internalRep.wideValue =
  2592 		Tcl_LongAsWide(objPtr->internalRep.longValue);
  2593 	objPtr->typePtr = &tclWideIntType;
  2594 	goto gotWide;
  2595     }
  2596     result = SetWideIntFromAny(interp, objPtr);
  2597     if (result == TCL_OK) {
  2598 	*wideIntPtr = objPtr->internalRep.wideValue;
  2599     }
  2600     return result;
  2601 }
  2602 
  2603 /*
  2604  *----------------------------------------------------------------------
  2605  *
  2606  * Tcl_DbIncrRefCount --
  2607  *
  2608  *	This procedure is normally called when debugging: i.e., when
  2609  *	TCL_MEM_DEBUG is defined. This checks to see whether or not
  2610  *	the memory has been freed before incrementing the ref count.
  2611  *
  2612  *	When TCL_MEM_DEBUG is not defined, this procedure just increments
  2613  *	the reference count of the object.
  2614  *
  2615  * Results:
  2616  *	None.
  2617  *
  2618  * Side effects:
  2619  *	The object's ref count is incremented.
  2620  *
  2621  *----------------------------------------------------------------------
  2622  */
  2623 
  2624 EXPORT_C void
  2625 Tcl_DbIncrRefCount(objPtr, file, line)
  2626     register Tcl_Obj *objPtr;	/* The object we are registering a
  2627 				 * reference to. */
  2628     CONST char *file;		/* The name of the source file calling this
  2629 				 * procedure; used for debugging. */
  2630     int line;			/* Line number in the source file; used
  2631 				 * for debugging. */
  2632 {
  2633 #ifdef TCL_MEM_DEBUG
  2634     if (objPtr->refCount == 0x61616161) {
  2635 	fprintf(stderr, "file = %s, line = %d\n", file, line);
  2636 	fflush(stderr);
  2637 	panic("Trying to increment refCount of previously disposed object.");
  2638     }
  2639 #endif
  2640     ++(objPtr)->refCount;
  2641 }
  2642 
  2643 /*
  2644  *----------------------------------------------------------------------
  2645  *
  2646  * Tcl_DbDecrRefCount --
  2647  *
  2648  *	This procedure is normally called when debugging: i.e., when
  2649  *	TCL_MEM_DEBUG is defined. This checks to see whether or not
  2650  *	the memory has been freed before decrementing the ref count.
  2651  *
  2652  *	When TCL_MEM_DEBUG is not defined, this procedure just decrements
  2653  *	the reference count of the object.
  2654  *
  2655  * Results:
  2656  *	None.
  2657  *
  2658  * Side effects:
  2659  *	The object's ref count is incremented.
  2660  *
  2661  *----------------------------------------------------------------------
  2662  */
  2663 
  2664 EXPORT_C void
  2665 Tcl_DbDecrRefCount(objPtr, file, line)
  2666     register Tcl_Obj *objPtr;	/* The object we are releasing a reference
  2667 				 * to. */
  2668     CONST char *file;		/* The name of the source file calling this
  2669 				 * procedure; used for debugging. */
  2670     int line;			/* Line number in the source file; used
  2671 				 * for debugging. */
  2672 {
  2673 #ifdef TCL_MEM_DEBUG
  2674     if (objPtr->refCount == 0x61616161) {
  2675 	fprintf(stderr, "file = %s, line = %d\n", file, line);
  2676 	fflush(stderr);
  2677 	panic("Trying to decrement refCount of previously disposed object.");
  2678     }
  2679 #endif
  2680     if (--(objPtr)->refCount <= 0) {
  2681 	TclFreeObj(objPtr);
  2682     }
  2683 }
  2684 
  2685 /*
  2686  *----------------------------------------------------------------------
  2687  *
  2688  * Tcl_DbIsShared --
  2689  *
  2690  *	This procedure is normally called when debugging: i.e., when
  2691  *	TCL_MEM_DEBUG is defined. It tests whether the object has a ref
  2692  *	count greater than one.
  2693  *
  2694  *	When TCL_MEM_DEBUG is not defined, this procedure just tests
  2695  *	if the object has a ref count greater than one.
  2696  *
  2697  * Results:
  2698  *	None.
  2699  *
  2700  * Side effects:
  2701  *	None.
  2702  *
  2703  *----------------------------------------------------------------------
  2704  */
  2705 
  2706 EXPORT_C int
  2707 Tcl_DbIsShared(objPtr, file, line)
  2708     register Tcl_Obj *objPtr;	/* The object to test for being shared. */
  2709     CONST char *file;		/* The name of the source file calling this
  2710 				 * procedure; used for debugging. */
  2711     int line;			/* Line number in the source file; used
  2712 				 * for debugging. */
  2713 {
  2714 #ifdef TCL_MEM_DEBUG
  2715     if (objPtr->refCount == 0x61616161) {
  2716 	fprintf(stderr, "file = %s, line = %d\n", file, line);
  2717 	fflush(stderr);
  2718 	panic("Trying to check whether previously disposed object is shared.");
  2719     }
  2720 #endif
  2721 #ifdef TCL_COMPILE_STATS
  2722     Tcl_MutexLock(&tclObjMutex);
  2723     if ((objPtr)->refCount <= 1) {
  2724 	tclObjsShared[1]++;
  2725     } else if ((objPtr)->refCount < TCL_MAX_SHARED_OBJ_STATS) {
  2726 	tclObjsShared[(objPtr)->refCount]++;
  2727     } else {
  2728 	tclObjsShared[0]++;
  2729     }
  2730     Tcl_MutexUnlock(&tclObjMutex);
  2731 #endif
  2732     return ((objPtr)->refCount > 1);
  2733 }
  2734 
  2735 /*
  2736  *----------------------------------------------------------------------
  2737  *
  2738  * Tcl_InitObjHashTable --
  2739  *
  2740  *	Given storage for a hash table, set up the fields to prepare
  2741  *	the hash table for use, the keys are Tcl_Obj *.
  2742  *
  2743  * Results:
  2744  *	None.
  2745  *
  2746  * Side effects:
  2747  *	TablePtr is now ready to be passed to Tcl_FindHashEntry and
  2748  *	Tcl_CreateHashEntry.
  2749  *
  2750  *----------------------------------------------------------------------
  2751  */
  2752 
  2753 EXPORT_C void
  2754 Tcl_InitObjHashTable(tablePtr)
  2755     register Tcl_HashTable *tablePtr;	/* Pointer to table record, which
  2756 					 * is supplied by the caller. */
  2757 {
  2758     Tcl_InitCustomHashTable(tablePtr, TCL_CUSTOM_PTR_KEYS,
  2759 	    &tclObjHashKeyType);
  2760 }
  2761 
  2762 /*
  2763  *----------------------------------------------------------------------
  2764  *
  2765  * AllocObjEntry --
  2766  *
  2767  *	Allocate space for a Tcl_HashEntry containing the Tcl_Obj * key.
  2768  *
  2769  * Results:
  2770  *	The return value is a pointer to the created entry.
  2771  *
  2772  * Side effects:
  2773  *	Increments the reference count on the object.
  2774  *
  2775  *----------------------------------------------------------------------
  2776  */
  2777 
  2778 static Tcl_HashEntry *
  2779 AllocObjEntry(tablePtr, keyPtr)
  2780     Tcl_HashTable *tablePtr;	/* Hash table. */
  2781     VOID *keyPtr;		/* Key to store in the hash table entry. */
  2782 {
  2783     Tcl_Obj *objPtr = (Tcl_Obj *) keyPtr;
  2784     Tcl_HashEntry *hPtr;
  2785 
  2786     hPtr = (Tcl_HashEntry *) ckalloc((unsigned) (sizeof(Tcl_HashEntry)));
  2787     hPtr->key.oneWordValue = (char *) objPtr;
  2788     Tcl_IncrRefCount (objPtr);
  2789 
  2790     return hPtr;
  2791 }
  2792 
  2793 /*
  2794  *----------------------------------------------------------------------
  2795  *
  2796  * CompareObjKeys --
  2797  *
  2798  *	Compares two Tcl_Obj * keys.
  2799  *
  2800  * Results:
  2801  *	The return value is 0 if they are different and 1 if they are
  2802  *	the same.
  2803  *
  2804  * Side effects:
  2805  *	None.
  2806  *
  2807  *----------------------------------------------------------------------
  2808  */
  2809 
  2810 static int
  2811 CompareObjKeys(keyPtr, hPtr)
  2812     VOID *keyPtr;		/* New key to compare. */
  2813     Tcl_HashEntry *hPtr;		/* Existing key to compare. */
  2814 {
  2815     Tcl_Obj *objPtr1 = (Tcl_Obj *) keyPtr;
  2816     Tcl_Obj *objPtr2 = (Tcl_Obj *) hPtr->key.oneWordValue;
  2817     register CONST char *p1, *p2;
  2818     register int l1, l2;
  2819 
  2820     /*
  2821      * If the object pointers are the same then they match.
  2822      */
  2823     if (objPtr1 == objPtr2) {
  2824 	return 1;
  2825     }
  2826 
  2827     /*
  2828      * Don't use Tcl_GetStringFromObj as it would prevent l1 and l2 being
  2829      * in a register.
  2830      */
  2831     p1 = TclGetString(objPtr1);
  2832     l1 = objPtr1->length;
  2833     p2 = TclGetString(objPtr2);
  2834     l2 = objPtr2->length;
  2835     
  2836     /*
  2837      * Only compare if the string representations are of the same length.
  2838      */
  2839     if (l1 == l2) {
  2840 	for (;; p1++, p2++, l1--) {
  2841 	    if (*p1 != *p2) {
  2842 		break;
  2843 	    }
  2844 	    if (l1 == 0) {
  2845 		return 1;
  2846 	    }
  2847 	}
  2848     }
  2849 
  2850     return 0;
  2851 }
  2852 
  2853 /*
  2854  *----------------------------------------------------------------------
  2855  *
  2856  * FreeObjEntry --
  2857  *
  2858  *	Frees space for a Tcl_HashEntry containing the Tcl_Obj * key.
  2859  *
  2860  * Results:
  2861  *	The return value is a pointer to the created entry.
  2862  *
  2863  * Side effects:
  2864  *	Decrements the reference count of the object.
  2865  *
  2866  *----------------------------------------------------------------------
  2867  */
  2868 
  2869 static void
  2870 FreeObjEntry(hPtr)
  2871     Tcl_HashEntry *hPtr;	/* Hash entry to free. */
  2872 {
  2873     Tcl_Obj *objPtr = (Tcl_Obj *) hPtr->key.oneWordValue;
  2874 
  2875     Tcl_DecrRefCount (objPtr);
  2876     ckfree ((char *) hPtr);
  2877 }
  2878 
  2879 /*
  2880  *----------------------------------------------------------------------
  2881  *
  2882  * HashObjKey --
  2883  *
  2884  *	Compute a one-word summary of the string representation of the
  2885  *	Tcl_Obj, which can be used to generate a hash index.
  2886  *
  2887  * Results:
  2888  *	The return value is a one-word summary of the information in
  2889  *	the string representation of the Tcl_Obj.
  2890  *
  2891  * Side effects:
  2892  *	None.
  2893  *
  2894  *----------------------------------------------------------------------
  2895  */
  2896 
  2897 static unsigned int
  2898 HashObjKey(tablePtr, keyPtr)
  2899     Tcl_HashTable *tablePtr;	/* Hash table. */
  2900     VOID *keyPtr;		/* Key from which to compute hash value. */
  2901 {
  2902     Tcl_Obj *objPtr = (Tcl_Obj *) keyPtr;
  2903     CONST char *string = TclGetString(objPtr);
  2904     int length = objPtr->length;
  2905     unsigned int result;
  2906     int i;
  2907 
  2908     /*
  2909      * I tried a zillion different hash functions and asked many other
  2910      * people for advice.  Many people had their own favorite functions,
  2911      * all different, but no-one had much idea why they were good ones.
  2912      * I chose the one below (multiply by 9 and add new character)
  2913      * because of the following reasons:
  2914      *
  2915      * 1. Multiplying by 10 is perfect for keys that are decimal strings,
  2916      *    and multiplying by 9 is just about as good.
  2917      * 2. Times-9 is (shift-left-3) plus (old).  This means that each
  2918      *    character's bits hang around in the low-order bits of the
  2919      *    hash value for ever, plus they spread fairly rapidly up to
  2920      *    the high-order bits to fill out the hash value.  This seems
  2921      *    works well both for decimal and non-decimal strings.
  2922      */
  2923 
  2924     result = 0;
  2925     for (i=0 ; i<length ; i++) {
  2926 	result += (result<<3) + string[i];
  2927     }
  2928     return result;
  2929 }
  2930 
  2931 /*
  2932  *----------------------------------------------------------------------
  2933  *
  2934  * Tcl_GetCommandFromObj --
  2935  *
  2936  *      Returns the command specified by the name in a Tcl_Obj.
  2937  *
  2938  * Results:
  2939  *	Returns a token for the command if it is found. Otherwise, if it
  2940  *	can't be found or there is an error, returns NULL.
  2941  *
  2942  * Side effects:
  2943  *      May update the internal representation for the object, caching
  2944  *      the command reference so that the next time this procedure is
  2945  *	called with the same object, the command can be found quickly.
  2946  *
  2947  *----------------------------------------------------------------------
  2948  */
  2949 
  2950 Tcl_Command
  2951 Tcl_GetCommandFromObj(interp, objPtr)
  2952     Tcl_Interp *interp;		/* The interpreter in which to resolve the
  2953 				 * command and to report errors. */
  2954     register Tcl_Obj *objPtr;	/* The object containing the command's
  2955 				 * name. If the name starts with "::", will
  2956 				 * be looked up in global namespace. Else,
  2957 				 * looked up first in the current namespace,
  2958 				 * then in global namespace. */
  2959 {
  2960     Interp *iPtr = (Interp *) interp;
  2961     register ResolvedCmdName *resPtr;
  2962     register Command *cmdPtr;
  2963     Namespace *currNsPtr;
  2964     int result;
  2965     CallFrame *savedFramePtr;
  2966     char *name;
  2967 
  2968     /*
  2969      * If the variable name is fully qualified, do as if the lookup were
  2970      * done from the global namespace; this helps avoid repeated lookups 
  2971      * of fully qualified names. It costs close to nothing, and may be very
  2972      * helpful for OO applications which pass along a command name ("this"),
  2973      * [Patch 456668]
  2974      */
  2975 
  2976     savedFramePtr = iPtr->varFramePtr;
  2977     name = Tcl_GetString(objPtr);
  2978     if ((*name++ == ':') && (*name == ':')) {
  2979 	iPtr->varFramePtr = NULL;
  2980     }
  2981 
  2982     /*
  2983      * Get the internal representation, converting to a command type if
  2984      * needed. The internal representation is a ResolvedCmdName that points
  2985      * to the actual command.
  2986      */
  2987     
  2988     if (objPtr->typePtr != &tclCmdNameType) {
  2989         result = tclCmdNameType.setFromAnyProc(interp, objPtr);
  2990         if (result != TCL_OK) {
  2991 	    iPtr->varFramePtr = savedFramePtr;
  2992             return (Tcl_Command) NULL;
  2993         }
  2994     }
  2995     resPtr = (ResolvedCmdName *) objPtr->internalRep.twoPtrValue.ptr1;
  2996 
  2997     /*
  2998      * Get the current namespace.
  2999      */
  3000     
  3001     if (iPtr->varFramePtr != NULL) {
  3002 	currNsPtr = iPtr->varFramePtr->nsPtr;
  3003     } else {
  3004 	currNsPtr = iPtr->globalNsPtr;
  3005     }
  3006 
  3007     /*
  3008      * Check the context namespace and the namespace epoch of the resolved
  3009      * symbol to make sure that it is fresh. If not, then force another
  3010      * conversion to the command type, to discard the old rep and create a
  3011      * new one. Note that we verify that the namespace id of the context
  3012      * namespace is the same as the one we cached; this insures that the
  3013      * namespace wasn't deleted and a new one created at the same address
  3014      * with the same command epoch.
  3015      */
  3016     
  3017     cmdPtr = NULL;
  3018     if ((resPtr != NULL)
  3019 	    && (resPtr->refNsPtr == currNsPtr)
  3020 	    && (resPtr->refNsId == currNsPtr->nsId)
  3021 	    && (resPtr->refNsCmdEpoch == currNsPtr->cmdRefEpoch)) {
  3022         cmdPtr = resPtr->cmdPtr;
  3023         if (cmdPtr->cmdEpoch != resPtr->cmdEpoch) {
  3024             cmdPtr = NULL;
  3025         }
  3026     }
  3027 
  3028     if (cmdPtr == NULL) {
  3029         result = tclCmdNameType.setFromAnyProc(interp, objPtr);
  3030         if (result != TCL_OK) {
  3031 	    iPtr->varFramePtr = savedFramePtr;
  3032             return (Tcl_Command) NULL;
  3033         }
  3034         resPtr = (ResolvedCmdName *) objPtr->internalRep.twoPtrValue.ptr1;
  3035         if (resPtr != NULL) {
  3036             cmdPtr = resPtr->cmdPtr;
  3037         }
  3038     }
  3039     iPtr->varFramePtr = savedFramePtr;
  3040     return (Tcl_Command) cmdPtr;
  3041 }
  3042 
  3043 /*
  3044  *----------------------------------------------------------------------
  3045  *
  3046  * TclSetCmdNameObj --
  3047  *
  3048  *	Modify an object to be an CmdName object that refers to the argument
  3049  *	Command structure.
  3050  *
  3051  * Results:
  3052  *	None.
  3053  *
  3054  * Side effects:
  3055  *	The object's old internal rep is freed. It's string rep is not
  3056  *	changed. The refcount in the Command structure is incremented to
  3057  *	keep it from being freed if the command is later deleted until
  3058  *	TclExecuteByteCode has a chance to recognize that it was deleted.
  3059  *
  3060  *----------------------------------------------------------------------
  3061  */
  3062 
  3063 void
  3064 TclSetCmdNameObj(interp, objPtr, cmdPtr)
  3065     Tcl_Interp *interp;		/* Points to interpreter containing command
  3066 				 * that should be cached in objPtr. */
  3067     register Tcl_Obj *objPtr;	/* Points to Tcl object to be changed to
  3068 				 * a CmdName object. */
  3069     Command *cmdPtr;		/* Points to Command structure that the
  3070 				 * CmdName object should refer to. */
  3071 {
  3072     Interp *iPtr = (Interp *) interp;
  3073     register ResolvedCmdName *resPtr;
  3074     Tcl_ObjType *oldTypePtr = objPtr->typePtr;
  3075     register Namespace *currNsPtr;
  3076 
  3077     if (oldTypePtr == &tclCmdNameType) {
  3078 	return;
  3079     }
  3080     
  3081     /*
  3082      * Get the current namespace.
  3083      */
  3084     
  3085     if (iPtr->varFramePtr != NULL) {
  3086 	currNsPtr = iPtr->varFramePtr->nsPtr;
  3087     } else {
  3088 	currNsPtr = iPtr->globalNsPtr;
  3089     }
  3090     
  3091     cmdPtr->refCount++;
  3092     resPtr = (ResolvedCmdName *) ckalloc(sizeof(ResolvedCmdName));
  3093     resPtr->cmdPtr = cmdPtr;
  3094     resPtr->refNsPtr = currNsPtr;
  3095     resPtr->refNsId  = currNsPtr->nsId;
  3096     resPtr->refNsCmdEpoch = currNsPtr->cmdRefEpoch;
  3097     resPtr->cmdEpoch = cmdPtr->cmdEpoch;
  3098     resPtr->refCount = 1;
  3099     
  3100     if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
  3101 	oldTypePtr->freeIntRepProc(objPtr);
  3102     }
  3103     objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) resPtr;
  3104     objPtr->internalRep.twoPtrValue.ptr2 = NULL;
  3105     objPtr->typePtr = &tclCmdNameType;
  3106 }
  3107 
  3108 /*
  3109  *----------------------------------------------------------------------
  3110  *
  3111  * FreeCmdNameInternalRep --
  3112  *
  3113  *	Frees the resources associated with a cmdName object's internal
  3114  *	representation.
  3115  *
  3116  * Results:
  3117  *	None.
  3118  *
  3119  * Side effects:
  3120  *	Decrements the ref count of any cached ResolvedCmdName structure
  3121  *	pointed to by the cmdName's internal representation. If this is 
  3122  *	the last use of the ResolvedCmdName, it is freed. This in turn
  3123  *	decrements the ref count of the Command structure pointed to by 
  3124  *	the ResolvedSymbol, which may free the Command structure.
  3125  *
  3126  *----------------------------------------------------------------------
  3127  */
  3128 
  3129 static void
  3130 FreeCmdNameInternalRep(objPtr)
  3131     register Tcl_Obj *objPtr;	/* CmdName object with internal
  3132 				 * representation to free. */
  3133 {
  3134     register ResolvedCmdName *resPtr =
  3135 	(ResolvedCmdName *) objPtr->internalRep.twoPtrValue.ptr1;
  3136 
  3137     if (resPtr != NULL) {
  3138 	/*
  3139 	 * Decrement the reference count of the ResolvedCmdName structure.
  3140 	 * If there are no more uses, free the ResolvedCmdName structure.
  3141 	 */
  3142     
  3143         resPtr->refCount--;
  3144         if (resPtr->refCount == 0) {
  3145             /*
  3146 	     * Now free the cached command, unless it is still in its
  3147              * hash table or if there are other references to it
  3148              * from other cmdName objects.
  3149 	     */
  3150 	    
  3151             Command *cmdPtr = resPtr->cmdPtr;
  3152             TclCleanupCommand(cmdPtr);
  3153             ckfree((char *) resPtr);
  3154         }
  3155     }
  3156 }
  3157 
  3158 /*
  3159  *----------------------------------------------------------------------
  3160  *
  3161  * DupCmdNameInternalRep --
  3162  *
  3163  *	Initialize the internal representation of an cmdName Tcl_Obj to a
  3164  *	copy of the internal representation of an existing cmdName object. 
  3165  *
  3166  * Results:
  3167  *	None.
  3168  *
  3169  * Side effects:
  3170  *	"copyPtr"s internal rep is set to point to the ResolvedCmdName
  3171  *	structure corresponding to "srcPtr"s internal rep. Increments the
  3172  *	ref count of the ResolvedCmdName structure pointed to by the
  3173  *	cmdName's internal representation.
  3174  *
  3175  *----------------------------------------------------------------------
  3176  */
  3177 
  3178 static void
  3179 DupCmdNameInternalRep(srcPtr, copyPtr)
  3180     Tcl_Obj *srcPtr;		/* Object with internal rep to copy. */
  3181     register Tcl_Obj *copyPtr;	/* Object with internal rep to set. */
  3182 {
  3183     register ResolvedCmdName *resPtr =
  3184         (ResolvedCmdName *) srcPtr->internalRep.twoPtrValue.ptr1;
  3185 
  3186     copyPtr->internalRep.twoPtrValue.ptr1 = (VOID *) resPtr;
  3187     copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
  3188     if (resPtr != NULL) {
  3189         resPtr->refCount++;
  3190     }
  3191     copyPtr->typePtr = &tclCmdNameType;
  3192 }
  3193 
  3194 /*
  3195  *----------------------------------------------------------------------
  3196  *
  3197  * SetCmdNameFromAny --
  3198  *
  3199  *	Generate an cmdName internal form for the Tcl object "objPtr".
  3200  *
  3201  * Results:
  3202  *	The return value is a standard Tcl result. The conversion always
  3203  *	succeeds and TCL_OK is returned.
  3204  *
  3205  * Side effects:
  3206  *	A pointer to a ResolvedCmdName structure that holds a cached pointer
  3207  *	to the command with a name that matches objPtr's string rep is
  3208  *	stored as objPtr's internal representation. This ResolvedCmdName
  3209  *	pointer will be NULL if no matching command was found. The ref count
  3210  *	of the cached Command's structure (if any) is also incremented.
  3211  *
  3212  *----------------------------------------------------------------------
  3213  */
  3214 
  3215 static int
  3216 SetCmdNameFromAny(interp, objPtr)
  3217     Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
  3218     register Tcl_Obj *objPtr;	/* The object to convert. */
  3219 {
  3220     Interp *iPtr = (Interp *) interp;
  3221     char *name;
  3222     Tcl_Command cmd;
  3223     register Command *cmdPtr;
  3224     Namespace *currNsPtr;
  3225     register ResolvedCmdName *resPtr;
  3226 
  3227     /*
  3228      * Get "objPtr"s string representation. Make it up-to-date if necessary.
  3229      */
  3230 
  3231     name = objPtr->bytes;
  3232     if (name == NULL) {
  3233 	name = Tcl_GetString(objPtr);
  3234     }
  3235 
  3236     /*
  3237      * Find the Command structure, if any, that describes the command called
  3238      * "name". Build a ResolvedCmdName that holds a cached pointer to this
  3239      * Command, and bump the reference count in the referenced Command
  3240      * structure. A Command structure will not be deleted as long as it is
  3241      * referenced from a CmdName object.
  3242      */
  3243 
  3244     cmd = Tcl_FindCommand(interp, name, (Tcl_Namespace *) NULL,
  3245 	    /*flags*/ 0);
  3246     cmdPtr = (Command *) cmd;
  3247     if (cmdPtr != NULL) {
  3248 	/*
  3249 	 * Get the current namespace.
  3250 	 */
  3251 	
  3252 	if (iPtr->varFramePtr != NULL) {
  3253 	    currNsPtr = iPtr->varFramePtr->nsPtr;
  3254 	} else {
  3255 	    currNsPtr = iPtr->globalNsPtr;
  3256 	}
  3257 	
  3258 	cmdPtr->refCount++;
  3259         resPtr = (ResolvedCmdName *) ckalloc(sizeof(ResolvedCmdName));
  3260         resPtr->cmdPtr        = cmdPtr;
  3261         resPtr->refNsPtr      = currNsPtr;
  3262         resPtr->refNsId       = currNsPtr->nsId;
  3263         resPtr->refNsCmdEpoch = currNsPtr->cmdRefEpoch;
  3264         resPtr->cmdEpoch      = cmdPtr->cmdEpoch;
  3265         resPtr->refCount      = 1;
  3266     } else {
  3267 	resPtr = NULL;	/* no command named "name" was found */
  3268     }
  3269 
  3270     /*
  3271      * Free the old internalRep before setting the new one. We do this as
  3272      * late as possible to allow the conversion code, in particular
  3273      * GetStringFromObj, to use that old internalRep. If no Command
  3274      * structure was found, leave NULL as the cached value.
  3275      */
  3276 
  3277     if ((objPtr->typePtr != NULL)
  3278 	    && (objPtr->typePtr->freeIntRepProc != NULL)) {
  3279 	objPtr->typePtr->freeIntRepProc(objPtr);
  3280     }
  3281     
  3282     objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) resPtr;
  3283     objPtr->internalRep.twoPtrValue.ptr2 = NULL;
  3284     objPtr->typePtr = &tclCmdNameType;
  3285     return TCL_OK;
  3286 }