Tcl Source Code

Artifact [f41126a512]
Login

Artifact f41126a512399ff5b86010a0b5d71ab22eca333d:

Attachment "sebres-3.4-patch3.patch" to ticket [3161787fff] added by sebres 2012-04-11 17:16:40.
Index: generic/itcl_bicmds.c
===================================================================
--- generic/itcl_bicmds.c	(revision 1)
+++ generic/itcl_bicmds.c	(working copy)
@@ -465,9 +465,8 @@
         Tcl_DStringSetLength(&buffer, 0);
         Tcl_DStringAppend(&buffer, (lastval) ? lastval : "", -1);
 
-        token = Tcl_GetStringFromObj(objv[i+1], (int*)NULL);
-
-        if (Tcl_SetVar2(interp, member->fullname, (char*)NULL, token,
+	// [SB] set obj, to prevent loss of obj type ...
+        if (Tcl_SetVar2Ex(interp, member->fullname, (char*)NULL, objv[i+1],
             TCL_LEAVE_ERR_MSG) == NULL) {
 
             char msg[256];
@@ -545,7 +544,7 @@
     ItclClass *contextClass;
     ItclObject *contextObj;
 
-    CONST char *name, *val;
+    CONST char *name; Tcl_Obj *val;
     ItclVarLookup *vlookup;
     Tcl_HashEntry *entry;
 
@@ -583,11 +582,11 @@
         return TCL_ERROR;
     }
 
-    val = Itcl_GetInstanceVar(interp, vlookup->vdefn->member->fullname,
+    val = Itcl_GetInstanceVarObj(interp, vlookup->vdefn->member->fullname,
         contextObj, contextObj->classDefn);
 
     if (val) {
-        Tcl_SetObjResult(interp, Tcl_NewStringObj(val, -1));
+        Tcl_SetObjResult(interp, val);
     } else {
         Tcl_SetObjResult(interp, Tcl_NewStringObj("<undefined>", -1));
     }
@@ -643,8 +642,8 @@
     Tcl_DStringFree(&optName);
 
 
-    if (vdefn->init) {
-        objPtr = Tcl_NewStringObj(vdefn->init, -1);
+    if (vdefn->initObj) {
+        objPtr = vdefn->initObj;
     } else {
         objPtr = Tcl_NewStringObj("<undefined>", -1);
     }
@@ -1353,8 +1352,8 @@
                             objPtr = Tcl_NewStringObj("<objectName>", -1);
                         }
                     }
-                    else if (vlookup->vdefn->init) {
-                        objPtr = Tcl_NewStringObj(vlookup->vdefn->init, -1);
+                    else if (vlookup->vdefn->initObj) {
+                        objPtr = vlookup->vdefn->initObj;
                     }
                     else {
                         objPtr = Tcl_NewStringObj("<undefined>", -1);
Index: generic/itcl_class.c
===================================================================
--- generic/itcl_class.c	(revision 1)
+++ generic/itcl_class.c	(working copy)
@@ -910,6 +910,118 @@
 
 /*
  * ------------------------------------------------------------------------
+ *  Itcl_HandleClassIntern()
+ *
+ *  Special case to create object without call any constructor of self 
+ *  or inherited.
+ *
+ *    ::itcl::struct <className> <objName>
+ *
+ *  This procedure creates a new object named <objName> in the appropriate class.
+ *  Note that if <objName> contains "#auto", that part is automatically replaced
+ *  by a unique string built from the class name.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_HandleClassIntern(
+    ClientData clientData,   /* class definition */
+    Tcl_Interp *interp,      /* current interpreter */
+    int objc,                /* number of arguments */
+    Tcl_Obj *CONST objv[]   /* argument objects */
+)
+{
+    ItclClass *cdefnPtr;
+    int result = TCL_OK;
+
+    Tcl_DString buffer;  /* buffer used to build object names */
+    char *token, *objName, *match;
+
+    ItclObject *newObj;
+
+    if (objc != 3) {
+	Tcl_AppendResult(interp,
+            "wrong # args: should be \"::itcl::struct <className> <objName>\"", 
+	    NULL);
+        return TCL_ERROR;
+    }
+
+    // find class :
+    cdefnPtr = Itcl_FindClass(interp, Tcl_GetString(objv[1]), /* autoload */ 1);
+    if (cdefnPtr == NULL) {
+        return TCL_ERROR;
+    }
+
+    // obj name :
+    token = Tcl_GetString(objv[2]);
+
+    /*
+     *  Create a new instance with that name.  
+     *  If the name contains "#auto", replace this with
+     *  a uniquely generated string based on the class name.
+     */
+    Tcl_DStringInit(&buffer);
+    objName = token;
+    match = strstr(token, "#auto");
+    if (match != NULL) {
+	int len;
+	char unique[TCL_INTEGER_SPACE]; /* for unique part of object names */
+	Tcl_CmdInfo dummy;
+	Tcl_UniChar ch;
+
+	Tcl_DStringAppend(&buffer, token, (match - token));
+
+	/*
+	 * Only lowercase the first char of $class, per itcl #auto semantics
+	 */
+	len = Tcl_UtfToUniChar(cdefnPtr->name, &ch);
+	ch = Tcl_UniCharToLower(ch);
+	Tcl_UniCharToUtfDString(&ch, 1, &buffer);
+	Tcl_DStringAppend(&buffer, cdefnPtr->name + len, -1);
+
+	/*
+	 *  Substitute a unique part in for "#auto", and keep
+	 *  incrementing a counter until a valid name is found.
+	 */
+	len = Tcl_DStringLength(&buffer);
+	do {
+	    sprintf(unique, "%d", cdefnPtr->unique++);
+
+	    Tcl_DStringTrunc(&buffer, len);
+	    Tcl_DStringAppend(&buffer, unique, -1);
+	    Tcl_DStringAppend(&buffer, match+5, -1);
+
+	    objName = Tcl_DStringValue(&buffer);
+
+	    /*
+	     * [Fix 227811] Check for any command with the given name, not
+	     * only objects.
+	     */
+
+	    if (Tcl_GetCommandInfo (interp, objName, &dummy) == 0) {
+		break;  /* if an error is found, bail out! */
+	    }
+	} while (1);
+    }
+
+    /*
+     *  Try to create a new object.  If successful, return the
+     *  object name as the result of this command.
+     *  -1 for objc - special case wo constructor ...
+     */
+    result = Itcl_CreateObject(interp, objName, cdefnPtr,
+        -1, objv, &newObj);
+
+    if (result == TCL_OK) {
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(objName, -1));
+    }
+
+    Tcl_DStringFree(&buffer);
+    return result;
+}
+
+
+/*
+ * ------------------------------------------------------------------------
  *  Itcl_ClassCmdResolver()
  *
  *  Used by the class namespaces to handle name resolution for all
@@ -1590,10 +1702,12 @@
     }
 
     if (init) {
-        vdefn->init = (char*)ckalloc((unsigned)(strlen(init)+1));
-        strcpy(vdefn->init, init);
+		vdefn->initObj=Tcl_NewStringObj(init,-1);
+		vdefn->init=Tcl_GetString(vdefn->initObj);
+		Tcl_IncrRefCount(vdefn->initObj);
     }
     else {
+        vdefn->initObj = NULL;
         vdefn->init = NULL;
     }
 
@@ -1617,8 +1731,8 @@
 {
     Itcl_DeleteMember(vdefn->member);
 
-    if (vdefn->init) {
-        ckfree(vdefn->init);
+    if (vdefn->initObj) {
+		Tcl_DecrRefCount(vdefn->initObj);
     }
     ckfree((char*)vdefn);
 }
Index: generic/itcl_cmds.c
===================================================================
--- generic/itcl_cmds.c	(revision 1)
+++ generic/itcl_cmds.c	(working copy)
@@ -307,6 +307,10 @@
     Itcl_PreserveData((ClientData)info);
 
 
+    // add builtin command to create object without constructor 
+    // (unserialize purposes) 
+    Tcl_CreateObjCommand(interp, "::itcl::struct", Itcl_HandleClassIntern,
+        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
     /*
      *  Add "code" and "scope" commands for handling scoped values.
      */
@@ -1603,7 +1607,7 @@
      *  "namespace inscope <namesp> <command>".  If it is,
      *  decode it.
      */
-    if (Itcl_DecodeScopedCommand(interp, name, &contextNs, &cmdName)
+    if (itclDecodeScopedCommand(interp, name, &contextNs, &cmdName)
         != TCL_OK) {
         return TCL_ERROR;
     }
@@ -1637,7 +1641,6 @@
      *    Got this far, so assume that it is a valid object
      */
     Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
-    ckfree(cmdName);
 
     return TCL_OK;
 }
@@ -1685,7 +1688,7 @@
      *    "namespace inscope <namesp> <command>".  If it is,
      *    decode it.
      */
-    if (Itcl_DecodeScopedCommand(interp, name, &contextNs, &cname) != TCL_OK) {
+    if (itclDecodeScopedCommand(interp, name, &contextNs, &cname) != TCL_OK) {
         return TCL_ERROR;
     }
 
@@ -1701,8 +1704,6 @@
         Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
     }
 
-    ckfree(cname);
-
     return TCL_OK;
 
 } /* end Itcl_IsClassCmd function */
Index: generic/itcl_methods.c
===================================================================
--- generic/itcl_methods.c	(revision 1)
+++ generic/itcl_methods.c	(working copy)
@@ -2424,6 +2424,78 @@
 
 /*
  * ------------------------------------------------------------------------
+ *  Itcl_InvokeMethodHashEntry()
+ *
+ *  Looks for a particular method in the specified class.  If the
+ *  method is found, it is invoked with the given arguments.  Any
+ *  protection level (protected/private) for the method is ignored.
+ *  If the method does not exist, this procedure does nothing.
+ *
+ *  This procedure is used primarily to invoke the constructor/destructor
+ *  when an object is created/destroyed.
+ *
+ *  Returns TCL_OK on success; otherwise, this procedure returns
+ *  TCL_ERROR along with an error message in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_InvokeMethodHashEntry(interp, entry, contextClass, contextObj, objc, objv)
+    Tcl_Interp *interp;       /* interpreter */
+    Tcl_HashEntry *entry;     /* hash entry of method */
+    ItclClass *contextClass;  /* current class being constructed */
+    ItclObject *contextObj;   /* object being constructed */
+    int objc;                 /* number of arguments */
+    Tcl_Obj *CONST objv[];    /* argument objects */
+{
+    int result = TCL_OK;
+
+    ItclMemberFunc *mfunc;
+    ItclMember *member;
+    Tcl_Obj *cmdlinePtr;
+    int cmdlinec;
+    Tcl_Obj **cmdlinev;
+
+    /*
+     *  Scan through the list of base classes and see if any of these
+     *  have not been constructed.  Invoke base class constructors
+     *  implicitly, as needed.  Go through the list of base classes
+     *  in reverse order, so that least-specific classes are constructed
+     *  first.
+     */
+    CONST char * name = entry->key.string;
+
+    mfunc  = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+    member = mfunc->member;
+
+    /*
+     *  Prepend the method name to the list of arguments.
+     */
+    cmdlinePtr = Itcl_CreateArgs(interp, entry->key.string, objc, objv);
+
+    (void) Tcl_ListObjGetElements((Tcl_Interp*)NULL, cmdlinePtr,
+        &cmdlinec, &cmdlinev);
+
+    /*
+     *  Execute the code for the method.  Be careful to protect
+     *  the method in case it gets deleted during execution.
+     */
+    Itcl_PreserveData((ClientData)mfunc);
+
+    result = Itcl_EvalMemberCode(interp, mfunc, member,
+        contextObj, cmdlinec, cmdlinev);
+
+    result = Itcl_ReportFuncErrors(interp, mfunc,
+        contextObj, result);
+
+    Itcl_ReleaseData((ClientData)mfunc);
+    Tcl_DecrRefCount(cmdlinePtr);
+
+    return result;
+}
+
+
+/*
+ * ------------------------------------------------------------------------
  *  Itcl_ReportFuncErrors()
  *
  *  Used to interpret the status code returned when the body of a
Index: generic/itcl_migrate.c
===================================================================
--- generic/itcl_migrate.c	(revision 1)
+++ generic/itcl_migrate.c	(working copy)
@@ -122,7 +122,7 @@
 Var *
 _TclNewVar()
 {
-    Var *varPtr;
+    register Var *varPtr;
 
     varPtr = (Var *) ckalloc(itclVarLocalSize);
     ItclInitVarFlags(varPtr);
@@ -143,7 +143,7 @@
 #if ITCL_TCL_PRE_8_5
 Var *
 ItclVarHashCreateVar(
-    TclVarHashTable *tablePtr,
+    ITclVarHashTable *tablePtr,
     const char *key,
     int *newPtr)
 {
Index: generic/itcl_objects.c
===================================================================
--- generic/itcl_objects.c	(revision 1)
+++ generic/itcl_objects.c	(working copy)
@@ -148,6 +148,7 @@
     newObj->dataSize = cdefnPtr->numInstanceVars;
     newObj->data = (Var**)ckalloc((unsigned)(newObj->dataSize*sizeof(Var*)));
 
+    // constructed table to listen all constructors of object :
     newObj->constructed = (Tcl_HashTable*)ckalloc(sizeof(Tcl_HashTable));
     Tcl_InitHashTable(newObj->constructed, TCL_STRING_KEYS);
     newObj->destructed = NULL;
@@ -166,7 +167,6 @@
     Itcl_EventuallyFree((ClientData)newObj, ItclFreeObject);
 
     Tcl_DStringFree(&buffer);
-    Tcl_DStringFree(&objName);
 
     /*
      *  Install the class namespace and object context so that
@@ -176,7 +176,10 @@
     if (Itcl_PushContext(interp, (ItclMember*)NULL, cdefnPtr, newObj,
         &context) != TCL_OK) {
 
+	    Tcl_DStringFree(&objName);
+
         return TCL_ERROR;
+
     }
 
     Itcl_InitHierIter(&hier, cdefn);
@@ -189,9 +192,10 @@
             if ((vdefn->member->flags & ITCL_THIS_VAR) != 0) {
                 if (cdPtr == cdefnPtr) {
                     ItclCreateObjVar(interp, vdefn, newObj);
-                    Tcl_SetVar2(interp, "this", (char*)NULL, "", 0);
-                    Tcl_TraceVar2(interp, "this", NULL,
-                        TCL_TRACE_READS|TCL_TRACE_WRITES, ItclTraceThisVar,
+                    Tcl_SetVar2(interp, "this", (const char*)NULL,
+						Tcl_DStringValue(&objName), 0);
+                    Tcl_TraceVar2(interp, "this", (const char*)NULL,
+                        TCL_TRACE_WRITES, ItclTraceThisVar,
                         (ClientData)newObj);
                 }
             }
@@ -204,8 +208,17 @@
     }
     Itcl_DeleteHierIter(&hier);
 
+    Tcl_DStringFree(&objName);
+
     Itcl_PopContext(interp, &context);  /* back to calling context */
 
+    // special case for unserialize (objc = -1)
+    // don't call any constructor of object :
+    if (objc == -1) {
+	result = TCL_OK;
+	goto wo_constructor;
+    }
+
     /*
      *  Now construct the object.  Look for a constructor in the
      *  most-specific class, and if there is one, invoke it.
@@ -215,15 +228,17 @@
      *  not called out explicitly in "initCode" code fragments are
      *  invoked implicitly without arguments.
      */
-    result = Itcl_InvokeMethodIfExists(interp, "constructor",
+    entry = Tcl_FindHashEntry(&cdefn->functions, "constructor");
+    if (entry) {
+	result = Itcl_InvokeMethodHashEntry(interp, entry,
         cdefn, newObj, objc, objv);
+    } else {
 
     /*
      *  If there is no constructor, construct the base classes
      *  in case they have constructors.  This will cause the
      *  same chain reaction.
      */
-    if (!Tcl_FindHashEntry(&cdefn->functions, "constructor")) {
         result = Itcl_ConstructBase(interp, newObj, cdefn);
     }
 
@@ -249,6 +264,8 @@
         result = Itcl_RestoreInterpState(interp, istate);
     }
 
+wo_constructor:
+
     /*
      *  At this point, the object is fully constructed.
      *  Destroy the "constructed" table in the object data, since
@@ -443,7 +460,8 @@
         result = Itcl_InvokeMethodIfExists(interp, "destructor",
             contextClass, contextObj, 0, (Tcl_Obj* CONST*)NULL);
 
-        if (result != TCL_OK) {
+        if ((result != TCL_OK)
+			&&((flags & ITCL_IGNORE_ERRS) == 0)) {
             return TCL_ERROR;
         }
     }
@@ -502,7 +520,7 @@
      *  "namespace inscope <namesp> <command>".  If it is,
      *  decode it.
      */
-    if (Itcl_DecodeScopedCommand(interp, name, &contextNs, &cmdName)
+    if (itclDecodeScopedCommand(interp, name, &contextNs, &cmdName)
         != TCL_OK) {
         return TCL_ERROR;
     }
@@ -520,8 +538,6 @@
         *roPtr = NULL;
     }
 
-    ckfree(cmdName);
-
     return TCL_OK;
 }
 
@@ -675,9 +691,15 @@
      * callframe refered to by 'framePtr' will be inconsistent
      * ('isProcCallFrame' set, but 'procPtr' not set).
      */
-    if (*token == 'i' && strcmp(token,"info") == 0) {
+
+    /*
+     * this error happens also by call of another functions (as info) *1!!!
+     *
+    */
+
+//*1!!!    if (*token == 'i' && strcmp(token,"info") == 0) {
         framePtr->isProcCallFrame = 0;
-    }
+//*1!!!    }
 
     result = Itcl_EvalArgs(interp, objc-1, objv+1);
 
@@ -740,8 +762,60 @@
     return val;
 }
 
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_GetInstanceVarObj()
+ *
+ *  Returns the current value for an object data member.  The member
+ *  name is interpreted with respect to the given class scope, which
+ *  is usually the most-specific class for the object.
+ *
+ *  If successful, this procedure returns a pointer to a string value
+ *  which remains alive until the variable changes it value.  If
+ *  anything goes wrong, this returns NULL.
+ * ------------------------------------------------------------------------
+ */
+Tcl_Obj*
+Itcl_GetInstanceVarObj(interp, name, contextObj, contextClass)
+    Tcl_Interp *interp;       /* current interpreter */
+    CONST char *name;         /* name of desired instance variable */
+    ItclObject *contextObj;   /* current object */
+    ItclClass *contextClass;  /* name is interpreted in this scope */
+{
+    ItclContext context;
+    Tcl_Obj *val;
 
 /*
+     *  Make sure that the current namespace context includes an
+     *  object that is being manipulated.
+     */
+    if (contextObj == NULL) {
+        Tcl_ResetResult(interp);
+        Tcl_SetResult(interp,
+            "cannot access object-specific info without an object context",
+		TCL_STATIC);
+        return NULL;
+    }
+
+    /*
+     *  Install the object context and access the data member
+     *  like any other variable.
+     */
+    if (Itcl_PushContext(interp, (ItclMember*)NULL, contextClass,
+        contextObj, &context) != TCL_OK) {
+
+        return NULL;
+    }
+
+    val = Tcl_GetVar2Ex(interp, (CONST84 char *)name, (char*)NULL,
+	    TCL_LEAVE_ERR_MSG);
+    Itcl_PopContext(interp, &context);
+
+    return val;
+}
+
+
+/*
  * ------------------------------------------------------------------------
  *  ItclReportObjectUsage()
  *
@@ -1112,12 +1186,12 @@
      *    owns the variable, so that we don't have any trouble
      *    accessing it.
      */
-    if (vdefn->init) {
+    if (vdefn->initObj) {
         if (Itcl_PushContext(interp, (ItclMember*)NULL,
             vdefn->member->classDefn, contextObj, &context) == TCL_OK) {
 
-            Tcl_SetVar2(interp, vdefn->member->fullname,
-                (char*)NULL, vdefn->init, 0);
+            Tcl_SetVar2Ex(interp, vdefn->member->fullname,
+                (char*)NULL, vdefn->initObj, 0);
             Itcl_PopContext(interp, &context);
         }
     }
@@ -1196,7 +1270,8 @@
      *  Look for the command representing the object and extract
      *  the object context.
      */
-    if (!Tcl_GetCommandInfo(interp, namev[1], &cmdInfo)) {
+    if (!Tcl_GetCommandInfo(interp, namev[1], &cmdInfo)
+	    || cmdInfo.objProc != Itcl_HandleInstance) {
         if (errs) {
             Tcl_AppendResult(errs,
                 "can't resolve scoped variable \"", name, "\": ",
@@ -1225,7 +1300,13 @@
     }
 
     vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+    if ((vlookup->vdefn->member->flags & ITCL_COMMON) == 0) {
+	// context variable :
     *rPtr = (Tcl_Var) contextObj->data[vlookup->var.index];
+    } else {
+	// common variable :
+       *rPtr = vlookup->var.common;
+    }
 
     ckfree((char*)namev);
     return TCL_OK;
Index: generic/itcl_parse.c
===================================================================
--- generic/itcl_parse.c	(revision 1)
+++ generic/itcl_parse.c	(working copy)
@@ -647,7 +647,8 @@
     if (objc == 3) {
         body = Tcl_GetString(objv[2]);
     } else {
-        cdefnPtr->initCode = Tcl_DuplicateObj(objv[2]);
+        //cdefnPtr->initCode = Tcl_DuplicateObj(objv[2]);
+        cdefnPtr->initCode = objv[2];
         Tcl_IncrRefCount(cdefnPtr->initCode);
         body = Tcl_GetString(objv[3]);
     }
Index: generic/itcl_util.c
===================================================================
--- generic/itcl_util.c	(revision 1)
+++ generic/itcl_util.c	(working copy)
@@ -33,6 +33,7 @@
  */
 static Itcl_ListElem *listPool = NULL;
 static int listPoolLen = 0;
+TCL_DECLARE_MUTEX(ItclListPoolLock)
 
 #define ITCL_VALID_LIST 0x01face10  /* magic bit pattern for validation */
 #define ITCL_LIST_POOL_SIZE 200     /* max number of elements in listPool */
@@ -68,6 +69,7 @@
 #define TCL_STATE_VALID 0x01233210  /* magic bit pattern for validation */
 
 
+
 /*
  * ------------------------------------------------------------------------
  *  Itcl_Assert()
@@ -276,12 +278,15 @@
 {
     Itcl_ListElem *elemPtr;
 
+	Tcl_MutexLock(&ItclListPoolLock);
     if (listPoolLen > 0) {
         elemPtr = listPool;
         listPool = elemPtr->next;
         --listPoolLen;
+		Tcl_MutexUnlock(&ItclListPoolLock);
     }
     else {
+		Tcl_MutexUnlock(&ItclListPoolLock);
         elemPtr = (Itcl_ListElem*)ckalloc((unsigned)sizeof(Itcl_ListElem));
     }
     elemPtr->owner = listPtr;
@@ -324,12 +329,15 @@
         listPtr->tail = elemPtr->prev;
     --listPtr->num;
 
+	Tcl_MutexLock(&ItclListPoolLock);
     if (listPoolLen < ITCL_LIST_POOL_SIZE) {
         elemPtr->next = listPool;
         listPool = elemPtr;
         ++listPoolLen;
+		Tcl_MutexUnlock(&ItclListPoolLock);
     }
     else {
+		Tcl_MutexUnlock(&ItclListPoolLock);
         ckfree((char*)elemPtr);
     }
     return nextPtr;
@@ -1244,8 +1252,8 @@
 
 /*
  * ------------------------------------------------------------------------
- *  Itcl_DecodeScopedCommand()
- *
+ *  itclDecodeScopedCommand()
+ *   for INTERN USE ONLY, see for EXTERN USE Itcl_DecodeScopedCommand.
  *  Decodes a scoped command of the form:
  *
  *      namespace inscope <namesp> <command>
@@ -1259,23 +1267,26 @@
  *  the interpreter.
  * ------------------------------------------------------------------------
  */
+// [SB] cause rCmdPtr could point to const "static" value (name or 3th element of list as string representation)
+// we will use INTERN itclDecodeScopedCommand that rCmdPtr variable should not be freed (with ckfree).
+// The Itcl_DecodeScopedCommand works as specified in 3.4 ChangeLog :
+//   - Needed to fix usage of Itcl_DecodeScopedCommand as rCmdPtr always
+//     needs to be freed.
 int
-Itcl_DecodeScopedCommand(interp, name, rNsPtr, rCmdPtr)
+itclDecodeScopedCommand(interp, name, rNsPtr, rCmdPtr)
     Tcl_Interp *interp;		/* current interpreter */
     CONST char *name;		/* string to be decoded */
     Tcl_Namespace **rNsPtr;	/* returns: namespace for scoped value */
     char **rCmdPtr;		/* returns: simple command word */
 {
     Tcl_Namespace *nsPtr = NULL;
-    char *cmdName;
+    char *cmdName = (char *)name;
     int len = strlen(name);
-    CONST char *pos;
+
+    char *pos;
     int listc, result;
-    CONST char **listv;
+    const char **listv;
 
-    cmdName = ckalloc((unsigned)strlen(name)+1);
-    strcpy(cmdName, name);
-
     if ((*name == 'n') && (len > 17) && (strncmp(name, "namespace", 9) == 0)) {
 	for (pos = (name + 9);  (*pos == ' ');  pos++) {
 	    /* empty body: skip over spaces */
@@ -1283,7 +1294,7 @@
 	if ((*pos == 'i') && ((pos + 7) <= (name + len))
 	        && (strncmp(pos, "inscope", 7) == 0)) {
 
-            result = Tcl_SplitList(interp, name, &listc,
+            result = Tcl_SplitList(interp, (CONST84 char *)name, &listc,
 		    &listv);
             if (result == TCL_OK) {
                 if (listc != 4) {
@@ -1292,19 +1303,19 @@
                         "namespace inscope namesp command\"",
                         (char*)NULL);
                     result = TCL_ERROR;
-                } else {
+                }
+                else {
                     nsPtr = Tcl_FindNamespace(interp, listv[2],
                         (Tcl_Namespace*)NULL, TCL_LEAVE_ERR_MSG);
 
                     if (!nsPtr) {
                         result = TCL_ERROR;
-                    } else {
-			ckfree(cmdName);
-                        cmdName = ckalloc((unsigned)(strlen(listv[3])+1));
-                        strcpy(cmdName, listv[3]);
                     }
+                    else {
+                        cmdName = listv[3];
                 }
             }
+            }
             ckfree((char*)listv);
 
             if (result != TCL_OK) {
@@ -1321,7 +1332,41 @@
     return TCL_OK;
 }
 
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DecodeScopedCommand()
+ *
+ *  Decodes a scoped command of the form:
+ *
+ *      namespace inscope <namesp> <command>
+ *
+ *  If the given string is not a scoped value, this procedure does
+ *  nothing and returns TCL_OK.  If the string is a scoped value,
+ *  then it is decoded, and the namespace, and the simple command
+ *  string are returned as arguments; the simple command should
+ *  be freed when no longer in use.  If anything goes wrong, this
+ *  procedure returns TCL_ERROR, along with an error message in
+ *  the interpreter.
+ * ------------------------------------------------------------------------
+ */
+ // [SB] in OK fail Itcl_DecodeScopedCommand returns in rCmdPtr always a dynamically allocated string to be freed.
+int
+Itcl_DecodeScopedCommand(interp, name, rNsPtr, rCmdPtr)
+    Tcl_Interp *interp;		/* current interpreter */
+    CONST char *name;		/* string to be decoded */
+    Tcl_Namespace **rNsPtr;	/* returns: namespace for scoped value */
+    char **rCmdPtr;		/* returns: simple command word */
+{
+   char * cmdName;
+   int ret = itclDecodeScopedCommand(interp, name, rNsPtr, &cmdName);
+   if (ret == TCL_OK) {
+      *rCmdPtr = ckalloc((unsigned)(strlen(cmdName)+1));
+      strcpy(*rCmdPtr, cmdName);
+   }
+   return TCL_OK;
+}
 
+
 /*
  * ------------------------------------------------------------------------
  *  Itcl_EvalArgs()
Index: generic/itclInt.h
===================================================================
--- generic/itclInt.h	(revision 1)
+++ generic/itclInt.h	(working copy)
@@ -163,13 +163,13 @@
 
 #define VarInHash Var
 
-#define TclVarHashTable Tcl_HashTable
+#define ITclVarHashTable Tcl_HashTable
 
 typedef struct ItclShortVar {
     int flags;
     union {
 	Tcl_Obj *objPtr;
-	TclVarHashTable *tablePtr;
+	ITclVarHashTable *tablePtr;
 	struct Var *linkPtr;
     } value;
 } ItclShortVar;
@@ -245,7 +245,7 @@
 #define MODULE_SCOPE
 #endif
 
-MODULE_SCOPE Var * ItclVarHashCreateVar (TclVarHashTable * tablePtr, 
+MODULE_SCOPE Var * ItclVarHashCreateVar (ITclVarHashTable * tablePtr, 
 				const char * key, int * newPtr);
 
 #endif /* Version dependent defs and macros */
@@ -254,6 +254,13 @@
 #define ItclVarHashFindVar(tablePtr, key) \
     ItclVarHashCreateVar((tablePtr), (key), NULL)
 
+extern int
+itclDecodeScopedCommand(
+    Tcl_Interp *interp,      /* current interpreter */
+    CONST char *name,        /* string to be decoded */
+    Tcl_Namespace **rNsPtr,  /* returns: namespace for scoped value */
+    char **rCmdPtr          /* returns: simple command word */
+);
 
 /*
  *  Common info for managing all known objects.
@@ -404,6 +411,7 @@
 typedef struct ItclVarDefn {
     ItclMember *member;          /* basic member info */
     char* init;                  /* initial value */
+    Tcl_Obj* initObj;            /* initial value */
 } ItclVarDefn;
 
 /*
Index: generic/itclIntDecls.h
===================================================================
--- generic/itclIntDecls.h	(revision 1)
+++ generic/itclIntDecls.h	(working copy)
@@ -342,6 +342,11 @@
 				Tcl_Interp * interp, CONST char * name, 
 				ItclObject * contextObj, 
 				ItclClass * contextClass));
+/* 48a */
+TCL_EXTERN(Tcl_Obj*)Itcl_GetInstanceVarObj _ANSI_ARGS_((
+				Tcl_Interp * interp, CONST char * name, 
+				ItclObject * contextObj, 
+				ItclClass * contextClass));
 #endif
 #ifndef Itcl_ScopedVarResolver_TCL_DECLARED
 #define Itcl_ScopedVarResolver_TCL_DECLARED
@@ -791,6 +796,20 @@
 				Tcl_Obj *CONST objv[]));
 #endif
 
+// [SB] extended command :
+TCL_EXTERN(int)		Itcl_InvokeMethodHashEntry _ANSI_ARGS_((
+    Tcl_Interp *interp,       /* interpreter */
+    Tcl_HashEntry *entry,     /* hash entry of method */
+    ItclClass *contextClass,  /* current class being constructed */
+    ItclObject *contextObj,   /* object being constructed */
+    int objc,                 /* number of arguments */
+    Tcl_Obj *CONST objv[]     /* argument objects */
+));
+TCL_EXTERN(int)		Itcl_HandleClassIntern _ANSI_ARGS_((ClientData clientData, 
+				Tcl_Interp * interp, int objc, 
+				Tcl_Obj *CONST objv[]));
+
+
 typedef struct ItclIntStubs {
     int magic;
     struct ItclIntStubHooks *hooks;