Itk - the [incr Tk] extension

Changes On Branch experiment
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch experiment Excluding Merge-Ins

This is equivalent to a diff from 46e858f9ac to fd54e0d1dc

2017-07-28
16:57
Several revisions to get evaluation contexts more reliably correct. Closed-Leaf check-in: b46f3c3fe0 user: dgp tags: dgp-method-type
15:57
Take care that the right commands are resolved in the right namespaces. Closed-Leaf check-in: fd54e0d1dc user: dgp tags: experiment
2017-07-27
16:31
Similar changes to the PropagatePublicVariable machinery. check-in: 0bd0be830c user: dgp tags: experiment
2017-07-25
20:35
Attempt to make code say clearly what it does, instead of achieving so much with namespace context games. check-in: 4af9618d9b user: dgp tags: experiment
2017-07-10
18:32
[6acb6a8363] When Itk_AddOptionPart() fails, be sure no remnant of the failed attempt remains to lead to nasty double free. check-in: 46e858f9ac user: dgp tags: dgp-method-type
2017-06-29
17:17
Bump to 4.1.0 check-in: c368859cb1 user: dgp tags: dgp-method-type

Changes to generic/itkArchBase.c.

387
388
389
390
391
392
393
394
395
396
397
398
399





400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
         *  Add a binding onto the new component, so that when its
         *  window is destroyed, it will automatically remove itself
         *  from its parent's component list.  Avoid doing these things
         *  for the "hull" component, since it is a special case and
         *  these things are not really necessary.
         */
        Tcl_DStringSetLength(&buffer, 0);
        Tcl_DStringAppend(&buffer, "bindtags ", -1);
        Tcl_DStringAppend(&buffer, path, -1);
        if (Tcl_Eval(interp, Tcl_DStringValue(&buffer)) != TCL_OK) {
            goto compFail;
        }






        Tcl_DStringSetLength(&buffer, 0);
        Tcl_DStringAppend(&buffer, "bind itk-destroy-", -1);
        Tcl_DStringAppend(&buffer, path, -1);
        Tcl_DStringAppend(&buffer, " <Destroy> [itcl::code ", -1);

        Tcl_DStringAppend(&buffer,
            Tcl_GetStringFromObj(objNamePtr,(int*)NULL), -1);

        Tcl_DStringAppend(&buffer, " itk_component delete ", -1);
        Tcl_DStringAppend(&buffer, name, -1);
        Tcl_DStringAppend(&buffer, "]\n", -1);
        Tcl_DStringAppend(&buffer, "bindtags ", -1);
        Tcl_DStringAppend(&buffer, path, -1);
        Tcl_DStringAppend(&buffer, " {itk-destroy-", -1);
        Tcl_DStringAppend(&buffer, path, -1);
        Tcl_DStringAppend(&buffer, " ", -1);
        Tcl_DStringAppend(&buffer, Tcl_GetStringResult(interp), -1);
        Tcl_DStringAppend(&buffer, "}", -1);

        if (Tcl_Eval(interp, Tcl_DStringValue(&buffer)) != TCL_OK) {
            goto compFail;
        }
    }

    /*
     *  Query the list of configuration options for this widget,







|





>
>
>
>
>

|

|







|






>







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
         *  Add a binding onto the new component, so that when its
         *  window is destroyed, it will automatically remove itself
         *  from its parent's component list.  Avoid doing these things
         *  for the "hull" component, since it is a special case and
         *  these things are not really necessary.
         */
        Tcl_DStringSetLength(&buffer, 0);
        Tcl_DStringAppend(&buffer, "::bindtags ", -1);
        Tcl_DStringAppend(&buffer, path, -1);
        if (Tcl_Eval(interp, Tcl_DStringValue(&buffer)) != TCL_OK) {
            goto compFail;
        }

	/*
	 * NOTE: We need the [::itcl::code] because the itk_component
	 * method is protected.
	 */

        Tcl_DStringSetLength(&buffer, 0);
        Tcl_DStringAppend(&buffer, "::bind itk-destroy-", -1);
        Tcl_DStringAppend(&buffer, path, -1);
        Tcl_DStringAppend(&buffer, " <Destroy> [::itcl::code ", -1);

        Tcl_DStringAppend(&buffer,
            Tcl_GetStringFromObj(objNamePtr,(int*)NULL), -1);

        Tcl_DStringAppend(&buffer, " itk_component delete ", -1);
        Tcl_DStringAppend(&buffer, name, -1);
        Tcl_DStringAppend(&buffer, "]\n", -1);
        Tcl_DStringAppend(&buffer, "::bindtags ", -1);
        Tcl_DStringAppend(&buffer, path, -1);
        Tcl_DStringAppend(&buffer, " {itk-destroy-", -1);
        Tcl_DStringAppend(&buffer, path, -1);
        Tcl_DStringAppend(&buffer, " ", -1);
        Tcl_DStringAppend(&buffer, Tcl_GetStringResult(interp), -1);
        Tcl_DStringAppend(&buffer, "}", -1);

        if (Tcl_Eval(interp, Tcl_DStringValue(&buffer)) != TCL_OK) {
            goto compFail;
        }
    }

    /*
     *  Query the list of configuration options for this widget,
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
    if (objc != 4) {
        objPtr = Tcl_NewStringObj("usual", -1);
        Tcl_IncrRefCount(objPtr);
    } else {
        objPtr = objv[3];
    }

    Tcl_Import(interp, NULL, "::itk::option-parser::*", 1);

    if (result == TCL_OK) {
        result = Tcl_EvalObj(interp, objPtr);
	Tcl_ForgetImport(interp, NULL, "::itk::option-parser::*");
    }

    if (objc != 4) {
        Tcl_DecrRefCount(objPtr);
    }
    if (result != TCL_OK) {
        goto compFail;
    }







<
|
<
|
|
<







480
481
482
483
484
485
486

487

488
489

490
491
492
493
494
495
496
    if (objc != 4) {
        objPtr = Tcl_NewStringObj("usual", -1);
        Tcl_IncrRefCount(objPtr);
    } else {
        objPtr = objv[3];
    }


    Tcl_Eval(interp, "::namespace path [::lreplace [::namespace path] end+1 end ::itk::option-parser]");

    result = Tcl_EvalObj(interp, objPtr);
    Tcl_Eval(interp, "::namespace path [::lrange [::namespace path] 0 end-1]");


    if (objc != 4) {
        Tcl_DecrRefCount(objPtr);
    }
    if (result != TCL_OK) {
        goto compFail;
    }
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657

       /*
        *  Clean up the binding tag that causes the widget to
        *  call this method automatically when destroyed.
        *  Ignore errors if anything goes wrong.
        */
        Tcl_DStringInit(&buffer);
        Tcl_DStringAppend(&buffer, "itk::remove_destroy_hook ", -1);
        Tcl_DStringAppend(&buffer, archComp->pathName, -1);
        (void) Tcl_Eval(interp, Tcl_DStringValue(&buffer));
        Tcl_ResetResult(interp);
        Tcl_DStringFree(&buffer);

        Tcl_UnsetVar2(interp, "itk_component", token, 0);
        Tcl_DeleteHashEntry(entry);







|







646
647
648
649
650
651
652
653
654
655
656
657
658
659
660

       /*
        *  Clean up the binding tag that causes the widget to
        *  call this method automatically when destroyed.
        *  Ignore errors if anything goes wrong.
        */
        Tcl_DStringInit(&buffer);
        Tcl_DStringAppend(&buffer, "::itk::remove_destroy_hook ", -1);
        Tcl_DStringAppend(&buffer, archComp->pathName, -1);
        (void) Tcl_Eval(interp, Tcl_DStringValue(&buffer));
        Tcl_ResetResult(interp);
        Tcl_DStringFree(&buffer);

        Tcl_UnsetVar2(interp, "itk_component", token, 0);
        Tcl_DeleteHashEntry(entry);
1593
1594
1595
1596
1597
1598
1599





1600
1601

1602
1603
1604
1605
1606
1607
1608
     */

    if (result == TCL_OK) {
	/*
	 * Casting away CONST of newval only to satisfy Tcl 8.3 and
	 * earlier headers.
	 */





        val = Tcl_SetVar2(interp, Tcl_GetString(ivPtr->fullNamePtr), (char *) NULL,
            (char *) newval, TCL_LEAVE_ERR_MSG);


        if (!val) {
            result = TCL_ERROR;
        }
    }

    if (result != TCL_OK) {







>
>
>
>
>


>







1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
     */

    if (result == TCL_OK) {
	/*
	 * Casting away CONST of newval only to satisfy Tcl 8.3 and
	 * earlier headers.
	 */

#if 1
	val = ItclSetInstanceVar(interp, Tcl_GetString(ivPtr->fullNamePtr),
		NULL, newval, contextObj, ivPtr->iclsPtr);
#else
        val = Tcl_SetVar2(interp, Tcl_GetString(ivPtr->fullNamePtr), (char *) NULL,
            (char *) newval, TCL_LEAVE_ERR_MSG);
#endif

        if (!val) {
            result = TCL_ERROR;
        }
    }

    if (result != TCL_OK) {
1616
1617
1618
1619
1620
1621
1622

1623
1624
1625
1626
1627
1628


1629
1630
1631
1632
1633
1634
1635
     *  If this variable has some "config" code, invoke it now.
     *
     *  NOTE:  Invoke the "config" code in the class scope
     *    containing the data member.
     */
    mcode = ivPtr->codePtr;
    if (mcode && mcode->bodyPtr) {

        Tcl_Namespace *saveNsPtr;
        Itcl_SetCallFrameResolver(interp, ivPtr->iclsPtr->resolvePtr);
        saveNsPtr = Tcl_GetCurrentNamespace(interp);
        Itcl_SetCallFrameNamespace(interp, ivPtr->iclsPtr->nsPtr);
        result = Tcl_EvalObjEx(interp, mcode->bodyPtr, 0);
        Itcl_SetCallFrameNamespace(interp, saveNsPtr);



        if (result == TCL_OK) {
            Tcl_ResetResult(interp);
        } else {
            char msg[256];
            sprintf(msg, "\n    (error in configuration of public variable \"%.100s\")", Tcl_GetString(ivPtr->fullNamePtr));
            Tcl_AddErrorInfo(interp, msg);







>
|
|
|
|

|
>
>







1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
     *  If this variable has some "config" code, invoke it now.
     *
     *  NOTE:  Invoke the "config" code in the class scope
     *    containing the data member.
     */
    mcode = ivPtr->codePtr;
    if (mcode && mcode->bodyPtr) {
	Tcl_CallFrame frame;

	Itcl_PushCallFrame(interp, &frame, ivPtr->iclsPtr->nsPtr, 1);
	Itcl_SetContext(interp, contextObj);

        result = Tcl_EvalObjEx(interp, mcode->bodyPtr, 0);

	Itcl_UnsetContext(interp);
	Itcl_PopCallFrame(interp);

        if (result == TCL_OK) {
            Tcl_ResetResult(interp);
        } else {
            char msg[256];
            sprintf(msg, "\n    (error in configuration of public variable \"%.100s\")", Tcl_GetString(ivPtr->fullNamePtr));
            Tcl_AddErrorInfo(interp, msg);
1721
1722
1723
1724
1725
1726
1727


1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745

1746







1747
1748
1749
1750
1751
1752
1753
1754
1755
1756

1757




1758
1759
1760
1761
1762
1763
1764
    CONST char *v; 
    char *lastval;
    Tcl_HashEntry *entry;
    ArchOption *archOpt;
    Itcl_ListElem *part;
    ArchOptionPart *optPart;
    Itcl_InterpState istate;



    /*
     *  Query the "itk_option" array to get the current setting.
     */
    entry = Tcl_FindHashEntry(&info->options, name);
    if (!entry) {
        /* Bug 227876
	 * Ensure that the interp result is unshared.
	 */

        Tcl_ResetResult (interp);
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
            "unknown option \"", name, "\"",
            (char*)NULL);
        return TCL_ERROR;
    }
    archOpt = (ArchOption*)Tcl_GetHashValue(entry);


    v = Tcl_GetVar2(interp, "itk_option", archOpt->switchName, 0);







    if (v) {
        lastval = (char*)ckalloc((unsigned)(strlen(v)+1));
        strcpy(lastval, v);
    } else {
        lastval = NULL;
    }

    /*
     *  Update the "itk_option" array with the new setting.
     */

    if (!Tcl_SetVar2(interp, "itk_option", archOpt->switchName, value, 0)) {




        Itk_ArchOptAccessError(interp, info, archOpt);
        result = TCL_ERROR;
        goto configDone;
    }

    /*
     *  Scan through all option parts to handle the new setting.







>
>


















>

>
>
>
>
>
>
>










>

>
>
>
>







1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
    CONST char *v; 
    char *lastval;
    Tcl_HashEntry *entry;
    ArchOption *archOpt;
    Itcl_ListElem *part;
    ArchOptionPart *optPart;
    Itcl_InterpState istate;
    ItclClass *iclsPtr;
    ItclObject *ioPtr;

    /*
     *  Query the "itk_option" array to get the current setting.
     */
    entry = Tcl_FindHashEntry(&info->options, name);
    if (!entry) {
        /* Bug 227876
	 * Ensure that the interp result is unshared.
	 */

        Tcl_ResetResult (interp);
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
            "unknown option \"", name, "\"",
            (char*)NULL);
        return TCL_ERROR;
    }
    archOpt = (ArchOption*)Tcl_GetHashValue(entry);

#if 0
    v = Tcl_GetVar2(interp, "itk_option", archOpt->switchName, 0);
#else
    Itcl_GetContext(interp, &iclsPtr, &ioPtr);

    v = ItclGetInstanceVar(interp, "itk_option", archOpt->switchName,
	    ioPtr, iclsPtr);
#endif

    if (v) {
        lastval = (char*)ckalloc((unsigned)(strlen(v)+1));
        strcpy(lastval, v);
    } else {
        lastval = NULL;
    }

    /*
     *  Update the "itk_option" array with the new setting.
     */
#if 0
    if (!Tcl_SetVar2(interp, "itk_option", archOpt->switchName, value, 0)) {
#else
    if (!ItclSetInstanceVar(interp, "itk_option", archOpt->switchName, value,
	    ioPtr, iclsPtr)) {
#endif
        Itk_ArchOptAccessError(interp, info, archOpt);
        result = TCL_ERROR;
        goto configDone;
    }

    /*
     *  Scan through all option parts to handle the new setting.
1782
1783
1784
1785
1786
1787
1788

1789




1790
1791
1792
1793
1794
1795
1796
     *  If the option configuration failed, then set the option
     *  back to its previous settings.  Scan back through all of
     *  the option parts and sync them up with the old value.
     */
    if (result == TCL_ERROR) {
        istate = Itcl_SaveInterpState(interp, result);


        Tcl_SetVar2(interp, "itk_option", archOpt->switchName, lastval, 0);





        part = Itcl_FirstListElem(&archOpt->parts);
        while (part) {
            optPart = (ArchOptionPart*)Itcl_GetListValue(part);
            (*optPart->configProc)(interp, info->itclObj,
                optPart->clientData, lastval);








>

>
>
>
>







1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
     *  If the option configuration failed, then set the option
     *  back to its previous settings.  Scan back through all of
     *  the option parts and sync them up with the old value.
     */
    if (result == TCL_ERROR) {
        istate = Itcl_SaveInterpState(interp, result);

#if 0
        Tcl_SetVar2(interp, "itk_option", archOpt->switchName, lastval, 0);
#else
	ItclSetInstanceVar(interp, "itk_option", archOpt->switchName, lastval,
	    ioPtr, iclsPtr);
#endif

        part = Itcl_FirstListElem(&archOpt->parts);
        while (part) {
            optPart = (ArchOptionPart*)Itcl_GetListValue(part);
            (*optPart->configProc)(interp, info->itclObj,
                optPart->clientData, lastval);

Changes to generic/itkArchetype.c.

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    if (!parserNs) {
        Itk_DelMergeInfo((char*)mergeInfo);
        Tcl_AddErrorInfo(interp, "\n    (while initializing itk)");
        return TCL_ERROR;
    }
    Itcl_PreserveData((ClientData)mergeInfo);
    Itcl_EventuallyFree((ClientData)mergeInfo, Itk_DelMergeInfo);
    Tcl_Export(interp, parserNs, "[a-z]*", 1);

    Tcl_CreateObjCommand(interp, "::itk::option-parser::keep",
        Itk_ArchOptKeepCmd,
        (ClientData)mergeInfo, (Tcl_CmdDeleteProc*)NULL);

    Tcl_CreateObjCommand(interp, "::itk::option-parser::ignore",
        Itk_ArchOptIgnoreCmd,







<







162
163
164
165
166
167
168

169
170
171
172
173
174
175
    if (!parserNs) {
        Itk_DelMergeInfo((char*)mergeInfo);
        Tcl_AddErrorInfo(interp, "\n    (while initializing itk)");
        return TCL_ERROR;
    }
    Itcl_PreserveData((ClientData)mergeInfo);
    Itcl_EventuallyFree((ClientData)mergeInfo, Itk_DelMergeInfo);


    Tcl_CreateObjCommand(interp, "::itk::option-parser::keep",
        Itk_ArchOptKeepCmd,
        (ClientData)mergeInfo, (Tcl_CmdDeleteProc*)NULL);

    Tcl_CreateObjCommand(interp, "::itk::option-parser::ignore",
        Itk_ArchOptIgnoreCmd,
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
	}
    }
    ItclShowArgs(1, "Itk_ArchConfigureCmd2", objc, objv);
    if (objc == 1) {
        Tcl_DStringInit(&buffer);

        for (i=0; i < info->order.len; i++) {
	    Tcl_Namespace *save = Tcl_GetCurrentNamespace(interp);
            archOpt = (ArchOption*)Tcl_GetHashValue(info->order.list[i]);

	    Itcl_SetCallFrameNamespace(interp, contextObj->iclsPtr->nsPtr);
            val = Tcl_GetVar2(interp, "itk_option", archOpt->switchName, 0);
	    Itcl_SetCallFrameNamespace(interp, save);

            if (!val) {
                Itk_ArchOptAccessError(interp, info, archOpt);
                Tcl_DStringFree(&buffer);
                return TCL_ERROR;
            }

            Tcl_DStringStartSublist(&buffer);







<


<
|
<
>







1063
1064
1065
1066
1067
1068
1069

1070
1071

1072

1073
1074
1075
1076
1077
1078
1079
1080
	}
    }
    ItclShowArgs(1, "Itk_ArchConfigureCmd2", objc, objv);
    if (objc == 1) {
        Tcl_DStringInit(&buffer);

        for (i=0; i < info->order.len; i++) {

            archOpt = (ArchOption*)Tcl_GetHashValue(info->order.list[i]);


	    val = ItclGetInstanceVar(interp, "itk_option", archOpt->switchName,

		    contextObj, contextClass);
            if (!val) {
                Itk_ArchOptAccessError(interp, info, archOpt);
                Tcl_DStringFree(&buffer);
                return TCL_ERROR;
            }

            Tcl_DStringStartSublist(&buffer);
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125

        /*
         *  If there is just one argument, then query the information
         *  for that one argument and return:
         *    {name resName resClass init value}
         */
        if (objc == 2) {
	    Tcl_Namespace *save = Tcl_GetCurrentNamespace(interp);
            token = Tcl_GetString(objv[1]);
            entry = Tcl_FindHashEntry(&info->options, token);
            if (!entry) {
                Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "unknown option \"", token, "\"",
                    (char*)NULL);
                return TCL_ERROR;
            }

            archOpt = (ArchOption*)Tcl_GetHashValue(entry);
	    Itcl_SetCallFrameNamespace(interp, contextObj->iclsPtr->nsPtr);
            val = Tcl_GetVar2(interp, "itk_option", archOpt->switchName, 0);
	    Itcl_SetCallFrameNamespace(interp, save);
            if (!val) {
                Itk_ArchOptAccessError(interp, info, archOpt);
                return TCL_ERROR;
            }

            Tcl_AppendElement(interp, archOpt->switchName);
            Tcl_AppendElement(interp,







<










|
|
|







1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121

        /*
         *  If there is just one argument, then query the information
         *  for that one argument and return:
         *    {name resName resClass init value}
         */
        if (objc == 2) {

            token = Tcl_GetString(objv[1]);
            entry = Tcl_FindHashEntry(&info->options, token);
            if (!entry) {
                Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "unknown option \"", token, "\"",
                    (char*)NULL);
                return TCL_ERROR;
            }

            archOpt = (ArchOption*)Tcl_GetHashValue(entry);

	    val = ItclGetInstanceVar(interp, "itk_option", archOpt->switchName,
		    contextObj, contextClass);
            if (!val) {
                Itk_ArchOptAccessError(interp, info, archOpt);
                return TCL_ERROR;
            }

            Tcl_AppendElement(interp, archOpt->switchName);
            Tcl_AppendElement(interp,
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
    /*
     *  Otherwise, it must be a series of "-option value" assignments.
     *  Look up each option and assign the new value.
     */
    for (objc--,objv++; objc > 0; objc-=2, objv+=2) {
	char *value;
	int code;
	Tcl_Namespace *save = Tcl_GetCurrentNamespace(interp);
        token = Tcl_GetString(objv[0]);
        if (objc < 2) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "value for \"", token, "\" missing",
                (char*)NULL);
            return TCL_ERROR;
        }
        value = Tcl_GetString(objv[1]);

	Itcl_SetCallFrameNamespace(interp, contextObj->iclsPtr->nsPtr);
        code = Itk_ArchConfigOption(interp, info, token, value);
	Itcl_SetCallFrameNamespace(interp, save);
        if (code != TCL_OK) {
            return TCL_ERROR;
        }
    }

    Tcl_ResetResult(interp);
    return TCL_OK;







|









|

|







1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
    /*
     *  Otherwise, it must be a series of "-option value" assignments.
     *  Look up each option and assign the new value.
     */
    for (objc--,objv++; objc > 0; objc-=2, objv+=2) {
	char *value;
	int code;
//	Tcl_Namespace *save = Tcl_GetCurrentNamespace(interp);
        token = Tcl_GetString(objv[0]);
        if (objc < 2) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "value for \"", token, "\" missing",
                (char*)NULL);
            return TCL_ERROR;
        }
        value = Tcl_GetString(objv[1]);

//	Itcl_SetCallFrameNamespace(interp, contextObj->iclsPtr->nsPtr);
        code = Itk_ArchConfigOption(interp, info, token, value);
//	Itcl_SetCallFrameNamespace(interp, save);
        if (code != TCL_OK) {
            return TCL_ERROR;
        }
    }

    Tcl_ResetResult(interp);
    return TCL_OK;

Changes to generic/itkOption.c.

213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234


235
236
237
238
239
240
241
    ItclObject *contextObj,    /* object being configured */
    ClientData cdata,          /* class option */
    CONST char *newval)        /* new value for this option */
{
    ItkClassOption *opt = (ItkClassOption*)cdata;
    int result = TCL_OK;
    ItclMemberCode *mcode;


    /*
     *  If the option has any config code, execute it now.
     *  Make sure that the namespace context is set up correctly.
     */
    mcode = opt->codePtr;
    if (mcode && mcode->bodyPtr) {
        Tcl_Namespace *saveNsPtr;
//fprintf(stderr, "EXE!%s!\n", Tcl_GetString(mcode->bodyPtr));
        Itcl_SetCallFrameResolver(interp, opt->iclsPtr->resolvePtr);
        saveNsPtr = Tcl_GetCurrentNamespace(interp);
//fprintf(stderr, "MCNS!%s!\n", saveNsPtr->fullName);
        Itcl_SetCallFrameNamespace(interp, opt->iclsPtr->nsPtr);
        result = Tcl_EvalObjEx(interp, mcode->bodyPtr, 0);
        Itcl_SetCallFrameNamespace(interp, saveNsPtr);



	/* 
	 * Here we engage in some ugly hackery workaround until
	 * someone has time to come back and implement this
	 * properly.
	 *
	 * In Itcl/Itk 3, the same machinery was used to implement







>







|
<
|
|
|
<

|
>
>







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231

232
233
234
235
236
237
238
239
240
241
242
    ItclObject *contextObj,    /* object being configured */
    ClientData cdata,          /* class option */
    CONST char *newval)        /* new value for this option */
{
    ItkClassOption *opt = (ItkClassOption*)cdata;
    int result = TCL_OK;
    ItclMemberCode *mcode;
    Tcl_CallFrame frame;

    /*
     *  If the option has any config code, execute it now.
     *  Make sure that the namespace context is set up correctly.
     */
    mcode = opt->codePtr;
    if (mcode && mcode->bodyPtr) {


	Itcl_PushCallFrame(interp, &frame, opt->iclsPtr->nsPtr, 1);
	Itcl_SetContext(interp, contextObj);


        result = Tcl_EvalObjEx(interp, mcode->bodyPtr, 0);

	Itcl_UnsetContext(interp);
	Itcl_PopCallFrame(interp);

	/* 
	 * Here we engage in some ugly hackery workaround until
	 * someone has time to come back and implement this
	 * properly.
	 *
	 * In Itcl/Itk 3, the same machinery was used to implement