Itk - the [incr Tk] extension

Check-in [b53797db6b]
Login

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

Overview
Comment:Support [return] in an itcl::configbody.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b53797db6b3d42874d920077504f9dbfca8d30fb
User & Date: dgp 2017-06-28 16:28:00.082
Context
2017-06-29
15:25
Bump to Itk 4.0.3. check-in: f48084eacd user: dgp tags: trunk
2017-06-28
16:28
Support [return] in an itcl::configbody. check-in: b53797db6b user: dgp tags: trunk
2016-09-19
19:01
Protect against loading Itk 4 in an interp already housing Itcl 3. check-in: 52ddb55ee0 user: dgp tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to generic/itkOption.c.
228
229
230
231
232
233
234
235










236
237
238



































239
240
241
242
243
244
245
//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);
#ifdef NOTDEF










        result = Itcl_EvalMemberCode(interp, (ItclMemberFunc*)NULL,
            opt->member, contextObj, 0, (Tcl_Obj**)NULL);
#endif



































    }
    return result;
}


/*
 * ------------------------------------------------------------------------







|
>
>
>
>
>
>
>
>
>
>


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
//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
	 * method invocation and configbody invocation, and the
	 * code here looked like:
	 *
	 
        result = Itcl_EvalMemberCode(interp, (ItclMemberFunc*)NULL,
            opt->member, contextObj, 0, (Tcl_Obj**)NULL);

	 *
	 * In Itcl 4, Itcl methods have become (a particular variant)
	 * of TclOO methods.  It's not clear whether config bodies
	 * should also do that, or what?
	 *
	 * Instead the existing solution above has been to just "eval"
	 * the configbody body script in a suitable context, which
	 * works very nearly correctly.  The trouble is that unlike
	 * method invocation, we've not pushed a proper frame, nor
	 * have we unwound a return level, so when the "eval" returns
	 * TCL_RETURN we've not been handling that right.  You will
	 * find some configbody bodies out there that expect to be
	 * able to use [return] for early exit.  Iwidgets test
	 * Extbutton-2.8 is an example.
	 *
	 * As a cheap workaround, we put in explicit special treatment
	 * for (result == TCL_RETURN) here.  This is essentially a
	 * reproduction of the Tcl internal routine TclUpdateReturnInfo()
	 * but without the benefit of internals access.
 	 */

	if (result == TCL_RETURN) {
	    Tcl_Obj *opts = Tcl_GetReturnOptions(interp, TCL_RETURN);
	    Tcl_Obj *levelKey = Tcl_NewStringObj("-level", -1);
	    Tcl_Obj *levelObj;
	    int level;

	    Tcl_DictObjGet(NULL, opts, levelKey, &levelObj);
	    Tcl_GetIntFromObj(NULL, levelObj, &level);

	    Tcl_DictObjPut(NULL, opts, levelKey, Tcl_NewIntObj(--level));
	    result = Tcl_SetReturnOptions(interp, opts);
	    
	    Tcl_DecrRefCount(levelKey);
	}
    }
    return result;
}


/*
 * ------------------------------------------------------------------------