|
Prev: freewrap with blt2.4 demo program:
Next: newbie
From: sandy on 4 Jul 2008 13:48 Hi, I'm trying to embed tcl interpreter in C, but observing different behaviors (shell vs embedded). For example, the script below entered line by line on shell and embedded interpreter gives different results. ######### 1) puts " Hi there!" 2) for {set i 0} {$i <= 10} {incr i} { 3) puts "no $i" 4) } ######### Tcl shell :- Shell pauses after line 2, waits till line 3 and 4 entered and executes the loop. Embedded interpreter :- After line 2, immediately throws error "missing close-brace" ######### I don't understand reason behind this different behavior, is there any way to get shell behavior in my embedded interpreter ? I can't expect user to enter nested loops in one line ;-) Here is my c code...... main (int argc, char *argv[]) { Tcl_Interp *interp; int code, temp; char *z; interp = Tcl_CreateInterp(); while(fgets(zLine, sizeof(zLine), stdin)) { code = Tcl_Eval(interp, zLine); if(code = TCL_ERROR) { z = Tcl_GetStringResult(interp); printf(" Error = %s\n", z ); } } } Thanks, Sandy
From: Glenn Jackman on 4 Jul 2008 14:06 At 2008-07-04 01:48PM, "sandy" wrote: > ######### > 1) puts " Hi there!" > 2) for {set i 0} {$i <= 10} {incr i} { > 3) puts "no $i" > 4) } > ######### > > Tcl shell :- Shell pauses after line 2, waits till line 3 and 4 > entered and executes the loop. The interpreter is waiting for the close brace of the for body. > Embedded interpreter :- After line 2, immediately throws error > "missing close-brace" You're evaluating an incomplete command. > Here is my c code...... > > main (int argc, char *argv[]) > { > Tcl_Interp *interp; > int code, temp; > char *z; > > interp = Tcl_CreateInterp(); > > while(fgets(zLine, sizeof(zLine), stdin)) > { > code = Tcl_Eval(interp, zLine); I'm not proficient in the C API, but you need to call Tcl_CommandComplete before Tcl_Eval -- Glenn Jackman Write a wise saying and your name will live forever. -- Anonymous
From: Neil Madden on 5 Jul 2008 10:36 Glenn Jackman wrote: [...] >> Here is my c code...... >> >> main (int argc, char *argv[]) >> { >> Tcl_Interp *interp; >> int code, temp; >> char *z; >> >> interp = Tcl_CreateInterp(); >> >> while(fgets(zLine, sizeof(zLine), stdin)) >> { >> code = Tcl_Eval(interp, zLine); > > I'm not proficient in the C API, but you need to call > Tcl_CommandComplete before Tcl_Eval Implicit in that advice is that you also need to buffer up input until Tcl_CommandComplete indicates that you have a complete command. It's easy to do in a tcl script: proc prompt {p varName} { upvar 1 $varName line puts -nonewline stdout $p flush stdout gets stdin line } set p "% " set cmd "" while {[prompt $p line] >= 0} { if {[info complete [append cmd $line\n]]} { catch { eval $cmd } result puts $result set cmd ""; set p "% " } else { set p " " } } -- Neil
From: sandy on 5 Jul 2008 23:28 On Jul 4, 2:06 pm, Glenn Jackman <gle...(a)ncf.ca> wrote: > At 2008-07-04 01:48PM, "sandy" wrote: > > > ######### > > 1) puts " Hi there!" > > 2) for {set i 0} {$i <= 10} {incr i} { > > 3) puts "no $i" > > 4) } > > ######### > > > Tcl shell :- Shell pauses after line 2, waits till line 3 and 4 > > entered and executes the loop. > > The interpreter is waiting for the close brace of the for body. > > > Embedded interpreter :- After line 2, immediately throws error > > "missing close-brace" > > You're evaluating an incomplete command. > > > Here is my c code...... > > > main (int argc, char *argv[]) > > { > > Tcl_Interp *interp; > > int code, temp; > > char *z; > > > interp = Tcl_CreateInterp(); > > > while(fgets(zLine, sizeof(zLine), stdin)) > > { > > code = Tcl_Eval(interp, zLine); > > I'm not proficient in the C API, but you need to call > Tcl_CommandComplete before Tcl_Eval > > -- > Glenn Jackman > Write a wise saying and your name will live forever. -- Anonymous Thanks a lot Glenn, you saved my day. I was not aware of this function. Regards, Sandy
From: sandy on 5 Jul 2008 23:32
On Jul 5, 10:36 am, Neil Madden <n...(a)cs.nott.ac.uk> wrote: > Glenn Jackman wrote: > > [...] > > > > >> Here is my c code...... > > >> main (int argc, char *argv[]) > >> { > >> Tcl_Interp *interp; > >> int code, temp; > >> char *z; > > >> interp = Tcl_CreateInterp(); > > >> while(fgets(zLine, sizeof(zLine), stdin)) > >> { > >> code = Tcl_Eval(interp, zLine); > > > I'm not proficient in the C API, but you need to call > > Tcl_CommandComplete before Tcl_Eval > > Implicit in that advice is that you also need to buffer up input until > Tcl_CommandComplete indicates that you have a complete command. It's > easy to do in a tcl script: > > proc prompt {p varName} { > upvar 1 $varName line > puts -nonewline stdout $p > flush stdout > gets stdin line} > > set p "% " > set cmd "" > while {[prompt $p line] >= 0} { > if {[info complete [append cmd $line\n]]} { > catch { eval $cmd } result > puts $result > set cmd ""; set p "% " > } else { > set p " " > } > > } > > -- Neil hi neil, my interface is C->tcl(interpreter), any way thanks for the inputs. |