is there a way to include an expect or tcl fragment inline via a file?

The Tcl programming language (Tool Command Language)

calbaregmailcom
Hi,

I have a question, and I hope someone can answer it.

I have an expect  procedure, and I want to optional include it in a file if it matches a certain criteria.

The criteria is if a debugger is attached and does, say, stepping, it will step through the code. If the debugger does something else, it will do that something else.

The $DebugCommands is a procedure that is dynanically called and seems to work, though, not exactly what is listed here.

I have an expect procedure snippet here:

1st way:
proc someMethod { } {
...
    expect {
        -i $adb_espresso_spawn_id -re ".+\r\n" {
            exp_continue
            }
        -i $adb_logcat_spawn_id -re ".+\r\n" {
            exp_continue
            }
        -i $adb_espresso_spawn_id eof {
            puts "quitting espresso, eof found."
            }
        -i $adb_espresso_spawn_id timeout {
            puts "Espresso timeout. Time to stop drinking coffee."
            }
        -i $adb_logcat_spawn_id timeout {
            puts "logcat timeout. Time to stop logcatting. Meow!"
            }
        -i $dbg_spawn_id eof {
            puts "dbg EOF."
        }
        -i $dbg_spawn_id -re ".+" {
            $DebugCommands
            exp_continue
        }
    }

Where $DebugCommands is:

proc debugCommands { } {
    global dbg_spawn_id

    expect {
        -i $dbg_spawn_id -re "main\[1\] .*\r\n" {
             puts "found <1> main\[1\]..."
             send "cont\r"
             }
         -i $dbg_spawn_id -re "Breakpoint hit:|Step completed:" {
            set breakpt_count 0 ;# counter used for debugging, this use to be in DebugCommands as a local variable

             puts "in breakpoint hit '$breakpt_count':...\n"
             expect -i $dbg_spawn_id -re "> " {
                 puts "in test for > ..."
                 if [ expr $breakpt_count < 1 ] {
                     puts "Stepping...\n"
                     incr breakpt_count 1
                     send "step\r"
                     exp_continue
                 } else {
                     puts "Continuing...\n"
                     send "cont\r"
                 }
             }
             ;#exp_continue
             }
         -i $dbg_spawn_id eof {
             puts "jdb eof.\n"
             ;#exp_continue
             }
    }
}

The expect clauses do seem to be invoked, however, the 1st clause is never called, if used in the DebugCommands proc, but putting them in a separate file (libdebugger.exp) seemed to break what worked. In particular, I think the nesting of the expect's is doing something bad.

2nd way:
I was wondering if there is a way to include just the file contents that work, and include them inline where the $DebugCommands is used?

That is:

        -i $dbg_spawn_id -re "main\[1\] " {
            puts "found <1> main\[1\]..."
            send "cont\r"
            }
        -i $dbg_spawn_id -re "Breakpoint hit:|Step completed:" {
            puts "in breakpoint hit..."
            expect -i $dbg_spawn_id -re "> " {
                puts "in test for > ..."
                if [ expr $breakpt_count < 3 ] {
                    puts "Stepping..."
                    send "step\r"
                } else {
                    puts "Continuing..."
                    send "cont\r"
                }
                incr breakpt_count 1
            }
            exp_continue
            }
        -i $dbg_spawn_id eof {
            puts "jdb eof."
            exp_continue
            }
<<<<<

proc someMethod { } {
...
    expect {
        -i $adb_espresso_spawn_id -re ".+\r\n" {
            exp_continue
            }
        -i $adb_logcat_spawn_id -re ".+\r\n" {
            exp_continue
            }
        -i $adb_espresso_spawn_id eof {
            puts "quitting espresso, eof found."
            }
        -i $adb_espresso_spawn_id timeout {
            puts "Espresso timeout. Time to stop drinking coffee."
            }
        -i $adb_logcat_spawn_id timeout {
            puts "logcat timeout. Time to stop logcatting. Meow!"
            }
        include "commands.exp"
        }
    }

With the substitued file ending up something like:

proc someMethod { } {

...

    # main expect loop
    set breakpt_count 0 ;# counter used for debugging

    expect {
        -i $adb_espresso_spawn_id -re ".+\r\n" {
            exp_continue
            }
        -i $adb_logcat_spawn_id -re ".+\r\n" {
            exp_continue
            }
        -i $adb_espresso_spawn_id eof {
            puts "quitting espresso, eof found."
            }
        -i $adb_espresso_spawn_id timeout {
            puts "Espresso timeout. Time to stop drinking coffee."
            }
        -i $adb_logcat_spawn_id timeout {
            puts "logcat timeout. Time to stop logcatting. Meow!"
            }
        -i $dbg_spawn_id -re "main\[1\] " {
            puts "found <1> main\[1\]..."
            send "cont\r"
            }
        -i $dbg_spawn_id -re "Breakpoint hit:|Step completed:" {
            puts "in breakpoint hit..."
            expect -i $dbg_spawn_id -re "> " {
                puts "in test for > ..."
                if [ expr $breakpt_count < 3 ] {
                    puts "Stepping..."
                    send "step\r"
                } else {
                    puts "Continuing..."
                    send "cont\r"
                }
                incr breakpt_count 1
            }
            exp_continue
            }
        -i $dbg_spawn_id eof {
            puts "jdb eof."
            exp_continue
            }
        } ;# expect
    }

Note, the 2nd final version directly above does work, since I got it out of our source repository.

Anyways,  let me know if there is a way to do this correctly. I would prefer if I could invoke it the 1st way, but the 2nd way was the way I was going to do it.

Thanks.                                            
DrS
It does not matter where your code is as long as you source it. 
However, for this case, I suggest putting all of your proc's in one 
single file.

Then:




This is the wrong way to invoke the debugCommands proc.  Instead, do this:

-i $dbg_spawn_id -re ".+" {
    set debug_result [debugCommands $include_any_args_here]
    exp_continue # or you can check for $debug_result first
}


DrS
                                            
Jose
Hi,

Thanks for the replies.

I thought of another way to try to solve this. That is, is there a way to do something like this?

That is to "re-send" the output so that it can be matched again?

I'm not sure how to do that, but I think if I can do that, the code may work since one of the matches isn't getting matched.

proc someMethod { } {
...
        -i $dbg_spawn_id -re ".+" { 
            debugCommands 
            exp_continue 
        }
...
}

Then in debugCommands:

proc debugCommands { } {
    global dbg_spawn_id

    send "expect_out(1,string)\r"

    expect { 
        -i $dbg_spawn_id -re "main\[1\] .*\r\n" { 
             puts "found <1> main\[1\]..." 
             send "cont\r" 
             } 
         -i $dbg_spawn_id -re "Breakpoint hit:|Step completed:" { 
            set breakpt_count 0 ;# counter used for debugging, this use to be in DebugCommands as a local variable 

             puts "in breakpoint hit '$breakpt_count':...\n" 
             expect -i $dbg_spawn_id -re "> " { 
                 puts "in test for > ..." 
                 if [ expr $breakpt_count < 1 ] { 
                     puts "Stepping...\n" 
                     incr breakpt_count 1 
                     send "step\r" 
                     exp_continue 
                 } else { 
                     puts "Continuing...\n" 
                     send "cont\r" 
                 } 
             } 
             ;#exp_continue 
             } 
         -i $dbg_spawn_id eof { 
             puts "jdb eof.\n" 
             ;#exp_continue 
             } 
    }
                                            
DrS
...




This is what I suggested in my reply to you earlier today.

DrS