/[dtapublic]/projs/trunk/shared_source/c_tcl_base_7_5_w_mods/tclobj.c
ViewVC logotype

Diff of /projs/trunk/shared_source/c_tcl_base_7_5_w_mods/tclobj.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 66 by dashley, Sun Oct 30 21:57:38 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2  /*  /*
3   * tclObj.c --   * tclObj.c --
4   *   *
5   *      This file contains Tcl object-related procedures that are used by   *      This file contains Tcl object-related procedures that are used by
6   *      many Tcl commands.   *      many Tcl commands.
7   *   *
8   * Copyright (c) 1995-1997 Sun Microsystems, Inc.   * Copyright (c) 1995-1997 Sun Microsystems, Inc.
9   * Copyright (c) 1999 by Scriptics Corporation.   * Copyright (c) 1999 by Scriptics Corporation.
10   *   *
11   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
12   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13   *   *
14   * RCS: @(#) $Id: tclobj.c,v 1.3 2001/09/12 18:12:20 dtashley Exp $   * RCS: @(#) $Id: tclobj.c,v 1.3 2001/09/12 18:12:20 dtashley Exp $
15   */   */
16    
17  #include "tclInt.h"  #include "tclInt.h"
18  #include "tclPort.h"  #include "tclPort.h"
19    
20  /*  /*
21   * Table of all object types.   * Table of all object types.
22   */   */
23    
24  static Tcl_HashTable typeTable;  static Tcl_HashTable typeTable;
25  static int typeTableInitialized = 0;    /* 0 means not yet initialized. */  static int typeTableInitialized = 0;    /* 0 means not yet initialized. */
26  TCL_DECLARE_MUTEX(tableMutex)  TCL_DECLARE_MUTEX(tableMutex)
27    
28  /*  /*
29   * Head of the list of free Tcl_Obj structs we maintain.   * Head of the list of free Tcl_Obj structs we maintain.
30   */   */
31    
32  Tcl_Obj *tclFreeObjList = NULL;  Tcl_Obj *tclFreeObjList = NULL;
33    
34  /*  /*
35   * The object allocator is single threaded.  This mutex is referenced   * The object allocator is single threaded.  This mutex is referenced
36   * by the TclNewObj macro, however, so must be visible.   * by the TclNewObj macro, however, so must be visible.
37   */   */
38    
39  #ifdef TCL_THREADS  #ifdef TCL_THREADS
40  Tcl_Mutex tclObjMutex;  Tcl_Mutex tclObjMutex;
41  #endif  #endif
42    
43  /*  /*
44   * Pointer to a heap-allocated string of length zero that the Tcl core uses   * Pointer to a heap-allocated string of length zero that the Tcl core uses
45   * as the value of an empty string representation for an object. This value   * as the value of an empty string representation for an object. This value
46   * is shared by all new objects allocated by Tcl_NewObj.   * is shared by all new objects allocated by Tcl_NewObj.
47   */   */
48    
49  static char emptyString;  static char emptyString;
50  char *tclEmptyStringRep = &emptyString;  char *tclEmptyStringRep = &emptyString;
51    
52  /*  /*
53   * The number of Tcl objects ever allocated (by Tcl_NewObj) and freed   * The number of Tcl objects ever allocated (by Tcl_NewObj) and freed
54   * (by TclFreeObj).   * (by TclFreeObj).
55   */   */
56    
57  #ifdef TCL_COMPILE_STATS  #ifdef TCL_COMPILE_STATS
58  long tclObjsAlloced = 0;  long tclObjsAlloced = 0;
59  long tclObjsFreed = 0;  long tclObjsFreed = 0;
60  #endif /* TCL_COMPILE_STATS */  #endif /* TCL_COMPILE_STATS */
61    
62  /*  /*
63   * Prototypes for procedures defined later in this file:   * Prototypes for procedures defined later in this file:
64   */   */
65    
66  static int              SetBooleanFromAny _ANSI_ARGS_((Tcl_Interp *interp,  static int              SetBooleanFromAny _ANSI_ARGS_((Tcl_Interp *interp,
67                              Tcl_Obj *objPtr));                              Tcl_Obj *objPtr));
68  static int              SetDoubleFromAny _ANSI_ARGS_((Tcl_Interp *interp,  static int              SetDoubleFromAny _ANSI_ARGS_((Tcl_Interp *interp,
69                              Tcl_Obj *objPtr));                              Tcl_Obj *objPtr));
70  static int              SetIntFromAny _ANSI_ARGS_((Tcl_Interp *interp,  static int              SetIntFromAny _ANSI_ARGS_((Tcl_Interp *interp,
71                              Tcl_Obj *objPtr));                              Tcl_Obj *objPtr));
72  static void             UpdateStringOfBoolean _ANSI_ARGS_((Tcl_Obj *objPtr));  static void             UpdateStringOfBoolean _ANSI_ARGS_((Tcl_Obj *objPtr));
73  static void             UpdateStringOfDouble _ANSI_ARGS_((Tcl_Obj *objPtr));  static void             UpdateStringOfDouble _ANSI_ARGS_((Tcl_Obj *objPtr));
74  static void             UpdateStringOfInt _ANSI_ARGS_((Tcl_Obj *objPtr));  static void             UpdateStringOfInt _ANSI_ARGS_((Tcl_Obj *objPtr));
75    
76  /*  /*
77   * The structures below defines the Tcl object types defined in this file by   * The structures below defines the Tcl object types defined in this file by
78   * means of procedures that can be invoked by generic object code. See also   * means of procedures that can be invoked by generic object code. See also
79   * tclStringObj.c, tclListObj.c, tclByteCode.c for other type manager   * tclStringObj.c, tclListObj.c, tclByteCode.c for other type manager
80   * implementations.   * implementations.
81   */   */
82    
83  Tcl_ObjType tclBooleanType = {  Tcl_ObjType tclBooleanType = {
84      "boolean",                          /* name */      "boolean",                          /* name */
85      (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */      (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
86      (Tcl_DupInternalRepProc *) NULL,    /* dupIntRepProc */      (Tcl_DupInternalRepProc *) NULL,    /* dupIntRepProc */
87      UpdateStringOfBoolean,              /* updateStringProc */      UpdateStringOfBoolean,              /* updateStringProc */
88      SetBooleanFromAny                   /* setFromAnyProc */      SetBooleanFromAny                   /* setFromAnyProc */
89  };  };
90    
91  Tcl_ObjType tclDoubleType = {  Tcl_ObjType tclDoubleType = {
92      "double",                           /* name */      "double",                           /* name */
93      (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */      (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
94      (Tcl_DupInternalRepProc *) NULL,    /* dupIntRepProc */      (Tcl_DupInternalRepProc *) NULL,    /* dupIntRepProc */
95      UpdateStringOfDouble,               /* updateStringProc */      UpdateStringOfDouble,               /* updateStringProc */
96      SetDoubleFromAny                    /* setFromAnyProc */      SetDoubleFromAny                    /* setFromAnyProc */
97  };  };
98    
99  Tcl_ObjType tclIntType = {  Tcl_ObjType tclIntType = {
100      "int",                              /* name */      "int",                              /* name */
101      (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */      (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
102      (Tcl_DupInternalRepProc *) NULL,    /* dupIntRepProc */      (Tcl_DupInternalRepProc *) NULL,    /* dupIntRepProc */
103      UpdateStringOfInt,                  /* updateStringProc */      UpdateStringOfInt,                  /* updateStringProc */
104      SetIntFromAny                       /* setFromAnyProc */      SetIntFromAny                       /* setFromAnyProc */
105  };  };
106    
107  /*  /*
108   *-------------------------------------------------------------------------   *-------------------------------------------------------------------------
109   *   *
110   * TclInitObjectSubsystem --   * TclInitObjectSubsystem --
111   *   *
112   *      This procedure is invoked to perform once-only initialization of   *      This procedure is invoked to perform once-only initialization of
113   *      the type table. It also registers the object types defined in   *      the type table. It also registers the object types defined in
114   *      this file.   *      this file.
115   *   *
116   * Results:   * Results:
117   *      None.   *      None.
118   *   *
119   * Side effects:   * Side effects:
120   *      Initializes the table of defined object types "typeTable" with   *      Initializes the table of defined object types "typeTable" with
121   *      builtin object types defined in this file.     *      builtin object types defined in this file.  
122   *   *
123   *-------------------------------------------------------------------------   *-------------------------------------------------------------------------
124   */   */
125    
126  void  void
127  TclInitObjSubsystem()  TclInitObjSubsystem()
128  {  {
129      Tcl_MutexLock(&tableMutex);      Tcl_MutexLock(&tableMutex);
130      typeTableInitialized = 1;      typeTableInitialized = 1;
131      Tcl_InitHashTable(&typeTable, TCL_STRING_KEYS);      Tcl_InitHashTable(&typeTable, TCL_STRING_KEYS);
132      Tcl_MutexUnlock(&tableMutex);      Tcl_MutexUnlock(&tableMutex);
133    
134      Tcl_RegisterObjType(&tclBooleanType);      Tcl_RegisterObjType(&tclBooleanType);
135      Tcl_RegisterObjType(&tclByteArrayType);      Tcl_RegisterObjType(&tclByteArrayType);
136      Tcl_RegisterObjType(&tclDoubleType);      Tcl_RegisterObjType(&tclDoubleType);
137      Tcl_RegisterObjType(&tclIntType);      Tcl_RegisterObjType(&tclIntType);
138      Tcl_RegisterObjType(&tclStringType);      Tcl_RegisterObjType(&tclStringType);
139      Tcl_RegisterObjType(&tclListType);      Tcl_RegisterObjType(&tclListType);
140      Tcl_RegisterObjType(&tclByteCodeType);      Tcl_RegisterObjType(&tclByteCodeType);
141      Tcl_RegisterObjType(&tclProcBodyType);      Tcl_RegisterObjType(&tclProcBodyType);
142    
143  #ifdef TCL_COMPILE_STATS  #ifdef TCL_COMPILE_STATS
144      Tcl_MutexLock(&tclObjMutex);      Tcl_MutexLock(&tclObjMutex);
145      tclObjsAlloced = 0;      tclObjsAlloced = 0;
146      tclObjsFreed = 0;      tclObjsFreed = 0;
147      Tcl_MutexUnlock(&tclObjMutex);      Tcl_MutexUnlock(&tclObjMutex);
148  #endif  #endif
149  }  }
150    
151  /*  /*
152   *----------------------------------------------------------------------   *----------------------------------------------------------------------
153   *   *
154   * TclFinalizeCompExecEnv --   * TclFinalizeCompExecEnv --
155   *   *
156   *      This procedure is called by Tcl_Finalize to clean up the Tcl   *      This procedure is called by Tcl_Finalize to clean up the Tcl
157   *      compilation and execution environment so it can later be properly   *      compilation and execution environment so it can later be properly
158   *      reinitialized.   *      reinitialized.
159   *   *
160   * Results:   * Results:
161   *      None.   *      None.
162   *   *
163   * Side effects:   * Side effects:
164   *      Cleans up the compilation and execution environment   *      Cleans up the compilation and execution environment
165   *   *
166   *----------------------------------------------------------------------   *----------------------------------------------------------------------
167   */   */
168    
169  void  void
170  TclFinalizeCompExecEnv()  TclFinalizeCompExecEnv()
171  {  {
172      Tcl_MutexLock(&tableMutex);      Tcl_MutexLock(&tableMutex);
173      if (typeTableInitialized) {      if (typeTableInitialized) {
174          Tcl_DeleteHashTable(&typeTable);          Tcl_DeleteHashTable(&typeTable);
175          typeTableInitialized = 0;          typeTableInitialized = 0;
176      }      }
177      Tcl_MutexUnlock(&tableMutex);      Tcl_MutexUnlock(&tableMutex);
178      Tcl_MutexLock(&tclObjMutex);      Tcl_MutexLock(&tclObjMutex);
179      tclFreeObjList = NULL;      tclFreeObjList = NULL;
180      Tcl_MutexUnlock(&tclObjMutex);      Tcl_MutexUnlock(&tclObjMutex);
181    
182      TclFinalizeCompilation();      TclFinalizeCompilation();
183      TclFinalizeExecution();      TclFinalizeExecution();
184  }  }
185    
186  /*  /*
187   *--------------------------------------------------------------   *--------------------------------------------------------------
188   *   *
189   * Tcl_RegisterObjType --   * Tcl_RegisterObjType --
190   *   *
191   *      This procedure is called to register a new Tcl object type   *      This procedure is called to register a new Tcl object type
192   *      in the table of all object types supported by Tcl.   *      in the table of all object types supported by Tcl.
193   *   *
194   * Results:   * Results:
195   *      None.   *      None.
196   *   *
197   * Side effects:   * Side effects:
198   *      The type is registered in the Tcl type table. If there was already   *      The type is registered in the Tcl type table. If there was already
199   *      a type with the same name as in typePtr, it is replaced with the   *      a type with the same name as in typePtr, it is replaced with the
200   *      new type.   *      new type.
201   *   *
202   *--------------------------------------------------------------   *--------------------------------------------------------------
203   */   */
204    
205  void  void
206  Tcl_RegisterObjType(typePtr)  Tcl_RegisterObjType(typePtr)
207      Tcl_ObjType *typePtr;       /* Information about object type;      Tcl_ObjType *typePtr;       /* Information about object type;
208                                   * storage must be statically                                   * storage must be statically
209                                   * allocated (must live forever). */                                   * allocated (must live forever). */
210  {  {
211      register Tcl_HashEntry *hPtr;      register Tcl_HashEntry *hPtr;
212      int new;      int new;
213    
214      /*      /*
215       * If there's already an object type with the given name, remove it.       * If there's already an object type with the given name, remove it.
216       */       */
217      Tcl_MutexLock(&tableMutex);      Tcl_MutexLock(&tableMutex);
218      hPtr = Tcl_FindHashEntry(&typeTable, typePtr->name);      hPtr = Tcl_FindHashEntry(&typeTable, typePtr->name);
219      if (hPtr != (Tcl_HashEntry *) NULL) {      if (hPtr != (Tcl_HashEntry *) NULL) {
220          Tcl_DeleteHashEntry(hPtr);          Tcl_DeleteHashEntry(hPtr);
221      }      }
222    
223      /*      /*
224       * Now insert the new object type.       * Now insert the new object type.
225       */       */
226    
227      hPtr = Tcl_CreateHashEntry(&typeTable, typePtr->name, &new);      hPtr = Tcl_CreateHashEntry(&typeTable, typePtr->name, &new);
228      if (new) {      if (new) {
229          Tcl_SetHashValue(hPtr, typePtr);          Tcl_SetHashValue(hPtr, typePtr);
230      }      }
231      Tcl_MutexUnlock(&tableMutex);      Tcl_MutexUnlock(&tableMutex);
232  }  }
233    
234  /*  /*
235   *----------------------------------------------------------------------   *----------------------------------------------------------------------
236   *   *
237   * Tcl_AppendAllObjTypes --   * Tcl_AppendAllObjTypes --
238   *   *
239   *      This procedure appends onto the argument object the name of each   *      This procedure appends onto the argument object the name of each
240   *      object type as a list element. This includes the builtin object   *      object type as a list element. This includes the builtin object
241   *      types (e.g. int, list) as well as those added using   *      types (e.g. int, list) as well as those added using
242   *      Tcl_NewObj. These names can be used, for example, with   *      Tcl_NewObj. These names can be used, for example, with
243   *      Tcl_GetObjType to get pointers to the corresponding Tcl_ObjType   *      Tcl_GetObjType to get pointers to the corresponding Tcl_ObjType
244   *      structures.   *      structures.
245   *   *
246   * Results:   * Results:
247   *      The return value is normally TCL_OK; in this case the object   *      The return value is normally TCL_OK; in this case the object
248   *      referenced by objPtr has each type name appended to it. If an   *      referenced by objPtr has each type name appended to it. If an
249   *      error occurs, TCL_ERROR is returned and the interpreter's result   *      error occurs, TCL_ERROR is returned and the interpreter's result
250   *      holds an error message.   *      holds an error message.
251   *   *
252   * Side effects:   * Side effects:
253   *      If necessary, the object referenced by objPtr is converted into   *      If necessary, the object referenced by objPtr is converted into
254   *      a list object.   *      a list object.
255   *   *
256   *----------------------------------------------------------------------   *----------------------------------------------------------------------
257   */   */
258    
259  int  int
260  Tcl_AppendAllObjTypes(interp, objPtr)  Tcl_AppendAllObjTypes(interp, objPtr)
261      Tcl_Interp *interp;         /* Interpreter used for error reporting. */      Tcl_Interp *interp;         /* Interpreter used for error reporting. */
262      Tcl_Obj *objPtr;            /* Points to the Tcl object onto which the      Tcl_Obj *objPtr;            /* Points to the Tcl object onto which the
263                                   * name of each registered type is appended                                   * name of each registered type is appended
264                                   * as a list element. */                                   * as a list element. */
265  {  {
266      register Tcl_HashEntry *hPtr;      register Tcl_HashEntry *hPtr;
267      Tcl_HashSearch search;      Tcl_HashSearch search;
268      Tcl_ObjType *typePtr;      Tcl_ObjType *typePtr;
269      int result;      int result;
270    
271      /*      /*
272       * This code assumes that types names do not contain embedded NULLs.       * This code assumes that types names do not contain embedded NULLs.
273       */       */
274    
275      Tcl_MutexLock(&tableMutex);      Tcl_MutexLock(&tableMutex);
276      for (hPtr = Tcl_FirstHashEntry(&typeTable, &search);      for (hPtr = Tcl_FirstHashEntry(&typeTable, &search);
277              hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {              hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
278          typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);          typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);
279          result = Tcl_ListObjAppendElement(interp, objPtr,          result = Tcl_ListObjAppendElement(interp, objPtr,
280                  Tcl_NewStringObj(typePtr->name, -1));                  Tcl_NewStringObj(typePtr->name, -1));
281          if (result == TCL_ERROR) {          if (result == TCL_ERROR) {
282              Tcl_MutexUnlock(&tableMutex);              Tcl_MutexUnlock(&tableMutex);
283              return result;              return result;
284          }          }
285      }      }
286      Tcl_MutexUnlock(&tableMutex);      Tcl_MutexUnlock(&tableMutex);
287      return TCL_OK;      return TCL_OK;
288  }  }
289    
290  /*  /*
291   *----------------------------------------------------------------------   *----------------------------------------------------------------------
292   *   *
293   * Tcl_GetObjType --   * Tcl_GetObjType --
294   *   *
295   *      This procedure looks up an object type by name.   *      This procedure looks up an object type by name.
296   *   *
297   * Results:   * Results:
298   *      If an object type with name matching "typeName" is found, a pointer   *      If an object type with name matching "typeName" is found, a pointer
299   *      to its Tcl_ObjType structure is returned; otherwise, NULL is   *      to its Tcl_ObjType structure is returned; otherwise, NULL is
300   *      returned.   *      returned.
301   *   *
302   * Side effects:   * Side effects:
303   *      None.   *      None.
304   *   *
305   *----------------------------------------------------------------------   *----------------------------------------------------------------------
306   */   */
307    
308  Tcl_ObjType *  Tcl_ObjType *
309  Tcl_GetObjType(typeName)  Tcl_GetObjType(typeName)
310      char *typeName;             /* Name of Tcl object type to look up. */      char *typeName;             /* Name of Tcl object type to look up. */
311  {  {
312      register Tcl_HashEntry *hPtr;      register Tcl_HashEntry *hPtr;
313      Tcl_ObjType *typePtr;      Tcl_ObjType *typePtr;
314    
315      Tcl_MutexLock(&tableMutex);      Tcl_MutexLock(&tableMutex);
316      hPtr = Tcl_FindHashEntry(&typeTable, typeName);      hPtr = Tcl_FindHashEntry(&typeTable, typeName);
317      if (hPtr != (Tcl_HashEntry *) NULL) {      if (hPtr != (Tcl_HashEntry *) NULL) {
318          typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);          typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);
319          Tcl_MutexUnlock(&tableMutex);          Tcl_MutexUnlock(&tableMutex);
320          return typePtr;          return typePtr;
321      }      }
322      Tcl_MutexUnlock(&tableMutex);      Tcl_MutexUnlock(&tableMutex);
323      return NULL;      return NULL;
324  }  }
325    
326  /*  /*
327   *----------------------------------------------------------------------   *----------------------------------------------------------------------
328   *   *
329   * Tcl_ConvertToType --   * Tcl_ConvertToType --
330   *   *
331   *      Convert the Tcl object "objPtr" to have type "typePtr" if possible.   *      Convert the Tcl object "objPtr" to have type "typePtr" if possible.
332   *   *
333   * Results:   * Results:
334   *      The return value is TCL_OK on success and TCL_ERROR on failure. If   *      The return value is TCL_OK on success and TCL_ERROR on failure. If
335   *      TCL_ERROR is returned, then the interpreter's result contains an   *      TCL_ERROR is returned, then the interpreter's result contains an
336   *      error message unless "interp" is NULL. Passing a NULL "interp"   *      error message unless "interp" is NULL. Passing a NULL "interp"
337   *      allows this procedure to be used as a test whether the conversion   *      allows this procedure to be used as a test whether the conversion
338   *      could be done (and in fact was done).   *      could be done (and in fact was done).
339   *   *
340   * Side effects:   * Side effects:
341   *      Any internal representation for the old type is freed.   *      Any internal representation for the old type is freed.
342   *   *
343   *----------------------------------------------------------------------   *----------------------------------------------------------------------
344   */   */
345    
346  int  int
347  Tcl_ConvertToType(interp, objPtr, typePtr)  Tcl_ConvertToType(interp, objPtr, typePtr)
348      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
349      Tcl_Obj *objPtr;            /* The object to convert. */      Tcl_Obj *objPtr;            /* The object to convert. */
350      Tcl_ObjType *typePtr;       /* The target type. */      Tcl_ObjType *typePtr;       /* The target type. */
351  {  {
352      if (objPtr->typePtr == typePtr) {      if (objPtr->typePtr == typePtr) {
353          return TCL_OK;          return TCL_OK;
354      }      }
355    
356      /*      /*
357       * Use the target type's Tcl_SetFromAnyProc to set "objPtr"s internal       * Use the target type's Tcl_SetFromAnyProc to set "objPtr"s internal
358       * form as appropriate for the target type. This frees the old internal       * form as appropriate for the target type. This frees the old internal
359       * representation.       * representation.
360       */       */
361    
362      return typePtr->setFromAnyProc(interp, objPtr);      return typePtr->setFromAnyProc(interp, objPtr);
363  }  }
364    
365  /*  /*
366   *----------------------------------------------------------------------   *----------------------------------------------------------------------
367   *   *
368   * Tcl_NewObj --   * Tcl_NewObj --
369   *   *
370   *      This procedure is normally called when not debugging: i.e., when   *      This procedure is normally called when not debugging: i.e., when
371   *      TCL_MEM_DEBUG is not defined. It creates new Tcl objects that denote   *      TCL_MEM_DEBUG is not defined. It creates new Tcl objects that denote
372   *      the empty string. These objects have a NULL object type and NULL   *      the empty string. These objects have a NULL object type and NULL
373   *      string representation byte pointer. Type managers call this routine   *      string representation byte pointer. Type managers call this routine
374   *      to allocate new objects that they further initialize.   *      to allocate new objects that they further initialize.
375   *   *
376   *      When TCL_MEM_DEBUG is defined, this procedure just returns the   *      When TCL_MEM_DEBUG is defined, this procedure just returns the
377   *      result of calling the debugging version Tcl_DbNewObj.   *      result of calling the debugging version Tcl_DbNewObj.
378   *   *
379   * Results:   * Results:
380   *      The result is a newly allocated object that represents the empty   *      The result is a newly allocated object that represents the empty
381   *      string. The new object's typePtr is set NULL and its ref count   *      string. The new object's typePtr is set NULL and its ref count
382   *      is set to 0.   *      is set to 0.
383   *   *
384   * Side effects:   * Side effects:
385   *      If compiling with TCL_COMPILE_STATS, this procedure increments   *      If compiling with TCL_COMPILE_STATS, this procedure increments
386   *      the global count of allocated objects (tclObjsAlloced).   *      the global count of allocated objects (tclObjsAlloced).
387   *   *
388   *----------------------------------------------------------------------   *----------------------------------------------------------------------
389   */   */
390    
391  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
392  #undef Tcl_NewObj  #undef Tcl_NewObj
393    
394  Tcl_Obj *  Tcl_Obj *
395  Tcl_NewObj()  Tcl_NewObj()
396  {  {
397      return Tcl_DbNewObj("unknown", 0);      return Tcl_DbNewObj("unknown", 0);
398  }  }
399    
400  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
401    
402  Tcl_Obj *  Tcl_Obj *
403  Tcl_NewObj()  Tcl_NewObj()
404  {  {
405      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
406    
407      /*      /*
408       * Allocate the object using the list of free Tcl_Obj structs       * Allocate the object using the list of free Tcl_Obj structs
409       * we maintain.       * we maintain.
410       */       */
411    
412      Tcl_MutexLock(&tclObjMutex);      Tcl_MutexLock(&tclObjMutex);
413      if (tclFreeObjList == NULL) {      if (tclFreeObjList == NULL) {
414          TclAllocateFreeObjects();          TclAllocateFreeObjects();
415      }      }
416      objPtr = tclFreeObjList;      objPtr = tclFreeObjList;
417      tclFreeObjList = (Tcl_Obj *) tclFreeObjList->internalRep.otherValuePtr;      tclFreeObjList = (Tcl_Obj *) tclFreeObjList->internalRep.otherValuePtr;
418            
419      objPtr->refCount = 0;      objPtr->refCount = 0;
420      objPtr->bytes    = tclEmptyStringRep;      objPtr->bytes    = tclEmptyStringRep;
421      objPtr->length   = 0;      objPtr->length   = 0;
422      objPtr->typePtr  = NULL;      objPtr->typePtr  = NULL;
423  #ifdef TCL_COMPILE_STATS  #ifdef TCL_COMPILE_STATS
424      tclObjsAlloced++;      tclObjsAlloced++;
425  #endif /* TCL_COMPILE_STATS */  #endif /* TCL_COMPILE_STATS */
426      Tcl_MutexUnlock(&tclObjMutex);      Tcl_MutexUnlock(&tclObjMutex);
427      return objPtr;      return objPtr;
428  }  }
429  #endif /* TCL_MEM_DEBUG */  #endif /* TCL_MEM_DEBUG */
430    
431  /*  /*
432   *----------------------------------------------------------------------   *----------------------------------------------------------------------
433   *   *
434   * Tcl_DbNewObj --   * Tcl_DbNewObj --
435   *   *
436   *      This procedure is normally called when debugging: i.e., when   *      This procedure is normally called when debugging: i.e., when
437   *      TCL_MEM_DEBUG is defined. It creates new Tcl objects that denote the   *      TCL_MEM_DEBUG is defined. It creates new Tcl objects that denote the
438   *      empty string. It is the same as the Tcl_NewObj procedure above   *      empty string. It is the same as the Tcl_NewObj procedure above
439   *      except that it calls Tcl_DbCkalloc directly with the file name and   *      except that it calls Tcl_DbCkalloc directly with the file name and
440   *      line number from its caller. This simplifies debugging since then   *      line number from its caller. This simplifies debugging since then
441   *      the checkmem command will report the correct file name and line   *      the checkmem command will report the correct file name and line
442   *      number when reporting objects that haven't been freed.   *      number when reporting objects that haven't been freed.
443   *   *
444   *      When TCL_MEM_DEBUG is not defined, this procedure just returns the   *      When TCL_MEM_DEBUG is not defined, this procedure just returns the
445   *      result of calling Tcl_NewObj.   *      result of calling Tcl_NewObj.
446   *   *
447   * Results:   * Results:
448   *      The result is a newly allocated that represents the empty string.   *      The result is a newly allocated that represents the empty string.
449   *      The new object's typePtr is set NULL and its ref count is set to 0.   *      The new object's typePtr is set NULL and its ref count is set to 0.
450   *   *
451   * Side effects:   * Side effects:
452   *      If compiling with TCL_COMPILE_STATS, this procedure increments   *      If compiling with TCL_COMPILE_STATS, this procedure increments
453   *      the global count of allocated objects (tclObjsAlloced).   *      the global count of allocated objects (tclObjsAlloced).
454   *   *
455   *----------------------------------------------------------------------   *----------------------------------------------------------------------
456   */   */
457    
458  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
459    
460  Tcl_Obj *  Tcl_Obj *
461  Tcl_DbNewObj(file, line)  Tcl_DbNewObj(file, line)
462      register char *file;        /* The name of the source file calling this      register char *file;        /* The name of the source file calling this
463                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
464      register int line;          /* Line number in the source file; used      register int line;          /* Line number in the source file; used
465                                   * for debugging. */                                   * for debugging. */
466  {  {
467      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
468    
469      /*      /*
470       * If debugging Tcl's memory usage, allocate the object using ckalloc.       * If debugging Tcl's memory usage, allocate the object using ckalloc.
471       * Otherwise, allocate it using the list of free Tcl_Obj structs we       * Otherwise, allocate it using the list of free Tcl_Obj structs we
472       * maintain.       * maintain.
473       */       */
474    
475      objPtr = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), file, line);      objPtr = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), file, line);
476      objPtr->refCount = 0;      objPtr->refCount = 0;
477      objPtr->bytes    = tclEmptyStringRep;      objPtr->bytes    = tclEmptyStringRep;
478      objPtr->length   = 0;      objPtr->length   = 0;
479      objPtr->typePtr  = NULL;      objPtr->typePtr  = NULL;
480  #ifdef TCL_COMPILE_STATS  #ifdef TCL_COMPILE_STATS
481      Tcl_MutexLock(&tclObjMutex);      Tcl_MutexLock(&tclObjMutex);
482      tclObjsAlloced++;      tclObjsAlloced++;
483      Tcl_MutexUnlock(&tclObjMutex);      Tcl_MutexUnlock(&tclObjMutex);
484  #endif /* TCL_COMPILE_STATS */  #endif /* TCL_COMPILE_STATS */
485      return objPtr;      return objPtr;
486  }  }
487    
488  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
489    
490  Tcl_Obj *  Tcl_Obj *
491  Tcl_DbNewObj(file, line)  Tcl_DbNewObj(file, line)
492      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
493                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
494      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
495                                   * for debugging. */                                   * for debugging. */
496  {  {
497      return Tcl_NewObj();      return Tcl_NewObj();
498  }  }
499  #endif /* TCL_MEM_DEBUG */  #endif /* TCL_MEM_DEBUG */
500    
501  /*  /*
502   *----------------------------------------------------------------------   *----------------------------------------------------------------------
503   *   *
504   * TclAllocateFreeObjects --   * TclAllocateFreeObjects --
505   *   *
506   *      Procedure to allocate a number of free Tcl_Objs. This is done using   *      Procedure to allocate a number of free Tcl_Objs. This is done using
507   *      a single ckalloc to reduce the overhead for Tcl_Obj allocation.   *      a single ckalloc to reduce the overhead for Tcl_Obj allocation.
508   *   *
509   *      Assumes mutex is held.   *      Assumes mutex is held.
510   *   *
511   * Results:   * Results:
512   *      None.   *      None.
513   *   *
514   * Side effects:   * Side effects:
515   *      tclFreeObjList, the head of the list of free Tcl_Objs, is set to the   *      tclFreeObjList, the head of the list of free Tcl_Objs, is set to the
516   *      first of a number of free Tcl_Obj's linked together by their   *      first of a number of free Tcl_Obj's linked together by their
517   *      internalRep.otherValuePtrs.   *      internalRep.otherValuePtrs.
518   *   *
519   *----------------------------------------------------------------------   *----------------------------------------------------------------------
520   */   */
521    
522  #define OBJS_TO_ALLOC_EACH_TIME 100  #define OBJS_TO_ALLOC_EACH_TIME 100
523    
524  void  void
525  TclAllocateFreeObjects()  TclAllocateFreeObjects()
526  {  {
527      Tcl_Obj tmp[2];      Tcl_Obj tmp[2];
528      size_t objSizePlusPadding = /* NB: this assumes byte addressing. */      size_t objSizePlusPadding = /* NB: this assumes byte addressing. */
529          ((int)(&(tmp[1])) - (int)(&(tmp[0])));          ((int)(&(tmp[1])) - (int)(&(tmp[0])));
530      size_t bytesToAlloc = (OBJS_TO_ALLOC_EACH_TIME * objSizePlusPadding);      size_t bytesToAlloc = (OBJS_TO_ALLOC_EACH_TIME * objSizePlusPadding);
531      char *basePtr;      char *basePtr;
532      register Tcl_Obj *prevPtr, *objPtr;      register Tcl_Obj *prevPtr, *objPtr;
533      register int i;      register int i;
534    
535      basePtr = (char *) ckalloc(bytesToAlloc);      basePtr = (char *) ckalloc(bytesToAlloc);
536      memset(basePtr, 0, bytesToAlloc);      memset(basePtr, 0, bytesToAlloc);
537    
538      prevPtr = NULL;      prevPtr = NULL;
539      objPtr = (Tcl_Obj *) basePtr;      objPtr = (Tcl_Obj *) basePtr;
540      for (i = 0;  i < OBJS_TO_ALLOC_EACH_TIME;  i++) {      for (i = 0;  i < OBJS_TO_ALLOC_EACH_TIME;  i++) {
541          objPtr->internalRep.otherValuePtr = (VOID *) prevPtr;          objPtr->internalRep.otherValuePtr = (VOID *) prevPtr;
542          prevPtr = objPtr;          prevPtr = objPtr;
543          objPtr = (Tcl_Obj *) (((char *)objPtr) + objSizePlusPadding);          objPtr = (Tcl_Obj *) (((char *)objPtr) + objSizePlusPadding);
544      }      }
545      tclFreeObjList = prevPtr;      tclFreeObjList = prevPtr;
546  }  }
547  #undef OBJS_TO_ALLOC_EACH_TIME  #undef OBJS_TO_ALLOC_EACH_TIME
548    
549  /*  /*
550   *----------------------------------------------------------------------   *----------------------------------------------------------------------
551   *   *
552   * TclFreeObj --   * TclFreeObj --
553   *   *
554   *      This procedure frees the memory associated with the argument   *      This procedure frees the memory associated with the argument
555   *      object. It is called by the tcl.h macro Tcl_DecrRefCount when an   *      object. It is called by the tcl.h macro Tcl_DecrRefCount when an
556   *      object's ref count is zero. It is only "public" since it must   *      object's ref count is zero. It is only "public" since it must
557   *      be callable by that macro wherever the macro is used. It should not   *      be callable by that macro wherever the macro is used. It should not
558   *      be directly called by clients.   *      be directly called by clients.
559   *   *
560   * Results:   * Results:
561   *      None.   *      None.
562   *   *
563   * Side effects:   * Side effects:
564   *      Deallocates the storage for the object's Tcl_Obj structure   *      Deallocates the storage for the object's Tcl_Obj structure
565   *      after deallocating the string representation and calling the   *      after deallocating the string representation and calling the
566   *      type-specific Tcl_FreeInternalRepProc to deallocate the object's   *      type-specific Tcl_FreeInternalRepProc to deallocate the object's
567   *      internal representation. If compiling with TCL_COMPILE_STATS,   *      internal representation. If compiling with TCL_COMPILE_STATS,
568   *      this procedure increments the global count of freed objects   *      this procedure increments the global count of freed objects
569   *      (tclObjsFreed).   *      (tclObjsFreed).
570   *   *
571   *----------------------------------------------------------------------   *----------------------------------------------------------------------
572   */   */
573    
574  void  void
575  TclFreeObj(objPtr)  TclFreeObj(objPtr)
576      register Tcl_Obj *objPtr;   /* The object to be freed. */      register Tcl_Obj *objPtr;   /* The object to be freed. */
577  {  {
578      register Tcl_ObjType *typePtr = objPtr->typePtr;      register Tcl_ObjType *typePtr = objPtr->typePtr;
579            
580  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
581      if ((objPtr)->refCount < -1) {      if ((objPtr)->refCount < -1) {
582          panic("Reference count for %lx was negative", objPtr);          panic("Reference count for %lx was negative", objPtr);
583      }      }
584  #endif /* TCL_MEM_DEBUG */  #endif /* TCL_MEM_DEBUG */
585    
586      if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {      if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
587          typePtr->freeIntRepProc(objPtr);          typePtr->freeIntRepProc(objPtr);
588      }      }
589      Tcl_InvalidateStringRep(objPtr);      Tcl_InvalidateStringRep(objPtr);
590    
591      /*      /*
592       * If debugging Tcl's memory usage, deallocate the object using ckfree.       * If debugging Tcl's memory usage, deallocate the object using ckfree.
593       * Otherwise, deallocate it by adding it onto the list of free       * Otherwise, deallocate it by adding it onto the list of free
594       * Tcl_Obj structs we maintain.       * Tcl_Obj structs we maintain.
595       */       */
596    
597      Tcl_MutexLock(&tclObjMutex);      Tcl_MutexLock(&tclObjMutex);
598  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
599      ckfree((char *) objPtr);      ckfree((char *) objPtr);
600  #else  #else
601      objPtr->internalRep.otherValuePtr = (VOID *) tclFreeObjList;      objPtr->internalRep.otherValuePtr = (VOID *) tclFreeObjList;
602      tclFreeObjList = objPtr;      tclFreeObjList = objPtr;
603  #endif /* TCL_MEM_DEBUG */  #endif /* TCL_MEM_DEBUG */
604    
605  #ifdef TCL_COMPILE_STATS  #ifdef TCL_COMPILE_STATS
606      tclObjsFreed++;      tclObjsFreed++;
607  #endif /* TCL_COMPILE_STATS */  #endif /* TCL_COMPILE_STATS */
608      Tcl_MutexUnlock(&tclObjMutex);      Tcl_MutexUnlock(&tclObjMutex);
609  }  }
610    
611  /*  /*
612   *----------------------------------------------------------------------   *----------------------------------------------------------------------
613   *   *
614   * Tcl_DuplicateObj --   * Tcl_DuplicateObj --
615   *   *
616   *      Create and return a new object that is a duplicate of the argument   *      Create and return a new object that is a duplicate of the argument
617   *      object.   *      object.
618   *   *
619   * Results:   * Results:
620   *      The return value is a pointer to a newly created Tcl_Obj. This   *      The return value is a pointer to a newly created Tcl_Obj. This
621   *      object has reference count 0 and the same type, if any, as the   *      object has reference count 0 and the same type, if any, as the
622   *      source object objPtr. Also:   *      source object objPtr. Also:
623   *        1) If the source object has a valid string rep, we copy it;   *        1) If the source object has a valid string rep, we copy it;
624   *           otherwise, the duplicate's string rep is set NULL to mark   *           otherwise, the duplicate's string rep is set NULL to mark
625   *           it invalid.   *           it invalid.
626   *        2) If the source object has an internal representation (i.e. its   *        2) If the source object has an internal representation (i.e. its
627   *           typePtr is non-NULL), the new object's internal rep is set to   *           typePtr is non-NULL), the new object's internal rep is set to
628   *           a copy; otherwise the new internal rep is marked invalid.   *           a copy; otherwise the new internal rep is marked invalid.
629   *   *
630   * Side effects:   * Side effects:
631   *      What constitutes "copying" the internal representation depends on   *      What constitutes "copying" the internal representation depends on
632   *      the type. For example, if the argument object is a list,   *      the type. For example, if the argument object is a list,
633   *      the element objects it points to will not actually be copied but   *      the element objects it points to will not actually be copied but
634   *      will be shared with the duplicate list. That is, the ref counts of   *      will be shared with the duplicate list. That is, the ref counts of
635   *      the element objects will be incremented.   *      the element objects will be incremented.
636   *   *
637   *----------------------------------------------------------------------   *----------------------------------------------------------------------
638   */   */
639    
640  Tcl_Obj *  Tcl_Obj *
641  Tcl_DuplicateObj(objPtr)  Tcl_DuplicateObj(objPtr)
642      register Tcl_Obj *objPtr;           /* The object to duplicate. */      register Tcl_Obj *objPtr;           /* The object to duplicate. */
643  {  {
644      register Tcl_ObjType *typePtr = objPtr->typePtr;      register Tcl_ObjType *typePtr = objPtr->typePtr;
645      register Tcl_Obj *dupPtr;      register Tcl_Obj *dupPtr;
646    
647      TclNewObj(dupPtr);      TclNewObj(dupPtr);
648    
649      if (objPtr->bytes == NULL) {      if (objPtr->bytes == NULL) {
650          dupPtr->bytes = NULL;          dupPtr->bytes = NULL;
651      } else if (objPtr->bytes != tclEmptyStringRep) {      } else if (objPtr->bytes != tclEmptyStringRep) {
652          int len = objPtr->length;          int len = objPtr->length;
653                    
654          dupPtr->bytes = (char *) ckalloc((unsigned) len+1);          dupPtr->bytes = (char *) ckalloc((unsigned) len+1);
655          if (len > 0) {          if (len > 0) {
656              memcpy((VOID *) dupPtr->bytes, (VOID *) objPtr->bytes,              memcpy((VOID *) dupPtr->bytes, (VOID *) objPtr->bytes,
657                     (unsigned) len);                     (unsigned) len);
658          }          }
659          dupPtr->bytes[len] = '\0';          dupPtr->bytes[len] = '\0';
660          dupPtr->length = len;          dupPtr->length = len;
661      }      }
662            
663      if (typePtr != NULL) {      if (typePtr != NULL) {
664          if (typePtr->dupIntRepProc == NULL) {          if (typePtr->dupIntRepProc == NULL) {
665              dupPtr->internalRep = objPtr->internalRep;              dupPtr->internalRep = objPtr->internalRep;
666              dupPtr->typePtr = typePtr;              dupPtr->typePtr = typePtr;
667          } else {          } else {
668              (*typePtr->dupIntRepProc)(objPtr, dupPtr);              (*typePtr->dupIntRepProc)(objPtr, dupPtr);
669          }          }
670      }      }
671      return dupPtr;      return dupPtr;
672  }  }
673    
674  /*  /*
675   *----------------------------------------------------------------------   *----------------------------------------------------------------------
676   *   *
677   * Tcl_GetString --   * Tcl_GetString --
678   *   *
679   *      Returns the string representation byte array pointer for an object.   *      Returns the string representation byte array pointer for an object.
680   *   *
681   * Results:   * Results:
682   *      Returns a pointer to the string representation of objPtr. The byte   *      Returns a pointer to the string representation of objPtr. The byte
683   *      array referenced by the returned pointer must not be modified by the   *      array referenced by the returned pointer must not be modified by the
684   *      caller. Furthermore, the caller must copy the bytes if they need to   *      caller. Furthermore, the caller must copy the bytes if they need to
685   *      retain them since the object's string rep can change as a result of   *      retain them since the object's string rep can change as a result of
686   *      other operations.   *      other operations.
687   *   *
688   * Side effects:   * Side effects:
689   *      May call the object's updateStringProc to update the string   *      May call the object's updateStringProc to update the string
690   *      representation from the internal representation.   *      representation from the internal representation.
691   *   *
692   *----------------------------------------------------------------------   *----------------------------------------------------------------------
693   */   */
694    
695  char *  char *
696  Tcl_GetString(objPtr)  Tcl_GetString(objPtr)
697      register Tcl_Obj *objPtr;   /* Object whose string rep byte pointer      register Tcl_Obj *objPtr;   /* Object whose string rep byte pointer
698                                   * should be returned. */                                   * should be returned. */
699  {  {
700      if (objPtr->bytes != NULL) {      if (objPtr->bytes != NULL) {
701          return objPtr->bytes;          return objPtr->bytes;
702      }      }
703    
704      if (objPtr->typePtr->updateStringProc == NULL) {      if (objPtr->typePtr->updateStringProc == NULL) {
705          panic("UpdateStringProc should not be invoked for type %s",          panic("UpdateStringProc should not be invoked for type %s",
706                  objPtr->typePtr->name);                  objPtr->typePtr->name);
707      }      }
708      (*objPtr->typePtr->updateStringProc)(objPtr);      (*objPtr->typePtr->updateStringProc)(objPtr);
709      return objPtr->bytes;      return objPtr->bytes;
710  }  }
711    
712  /*  /*
713   *----------------------------------------------------------------------   *----------------------------------------------------------------------
714   *   *
715   * Tcl_GetStringFromObj --   * Tcl_GetStringFromObj --
716   *   *
717   *      Returns the string representation's byte array pointer and length   *      Returns the string representation's byte array pointer and length
718   *      for an object.   *      for an object.
719   *   *
720   * Results:   * Results:
721   *      Returns a pointer to the string representation of objPtr. If   *      Returns a pointer to the string representation of objPtr. If
722   *      lengthPtr isn't NULL, the length of the string representation is   *      lengthPtr isn't NULL, the length of the string representation is
723   *      stored at *lengthPtr. The byte array referenced by the returned   *      stored at *lengthPtr. The byte array referenced by the returned
724   *      pointer must not be modified by the caller. Furthermore, the   *      pointer must not be modified by the caller. Furthermore, the
725   *      caller must copy the bytes if they need to retain them since the   *      caller must copy the bytes if they need to retain them since the
726   *      object's string rep can change as a result of other operations.   *      object's string rep can change as a result of other operations.
727   *   *
728   * Side effects:   * Side effects:
729   *      May call the object's updateStringProc to update the string   *      May call the object's updateStringProc to update the string
730   *      representation from the internal representation.   *      representation from the internal representation.
731   *   *
732   *----------------------------------------------------------------------   *----------------------------------------------------------------------
733   */   */
734    
735  char *  char *
736  Tcl_GetStringFromObj(objPtr, lengthPtr)  Tcl_GetStringFromObj(objPtr, lengthPtr)
737      register Tcl_Obj *objPtr;   /* Object whose string rep byte pointer      register Tcl_Obj *objPtr;   /* Object whose string rep byte pointer
738                                   * should be returned. */                                   * should be returned. */
739      register int *lengthPtr;    /* If non-NULL, the location where the      register int *lengthPtr;    /* If non-NULL, the location where the
740                                   * string rep's byte array length should be                                   * string rep's byte array length should be
741                                   * stored. If NULL, no length is stored. */                                   * stored. If NULL, no length is stored. */
742  {  {
743      if (objPtr->bytes != NULL) {      if (objPtr->bytes != NULL) {
744          if (lengthPtr != NULL) {          if (lengthPtr != NULL) {
745              *lengthPtr = objPtr->length;              *lengthPtr = objPtr->length;
746          }          }
747          return objPtr->bytes;          return objPtr->bytes;
748      }      }
749    
750      if (objPtr->typePtr->updateStringProc == NULL) {      if (objPtr->typePtr->updateStringProc == NULL) {
751          panic("UpdateStringProc should not be invoked for type %s",          panic("UpdateStringProc should not be invoked for type %s",
752                  objPtr->typePtr->name);                  objPtr->typePtr->name);
753      }      }
754      (*objPtr->typePtr->updateStringProc)(objPtr);      (*objPtr->typePtr->updateStringProc)(objPtr);
755      if (lengthPtr != NULL) {      if (lengthPtr != NULL) {
756          *lengthPtr = objPtr->length;          *lengthPtr = objPtr->length;
757      }      }
758      return objPtr->bytes;      return objPtr->bytes;
759  }  }
760    
761  /*  /*
762   *----------------------------------------------------------------------   *----------------------------------------------------------------------
763   *   *
764   * Tcl_InvalidateStringRep --   * Tcl_InvalidateStringRep --
765   *   *
766   *      This procedure is called to invalidate an object's string   *      This procedure is called to invalidate an object's string
767   *      representation.   *      representation.
768   *   *
769   * Results:   * Results:
770   *      None.   *      None.
771   *   *
772   * Side effects:   * Side effects:
773   *      Deallocates the storage for any old string representation, then   *      Deallocates the storage for any old string representation, then
774   *      sets the string representation NULL to mark it invalid.   *      sets the string representation NULL to mark it invalid.
775   *   *
776   *----------------------------------------------------------------------   *----------------------------------------------------------------------
777   */   */
778    
779  void  void
780  Tcl_InvalidateStringRep(objPtr)  Tcl_InvalidateStringRep(objPtr)
781       register Tcl_Obj *objPtr;  /* Object whose string rep byte pointer       register Tcl_Obj *objPtr;  /* Object whose string rep byte pointer
782                                   * should be freed. */                                   * should be freed. */
783  {  {
784      if (objPtr->bytes != NULL) {      if (objPtr->bytes != NULL) {
785          if (objPtr->bytes != tclEmptyStringRep) {          if (objPtr->bytes != tclEmptyStringRep) {
786              ckfree((char *) objPtr->bytes);              ckfree((char *) objPtr->bytes);
787          }          }
788          objPtr->bytes = NULL;          objPtr->bytes = NULL;
789      }      }
790  }  }
791    
792  /*  /*
793   *----------------------------------------------------------------------   *----------------------------------------------------------------------
794   *   *
795   * Tcl_NewBooleanObj --   * Tcl_NewBooleanObj --
796   *   *
797   *      This procedure is normally called when not debugging: i.e., when   *      This procedure is normally called when not debugging: i.e., when
798   *      TCL_MEM_DEBUG is not defined. It creates a new boolean object and   *      TCL_MEM_DEBUG is not defined. It creates a new boolean object and
799   *      initializes it from the argument boolean value. A nonzero   *      initializes it from the argument boolean value. A nonzero
800   *      "boolValue" is coerced to 1.   *      "boolValue" is coerced to 1.
801   *   *
802   *      When TCL_MEM_DEBUG is defined, this procedure just returns the   *      When TCL_MEM_DEBUG is defined, this procedure just returns the
803   *      result of calling the debugging version Tcl_DbNewBooleanObj.   *      result of calling the debugging version Tcl_DbNewBooleanObj.
804   *   *
805   * Results:   * Results:
806   *      The newly created object is returned. This object will have an   *      The newly created object is returned. This object will have an
807   *      invalid string representation. The returned object has ref count 0.   *      invalid string representation. The returned object has ref count 0.
808   *   *
809   * Side effects:   * Side effects:
810   *      None.   *      None.
811   *   *
812   *----------------------------------------------------------------------   *----------------------------------------------------------------------
813   */   */
814    
815  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
816  #undef Tcl_NewBooleanObj  #undef Tcl_NewBooleanObj
817    
818  Tcl_Obj *  Tcl_Obj *
819  Tcl_NewBooleanObj(boolValue)  Tcl_NewBooleanObj(boolValue)
820      register int boolValue;     /* Boolean used to initialize new object. */      register int boolValue;     /* Boolean used to initialize new object. */
821  {  {
822      return Tcl_DbNewBooleanObj(boolValue, "unknown", 0);      return Tcl_DbNewBooleanObj(boolValue, "unknown", 0);
823  }  }
824    
825  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
826    
827  Tcl_Obj *  Tcl_Obj *
828  Tcl_NewBooleanObj(boolValue)  Tcl_NewBooleanObj(boolValue)
829      register int boolValue;     /* Boolean used to initialize new object. */      register int boolValue;     /* Boolean used to initialize new object. */
830  {  {
831      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
832    
833      TclNewObj(objPtr);      TclNewObj(objPtr);
834      objPtr->bytes = NULL;      objPtr->bytes = NULL;
835            
836      objPtr->internalRep.longValue = (boolValue? 1 : 0);      objPtr->internalRep.longValue = (boolValue? 1 : 0);
837      objPtr->typePtr = &tclBooleanType;      objPtr->typePtr = &tclBooleanType;
838      return objPtr;      return objPtr;
839  }  }
840  #endif /* TCL_MEM_DEBUG */  #endif /* TCL_MEM_DEBUG */
841    
842  /*  /*
843   *----------------------------------------------------------------------   *----------------------------------------------------------------------
844   *   *
845   * Tcl_DbNewBooleanObj --   * Tcl_DbNewBooleanObj --
846   *   *
847   *      This procedure is normally called when debugging: i.e., when   *      This procedure is normally called when debugging: i.e., when
848   *      TCL_MEM_DEBUG is defined. It creates new boolean objects. It is the   *      TCL_MEM_DEBUG is defined. It creates new boolean objects. It is the
849   *      same as the Tcl_NewBooleanObj procedure above except that it calls   *      same as the Tcl_NewBooleanObj procedure above except that it calls
850   *      Tcl_DbCkalloc directly with the file name and line number from its   *      Tcl_DbCkalloc directly with the file name and line number from its
851   *      caller. This simplifies debugging since then the checkmem command   *      caller. This simplifies debugging since then the checkmem command
852   *      will report the correct file name and line number when reporting   *      will report the correct file name and line number when reporting
853   *      objects that haven't been freed.   *      objects that haven't been freed.
854   *   *
855   *      When TCL_MEM_DEBUG is not defined, this procedure just returns the   *      When TCL_MEM_DEBUG is not defined, this procedure just returns the
856   *      result of calling Tcl_NewBooleanObj.   *      result of calling Tcl_NewBooleanObj.
857   *   *
858   * Results:   * Results:
859   *      The newly created object is returned. This object will have an   *      The newly created object is returned. This object will have an
860   *      invalid string representation. The returned object has ref count 0.   *      invalid string representation. The returned object has ref count 0.
861   *   *
862   * Side effects:   * Side effects:
863   *      None.   *      None.
864   *   *
865   *----------------------------------------------------------------------   *----------------------------------------------------------------------
866   */   */
867    
868  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
869    
870  Tcl_Obj *  Tcl_Obj *
871  Tcl_DbNewBooleanObj(boolValue, file, line)  Tcl_DbNewBooleanObj(boolValue, file, line)
872      register int boolValue;     /* Boolean used to initialize new object. */      register int boolValue;     /* Boolean used to initialize new object. */
873      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
874                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
875      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
876                                   * for debugging. */                                   * for debugging. */
877  {  {
878      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
879    
880      TclDbNewObj(objPtr, file, line);      TclDbNewObj(objPtr, file, line);
881      objPtr->bytes = NULL;      objPtr->bytes = NULL;
882            
883      objPtr->internalRep.longValue = (boolValue? 1 : 0);      objPtr->internalRep.longValue = (boolValue? 1 : 0);
884      objPtr->typePtr = &tclBooleanType;      objPtr->typePtr = &tclBooleanType;
885      return objPtr;      return objPtr;
886  }  }
887    
888  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
889    
890  Tcl_Obj *  Tcl_Obj *
891  Tcl_DbNewBooleanObj(boolValue, file, line)  Tcl_DbNewBooleanObj(boolValue, file, line)
892      register int boolValue;     /* Boolean used to initialize new object. */      register int boolValue;     /* Boolean used to initialize new object. */
893      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
894                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
895      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
896                                   * for debugging. */                                   * for debugging. */
897  {  {
898      return Tcl_NewBooleanObj(boolValue);      return Tcl_NewBooleanObj(boolValue);
899  }  }
900  #endif /* TCL_MEM_DEBUG */  #endif /* TCL_MEM_DEBUG */
901    
902  /*  /*
903   *----------------------------------------------------------------------   *----------------------------------------------------------------------
904   *   *
905   * Tcl_SetBooleanObj --   * Tcl_SetBooleanObj --
906   *   *
907   *      Modify an object to be a boolean object and to have the specified   *      Modify an object to be a boolean object and to have the specified
908   *      boolean value. A nonzero "boolValue" is coerced to 1.   *      boolean value. A nonzero "boolValue" is coerced to 1.
909   *   *
910   * Results:   * Results:
911   *      None.   *      None.
912   *   *
913   * Side effects:   * Side effects:
914   *      The object's old string rep, if any, is freed. Also, any old   *      The object's old string rep, if any, is freed. Also, any old
915   *      internal rep is freed.   *      internal rep is freed.
916   *   *
917   *----------------------------------------------------------------------   *----------------------------------------------------------------------
918   */   */
919    
920  void  void
921  Tcl_SetBooleanObj(objPtr, boolValue)  Tcl_SetBooleanObj(objPtr, boolValue)
922      register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */      register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */
923      register int boolValue;     /* Boolean used to set object's value. */      register int boolValue;     /* Boolean used to set object's value. */
924  {  {
925      register Tcl_ObjType *oldTypePtr = objPtr->typePtr;      register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
926    
927      if (Tcl_IsShared(objPtr)) {      if (Tcl_IsShared(objPtr)) {
928          panic("Tcl_SetBooleanObj called with shared object");          panic("Tcl_SetBooleanObj called with shared object");
929      }      }
930            
931      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
932          oldTypePtr->freeIntRepProc(objPtr);          oldTypePtr->freeIntRepProc(objPtr);
933      }      }
934            
935      objPtr->internalRep.longValue = (boolValue? 1 : 0);      objPtr->internalRep.longValue = (boolValue? 1 : 0);
936      objPtr->typePtr = &tclBooleanType;      objPtr->typePtr = &tclBooleanType;
937      Tcl_InvalidateStringRep(objPtr);      Tcl_InvalidateStringRep(objPtr);
938  }  }
939    
940  /*  /*
941   *----------------------------------------------------------------------   *----------------------------------------------------------------------
942   *   *
943   * Tcl_GetBooleanFromObj --   * Tcl_GetBooleanFromObj --
944   *   *
945   *      Attempt to return a boolean from the Tcl object "objPtr". If the   *      Attempt to return a boolean from the Tcl object "objPtr". If the
946   *      object is not already a boolean, an attempt will be made to convert   *      object is not already a boolean, an attempt will be made to convert
947   *      it to one.   *      it to one.
948   *   *
949   * Results:   * Results:
950   *      The return value is a standard Tcl object result. If an error occurs   *      The return value is a standard Tcl object result. If an error occurs
951   *      during conversion, an error message is left in the interpreter's   *      during conversion, an error message is left in the interpreter's
952   *      result unless "interp" is NULL.   *      result unless "interp" is NULL.
953   *   *
954   * Side effects:   * Side effects:
955   *      If the object is not already a boolean, the conversion will free   *      If the object is not already a boolean, the conversion will free
956   *      any old internal representation.   *      any old internal representation.
957   *   *
958   *----------------------------------------------------------------------   *----------------------------------------------------------------------
959   */   */
960    
961  int  int
962  Tcl_GetBooleanFromObj(interp, objPtr, boolPtr)  Tcl_GetBooleanFromObj(interp, objPtr, boolPtr)
963      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
964      register Tcl_Obj *objPtr;   /* The object from which to get boolean. */      register Tcl_Obj *objPtr;   /* The object from which to get boolean. */
965      register int *boolPtr;      /* Place to store resulting boolean. */      register int *boolPtr;      /* Place to store resulting boolean. */
966  {  {
967      register int result;      register int result;
968    
969      result = SetBooleanFromAny(interp, objPtr);      result = SetBooleanFromAny(interp, objPtr);
970      if (result == TCL_OK) {      if (result == TCL_OK) {
971          *boolPtr = (int) objPtr->internalRep.longValue;          *boolPtr = (int) objPtr->internalRep.longValue;
972      }      }
973      return result;      return result;
974  }  }
975    
976  /*  /*
977   *----------------------------------------------------------------------   *----------------------------------------------------------------------
978   *   *
979   * SetBooleanFromAny --   * SetBooleanFromAny --
980   *   *
981   *      Attempt to generate a boolean internal form for the Tcl object   *      Attempt to generate a boolean internal form for the Tcl object
982   *      "objPtr".   *      "objPtr".
983   *   *
984   * Results:   * Results:
985   *      The return value is a standard Tcl result. If an error occurs during   *      The return value is a standard Tcl result. If an error occurs during
986   *      conversion, an error message is left in the interpreter's result   *      conversion, an error message is left in the interpreter's result
987   *      unless "interp" is NULL.   *      unless "interp" is NULL.
988   *   *
989   * Side effects:   * Side effects:
990   *      If no error occurs, an integer 1 or 0 is stored as "objPtr"s   *      If no error occurs, an integer 1 or 0 is stored as "objPtr"s
991   *      internal representation and the type of "objPtr" is set to boolean.   *      internal representation and the type of "objPtr" is set to boolean.
992   *   *
993   *----------------------------------------------------------------------   *----------------------------------------------------------------------
994   */   */
995    
996  static int  static int
997  SetBooleanFromAny(interp, objPtr)  SetBooleanFromAny(interp, objPtr)
998      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
999      register Tcl_Obj *objPtr;   /* The object to convert. */      register Tcl_Obj *objPtr;   /* The object to convert. */
1000  {  {
1001      Tcl_ObjType *oldTypePtr = objPtr->typePtr;      Tcl_ObjType *oldTypePtr = objPtr->typePtr;
1002      char *string, *end;      char *string, *end;
1003      register char c;      register char c;
1004      char lowerCase[10];      char lowerCase[10];
1005      int newBool, length;      int newBool, length;
1006      register int i;      register int i;
1007      double dbl;      double dbl;
1008    
1009      /*      /*
1010       * Get the string representation. Make it up-to-date if necessary.       * Get the string representation. Make it up-to-date if necessary.
1011       */       */
1012    
1013      string = Tcl_GetStringFromObj(objPtr, &length);      string = Tcl_GetStringFromObj(objPtr, &length);
1014    
1015      /*      /*
1016       * Copy the string converting its characters to lower case.       * Copy the string converting its characters to lower case.
1017       */       */
1018    
1019      for (i = 0;  (i < 9) && (i < length);  i++) {      for (i = 0;  (i < 9) && (i < length);  i++) {
1020          c = string[i];          c = string[i];
1021          /*          /*
1022           * Weed out international characters so we can safely operate           * Weed out international characters so we can safely operate
1023           * on single bytes.           * on single bytes.
1024           */           */
1025    
1026          if (c & 0x80) {          if (c & 0x80) {
1027              goto badBoolean;              goto badBoolean;
1028          }          }
1029          if (Tcl_UniCharIsUpper(UCHAR(c))) {          if (Tcl_UniCharIsUpper(UCHAR(c))) {
1030              c = (char) Tcl_UniCharToLower(UCHAR(c));              c = (char) Tcl_UniCharToLower(UCHAR(c));
1031          }          }
1032          lowerCase[i] = c;          lowerCase[i] = c;
1033      }      }
1034      lowerCase[i] = 0;      lowerCase[i] = 0;
1035    
1036      /*      /*
1037       * Parse the string as a boolean. We use an implementation here that       * Parse the string as a boolean. We use an implementation here that
1038       * doesn't report errors in interp if interp is NULL.       * doesn't report errors in interp if interp is NULL.
1039       */       */
1040    
1041      c = lowerCase[0];      c = lowerCase[0];
1042      if ((c == '0') && (lowerCase[1] == '\0')) {      if ((c == '0') && (lowerCase[1] == '\0')) {
1043          newBool = 0;          newBool = 0;
1044      } else if ((c == '1') && (lowerCase[1] == '\0')) {      } else if ((c == '1') && (lowerCase[1] == '\0')) {
1045          newBool = 1;          newBool = 1;
1046      } else if ((c == 'y') && (strncmp(lowerCase, "yes", (size_t) length) == 0)) {      } else if ((c == 'y') && (strncmp(lowerCase, "yes", (size_t) length) == 0)) {
1047          newBool = 1;          newBool = 1;
1048      } else if ((c == 'n') && (strncmp(lowerCase, "no", (size_t) length) == 0)) {      } else if ((c == 'n') && (strncmp(lowerCase, "no", (size_t) length) == 0)) {
1049          newBool = 0;          newBool = 0;
1050      } else if ((c == 't') && (strncmp(lowerCase, "true", (size_t) length) == 0)) {      } else if ((c == 't') && (strncmp(lowerCase, "true", (size_t) length) == 0)) {
1051          newBool = 1;          newBool = 1;
1052      } else if ((c == 'f') && (strncmp(lowerCase, "false", (size_t) length) == 0)) {      } else if ((c == 'f') && (strncmp(lowerCase, "false", (size_t) length) == 0)) {
1053          newBool = 0;          newBool = 0;
1054      } else if ((c == 'o') && (length >= 2)) {      } else if ((c == 'o') && (length >= 2)) {
1055          if (strncmp(lowerCase, "on", (size_t) length) == 0) {          if (strncmp(lowerCase, "on", (size_t) length) == 0) {
1056              newBool = 1;              newBool = 1;
1057          } else if (strncmp(lowerCase, "off", (size_t) length) == 0) {          } else if (strncmp(lowerCase, "off", (size_t) length) == 0) {
1058              newBool = 0;              newBool = 0;
1059          } else {          } else {
1060              goto badBoolean;              goto badBoolean;
1061          }          }
1062      } else {      } else {
1063          /*          /*
1064           * Still might be a string containing the characters representing an           * Still might be a string containing the characters representing an
1065           * int or double that wasn't handled above. This would be a string           * int or double that wasn't handled above. This would be a string
1066           * like "27" or "1.0" that is non-zero and not "1". Such a string           * like "27" or "1.0" that is non-zero and not "1". Such a string
1067           * whould result in the boolean value true. We try converting to           * whould result in the boolean value true. We try converting to
1068           * double. If that succeeds and the resulting double is non-zero, we           * double. If that succeeds and the resulting double is non-zero, we
1069           * have a "true". Note that numbers can't have embedded NULLs.           * have a "true". Note that numbers can't have embedded NULLs.
1070           */           */
1071    
1072          dbl = strtod(string, &end);          dbl = strtod(string, &end);
1073          if (end == string) {          if (end == string) {
1074              goto badBoolean;              goto badBoolean;
1075          }          }
1076    
1077          /*          /*
1078           * Make sure the string has no garbage after the end of the double.           * Make sure the string has no garbage after the end of the double.
1079           */           */
1080                    
1081          while ((end < (string+length))          while ((end < (string+length))
1082                  && isspace(UCHAR(*end))) { /* INTL: ISO only */                  && isspace(UCHAR(*end))) { /* INTL: ISO only */
1083              end++;              end++;
1084          }          }
1085          if (end != (string+length)) {          if (end != (string+length)) {
1086              goto badBoolean;              goto badBoolean;
1087          }          }
1088          newBool = (dbl != 0.0);          newBool = (dbl != 0.0);
1089      }      }
1090    
1091      /*      /*
1092       * Free the old internalRep before setting the new one. We do this as       * Free the old internalRep before setting the new one. We do this as
1093       * late as possible to allow the conversion code, in particular       * late as possible to allow the conversion code, in particular
1094       * Tcl_GetStringFromObj, to use that old internalRep.       * Tcl_GetStringFromObj, to use that old internalRep.
1095       */       */
1096    
1097      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
1098          oldTypePtr->freeIntRepProc(objPtr);          oldTypePtr->freeIntRepProc(objPtr);
1099      }      }
1100    
1101      objPtr->internalRep.longValue = newBool;      objPtr->internalRep.longValue = newBool;
1102      objPtr->typePtr = &tclBooleanType;      objPtr->typePtr = &tclBooleanType;
1103      return TCL_OK;      return TCL_OK;
1104    
1105      badBoolean:      badBoolean:
1106      if (interp != NULL) {      if (interp != NULL) {
1107          /*          /*
1108           * Must copy string before resetting the result in case a caller           * Must copy string before resetting the result in case a caller
1109           * is trying to convert the interpreter's result to a boolean.           * is trying to convert the interpreter's result to a boolean.
1110           */           */
1111                    
1112          char buf[100];          char buf[100];
1113          sprintf(buf, "expected boolean value but got \"%.50s\"", string);          sprintf(buf, "expected boolean value but got \"%.50s\"", string);
1114          Tcl_ResetResult(interp);          Tcl_ResetResult(interp);
1115          Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);          Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
1116      }      }
1117      return TCL_ERROR;      return TCL_ERROR;
1118  }  }
1119    
1120  /*  /*
1121   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1122   *   *
1123   * UpdateStringOfBoolean --   * UpdateStringOfBoolean --
1124   *   *
1125   *      Update the string representation for a boolean object.   *      Update the string representation for a boolean object.
1126   *      Note: This procedure does not free an existing old string rep   *      Note: This procedure does not free an existing old string rep
1127   *      so storage will be lost if this has not already been done.   *      so storage will be lost if this has not already been done.
1128   *   *
1129   * Results:   * Results:
1130   *      None.   *      None.
1131   *   *
1132   * Side effects:   * Side effects:
1133   *      The object's string is set to a valid string that results from   *      The object's string is set to a valid string that results from
1134   *      the boolean-to-string conversion.   *      the boolean-to-string conversion.
1135   *   *
1136   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1137   */   */
1138    
1139  static void  static void
1140  UpdateStringOfBoolean(objPtr)  UpdateStringOfBoolean(objPtr)
1141      register Tcl_Obj *objPtr;   /* Int object whose string rep to update. */      register Tcl_Obj *objPtr;   /* Int object whose string rep to update. */
1142  {  {
1143      char *s = ckalloc((unsigned) 2);      char *s = ckalloc((unsigned) 2);
1144            
1145      s[0] = (char) (objPtr->internalRep.longValue? '1' : '0');      s[0] = (char) (objPtr->internalRep.longValue? '1' : '0');
1146      s[1] = '\0';      s[1] = '\0';
1147      objPtr->bytes = s;      objPtr->bytes = s;
1148      objPtr->length = 1;      objPtr->length = 1;
1149  }  }
1150    
1151  /*  /*
1152   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1153   *   *
1154   * Tcl_NewDoubleObj --   * Tcl_NewDoubleObj --
1155   *   *
1156   *      This procedure is normally called when not debugging: i.e., when   *      This procedure is normally called when not debugging: i.e., when
1157   *      TCL_MEM_DEBUG is not defined. It creates a new double object and   *      TCL_MEM_DEBUG is not defined. It creates a new double object and
1158   *      initializes it from the argument double value.   *      initializes it from the argument double value.
1159   *   *
1160   *      When TCL_MEM_DEBUG is defined, this procedure just returns the   *      When TCL_MEM_DEBUG is defined, this procedure just returns the
1161   *      result of calling the debugging version Tcl_DbNewDoubleObj.   *      result of calling the debugging version Tcl_DbNewDoubleObj.
1162   *   *
1163   * Results:   * Results:
1164   *      The newly created object is returned. This object will have an   *      The newly created object is returned. This object will have an
1165   *      invalid string representation. The returned object has ref count 0.   *      invalid string representation. The returned object has ref count 0.
1166   *   *
1167   * Side effects:   * Side effects:
1168   *      None.   *      None.
1169   *   *
1170   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1171   */   */
1172    
1173  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
1174  #undef Tcl_NewDoubleObj  #undef Tcl_NewDoubleObj
1175    
1176  Tcl_Obj *  Tcl_Obj *
1177  Tcl_NewDoubleObj(dblValue)  Tcl_NewDoubleObj(dblValue)
1178      register double dblValue;   /* Double used to initialize the object. */      register double dblValue;   /* Double used to initialize the object. */
1179  {  {
1180      return Tcl_DbNewDoubleObj(dblValue, "unknown", 0);      return Tcl_DbNewDoubleObj(dblValue, "unknown", 0);
1181  }  }
1182    
1183  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
1184    
1185  Tcl_Obj *  Tcl_Obj *
1186  Tcl_NewDoubleObj(dblValue)  Tcl_NewDoubleObj(dblValue)
1187      register double dblValue;   /* Double used to initialize the object. */      register double dblValue;   /* Double used to initialize the object. */
1188  {  {
1189      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
1190    
1191      TclNewObj(objPtr);      TclNewObj(objPtr);
1192      objPtr->bytes = NULL;      objPtr->bytes = NULL;
1193            
1194      objPtr->internalRep.doubleValue = dblValue;      objPtr->internalRep.doubleValue = dblValue;
1195      objPtr->typePtr = &tclDoubleType;      objPtr->typePtr = &tclDoubleType;
1196      return objPtr;      return objPtr;
1197  }  }
1198  #endif /* if TCL_MEM_DEBUG */  #endif /* if TCL_MEM_DEBUG */
1199    
1200  /*  /*
1201   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1202   *   *
1203   * Tcl_DbNewDoubleObj --   * Tcl_DbNewDoubleObj --
1204   *   *
1205   *      This procedure is normally called when debugging: i.e., when   *      This procedure is normally called when debugging: i.e., when
1206   *      TCL_MEM_DEBUG is defined. It creates new double objects. It is the   *      TCL_MEM_DEBUG is defined. It creates new double objects. It is the
1207   *      same as the Tcl_NewDoubleObj procedure above except that it calls   *      same as the Tcl_NewDoubleObj procedure above except that it calls
1208   *      Tcl_DbCkalloc directly with the file name and line number from its   *      Tcl_DbCkalloc directly with the file name and line number from its
1209   *      caller. This simplifies debugging since then the checkmem command   *      caller. This simplifies debugging since then the checkmem command
1210   *      will report the correct file name and line number when reporting   *      will report the correct file name and line number when reporting
1211   *      objects that haven't been freed.   *      objects that haven't been freed.
1212   *   *
1213   *      When TCL_MEM_DEBUG is not defined, this procedure just returns the   *      When TCL_MEM_DEBUG is not defined, this procedure just returns the
1214   *      result of calling Tcl_NewDoubleObj.   *      result of calling Tcl_NewDoubleObj.
1215   *   *
1216   * Results:   * Results:
1217   *      The newly created object is returned. This object will have an   *      The newly created object is returned. This object will have an
1218   *      invalid string representation. The returned object has ref count 0.   *      invalid string representation. The returned object has ref count 0.
1219   *   *
1220   * Side effects:   * Side effects:
1221   *      None.   *      None.
1222   *   *
1223   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1224   */   */
1225    
1226  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
1227    
1228  Tcl_Obj *  Tcl_Obj *
1229  Tcl_DbNewDoubleObj(dblValue, file, line)  Tcl_DbNewDoubleObj(dblValue, file, line)
1230      register double dblValue;   /* Double used to initialize the object. */      register double dblValue;   /* Double used to initialize the object. */
1231      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
1232                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
1233      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
1234                                   * for debugging. */                                   * for debugging. */
1235  {  {
1236      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
1237    
1238      TclDbNewObj(objPtr, file, line);      TclDbNewObj(objPtr, file, line);
1239      objPtr->bytes = NULL;      objPtr->bytes = NULL;
1240            
1241      objPtr->internalRep.doubleValue = dblValue;      objPtr->internalRep.doubleValue = dblValue;
1242      objPtr->typePtr = &tclDoubleType;      objPtr->typePtr = &tclDoubleType;
1243      return objPtr;      return objPtr;
1244  }  }
1245    
1246  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
1247    
1248  Tcl_Obj *  Tcl_Obj *
1249  Tcl_DbNewDoubleObj(dblValue, file, line)  Tcl_DbNewDoubleObj(dblValue, file, line)
1250      register double dblValue;   /* Double used to initialize the object. */      register double dblValue;   /* Double used to initialize the object. */
1251      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
1252                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
1253      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
1254                                   * for debugging. */                                   * for debugging. */
1255  {  {
1256      return Tcl_NewDoubleObj(dblValue);      return Tcl_NewDoubleObj(dblValue);
1257  }  }
1258  #endif /* TCL_MEM_DEBUG */  #endif /* TCL_MEM_DEBUG */
1259    
1260  /*  /*
1261   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1262   *   *
1263   * Tcl_SetDoubleObj --   * Tcl_SetDoubleObj --
1264   *   *
1265   *      Modify an object to be a double object and to have the specified   *      Modify an object to be a double object and to have the specified
1266   *      double value.   *      double value.
1267   *   *
1268   * Results:   * Results:
1269   *      None.   *      None.
1270   *   *
1271   * Side effects:   * Side effects:
1272   *      The object's old string rep, if any, is freed. Also, any old   *      The object's old string rep, if any, is freed. Also, any old
1273   *      internal rep is freed.   *      internal rep is freed.
1274   *   *
1275   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1276   */   */
1277    
1278  void  void
1279  Tcl_SetDoubleObj(objPtr, dblValue)  Tcl_SetDoubleObj(objPtr, dblValue)
1280      register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */      register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */
1281      register double dblValue;   /* Double used to set the object's value. */      register double dblValue;   /* Double used to set the object's value. */
1282  {  {
1283      register Tcl_ObjType *oldTypePtr = objPtr->typePtr;      register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
1284    
1285      if (Tcl_IsShared(objPtr)) {      if (Tcl_IsShared(objPtr)) {
1286          panic("Tcl_SetDoubleObj called with shared object");          panic("Tcl_SetDoubleObj called with shared object");
1287      }      }
1288    
1289      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
1290          oldTypePtr->freeIntRepProc(objPtr);          oldTypePtr->freeIntRepProc(objPtr);
1291      }      }
1292            
1293      objPtr->internalRep.doubleValue = dblValue;      objPtr->internalRep.doubleValue = dblValue;
1294      objPtr->typePtr = &tclDoubleType;      objPtr->typePtr = &tclDoubleType;
1295      Tcl_InvalidateStringRep(objPtr);      Tcl_InvalidateStringRep(objPtr);
1296  }  }
1297    
1298  /*  /*
1299   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1300   *   *
1301   * Tcl_GetDoubleFromObj --   * Tcl_GetDoubleFromObj --
1302   *   *
1303   *      Attempt to return a double from the Tcl object "objPtr". If the   *      Attempt to return a double from the Tcl object "objPtr". If the
1304   *      object is not already a double, an attempt will be made to convert   *      object is not already a double, an attempt will be made to convert
1305   *      it to one.   *      it to one.
1306   *   *
1307   * Results:   * Results:
1308   *      The return value is a standard Tcl object result. If an error occurs   *      The return value is a standard Tcl object result. If an error occurs
1309   *      during conversion, an error message is left in the interpreter's   *      during conversion, an error message is left in the interpreter's
1310   *      result unless "interp" is NULL.   *      result unless "interp" is NULL.
1311   *   *
1312   * Side effects:   * Side effects:
1313   *      If the object is not already a double, the conversion will free   *      If the object is not already a double, the conversion will free
1314   *      any old internal representation.   *      any old internal representation.
1315   *   *
1316   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1317   */   */
1318    
1319  int  int
1320  Tcl_GetDoubleFromObj(interp, objPtr, dblPtr)  Tcl_GetDoubleFromObj(interp, objPtr, dblPtr)
1321      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
1322      register Tcl_Obj *objPtr;   /* The object from which to get a double. */      register Tcl_Obj *objPtr;   /* The object from which to get a double. */
1323      register double *dblPtr;    /* Place to store resulting double. */      register double *dblPtr;    /* Place to store resulting double. */
1324  {  {
1325      register int result;      register int result;
1326            
1327      if (objPtr->typePtr == &tclDoubleType) {      if (objPtr->typePtr == &tclDoubleType) {
1328          *dblPtr = objPtr->internalRep.doubleValue;          *dblPtr = objPtr->internalRep.doubleValue;
1329          return TCL_OK;          return TCL_OK;
1330      }      }
1331    
1332      result = SetDoubleFromAny(interp, objPtr);      result = SetDoubleFromAny(interp, objPtr);
1333      if (result == TCL_OK) {      if (result == TCL_OK) {
1334          *dblPtr = objPtr->internalRep.doubleValue;          *dblPtr = objPtr->internalRep.doubleValue;
1335      }      }
1336      return result;      return result;
1337  }  }
1338    
1339  /*  /*
1340   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1341   *   *
1342   * SetDoubleFromAny --   * SetDoubleFromAny --
1343   *   *
1344   *      Attempt to generate an double-precision floating point internal form   *      Attempt to generate an double-precision floating point internal form
1345   *      for the Tcl object "objPtr".   *      for the Tcl object "objPtr".
1346   *   *
1347   * Results:   * Results:
1348   *      The return value is a standard Tcl object result. If an error occurs   *      The return value is a standard Tcl object result. If an error occurs
1349   *      during conversion, an error message is left in the interpreter's   *      during conversion, an error message is left in the interpreter's
1350   *      result unless "interp" is NULL.   *      result unless "interp" is NULL.
1351   *   *
1352   * Side effects:   * Side effects:
1353   *      If no error occurs, a double is stored as "objPtr"s internal   *      If no error occurs, a double is stored as "objPtr"s internal
1354   *      representation.   *      representation.
1355   *   *
1356   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1357   */   */
1358    
1359  static int  static int
1360  SetDoubleFromAny(interp, objPtr)  SetDoubleFromAny(interp, objPtr)
1361      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
1362      register Tcl_Obj *objPtr;   /* The object to convert. */      register Tcl_Obj *objPtr;   /* The object to convert. */
1363  {  {
1364      Tcl_ObjType *oldTypePtr = objPtr->typePtr;      Tcl_ObjType *oldTypePtr = objPtr->typePtr;
1365      char *string, *end;      char *string, *end;
1366      double newDouble;      double newDouble;
1367      int length;      int length;
1368    
1369      /*      /*
1370       * Get the string representation. Make it up-to-date if necessary.       * Get the string representation. Make it up-to-date if necessary.
1371       */       */
1372    
1373      string = Tcl_GetStringFromObj(objPtr, &length);      string = Tcl_GetStringFromObj(objPtr, &length);
1374    
1375      /*      /*
1376       * Now parse "objPtr"s string as an double. Numbers can't have embedded       * Now parse "objPtr"s string as an double. Numbers can't have embedded
1377       * NULLs. We use an implementation here that doesn't report errors in       * NULLs. We use an implementation here that doesn't report errors in
1378       * interp if interp is NULL.       * interp if interp is NULL.
1379       */       */
1380    
1381      errno = 0;      errno = 0;
1382      newDouble = strtod(string, &end);      newDouble = strtod(string, &end);
1383      if (end == string) {      if (end == string) {
1384          badDouble:          badDouble:
1385          if (interp != NULL) {          if (interp != NULL) {
1386              /*              /*
1387               * Must copy string before resetting the result in case a caller               * Must copy string before resetting the result in case a caller
1388               * is trying to convert the interpreter's result to an int.               * is trying to convert the interpreter's result to an int.
1389               */               */
1390                            
1391              char buf[100];              char buf[100];
1392              sprintf(buf, "expected floating-point number but got \"%.50s\"",              sprintf(buf, "expected floating-point number but got \"%.50s\"",
1393                      string);                      string);
1394              Tcl_ResetResult(interp);              Tcl_ResetResult(interp);
1395              Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);              Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
1396          }          }
1397          return TCL_ERROR;          return TCL_ERROR;
1398      }      }
1399      if (errno != 0) {      if (errno != 0) {
1400          if (interp != NULL) {          if (interp != NULL) {
1401              TclExprFloatError(interp, newDouble);              TclExprFloatError(interp, newDouble);
1402          }          }
1403          return TCL_ERROR;          return TCL_ERROR;
1404      }      }
1405    
1406      /*      /*
1407       * Make sure that the string has no garbage after the end of the double.       * Make sure that the string has no garbage after the end of the double.
1408       */       */
1409            
1410      while ((end < (string+length))      while ((end < (string+length))
1411              && isspace(UCHAR(*end))) { /* INTL: ISO space. */              && isspace(UCHAR(*end))) { /* INTL: ISO space. */
1412          end++;          end++;
1413      }      }
1414      if (end != (string+length)) {      if (end != (string+length)) {
1415          goto badDouble;          goto badDouble;
1416      }      }
1417            
1418      /*      /*
1419       * The conversion to double succeeded. Free the old internalRep before       * The conversion to double succeeded. Free the old internalRep before
1420       * setting the new one. We do this as late as possible to allow the       * setting the new one. We do this as late as possible to allow the
1421       * conversion code, in particular Tcl_GetStringFromObj, to use that old       * conversion code, in particular Tcl_GetStringFromObj, to use that old
1422       * internalRep.       * internalRep.
1423       */       */
1424            
1425      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
1426          oldTypePtr->freeIntRepProc(objPtr);          oldTypePtr->freeIntRepProc(objPtr);
1427      }      }
1428    
1429      objPtr->internalRep.doubleValue = newDouble;      objPtr->internalRep.doubleValue = newDouble;
1430      objPtr->typePtr = &tclDoubleType;      objPtr->typePtr = &tclDoubleType;
1431      return TCL_OK;      return TCL_OK;
1432  }  }
1433    
1434  /*  /*
1435   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1436   *   *
1437   * UpdateStringOfDouble --   * UpdateStringOfDouble --
1438   *   *
1439   *      Update the string representation for a double-precision floating   *      Update the string representation for a double-precision floating
1440   *      point object. This must obey the current tcl_precision value for   *      point object. This must obey the current tcl_precision value for
1441   *      double-to-string conversions. Note: This procedure does not free an   *      double-to-string conversions. Note: This procedure does not free an
1442   *      existing old string rep so storage will be lost if this has not   *      existing old string rep so storage will be lost if this has not
1443   *      already been done.   *      already been done.
1444   *   *
1445   * Results:   * Results:
1446   *      None.   *      None.
1447   *   *
1448   * Side effects:   * Side effects:
1449   *      The object's string is set to a valid string that results from   *      The object's string is set to a valid string that results from
1450   *      the double-to-string conversion.   *      the double-to-string conversion.
1451   *   *
1452   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1453   */   */
1454    
1455  static void  static void
1456  UpdateStringOfDouble(objPtr)  UpdateStringOfDouble(objPtr)
1457      register Tcl_Obj *objPtr;   /* Double obj with string rep to update. */      register Tcl_Obj *objPtr;   /* Double obj with string rep to update. */
1458  {  {
1459      char buffer[TCL_DOUBLE_SPACE];      char buffer[TCL_DOUBLE_SPACE];
1460      register int len;      register int len;
1461            
1462      Tcl_PrintDouble((Tcl_Interp *) NULL, objPtr->internalRep.doubleValue,      Tcl_PrintDouble((Tcl_Interp *) NULL, objPtr->internalRep.doubleValue,
1463              buffer);              buffer);
1464      len = strlen(buffer);      len = strlen(buffer);
1465            
1466      objPtr->bytes = (char *) ckalloc((unsigned) len + 1);      objPtr->bytes = (char *) ckalloc((unsigned) len + 1);
1467      strcpy(objPtr->bytes, buffer);      strcpy(objPtr->bytes, buffer);
1468      objPtr->length = len;      objPtr->length = len;
1469  }  }
1470    
1471  /*  /*
1472   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1473   *   *
1474   * Tcl_NewIntObj --   * Tcl_NewIntObj --
1475   *   *
1476   *      If a client is compiled with TCL_MEM_DEBUG defined, calls to   *      If a client is compiled with TCL_MEM_DEBUG defined, calls to
1477   *      Tcl_NewIntObj to create a new integer object end up calling the   *      Tcl_NewIntObj to create a new integer object end up calling the
1478   *      debugging procedure Tcl_DbNewLongObj instead.   *      debugging procedure Tcl_DbNewLongObj instead.
1479   *   *
1480   *      Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,   *      Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,
1481   *      calls to Tcl_NewIntObj result in a call to one of the two   *      calls to Tcl_NewIntObj result in a call to one of the two
1482   *      Tcl_NewIntObj implementations below. We provide two implementations   *      Tcl_NewIntObj implementations below. We provide two implementations
1483   *      so that the Tcl core can be compiled to do memory debugging of the   *      so that the Tcl core can be compiled to do memory debugging of the
1484   *      core even if a client does not request it for itself.   *      core even if a client does not request it for itself.
1485   *   *
1486   *      Integer and long integer objects share the same "integer" type   *      Integer and long integer objects share the same "integer" type
1487   *      implementation. We store all integers as longs and Tcl_GetIntFromObj   *      implementation. We store all integers as longs and Tcl_GetIntFromObj
1488   *      checks whether the current value of the long can be represented by   *      checks whether the current value of the long can be represented by
1489   *      an int.   *      an int.
1490   *   *
1491   * Results:   * Results:
1492   *      The newly created object is returned. This object will have an   *      The newly created object is returned. This object will have an
1493   *      invalid string representation. The returned object has ref count 0.   *      invalid string representation. The returned object has ref count 0.
1494   *   *
1495   * Side effects:   * Side effects:
1496   *      None.   *      None.
1497   *   *
1498   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1499   */   */
1500    
1501  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
1502  #undef Tcl_NewIntObj  #undef Tcl_NewIntObj
1503    
1504  Tcl_Obj *  Tcl_Obj *
1505  Tcl_NewIntObj(intValue)  Tcl_NewIntObj(intValue)
1506      register int intValue;      /* Int used to initialize the new object. */      register int intValue;      /* Int used to initialize the new object. */
1507  {  {
1508      return Tcl_DbNewLongObj((long)intValue, "unknown", 0);      return Tcl_DbNewLongObj((long)intValue, "unknown", 0);
1509  }  }
1510    
1511  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
1512    
1513  Tcl_Obj *  Tcl_Obj *
1514  Tcl_NewIntObj(intValue)  Tcl_NewIntObj(intValue)
1515      register int intValue;      /* Int used to initialize the new object. */      register int intValue;      /* Int used to initialize the new object. */
1516  {  {
1517      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
1518    
1519      TclNewObj(objPtr);      TclNewObj(objPtr);
1520      objPtr->bytes = NULL;      objPtr->bytes = NULL;
1521            
1522      objPtr->internalRep.longValue = (long)intValue;      objPtr->internalRep.longValue = (long)intValue;
1523      objPtr->typePtr = &tclIntType;      objPtr->typePtr = &tclIntType;
1524      return objPtr;      return objPtr;
1525  }  }
1526  #endif /* if TCL_MEM_DEBUG */  #endif /* if TCL_MEM_DEBUG */
1527    
1528  /*  /*
1529   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1530   *   *
1531   * Tcl_SetIntObj --   * Tcl_SetIntObj --
1532   *   *
1533   *      Modify an object to be an integer and to have the specified integer   *      Modify an object to be an integer and to have the specified integer
1534   *      value.   *      value.
1535   *   *
1536   * Results:   * Results:
1537   *      None.   *      None.
1538   *   *
1539   * Side effects:   * Side effects:
1540   *      The object's old string rep, if any, is freed. Also, any old   *      The object's old string rep, if any, is freed. Also, any old
1541   *      internal rep is freed.   *      internal rep is freed.
1542   *   *
1543   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1544   */   */
1545    
1546  void  void
1547  Tcl_SetIntObj(objPtr, intValue)  Tcl_SetIntObj(objPtr, intValue)
1548      register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */      register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */
1549      register int intValue;      /* Integer used to set object's value. */      register int intValue;      /* Integer used to set object's value. */
1550  {  {
1551      register Tcl_ObjType *oldTypePtr = objPtr->typePtr;      register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
1552    
1553      if (Tcl_IsShared(objPtr)) {      if (Tcl_IsShared(objPtr)) {
1554          panic("Tcl_SetIntObj called with shared object");          panic("Tcl_SetIntObj called with shared object");
1555      }      }
1556            
1557      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
1558          oldTypePtr->freeIntRepProc(objPtr);          oldTypePtr->freeIntRepProc(objPtr);
1559      }      }
1560            
1561      objPtr->internalRep.longValue = (long) intValue;      objPtr->internalRep.longValue = (long) intValue;
1562      objPtr->typePtr = &tclIntType;      objPtr->typePtr = &tclIntType;
1563      Tcl_InvalidateStringRep(objPtr);      Tcl_InvalidateStringRep(objPtr);
1564  }  }
1565    
1566    
1567    
1568  /*  /*
1569   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1570   * Tcl_ParseStringToInts --   * Tcl_ParseStringToInts --
1571   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1572   * DESCRIPTION   * DESCRIPTION
1573   *         Parses a string to both a machine signed integer and a machine     *         Parses a string to both a machine signed integer and a machine  
1574   *         signed long (and, depending on the platform, these may be the same   *         signed long (and, depending on the platform, these may be the same
1575   *    size).  All errors, including overflow, are detected.  The three   *    size).  All errors, including overflow, are detected.  The three
1576   *         formats accepted are decimal, octal, and hexadecimal.           *         formats accepted are decimal, octal, and hexadecimal.        
1577   *   *
1578   *    This function forms the canonical arbiter of what is and is not   *    This function forms the canonical arbiter of what is and is not
1579   *    an integer.  This function can be used to parse only, without   *    an integer.  This function can be used to parse only, without
1580   *    returning any numerical results.   *    returning any numerical results.
1581   *   *
1582   *    All formats (decimal, octal, hexadecimal) allow whitespace both   *    All formats (decimal, octal, hexadecimal) allow whitespace both
1583   *    before and after the digits of the number.   *    before and after the digits of the number.
1584   *   *
1585   *    All formats (decimal, octal, hexadecimal) allow an arbitrary number   *    All formats (decimal, octal, hexadecimal) allow an arbitrary number
1586   *    of unary sign operators before the number (+ and -).  The number   *    of unary sign operators before the number (+ and -).  The number
1587   *    will be negated if the number of "-" operators is odd, and not   *    will be negated if the number of "-" operators is odd, and not
1588   *    negated if the number is even.  The operators are not required to   *    negated if the number is even.  The operators are not required to
1589   *    be contiguous, and may be separated by whitespace.  The operators   *    be contiguous, and may be separated by whitespace.  The operators
1590   *    may be separated from the digits by whitespace (this is to be con-   *    may be separated from the digits by whitespace (this is to be con-
1591   *    sistent with current behavior).   *    sistent with current behavior).
1592   *   *
1593   *    A decimal number consists of the following components.   *    A decimal number consists of the following components.
1594   *       a)Optional leading whitespace.   *       a)Optional leading whitespace.
1595   *       b)An arbitrary number of leading "-" and "+" unary operators,   *       b)An arbitrary number of leading "-" and "+" unary operators,
1596   *         which may be separated by whitespace, and may be separated   *         which may be separated by whitespace, and may be separated
1597   *         from the digits of the number by whitespace.   *         from the digits of the number by whitespace.
1598   *       c)The digits of the number, which may not begin with "0", and   *       c)The digits of the number, which may not begin with "0", and
1599   *         must be contiguous.   *         must be contiguous.
1600   *       d)Optional trailing whitespace.   *       d)Optional trailing whitespace.
1601   *   *
1602   *    A decimal number is illegal if it is effectively positive but   *    A decimal number is illegal if it is effectively positive but
1603   *    is larger than the maximum positive integer of the size being   *    is larger than the maximum positive integer of the size being
1604   *    considered.  By "effectively" positive, I mean having an even   *    considered.  By "effectively" positive, I mean having an even
1605   *    number of unary "-" operators (including zero of them).   *    number of unary "-" operators (including zero of them).
1606   *   *
1607   *    A decimal number is also illegal if it is effectively negative   *    A decimal number is also illegal if it is effectively negative
1608   *    but less than the maximum negative integer of the size being   *    but less than the maximum negative integer of the size being
1609   *    considered.   *    considered.
1610   *   *
1611   *    An octal number is just like a decimal number, except that its   *    An octal number is just like a decimal number, except that its
1612   *    first digit is zero, and no digit may exceed "7".  An octal number   *    first digit is zero, and no digit may exceed "7".  An octal number
1613   *    is illegal only if the configuration of 1-bits specified before   *    is illegal only if the configuration of 1-bits specified before
1614   *    negation exceeds the ability of the machine integer being   *    negation exceeds the ability of the machine integer being
1615   *    considered to hold them--an octal number is exempt from sign   *    considered to hold them--an octal number is exempt from sign
1616   *    considerations.   *    considerations.
1617   *   *
1618   *    A hexadecimal number is just like an octal number, except that   *    A hexadecimal number is just like an octal number, except that
1619   *    the first two digits must be "0x" or "0X", and the digits in   *    the first two digits must be "0x" or "0X", and the digits in
1620   *    the number may be 0-9, A-F, and a-f.  Again, a hexadecimal number   *    the number may be 0-9, A-F, and a-f.  Again, a hexadecimal number
1621   *    is exempt from sign considerations, and will be declared illegal   *    is exempt from sign considerations, and will be declared illegal
1622   *    only if the bit pattern before possible negation will not fit in   *    only if the bit pattern before possible negation will not fit in
1623   *    the machine integer being considered.   *    the machine integer being considered.
1624   *   *
1625   *    The descriptions of legal and illegal above carry over to long   *    The descriptions of legal and illegal above carry over to long
1626   *    integers.  A string may represent a valid long integer but an   *    integers.  A string may represent a valid long integer but an
1627   *    invalid integer.  In all cases, the criteria for illegality is   *    invalid integer.  In all cases, the criteria for illegality is
1628   *    the same.   *    the same.
1629   *   *
1630   *    Negation in all cases is carried out in the two's complement   *    Negation in all cases is carried out in the two's complement
1631   *    fashion (i.e. one's complement plus one).   *    fashion (i.e. one's complement plus one).
1632   *   *
1633   * LEGALITY/ILLEGALITY EXAMPLES   * LEGALITY/ILLEGALITY EXAMPLES
1634   *    Below are listed several examples which illustrate what is legal and   *    Below are listed several examples which illustrate what is legal and
1635   *    what is illegal, and why.  Assume a 32-bit machine integer in   *    what is illegal, and why.  Assume a 32-bit machine integer in
1636   *    standard 2's complement configuration.   *    standard 2's complement configuration.
1637   *   *
1638   *    4000000000 (illegal)   *    4000000000 (illegal)
1639   *       Illegal because a positive number is specified which is larger   *       Illegal because a positive number is specified which is larger
1640   *       than the largest machine positive integer.   *       than the largest machine positive integer.
1641   *    2147483647 (legal)   *    2147483647 (legal)
1642   *       This maps to a legal positive machine integer.   *       This maps to a legal positive machine integer.
1643   *    2147483648 (illegal)   *    2147483648 (illegal)
1644   *       This number is larger than the largest positive integer.   *       This number is larger than the largest positive integer.
1645   *    -2147483648 (legal)   *    -2147483648 (legal)
1646   *       This number is a legal negative integer.   *       This number is a legal negative integer.
1647   *    ----2147483648 (illegal)   *    ----2147483648 (illegal)
1648   *       The number is effectively positive, but will not fit into   *       The number is effectively positive, but will not fit into
1649   *       a positive integer.   *       a positive integer.
1650   *    -----2147483648 (legal)   *    -----2147483648 (legal)
1651   *       The number is effectively negative, and will fit into a negative   *       The number is effectively negative, and will fit into a negative
1652   *       machine integer.   *       machine integer.
1653   *    + - +++ - + - + ---- 0000000000000000 (legal)   *    + - +++ - + - + ---- 0000000000000000 (legal)
1654   *       Any number of unary + and - operators may be specified, they   *       Any number of unary + and - operators may be specified, they
1655   *       are not required to be contiguous, and any number of zero digits   *       are not required to be contiguous, and any number of zero digits
1656   *       are allowed.   *       are allowed.
1657   *       *    
1658   *    + - +++ - + - + ---- 0000000000000008 (illegal)   *    + - +++ - + - + ---- 0000000000000008 (illegal)
1659   *       The digit "8" cannot appear in an octal number.   *       The digit "8" cannot appear in an octal number.
1660   *   *
1661   *    +-+-+---- 0x0000000000000000000000000000000000000000000Ff (legal)   *    +-+-+---- 0x0000000000000000000000000000000000000000000Ff (legal)
1662   *       The only consideration for a hexadecimal number is that the   *       The only consideration for a hexadecimal number is that the
1663   *       1's in the bit pattern fit into 32 bits.  They do.   *       1's in the bit pattern fit into 32 bits.  They do.
1664   *   *
1665   *    -0xABCDEF01 (legal)   *    -0xABCDEF01 (legal)
1666   *       The number, before negation, fits into 32 bits.   *       The number, before negation, fits into 32 bits.
1667   *   *
1668   *    -0x6ABCDEF01 (illegal)   *    -0x6ABCDEF01 (illegal)
1669   *       The number, before negation, does not fit into 32 bits.   *       The number, before negation, does not fit into 32 bits.
1670   *   *
1671   *    077777777777 (illegal)   *    077777777777 (illegal)
1672   *       The octal number contains 33 significant bits, and cannot be   *       The octal number contains 33 significant bits, and cannot be
1673   *       contained by a machine integer.   *       contained by a machine integer.
1674   *    037777777777 (illegal)   *    037777777777 (illegal)
1675   *       This octal number contains only 32 significant bits, and   *       This octal number contains only 32 significant bits, and
1676   *       can be contained in a machine integer.   *       can be contained in a machine integer.
1677   *   *
1678   *   *
1679   * INPUTS   * INPUTS
1680   *    s   *    s
1681   *       Pointer to string to accept as input.  This pointer may not   *       Pointer to string to accept as input.  This pointer may not
1682   *       be NULL.   *       be NULL.
1683   *    len   *    len
1684   *       The maximum number of characters to use from s.  If this   *       The maximum number of characters to use from s.  If this
1685   *       parameter is non-negative, this function will treat s as if   *       parameter is non-negative, this function will treat s as if
1686   *       s[len] is the \0 terminator.  (By the way, since a valid integer   *       s[len] is the \0 terminator.  (By the way, since a valid integer
1687   *       can never be specified with zero characters, zero here will   *       can never be specified with zero characters, zero here will
1688   *       always result in unsuccessful parses.)  If this parameter is   *       always result in unsuccessful parses.)  If this parameter is
1689   *       negative (commonly "-1"), it indicates to use a zero terminator   *       negative (commonly "-1"), it indicates to use a zero terminator
1690   *       in s.   *       in s.
1691   *    *err_result   *    *err_result
1692   *       This is a bit-packed integer which indicates the result   *       This is a bit-packed integer which indicates the result
1693   *       of the parsing.  Bits are set on failure rather than   *       of the parsing.  Bits are set on failure rather than
1694   *       success.  If this integer tests 0, then no errors occured.   *       success.  If this integer tests 0, then no errors occured.
1695   *       The pointer to this integer may be NULL, in which case the   *       The pointer to this integer may be NULL, in which case the
1696   *       result is not assigned.   *       result is not assigned.
1697   *       *    
1698   *       Since the ANSI C spec requires that integers be at least   *       Since the ANSI C spec requires that integers be at least
1699   *       16 bits, we have room for 16 flags here.   *       16 bits, we have room for 16 flags here.
1700   *   *
1701   *       The bits defined in this integer are listed below.  All bits   *       The bits defined in this integer are listed below.  All bits
1702   *       not identified are unused and will always be zero.   *       not identified are unused and will always be zero.
1703   *          a)0x0001 :  The input string was syntactically bad and could   *          a)0x0001 :  The input string was syntactically bad and could
1704   *                      not be parsed as an integer at all, of any   *                      not be parsed as an integer at all, of any
1705   *                      size (example:  illegal characters).  In other   *                      size (example:  illegal characters).  In other
1706   *                      words, the error was not related to size of the   *                      words, the error was not related to size of the
1707   *                      integer, but rather it was not well-formed.   *                      integer, but rather it was not well-formed.
1708   *          b)0x0002 :  Could not be parsed as a signed integer--too   *          b)0x0002 :  Could not be parsed as a signed integer--too
1709   *                      negative.   *                      negative.
1710   *          c)0x0004 :  Could not be parsed as a signed integer--too   *          c)0x0004 :  Could not be parsed as a signed integer--too
1711   *                      positive.   *                      positive.
1712   *          d)0x0008 :  Could not be parsed as an unsigned integer--   *          d)0x0008 :  Could not be parsed as an unsigned integer--
1713   *                      too negative (which means < 0).   *                      too negative (which means < 0).
1714   *          e)0x0010 :  Could not be parsed as an unsigned integer--   *          e)0x0010 :  Could not be parsed as an unsigned integer--
1715   *                      too positive.   *                      too positive.
1716   *          f)0x0020 :  Could not be parsed as an integer--too many   *          f)0x0020 :  Could not be parsed as an integer--too many
1717   *                      bits specified (applies only to octal and hex   *                      bits specified (applies only to octal and hex
1718   *                      numbers).   *                      numbers).
1719   *          g)0x0040 :  Could not be parsed as a signed long--too negative.   *          g)0x0040 :  Could not be parsed as a signed long--too negative.
1720   *          h)0x0080 :  Could not be parsed as a signed long--too positive.   *          h)0x0080 :  Could not be parsed as a signed long--too positive.
1721   *          i)0x0100 :  Could not be parsed as an unsigned long--too negative.   *          i)0x0100 :  Could not be parsed as an unsigned long--too negative.
1722   *          j)0x0200 :  Could not be parsed as an unsigned long--too positive.   *          j)0x0200 :  Could not be parsed as an unsigned long--too positive.
1723   *          k)0x0400 :  Could not be parsed as an long--too many   *          k)0x0400 :  Could not be parsed as an long--too many
1724   *                      bits specified (applies only to octal and hex   *                      bits specified (applies only to octal and hex
1725   *                      numbers).   *                      numbers).
1726   *   *
1727   *    *int_result   *    *int_result
1728   *       The result of attempted conversion to an integer.  If   *       The result of attempted conversion to an integer.  If
1729   *       flag (a) or flag (f) is set, this result is undefined.     *       flag (a) or flag (f) is set, this result is undefined.  
1730   *       If at least one of (b) or (c) are set but neither of   *       If at least one of (b) or (c) are set but neither of
1731   *       (d) or (e) are set, this contains the bit pattern of a   *       (d) or (e) are set, this contains the bit pattern of a
1732   *       valid unsigned integer.   *       valid unsigned integer.
1733   *       of flags (b) through (d) are set but none of flags   *       of flags (b) through (d) are set but none of flags
1734   *         *      
1735   *   *
1736   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1737   */   */
1738    
1739  void Tcl_ParseStringToInts(char *s)  void Tcl_ParseStringToInts(char *s)
1740     {     {
1741    
1742     }     }
1743    
1744    
1745    
1746  /*  /*
1747   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1748   *   *
1749   * Tcl_GetIntFromObj --   * Tcl_GetIntFromObj --
1750   *   *
1751   *      Attempt to return an int from the Tcl object "objPtr". If the object   *      Attempt to return an int from the Tcl object "objPtr". If the object
1752   *      is not already an int, an attempt will be made to convert it to one.   *      is not already an int, an attempt will be made to convert it to one.
1753   *   *
1754   *      Integer and long integer objects share the same "integer" type   *      Integer and long integer objects share the same "integer" type
1755   *      implementation. We store all integers as longs and Tcl_GetIntFromObj   *      implementation. We store all integers as longs and Tcl_GetIntFromObj
1756   *      checks whether the current value of the long can be represented by   *      checks whether the current value of the long can be represented by
1757   *      an int.   *      an int.
1758   *   *
1759   * Results:   * Results:
1760   *      The return value is a standard Tcl object result. If an error occurs   *      The return value is a standard Tcl object result. If an error occurs
1761   *      during conversion or if the long integer held by the object   *      during conversion or if the long integer held by the object
1762   *      can not be represented by an int, an error message is left in   *      can not be represented by an int, an error message is left in
1763   *      the interpreter's result unless "interp" is NULL.   *      the interpreter's result unless "interp" is NULL.
1764   *   *
1765   * Side effects:   * Side effects:
1766   *      If the object is not already an int, the conversion will free   *      If the object is not already an int, the conversion will free
1767   *      any old internal representation.   *      any old internal representation.
1768   *   *
1769   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1770   */   */
1771    
1772  int  int
1773  Tcl_GetIntFromObj(interp, objPtr, intPtr)  Tcl_GetIntFromObj(interp, objPtr, intPtr)
1774      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
1775      register Tcl_Obj *objPtr;   /* The object from which to get a int. */      register Tcl_Obj *objPtr;   /* The object from which to get a int. */
1776      register int *intPtr;       /* Place to store resulting int. */      register int *intPtr;       /* Place to store resulting int. */
1777  {  {
1778      register long l;      register long l;
1779      int result;      int result;
1780            
1781      if (objPtr->typePtr != &tclIntType) {      if (objPtr->typePtr != &tclIntType) {
1782          result = SetIntFromAny(interp, objPtr);          result = SetIntFromAny(interp, objPtr);
1783          if (result != TCL_OK) {          if (result != TCL_OK) {
1784              return result;              return result;
1785          }          }
1786      }      }
1787      l = objPtr->internalRep.longValue;      l = objPtr->internalRep.longValue;
1788      if (((long)((int)l)) == l) {      if (((long)((int)l)) == l) {
1789          *intPtr = (int)objPtr->internalRep.longValue;          *intPtr = (int)objPtr->internalRep.longValue;
1790          return TCL_OK;          return TCL_OK;
1791      }      }
1792      if (interp != NULL) {      if (interp != NULL) {
1793          Tcl_ResetResult(interp);          Tcl_ResetResult(interp);
1794          Tcl_AppendToObj(Tcl_GetObjResult(interp),          Tcl_AppendToObj(Tcl_GetObjResult(interp),
1795                  "integer value too large to represent as non-long integer", -1);                  "integer value too large to represent as non-long integer", -1);
1796      }      }
1797      return TCL_ERROR;      return TCL_ERROR;
1798  }  }
1799    
1800  /*  /*
1801   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1802   *   *
1803   * SetIntFromAny --   * SetIntFromAny --
1804   *   *
1805   *      Attempt to generate an integer internal form for the Tcl object   *      Attempt to generate an integer internal form for the Tcl object
1806   *      "objPtr".   *      "objPtr".
1807   *   *
1808   * Results:   * Results:
1809   *      The return value is a standard object Tcl result. If an error occurs   *      The return value is a standard object Tcl result. If an error occurs
1810   *      during conversion, an error message is left in the interpreter's   *      during conversion, an error message is left in the interpreter's
1811   *      result unless "interp" is NULL.   *      result unless "interp" is NULL.
1812   *   *
1813   * Side effects:   * Side effects:
1814   *      If no error occurs, an int is stored as "objPtr"s internal   *      If no error occurs, an int is stored as "objPtr"s internal
1815   *      representation.   *      representation.
1816   *   *
1817   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1818   */   */
1819    
1820  static int  static int
1821  SetIntFromAny(interp, objPtr)  SetIntFromAny(interp, objPtr)
1822      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
1823      register Tcl_Obj *objPtr;   /* The object to convert. */      register Tcl_Obj *objPtr;   /* The object to convert. */
1824  {  {
1825      Tcl_ObjType *oldTypePtr = objPtr->typePtr;      Tcl_ObjType *oldTypePtr = objPtr->typePtr;
1826      char *string, *end;      char *string, *end;
1827      int length;      int length;
1828      register char *p;      register char *p;
1829      long newLong;      long newLong;
1830    
1831      /*      /*
1832       * Get the string representation. Make it up-to-date if necessary.       * Get the string representation. Make it up-to-date if necessary.
1833       */       */
1834    
1835      string = Tcl_GetStringFromObj(objPtr, &length);      string = Tcl_GetStringFromObj(objPtr, &length);
1836    
1837      /*      /*
1838       * Now parse "objPtr"s string as an int. We use an implementation here       * Now parse "objPtr"s string as an int. We use an implementation here
1839       * that doesn't report errors in interp if interp is NULL. Note: use       * that doesn't report errors in interp if interp is NULL. Note: use
1840       * strtoul instead of strtol for integer conversions to allow full-size       * strtoul instead of strtol for integer conversions to allow full-size
1841       * unsigned numbers, but don't depend on strtoul to handle sign       * unsigned numbers, but don't depend on strtoul to handle sign
1842       * characters; it won't in some implementations.       * characters; it won't in some implementations.
1843       */       */
1844    
1845      errno = 0;      errno = 0;
1846      for (p = string;  isspace(UCHAR(*p));  p++) { /* INTL: ISO space. */      for (p = string;  isspace(UCHAR(*p));  p++) { /* INTL: ISO space. */
1847          /* Empty loop body. */          /* Empty loop body. */
1848      }      }
1849      if (*p == '-') {      if (*p == '-') {
1850          p++;          p++;
1851          newLong = -((long)strtoul(p, &end, 0));          newLong = -((long)strtoul(p, &end, 0));
1852      } else if (*p == '+') {      } else if (*p == '+') {
1853          p++;          p++;
1854          newLong = strtoul(p, &end, 0);          newLong = strtoul(p, &end, 0);
1855      } else {      } else {
1856          newLong = strtoul(p, &end, 0);          newLong = strtoul(p, &end, 0);
1857      }      }
1858      if (end == p) {      if (end == p) {
1859          badInteger:          badInteger:
1860          if (interp != NULL) {          if (interp != NULL) {
1861              /*              /*
1862               * Must copy string before resetting the result in case a caller               * Must copy string before resetting the result in case a caller
1863               * is trying to convert the interpreter's result to an int.               * is trying to convert the interpreter's result to an int.
1864               */               */
1865                            
1866              char buf[100];              char buf[100];
1867              sprintf(buf, "expected integer but got \"%.50s\"", string);              sprintf(buf, "expected integer but got \"%.50s\"", string);
1868              Tcl_ResetResult(interp);              Tcl_ResetResult(interp);
1869              Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);              Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
1870              TclCheckBadOctal(interp, string);              TclCheckBadOctal(interp, string);
1871          }          }
1872          return TCL_ERROR;          return TCL_ERROR;
1873      }      }
1874      if (errno == ERANGE) {      if (errno == ERANGE) {
1875          if (interp != NULL) {          if (interp != NULL) {
1876              char *s = "integer value too large to represent";              char *s = "integer value too large to represent";
1877              Tcl_ResetResult(interp);              Tcl_ResetResult(interp);
1878              Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);              Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
1879              Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *) NULL);              Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *) NULL);
1880          }          }
1881          return TCL_ERROR;          return TCL_ERROR;
1882      }      }
1883    
1884      /*      /*
1885       * Make sure that the string has no garbage after the end of the int.       * Make sure that the string has no garbage after the end of the int.
1886       */       */
1887            
1888      while ((end < (string+length))      while ((end < (string+length))
1889              && isspace(UCHAR(*end))) { /* INTL: ISO space. */              && isspace(UCHAR(*end))) { /* INTL: ISO space. */
1890          end++;          end++;
1891      }      }
1892      if (end != (string+length)) {      if (end != (string+length)) {
1893          goto badInteger;          goto badInteger;
1894      }      }
1895    
1896      /*      /*
1897       * The conversion to int succeeded. Free the old internalRep before       * The conversion to int succeeded. Free the old internalRep before
1898       * setting the new one. We do this as late as possible to allow the       * setting the new one. We do this as late as possible to allow the
1899       * conversion code, in particular Tcl_GetStringFromObj, to use that old       * conversion code, in particular Tcl_GetStringFromObj, to use that old
1900       * internalRep.       * internalRep.
1901       */       */
1902    
1903      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
1904          oldTypePtr->freeIntRepProc(objPtr);          oldTypePtr->freeIntRepProc(objPtr);
1905      }      }
1906            
1907      objPtr->internalRep.longValue = newLong;      objPtr->internalRep.longValue = newLong;
1908      objPtr->typePtr = &tclIntType;      objPtr->typePtr = &tclIntType;
1909      return TCL_OK;      return TCL_OK;
1910  }  }
1911    
1912  /*  /*
1913   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1914   *   *
1915   * UpdateStringOfInt --   * UpdateStringOfInt --
1916   *   *
1917   *      Update the string representation for an integer object.   *      Update the string representation for an integer object.
1918   *      Note: This procedure does not free an existing old string rep   *      Note: This procedure does not free an existing old string rep
1919   *      so storage will be lost if this has not already been done.   *      so storage will be lost if this has not already been done.
1920   *   *
1921   * Results:   * Results:
1922   *      None.   *      None.
1923   *   *
1924   * Side effects:   * Side effects:
1925   *      The object's string is set to a valid string that results from   *      The object's string is set to a valid string that results from
1926   *      the int-to-string conversion.   *      the int-to-string conversion.
1927   *   *
1928   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1929   */   */
1930    
1931  static void  static void
1932  UpdateStringOfInt(objPtr)  UpdateStringOfInt(objPtr)
1933      register Tcl_Obj *objPtr;   /* Int object whose string rep to update. */      register Tcl_Obj *objPtr;   /* Int object whose string rep to update. */
1934  {  {
1935      char buffer[TCL_INTEGER_SPACE];      char buffer[TCL_INTEGER_SPACE];
1936      register int len;      register int len;
1937            
1938      len = TclFormatInt(buffer, objPtr->internalRep.longValue);      len = TclFormatInt(buffer, objPtr->internalRep.longValue);
1939            
1940      objPtr->bytes = ckalloc((unsigned) len + 1);      objPtr->bytes = ckalloc((unsigned) len + 1);
1941      strcpy(objPtr->bytes, buffer);      strcpy(objPtr->bytes, buffer);
1942      objPtr->length = len;      objPtr->length = len;
1943  }  }
1944    
1945  /*  /*
1946   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1947   *   *
1948   * Tcl_NewLongObj --   * Tcl_NewLongObj --
1949   *   *
1950   *      If a client is compiled with TCL_MEM_DEBUG defined, calls to   *      If a client is compiled with TCL_MEM_DEBUG defined, calls to
1951   *      Tcl_NewLongObj to create a new long integer object end up calling   *      Tcl_NewLongObj to create a new long integer object end up calling
1952   *      the debugging procedure Tcl_DbNewLongObj instead.   *      the debugging procedure Tcl_DbNewLongObj instead.
1953   *   *
1954   *      Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,   *      Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,
1955   *      calls to Tcl_NewLongObj result in a call to one of the two   *      calls to Tcl_NewLongObj result in a call to one of the two
1956   *      Tcl_NewLongObj implementations below. We provide two implementations   *      Tcl_NewLongObj implementations below. We provide two implementations
1957   *      so that the Tcl core can be compiled to do memory debugging of the   *      so that the Tcl core can be compiled to do memory debugging of the
1958   *      core even if a client does not request it for itself.   *      core even if a client does not request it for itself.
1959   *   *
1960   *      Integer and long integer objects share the same "integer" type   *      Integer and long integer objects share the same "integer" type
1961   *      implementation. We store all integers as longs and Tcl_GetIntFromObj   *      implementation. We store all integers as longs and Tcl_GetIntFromObj
1962   *      checks whether the current value of the long can be represented by   *      checks whether the current value of the long can be represented by
1963   *      an int.   *      an int.
1964   *   *
1965   * Results:   * Results:
1966   *      The newly created object is returned. This object will have an   *      The newly created object is returned. This object will have an
1967   *      invalid string representation. The returned object has ref count 0.   *      invalid string representation. The returned object has ref count 0.
1968   *   *
1969   * Side effects:   * Side effects:
1970   *      None.   *      None.
1971   *   *
1972   *----------------------------------------------------------------------   *----------------------------------------------------------------------
1973   */   */
1974    
1975  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
1976  #undef Tcl_NewLongObj  #undef Tcl_NewLongObj
1977    
1978  Tcl_Obj *  Tcl_Obj *
1979  Tcl_NewLongObj(longValue)  Tcl_NewLongObj(longValue)
1980      register long longValue;    /* Long integer used to initialize the      register long longValue;    /* Long integer used to initialize the
1981                                   * new object. */                                   * new object. */
1982  {  {
1983      return Tcl_DbNewLongObj(longValue, "unknown", 0);      return Tcl_DbNewLongObj(longValue, "unknown", 0);
1984  }  }
1985    
1986  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
1987    
1988  Tcl_Obj *  Tcl_Obj *
1989  Tcl_NewLongObj(longValue)  Tcl_NewLongObj(longValue)
1990      register long longValue;    /* Long integer used to initialize the      register long longValue;    /* Long integer used to initialize the
1991                                   * new object. */                                   * new object. */
1992  {  {
1993      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
1994    
1995      TclNewObj(objPtr);      TclNewObj(objPtr);
1996      objPtr->bytes = NULL;      objPtr->bytes = NULL;
1997            
1998      objPtr->internalRep.longValue = longValue;      objPtr->internalRep.longValue = longValue;
1999      objPtr->typePtr = &tclIntType;      objPtr->typePtr = &tclIntType;
2000      return objPtr;      return objPtr;
2001  }  }
2002  #endif /* if TCL_MEM_DEBUG */  #endif /* if TCL_MEM_DEBUG */
2003    
2004  /*  /*
2005   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2006   *   *
2007   * Tcl_DbNewLongObj --   * Tcl_DbNewLongObj --
2008   *   *
2009   *      If a client is compiled with TCL_MEM_DEBUG defined, calls to   *      If a client is compiled with TCL_MEM_DEBUG defined, calls to
2010   *      Tcl_NewIntObj and Tcl_NewLongObj to create new integer or   *      Tcl_NewIntObj and Tcl_NewLongObj to create new integer or
2011   *      long integer objects end up calling the debugging procedure   *      long integer objects end up calling the debugging procedure
2012   *      Tcl_DbNewLongObj instead. We provide two implementations of   *      Tcl_DbNewLongObj instead. We provide two implementations of
2013   *      Tcl_DbNewLongObj so that whether the Tcl core is compiled to do   *      Tcl_DbNewLongObj so that whether the Tcl core is compiled to do
2014   *      memory debugging of the core is independent of whether a client   *      memory debugging of the core is independent of whether a client
2015   *      requests debugging for itself.   *      requests debugging for itself.
2016   *   *
2017   *      When the core is compiled with TCL_MEM_DEBUG defined,   *      When the core is compiled with TCL_MEM_DEBUG defined,
2018   *      Tcl_DbNewLongObj calls Tcl_DbCkalloc directly with the file name and   *      Tcl_DbNewLongObj calls Tcl_DbCkalloc directly with the file name and
2019   *      line number from its caller. This simplifies debugging since then   *      line number from its caller. This simplifies debugging since then
2020   *      the checkmem command will report the caller's file name and line   *      the checkmem command will report the caller's file name and line
2021   *      number when reporting objects that haven't been freed.   *      number when reporting objects that haven't been freed.
2022   *   *
2023   *      Otherwise, when the core is compiled without TCL_MEM_DEBUG defined,   *      Otherwise, when the core is compiled without TCL_MEM_DEBUG defined,
2024   *      this procedure just returns the result of calling Tcl_NewLongObj.   *      this procedure just returns the result of calling Tcl_NewLongObj.
2025   *   *
2026   * Results:   * Results:
2027   *      The newly created long integer object is returned. This object   *      The newly created long integer object is returned. This object
2028   *      will have an invalid string representation. The returned object has   *      will have an invalid string representation. The returned object has
2029   *      ref count 0.   *      ref count 0.
2030   *   *
2031   * Side effects:   * Side effects:
2032   *      Allocates memory.   *      Allocates memory.
2033   *   *
2034   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2035   */   */
2036    
2037  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
2038    
2039  Tcl_Obj *  Tcl_Obj *
2040  Tcl_DbNewLongObj(longValue, file, line)  Tcl_DbNewLongObj(longValue, file, line)
2041      register long longValue;    /* Long integer used to initialize the      register long longValue;    /* Long integer used to initialize the
2042                                   * new object. */                                   * new object. */
2043      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
2044                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
2045      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
2046                                   * for debugging. */                                   * for debugging. */
2047  {  {
2048      register Tcl_Obj *objPtr;      register Tcl_Obj *objPtr;
2049    
2050      TclDbNewObj(objPtr, file, line);      TclDbNewObj(objPtr, file, line);
2051      objPtr->bytes = NULL;      objPtr->bytes = NULL;
2052            
2053      objPtr->internalRep.longValue = longValue;      objPtr->internalRep.longValue = longValue;
2054      objPtr->typePtr = &tclIntType;      objPtr->typePtr = &tclIntType;
2055      return objPtr;      return objPtr;
2056  }  }
2057    
2058  #else /* if not TCL_MEM_DEBUG */  #else /* if not TCL_MEM_DEBUG */
2059    
2060  Tcl_Obj *  Tcl_Obj *
2061  Tcl_DbNewLongObj(longValue, file, line)  Tcl_DbNewLongObj(longValue, file, line)
2062      register long longValue;    /* Long integer used to initialize the      register long longValue;    /* Long integer used to initialize the
2063                                   * new object. */                                   * new object. */
2064      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
2065                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
2066      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
2067                                   * for debugging. */                                   * for debugging. */
2068  {  {
2069      return Tcl_NewLongObj(longValue);      return Tcl_NewLongObj(longValue);
2070  }  }
2071  #endif /* TCL_MEM_DEBUG */  #endif /* TCL_MEM_DEBUG */
2072    
2073  /*  /*
2074   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2075   *   *
2076   * Tcl_SetLongObj --   * Tcl_SetLongObj --
2077   *   *
2078   *      Modify an object to be an integer object and to have the specified   *      Modify an object to be an integer object and to have the specified
2079   *      long integer value.   *      long integer value.
2080   *   *
2081   * Results:   * Results:
2082   *      None.   *      None.
2083   *   *
2084   * Side effects:   * Side effects:
2085   *      The object's old string rep, if any, is freed. Also, any old   *      The object's old string rep, if any, is freed. Also, any old
2086   *      internal rep is freed.   *      internal rep is freed.
2087   *   *
2088   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2089   */   */
2090    
2091  void  void
2092  Tcl_SetLongObj(objPtr, longValue)  Tcl_SetLongObj(objPtr, longValue)
2093      register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */      register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */
2094      register long longValue;    /* Long integer used to initialize the      register long longValue;    /* Long integer used to initialize the
2095                                   * object's value. */                                   * object's value. */
2096  {  {
2097      register Tcl_ObjType *oldTypePtr = objPtr->typePtr;      register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
2098    
2099      if (Tcl_IsShared(objPtr)) {      if (Tcl_IsShared(objPtr)) {
2100          panic("Tcl_SetLongObj called with shared object");          panic("Tcl_SetLongObj called with shared object");
2101      }      }
2102    
2103      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {      if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
2104          oldTypePtr->freeIntRepProc(objPtr);          oldTypePtr->freeIntRepProc(objPtr);
2105      }      }
2106            
2107      objPtr->internalRep.longValue = longValue;      objPtr->internalRep.longValue = longValue;
2108      objPtr->typePtr = &tclIntType;      objPtr->typePtr = &tclIntType;
2109      Tcl_InvalidateStringRep(objPtr);      Tcl_InvalidateStringRep(objPtr);
2110  }  }
2111    
2112  /*  /*
2113   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2114   *   *
2115   * Tcl_GetLongFromObj --   * Tcl_GetLongFromObj --
2116   *   *
2117   *      Attempt to return an long integer from the Tcl object "objPtr". If   *      Attempt to return an long integer from the Tcl object "objPtr". If
2118   *      the object is not already an int object, an attempt will be made to   *      the object is not already an int object, an attempt will be made to
2119   *      convert it to one.   *      convert it to one.
2120   *   *
2121   * Results:   * Results:
2122   *      The return value is a standard Tcl object result. If an error occurs   *      The return value is a standard Tcl object result. If an error occurs
2123   *      during conversion, an error message is left in the interpreter's   *      during conversion, an error message is left in the interpreter's
2124   *      result unless "interp" is NULL.   *      result unless "interp" is NULL.
2125   *   *
2126   * Side effects:   * Side effects:
2127   *      If the object is not already an int object, the conversion will free   *      If the object is not already an int object, the conversion will free
2128   *      any old internal representation.   *      any old internal representation.
2129   *   *
2130   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2131   */   */
2132    
2133  int  int
2134  Tcl_GetLongFromObj(interp, objPtr, longPtr)  Tcl_GetLongFromObj(interp, objPtr, longPtr)
2135      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */      Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
2136      register Tcl_Obj *objPtr;   /* The object from which to get a long. */      register Tcl_Obj *objPtr;   /* The object from which to get a long. */
2137      register long *longPtr;     /* Place to store resulting long. */      register long *longPtr;     /* Place to store resulting long. */
2138  {  {
2139      register int result;      register int result;
2140            
2141      if (objPtr->typePtr == &tclIntType) {      if (objPtr->typePtr == &tclIntType) {
2142          *longPtr = objPtr->internalRep.longValue;          *longPtr = objPtr->internalRep.longValue;
2143          return TCL_OK;          return TCL_OK;
2144      }      }
2145      result = SetIntFromAny(interp, objPtr);      result = SetIntFromAny(interp, objPtr);
2146      if (result == TCL_OK) {      if (result == TCL_OK) {
2147          *longPtr = objPtr->internalRep.longValue;          *longPtr = objPtr->internalRep.longValue;
2148      }      }
2149      return result;      return result;
2150  }  }
2151    
2152  /*  /*
2153   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2154   *   *
2155   * Tcl_DbIncrRefCount --   * Tcl_DbIncrRefCount --
2156   *   *
2157   *      This procedure is normally called when debugging: i.e., when   *      This procedure is normally called when debugging: i.e., when
2158   *      TCL_MEM_DEBUG is defined. This checks to see whether or not   *      TCL_MEM_DEBUG is defined. This checks to see whether or not
2159   *      the memory has been freed before incrementing the ref count.   *      the memory has been freed before incrementing the ref count.
2160   *   *
2161   *      When TCL_MEM_DEBUG is not defined, this procedure just increments   *      When TCL_MEM_DEBUG is not defined, this procedure just increments
2162   *      the reference count of the object.   *      the reference count of the object.
2163   *   *
2164   * Results:   * Results:
2165   *      None.   *      None.
2166   *   *
2167   * Side effects:   * Side effects:
2168   *      The object's ref count is incremented.   *      The object's ref count is incremented.
2169   *   *
2170   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2171   */   */
2172    
2173  void  void
2174  Tcl_DbIncrRefCount(objPtr, file, line)  Tcl_DbIncrRefCount(objPtr, file, line)
2175      register Tcl_Obj *objPtr;   /* The object we are registering a      register Tcl_Obj *objPtr;   /* The object we are registering a
2176                                   * reference to. */                                   * reference to. */
2177      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
2178                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
2179      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
2180                                   * for debugging. */                                   * for debugging. */
2181  {  {
2182  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
2183      if (objPtr->refCount == 0x61616161) {      if (objPtr->refCount == 0x61616161) {
2184          fprintf(stderr, "file = %s, line = %d\n", file, line);          fprintf(stderr, "file = %s, line = %d\n", file, line);
2185          fflush(stderr);          fflush(stderr);
2186          panic("Trying to increment refCount of previously disposed object.");          panic("Trying to increment refCount of previously disposed object.");
2187      }      }
2188  #endif  #endif
2189      ++(objPtr)->refCount;      ++(objPtr)->refCount;
2190  }  }
2191    
2192  /*  /*
2193   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2194   *   *
2195   * Tcl_DbDecrRefCount --   * Tcl_DbDecrRefCount --
2196   *   *
2197   *      This procedure is normally called when debugging: i.e., when   *      This procedure is normally called when debugging: i.e., when
2198   *      TCL_MEM_DEBUG is defined. This checks to see whether or not   *      TCL_MEM_DEBUG is defined. This checks to see whether or not
2199   *      the memory has been freed before decrementing the ref count.   *      the memory has been freed before decrementing the ref count.
2200   *   *
2201   *      When TCL_MEM_DEBUG is not defined, this procedure just decrements   *      When TCL_MEM_DEBUG is not defined, this procedure just decrements
2202   *      the reference count of the object.   *      the reference count of the object.
2203   *   *
2204   * Results:   * Results:
2205   *      None.   *      None.
2206   *   *
2207   * Side effects:   * Side effects:
2208   *      The object's ref count is incremented.   *      The object's ref count is incremented.
2209   *   *
2210   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2211   */   */
2212    
2213  void  void
2214  Tcl_DbDecrRefCount(objPtr, file, line)  Tcl_DbDecrRefCount(objPtr, file, line)
2215      register Tcl_Obj *objPtr;   /* The object we are releasing a reference      register Tcl_Obj *objPtr;   /* The object we are releasing a reference
2216                                   * to. */                                   * to. */
2217      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
2218                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
2219      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
2220                                   * for debugging. */                                   * for debugging. */
2221  {  {
2222  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
2223      if (objPtr->refCount == 0x61616161) {      if (objPtr->refCount == 0x61616161) {
2224          fprintf(stderr, "file = %s, line = %d\n", file, line);          fprintf(stderr, "file = %s, line = %d\n", file, line);
2225          fflush(stderr);          fflush(stderr);
2226          panic("Trying to decrement refCount of previously disposed object.");          panic("Trying to decrement refCount of previously disposed object.");
2227      }      }
2228  #endif  #endif
2229      if (--(objPtr)->refCount <= 0) {      if (--(objPtr)->refCount <= 0) {
2230          TclFreeObj(objPtr);          TclFreeObj(objPtr);
2231      }      }
2232  }  }
2233    
2234  /*  /*
2235   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2236   *   *
2237   * Tcl_DbIsShared --   * Tcl_DbIsShared --
2238   *   *
2239   *      This procedure is normally called when debugging: i.e., when   *      This procedure is normally called when debugging: i.e., when
2240   *      TCL_MEM_DEBUG is defined. It tests whether the object has a ref   *      TCL_MEM_DEBUG is defined. It tests whether the object has a ref
2241   *      count greater than one.   *      count greater than one.
2242   *   *
2243   *      When TCL_MEM_DEBUG is not defined, this procedure just tests   *      When TCL_MEM_DEBUG is not defined, this procedure just tests
2244   *      if the object has a ref count greater than one.   *      if the object has a ref count greater than one.
2245   *   *
2246   * Results:   * Results:
2247   *      None.   *      None.
2248   *   *
2249   * Side effects:   * Side effects:
2250   *      None.   *      None.
2251   *   *
2252   *----------------------------------------------------------------------   *----------------------------------------------------------------------
2253   */   */
2254    
2255  int  int
2256  Tcl_DbIsShared(objPtr, file, line)  Tcl_DbIsShared(objPtr, file, line)
2257      register Tcl_Obj *objPtr;   /* The object to test for being shared. */      register Tcl_Obj *objPtr;   /* The object to test for being shared. */
2258      char *file;                 /* The name of the source file calling this      char *file;                 /* The name of the source file calling this
2259                                   * procedure; used for debugging. */                                   * procedure; used for debugging. */
2260      int line;                   /* Line number in the source file; used      int line;                   /* Line number in the source file; used
2261                                   * for debugging. */                                   * for debugging. */
2262  {  {
2263  #ifdef TCL_MEM_DEBUG  #ifdef TCL_MEM_DEBUG
2264      if (objPtr->refCount == 0x61616161) {      if (objPtr->refCount == 0x61616161) {
2265          fprintf(stderr, "file = %s, line = %d\n", file, line);          fprintf(stderr, "file = %s, line = %d\n", file, line);
2266          fflush(stderr);          fflush(stderr);
2267          panic("Trying to check whether previously disposed object is shared.");          panic("Trying to check whether previously disposed object is shared.");
2268      }      }
2269  #endif  #endif
2270      return ((objPtr)->refCount > 1);      return ((objPtr)->refCount > 1);
2271  }  }
2272    
2273  /* End of tclobj.c */  /* End of tclobj.c */

Legend:
Removed from v.66  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25