From: sandy on
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
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
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
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
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.
 |  Next  |  Last
Pages: 1 2
Prev: freewrap with blt2.4 demo program:
Next: newbie