tclObj.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:93k
源码类别:

通讯编程

开发平台:

Visual C++

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