From: Matthias Meier on 29 Apr 2010 05:39 Hello, i want to "reset" an Interpreter after evaluating a script to the state it was after initialisation. (that means: delete all the vars/procs which were created during the script-evaluation) i.E -------------------------------------- int fkt ( char* script ) { static Tcl_Interp* interp = (Tcl_Interp*)0; if( !interp ) interp = Tcl_CreateInterp(); Tcl_Eval( interp, script ); fprintf( stderr, "Result = '%s'\n", interp->result ); Tcl_ResetResult( interp ); // Reset interp to the state after Tcl_CreateInterp() // ?? return(0); } fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); --------------------------------------- should print Result = '1' Result = '1' and not - as it is - Result = '1' Result = '2' I could delete the interpreter and create it new, every time i call the function, but this consumes to much time. I could delete all global vars (procs) after calling my script: fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); fkt( "foreach var [info globals] { unset $var }" ); fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); fkt( "foreach var [info globals] { unset $var }" ); but this would delete all 'system-vars' too (tcl_version ...). Is there a posibility to 'duplicate' an interpreter (which ist faster then create a new one?) or to 'reset' an interpreter to the state it was bevore the script was evaluated or to the state it was after initialisation? Thanks for all hints! Matthias
From: Alexandre Ferrieux on 29 Apr 2010 18:27 On Apr 29, 11:39 am, Matthias Meier <Me...(a)FuH-E.de> wrote: > Hello, > > i want to "reset" an Interpreter after evaluating a script to the state it was after initialisation. > (that means: delete all the vars/procs which were created during the script-evaluation) > > i.E > > -------------------------------------- > int fkt ( char* script ) > { > static Tcl_Interp* interp = (Tcl_Interp*)0; > > if( !interp ) interp = Tcl_CreateInterp(); > > Tcl_Eval( interp, script ); > fprintf( stderr, "Result = '%s'\n", interp->result ); > > Tcl_ResetResult( interp ); > > // Reset interp to the state after Tcl_CreateInterp() > // ?? > > return(0); > > } > > fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); > fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); > --------------------------------------- > > should print > Result = '1' > Result = '1' > > and not - as it is - > > Result = '1' > Result = '2' > > I could delete the interpreter and create it new, every time i call the function, but this consumes to much time. > > I could delete all global vars (procs) after calling my script: > > fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); > fkt( "foreach var [info globals] { unset $var }" ); > fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); > fkt( "foreach var [info globals] { unset $var }" ); > > but this would delete all 'system-vars' too (tcl_version ...). > > Is there a posibility to 'duplicate' an interpreter (which ist faster then create a new one?) or to 'reset' an interpreter to the state it was bevore the script was evaluated or to the state it was after initialisation? > > Thanks for all hints! > > Matthias You could just delete the new vars and procs: foreach var [info globals] {set oldvar($var) 1} # same for procs CODE foreach var [info globals] {if {![info exists oldvar($var)]} {unset $var}} # same for procs But may I ask what you're trying to do ? -Alex
From: Alexandre Ferrieux on 29 Apr 2010 18:51 On Apr 30, 12:27 am, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> wrote: > On Apr 29, 11:39 am, Matthias Meier <Me...(a)FuH-E.de> wrote: > > > > > > > Hello, > > > i want to "reset" an Interpreter after evaluating a script to the state it was after initialisation. > > (that means: delete all the vars/procs which were created during the script-evaluation) > > > i.E > > > -------------------------------------- > > int fkt ( char* script ) > > { > > static Tcl_Interp* interp = (Tcl_Interp*)0; > > > if( !interp ) interp = Tcl_CreateInterp(); > > > Tcl_Eval( interp, script ); > > fprintf( stderr, "Result = '%s'\n", interp->result ); > > > Tcl_ResetResult( interp ); > > > // Reset interp to the state after Tcl_CreateInterp() > > // ?? > > > return(0); > > > } > > > fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); > > fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); > > --------------------------------------- > > > should print > > Result = '1' > > Result = '1' > > > and not - as it is - > > > Result = '1' > > Result = '2' > > > I could delete the interpreter and create it new, every time i call the function, but this consumes to much time. > > > I could delete all global vars (procs) after calling my script: > > > fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); > > fkt( "foreach var [info globals] { unset $var }" ); > > fkt( "if { ![info exists anz] } { set anz 0 }; incr anz; return $anz" ); > > fkt( "foreach var [info globals] { unset $var }" ); > > > but this would delete all 'system-vars' too (tcl_version ...). > > > Is there a posibility to 'duplicate' an interpreter (which ist faster then create a new one?) or to 'reset' an interpreter to the state it was bevore the script was evaluated or to the state it was after initialisation? > > > Thanks for all hints! > > > Matthias > > You could just delete the new vars and procs: > > foreach var [info globals] {set oldvar($var) 1} > # same for procs > CODE > foreach var [info globals] {if {![info exists oldvar($var)]} > {unset $var}} > # same for procs of course: foreach var [info globals] {if {($var!="oldvar")&&![info exists oldvar($var)]} {unset $var}} -Alex
From: Erik Leunissen on 30 Apr 2010 04:47 Matthias Meier wrote: > Hello, > > i want to "reset" an Interpreter after evaluating a script to the state > it was after initialisation. > (that means: delete all the vars/procs which were created during the > script-evaluation) > Alex has shown you how to delete variables and procs using an simple bookkeeping mechanism. If "resetting" an interpreter also includes restoring values that were changed, and restoring procs to their original after they were redefined, then additional bookkeeping is required which is tedious and error prone. In that case you might reconsider spawning a separate interp for each script to evaluate. If safety is one of your concerns, you may want to use the safe slave interp mechanism using [interp create -safe], cf: http://wiki.tcl.tk/4204 Or maybe the safe base mechanism is something for you: http://www.tcl.tk/man/tcl8.4/TclCmd/safe.htm Erik -- leunissen@ nl | Merge the left part of these two lines into one, e. hccnet. | respecting a character's position in a line.
From: Matthias Meier on 3 May 2010 02:51
Alexandre Ferrieux schrieb: > On Apr 29, 11:39 am, Matthias Meier <Me...(a)FuH-E.de> wrote: >> Hello, >> >> i want to "reset" an Interpreter after evaluating a script to the state it was after initialisation. >> (that means: delete all the vars/procs which were created during the script-evaluation) >> > But may I ask what you're trying to do ? I have an tcl-interpreter in a long running (c-written) server-process. During server livetime various scripts (which have nothing to do with each other) are interpreted and i want to ensure that the scripts are don't affect each other. (i.E. just because one script uses variables (variable names) which an other Script uses too) Therefore i would like to evaluate each script in a 'new'/clean interpreter. But creating a new interpreter ( Tcl_CreateInterp() ) every time would consume too much time. Because the problem is time-critical im looking for the most performant way to 'reset' the interpreter. (I hoped there is a more performant way to do it then unsetting the vars one by one) Matthias |