Itk - the [incr Tk] extension

Check-in [b46f3c3fe0]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to tclconference@googlegroups.com
or submit via the online form by Sep 9.

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

Overview
Comment:Several revisions to get evaluation contexts more reliably correct.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dgp-method-type
Files: files | file ages | folders
SHA1:b46f3c3fe00d0d0e617d4ddfd7dd95a377fe8810
User & Date: dgp 2017-07-28 16:57:26
Context
2017-07-28
17:04
Repurpose the trunk for ongoing development of Itk 4.1.*. check-in: fc469d3c3b user: dgp tags: trunk, itk-4-1-0
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-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
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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
...
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
...
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
....
1593
1594
1595
1596
1597
1598
1599





1600
1601

1602
1603
1604
1605
1606
1607
1608
....
1616
1617
1618
1619
1620
1621
1622
1623
1624

1625
1626

1627
1628



1629
1630
1631
1632
1633
1634
1635
....
1721
1722
1723
1724
1725
1726
1727


1728
1729
1730
1731
1732
1733
1734
....
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
....
1782
1783
1784
1785
1786
1787
1788

1789




1790
1791
1792
1793
1794
1795
1796
         *  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,
................................................................................
    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;
    }
................................................................................

       /*
        *  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);
................................................................................
     */

    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) {
................................................................................
     *  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);
................................................................................
    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
................................................................................
        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.
................................................................................
     *  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);








|





>
>
>
>
>

|

|







|






>







 







|
<
<
|
<
<
>







 







|







 







>
>
>
>
>


>







 







|
<
>
|
|
>

<
>
>
>







 







>
>







 







>

>
>
>
>
>
>
>










>

>
>
>
>







 







>

>
>
>
>







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
...
480
481
482
483
484
485
486
487


488


489
490
491
492
493
494
495
496
...
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
....
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
....
1625
1626
1627
1628
1629
1630
1631
1632

1633
1634
1635
1636
1637

1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
....
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
....
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
....
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
         *  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,
................................................................................
    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;
    }
................................................................................

       /*
        *  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);
................................................................................
     */

    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) {
................................................................................
     *  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);
................................................................................
    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
................................................................................
        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.
................................................................................
     *  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
....
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
....
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
....
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
    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,
................................................................................
	}
    }
    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);
................................................................................

        /*
         *  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,
................................................................................
    /*
     *  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;







<







 







<


<
|
<
>







 







<










|
|
|







 







|









|

|







162
163
164
165
166
167
168

169
170
171
172
173
174
175
....
1063
1064
1065
1066
1067
1068
1069

1070
1071

1072

1073
1074
1075
1076
1077
1078
1079
1080
....
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
....
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
    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,
................................................................................
	}
    }
    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);
................................................................................

        /*
         *  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,
................................................................................
    /*
     *  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