Posted to tcl by hypnotoad at Fri Dec 05 19:28:48 GMT 2014view pretty
cstruct::function ${EnsembleName}_nodeeval { returns int arglist {Tcl_Interp *interp,%StructName% *p,Tcl_Obj *body,int writeback} } { Tcl_Obj *id; Tcl_Obj *pValueDict; int i; Tcl_Obj **varv; int varc,result; if(!p) { return TCL_CONTINUE; } pValueDict=%StructName%_StructToDict(interp,p,1); if(!pValueDict) { return TCL_CONTINUE; } if (Tcl_ListObjGetElements(interp, pValueDict, &varc, &varv) != TCL_OK) { return TCL_ERROR; } for(i=0;i<varc;i+=2) { //Tcl_IncrRefCount(varv[i+1]); Tcl_ObjSetVar2(interp, varv[i], (Tcl_Obj *)NULL, varv[i+1], 0); } id=%EnsembleName%_Identify(p); Tcl_ObjSetVar2(interp,Irm_NewStringObj("id"),NULL,id,0); Tcl_ObjSetVar2(interp,Irm_NewStringObj("typeid"),NULL,%EnsembleName%_TypeToTclObj(p),0); Tcl_ObjSetVar2(interp,Irm_NewStringObj("groupid"),NULL,%EnsembleName%_GroupToTclObj(p),0); Tcl_ObjSetVar2(interp,Irm_NewStringObj("config_dict"),NULL,Tcl_DuplicateObj(pValueDict),0); result=Tcl_EvalObjEx(interp, body, 0); if(result!=TCL_OK) { if(pValueDict) { Tcl_DecrRefCount(pValueDict); } return result; } if(writeback){ /* ** Read values back into the dict ** For now, we limit writeback to state variables ** And we don't care about garbage values */ for(i=0;i<varc;i+=2) { Tcl_Obj *newValue; int offset; int type; newValue=Tcl_ObjGetVar2(interp,varv[i],(Tcl_Obj*)NULL,0); if(newValue==varv[i+1]) { /* Undocumented, unsanctioned, but it works in practice ** If the pointer hasn't changed, neither has the value */ continue; } if(!newValue) { /* Variable must have been unset... move along */ continue; } if( %StructName%_StructValueOffset(0, varv[i], &offset, &type) == TCL_OK ) { %StructName%_StructSet(interp,p,offset,newValue); } else { %StructName%_SpecDictPut(p,varv[i],newValue); } } %StructName%_ApplySettings(p); } if(pValueDict) { Tcl_DecrRefCount(pValueDict); } return TCL_OK; }